diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/cmac/cmac.c | 100 |
1 files changed, 66 insertions, 34 deletions
diff --git a/src/lib/libcrypto/cmac/cmac.c b/src/lib/libcrypto/cmac/cmac.c index 9c05a98e15..f5b5f5e320 100644 --- a/src/lib/libcrypto/cmac/cmac.c +++ b/src/lib/libcrypto/cmac/cmac.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: cmac.c,v 1.14 2023/07/08 14:27:14 beck Exp $ */ | 1 | /* $OpenBSD: cmac.c,v 1.15 2023/11/29 18:11:10 tb Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project. | 3 | * project. |
| 4 | */ | 4 | */ |
| @@ -59,37 +59,52 @@ | |||
| 59 | 59 | ||
| 60 | #include "evp_local.h" | 60 | #include "evp_local.h" |
| 61 | 61 | ||
| 62 | /* | ||
| 63 | * This implementation follows https://doi.org/10.6028/NIST.SP.800-38B | ||
| 64 | */ | ||
| 65 | |||
| 66 | /* | ||
| 67 | * CMAC context. k1 and k2 are the secret subkeys, computed as in section 6.1. | ||
| 68 | * The temporary block tbl is a scratch buffer that holds intermediate secrets. | ||
| 69 | */ | ||
| 62 | struct CMAC_CTX_st { | 70 | struct CMAC_CTX_st { |
| 63 | /* Cipher context to use */ | ||
| 64 | EVP_CIPHER_CTX cctx; | 71 | EVP_CIPHER_CTX cctx; |
| 65 | /* Keys k1 and k2 */ | ||
| 66 | unsigned char k1[EVP_MAX_BLOCK_LENGTH]; | 72 | unsigned char k1[EVP_MAX_BLOCK_LENGTH]; |
| 67 | unsigned char k2[EVP_MAX_BLOCK_LENGTH]; | 73 | unsigned char k2[EVP_MAX_BLOCK_LENGTH]; |
| 68 | /* Temporary block */ | ||
| 69 | unsigned char tbl[EVP_MAX_BLOCK_LENGTH]; | 74 | unsigned char tbl[EVP_MAX_BLOCK_LENGTH]; |
| 70 | /* Last (possibly partial) block */ | ||
| 71 | unsigned char last_block[EVP_MAX_BLOCK_LENGTH]; | 75 | unsigned char last_block[EVP_MAX_BLOCK_LENGTH]; |
| 72 | /* Number of bytes in last block: -1 means context not initialised */ | 76 | /* Bytes in last block. -1 means not initialized. */ |
| 73 | int nlast_block; | 77 | int nlast_block; |
| 74 | }; | 78 | }; |
| 75 | 79 | ||
| 76 | 80 | /* | |
| 77 | /* Make temporary keys K1 and K2 */ | 81 | * SP 800-38B, section 6.1, steps 2 and 3: given the input key l, calculate |
| 78 | 82 | * the subkeys k1 and k2: shift l one bit to the left. If the most significant | |
| 83 | * bit of l was 1, additionally xor the result with Rb to get kn. | ||
| 84 | * | ||
| 85 | * Step 2: calculate k1 with l being the intermediate block CIPH_K(0), | ||
| 86 | * Step 3: calculate k2 from l == k1. | ||
| 87 | * | ||
| 88 | * Per 5.3, Rb is the lexically first irreducible polynomial of degree b with | ||
| 89 | * the minimum number of non-zero terms. This gives R128 = (1 << 128) | 0x87 | ||
| 90 | * and R64 = (1 << 64) | 0x1b for the only supported block sizes 128 and 64. | ||
| 91 | */ | ||
| 79 | static void | 92 | static void |
| 80 | make_kn(unsigned char *k1, unsigned char *l, int bl) | 93 | make_kn(unsigned char *kn, const unsigned char *l, int bl) |
| 81 | { | 94 | { |
| 95 | unsigned char mask, Rb; | ||
| 82 | int i; | 96 | int i; |
| 83 | 97 | ||
| 84 | /* Shift block to left, including carry */ | 98 | /* Choose Rb according to the block size in bytes. */ |
| 85 | for (i = 0; i < bl; i++) { | 99 | Rb = bl == 16 ? 0x87 : 0x1b; |
| 86 | k1[i] = l[i] << 1; | 100 | |
| 87 | if (i < bl - 1 && l[i + 1] & 0x80) | 101 | /* Compute l << 1 up to last byte. */ |
| 88 | k1[i] |= 1; | 102 | for (i = 0; i < bl - 1; i++) |
| 89 | } | 103 | kn[i] = (l[i] << 1) | (l[i + 1] >> 7); |
| 90 | /* If MSB set fixup with R */ | 104 | |
| 91 | if (l[0] & 0x80) | 105 | /* Only xor with Rb if the MSB is one. */ |
| 92 | k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b; | 106 | mask = 0 - (l[0] >> 7); |
| 107 | kn[bl - 1] = (l[bl - 1] << 1) ^ (Rb & mask); | ||
| 93 | } | 108 | } |
| 94 | 109 | ||
| 95 | CMAC_CTX * | 110 | CMAC_CTX * |
| @@ -160,44 +175,61 @@ CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, | |||
| 160 | const EVP_CIPHER *cipher, ENGINE *impl) | 175 | const EVP_CIPHER *cipher, ENGINE *impl) |
| 161 | { | 176 | { |
| 162 | static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH]; | 177 | static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH]; |
| 178 | int bl; | ||
| 163 | 179 | ||
| 164 | /* All zeros means restart */ | 180 | /* All zeros means restart */ |
| 165 | if (!key && !cipher && !impl && keylen == 0) { | 181 | if (key == NULL && cipher == NULL && impl == NULL && keylen == 0) { |
| 166 | /* Not initialised */ | 182 | /* Not initialised */ |
| 167 | if (ctx->nlast_block == -1) | 183 | if (ctx->nlast_block == -1) |
| 168 | return 0; | 184 | return 0; |
| 169 | if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) | 185 | if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) |
| 170 | return 0; | 186 | return 0; |
| 171 | memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx)); | 187 | explicit_bzero(ctx->tbl, sizeof(ctx->tbl)); |
| 172 | ctx->nlast_block = 0; | 188 | ctx->nlast_block = 0; |
| 173 | return 1; | 189 | return 1; |
| 174 | } | 190 | } |
| 175 | /* Initialise context */ | ||
| 176 | if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL)) | ||
| 177 | return 0; | ||
| 178 | /* Non-NULL key means initialisation complete */ | ||
| 179 | if (key) { | ||
| 180 | int bl; | ||
| 181 | 191 | ||
| 182 | if (!EVP_CIPHER_CTX_cipher(&ctx->cctx)) | 192 | /* Initialise context. */ |
| 193 | if (cipher != NULL) { | ||
| 194 | if (!EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL)) | ||
| 183 | return 0; | 195 | return 0; |
| 196 | } | ||
| 197 | |||
| 198 | /* Non-NULL key means initialisation is complete. */ | ||
| 199 | if (key != NULL) { | ||
| 200 | if (EVP_CIPHER_CTX_cipher(&ctx->cctx) == NULL) | ||
| 201 | return 0; | ||
| 202 | |||
| 203 | /* make_kn() only supports block sizes of 8 and 16 bytes. */ | ||
| 204 | bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); | ||
| 205 | if (bl != 8 && bl != 16) | ||
| 206 | return 0; | ||
| 207 | |||
| 208 | /* | ||
| 209 | * Section 6.1, step 1: store the intermediate secret CIPH_K(0) | ||
| 210 | * in ctx->tbl. | ||
| 211 | */ | ||
| 184 | if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen)) | 212 | if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen)) |
| 185 | return 0; | 213 | return 0; |
| 186 | if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv)) | 214 | if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv)) |
| 187 | return 0; | 215 | return 0; |
| 188 | bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); | ||
| 189 | if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl)) | 216 | if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl)) |
| 190 | return 0; | 217 | return 0; |
| 218 | |||
| 219 | /* Section 6.1, step 2: compute k1 from intermediate secret. */ | ||
| 191 | make_kn(ctx->k1, ctx->tbl, bl); | 220 | make_kn(ctx->k1, ctx->tbl, bl); |
| 221 | /* Section 6.1, step 3: compute k2 from k1. */ | ||
| 192 | make_kn(ctx->k2, ctx->k1, bl); | 222 | make_kn(ctx->k2, ctx->k1, bl); |
| 193 | explicit_bzero(ctx->tbl, bl); | 223 | |
| 194 | /* Reset context again ready for first data block */ | 224 | /* Destroy intermediate secret and reset last block count. */ |
| 225 | explicit_bzero(ctx->tbl, sizeof(ctx->tbl)); | ||
| 226 | ctx->nlast_block = 0; | ||
| 227 | |||
| 228 | /* Reset context again to get ready for the first data block. */ | ||
| 195 | if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) | 229 | if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) |
| 196 | return 0; | 230 | return 0; |
| 197 | /* Zero tbl so resume works */ | ||
| 198 | memset(ctx->tbl, 0, bl); | ||
| 199 | ctx->nlast_block = 0; | ||
| 200 | } | 231 | } |
| 232 | |||
| 201 | return 1; | 233 | return 1; |
| 202 | } | 234 | } |
| 203 | LCRYPTO_ALIAS(CMAC_Init); | 235 | LCRYPTO_ALIAS(CMAC_Init); |
