/src/mbedtls/library/cmac.c
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * \file cmac.c |
3 | | * |
4 | | * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES |
5 | | * |
6 | | * Copyright The Mbed TLS Contributors |
7 | | * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later |
8 | | */ |
9 | | |
10 | | /* |
11 | | * References: |
12 | | * |
13 | | * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The |
14 | | * CMAC Mode for Authentication |
15 | | * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf |
16 | | * |
17 | | * - RFC 4493 - The AES-CMAC Algorithm |
18 | | * https://tools.ietf.org/html/rfc4493 |
19 | | * |
20 | | * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message |
21 | | * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128) |
22 | | * Algorithm for the Internet Key Exchange Protocol (IKE) |
23 | | * https://tools.ietf.org/html/rfc4615 |
24 | | * |
25 | | * Additional test vectors: ISO/IEC 9797-1 |
26 | | * |
27 | | */ |
28 | | |
29 | | #include "common.h" |
30 | | |
31 | | #if defined(MBEDTLS_CMAC_C) |
32 | | |
33 | | #include "mbedtls/cmac.h" |
34 | | #include "mbedtls/platform_util.h" |
35 | | #include "mbedtls/error.h" |
36 | | #include "mbedtls/platform.h" |
37 | | #include "constant_time_internal.h" |
38 | | |
39 | | #include <string.h> |
40 | | |
41 | | #if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) |
42 | | |
43 | | /* |
44 | | * Multiplication by u in the Galois field of GF(2^n) |
45 | | * |
46 | | * As explained in NIST SP 800-38B, this can be computed: |
47 | | * |
48 | | * If MSB(p) = 0, then p = (p << 1) |
49 | | * If MSB(p) = 1, then p = (p << 1) ^ R_n |
50 | | * with R_64 = 0x1B and R_128 = 0x87 |
51 | | * |
52 | | * Input and output MUST NOT point to the same buffer |
53 | | * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES. |
54 | | */ |
55 | | static int cmac_multiply_by_u(unsigned char *output, |
56 | | const unsigned char *input, |
57 | | size_t blocksize) |
58 | 4 | { |
59 | 4 | const unsigned char R_128 = 0x87; |
60 | 4 | unsigned char R_n; |
61 | 4 | uint32_t overflow = 0x00; |
62 | 4 | int i; |
63 | | |
64 | 4 | if (blocksize == MBEDTLS_AES_BLOCK_SIZE) { |
65 | 4 | R_n = R_128; |
66 | 4 | } |
67 | 0 | #if defined(MBEDTLS_DES_C) |
68 | 0 | else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) { |
69 | 0 | const unsigned char R_64 = 0x1B; |
70 | 0 | R_n = R_64; |
71 | 0 | } |
72 | 0 | #endif |
73 | 0 | else { |
74 | 0 | return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
75 | 0 | } |
76 | | |
77 | 20 | for (i = (int) blocksize - 4; i >= 0; i -= 4) { |
78 | 16 | uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0); |
79 | 16 | uint32_t new_overflow = i32 >> 31; |
80 | 16 | i32 = (i32 << 1) | overflow; |
81 | 16 | MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0); |
82 | 16 | overflow = new_overflow; |
83 | 16 | } |
84 | | |
85 | 4 | R_n = (unsigned char) mbedtls_ct_uint_if_else_0(mbedtls_ct_bool(input[0] >> 7), R_n); |
86 | 4 | output[blocksize - 1] ^= R_n; |
87 | | |
88 | 4 | return 0; |
89 | 4 | } |
90 | | |
91 | | /* |
92 | | * Generate subkeys |
93 | | * |
94 | | * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm |
95 | | */ |
96 | | static int cmac_generate_subkeys(mbedtls_cipher_context_t *ctx, |
97 | | unsigned char *K1, unsigned char *K2) |
98 | 2 | { |
99 | 2 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
100 | 2 | unsigned char L[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; |
101 | 2 | size_t olen, block_size; |
102 | | |
103 | 2 | mbedtls_platform_zeroize(L, sizeof(L)); |
104 | | |
105 | 2 | block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info); |
106 | | |
107 | | /* Calculate Ek(0) */ |
108 | 2 | if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) { |
109 | 0 | goto exit; |
110 | 0 | } |
111 | | |
112 | | /* |
113 | | * Generate K1 and K2 |
114 | | */ |
115 | 2 | if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) { |
116 | 0 | goto exit; |
117 | 0 | } |
118 | | |
119 | 2 | if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) { |
120 | 0 | goto exit; |
121 | 0 | } |
122 | | |
123 | 2 | exit: |
124 | 2 | mbedtls_platform_zeroize(L, sizeof(L)); |
125 | | |
126 | 2 | return ret; |
127 | 2 | } |
128 | | #endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */ |
129 | | |
130 | | #if !defined(MBEDTLS_CMAC_ALT) |
131 | | |
132 | | /* |
133 | | * Create padded last block from (partial) last block. |
134 | | * |
135 | | * We can't use the padding option from the cipher layer, as it only works for |
136 | | * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition. |
137 | | */ |
138 | | static void cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE], |
139 | | size_t padded_block_len, |
140 | | const unsigned char *last_block, |
141 | | size_t last_block_len) |
142 | 2 | { |
143 | 2 | size_t j; |
144 | | |
145 | 34 | for (j = 0; j < padded_block_len; j++) { |
146 | 32 | if (j < last_block_len) { |
147 | 6 | padded_block[j] = last_block[j]; |
148 | 26 | } else if (j == last_block_len) { |
149 | 2 | padded_block[j] = 0x80; |
150 | 24 | } else { |
151 | 24 | padded_block[j] = 0x00; |
152 | 24 | } |
153 | 32 | } |
154 | 2 | } |
155 | | |
156 | | int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx, |
157 | | const unsigned char *key, size_t keybits) |
158 | 2 | { |
159 | 2 | mbedtls_cipher_type_t type; |
160 | 2 | mbedtls_cmac_context_t *cmac_ctx; |
161 | 2 | int retval; |
162 | | |
163 | 2 | if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) { |
164 | 0 | return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
165 | 0 | } |
166 | | |
167 | 2 | if ((retval = mbedtls_cipher_setkey(ctx, key, (int) keybits, |
168 | 2 | MBEDTLS_ENCRYPT)) != 0) { |
169 | 0 | return retval; |
170 | 0 | } |
171 | | |
172 | 2 | type = mbedtls_cipher_info_get_type(ctx->cipher_info); |
173 | | |
174 | 2 | switch (type) { |
175 | 0 | case MBEDTLS_CIPHER_AES_128_ECB: |
176 | 2 | case MBEDTLS_CIPHER_AES_192_ECB: |
177 | 2 | case MBEDTLS_CIPHER_AES_256_ECB: |
178 | 2 | case MBEDTLS_CIPHER_DES_EDE3_ECB: |
179 | 2 | break; |
180 | 0 | default: |
181 | 0 | return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
182 | 2 | } |
183 | | |
184 | | /* Allocated and initialise in the cipher context memory for the CMAC |
185 | | * context */ |
186 | 2 | cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t)); |
187 | 2 | if (cmac_ctx == NULL) { |
188 | 0 | return MBEDTLS_ERR_CIPHER_ALLOC_FAILED; |
189 | 0 | } |
190 | | |
191 | 2 | ctx->cmac_ctx = cmac_ctx; |
192 | | |
193 | 2 | mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state)); |
194 | | |
195 | 2 | return 0; |
196 | 2 | } |
197 | | |
198 | | int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx, |
199 | | const unsigned char *input, size_t ilen) |
200 | 2 | { |
201 | 2 | mbedtls_cmac_context_t *cmac_ctx; |
202 | 2 | unsigned char *state; |
203 | 2 | int ret = 0; |
204 | 2 | size_t n, j, olen, block_size; |
205 | | |
206 | 2 | if (ctx == NULL || ctx->cipher_info == NULL || input == NULL || |
207 | 2 | ctx->cmac_ctx == NULL) { |
208 | 0 | return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
209 | 0 | } |
210 | | |
211 | 2 | cmac_ctx = ctx->cmac_ctx; |
212 | 2 | block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info); |
213 | 2 | state = ctx->cmac_ctx->state; |
214 | | |
215 | | /* Without the MBEDTLS_ASSUME below, gcc -O3 will generate a warning of the form |
216 | | * error: writing 16 bytes into a region of size 0 [-Werror=stringop-overflow=] */ |
217 | 2 | MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE); |
218 | | |
219 | | /* Is there data still to process from the last call, that's greater in |
220 | | * size than a block? */ |
221 | 2 | if (cmac_ctx->unprocessed_len > 0 && |
222 | 2 | ilen > block_size - cmac_ctx->unprocessed_len) { |
223 | 0 | memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], |
224 | 0 | input, |
225 | 0 | block_size - cmac_ctx->unprocessed_len); |
226 | |
|
227 | 0 | mbedtls_xor_no_simd(state, cmac_ctx->unprocessed_block, state, block_size); |
228 | |
|
229 | 0 | if ((ret = mbedtls_cipher_update(ctx, state, block_size, state, |
230 | 0 | &olen)) != 0) { |
231 | 0 | goto exit; |
232 | 0 | } |
233 | | |
234 | 0 | input += block_size - cmac_ctx->unprocessed_len; |
235 | 0 | ilen -= block_size - cmac_ctx->unprocessed_len; |
236 | 0 | cmac_ctx->unprocessed_len = 0; |
237 | 0 | } |
238 | | |
239 | | /* n is the number of blocks including any final partial block */ |
240 | 2 | n = (ilen + block_size - 1) / block_size; |
241 | | |
242 | | /* Iterate across the input data in block sized chunks, excluding any |
243 | | * final partial or complete block */ |
244 | 158 | for (j = 1; j < n; j++) { |
245 | 156 | mbedtls_xor_no_simd(state, input, state, block_size); |
246 | | |
247 | 156 | if ((ret = mbedtls_cipher_update(ctx, state, block_size, state, |
248 | 156 | &olen)) != 0) { |
249 | 0 | goto exit; |
250 | 0 | } |
251 | | |
252 | 156 | ilen -= block_size; |
253 | 156 | input += block_size; |
254 | 156 | } |
255 | | |
256 | | /* If there is data left over that wasn't aligned to a block */ |
257 | 2 | if (ilen > 0) { |
258 | 2 | memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], |
259 | 2 | input, |
260 | 2 | ilen); |
261 | 2 | cmac_ctx->unprocessed_len += ilen; |
262 | 2 | } |
263 | | |
264 | 2 | exit: |
265 | 2 | return ret; |
266 | 2 | } |
267 | | |
268 | | int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx, |
269 | | unsigned char *output) |
270 | 2 | { |
271 | 2 | mbedtls_cmac_context_t *cmac_ctx; |
272 | 2 | unsigned char *state, *last_block; |
273 | 2 | unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; |
274 | 2 | unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; |
275 | 2 | unsigned char M_last[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; |
276 | 2 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
277 | 2 | size_t olen, block_size; |
278 | | |
279 | 2 | if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL || |
280 | 2 | output == NULL) { |
281 | 0 | return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
282 | 0 | } |
283 | | |
284 | 2 | cmac_ctx = ctx->cmac_ctx; |
285 | 2 | block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info); |
286 | 2 | MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE); // silence GCC warning |
287 | 2 | state = cmac_ctx->state; |
288 | | |
289 | 2 | mbedtls_platform_zeroize(K1, sizeof(K1)); |
290 | 2 | mbedtls_platform_zeroize(K2, sizeof(K2)); |
291 | 2 | cmac_generate_subkeys(ctx, K1, K2); |
292 | | |
293 | 2 | last_block = cmac_ctx->unprocessed_block; |
294 | | |
295 | | /* Calculate last block */ |
296 | 2 | if (cmac_ctx->unprocessed_len < block_size) { |
297 | 2 | cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len); |
298 | 2 | mbedtls_xor(M_last, M_last, K2, block_size); |
299 | 2 | } else { |
300 | | /* Last block is complete block */ |
301 | 0 | mbedtls_xor(M_last, last_block, K1, block_size); |
302 | 0 | } |
303 | | |
304 | | |
305 | 2 | mbedtls_xor(state, M_last, state, block_size); |
306 | 2 | if ((ret = mbedtls_cipher_update(ctx, state, block_size, state, |
307 | 2 | &olen)) != 0) { |
308 | 0 | goto exit; |
309 | 0 | } |
310 | | |
311 | 2 | memcpy(output, state, block_size); |
312 | | |
313 | 2 | exit: |
314 | | /* Wipe the generated keys on the stack, and any other transients to avoid |
315 | | * side channel leakage */ |
316 | 2 | mbedtls_platform_zeroize(K1, sizeof(K1)); |
317 | 2 | mbedtls_platform_zeroize(K2, sizeof(K2)); |
318 | | |
319 | 2 | cmac_ctx->unprocessed_len = 0; |
320 | 2 | mbedtls_platform_zeroize(cmac_ctx->unprocessed_block, |
321 | 2 | sizeof(cmac_ctx->unprocessed_block)); |
322 | | |
323 | 2 | mbedtls_platform_zeroize(state, MBEDTLS_CMAC_MAX_BLOCK_SIZE); |
324 | 2 | return ret; |
325 | 2 | } |
326 | | |
327 | | int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx) |
328 | 0 | { |
329 | 0 | mbedtls_cmac_context_t *cmac_ctx; |
330 | |
|
331 | 0 | if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) { |
332 | 0 | return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
333 | 0 | } |
334 | | |
335 | 0 | cmac_ctx = ctx->cmac_ctx; |
336 | | |
337 | | /* Reset the internal state */ |
338 | 0 | cmac_ctx->unprocessed_len = 0; |
339 | 0 | mbedtls_platform_zeroize(cmac_ctx->unprocessed_block, |
340 | 0 | sizeof(cmac_ctx->unprocessed_block)); |
341 | 0 | mbedtls_platform_zeroize(cmac_ctx->state, |
342 | 0 | sizeof(cmac_ctx->state)); |
343 | |
|
344 | 0 | return 0; |
345 | 0 | } |
346 | | |
347 | | int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info, |
348 | | const unsigned char *key, size_t keylen, |
349 | | const unsigned char *input, size_t ilen, |
350 | | unsigned char *output) |
351 | 731 | { |
352 | 731 | mbedtls_cipher_context_t ctx; |
353 | 731 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
354 | | |
355 | 731 | if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) { |
356 | 731 | return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
357 | 731 | } |
358 | | |
359 | 0 | mbedtls_cipher_init(&ctx); |
360 | |
|
361 | 0 | if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) { |
362 | 0 | goto exit; |
363 | 0 | } |
364 | | |
365 | 0 | ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen); |
366 | 0 | if (ret != 0) { |
367 | 0 | goto exit; |
368 | 0 | } |
369 | | |
370 | 0 | ret = mbedtls_cipher_cmac_update(&ctx, input, ilen); |
371 | 0 | if (ret != 0) { |
372 | 0 | goto exit; |
373 | 0 | } |
374 | | |
375 | 0 | ret = mbedtls_cipher_cmac_finish(&ctx, output); |
376 | |
|
377 | 0 | exit: |
378 | 0 | mbedtls_cipher_free(&ctx); |
379 | |
|
380 | 0 | return ret; |
381 | 0 | } |
382 | | |
383 | | #if defined(MBEDTLS_AES_C) |
384 | | /* |
385 | | * Implementation of AES-CMAC-PRF-128 defined in RFC 4615 |
386 | | */ |
387 | | int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length, |
388 | | const unsigned char *input, size_t in_len, |
389 | | unsigned char output[16]) |
390 | 0 | { |
391 | 0 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
392 | 0 | const mbedtls_cipher_info_t *cipher_info; |
393 | 0 | unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE]; |
394 | 0 | unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE]; |
395 | |
|
396 | 0 | if (key == NULL || input == NULL || output == NULL) { |
397 | 0 | return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
398 | 0 | } |
399 | | |
400 | 0 | cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); |
401 | 0 | if (cipher_info == NULL) { |
402 | | /* Failing at this point must be due to a build issue */ |
403 | 0 | ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; |
404 | 0 | goto exit; |
405 | 0 | } |
406 | | |
407 | 0 | if (key_length == MBEDTLS_AES_BLOCK_SIZE) { |
408 | | /* Use key as is */ |
409 | 0 | memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE); |
410 | 0 | } else { |
411 | 0 | memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE); |
412 | |
|
413 | 0 | ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key, |
414 | 0 | key_length, int_key); |
415 | 0 | if (ret != 0) { |
416 | 0 | goto exit; |
417 | 0 | } |
418 | 0 | } |
419 | | |
420 | 0 | ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len, |
421 | 0 | output); |
422 | |
|
423 | 0 | exit: |
424 | 0 | mbedtls_platform_zeroize(int_key, sizeof(int_key)); |
425 | |
|
426 | 0 | return ret; |
427 | 0 | } |
428 | | #endif /* MBEDTLS_AES_C */ |
429 | | |
430 | | #endif /* !MBEDTLS_CMAC_ALT */ |
431 | | |
432 | | #if defined(MBEDTLS_SELF_TEST) |
433 | | /* |
434 | | * CMAC test data for SP800-38B |
435 | | * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf |
436 | | * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf |
437 | | * |
438 | | * AES-CMAC-PRF-128 test data from RFC 4615 |
439 | | * https://tools.ietf.org/html/rfc4615#page-4 |
440 | | */ |
441 | | |
442 | 0 | #define NB_CMAC_TESTS_PER_KEY 4 |
443 | 0 | #define NB_PRF_TESTS 3 |
444 | | |
445 | | #if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) |
446 | | /* All CMAC test inputs are truncated from the same 64 byte buffer. */ |
447 | | static const unsigned char test_message[] = { |
448 | | /* PT */ |
449 | | 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, |
450 | | 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, |
451 | | 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, |
452 | | 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, |
453 | | 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, |
454 | | 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, |
455 | | 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, |
456 | | 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 |
457 | | }; |
458 | | #endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */ |
459 | | |
460 | | #if defined(MBEDTLS_AES_C) |
461 | | /* Truncation point of message for AES CMAC tests */ |
462 | | static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = { |
463 | | /* Mlen */ |
464 | | 0, |
465 | | 16, |
466 | | 20, |
467 | | 64 |
468 | | }; |
469 | | |
470 | | /* CMAC-AES128 Test Data */ |
471 | | static const unsigned char aes_128_key[16] = { |
472 | | 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, |
473 | | 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c |
474 | | }; |
475 | | static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { |
476 | | { |
477 | | /* K1 */ |
478 | | 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66, |
479 | | 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde |
480 | | }, |
481 | | { |
482 | | /* K2 */ |
483 | | 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc, |
484 | | 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b |
485 | | } |
486 | | }; |
487 | | static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = |
488 | | { |
489 | | { |
490 | | /* Example #1 */ |
491 | | 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, |
492 | | 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 |
493 | | }, |
494 | | { |
495 | | /* Example #2 */ |
496 | | 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, |
497 | | 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c |
498 | | }, |
499 | | { |
500 | | /* Example #3 */ |
501 | | 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8, |
502 | | 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde |
503 | | }, |
504 | | { |
505 | | /* Example #4 */ |
506 | | 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, |
507 | | 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe |
508 | | } |
509 | | }; |
510 | | |
511 | | /* CMAC-AES192 Test Data */ |
512 | | #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) |
513 | | static const unsigned char aes_192_key[24] = { |
514 | | 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, |
515 | | 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, |
516 | | 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b |
517 | | }; |
518 | | static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { |
519 | | { |
520 | | /* K1 */ |
521 | | 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27, |
522 | | 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96 |
523 | | }, |
524 | | { |
525 | | /* K2 */ |
526 | | 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e, |
527 | | 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c |
528 | | } |
529 | | }; |
530 | | static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = |
531 | | { |
532 | | { |
533 | | /* Example #1 */ |
534 | | 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5, |
535 | | 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67 |
536 | | }, |
537 | | { |
538 | | /* Example #2 */ |
539 | | 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, |
540 | | 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84 |
541 | | }, |
542 | | { |
543 | | /* Example #3 */ |
544 | | 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04, |
545 | | 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8 |
546 | | }, |
547 | | { |
548 | | /* Example #4 */ |
549 | | 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79, |
550 | | 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11 |
551 | | } |
552 | | }; |
553 | | #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ |
554 | | |
555 | | /* CMAC-AES256 Test Data */ |
556 | | #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) |
557 | | static const unsigned char aes_256_key[32] = { |
558 | | 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, |
559 | | 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, |
560 | | 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, |
561 | | 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 |
562 | | }; |
563 | | static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { |
564 | | { |
565 | | /* K1 */ |
566 | | 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac, |
567 | | 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f |
568 | | }, |
569 | | { |
570 | | /* K2 */ |
571 | | 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58, |
572 | | 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9 |
573 | | } |
574 | | }; |
575 | | static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = |
576 | | { |
577 | | { |
578 | | /* Example #1 */ |
579 | | 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e, |
580 | | 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83 |
581 | | }, |
582 | | { |
583 | | /* Example #2 */ |
584 | | 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, |
585 | | 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c |
586 | | }, |
587 | | { |
588 | | /* Example #3 */ |
589 | | 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a, |
590 | | 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93 |
591 | | }, |
592 | | { |
593 | | /* Example #4 */ |
594 | | 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5, |
595 | | 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10 |
596 | | } |
597 | | }; |
598 | | #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ |
599 | | #endif /* MBEDTLS_AES_C */ |
600 | | |
601 | | #if defined(MBEDTLS_DES_C) |
602 | | /* Truncation point of message for 3DES CMAC tests */ |
603 | | static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = { |
604 | | 0, |
605 | | 16, |
606 | | 20, |
607 | | 32 |
608 | | }; |
609 | | |
610 | | /* CMAC-TDES (Generation) - 2 Key Test Data */ |
611 | | static const unsigned char des3_2key_key[24] = { |
612 | | /* Key1 */ |
613 | | 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, |
614 | | /* Key2 */ |
615 | | 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01, |
616 | | /* Key3 */ |
617 | | 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef |
618 | | }; |
619 | | static const unsigned char des3_2key_subkeys[2][8] = { |
620 | | { |
621 | | /* K1 */ |
622 | | 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9 |
623 | | }, |
624 | | { |
625 | | /* K2 */ |
626 | | 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2 |
627 | | } |
628 | | }; |
629 | | static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] |
630 | | = { |
631 | | { |
632 | | /* Sample #1 */ |
633 | | 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60 |
634 | | }, |
635 | | { |
636 | | /* Sample #2 */ |
637 | | 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b |
638 | | }, |
639 | | { |
640 | | /* Sample #3 */ |
641 | | 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69 |
642 | | }, |
643 | | { |
644 | | /* Sample #4 */ |
645 | | 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb |
646 | | } |
647 | | }; |
648 | | |
649 | | /* CMAC-TDES (Generation) - 3 Key Test Data */ |
650 | | static const unsigned char des3_3key_key[24] = { |
651 | | /* Key1 */ |
652 | | 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef, |
653 | | /* Key2 */ |
654 | | 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, |
655 | | /* Key3 */ |
656 | | 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23 |
657 | | }; |
658 | | static const unsigned char des3_3key_subkeys[2][8] = { |
659 | | { |
660 | | /* K1 */ |
661 | | 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0 |
662 | | }, |
663 | | { |
664 | | /* K2 */ |
665 | | 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b |
666 | | } |
667 | | }; |
668 | | static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] |
669 | | = { |
670 | | { |
671 | | /* Sample #1 */ |
672 | | 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50 |
673 | | }, |
674 | | { |
675 | | /* Sample #2 */ |
676 | | 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09 |
677 | | }, |
678 | | { |
679 | | /* Sample #3 */ |
680 | | 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2 |
681 | | }, |
682 | | { |
683 | | /* Sample #4 */ |
684 | | 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5 |
685 | | } |
686 | | }; |
687 | | |
688 | | #endif /* MBEDTLS_DES_C */ |
689 | | |
690 | | #if defined(MBEDTLS_AES_C) |
691 | | /* AES AES-CMAC-PRF-128 Test Data */ |
692 | | static const unsigned char PRFK[] = { |
693 | | /* Key */ |
694 | | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
695 | | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
696 | | 0xed, 0xcb |
697 | | }; |
698 | | |
699 | | /* Sizes in bytes */ |
700 | | static const size_t PRFKlen[NB_PRF_TESTS] = { |
701 | | 18, |
702 | | 16, |
703 | | 10 |
704 | | }; |
705 | | |
706 | | /* Message */ |
707 | | static const unsigned char PRFM[] = { |
708 | | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
709 | | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
710 | | 0x10, 0x11, 0x12, 0x13 |
711 | | }; |
712 | | |
713 | | static const unsigned char PRFT[NB_PRF_TESTS][16] = { |
714 | | { |
715 | | 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b, |
716 | | 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a |
717 | | }, |
718 | | { |
719 | | 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52, |
720 | | 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d |
721 | | }, |
722 | | { |
723 | | 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee, |
724 | | 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d |
725 | | } |
726 | | }; |
727 | | #endif /* MBEDTLS_AES_C */ |
728 | | |
729 | | static int cmac_test_subkeys(int verbose, |
730 | | const char *testname, |
731 | | const unsigned char *key, |
732 | | int keybits, |
733 | | const unsigned char *subkeys, |
734 | | mbedtls_cipher_type_t cipher_type, |
735 | | int block_size, |
736 | | int num_tests) |
737 | 0 | { |
738 | 0 | int i, ret = 0; |
739 | 0 | mbedtls_cipher_context_t ctx; |
740 | 0 | const mbedtls_cipher_info_t *cipher_info; |
741 | 0 | unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; |
742 | 0 | unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; |
743 | |
|
744 | 0 | cipher_info = mbedtls_cipher_info_from_type(cipher_type); |
745 | 0 | if (cipher_info == NULL) { |
746 | | /* Failing at this point must be due to a build issue */ |
747 | 0 | return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; |
748 | 0 | } |
749 | | |
750 | 0 | for (i = 0; i < num_tests; i++) { |
751 | 0 | if (verbose != 0) { |
752 | 0 | mbedtls_printf(" %s CMAC subkey #%d: ", testname, i + 1); |
753 | 0 | } |
754 | |
|
755 | 0 | mbedtls_cipher_init(&ctx); |
756 | |
|
757 | 0 | if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) { |
758 | 0 | if (verbose != 0) { |
759 | 0 | mbedtls_printf("test execution failed\n"); |
760 | 0 | } |
761 | |
|
762 | 0 | goto cleanup; |
763 | 0 | } |
764 | | |
765 | 0 | if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits, |
766 | 0 | MBEDTLS_ENCRYPT)) != 0) { |
767 | | /* When CMAC is implemented by an alternative implementation, or |
768 | | * the underlying primitive itself is implemented alternatively, |
769 | | * AES-192 may be unavailable. This should not cause the selftest |
770 | | * function to fail. */ |
771 | 0 | if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED || |
772 | 0 | ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) && |
773 | 0 | cipher_type == MBEDTLS_CIPHER_AES_192_ECB) { |
774 | 0 | if (verbose != 0) { |
775 | 0 | mbedtls_printf("skipped\n"); |
776 | 0 | } |
777 | 0 | goto next_test; |
778 | 0 | } |
779 | | |
780 | 0 | if (verbose != 0) { |
781 | 0 | mbedtls_printf("test execution failed\n"); |
782 | 0 | } |
783 | |
|
784 | 0 | goto cleanup; |
785 | 0 | } |
786 | | |
787 | 0 | ret = cmac_generate_subkeys(&ctx, K1, K2); |
788 | 0 | if (ret != 0) { |
789 | 0 | if (verbose != 0) { |
790 | 0 | mbedtls_printf("failed\n"); |
791 | 0 | } |
792 | |
|
793 | 0 | goto cleanup; |
794 | 0 | } |
795 | | |
796 | 0 | if ((ret = memcmp(K1, subkeys, block_size)) != 0 || |
797 | 0 | (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) { |
798 | 0 | if (verbose != 0) { |
799 | 0 | mbedtls_printf("failed\n"); |
800 | 0 | } |
801 | |
|
802 | 0 | goto cleanup; |
803 | 0 | } |
804 | | |
805 | 0 | if (verbose != 0) { |
806 | 0 | mbedtls_printf("passed\n"); |
807 | 0 | } |
808 | |
|
809 | 0 | next_test: |
810 | 0 | mbedtls_cipher_free(&ctx); |
811 | 0 | } |
812 | | |
813 | 0 | ret = 0; |
814 | 0 | goto exit; |
815 | | |
816 | 0 | cleanup: |
817 | 0 | mbedtls_cipher_free(&ctx); |
818 | |
|
819 | 0 | exit: |
820 | 0 | return ret; |
821 | 0 | } |
822 | | |
823 | | static int cmac_test_wth_cipher(int verbose, |
824 | | const char *testname, |
825 | | const unsigned char *key, |
826 | | int keybits, |
827 | | const unsigned char *messages, |
828 | | const unsigned int message_lengths[4], |
829 | | const unsigned char *expected_result, |
830 | | mbedtls_cipher_type_t cipher_type, |
831 | | int block_size, |
832 | | int num_tests) |
833 | 0 | { |
834 | 0 | const mbedtls_cipher_info_t *cipher_info; |
835 | 0 | int i, ret = 0; |
836 | 0 | unsigned char output[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; |
837 | |
|
838 | 0 | cipher_info = mbedtls_cipher_info_from_type(cipher_type); |
839 | 0 | if (cipher_info == NULL) { |
840 | | /* Failing at this point must be due to a build issue */ |
841 | 0 | ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; |
842 | 0 | goto exit; |
843 | 0 | } |
844 | | |
845 | 0 | for (i = 0; i < num_tests; i++) { |
846 | 0 | if (verbose != 0) { |
847 | 0 | mbedtls_printf(" %s CMAC #%d: ", testname, i + 1); |
848 | 0 | } |
849 | |
|
850 | 0 | if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages, |
851 | 0 | message_lengths[i], output)) != 0) { |
852 | | /* When CMAC is implemented by an alternative implementation, or |
853 | | * the underlying primitive itself is implemented alternatively, |
854 | | * AES-192 and/or 3DES may be unavailable. This should not cause |
855 | | * the selftest function to fail. */ |
856 | 0 | if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED || |
857 | 0 | ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) && |
858 | 0 | (cipher_type == MBEDTLS_CIPHER_AES_192_ECB || |
859 | 0 | cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) { |
860 | 0 | if (verbose != 0) { |
861 | 0 | mbedtls_printf("skipped\n"); |
862 | 0 | } |
863 | 0 | continue; |
864 | 0 | } |
865 | | |
866 | 0 | if (verbose != 0) { |
867 | 0 | mbedtls_printf("failed\n"); |
868 | 0 | } |
869 | 0 | goto exit; |
870 | 0 | } |
871 | | |
872 | 0 | if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) { |
873 | 0 | if (verbose != 0) { |
874 | 0 | mbedtls_printf("failed\n"); |
875 | 0 | } |
876 | 0 | goto exit; |
877 | 0 | } |
878 | | |
879 | 0 | if (verbose != 0) { |
880 | 0 | mbedtls_printf("passed\n"); |
881 | 0 | } |
882 | 0 | } |
883 | 0 | ret = 0; |
884 | |
|
885 | 0 | exit: |
886 | 0 | return ret; |
887 | 0 | } |
888 | | |
889 | | #if defined(MBEDTLS_AES_C) |
890 | | static int test_aes128_cmac_prf(int verbose) |
891 | 0 | { |
892 | 0 | int i; |
893 | 0 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
894 | 0 | unsigned char output[MBEDTLS_AES_BLOCK_SIZE]; |
895 | |
|
896 | 0 | for (i = 0; i < NB_PRF_TESTS; i++) { |
897 | 0 | mbedtls_printf(" AES CMAC 128 PRF #%d: ", i); |
898 | 0 | ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output); |
899 | 0 | if (ret != 0 || |
900 | 0 | memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) { |
901 | |
|
902 | 0 | if (verbose != 0) { |
903 | 0 | mbedtls_printf("failed\n"); |
904 | 0 | } |
905 | |
|
906 | 0 | return ret; |
907 | 0 | } else if (verbose != 0) { |
908 | 0 | mbedtls_printf("passed\n"); |
909 | 0 | } |
910 | 0 | } |
911 | 0 | return ret; |
912 | 0 | } |
913 | | #endif /* MBEDTLS_AES_C */ |
914 | | |
915 | | int mbedtls_cmac_self_test(int verbose) |
916 | 0 | { |
917 | 0 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
918 | |
|
919 | 0 | #if defined(MBEDTLS_AES_C) |
920 | | /* AES-128 */ |
921 | 0 | if ((ret = cmac_test_subkeys(verbose, |
922 | 0 | "AES 128", |
923 | 0 | aes_128_key, |
924 | 0 | 128, |
925 | 0 | (const unsigned char *) aes_128_subkeys, |
926 | 0 | MBEDTLS_CIPHER_AES_128_ECB, |
927 | 0 | MBEDTLS_AES_BLOCK_SIZE, |
928 | 0 | NB_CMAC_TESTS_PER_KEY)) != 0) { |
929 | 0 | return ret; |
930 | 0 | } |
931 | | |
932 | 0 | if ((ret = cmac_test_wth_cipher(verbose, |
933 | 0 | "AES 128", |
934 | 0 | aes_128_key, |
935 | 0 | 128, |
936 | 0 | test_message, |
937 | 0 | aes_message_lengths, |
938 | 0 | (const unsigned char *) aes_128_expected_result, |
939 | 0 | MBEDTLS_CIPHER_AES_128_ECB, |
940 | 0 | MBEDTLS_AES_BLOCK_SIZE, |
941 | 0 | NB_CMAC_TESTS_PER_KEY)) != 0) { |
942 | 0 | return ret; |
943 | 0 | } |
944 | | |
945 | | /* AES-192 */ |
946 | 0 | #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) |
947 | 0 | if ((ret = cmac_test_subkeys(verbose, |
948 | 0 | "AES 192", |
949 | 0 | aes_192_key, |
950 | 0 | 192, |
951 | 0 | (const unsigned char *) aes_192_subkeys, |
952 | 0 | MBEDTLS_CIPHER_AES_192_ECB, |
953 | 0 | MBEDTLS_AES_BLOCK_SIZE, |
954 | 0 | NB_CMAC_TESTS_PER_KEY)) != 0) { |
955 | 0 | return ret; |
956 | 0 | } |
957 | | |
958 | 0 | if ((ret = cmac_test_wth_cipher(verbose, |
959 | 0 | "AES 192", |
960 | 0 | aes_192_key, |
961 | 0 | 192, |
962 | 0 | test_message, |
963 | 0 | aes_message_lengths, |
964 | 0 | (const unsigned char *) aes_192_expected_result, |
965 | 0 | MBEDTLS_CIPHER_AES_192_ECB, |
966 | 0 | MBEDTLS_AES_BLOCK_SIZE, |
967 | 0 | NB_CMAC_TESTS_PER_KEY)) != 0) { |
968 | 0 | return ret; |
969 | 0 | } |
970 | 0 | #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ |
971 | | |
972 | | /* AES-256 */ |
973 | 0 | #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) |
974 | 0 | if ((ret = cmac_test_subkeys(verbose, |
975 | 0 | "AES 256", |
976 | 0 | aes_256_key, |
977 | 0 | 256, |
978 | 0 | (const unsigned char *) aes_256_subkeys, |
979 | 0 | MBEDTLS_CIPHER_AES_256_ECB, |
980 | 0 | MBEDTLS_AES_BLOCK_SIZE, |
981 | 0 | NB_CMAC_TESTS_PER_KEY)) != 0) { |
982 | 0 | return ret; |
983 | 0 | } |
984 | | |
985 | 0 | if ((ret = cmac_test_wth_cipher(verbose, |
986 | 0 | "AES 256", |
987 | 0 | aes_256_key, |
988 | 0 | 256, |
989 | 0 | test_message, |
990 | 0 | aes_message_lengths, |
991 | 0 | (const unsigned char *) aes_256_expected_result, |
992 | 0 | MBEDTLS_CIPHER_AES_256_ECB, |
993 | 0 | MBEDTLS_AES_BLOCK_SIZE, |
994 | 0 | NB_CMAC_TESTS_PER_KEY)) != 0) { |
995 | 0 | return ret; |
996 | 0 | } |
997 | 0 | #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ |
998 | 0 | #endif /* MBEDTLS_AES_C */ |
999 | | |
1000 | 0 | #if defined(MBEDTLS_DES_C) |
1001 | | /* 3DES 2 key */ |
1002 | 0 | if ((ret = cmac_test_subkeys(verbose, |
1003 | 0 | "3DES 2 key", |
1004 | 0 | des3_2key_key, |
1005 | 0 | 192, |
1006 | 0 | (const unsigned char *) des3_2key_subkeys, |
1007 | 0 | MBEDTLS_CIPHER_DES_EDE3_ECB, |
1008 | 0 | MBEDTLS_DES3_BLOCK_SIZE, |
1009 | 0 | NB_CMAC_TESTS_PER_KEY)) != 0) { |
1010 | 0 | return ret; |
1011 | 0 | } |
1012 | | |
1013 | 0 | if ((ret = cmac_test_wth_cipher(verbose, |
1014 | 0 | "3DES 2 key", |
1015 | 0 | des3_2key_key, |
1016 | 0 | 192, |
1017 | 0 | test_message, |
1018 | 0 | des3_message_lengths, |
1019 | 0 | (const unsigned char *) des3_2key_expected_result, |
1020 | 0 | MBEDTLS_CIPHER_DES_EDE3_ECB, |
1021 | 0 | MBEDTLS_DES3_BLOCK_SIZE, |
1022 | 0 | NB_CMAC_TESTS_PER_KEY)) != 0) { |
1023 | 0 | return ret; |
1024 | 0 | } |
1025 | | |
1026 | | /* 3DES 3 key */ |
1027 | 0 | if ((ret = cmac_test_subkeys(verbose, |
1028 | 0 | "3DES 3 key", |
1029 | 0 | des3_3key_key, |
1030 | 0 | 192, |
1031 | 0 | (const unsigned char *) des3_3key_subkeys, |
1032 | 0 | MBEDTLS_CIPHER_DES_EDE3_ECB, |
1033 | 0 | MBEDTLS_DES3_BLOCK_SIZE, |
1034 | 0 | NB_CMAC_TESTS_PER_KEY)) != 0) { |
1035 | 0 | return ret; |
1036 | 0 | } |
1037 | | |
1038 | 0 | if ((ret = cmac_test_wth_cipher(verbose, |
1039 | 0 | "3DES 3 key", |
1040 | 0 | des3_3key_key, |
1041 | 0 | 192, |
1042 | 0 | test_message, |
1043 | 0 | des3_message_lengths, |
1044 | 0 | (const unsigned char *) des3_3key_expected_result, |
1045 | 0 | MBEDTLS_CIPHER_DES_EDE3_ECB, |
1046 | 0 | MBEDTLS_DES3_BLOCK_SIZE, |
1047 | 0 | NB_CMAC_TESTS_PER_KEY)) != 0) { |
1048 | 0 | return ret; |
1049 | 0 | } |
1050 | 0 | #endif /* MBEDTLS_DES_C */ |
1051 | | |
1052 | 0 | #if defined(MBEDTLS_AES_C) |
1053 | 0 | if ((ret = test_aes128_cmac_prf(verbose)) != 0) { |
1054 | 0 | return ret; |
1055 | 0 | } |
1056 | 0 | #endif /* MBEDTLS_AES_C */ |
1057 | | |
1058 | 0 | if (verbose != 0) { |
1059 | 0 | mbedtls_printf("\n"); |
1060 | 0 | } |
1061 | |
|
1062 | 0 | return 0; |
1063 | 0 | } |
1064 | | |
1065 | | #endif /* MBEDTLS_SELF_TEST */ |
1066 | | |
1067 | | #endif /* MBEDTLS_CMAC_C */ |