Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(376)

Side by Side Diff: nss/mozilla/security/nss/lib/freebl/rijndael.c

Issue 10919163: Add GCM, CTR, and CTS modes to AES. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* ***** BEGIN LICENSE BLOCK ***** 1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 * 3 *
4 * The contents of this file are subject to the Mozilla Public License Version 4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with 5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at 6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/ 7 * http://www.mozilla.org/MPL/
8 * 8 *
9 * Software distributed under the License is distributed on an "AS IS" basis, 9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
(...skipping 29 matching lines...) Expand all
40 #endif 40 #endif
41 41
42 #include "prinit.h" 42 #include "prinit.h"
43 #include "prerr.h" 43 #include "prerr.h"
44 #include "secerr.h" 44 #include "secerr.h"
45 45
46 #include "prtypes.h" 46 #include "prtypes.h"
47 #include "blapi.h" 47 #include "blapi.h"
48 #include "rijndael.h" 48 #include "rijndael.h"
49 49
50 #include "cts.h"
51 #include "ctr.h"
52 #include "gcm.h"
53
50 #if USE_HW_AES 54 #if USE_HW_AES
51 #include "intel-aes.h" 55 #include "intel-aes.h"
52 #include "mpi.h" 56 #include "mpi.h"
53 #endif 57 #endif
54 58
55 /* 59 /*
56 * There are currently five ways to build this code, varying in performance 60 * There are currently five ways to build this code, varying in performance
57 * and code size. 61 * and code size.
58 * 62 *
59 * RIJNDAEL_INCLUDE_TABLES Include all tables from rijndael32.tab 63 * RIJNDAEL_INCLUDE_TABLES Include all tables from rijndael32.tab
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 cx->Nb = blocksize / 4; 1047 cx->Nb = blocksize / 4;
1044 /* Nk = (key size in bits) / 32 */ 1048 /* Nk = (key size in bits) / 32 */
1045 Nk = keysize / 4; 1049 Nk = keysize / 4;
1046 /* Obtain number of rounds from "table" */ 1050 /* Obtain number of rounds from "table" */
1047 cx->Nr = RIJNDAEL_NUM_ROUNDS(Nk, cx->Nb); 1051 cx->Nr = RIJNDAEL_NUM_ROUNDS(Nk, cx->Nb);
1048 /* copy in the iv, if neccessary */ 1052 /* copy in the iv, if neccessary */
1049 if (mode == NSS_AES_CBC) { 1053 if (mode == NSS_AES_CBC) {
1050 memcpy(cx->iv, iv, blocksize); 1054 memcpy(cx->iv, iv, blocksize);
1051 #if USE_HW_AES 1055 #if USE_HW_AES
1052 if (use_hw_aes) { 1056 if (use_hw_aes) {
1053 » cx->worker = intel_aes_cbc_worker(encrypt, keysize); 1057 » cx->worker = (freeblCipherFunc)
1058 » » » » intel_aes_cbc_worker(encrypt, keysize);
1054 } else 1059 } else
1055 #endif 1060 #endif
1056 » cx->worker = (encrypt 1061 » cx->worker = (freeblCipherFunc) (encrypt
1057 ? &rijndael_encryptCBC : &rijndael_decryptCBC); 1062 ? &rijndael_encryptCBC : &rijndael_decryptCBC);
1058 } else { 1063 } else {
1059 #if USE_HW_AES 1064 #if USE_HW_AES
1060 if (use_hw_aes) { 1065 if (use_hw_aes) {
1061 » cx->worker = intel_aes_ecb_worker(encrypt, keysize); 1066 » cx->worker = (freeblCipherFunc)
1067 » » » » intel_aes_ecb_worker(encrypt, keysize);
1062 } else 1068 } else
1063 #endif 1069 #endif
1064 » cx->worker = (encrypt 1070 » cx->worker = (freeblCipherFunc) (encrypt
1065 ? &rijndael_encryptECB : &rijndael_decryptECB); 1071 ? &rijndael_encryptECB : &rijndael_decryptECB);
1066 } 1072 }
1067 PORT_Assert((cx->Nb * (cx->Nr + 1)) <= RIJNDAEL_MAX_EXP_KEY_SIZE); 1073 PORT_Assert((cx->Nb * (cx->Nr + 1)) <= RIJNDAEL_MAX_EXP_KEY_SIZE);
1068 if ((cx->Nb * (cx->Nr + 1)) > RIJNDAEL_MAX_EXP_KEY_SIZE) { 1074 if ((cx->Nb * (cx->Nr + 1)) > RIJNDAEL_MAX_EXP_KEY_SIZE) {
1069 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 1075 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1070 goto cleanup; 1076 goto cleanup;
1071 } 1077 }
1072 #ifdef USE_HW_AES 1078 #ifdef USE_HW_AES
1073 if (use_hw_aes) { 1079 if (use_hw_aes) {
1074 intel_aes_init(encrypt, keysize); 1080 intel_aes_init(encrypt, keysize);
(...skipping 12 matching lines...) Expand all
1087 #endif 1093 #endif
1088 /* Generate expanded key */ 1094 /* Generate expanded key */
1089 if (encrypt) { 1095 if (encrypt) {
1090 if (rijndael_key_expansion(cx, key, Nk) != SECSuccess) 1096 if (rijndael_key_expansion(cx, key, Nk) != SECSuccess)
1091 goto cleanup; 1097 goto cleanup;
1092 } else { 1098 } else {
1093 if (rijndael_invkey_expansion(cx, key, Nk) != SECSuccess) 1099 if (rijndael_invkey_expansion(cx, key, Nk) != SECSuccess)
1094 goto cleanup; 1100 goto cleanup;
1095 } 1101 }
1096 } 1102 }
1103 cx->worker_cx = cx;
1104 cx->destroy = NULL;
1105 cx->isBlock = PR_TRUE;
1097 return SECSuccess; 1106 return SECSuccess;
1098 cleanup: 1107 cleanup:
1099 return SECFailure; 1108 return SECFailure;
1100 } 1109 }
1101 1110
1102 1111
1103 /* AES_CreateContext 1112 /* AES_CreateContext
1104 * 1113 *
1105 * create a new context for Rijndael operations 1114 * create a new context for Rijndael operations
1106 */ 1115 */
1107 AESContext * 1116 AESContext *
1108 AES_CreateContext(const unsigned char *key, const unsigned char *iv, 1117 AES_CreateContext(const unsigned char *key, const unsigned char *iv,
1109 int mode, int encrypt, 1118 int mode, int encrypt,
1110 unsigned int keysize, unsigned int blocksize) 1119 unsigned int keysize, unsigned int blocksize)
1111 { 1120 {
1112 AESContext *cx = AES_AllocateContext(); 1121 AESContext *cx = AES_AllocateContext();
1113 if (cx) { 1122 int basemode = mode;;
1114 » SECStatus rv = AES_InitContext(cx, key, keysize, iv, mode, encrypt, 1123 PRBool baseencrypt = encrypt;
1115 » » » » blocksize); 1124 SECStatus rv;
1116 » if (rv != SECSuccess) { 1125
1117 » AES_DestroyContext(cx, PR_TRUE); 1126 switch (mode) {
1118 » cx = NULL; 1127 case NSS_AES_CTS:
1119 » } 1128 » basemode = NSS_AES_CBC;
1129 » break;
1130 case NSS_AES_GCM:
1131 case NSS_AES_CTR:
1132 » basemode = NSS_AES;
1133 » baseencrypt = PR_TRUE;
1134 » break;
1135 }
1136 if (cx == NULL) {
1137 » return NULL;
1138 }
1139 rv = AES_InitContext(cx, key, keysize, iv, basemode,
1140 » » » » » baseencrypt, blocksize);
1141 if (rv != SECSuccess) {
1142 » AES_DestroyContext(cx, PR_TRUE);
1143 » return NULL;
1144 }
1145
1146 /* finally, set up any mode specific contexts */
1147 switch (mode) {
1148 case NSS_AES_CTS:
1149 » cx->worker_cx = CTS_CreateContext(cx, cx->worker, iv, blocksize);
1150 » cx->worker = (freeblCipherFunc)
1151 » » » (encrypt ? CTS_EncryptUpdate : CTS_DecryptUpdate);
1152 » cx->destroy = (freeblDestroyFunc) CTS_DestroyContext;
1153 » cx->isBlock = PR_FALSE;
1154 » break;
1155 case NSS_AES_GCM:
1156 » cx->worker_cx = GCM_CreateContext(cx, cx->worker, iv, blocksize);
1157 » cx->worker = (freeblCipherFunc)
1158 » » » (encrypt ? GCM_EncryptUpdate : GCM_DecryptUpdate);
1159 » cx->destroy = (freeblDestroyFunc) GCM_DestroyContext;
1160 » cx->isBlock = PR_FALSE;
1161 » break;
1162 case NSS_AES_CTR:
1163 » cx->worker_cx = CTR_CreateContext(cx, cx->worker, iv, blocksize);
1164 » cx->worker = (freeblCipherFunc) CTR_Update ;
1165 » cx->destroy = (freeblDestroyFunc) CTR_DestroyContext;
1166 » cx->isBlock = PR_FALSE;
1167 » break;
1168 default:
1169 » /* everything has already been set up by AES_InitContext, just return*/
1170 » return cx;
1171 }
1172 /* check to see if we succeeded in getting the worker context */
1173 if (cx->worker_cx == NULL) {
1174 » /* no, just destroy the existing context */
1175 » cx->destroy = NULL; /* paranoia, though you can see a dozen lines */
1176 » » » /* below that this isn't necessary */
1177 » AES_DestroyContext(cx, PR_TRUE);
1178 » return NULL;
1120 } 1179 }
1121 return cx; 1180 return cx;
1122 } 1181 }
1123 1182
1183
1124 /* 1184 /*
1125 * AES_DestroyContext 1185 * AES_DestroyContext
1126 * 1186 *
1127 * Zero an AES cipher context. If freeit is true, also free the pointer 1187 * Zero an AES cipher context. If freeit is true, also free the pointer
1128 * to the context. 1188 * to the context.
1129 */ 1189 */
1130 void 1190 void
1131 AES_DestroyContext(AESContext *cx, PRBool freeit) 1191 AES_DestroyContext(AESContext *cx, PRBool freeit)
1132 { 1192 {
1133 /* memset(cx, 0, sizeof *cx); */ 1193 /* memset(cx, 0, sizeof *cx); */
1194 if (freeit && cx->worker_cx && cx->destroy) {
Ryan Sleevi 2012/09/11 19:34:30 It's not clear why you switch on freeit here. My
rjrejyea 2012/09/19 22:19:33 It's ugly and has to do with psuedo private caller
1195 (*cx->destroy)(cx->worker_cx, freeit);
1196 }
1134 if (freeit) 1197 if (freeit)
1135 PORT_Free(cx); 1198 PORT_Free(cx);
1136 } 1199 }
1137 1200
1138 /* 1201 /*
1139 * AES_Encrypt 1202 * AES_Encrypt
1140 * 1203 *
1141 * Encrypt an arbitrary-length buffer. The output buffer must already be 1204 * Encrypt an arbitrary-length buffer. The output buffer must already be
1142 * allocated to at least inputLen. 1205 * allocated to at least inputLen.
1143 */ 1206 */
1144 SECStatus 1207 SECStatus
1145 AES_Encrypt(AESContext *cx, unsigned char *output, 1208 AES_Encrypt(AESContext *cx, unsigned char *output,
1146 unsigned int *outputLen, unsigned int maxOutputLen, 1209 unsigned int *outputLen, unsigned int maxOutputLen,
1147 const unsigned char *input, unsigned int inputLen) 1210 const unsigned char *input, unsigned int inputLen)
1148 { 1211 {
1149 int blocksize; 1212 int blocksize;
1150 /* Check args */ 1213 /* Check args */
1151 if (cx == NULL || output == NULL || input == NULL) { 1214 if (cx == NULL || output == NULL || input == NULL) {
1152 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1215 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1153 return SECFailure; 1216 return SECFailure;
1154 } 1217 }
1155 blocksize = 4 * cx->Nb; 1218 blocksize = 4 * cx->Nb;
1156 if (inputLen % blocksize != 0) { 1219 if (cx->isBlock && (inputLen % blocksize != 0)) {
1157 PORT_SetError(SEC_ERROR_INPUT_LEN); 1220 PORT_SetError(SEC_ERROR_INPUT_LEN);
1158 return SECFailure; 1221 return SECFailure;
1159 } 1222 }
1160 if (maxOutputLen < inputLen) { 1223 if (maxOutputLen < inputLen) {
1161 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 1224 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1162 return SECFailure; 1225 return SECFailure;
1163 } 1226 }
1164 *outputLen = inputLen; 1227 *outputLen = inputLen;
1165 return (*cx->worker)(cx, output, outputLen, maxOutputLen,» 1228 return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,»
1166 input, inputLen, blocksize); 1229 input, inputLen, blocksize);
1167 } 1230 }
1168 1231
1169 /* 1232 /*
1170 * AES_Decrypt 1233 * AES_Decrypt
1171 * 1234 *
1172 * Decrypt and arbitrary-length buffer. The output buffer must already be 1235 * Decrypt and arbitrary-length buffer. The output buffer must already be
1173 * allocated to at least inputLen. 1236 * allocated to at least inputLen.
1174 */ 1237 */
1175 SECStatus 1238 SECStatus
1176 AES_Decrypt(AESContext *cx, unsigned char *output, 1239 AES_Decrypt(AESContext *cx, unsigned char *output,
1177 unsigned int *outputLen, unsigned int maxOutputLen, 1240 unsigned int *outputLen, unsigned int maxOutputLen,
1178 const unsigned char *input, unsigned int inputLen) 1241 const unsigned char *input, unsigned int inputLen)
1179 { 1242 {
1180 int blocksize; 1243 int blocksize;
1181 /* Check args */ 1244 /* Check args */
1182 if (cx == NULL || output == NULL || input == NULL) { 1245 if (cx == NULL || output == NULL || input == NULL) {
1183 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1246 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1184 return SECFailure; 1247 return SECFailure;
1185 } 1248 }
1186 blocksize = 4 * cx->Nb; 1249 blocksize = 4 * cx->Nb;
1187 if (inputLen % blocksize != 0) { 1250 if (cx->isBlock && (inputLen % blocksize != 0)) {
1188 PORT_SetError(SEC_ERROR_INPUT_LEN); 1251 PORT_SetError(SEC_ERROR_INPUT_LEN);
1189 return SECFailure; 1252 return SECFailure;
1190 } 1253 }
1191 if (maxOutputLen < inputLen) { 1254 if (maxOutputLen < inputLen) {
1192 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 1255 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1193 return SECFailure; 1256 return SECFailure;
1194 } 1257 }
1195 *outputLen = inputLen; 1258 *outputLen = inputLen;
1196 return (*cx->worker)(cx, output, outputLen, maxOutputLen,» 1259 return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,»
1197 input, inputLen, blocksize); 1260 input, inputLen, blocksize);
1198 } 1261 }
OLDNEW
« nss/mozilla/security/nss/lib/freebl/gcm.c ('K') | « nss/mozilla/security/nss/lib/freebl/rijndael.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698