cmac.c (9962B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifdef FREEBL_NO_DEPEND 6 #include "stubs.h" 7 #endif 8 9 #include "rijndael.h" 10 #include "blapi.h" 11 #include "cmac.h" 12 #include "secerr.h" 13 #include "nspr.h" 14 15 struct CMACContextStr { 16 /* Information about the block cipher to use internally. The cipher should 17 * be placed in ECB mode so that we can use it to directly encrypt blocks. 18 * 19 * 20 * To add a new cipher, add an entry to CMACCipher, update CMAC_Init, 21 * cmac_Encrypt, and CMAC_Destroy methods to handle the new cipher, and 22 * add a new Context pointer to the cipher union with the correct type. */ 23 CMACCipher cipherType; 24 union { 25 AESContext *aes; 26 } cipher; 27 unsigned int blockSize; 28 29 /* Internal keys which are conditionally used by the algorithm. Derived 30 * from encrypting the NULL block. We leave the storing of (and the 31 * cleanup of) the CMAC key to the underlying block cipher. */ 32 unsigned char k1[MAX_BLOCK_SIZE]; 33 unsigned char k2[MAX_BLOCK_SIZE]; 34 35 /* When Update is called with data which isn't a multiple of the block 36 * size, we need a place to put it. HMAC handles this by passing it to 37 * the underlying hash function right away; we can't do that as the 38 * contract on the cipher object is different. */ 39 unsigned int partialIndex; 40 unsigned char partialBlock[MAX_BLOCK_SIZE]; 41 42 /* Last encrypted block. This gets xor-ed with partialBlock prior to 43 * encrypting it. NIST defines this to be the empty string to begin. */ 44 unsigned char lastBlock[MAX_BLOCK_SIZE]; 45 }; 46 47 static void 48 cmac_ShiftLeftOne(unsigned char *out, const unsigned char *in, int length) 49 { 50 int i = 0; 51 for (; i < length - 1; i++) { 52 out[i] = in[i] << 1; 53 out[i] |= in[i + 1] >> 7; 54 } 55 out[i] = in[i] << 1; 56 } 57 58 static SECStatus 59 cmac_Encrypt(CMACContext *ctx, unsigned char *output, 60 const unsigned char *input, 61 unsigned int inputLen) 62 { 63 if (ctx->cipherType == CMAC_AES) { 64 unsigned int tmpOutputLen; 65 SECStatus rv = AES_Encrypt(ctx->cipher.aes, output, &tmpOutputLen, 66 ctx->blockSize, input, inputLen); 67 68 /* Assumption: AES_Encrypt (when in ECB mode) always returns an 69 * output of length equal to blockSize (what was pass as the value 70 * of the maxOutputLen parameter). */ 71 PORT_Assert(tmpOutputLen == ctx->blockSize); 72 return rv; 73 } 74 75 return SECFailure; 76 } 77 78 /* NIST SP.800-38B, 6.1 Subkey Generation */ 79 static SECStatus 80 cmac_GenerateSubkeys(CMACContext *ctx) 81 { 82 unsigned char null_block[MAX_BLOCK_SIZE] = { 0 }; 83 unsigned char L[MAX_BLOCK_SIZE]; 84 unsigned char v; 85 unsigned char i; 86 87 /* Step 1: L = AES(key, null_block) */ 88 if (cmac_Encrypt(ctx, L, null_block, ctx->blockSize) != SECSuccess) { 89 return SECFailure; 90 } 91 92 /* In the following, some effort has been made to be constant time. Rather 93 * than conditioning on the value of the MSB (of L or K1), we use the loop 94 * to build a mask for the conditional constant. */ 95 96 /* Step 2: If MSB(L) = 0, K1 = L << 1. Else, K1 = (L << 1) ^ R_b. */ 97 cmac_ShiftLeftOne(ctx->k1, L, ctx->blockSize); 98 v = L[0] >> 7; 99 for (i = 1; i <= 7; i <<= 1) { 100 v |= (v << i); 101 } 102 ctx->k1[ctx->blockSize - 1] ^= (0x87 & v); 103 104 /* Step 3: If MSB(K1) = 0, K2 = K1 << 1. Else, K2 = (K1 <, 1) ^ R_b. */ 105 cmac_ShiftLeftOne(ctx->k2, ctx->k1, ctx->blockSize); 106 v = ctx->k1[0] >> 7; 107 for (i = 1; i <= 7; i <<= 1) { 108 v |= (v << i); 109 } 110 ctx->k2[ctx->blockSize - 1] ^= (0x87 & v); 111 112 /* Any intermediate value in the computation of the subkey shall be 113 * secret. */ 114 PORT_Memset(null_block, 0, MAX_BLOCK_SIZE); 115 PORT_Memset(L, 0, MAX_BLOCK_SIZE); 116 117 /* Step 4: Return the values. */ 118 return SECSuccess; 119 } 120 121 /* NIST SP.800-38B, 6.2 MAC Generation step 6 */ 122 static SECStatus 123 cmac_UpdateState(CMACContext *ctx) 124 { 125 if (ctx == NULL || ctx->partialIndex != ctx->blockSize) { 126 PORT_SetError(SEC_ERROR_INVALID_ARGS); 127 return SECFailure; 128 } 129 130 /* Step 6: C_i = CIPHER(key, C_{i-1} ^ M_i) for 1 <= i <= n, and 131 * C_0 is defined as the empty string. */ 132 133 for (unsigned int index = 0; index < ctx->blockSize; index++) { 134 ctx->partialBlock[index] ^= ctx->lastBlock[index]; 135 } 136 137 return cmac_Encrypt(ctx, ctx->lastBlock, ctx->partialBlock, ctx->blockSize); 138 } 139 140 SECStatus 141 CMAC_Init(CMACContext *ctx, CMACCipher type, 142 const unsigned char *key, unsigned int key_len) 143 { 144 if (ctx == NULL) { 145 PORT_SetError(SEC_ERROR_NO_MEMORY); 146 return SECFailure; 147 } 148 149 /* We only currently support AES-CMAC. */ 150 if (type != CMAC_AES) { 151 PORT_SetError(SEC_ERROR_INVALID_ARGS); 152 return SECFailure; 153 } 154 155 PORT_Memset(ctx, 0, sizeof(*ctx)); 156 157 ctx->blockSize = AES_BLOCK_SIZE; 158 ctx->cipherType = CMAC_AES; 159 ctx->cipher.aes = AES_CreateContext(key, NULL, NSS_AES, 1, key_len, 160 ctx->blockSize); 161 if (ctx->cipher.aes == NULL) { 162 return SECFailure; 163 } 164 165 return CMAC_Begin(ctx); 166 } 167 168 CMACContext * 169 CMAC_Create(CMACCipher type, const unsigned char *key, 170 unsigned int key_len) 171 { 172 CMACContext *result = PORT_New(CMACContext); 173 174 if (CMAC_Init(result, type, key, key_len) != SECSuccess) { 175 CMAC_Destroy(result, PR_TRUE); 176 return NULL; 177 } 178 179 return result; 180 } 181 182 SECStatus 183 CMAC_Begin(CMACContext *ctx) 184 { 185 if (ctx == NULL) { 186 return SECFailure; 187 } 188 189 /* Ensure that our blockSize is less than the maximum. When this fails, 190 * a cipher with a larger block size was added and MAX_BLOCK_SIZE needs 191 * to be updated accordingly. */ 192 PORT_Assert(ctx->blockSize <= MAX_BLOCK_SIZE); 193 194 if (cmac_GenerateSubkeys(ctx) != SECSuccess) { 195 return SECFailure; 196 } 197 198 /* Set the index to write partial blocks at to zero. This saves us from 199 * having to clear ctx->partialBlock. */ 200 ctx->partialIndex = 0; 201 202 /* Step 5: Let C_0 = 0^b. */ 203 PORT_Memset(ctx->lastBlock, 0, ctx->blockSize); 204 205 return SECSuccess; 206 } 207 208 /* NIST SP.800-38B, 6.2 MAC Generation */ 209 SECStatus 210 CMAC_Update(CMACContext *ctx, const unsigned char *data, 211 unsigned int data_len) 212 { 213 unsigned int data_index = 0; 214 if (ctx == NULL) { 215 PORT_SetError(SEC_ERROR_INVALID_ARGS); 216 return SECFailure; 217 } 218 219 if (data == NULL || data_len == 0) { 220 return SECSuccess; 221 } 222 223 /* Copy as many bytes from data into ctx->partialBlock as we can, up to 224 * the maximum of the remaining data and the remaining space in 225 * ctx->partialBlock. 226 * 227 * Note that we swap the order (encrypt *then* copy) because the last 228 * block is different from the rest. If we end on an even multiple of 229 * the block size, we have to be able to XOR it with K1. But we won't know 230 * that it is the last until CMAC_Finish is called (and by then, CMAC_Update 231 * has already returned). */ 232 while (data_index < data_len) { 233 if (ctx->partialIndex == ctx->blockSize) { 234 if (cmac_UpdateState(ctx) != SECSuccess) { 235 return SECFailure; 236 } 237 238 ctx->partialIndex = 0; 239 } 240 241 unsigned int copy_len = data_len - data_index; 242 if (copy_len > (ctx->blockSize - ctx->partialIndex)) { 243 copy_len = ctx->blockSize - ctx->partialIndex; 244 } 245 246 PORT_Memcpy(ctx->partialBlock + ctx->partialIndex, data + data_index, copy_len); 247 data_index += copy_len; 248 ctx->partialIndex += copy_len; 249 } 250 251 return SECSuccess; 252 } 253 254 /* NIST SP.800-38B, 6.2 MAC Generation */ 255 SECStatus 256 CMAC_Finish(CMACContext *ctx, unsigned char *result, 257 unsigned int *result_len, 258 unsigned int max_result_len) 259 { 260 if (ctx == NULL || result == NULL || max_result_len == 0) { 261 PORT_SetError(SEC_ERROR_INVALID_ARGS); 262 return SECFailure; 263 } 264 265 if (max_result_len > ctx->blockSize) { 266 /* This is a weird situation. The PKCS #11 soft tokencode passes 267 * sizeof(result) here, which is hard-coded as SFTK_MAX_MAC_LENGTH. 268 * This later gets truncated to min(SFTK_MAX_MAC_LENGTH, requested). */ 269 max_result_len = ctx->blockSize; 270 } 271 272 /* Step 4: If M_n* is a complete block, M_n = K1 ^ M_n*. Else, 273 * M_n = K2 ^ (M_n* || 10^j). */ 274 if (ctx->partialIndex == ctx->blockSize) { 275 /* XOR in K1. */ 276 for (unsigned int index = 0; index < ctx->blockSize; index++) { 277 ctx->partialBlock[index] ^= ctx->k1[index]; 278 } 279 } else { 280 /* Use 10* padding on the partial block. */ 281 ctx->partialBlock[ctx->partialIndex++] = 0x80; 282 PORT_Memset(ctx->partialBlock + ctx->partialIndex, 0, 283 ctx->blockSize - ctx->partialIndex); 284 ctx->partialIndex = ctx->blockSize; 285 286 /* XOR in K2. */ 287 for (unsigned int index = 0; index < ctx->blockSize; index++) { 288 ctx->partialBlock[index] ^= ctx->k2[index]; 289 } 290 } 291 292 /* Encrypt the block. */ 293 if (cmac_UpdateState(ctx) != SECSuccess) { 294 return SECFailure; 295 } 296 297 /* Step 7 & 8: T = MSB_tlen(C_n); return T. */ 298 PORT_Memcpy(result, ctx->lastBlock, max_result_len); 299 if (result_len != NULL) { 300 *result_len = max_result_len; 301 } 302 return SECSuccess; 303 } 304 305 void 306 CMAC_Destroy(CMACContext *ctx, PRBool free_it) 307 { 308 if (ctx == NULL) { 309 return; 310 } 311 312 if (ctx->cipherType == CMAC_AES && ctx->cipher.aes != NULL) { 313 AES_DestroyContext(ctx->cipher.aes, PR_TRUE); 314 } 315 316 /* Destroy everything in the context. This includes sensitive data in 317 * K1, K2, and lastBlock. */ 318 PORT_Memset(ctx, 0, sizeof(*ctx)); 319 320 if (free_it == PR_TRUE) { 321 PORT_Free(ctx); 322 } 323 }