]> git.zerfleddert.de Git - proxmark3-svn/blob - common/polarssl/aes_cmac128.c
FIDO U2F NFC authenticators (#697)
[proxmark3-svn] / common / polarssl / aes_cmac128.c
1 /*
2 * AES-CMAC from NIST Special Publication 800-38B \97 Recommendation for block cipher modes of operation: The CMAC mode for authentication.
3 *
4 * Copyright (C) 2006-2014, Brainspark B.V.
5 * Copyright (C) 2014, Anargyros Plemenos
6 * Tests added Merkok, 2018
7 *
8 * This file is part of PolarSSL (http://www.polarssl.org)
9 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
10 *
11 * All rights reserved.
12 *
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.
17 *
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.
22 *
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.
26 *
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.
29 * Tests here:
30 * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CMAC.pdf
31 */
32
33 #include "polarssl/aes_cmac128.h"
34 #include <stdio.h>
35
36 #define MIN(a,b) ((a)<(b)?(a):(b))
37 #define _MSB(x) (((x)[0] & 0x80)?1:0)
38
39 #if !defined(POLARSSL_CONFIG_FILE)
40 #include "polarssl_config.h"
41 #else
42 #include POLARSSL_CONFIG_FILE
43 #endif
44
45 #if defined(POLARSSL_AES_C)
46 #include "aes.h"
47 #endif
48
49 #if defined(POLARSSL_PLATFORM_C)
50 #include "polarssl/platform.h"
51 #else
52 #define polarssl_printf printf
53 #endif
54
55
56 /**
57 * zero a structure
58 */
59 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
60
61 /**
62 * zero a structure given a pointer to the structure
63 */
64 #define ZERO_STRUCTP(x) do{ if((x) != NULL) memset((char *)(x), 0, sizeof(*(x)));} while(0)
65
66
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
71 };
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
75 };
76
77 static inline void aes_cmac_128_left_shift_1(const uint8_t in[16], uint8_t out[16])
78 {
79 uint8_t overflow = 0;
80 int8_t i;
81
82 for (i = 15; i >= 0; i--) {
83 out[i] = in[i] << 1;
84 out[i] |= overflow;
85 overflow = _MSB(&in[i]);
86 }
87 }
88
89 static inline void aes_cmac_128_xor(const uint8_t in1[16], const uint8_t in2[16],
90 uint8_t out[16])
91 {
92 uint8_t i;
93
94 for (i = 0; i < 16; i++) {
95 out[i] = in1[i] ^ in2[i];
96 }
97 }
98
99 /*
100 * AES-CMAC-128 context setup
101 */
102 void aes_cmac128_starts(aes_cmac128_context *ctx, const uint8_t K[16])
103 {
104 uint8_t L[16];
105
106 /* Zero struct of aes_context */
107 ZERO_STRUCTP(ctx);
108 /* Initialize aes_context */
109 aes_setkey_enc(&ctx->aes_key, K, 128);
110
111 /* step 1 - generate subkeys k1 and k2 */
112 aes_crypt_ecb(&ctx->aes_key, AES_ENCRYPT, const_Zero, L);
113
114 if (_MSB(L) == 0) {
115 aes_cmac_128_left_shift_1(L, ctx->K1);
116 } else {
117 uint8_t tmp_block[16];
118
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);
122 }
123
124 if (_MSB(ctx->K1) == 0) {
125 aes_cmac_128_left_shift_1(ctx->K1, ctx->K2);
126 } else {
127 uint8_t tmp_block[16];
128
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);
132 }
133
134 ZERO_STRUCT(L);
135 }
136
137 /*
138 * AES-CMAC-128 process message
139 */
140 void aes_cmac128_update(aes_cmac128_context *ctx, const uint8_t *_msg, size_t _msg_len)
141 {
142 uint8_t tmp_block[16];
143 uint8_t Y[16];
144 const uint8_t *msg = _msg;
145 size_t msg_len = _msg_len;
146
147 /*
148 * copy the remembered last block
149 */
150 ZERO_STRUCT(tmp_block);
151 if (ctx->last_len) {
152 memcpy(tmp_block, ctx->last, ctx->last_len);
153 }
154
155 /*
156 * check if we expand the block
157 */
158 if (ctx->last_len < 16) {
159 size_t len = MIN(16 - ctx->last_len, msg_len);
160
161 memcpy(&tmp_block[ctx->last_len], msg, len);
162 memcpy(ctx->last, tmp_block, 16);
163 msg += len;
164 msg_len -= len;
165 ctx->last_len += len;
166 }
167
168 if (msg_len == 0) {
169 /* if it is still the last block, we are done */
170 ZERO_STRUCT(tmp_block);
171 return;
172 }
173
174 /*
175 * It is not the last block anymore
176 */
177 ZERO_STRUCT(ctx->last);
178 ctx->last_len = 0;
179
180 /*
181 * now checksum everything but the last block
182 */
183 aes_cmac_128_xor(ctx->X, tmp_block, Y);
184 aes_crypt_ecb(&ctx->aes_key, AES_ENCRYPT, Y, ctx->X);
185
186 while (msg_len > 16) {
187 memcpy(tmp_block, msg, 16);
188 msg += 16;
189 msg_len -= 16;
190
191 aes_cmac_128_xor(ctx->X, tmp_block, Y);
192 aes_crypt_ecb(&ctx->aes_key, AES_ENCRYPT, Y, ctx->X);
193 }
194
195 /*
196 * copy the last block, it will be processed in
197 * aes_cmac128_final().
198 */
199 memcpy(ctx->last, msg, msg_len);
200 ctx->last_len = msg_len;
201
202 ZERO_STRUCT(tmp_block);
203 ZERO_STRUCT(Y);
204 }
205
206 /*
207 * AES-CMAC-128 compute T
208 */
209 void aes_cmac128_final(aes_cmac128_context *ctx, uint8_t T[16])
210 {
211 uint8_t tmp_block[16];
212 uint8_t Y[16];
213
214 if (ctx->last_len < 16) {
215 ctx->last[ctx->last_len] = 0x80;
216 aes_cmac_128_xor(ctx->last, ctx->K2, tmp_block);
217 } else {
218 aes_cmac_128_xor(ctx->last, ctx->K1, tmp_block);
219 }
220
221 aes_cmac_128_xor(tmp_block, ctx->X, Y);
222 aes_crypt_ecb(&ctx->aes_key, AES_ENCRYPT, Y, T);
223
224 ZERO_STRUCT(tmp_block);
225 ZERO_STRUCT(Y);
226 ZERO_STRUCTP(ctx);
227 }
228
229 /*
230 * Checkup routine
231 *
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
234 */
235 int aes_cmac_self_test( int verbose )
236 {
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;
240 int ret;
241
242 // check Example1:
243 if( verbose != 0 )
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)) {
251 if( verbose != 0 )
252 polarssl_printf( "passed\n" );
253 } else {
254 polarssl_printf( "failed\n" );
255 ret = 1;
256 goto exit;
257 }
258
259 // check Example2:
260 if( verbose != 0 )
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)) {
268 if( verbose != 0 )
269 polarssl_printf( "passed\n" );
270 } else {
271 polarssl_printf( "failed\n" );
272 ret = 1;
273 goto exit;
274 }
275
276 // check Example3:
277 if( verbose != 0 )
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)) {
286 if( verbose != 0 )
287 polarssl_printf( "passed\n" );
288 } else {
289 polarssl_printf( "failed\n" );
290 ret = 1;
291 goto exit;
292 }
293
294 // check Example4:
295 if( verbose != 0 )
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)) {
306 if( verbose != 0 )
307 polarssl_printf( "passed\n" );
308 } else {
309 polarssl_printf( "failed\n" );
310 ret = 1;
311 goto exit;
312 }
313
314 if( verbose != 0 )
315 polarssl_printf( "\n" );
316
317 ret = 0;
318
319 exit:
320 return( ret );
321 }
322
Impressum, Datenschutz