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