1 /*
2 * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 /*
11 * CMAC low level APIs are deprecated for public use, but still ok for internal
12 * use.
13 */
14 #include "internal/deprecated.h"
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19
20 #include "internal/nelem.h"
21
22 #include <openssl/cmac.h>
23 #include <openssl/aes.h>
24 #include <openssl/evp.h>
25
26 #include "testutil.h"
27
28 static const char xtskey[32] = {
29 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
30 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
31 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
32 };
33
34 static struct test_st {
35 const char key[32];
36 int key_len;
37 unsigned char data[4096];
38 int data_len;
39 const char *mac;
40 } test[] = {
41 {
42 {
43 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
44 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
45 },
46 16,
47 "My test data",
48 12,
49 "29cec977c48f63c200bd5c4a6881b224"
50 },
51 {
52 {
53 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
54 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
55 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
56 },
57 32,
58 "My test data",
59 12,
60 "db6493aa04e4761f473b2b453c031c9a"
61 },
62 {
63 {
64 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
65 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
66 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
67 },
68 32,
69 "My test data again",
70 18,
71 "65c11c75ecf590badd0a5e56cbb8af60"
72 },
73 /* for aes-128-cbc */
74 {
75 {
76 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
77 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
78 },
79 16,
80 /* repeat the string below until filling 3072 bytes */
81 "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
82 3072,
83 "35da8a02a7afce90e5b711308cee2dee"
84 },
85 /* for aes-192-cbc */
86 {
87 {
88 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
89 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
90 0x16, 0x17
91 },
92 24,
93 /* repeat the string below until filling 4095 bytes */
94 "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
95 4095,
96 "59053f4e81f3593610f987adb547c5b2"
97 },
98 /* for aes-256-cbc */
99 {
100 {
101 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
102 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
103 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
104 },
105 32,
106 /* repeat the string below until filling 2560 bytes */
107 "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
108 2560,
109 "9c6cf85f7f4baca99725764a0df973a9"
110 },
111 /* for des-ede3-cbc */
112 {
113 {
114 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
115 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
116 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
117 },
118 24,
119 /* repeat the string below until filling 2048 bytes */
120 "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
121 2048,
122 "2c2fccc7fcc5d98a"
123 },
124 /* for sm4-cbc */
125 {
126 {
127 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
128 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
129 },
130 16,
131 /* repeat the string below until filling 2049 bytes */
132 "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
133 2049,
134 "c9a9cbc82a3b2d96074e386fce1216f2"
135 },
136 };
137
138 static char *pt(unsigned char *md, unsigned int len);
139
test_cmac_bad(void)140 static int test_cmac_bad(void)
141 {
142 CMAC_CTX *ctx = NULL;
143 int ret = 0;
144
145 ctx = CMAC_CTX_new();
146 if (!TEST_ptr(ctx)
147 || !TEST_false(CMAC_Init(ctx, NULL, 0, NULL, NULL))
148 || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len))
149 /* Should be able to pass cipher first, and then key */
150 || !TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_128_cbc(), NULL))
151 /* Must have a key */
152 || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len))
153 /* Now supply the key */
154 || !TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, NULL, NULL))
155 /* Update should now work */
156 || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len))
157 /* XTS is not a suitable cipher to use */
158 || !TEST_false(CMAC_Init(ctx, xtskey, sizeof(xtskey), EVP_aes_128_xts(),
159 NULL))
160 || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len)))
161 goto err;
162
163 ret = 1;
164 err:
165 CMAC_CTX_free(ctx);
166 return ret;
167 }
168
test_cmac_run(void)169 static int test_cmac_run(void)
170 {
171 char *p;
172 CMAC_CTX *ctx = NULL;
173 unsigned char buf[AES_BLOCK_SIZE];
174 size_t len;
175 int ret = 0;
176 size_t case_idx = 0;
177
178 ctx = CMAC_CTX_new();
179
180 /* Construct input data, fill repeatedly until reaching data length */
181 for (case_idx = 0; case_idx < OSSL_NELEM(test); case_idx++) {
182 size_t str_len = strlen((char *)test[case_idx].data);
183 size_t fill_len = test[case_idx].data_len - str_len;
184 size_t fill_idx = str_len;
185 while (fill_len > 0) {
186 if (fill_len > str_len) {
187 memcpy(&test[case_idx].data[fill_idx], test[case_idx].data, str_len);
188 fill_len -= str_len;
189 fill_idx += str_len;
190 } else {
191 memcpy(&test[case_idx].data[fill_idx], test[case_idx].data, fill_len);
192 fill_len = 0;
193 }
194 }
195 }
196
197 if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len,
198 EVP_aes_128_cbc(), NULL))
199 || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len))
200 || !TEST_true(CMAC_Final(ctx, buf, &len)))
201 goto err;
202
203 p = pt(buf, len);
204 if (!TEST_str_eq(p, test[0].mac))
205 goto err;
206
207 if (!TEST_true(CMAC_Init(ctx, test[1].key, test[1].key_len,
208 EVP_aes_256_cbc(), NULL))
209 || !TEST_true(CMAC_Update(ctx, test[1].data, test[1].data_len))
210 || !TEST_true(CMAC_Final(ctx, buf, &len)))
211 goto err;
212
213 p = pt(buf, len);
214 if (!TEST_str_eq(p, test[1].mac))
215 goto err;
216
217 if (!TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL))
218 || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len))
219 || !TEST_true(CMAC_Final(ctx, buf, &len)))
220 goto err;
221 p = pt(buf, len);
222 if (!TEST_str_eq(p, test[2].mac))
223 goto err;
224 /* Test reusing a key */
225 if (!TEST_true(CMAC_Init(ctx, NULL, 0, NULL, NULL))
226 || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len))
227 || !TEST_true(CMAC_Final(ctx, buf, &len)))
228 goto err;
229 p = pt(buf, len);
230 if (!TEST_str_eq(p, test[2].mac))
231 goto err;
232
233 /* Test setting the cipher and key separately */
234 if (!TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_256_cbc(), NULL))
235 || !TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL))
236 || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len))
237 || !TEST_true(CMAC_Final(ctx, buf, &len)))
238 goto err;
239 p = pt(buf, len);
240 if (!TEST_str_eq(p, test[2].mac))
241 goto err;
242
243 /* Test data length is greater than 1 block length */
244 if (!TEST_true(CMAC_Init(ctx, test[3].key, test[3].key_len,
245 EVP_aes_128_cbc(), NULL))
246 || !TEST_true(CMAC_Update(ctx, test[3].data, test[3].data_len))
247 || !TEST_true(CMAC_Final(ctx, buf, &len)))
248 goto err;
249 p = pt(buf, len);
250 if (!TEST_str_eq(p, test[3].mac))
251 goto err;
252
253 if (!TEST_true(CMAC_Init(ctx, test[4].key, test[4].key_len,
254 EVP_aes_192_cbc(), NULL))
255 || !TEST_true(CMAC_Update(ctx, test[4].data, test[4].data_len))
256 || !TEST_true(CMAC_Final(ctx, buf, &len)))
257 goto err;
258 p = pt(buf, len);
259 if (!TEST_str_eq(p, test[4].mac))
260 goto err;
261
262 if (!TEST_true(CMAC_Init(ctx, test[5].key, test[5].key_len,
263 EVP_aes_256_cbc(), NULL))
264 || !TEST_true(CMAC_Update(ctx, test[5].data, test[5].data_len))
265 || !TEST_true(CMAC_Final(ctx, buf, &len)))
266 goto err;
267 p = pt(buf, len);
268 if (!TEST_str_eq(p, test[5].mac))
269 goto err;
270
271 #ifndef OPENSSL_NO_DES
272 if (!TEST_true(CMAC_Init(ctx, test[6].key, test[6].key_len,
273 EVP_des_ede3_cbc(), NULL))
274 || !TEST_true(CMAC_Update(ctx, test[6].data, test[6].data_len))
275 || !TEST_true(CMAC_Final(ctx, buf, &len)))
276 goto err;
277 p = pt(buf, len);
278 if (!TEST_str_eq(p, test[6].mac))
279 goto err;
280 #endif
281
282 #ifndef OPENSSL_NO_SM4
283 if (!TEST_true(CMAC_Init(ctx, test[7].key, test[7].key_len,
284 EVP_sm4_cbc(), NULL))
285 || !TEST_true(CMAC_Update(ctx, test[7].data, test[7].data_len))
286 || !TEST_true(CMAC_Final(ctx, buf, &len)))
287 goto err;
288 p = pt(buf, len);
289 if (!TEST_str_eq(p, test[7].mac))
290 goto err;
291 #endif
292
293 ret = 1;
294 err:
295 CMAC_CTX_free(ctx);
296 return ret;
297 }
298
test_cmac_copy(void)299 static int test_cmac_copy(void)
300 {
301 char *p;
302 CMAC_CTX *ctx = NULL, *ctx2 = NULL;
303 unsigned char buf[AES_BLOCK_SIZE];
304 size_t len;
305 int ret = 0;
306
307 ctx = CMAC_CTX_new();
308 ctx2 = CMAC_CTX_new();
309 if (!TEST_ptr(ctx) || !TEST_ptr(ctx2))
310 goto err;
311
312 if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len,
313 EVP_aes_128_cbc(), NULL))
314 || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len))
315 || !TEST_true(CMAC_CTX_copy(ctx2, ctx))
316 || !TEST_true(CMAC_Final(ctx2, buf, &len)))
317 goto err;
318
319 p = pt(buf, len);
320 if (!TEST_str_eq(p, test[0].mac))
321 goto err;
322
323 ret = 1;
324 err:
325 CMAC_CTX_free(ctx2);
326 CMAC_CTX_free(ctx);
327 return ret;
328 }
329
330 #define OSSL_HEX_CHARS_PER_BYTE 2
pt(unsigned char * md,unsigned int len)331 static char *pt(unsigned char *md, unsigned int len)
332 {
333 unsigned int i;
334 static char buf[81];
335
336 for (i = 0; i < len && (i + 1) * OSSL_HEX_CHARS_PER_BYTE < sizeof(buf); i++)
337 BIO_snprintf(buf + i * OSSL_HEX_CHARS_PER_BYTE,
338 OSSL_HEX_CHARS_PER_BYTE + 1, "%02x", md[i]);
339 return buf;
340 }
341
setup_tests(void)342 int setup_tests(void)
343 {
344 ADD_TEST(test_cmac_bad);
345 ADD_TEST(test_cmac_run);
346 ADD_TEST(test_cmac_copy);
347 return 1;
348 }
349
350