1 /*
2 * NIST SP800-38D compliant GCM implementation
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22 /*
23 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
24 *
25 * See also:
26 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
27 *
28 * We use the algorithm described as Shoup's method with 4-bit tables in
29 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
30 */
31
32 #if !defined(MBEDTLS_CONFIG_FILE)
33 #include "mbedtls/config.h"
34 #else
35 #include MBEDTLS_CONFIG_FILE
36 #endif
37
38 #if defined(MBEDTLS_GCM_C)
39
40 #include "mbedtls/gcm.h"
41 #include "mbedtls/platform_util.h"
42
43 #include <string.h>
44
45 #if defined(MBEDTLS_AESNI_C)
46 #include "mbedtls/aesni.h"
47 #endif
48
49 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
50 #include "mbedtls/aes.h"
51 #include "mbedtls/platform.h"
52 #if !defined(MBEDTLS_PLATFORM_C)
53 #include <stdio.h>
54 #define mbedtls_printf printf
55 #endif /* MBEDTLS_PLATFORM_C */
56 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
57
58 #if !defined(MBEDTLS_GCM_ALT)
59
60 /* Parameter validation macros */
61 #define GCM_VALIDATE_RET( cond ) \
62 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
63 #define GCM_VALIDATE( cond ) \
64 MBEDTLS_INTERNAL_VALIDATE( cond )
65
66 /*
67 * 32-bit integer manipulation macros (big endian)
68 */
69 #ifndef GET_UINT32_BE
70 #define GET_UINT32_BE(n,b,i) \
71 { \
72 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
73 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
74 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
75 | ( (uint32_t) (b)[(i) + 3] ); \
76 }
77 #endif
78
79 #ifndef PUT_UINT32_BE
80 #define PUT_UINT32_BE(n,b,i) \
81 { \
82 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
83 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
84 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
85 (b)[(i) + 3] = (unsigned char) ( (n) ); \
86 }
87 #endif
88
89 /*
90 * Initialize a context
91 */
mbedtls_gcm_init(mbedtls_gcm_context * ctx)92 void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
93 {
94 GCM_VALIDATE( ctx != NULL );
95 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
96 }
97
98 /*
99 * Precompute small multiples of H, that is set
100 * HH[i] || HL[i] = H times i,
101 * where i is seen as a field element as in [MGV], ie high-order bits
102 * correspond to low powers of P. The result is stored in the same way, that
103 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
104 * corresponds to P^127.
105 */
gcm_gen_table(mbedtls_gcm_context * ctx)106 static int gcm_gen_table( mbedtls_gcm_context *ctx )
107 {
108 int ret, i, j;
109 uint64_t hi, lo;
110 uint64_t vl, vh;
111 unsigned char h[16];
112 size_t olen = 0;
113
114 memset( h, 0, 16 );
115 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
116 return( ret );
117
118 /* pack h as two 64-bits ints, big-endian */
119 GET_UINT32_BE( hi, h, 0 );
120 GET_UINT32_BE( lo, h, 4 );
121 vh = (uint64_t) hi << 32 | lo;
122
123 GET_UINT32_BE( hi, h, 8 );
124 GET_UINT32_BE( lo, h, 12 );
125 vl = (uint64_t) hi << 32 | lo;
126
127 /* 8 = 1000 corresponds to 1 in GF(2^128) */
128 ctx->HL[8] = vl;
129 ctx->HH[8] = vh;
130
131 #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
132 /* With CLMUL support, we need only h, not the rest of the table */
133 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
134 return( 0 );
135 #endif
136
137 /* 0 corresponds to 0 in GF(2^128) */
138 ctx->HH[0] = 0;
139 ctx->HL[0] = 0;
140
141 for( i = 4; i > 0; i >>= 1 )
142 {
143 uint32_t T = ( vl & 1 ) * 0xe1000000U;
144 vl = ( vh << 63 ) | ( vl >> 1 );
145 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
146
147 ctx->HL[i] = vl;
148 ctx->HH[i] = vh;
149 }
150
151 for( i = 2; i <= 8; i *= 2 )
152 {
153 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
154 vh = *HiH;
155 vl = *HiL;
156 for( j = 1; j < i; j++ )
157 {
158 HiH[j] = vh ^ ctx->HH[j];
159 HiL[j] = vl ^ ctx->HL[j];
160 }
161 }
162
163 return( 0 );
164 }
165
mbedtls_gcm_setkey(mbedtls_gcm_context * ctx,mbedtls_cipher_id_t cipher,const unsigned char * key,unsigned int keybits)166 int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
167 mbedtls_cipher_id_t cipher,
168 const unsigned char *key,
169 unsigned int keybits )
170 {
171 int ret;
172 const mbedtls_cipher_info_t *cipher_info;
173
174 GCM_VALIDATE_RET( ctx != NULL );
175 GCM_VALIDATE_RET( key != NULL );
176 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
177
178 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
179 if( cipher_info == NULL )
180 return( MBEDTLS_ERR_GCM_BAD_INPUT );
181
182 if( cipher_info->block_size != 16 )
183 return( MBEDTLS_ERR_GCM_BAD_INPUT );
184
185 mbedtls_cipher_free( &ctx->cipher_ctx );
186
187 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
188 return( ret );
189
190 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
191 MBEDTLS_ENCRYPT ) ) != 0 )
192 {
193 return( ret );
194 }
195
196 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
197 return( ret );
198
199 return( 0 );
200 }
201
202 /*
203 * Shoup's method for multiplication use this table with
204 * last4[x] = x times P^128
205 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
206 */
207 static const uint64_t last4[16] =
208 {
209 0x0000, 0x1c20, 0x3840, 0x2460,
210 0x7080, 0x6ca0, 0x48c0, 0x54e0,
211 0xe100, 0xfd20, 0xd940, 0xc560,
212 0x9180, 0x8da0, 0xa9c0, 0xb5e0
213 };
214
215 /*
216 * Sets output to x times H using the precomputed tables.
217 * x and output are seen as elements of GF(2^128) as in [MGV].
218 */
gcm_mult(mbedtls_gcm_context * ctx,const unsigned char x[16],unsigned char output[16])219 static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
220 unsigned char output[16] )
221 {
222 int i = 0;
223 unsigned char lo, hi, rem;
224 uint64_t zh, zl;
225
226 #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
227 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
228 unsigned char h[16];
229
230 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
231 PUT_UINT32_BE( ctx->HH[8], h, 4 );
232 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
233 PUT_UINT32_BE( ctx->HL[8], h, 12 );
234
235 mbedtls_aesni_gcm_mult( output, x, h );
236 return;
237 }
238 #endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
239
240 lo = x[15] & 0xf;
241
242 zh = ctx->HH[lo];
243 zl = ctx->HL[lo];
244
245 for( i = 15; i >= 0; i-- )
246 {
247 lo = x[i] & 0xf;
248 hi = x[i] >> 4;
249
250 if( i != 15 )
251 {
252 rem = (unsigned char) zl & 0xf;
253 zl = ( zh << 60 ) | ( zl >> 4 );
254 zh = ( zh >> 4 );
255 zh ^= (uint64_t) last4[rem] << 48;
256 zh ^= ctx->HH[lo];
257 zl ^= ctx->HL[lo];
258
259 }
260
261 rem = (unsigned char) zl & 0xf;
262 zl = ( zh << 60 ) | ( zl >> 4 );
263 zh = ( zh >> 4 );
264 zh ^= (uint64_t) last4[rem] << 48;
265 zh ^= ctx->HH[hi];
266 zl ^= ctx->HL[hi];
267 }
268
269 PUT_UINT32_BE( zh >> 32, output, 0 );
270 PUT_UINT32_BE( zh, output, 4 );
271 PUT_UINT32_BE( zl >> 32, output, 8 );
272 PUT_UINT32_BE( zl, output, 12 );
273 }
274
mbedtls_gcm_starts(mbedtls_gcm_context * ctx,int mode,const unsigned char * iv,size_t iv_len,const unsigned char * add,size_t add_len)275 int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
276 int mode,
277 const unsigned char *iv,
278 size_t iv_len,
279 const unsigned char *add,
280 size_t add_len )
281 {
282 int ret;
283 unsigned char work_buf[16];
284 size_t i;
285 const unsigned char *p;
286 size_t use_len, olen = 0;
287
288 GCM_VALIDATE_RET( ctx != NULL );
289 GCM_VALIDATE_RET( iv != NULL );
290 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
291
292 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
293 /* IV is not allowed to be zero length */
294 if( iv_len == 0 ||
295 ( (uint64_t) iv_len ) >> 61 != 0 ||
296 ( (uint64_t) add_len ) >> 61 != 0 )
297 {
298 return( MBEDTLS_ERR_GCM_BAD_INPUT );
299 }
300
301 memset( ctx->y, 0x00, sizeof(ctx->y) );
302 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
303
304 ctx->mode = mode;
305 ctx->len = 0;
306 ctx->add_len = 0;
307
308 if( iv_len == 12 )
309 {
310 memcpy( ctx->y, iv, iv_len );
311 ctx->y[15] = 1;
312 }
313 else
314 {
315 memset( work_buf, 0x00, 16 );
316 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
317
318 p = iv;
319 while( iv_len > 0 )
320 {
321 use_len = ( iv_len < 16 ) ? iv_len : 16;
322
323 for( i = 0; i < use_len; i++ )
324 ctx->y[i] ^= p[i];
325
326 gcm_mult( ctx, ctx->y, ctx->y );
327
328 iv_len -= use_len;
329 p += use_len;
330 }
331
332 for( i = 0; i < 16; i++ )
333 ctx->y[i] ^= work_buf[i];
334
335 gcm_mult( ctx, ctx->y, ctx->y );
336 }
337
338 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
339 &olen ) ) != 0 )
340 {
341 return( ret );
342 }
343
344 ctx->add_len = add_len;
345 p = add;
346 while( add_len > 0 )
347 {
348 use_len = ( add_len < 16 ) ? add_len : 16;
349
350 for( i = 0; i < use_len; i++ )
351 ctx->buf[i] ^= p[i];
352
353 gcm_mult( ctx, ctx->buf, ctx->buf );
354
355 add_len -= use_len;
356 p += use_len;
357 }
358
359 return( 0 );
360 }
361
mbedtls_gcm_update(mbedtls_gcm_context * ctx,size_t length,const unsigned char * input,unsigned char * output)362 int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
363 size_t length,
364 const unsigned char *input,
365 unsigned char *output )
366 {
367 int ret;
368 unsigned char ectr[16];
369 size_t i;
370 const unsigned char *p;
371 unsigned char *out_p = output;
372 size_t use_len, olen = 0;
373
374 GCM_VALIDATE_RET( ctx != NULL );
375 GCM_VALIDATE_RET( length == 0 || input != NULL );
376 GCM_VALIDATE_RET( length == 0 || output != NULL );
377
378 if( output > input && (size_t) ( output - input ) < length )
379 return( MBEDTLS_ERR_GCM_BAD_INPUT );
380
381 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
382 * Also check for possible overflow */
383 if( ctx->len + length < ctx->len ||
384 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
385 {
386 return( MBEDTLS_ERR_GCM_BAD_INPUT );
387 }
388
389 ctx->len += length;
390
391 p = input;
392 while( length > 0 )
393 {
394 use_len = ( length < 16 ) ? length : 16;
395
396 for( i = 16; i > 12; i-- )
397 if( ++ctx->y[i - 1] != 0 )
398 break;
399
400 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
401 &olen ) ) != 0 )
402 {
403 return( ret );
404 }
405
406 for( i = 0; i < use_len; i++ )
407 {
408 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
409 ctx->buf[i] ^= p[i];
410 out_p[i] = ectr[i] ^ p[i];
411 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
412 ctx->buf[i] ^= out_p[i];
413 }
414
415 gcm_mult( ctx, ctx->buf, ctx->buf );
416
417 length -= use_len;
418 p += use_len;
419 out_p += use_len;
420 }
421
422 return( 0 );
423 }
424
mbedtls_gcm_finish(mbedtls_gcm_context * ctx,unsigned char * tag,size_t tag_len)425 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
426 unsigned char *tag,
427 size_t tag_len )
428 {
429 unsigned char work_buf[16];
430 size_t i;
431 uint64_t orig_len;
432 uint64_t orig_add_len;
433
434 GCM_VALIDATE_RET( ctx != NULL );
435 GCM_VALIDATE_RET( tag != NULL );
436
437 orig_len = ctx->len * 8;
438 orig_add_len = ctx->add_len * 8;
439
440 if( tag_len > 16 || tag_len < 4 )
441 return( MBEDTLS_ERR_GCM_BAD_INPUT );
442
443 memcpy( tag, ctx->base_ectr, tag_len );
444
445 if( orig_len || orig_add_len )
446 {
447 memset( work_buf, 0x00, 16 );
448
449 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
450 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
451 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
452 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
453
454 for( i = 0; i < 16; i++ )
455 ctx->buf[i] ^= work_buf[i];
456
457 gcm_mult( ctx, ctx->buf, ctx->buf );
458
459 for( i = 0; i < tag_len; i++ )
460 tag[i] ^= ctx->buf[i];
461 }
462
463 return( 0 );
464 }
465
mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context * ctx,int mode,size_t length,const unsigned char * iv,size_t iv_len,const unsigned char * add,size_t add_len,const unsigned char * input,unsigned char * output,size_t tag_len,unsigned char * tag)466 int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
467 int mode,
468 size_t length,
469 const unsigned char *iv,
470 size_t iv_len,
471 const unsigned char *add,
472 size_t add_len,
473 const unsigned char *input,
474 unsigned char *output,
475 size_t tag_len,
476 unsigned char *tag )
477 {
478 int ret;
479
480 GCM_VALIDATE_RET( ctx != NULL );
481 GCM_VALIDATE_RET( iv != NULL );
482 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
483 GCM_VALIDATE_RET( length == 0 || input != NULL );
484 GCM_VALIDATE_RET( length == 0 || output != NULL );
485 GCM_VALIDATE_RET( tag != NULL );
486
487 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
488 return( ret );
489
490 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
491 return( ret );
492
493 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
494 return( ret );
495
496 return( 0 );
497 }
498
mbedtls_gcm_auth_decrypt(mbedtls_gcm_context * ctx,size_t length,const unsigned char * iv,size_t iv_len,const unsigned char * add,size_t add_len,const unsigned char * tag,size_t tag_len,const unsigned char * input,unsigned char * output)499 int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
500 size_t length,
501 const unsigned char *iv,
502 size_t iv_len,
503 const unsigned char *add,
504 size_t add_len,
505 const unsigned char *tag,
506 size_t tag_len,
507 const unsigned char *input,
508 unsigned char *output )
509 {
510 int ret;
511 unsigned char check_tag[16];
512 size_t i;
513 int diff;
514
515 GCM_VALIDATE_RET( ctx != NULL );
516 GCM_VALIDATE_RET( iv != NULL );
517 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
518 GCM_VALIDATE_RET( tag != NULL );
519 GCM_VALIDATE_RET( length == 0 || input != NULL );
520 GCM_VALIDATE_RET( length == 0 || output != NULL );
521
522 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
523 iv, iv_len, add, add_len,
524 input, output, tag_len, check_tag ) ) != 0 )
525 {
526 return( ret );
527 }
528
529 /* Check tag in "constant-time" */
530 for( diff = 0, i = 0; i < tag_len; i++ )
531 diff |= tag[i] ^ check_tag[i];
532
533 if( diff != 0 )
534 {
535 mbedtls_platform_zeroize( output, length );
536 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
537 }
538
539 return( 0 );
540 }
541
mbedtls_gcm_free(mbedtls_gcm_context * ctx)542 void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
543 {
544 if( ctx == NULL )
545 return;
546 mbedtls_cipher_free( &ctx->cipher_ctx );
547 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
548 }
549
550 #endif /* !MBEDTLS_GCM_ALT */
551
552 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
553 /*
554 * AES-GCM test vectors from:
555 *
556 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
557 */
558 #define MAX_TESTS 6
559
560 static const int key_index[MAX_TESTS] =
561 { 0, 0, 1, 1, 1, 1 };
562
563 static const unsigned char key[MAX_TESTS][32] =
564 {
565 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
569 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
570 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
571 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
572 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
573 };
574
575 static const size_t iv_len[MAX_TESTS] =
576 { 12, 12, 12, 12, 8, 60 };
577
578 static const int iv_index[MAX_TESTS] =
579 { 0, 0, 1, 1, 1, 2 };
580
581 static const unsigned char iv[MAX_TESTS][64] =
582 {
583 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00 },
585 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
586 0xde, 0xca, 0xf8, 0x88 },
587 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
588 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
589 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
590 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
591 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
592 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
593 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
594 0xa6, 0x37, 0xb3, 0x9b },
595 };
596
597 static const size_t add_len[MAX_TESTS] =
598 { 0, 0, 0, 20, 20, 20 };
599
600 static const int add_index[MAX_TESTS] =
601 { 0, 0, 0, 1, 1, 1 };
602
603 static const unsigned char additional[MAX_TESTS][64] =
604 {
605 { 0x00 },
606 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
607 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
608 0xab, 0xad, 0xda, 0xd2 },
609 };
610
611 static const size_t pt_len[MAX_TESTS] =
612 { 0, 16, 64, 60, 60, 60 };
613
614 static const int pt_index[MAX_TESTS] =
615 { 0, 0, 1, 1, 1, 1 };
616
617 static const unsigned char pt[MAX_TESTS][64] =
618 {
619 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
621 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
622 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
623 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
624 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
625 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
626 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
627 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
628 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
629 };
630
631 static const unsigned char ct[MAX_TESTS * 3][64] =
632 {
633 { 0x00 },
634 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
635 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
636 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
637 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
638 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
639 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
640 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
641 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
642 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
643 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
644 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
645 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
646 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
647 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
648 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
649 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
650 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
651 0x3d, 0x58, 0xe0, 0x91 },
652 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
653 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
654 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
655 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
656 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
657 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
658 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
659 0xc2, 0x3f, 0x45, 0x98 },
660 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
661 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
662 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
663 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
664 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
665 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
666 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
667 0x4c, 0x34, 0xae, 0xe5 },
668 { 0x00 },
669 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
670 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
671 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
672 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
673 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
674 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
675 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
676 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
677 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
678 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
679 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
680 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
681 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
682 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
683 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
684 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
685 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
686 0xcc, 0xda, 0x27, 0x10 },
687 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
688 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
689 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
690 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
691 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
692 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
693 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
694 0xa0, 0xf0, 0x62, 0xf7 },
695 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
696 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
697 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
698 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
699 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
700 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
701 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
702 0xe9, 0xb7, 0x37, 0x3b },
703 { 0x00 },
704 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
705 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
706 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
707 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
708 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
709 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
710 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
711 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
712 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
713 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
714 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
715 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
716 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
717 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
718 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
719 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
720 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
721 0xbc, 0xc9, 0xf6, 0x62 },
722 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
723 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
724 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
725 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
726 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
727 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
728 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
729 0xf4, 0x7c, 0x9b, 0x1f },
730 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
731 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
732 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
733 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
734 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
735 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
736 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
737 0x44, 0xae, 0x7e, 0x3f },
738 };
739
740 static const unsigned char tag[MAX_TESTS * 3][16] =
741 {
742 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
743 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
744 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
745 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
746 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
747 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
748 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
749 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
750 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
751 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
752 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
753 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
754 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
755 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
756 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
757 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
758 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
759 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
760 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
761 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
762 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
763 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
764 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
765 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
766 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
767 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
768 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
769 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
770 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
771 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
772 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
773 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
774 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
775 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
776 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
777 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
778 };
779
mbedtls_gcm_self_test(int verbose)780 int mbedtls_gcm_self_test( int verbose )
781 {
782 mbedtls_gcm_context ctx;
783 unsigned char buf[64];
784 unsigned char tag_buf[16];
785 int i, j, ret;
786 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
787
788 for( j = 0; j < 3; j++ )
789 {
790 int key_len = 128 + 64 * j;
791
792 for( i = 0; i < MAX_TESTS; i++ )
793 {
794 mbedtls_gcm_init( &ctx );
795
796 if( verbose != 0 )
797 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
798 key_len, i, "enc" );
799
800 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
801 key_len );
802 /*
803 * AES-192 is an optional feature that may be unavailable when
804 * there is an alternative underlying implementation i.e. when
805 * MBEDTLS_AES_ALT is defined.
806 */
807 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
808 {
809 mbedtls_printf( "skipped\n" );
810 break;
811 }
812 else if( ret != 0 )
813 {
814 goto exit;
815 }
816
817 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
818 pt_len[i],
819 iv[iv_index[i]], iv_len[i],
820 additional[add_index[i]], add_len[i],
821 pt[pt_index[i]], buf, 16, tag_buf );
822 if( ret != 0 )
823 goto exit;
824
825 if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
826 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
827 {
828 ret = 1;
829 goto exit;
830 }
831
832 mbedtls_gcm_free( &ctx );
833
834 if( verbose != 0 )
835 mbedtls_printf( "passed\n" );
836
837 mbedtls_gcm_init( &ctx );
838
839 if( verbose != 0 )
840 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
841 key_len, i, "dec" );
842
843 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
844 key_len );
845 if( ret != 0 )
846 goto exit;
847
848 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
849 pt_len[i],
850 iv[iv_index[i]], iv_len[i],
851 additional[add_index[i]], add_len[i],
852 ct[j * 6 + i], buf, 16, tag_buf );
853
854 if( ret != 0 )
855 goto exit;
856
857 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
858 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
859 {
860 ret = 1;
861 goto exit;
862 }
863
864 mbedtls_gcm_free( &ctx );
865
866 if( verbose != 0 )
867 mbedtls_printf( "passed\n" );
868
869 mbedtls_gcm_init( &ctx );
870
871 if( verbose != 0 )
872 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
873 key_len, i, "enc" );
874
875 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
876 key_len );
877 if( ret != 0 )
878 goto exit;
879
880 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
881 iv[iv_index[i]], iv_len[i],
882 additional[add_index[i]], add_len[i] );
883 if( ret != 0 )
884 goto exit;
885
886 if( pt_len[i] > 32 )
887 {
888 size_t rest_len = pt_len[i] - 32;
889 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
890 if( ret != 0 )
891 goto exit;
892
893 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
894 buf + 32 );
895 if( ret != 0 )
896 goto exit;
897 }
898 else
899 {
900 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
901 if( ret != 0 )
902 goto exit;
903 }
904
905 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
906 if( ret != 0 )
907 goto exit;
908
909 if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
910 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
911 {
912 ret = 1;
913 goto exit;
914 }
915
916 mbedtls_gcm_free( &ctx );
917
918 if( verbose != 0 )
919 mbedtls_printf( "passed\n" );
920
921 mbedtls_gcm_init( &ctx );
922
923 if( verbose != 0 )
924 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
925 key_len, i, "dec" );
926
927 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
928 key_len );
929 if( ret != 0 )
930 goto exit;
931
932 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
933 iv[iv_index[i]], iv_len[i],
934 additional[add_index[i]], add_len[i] );
935 if( ret != 0 )
936 goto exit;
937
938 if( pt_len[i] > 32 )
939 {
940 size_t rest_len = pt_len[i] - 32;
941 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
942 if( ret != 0 )
943 goto exit;
944
945 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
946 buf + 32 );
947 if( ret != 0 )
948 goto exit;
949 }
950 else
951 {
952 ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
953 buf );
954 if( ret != 0 )
955 goto exit;
956 }
957
958 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
959 if( ret != 0 )
960 goto exit;
961
962 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
963 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
964 {
965 ret = 1;
966 goto exit;
967 }
968
969 mbedtls_gcm_free( &ctx );
970
971 if( verbose != 0 )
972 mbedtls_printf( "passed\n" );
973 }
974 }
975
976 if( verbose != 0 )
977 mbedtls_printf( "\n" );
978
979 ret = 0;
980
981 exit:
982 if( ret != 0 )
983 {
984 if( verbose != 0 )
985 mbedtls_printf( "failed\n" );
986 mbedtls_gcm_free( &ctx );
987 }
988
989 return( ret );
990 }
991
992 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
993
994 #endif /* MBEDTLS_GCM_C */
995