]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - common/polarssl/aes_cmac128.c
2 * AES-CMAC from NIST Special Publication 800-38B \97 Recommendation for block cipher modes of operation: The CMAC mode for authentication.
4 * Copyright (C) 2006-2014, Brainspark B.V.
5 * Copyright (C) 2014, Anargyros Plemenos
6 * Tests added Merkok, 2018
8 * This file is part of PolarSSL (http://www.polarssl.org)
9 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
11 * All rights reserved.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * Reference : https://polarssl.org/discussions/generic/authentication-token
28 * NIST Special Publication 800-38B \97 Recommendation for block cipher modes of operation: The CMAC mode for authentication.
30 * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CMAC.pdf
33 #include "polarssl/aes_cmac128.h"
36 #define MIN(a,b) ((a)<(b)?(a):(b))
37 #define _MSB(x) (((x)[0] & 0x80)?1:0)
39 #if !defined(POLARSSL_CONFIG_FILE)
40 #include "polarssl_config.h"
42 #include POLARSSL_CONFIG_FILE
45 #if defined(POLARSSL_AES_C)
49 #if defined(POLARSSL_PLATFORM_C)
50 #include "polarssl/platform.h"
52 #define polarssl_printf printf
59 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
62 * zero a structure given a pointer to the structure
64 #define ZERO_STRUCTP(x) do{ if((x) != NULL) memset((char *)(x), 0, sizeof(*(x)));} while(0)
67 /* For CMAC Calculation */
68 static unsigned char const_Rb
[16] = {
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
72 static unsigned char const_Zero
[16] = {
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
77 static inline void aes_cmac_128_left_shift_1(const uint8_t in
[16], uint8_t out
[16])
82 for (i
= 15; i
>= 0; i
--) {
85 overflow
= _MSB(&in
[i
]);
89 static inline void aes_cmac_128_xor(const uint8_t in1
[16], const uint8_t in2
[16],
94 for (i
= 0; i
< 16; i
++) {
95 out
[i
] = in1
[i
] ^ in2
[i
];
100 * AES-CMAC-128 context setup
102 void aes_cmac128_starts(aes_cmac128_context
*ctx
, const uint8_t K
[16])
106 /* Zero struct of aes_context */
108 /* Initialize aes_context */
109 aes_setkey_enc(&ctx
->aes_key
, K
, 128);
111 /* step 1 - generate subkeys k1 and k2 */
112 aes_crypt_ecb(&ctx
->aes_key
, AES_ENCRYPT
, const_Zero
, L
);
115 aes_cmac_128_left_shift_1(L
, ctx
->K1
);
117 uint8_t tmp_block
[16];
119 aes_cmac_128_left_shift_1(L
, tmp_block
);
120 aes_cmac_128_xor(tmp_block
, const_Rb
, ctx
->K1
);
121 ZERO_STRUCT(tmp_block
);
124 if (_MSB(ctx
->K1
) == 0) {
125 aes_cmac_128_left_shift_1(ctx
->K1
, ctx
->K2
);
127 uint8_t tmp_block
[16];
129 aes_cmac_128_left_shift_1(ctx
->K1
, tmp_block
);
130 aes_cmac_128_xor(tmp_block
, const_Rb
, ctx
->K2
);
131 ZERO_STRUCT(tmp_block
);
138 * AES-CMAC-128 process message
140 void aes_cmac128_update(aes_cmac128_context
*ctx
, const uint8_t *_msg
, size_t _msg_len
)
142 uint8_t tmp_block
[16];
144 const uint8_t *msg
= _msg
;
145 size_t msg_len
= _msg_len
;
148 * copy the remembered last block
150 ZERO_STRUCT(tmp_block
);
152 memcpy(tmp_block
, ctx
->last
, ctx
->last_len
);
156 * check if we expand the block
158 if (ctx
->last_len
< 16) {
159 size_t len
= MIN(16 - ctx
->last_len
, msg_len
);
161 memcpy(&tmp_block
[ctx
->last_len
], msg
, len
);
162 memcpy(ctx
->last
, tmp_block
, 16);
165 ctx
->last_len
+= len
;
169 /* if it is still the last block, we are done */
170 ZERO_STRUCT(tmp_block
);
175 * It is not the last block anymore
177 ZERO_STRUCT(ctx
->last
);
181 * now checksum everything but the last block
183 aes_cmac_128_xor(ctx
->X
, tmp_block
, Y
);
184 aes_crypt_ecb(&ctx
->aes_key
, AES_ENCRYPT
, Y
, ctx
->X
);
186 while (msg_len
> 16) {
187 memcpy(tmp_block
, msg
, 16);
191 aes_cmac_128_xor(ctx
->X
, tmp_block
, Y
);
192 aes_crypt_ecb(&ctx
->aes_key
, AES_ENCRYPT
, Y
, ctx
->X
);
196 * copy the last block, it will be processed in
197 * aes_cmac128_final().
199 memcpy(ctx
->last
, msg
, msg_len
);
200 ctx
->last_len
= msg_len
;
202 ZERO_STRUCT(tmp_block
);
207 * AES-CMAC-128 compute T
209 void aes_cmac128_final(aes_cmac128_context
*ctx
, uint8_t T
[16])
211 uint8_t tmp_block
[16];
214 if (ctx
->last_len
< 16) {
215 ctx
->last
[ctx
->last_len
] = 0x80;
216 aes_cmac_128_xor(ctx
->last
, ctx
->K2
, tmp_block
);
218 aes_cmac_128_xor(ctx
->last
, ctx
->K1
, tmp_block
);
221 aes_cmac_128_xor(tmp_block
, ctx
->X
, Y
);
222 aes_crypt_ecb(&ctx
->aes_key
, AES_ENCRYPT
, Y
, T
);
224 ZERO_STRUCT(tmp_block
);
232 * https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values
233 * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CMAC.pdf
235 int aes_cmac_self_test( int verbose
)
237 unsigned char key
[16] = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C};
238 unsigned char mac
[16] = {0};
239 aes_cmac128_context ctx
;
244 polarssl_printf( " AES-CMAC-128 zero length data: " );
245 unsigned char ex1data
[16] = {0};
246 aes_cmac128_starts(&ctx
, key
);
247 aes_cmac128_update(&ctx
, ex1data
, 0);
248 aes_cmac128_final(&ctx
, mac
);
249 unsigned char ex1res
[16] = {0xBB, 0x1D, 0x69, 0x29, 0xE9, 0x59, 0x37, 0x28, 0x7F, 0xA3, 0x7D, 0x12, 0x9B, 0x75, 0x67, 0x46};
250 if(!memcmp(mac
, ex1res
, 16)) {
252 polarssl_printf( "passed\n" );
254 polarssl_printf( "failed\n" );
261 polarssl_printf( " AES-CMAC-128 one block data : " );
262 unsigned char ex2data
[16] = {0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A};
263 aes_cmac128_starts(&ctx
, key
);
264 aes_cmac128_update(&ctx
, ex2data
, sizeof(ex2data
));
265 aes_cmac128_final(&ctx
, mac
);
266 unsigned char ex2res
[16] = {0x07, 0x0A, 0x16, 0xB4, 0x6B, 0x4D, 0x41, 0x44, 0xF7, 0x9B, 0xDD, 0x9D, 0xD0, 0x4A, 0x28, 0x7C};
267 if(!memcmp(mac
, ex2res
, 16)) {
269 polarssl_printf( "passed\n" );
271 polarssl_printf( "failed\n" );
278 polarssl_printf( " AES-CMAC-128 20 bytes of data: " );
279 unsigned char ex3data
[20] = {0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
280 0xAE, 0x2D, 0x8A, 0x57};
281 aes_cmac128_starts(&ctx
, key
);
282 aes_cmac128_update(&ctx
, ex3data
, sizeof(ex3data
));
283 aes_cmac128_final(&ctx
, mac
);
284 unsigned char ex3res
[16] = {0x7D, 0x85, 0x44, 0x9E, 0xA6, 0xEA, 0x19, 0xC8, 0x23, 0xA7, 0xBF, 0x78, 0x83, 0x7D, 0xFA, 0xDE};
285 if(!memcmp(mac
, ex3res
, 16)) {
287 polarssl_printf( "passed\n" );
289 polarssl_printf( "failed\n" );
296 polarssl_printf( " AES-CMAC-128 4 blocks of data: " );
297 unsigned char ex4data
[64] = {0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
298 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
299 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
300 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10};
301 aes_cmac128_starts(&ctx
, key
);
302 aes_cmac128_update(&ctx
, ex4data
, sizeof(ex4data
));
303 aes_cmac128_final(&ctx
, mac
);
304 unsigned char ex4res
[16] = {0x51, 0xF0, 0xBE, 0xBF, 0x7E, 0x3B, 0x9D, 0x92, 0xFC, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3C, 0xFE};
305 if(!memcmp(mac
, ex4res
, 16)) {
307 polarssl_printf( "passed\n" );
309 polarssl_printf( "failed\n" );
315 polarssl_printf( "\n" );