gcm.c 32 KB

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