diff options
Diffstat (limited to '')
-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); |