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