1 /* $OpenBSD: cmac.c,v 1.24 2024/05/20 14:53:37 tb Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5 /* ====================================================================
6 * Copyright (c) 2010 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 */
53
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57
58 #include <openssl/cmac.h>
59
60 #include "evp_local.h"
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 */
70 struct CMAC_CTX_st {
71 EVP_CIPHER_CTX *cipher_ctx;
72 unsigned char k1[EVP_MAX_BLOCK_LENGTH];
73 unsigned char k2[EVP_MAX_BLOCK_LENGTH];
74 unsigned char tbl[EVP_MAX_BLOCK_LENGTH];
75 unsigned char last_block[EVP_MAX_BLOCK_LENGTH];
76 /* Bytes in last block. -1 means not initialized. */
77 int nlast_block;
78 };
79
80 /*
81 * SP 800-38B, section 6.1, steps 2 and 3: given the input key l, calculate
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 */
92 static void
make_kn(unsigned char * kn,const unsigned char * l,int block_size)93 make_kn(unsigned char *kn, const unsigned char *l, int block_size)
94 {
95 unsigned char mask, Rb;
96 int i;
97
98 /* Choose Rb according to the block size in bytes. */
99 Rb = block_size == 16 ? 0x87 : 0x1b;
100
101 /* Compute l << 1 up to last byte. */
102 for (i = 0; i < block_size - 1; i++)
103 kn[i] = (l[i] << 1) | (l[i + 1] >> 7);
104
105 /* Only xor with Rb if the MSB is one. */
106 mask = 0 - (l[0] >> 7);
107 kn[block_size - 1] = (l[block_size - 1] << 1) ^ (Rb & mask);
108 }
109
110 CMAC_CTX *
CMAC_CTX_new(void)111 CMAC_CTX_new(void)
112 {
113 CMAC_CTX *ctx;
114
115 if ((ctx = calloc(1, sizeof(CMAC_CTX))) == NULL)
116 goto err;
117 if ((ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL)
118 goto err;
119
120 ctx->nlast_block = -1;
121
122 return ctx;
123
124 err:
125 CMAC_CTX_free(ctx);
126
127 return NULL;
128 }
129 LCRYPTO_ALIAS(CMAC_CTX_new);
130
131 void
CMAC_CTX_cleanup(CMAC_CTX * ctx)132 CMAC_CTX_cleanup(CMAC_CTX *ctx)
133 {
134 (void)EVP_CIPHER_CTX_reset(ctx->cipher_ctx);
135 explicit_bzero(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
136 explicit_bzero(ctx->k1, EVP_MAX_BLOCK_LENGTH);
137 explicit_bzero(ctx->k2, EVP_MAX_BLOCK_LENGTH);
138 explicit_bzero(ctx->last_block, EVP_MAX_BLOCK_LENGTH);
139 ctx->nlast_block = -1;
140 }
141 LCRYPTO_ALIAS(CMAC_CTX_cleanup);
142
143 EVP_CIPHER_CTX *
CMAC_CTX_get0_cipher_ctx(CMAC_CTX * ctx)144 CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)
145 {
146 return ctx->cipher_ctx;
147 }
148 LCRYPTO_ALIAS(CMAC_CTX_get0_cipher_ctx);
149
150 void
CMAC_CTX_free(CMAC_CTX * ctx)151 CMAC_CTX_free(CMAC_CTX *ctx)
152 {
153 if (ctx == NULL)
154 return;
155
156 CMAC_CTX_cleanup(ctx);
157 EVP_CIPHER_CTX_free(ctx->cipher_ctx);
158 freezero(ctx, sizeof(CMAC_CTX));
159 }
160 LCRYPTO_ALIAS(CMAC_CTX_free);
161
162 int
CMAC_CTX_copy(CMAC_CTX * out,const CMAC_CTX * in)163 CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
164 {
165 int block_size;
166
167 if (in->nlast_block == -1)
168 return 0;
169 if (!EVP_CIPHER_CTX_copy(out->cipher_ctx, in->cipher_ctx))
170 return 0;
171 block_size = EVP_CIPHER_CTX_block_size(in->cipher_ctx);
172 memcpy(out->k1, in->k1, block_size);
173 memcpy(out->k2, in->k2, block_size);
174 memcpy(out->tbl, in->tbl, block_size);
175 memcpy(out->last_block, in->last_block, block_size);
176 out->nlast_block = in->nlast_block;
177 return 1;
178 }
179 LCRYPTO_ALIAS(CMAC_CTX_copy);
180
181 int
CMAC_Init(CMAC_CTX * ctx,const void * key,size_t keylen,const EVP_CIPHER * cipher,ENGINE * impl)182 CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
183 const EVP_CIPHER *cipher, ENGINE *impl)
184 {
185 static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH];
186 int block_size;
187
188 /* All zeros means restart */
189 if (key == NULL && cipher == NULL && keylen == 0) {
190 /* Not initialised */
191 if (ctx->nlast_block == -1)
192 return 0;
193 if (!EVP_EncryptInit_ex(ctx->cipher_ctx, NULL, NULL, NULL, zero_iv))
194 return 0;
195 explicit_bzero(ctx->tbl, sizeof(ctx->tbl));
196 ctx->nlast_block = 0;
197 return 1;
198 }
199
200 /* Initialise context. */
201 if (cipher != NULL) {
202 /*
203 * Disallow ciphers for which EVP_Cipher() behaves differently.
204 * These are AEAD ciphers (or AES keywrap) for which the CMAC
205 * construction makes little sense.
206 */
207 if ((cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0)
208 return 0;
209 if (!EVP_EncryptInit_ex(ctx->cipher_ctx, cipher, NULL, NULL, NULL))
210 return 0;
211 }
212
213 /* Non-NULL key means initialisation is complete. */
214 if (key != NULL) {
215 if (EVP_CIPHER_CTX_cipher(ctx->cipher_ctx) == NULL)
216 return 0;
217
218 /* make_kn() only supports block sizes of 8 and 16 bytes. */
219 block_size = EVP_CIPHER_CTX_block_size(ctx->cipher_ctx);
220 if (block_size != 8 && block_size != 16)
221 return 0;
222
223 /*
224 * Section 6.1, step 1: store the intermediate secret CIPH_K(0)
225 * in ctx->tbl.
226 */
227 if (!EVP_CIPHER_CTX_set_key_length(ctx->cipher_ctx, keylen))
228 return 0;
229 if (!EVP_EncryptInit_ex(ctx->cipher_ctx, NULL, NULL, key, zero_iv))
230 return 0;
231 if (!EVP_Cipher(ctx->cipher_ctx, ctx->tbl, zero_iv, block_size))
232 return 0;
233
234 /* Section 6.1, step 2: compute k1 from intermediate secret. */
235 make_kn(ctx->k1, ctx->tbl, block_size);
236 /* Section 6.1, step 3: compute k2 from k1. */
237 make_kn(ctx->k2, ctx->k1, block_size);
238
239 /* Destroy intermediate secret and reset last block count. */
240 explicit_bzero(ctx->tbl, sizeof(ctx->tbl));
241 ctx->nlast_block = 0;
242
243 /* Reset context again to get ready for the first data block. */
244 if (!EVP_EncryptInit_ex(ctx->cipher_ctx, NULL, NULL, NULL, zero_iv))
245 return 0;
246 }
247
248 return 1;
249 }
250 LCRYPTO_ALIAS(CMAC_Init);
251
252 int
CMAC_Update(CMAC_CTX * ctx,const void * in,size_t dlen)253 CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
254 {
255 const unsigned char *data = in;
256 size_t block_size;
257
258 if (ctx->nlast_block == -1)
259 return 0;
260 if (dlen == 0)
261 return 1;
262 block_size = EVP_CIPHER_CTX_block_size(ctx->cipher_ctx);
263 /* Copy into partial block if we need to */
264 if (ctx->nlast_block > 0) {
265 size_t nleft;
266
267 nleft = block_size - ctx->nlast_block;
268 if (dlen < nleft)
269 nleft = dlen;
270 memcpy(ctx->last_block + ctx->nlast_block, data, nleft);
271 dlen -= nleft;
272 ctx->nlast_block += nleft;
273 /* If no more to process return */
274 if (dlen == 0)
275 return 1;
276 data += nleft;
277 /* Else not final block so encrypt it */
278 if (!EVP_Cipher(ctx->cipher_ctx, ctx->tbl, ctx->last_block,
279 block_size))
280 return 0;
281 }
282 /* Encrypt all but one of the complete blocks left */
283 while (dlen > block_size) {
284 if (!EVP_Cipher(ctx->cipher_ctx, ctx->tbl, data, block_size))
285 return 0;
286 dlen -= block_size;
287 data += block_size;
288 }
289 /* Copy any data left to last block buffer */
290 memcpy(ctx->last_block, data, dlen);
291 ctx->nlast_block = dlen;
292 return 1;
293 }
294 LCRYPTO_ALIAS(CMAC_Update);
295
296 int
CMAC_Final(CMAC_CTX * ctx,unsigned char * out,size_t * poutlen)297 CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
298 {
299 int i, block_size, lb;
300
301 if (ctx->nlast_block == -1)
302 return 0;
303 block_size = EVP_CIPHER_CTX_block_size(ctx->cipher_ctx);
304 *poutlen = (size_t)block_size;
305 if (!out)
306 return 1;
307 lb = ctx->nlast_block;
308 /* Is last block complete? */
309 if (lb == block_size) {
310 for (i = 0; i < block_size; i++)
311 out[i] = ctx->last_block[i] ^ ctx->k1[i];
312 } else {
313 ctx->last_block[lb] = 0x80;
314 if (block_size - lb > 1)
315 memset(ctx->last_block + lb + 1, 0, block_size - lb - 1);
316 for (i = 0; i < block_size; i++)
317 out[i] = ctx->last_block[i] ^ ctx->k2[i];
318 }
319 if (!EVP_Cipher(ctx->cipher_ctx, out, out, block_size)) {
320 explicit_bzero(out, block_size);
321 return 0;
322 }
323 return 1;
324 }
325 LCRYPTO_ALIAS(CMAC_Final);
326