Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

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