]>
Commit | Line | Data |
---|---|---|
a370ff8d | 1 | /* |
fd54fadb | 2 | * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. |
a370ff8d MC |
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; | |
e8dc77f8 | 37 | unsigned char data[4096]; |
a370ff8d MC |
38 | int data_len; |
39 | const char *mac; | |
fbff5b57 | 40 | } test[] = { |
a370ff8d MC |
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 | }, | |
fd54fadb | 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, | |
6ea4da6e | 80 | /* repeat the string below until filling 3072 bytes */ |
fd54fadb | 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, | |
6ea4da6e | 93 | /* repeat the string below until filling 4095 bytes */ |
e8dc77f8 | 94 | "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#", |
fd54fadb | 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, | |
6ea4da6e | 106 | /* repeat the string below until filling 2560 bytes */ |
fd54fadb | 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, | |
6ea4da6e | 119 | /* repeat the string below until filling 2048 bytes */ |
fd54fadb | 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, | |
6ea4da6e | 131 | /* repeat the string below until filling 2049 bytes */ |
e8dc77f8 | 132 | "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#", |
fd54fadb | 133 | 2049, |
134 | "c9a9cbc82a3b2d96074e386fce1216f2" | |
135 | }, | |
a370ff8d MC |
136 | }; |
137 | ||
138 | static char *pt(unsigned char *md, unsigned int len); | |
139 | ||
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 | ||
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; | |
fbff5b57 | 176 | size_t case_idx = 0; |
a370ff8d MC |
177 | |
178 | ctx = CMAC_CTX_new(); | |
179 | ||
6ea4da6e | 180 | /* Construct input data, fill repeatedly until reaching data length */ |
fbff5b57 | 181 | for (case_idx = 0; case_idx < OSSL_NELEM(test); case_idx++) { |
e8dc77f8 | 182 | size_t str_len = strlen((char *)test[case_idx].data); |
6ea4da6e DP |
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; | |
e8dc77f8 | 190 | } else { |
6ea4da6e DP |
191 | memcpy(&test[case_idx].data[fill_idx], test[case_idx].data, fill_len); |
192 | fill_len = 0; | |
e8dc77f8 | 193 | } |
194 | } | |
195 | } | |
196 | ||
a370ff8d MC |
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 | ||
fd54fadb | 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 | ||
fbff5b57 | 271 | #ifndef OPENSSL_NO_DES |
fd54fadb | 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; | |
fbff5b57 | 280 | #endif |
fd54fadb | 281 | |
fbff5b57 | 282 | #ifndef OPENSSL_NO_SM4 |
fd54fadb | 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; | |
fbff5b57 | 291 | #endif |
fd54fadb | 292 | |
a370ff8d MC |
293 | ret = 1; |
294 | err: | |
295 | CMAC_CTX_free(ctx); | |
296 | return ret; | |
297 | } | |
298 | ||
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 | static char *pt(unsigned char *md, unsigned int len) | |
331 | { | |
332 | unsigned int i; | |
333 | static char buf[80]; | |
334 | ||
335 | for (i = 0; i < len; i++) | |
336 | sprintf(&(buf[i * 2]), "%02x", md[i]); | |
337 | return buf; | |
338 | } | |
339 | ||
340 | int setup_tests(void) | |
341 | { | |
342 | ADD_TEST(test_cmac_bad); | |
343 | ADD_TEST(test_cmac_run); | |
344 | ADD_TEST(test_cmac_copy); | |
345 | return 1; | |
346 | } | |
347 |