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