gcm.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
  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. /*
  8. * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
  9. *
  10. * See also:
  11. * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
  12. *
  13. * We use the algorithm described as Shoup's method with 4-bit tables in
  14. * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
  15. */
  16. #include "common.h"
  17. #if defined(MBEDTLS_GCM_C)
  18. #include "mbedtls/gcm.h"
  19. #include "mbedtls/platform.h"
  20. #include "mbedtls/platform_util.h"
  21. #include "mbedtls/error.h"
  22. #include "mbedtls/constant_time.h"
  23. #if defined(MBEDTLS_BLOCK_CIPHER_C)
  24. #include "block_cipher_internal.h"
  25. #endif
  26. #include <string.h>
  27. #if defined(MBEDTLS_AESNI_C)
  28. #include "aesni.h"
  29. #endif
  30. #if defined(MBEDTLS_AESCE_C)
  31. #include "aesce.h"
  32. #endif
  33. #if !defined(MBEDTLS_GCM_ALT)
  34. /* Used to select the acceleration mechanism */
  35. #define MBEDTLS_GCM_ACC_SMALLTABLE 0
  36. #define MBEDTLS_GCM_ACC_LARGETABLE 1
  37. #define MBEDTLS_GCM_ACC_AESNI 2
  38. #define MBEDTLS_GCM_ACC_AESCE 3
  39. /*
  40. * Initialize a context
  41. */
  42. void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
  43. {
  44. memset(ctx, 0, sizeof(mbedtls_gcm_context));
  45. }
  46. static inline void gcm_set_acceleration(mbedtls_gcm_context *ctx)
  47. {
  48. #if defined(MBEDTLS_GCM_LARGE_TABLE)
  49. ctx->acceleration = MBEDTLS_GCM_ACC_LARGETABLE;
  50. #else
  51. ctx->acceleration = MBEDTLS_GCM_ACC_SMALLTABLE;
  52. #endif
  53. #if defined(MBEDTLS_AESNI_HAVE_CODE)
  54. /* With CLMUL support, we need only h, not the rest of the table */
  55. if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
  56. ctx->acceleration = MBEDTLS_GCM_ACC_AESNI;
  57. }
  58. #endif
  59. #if defined(MBEDTLS_AESCE_HAVE_CODE)
  60. if (MBEDTLS_AESCE_HAS_SUPPORT()) {
  61. ctx->acceleration = MBEDTLS_GCM_ACC_AESCE;
  62. }
  63. #endif
  64. }
  65. static inline void gcm_gen_table_rightshift(uint64_t dst[2], const uint64_t src[2])
  66. {
  67. uint8_t *u8Dst = (uint8_t *) dst;
  68. uint8_t *u8Src = (uint8_t *) src;
  69. MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[1], 0) >> 1, &dst[1], 0);
  70. u8Dst[8] |= (u8Src[7] & 0x01) << 7;
  71. MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[0], 0) >> 1, &dst[0], 0);
  72. u8Dst[0] ^= (u8Src[15] & 0x01) ? 0xE1 : 0;
  73. }
  74. /*
  75. * Precompute small multiples of H, that is set
  76. * HH[i] || HL[i] = H times i,
  77. * where i is seen as a field element as in [MGV], ie high-order bits
  78. * correspond to low powers of P. The result is stored in the same way, that
  79. * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
  80. * corresponds to P^127.
  81. */
  82. static int gcm_gen_table(mbedtls_gcm_context *ctx)
  83. {
  84. int ret, i, j;
  85. uint64_t u64h[2] = { 0 };
  86. uint8_t *h = (uint8_t *) u64h;
  87. #if defined(MBEDTLS_BLOCK_CIPHER_C)
  88. ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, h, h);
  89. #else
  90. size_t olen = 0;
  91. ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen);
  92. #endif
  93. if (ret != 0) {
  94. return ret;
  95. }
  96. gcm_set_acceleration(ctx);
  97. /* MBEDTLS_GCM_HTABLE_SIZE/2 = 1000 corresponds to 1 in GF(2^128) */
  98. ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][0] = u64h[0];
  99. ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][1] = u64h[1];
  100. switch (ctx->acceleration) {
  101. #if defined(MBEDTLS_AESNI_HAVE_CODE)
  102. case MBEDTLS_GCM_ACC_AESNI:
  103. return 0;
  104. #endif
  105. #if defined(MBEDTLS_AESCE_HAVE_CODE)
  106. case MBEDTLS_GCM_ACC_AESCE:
  107. return 0;
  108. #endif
  109. default:
  110. /* 0 corresponds to 0 in GF(2^128) */
  111. ctx->H[0][0] = 0;
  112. ctx->H[0][1] = 0;
  113. for (i = MBEDTLS_GCM_HTABLE_SIZE/4; i > 0; i >>= 1) {
  114. gcm_gen_table_rightshift(ctx->H[i], ctx->H[i*2]);
  115. }
  116. #if !defined(MBEDTLS_GCM_LARGE_TABLE)
  117. /* pack elements of H as 64-bits ints, big-endian */
  118. for (i = MBEDTLS_GCM_HTABLE_SIZE/2; i > 0; i >>= 1) {
  119. MBEDTLS_PUT_UINT64_BE(ctx->H[i][0], &ctx->H[i][0], 0);
  120. MBEDTLS_PUT_UINT64_BE(ctx->H[i][1], &ctx->H[i][1], 0);
  121. }
  122. #endif
  123. for (i = 2; i < MBEDTLS_GCM_HTABLE_SIZE; i <<= 1) {
  124. for (j = 1; j < i; j++) {
  125. mbedtls_xor_no_simd((unsigned char *) ctx->H[i+j],
  126. (unsigned char *) ctx->H[i],
  127. (unsigned char *) ctx->H[j],
  128. 16);
  129. }
  130. }
  131. }
  132. return 0;
  133. }
  134. int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
  135. mbedtls_cipher_id_t cipher,
  136. const unsigned char *key,
  137. unsigned int keybits)
  138. {
  139. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  140. if (keybits != 128 && keybits != 192 && keybits != 256) {
  141. return MBEDTLS_ERR_GCM_BAD_INPUT;
  142. }
  143. #if defined(MBEDTLS_BLOCK_CIPHER_C)
  144. mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
  145. if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) {
  146. return ret;
  147. }
  148. if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) {
  149. return ret;
  150. }
  151. #else
  152. const mbedtls_cipher_info_t *cipher_info;
  153. cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
  154. MBEDTLS_MODE_ECB);
  155. if (cipher_info == NULL) {
  156. return MBEDTLS_ERR_GCM_BAD_INPUT;
  157. }
  158. if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) {
  159. return MBEDTLS_ERR_GCM_BAD_INPUT;
  160. }
  161. mbedtls_cipher_free(&ctx->cipher_ctx);
  162. if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) {
  163. return ret;
  164. }
  165. if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits,
  166. MBEDTLS_ENCRYPT)) != 0) {
  167. return ret;
  168. }
  169. #endif
  170. if ((ret = gcm_gen_table(ctx)) != 0) {
  171. return ret;
  172. }
  173. return 0;
  174. }
  175. #if defined(MBEDTLS_GCM_LARGE_TABLE)
  176. static const uint16_t last8[256] = {
  177. 0x0000, 0xc201, 0x8403, 0x4602, 0x0807, 0xca06, 0x8c04, 0x4e05,
  178. 0x100e, 0xd20f, 0x940d, 0x560c, 0x1809, 0xda08, 0x9c0a, 0x5e0b,
  179. 0x201c, 0xe21d, 0xa41f, 0x661e, 0x281b, 0xea1a, 0xac18, 0x6e19,
  180. 0x3012, 0xf213, 0xb411, 0x7610, 0x3815, 0xfa14, 0xbc16, 0x7e17,
  181. 0x4038, 0x8239, 0xc43b, 0x063a, 0x483f, 0x8a3e, 0xcc3c, 0x0e3d,
  182. 0x5036, 0x9237, 0xd435, 0x1634, 0x5831, 0x9a30, 0xdc32, 0x1e33,
  183. 0x6024, 0xa225, 0xe427, 0x2626, 0x6823, 0xaa22, 0xec20, 0x2e21,
  184. 0x702a, 0xb22b, 0xf429, 0x3628, 0x782d, 0xba2c, 0xfc2e, 0x3e2f,
  185. 0x8070, 0x4271, 0x0473, 0xc672, 0x8877, 0x4a76, 0x0c74, 0xce75,
  186. 0x907e, 0x527f, 0x147d, 0xd67c, 0x9879, 0x5a78, 0x1c7a, 0xde7b,
  187. 0xa06c, 0x626d, 0x246f, 0xe66e, 0xa86b, 0x6a6a, 0x2c68, 0xee69,
  188. 0xb062, 0x7263, 0x3461, 0xf660, 0xb865, 0x7a64, 0x3c66, 0xfe67,
  189. 0xc048, 0x0249, 0x444b, 0x864a, 0xc84f, 0x0a4e, 0x4c4c, 0x8e4d,
  190. 0xd046, 0x1247, 0x5445, 0x9644, 0xd841, 0x1a40, 0x5c42, 0x9e43,
  191. 0xe054, 0x2255, 0x6457, 0xa656, 0xe853, 0x2a52, 0x6c50, 0xae51,
  192. 0xf05a, 0x325b, 0x7459, 0xb658, 0xf85d, 0x3a5c, 0x7c5e, 0xbe5f,
  193. 0x00e1, 0xc2e0, 0x84e2, 0x46e3, 0x08e6, 0xcae7, 0x8ce5, 0x4ee4,
  194. 0x10ef, 0xd2ee, 0x94ec, 0x56ed, 0x18e8, 0xdae9, 0x9ceb, 0x5eea,
  195. 0x20fd, 0xe2fc, 0xa4fe, 0x66ff, 0x28fa, 0xeafb, 0xacf9, 0x6ef8,
  196. 0x30f3, 0xf2f2, 0xb4f0, 0x76f1, 0x38f4, 0xfaf5, 0xbcf7, 0x7ef6,
  197. 0x40d9, 0x82d8, 0xc4da, 0x06db, 0x48de, 0x8adf, 0xccdd, 0x0edc,
  198. 0x50d7, 0x92d6, 0xd4d4, 0x16d5, 0x58d0, 0x9ad1, 0xdcd3, 0x1ed2,
  199. 0x60c5, 0xa2c4, 0xe4c6, 0x26c7, 0x68c2, 0xaac3, 0xecc1, 0x2ec0,
  200. 0x70cb, 0xb2ca, 0xf4c8, 0x36c9, 0x78cc, 0xbacd, 0xfccf, 0x3ece,
  201. 0x8091, 0x4290, 0x0492, 0xc693, 0x8896, 0x4a97, 0x0c95, 0xce94,
  202. 0x909f, 0x529e, 0x149c, 0xd69d, 0x9898, 0x5a99, 0x1c9b, 0xde9a,
  203. 0xa08d, 0x628c, 0x248e, 0xe68f, 0xa88a, 0x6a8b, 0x2c89, 0xee88,
  204. 0xb083, 0x7282, 0x3480, 0xf681, 0xb884, 0x7a85, 0x3c87, 0xfe86,
  205. 0xc0a9, 0x02a8, 0x44aa, 0x86ab, 0xc8ae, 0x0aaf, 0x4cad, 0x8eac,
  206. 0xd0a7, 0x12a6, 0x54a4, 0x96a5, 0xd8a0, 0x1aa1, 0x5ca3, 0x9ea2,
  207. 0xe0b5, 0x22b4, 0x64b6, 0xa6b7, 0xe8b2, 0x2ab3, 0x6cb1, 0xaeb0,
  208. 0xf0bb, 0x32ba, 0x74b8, 0xb6b9, 0xf8bc, 0x3abd, 0x7cbf, 0xbebe
  209. };
  210. static void gcm_mult_largetable(uint8_t *output, const uint8_t *x, uint64_t H[256][2])
  211. {
  212. int i;
  213. uint64_t u64z[2];
  214. uint16_t *u16z = (uint16_t *) u64z;
  215. uint8_t *u8z = (uint8_t *) u64z;
  216. uint8_t rem;
  217. u64z[0] = 0;
  218. u64z[1] = 0;
  219. if (MBEDTLS_IS_BIG_ENDIAN) {
  220. for (i = 15; i > 0; i--) {
  221. mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16);
  222. rem = u8z[15];
  223. u64z[1] >>= 8;
  224. u8z[8] = u8z[7];
  225. u64z[0] >>= 8;
  226. u16z[0] ^= MBEDTLS_GET_UINT16_LE(&last8[rem], 0);
  227. }
  228. } else {
  229. for (i = 15; i > 0; i--) {
  230. mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16);
  231. rem = u8z[15];
  232. u64z[1] <<= 8;
  233. u8z[8] = u8z[7];
  234. u64z[0] <<= 8;
  235. u16z[0] ^= last8[rem];
  236. }
  237. }
  238. mbedtls_xor_no_simd(output, u8z, (uint8_t *) H[x[0]], 16);
  239. }
  240. #else
  241. /*
  242. * Shoup's method for multiplication use this table with
  243. * last4[x] = x times P^128
  244. * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
  245. */
  246. static const uint16_t last4[16] =
  247. {
  248. 0x0000, 0x1c20, 0x3840, 0x2460,
  249. 0x7080, 0x6ca0, 0x48c0, 0x54e0,
  250. 0xe100, 0xfd20, 0xd940, 0xc560,
  251. 0x9180, 0x8da0, 0xa9c0, 0xb5e0
  252. };
  253. static void gcm_mult_smalltable(uint8_t *output, const uint8_t *x, uint64_t H[16][2])
  254. {
  255. int i = 0;
  256. unsigned char lo, hi, rem;
  257. uint64_t u64z[2];
  258. const uint64_t *pu64z = NULL;
  259. uint8_t *u8z = (uint8_t *) u64z;
  260. lo = x[15] & 0xf;
  261. hi = (x[15] >> 4) & 0xf;
  262. pu64z = H[lo];
  263. rem = (unsigned char) pu64z[1] & 0xf;
  264. u64z[1] = (pu64z[0] << 60) | (pu64z[1] >> 4);
  265. u64z[0] = (pu64z[0] >> 4);
  266. u64z[0] ^= (uint64_t) last4[rem] << 48;
  267. mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16);
  268. for (i = 14; i >= 0; i--) {
  269. lo = x[i] & 0xf;
  270. hi = (x[i] >> 4) & 0xf;
  271. rem = (unsigned char) u64z[1] & 0xf;
  272. u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4);
  273. u64z[0] = (u64z[0] >> 4);
  274. u64z[0] ^= (uint64_t) last4[rem] << 48;
  275. mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[lo], 16);
  276. rem = (unsigned char) u64z[1] & 0xf;
  277. u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4);
  278. u64z[0] = (u64z[0] >> 4);
  279. u64z[0] ^= (uint64_t) last4[rem] << 48;
  280. mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16);
  281. }
  282. MBEDTLS_PUT_UINT64_BE(u64z[0], output, 0);
  283. MBEDTLS_PUT_UINT64_BE(u64z[1], output, 8);
  284. }
  285. #endif
  286. /*
  287. * Sets output to x times H using the precomputed tables.
  288. * x and output are seen as elements of GF(2^128) as in [MGV].
  289. */
  290. static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16],
  291. unsigned char output[16])
  292. {
  293. switch (ctx->acceleration) {
  294. #if defined(MBEDTLS_AESNI_HAVE_CODE)
  295. case MBEDTLS_GCM_ACC_AESNI:
  296. mbedtls_aesni_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
  297. break;
  298. #endif
  299. #if defined(MBEDTLS_AESCE_HAVE_CODE)
  300. case MBEDTLS_GCM_ACC_AESCE:
  301. mbedtls_aesce_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
  302. break;
  303. #endif
  304. #if defined(MBEDTLS_GCM_LARGE_TABLE)
  305. case MBEDTLS_GCM_ACC_LARGETABLE:
  306. gcm_mult_largetable(output, x, ctx->H);
  307. break;
  308. #else
  309. case MBEDTLS_GCM_ACC_SMALLTABLE:
  310. gcm_mult_smalltable(output, x, ctx->H);
  311. break;
  312. #endif
  313. }
  314. return;
  315. }
  316. int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
  317. int mode,
  318. const unsigned char *iv, size_t iv_len)
  319. {
  320. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  321. unsigned char work_buf[16];
  322. const unsigned char *p;
  323. size_t use_len;
  324. uint64_t iv_bits;
  325. #if !defined(MBEDTLS_BLOCK_CIPHER_C)
  326. size_t olen = 0;
  327. #endif
  328. /* IV is limited to 2^64 bits, so 2^61 bytes */
  329. /* IV is not allowed to be zero length */
  330. if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) {
  331. return MBEDTLS_ERR_GCM_BAD_INPUT;
  332. }
  333. memset(ctx->y, 0x00, sizeof(ctx->y));
  334. memset(ctx->buf, 0x00, sizeof(ctx->buf));
  335. ctx->mode = mode;
  336. ctx->len = 0;
  337. ctx->add_len = 0;
  338. if (iv_len == 12) {
  339. memcpy(ctx->y, iv, iv_len);
  340. ctx->y[15] = 1;
  341. } else {
  342. memset(work_buf, 0x00, 16);
  343. iv_bits = (uint64_t) iv_len * 8;
  344. MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8);
  345. p = iv;
  346. while (iv_len > 0) {
  347. use_len = (iv_len < 16) ? iv_len : 16;
  348. #if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110)
  349. #pragma GCC diagnostic push
  350. #pragma GCC diagnostic warning "-Wstringop-overflow=0"
  351. #endif
  352. mbedtls_xor(ctx->y, ctx->y, p, use_len);
  353. #if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110)
  354. #pragma GCC diagnostic pop
  355. #endif
  356. gcm_mult(ctx, ctx->y, ctx->y);
  357. iv_len -= use_len;
  358. p += use_len;
  359. }
  360. mbedtls_xor(ctx->y, ctx->y, work_buf, 16);
  361. gcm_mult(ctx, ctx->y, ctx->y);
  362. }
  363. #if defined(MBEDTLS_BLOCK_CIPHER_C)
  364. ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->base_ectr);
  365. #else
  366. ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, &olen);
  367. #endif
  368. if (ret != 0) {
  369. return ret;
  370. }
  371. return 0;
  372. }
  373. /**
  374. * mbedtls_gcm_context::buf contains the partial state of the computation of
  375. * the authentication tag.
  376. * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
  377. * different stages of the computation:
  378. * * len == 0 && add_len == 0: initial state
  379. * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
  380. * a partial block of AD that has been
  381. * xored in but not yet multiplied in.
  382. * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
  383. * the data ends now.
  384. * * len % 16 != 0: the first `len % 16` bytes have
  385. * a partial block of ciphertext that has
  386. * been xored in but not yet multiplied in.
  387. * * len > 0 && len % 16 == 0: the authentication tag is correct if
  388. * the data ends now.
  389. */
  390. int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx,
  391. const unsigned char *add, size_t add_len)
  392. {
  393. const unsigned char *p;
  394. size_t use_len, offset;
  395. uint64_t new_add_len;
  396. /* AD is limited to 2^64 bits, ie 2^61 bytes
  397. * Also check for possible overflow */
  398. #if SIZE_MAX > 0xFFFFFFFFFFFFFFFFULL
  399. if (add_len > 0xFFFFFFFFFFFFFFFFULL) {
  400. return MBEDTLS_ERR_GCM_BAD_INPUT;
  401. }
  402. #endif
  403. new_add_len = ctx->add_len + (uint64_t) add_len;
  404. if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) {
  405. return MBEDTLS_ERR_GCM_BAD_INPUT;
  406. }
  407. offset = ctx->add_len % 16;
  408. p = add;
  409. if (offset != 0) {
  410. use_len = 16 - offset;
  411. if (use_len > add_len) {
  412. use_len = add_len;
  413. }
  414. mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len);
  415. if (offset + use_len == 16) {
  416. gcm_mult(ctx, ctx->buf, ctx->buf);
  417. }
  418. ctx->add_len += use_len;
  419. add_len -= use_len;
  420. p += use_len;
  421. }
  422. ctx->add_len += add_len;
  423. while (add_len >= 16) {
  424. mbedtls_xor(ctx->buf, ctx->buf, p, 16);
  425. gcm_mult(ctx, ctx->buf, ctx->buf);
  426. add_len -= 16;
  427. p += 16;
  428. }
  429. if (add_len > 0) {
  430. mbedtls_xor(ctx->buf, ctx->buf, p, add_len);
  431. }
  432. return 0;
  433. }
  434. /* Increment the counter. */
  435. static void gcm_incr(unsigned char y[16])
  436. {
  437. uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12);
  438. x++;
  439. MBEDTLS_PUT_UINT32_BE(x, y, 12);
  440. }
  441. /* Calculate and apply the encryption mask. Process use_len bytes of data,
  442. * starting at position offset in the mask block. */
  443. static int gcm_mask(mbedtls_gcm_context *ctx,
  444. unsigned char ectr[16],
  445. size_t offset, size_t use_len,
  446. const unsigned char *input,
  447. unsigned char *output)
  448. {
  449. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  450. #if defined(MBEDTLS_BLOCK_CIPHER_C)
  451. ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ectr);
  452. #else
  453. size_t olen = 0;
  454. ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen);
  455. #endif
  456. if (ret != 0) {
  457. mbedtls_platform_zeroize(ectr, 16);
  458. return ret;
  459. }
  460. if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
  461. mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len);
  462. }
  463. mbedtls_xor(output, ectr + offset, input, use_len);
  464. if (ctx->mode == MBEDTLS_GCM_ENCRYPT) {
  465. mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len);
  466. }
  467. return 0;
  468. }
  469. int mbedtls_gcm_update(mbedtls_gcm_context *ctx,
  470. const unsigned char *input, size_t input_length,
  471. unsigned char *output, size_t output_size,
  472. size_t *output_length)
  473. {
  474. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  475. const unsigned char *p = input;
  476. unsigned char *out_p = output;
  477. size_t offset;
  478. unsigned char ectr[16] = { 0 };
  479. if (output_size < input_length) {
  480. return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL;
  481. }
  482. *output_length = input_length;
  483. /* Exit early if input_length==0 so that we don't do any pointer arithmetic
  484. * on a potentially null pointer.
  485. * Returning early also means that the last partial block of AD remains
  486. * untouched for mbedtls_gcm_finish */
  487. if (input_length == 0) {
  488. return 0;
  489. }
  490. if (output > input && (size_t) (output - input) < input_length) {
  491. return MBEDTLS_ERR_GCM_BAD_INPUT;
  492. }
  493. /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
  494. * Also check for possible overflow */
  495. if (ctx->len + input_length < ctx->len ||
  496. (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) {
  497. return MBEDTLS_ERR_GCM_BAD_INPUT;
  498. }
  499. if (ctx->len == 0 && ctx->add_len % 16 != 0) {
  500. gcm_mult(ctx, ctx->buf, ctx->buf);
  501. }
  502. offset = ctx->len % 16;
  503. if (offset != 0) {
  504. size_t use_len = 16 - offset;
  505. if (use_len > input_length) {
  506. use_len = input_length;
  507. }
  508. if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) {
  509. return ret;
  510. }
  511. if (offset + use_len == 16) {
  512. gcm_mult(ctx, ctx->buf, ctx->buf);
  513. }
  514. ctx->len += use_len;
  515. input_length -= use_len;
  516. p += use_len;
  517. out_p += use_len;
  518. }
  519. ctx->len += input_length;
  520. while (input_length >= 16) {
  521. gcm_incr(ctx->y);
  522. if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) {
  523. return ret;
  524. }
  525. gcm_mult(ctx, ctx->buf, ctx->buf);
  526. input_length -= 16;
  527. p += 16;
  528. out_p += 16;
  529. }
  530. if (input_length > 0) {
  531. gcm_incr(ctx->y);
  532. if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) {
  533. return ret;
  534. }
  535. }
  536. mbedtls_platform_zeroize(ectr, sizeof(ectr));
  537. return 0;
  538. }
  539. int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
  540. unsigned char *output, size_t output_size,
  541. size_t *output_length,
  542. unsigned char *tag, size_t tag_len)
  543. {
  544. unsigned char work_buf[16];
  545. uint64_t orig_len;
  546. uint64_t orig_add_len;
  547. /* We never pass any output in finish(). The output parameter exists only
  548. * for the sake of alternative implementations. */
  549. (void) output;
  550. (void) output_size;
  551. *output_length = 0;
  552. /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
  553. * and AD length is restricted to 2^64 bits, ie 2^61 bytes so neither of
  554. * the two multiplications would overflow. */
  555. orig_len = ctx->len * 8;
  556. orig_add_len = ctx->add_len * 8;
  557. if (ctx->len == 0 && ctx->add_len % 16 != 0) {
  558. gcm_mult(ctx, ctx->buf, ctx->buf);
  559. }
  560. if (tag_len > 16 || tag_len < 4) {
  561. return MBEDTLS_ERR_GCM_BAD_INPUT;
  562. }
  563. if (ctx->len % 16 != 0) {
  564. gcm_mult(ctx, ctx->buf, ctx->buf);
  565. }
  566. memcpy(tag, ctx->base_ectr, tag_len);
  567. if (orig_len || orig_add_len) {
  568. memset(work_buf, 0x00, 16);
  569. MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
  570. MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
  571. MBEDTLS_PUT_UINT32_BE((orig_len >> 32), work_buf, 8);
  572. MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
  573. mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
  574. gcm_mult(ctx, ctx->buf, ctx->buf);
  575. mbedtls_xor(tag, tag, ctx->buf, tag_len);
  576. }
  577. return 0;
  578. }
  579. int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
  580. int mode,
  581. size_t length,
  582. const unsigned char *iv,
  583. size_t iv_len,
  584. const unsigned char *add,
  585. size_t add_len,
  586. const unsigned char *input,
  587. unsigned char *output,
  588. size_t tag_len,
  589. unsigned char *tag)
  590. {
  591. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  592. size_t olen;
  593. if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
  594. return ret;
  595. }
  596. if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
  597. return ret;
  598. }
  599. if ((ret = mbedtls_gcm_update(ctx, input, length,
  600. output, length, &olen)) != 0) {
  601. return ret;
  602. }
  603. if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
  604. return ret;
  605. }
  606. return 0;
  607. }
  608. int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
  609. size_t length,
  610. const unsigned char *iv,
  611. size_t iv_len,
  612. const unsigned char *add,
  613. size_t add_len,
  614. const unsigned char *tag,
  615. size_t tag_len,
  616. const unsigned char *input,
  617. unsigned char *output)
  618. {
  619. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  620. unsigned char check_tag[16];
  621. int diff;
  622. if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
  623. iv, iv_len, add, add_len,
  624. input, output, tag_len, check_tag)) != 0) {
  625. return ret;
  626. }
  627. /* Check tag in "constant-time" */
  628. diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
  629. if (diff != 0) {
  630. mbedtls_platform_zeroize(output, length);
  631. return MBEDTLS_ERR_GCM_AUTH_FAILED;
  632. }
  633. return 0;
  634. }
  635. void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
  636. {
  637. if (ctx == NULL) {
  638. return;
  639. }
  640. #if defined(MBEDTLS_BLOCK_CIPHER_C)
  641. mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
  642. #else
  643. mbedtls_cipher_free(&ctx->cipher_ctx);
  644. #endif
  645. mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
  646. }
  647. #endif /* !MBEDTLS_GCM_ALT */
  648. #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_CCM_GCM_CAN_AES)
  649. /*
  650. * AES-GCM test vectors from:
  651. *
  652. * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
  653. */
  654. #define MAX_TESTS 6
  655. static const int key_index_test_data[MAX_TESTS] =
  656. { 0, 0, 1, 1, 1, 1 };
  657. static const unsigned char key_test_data[][32] =
  658. {
  659. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  660. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  661. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  662. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  663. { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
  664. 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
  665. 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
  666. 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
  667. };
  668. static const size_t iv_len_test_data[MAX_TESTS] =
  669. { 12, 12, 12, 12, 8, 60 };
  670. static const int iv_index_test_data[MAX_TESTS] =
  671. { 0, 0, 1, 1, 1, 2 };
  672. static const unsigned char iv_test_data[][64] =
  673. {
  674. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  675. 0x00, 0x00, 0x00, 0x00 },
  676. { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
  677. 0xde, 0xca, 0xf8, 0x88 },
  678. { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
  679. 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
  680. 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
  681. 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
  682. 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
  683. 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
  684. 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
  685. 0xa6, 0x37, 0xb3, 0x9b },
  686. };
  687. static const size_t add_len_test_data[MAX_TESTS] =
  688. { 0, 0, 0, 20, 20, 20 };
  689. static const int add_index_test_data[MAX_TESTS] =
  690. { 0, 0, 0, 1, 1, 1 };
  691. static const unsigned char additional_test_data[][64] =
  692. {
  693. { 0x00 },
  694. { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
  695. 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
  696. 0xab, 0xad, 0xda, 0xd2 },
  697. };
  698. static const size_t pt_len_test_data[MAX_TESTS] =
  699. { 0, 16, 64, 60, 60, 60 };
  700. static const int pt_index_test_data[MAX_TESTS] =
  701. { 0, 0, 1, 1, 1, 1 };
  702. static const unsigned char pt_test_data[][64] =
  703. {
  704. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  705. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  706. { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
  707. 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
  708. 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
  709. 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
  710. 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
  711. 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
  712. 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
  713. 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
  714. };
  715. static const unsigned char ct_test_data[][64] =
  716. {
  717. { 0x00 },
  718. { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
  719. 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
  720. { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
  721. 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
  722. 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
  723. 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
  724. 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
  725. 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
  726. 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
  727. 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
  728. { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
  729. 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
  730. 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
  731. 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
  732. 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
  733. 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
  734. 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
  735. 0x3d, 0x58, 0xe0, 0x91 },
  736. { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
  737. 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
  738. 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
  739. 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
  740. 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
  741. 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
  742. 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
  743. 0xc2, 0x3f, 0x45, 0x98 },
  744. { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
  745. 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
  746. 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
  747. 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
  748. 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
  749. 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
  750. 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
  751. 0x4c, 0x34, 0xae, 0xe5 },
  752. #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
  753. { 0x00 },
  754. { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
  755. 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
  756. { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
  757. 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
  758. 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
  759. 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
  760. 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
  761. 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
  762. 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
  763. 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
  764. { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
  765. 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
  766. 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
  767. 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
  768. 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
  769. 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
  770. 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
  771. 0xcc, 0xda, 0x27, 0x10 },
  772. { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
  773. 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
  774. 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
  775. 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
  776. 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
  777. 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
  778. 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
  779. 0xa0, 0xf0, 0x62, 0xf7 },
  780. { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
  781. 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
  782. 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
  783. 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
  784. 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
  785. 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
  786. 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
  787. 0xe9, 0xb7, 0x37, 0x3b },
  788. { 0x00 },
  789. { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
  790. 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
  791. { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
  792. 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
  793. 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
  794. 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
  795. 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
  796. 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
  797. 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
  798. 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
  799. { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
  800. 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
  801. 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
  802. 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
  803. 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
  804. 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
  805. 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
  806. 0xbc, 0xc9, 0xf6, 0x62 },
  807. { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
  808. 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
  809. 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
  810. 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
  811. 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
  812. 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
  813. 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
  814. 0xf4, 0x7c, 0x9b, 0x1f },
  815. { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
  816. 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
  817. 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
  818. 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
  819. 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
  820. 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
  821. 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
  822. 0x44, 0xae, 0x7e, 0x3f },
  823. #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
  824. };
  825. static const unsigned char tag_test_data[][16] =
  826. {
  827. { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
  828. 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
  829. { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
  830. 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
  831. { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
  832. 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
  833. { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
  834. 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
  835. { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
  836. 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
  837. { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
  838. 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
  839. #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
  840. { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
  841. 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
  842. { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
  843. 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
  844. { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
  845. 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
  846. { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
  847. 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
  848. { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
  849. 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
  850. { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
  851. 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
  852. { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
  853. 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
  854. { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
  855. 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
  856. { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
  857. 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
  858. { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
  859. 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
  860. { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
  861. 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
  862. { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
  863. 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
  864. #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
  865. };
  866. int mbedtls_gcm_self_test(int verbose)
  867. {
  868. mbedtls_gcm_context ctx;
  869. unsigned char buf[64];
  870. unsigned char tag_buf[16];
  871. int i, j, ret;
  872. mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
  873. size_t olen;
  874. if (verbose != 0) {
  875. #if defined(MBEDTLS_GCM_ALT)
  876. mbedtls_printf(" GCM note: alternative implementation.\n");
  877. #else /* MBEDTLS_GCM_ALT */
  878. #if defined(MBEDTLS_AESNI_HAVE_CODE)
  879. if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
  880. mbedtls_printf(" GCM note: using AESNI.\n");
  881. } else
  882. #endif
  883. #if defined(MBEDTLS_AESCE_HAVE_CODE)
  884. if (MBEDTLS_AESCE_HAS_SUPPORT()) {
  885. mbedtls_printf(" GCM note: using AESCE.\n");
  886. } else
  887. #endif
  888. mbedtls_printf(" GCM note: built-in implementation.\n");
  889. #endif /* MBEDTLS_GCM_ALT */
  890. }
  891. static const int loop_limit =
  892. (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS;
  893. for (j = 0; j < loop_limit; j++) {
  894. int key_len = 128 + 64 * j;
  895. for (i = 0; i < MAX_TESTS; i++) {
  896. if (verbose != 0) {
  897. mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
  898. key_len, i, "enc");
  899. }
  900. mbedtls_gcm_init(&ctx);
  901. ret = mbedtls_gcm_setkey(&ctx, cipher,
  902. key_test_data[key_index_test_data[i]],
  903. key_len);
  904. /*
  905. * AES-192 is an optional feature that may be unavailable when
  906. * there is an alternative underlying implementation i.e. when
  907. * MBEDTLS_AES_ALT is defined.
  908. */
  909. if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) {
  910. mbedtls_printf("skipped\n");
  911. break;
  912. } else if (ret != 0) {
  913. goto exit;
  914. }
  915. ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
  916. pt_len_test_data[i],
  917. iv_test_data[iv_index_test_data[i]],
  918. iv_len_test_data[i],
  919. additional_test_data[add_index_test_data[i]],
  920. add_len_test_data[i],
  921. pt_test_data[pt_index_test_data[i]],
  922. buf, 16, tag_buf);
  923. #if defined(MBEDTLS_GCM_ALT)
  924. /* Allow alternative implementations to only support 12-byte nonces. */
  925. if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
  926. iv_len_test_data[i] != 12) {
  927. mbedtls_printf("skipped\n");
  928. break;
  929. }
  930. #endif /* defined(MBEDTLS_GCM_ALT) */
  931. if (ret != 0) {
  932. goto exit;
  933. }
  934. if (memcmp(buf, ct_test_data[j * 6 + i],
  935. pt_len_test_data[i]) != 0 ||
  936. memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
  937. ret = 1;
  938. goto exit;
  939. }
  940. mbedtls_gcm_free(&ctx);
  941. if (verbose != 0) {
  942. mbedtls_printf("passed\n");
  943. }
  944. mbedtls_gcm_init(&ctx);
  945. if (verbose != 0) {
  946. mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
  947. key_len, i, "dec");
  948. }
  949. ret = mbedtls_gcm_setkey(&ctx, cipher,
  950. key_test_data[key_index_test_data[i]],
  951. key_len);
  952. if (ret != 0) {
  953. goto exit;
  954. }
  955. ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT,
  956. pt_len_test_data[i],
  957. iv_test_data[iv_index_test_data[i]],
  958. iv_len_test_data[i],
  959. additional_test_data[add_index_test_data[i]],
  960. add_len_test_data[i],
  961. ct_test_data[j * 6 + i], buf, 16, tag_buf);
  962. if (ret != 0) {
  963. goto exit;
  964. }
  965. if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
  966. pt_len_test_data[i]) != 0 ||
  967. memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
  968. ret = 1;
  969. goto exit;
  970. }
  971. mbedtls_gcm_free(&ctx);
  972. if (verbose != 0) {
  973. mbedtls_printf("passed\n");
  974. }
  975. mbedtls_gcm_init(&ctx);
  976. if (verbose != 0) {
  977. mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
  978. key_len, i, "enc");
  979. }
  980. ret = mbedtls_gcm_setkey(&ctx, cipher,
  981. key_test_data[key_index_test_data[i]],
  982. key_len);
  983. if (ret != 0) {
  984. goto exit;
  985. }
  986. ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT,
  987. iv_test_data[iv_index_test_data[i]],
  988. iv_len_test_data[i]);
  989. if (ret != 0) {
  990. goto exit;
  991. }
  992. ret = mbedtls_gcm_update_ad(&ctx,
  993. additional_test_data[add_index_test_data[i]],
  994. add_len_test_data[i]);
  995. if (ret != 0) {
  996. goto exit;
  997. }
  998. if (pt_len_test_data[i] > 32) {
  999. size_t rest_len = pt_len_test_data[i] - 32;
  1000. ret = mbedtls_gcm_update(&ctx,
  1001. pt_test_data[pt_index_test_data[i]],
  1002. 32,
  1003. buf, sizeof(buf), &olen);
  1004. if (ret != 0) {
  1005. goto exit;
  1006. }
  1007. if (olen != 32) {
  1008. goto exit;
  1009. }
  1010. ret = mbedtls_gcm_update(&ctx,
  1011. pt_test_data[pt_index_test_data[i]] + 32,
  1012. rest_len,
  1013. buf + 32, sizeof(buf) - 32, &olen);
  1014. if (ret != 0) {
  1015. goto exit;
  1016. }
  1017. if (olen != rest_len) {
  1018. goto exit;
  1019. }
  1020. } else {
  1021. ret = mbedtls_gcm_update(&ctx,
  1022. pt_test_data[pt_index_test_data[i]],
  1023. pt_len_test_data[i],
  1024. buf, sizeof(buf), &olen);
  1025. if (ret != 0) {
  1026. goto exit;
  1027. }
  1028. if (olen != pt_len_test_data[i]) {
  1029. goto exit;
  1030. }
  1031. }
  1032. ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
  1033. if (ret != 0) {
  1034. goto exit;
  1035. }
  1036. if (memcmp(buf, ct_test_data[j * 6 + i],
  1037. pt_len_test_data[i]) != 0 ||
  1038. memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
  1039. ret = 1;
  1040. goto exit;
  1041. }
  1042. mbedtls_gcm_free(&ctx);
  1043. if (verbose != 0) {
  1044. mbedtls_printf("passed\n");
  1045. }
  1046. mbedtls_gcm_init(&ctx);
  1047. if (verbose != 0) {
  1048. mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
  1049. key_len, i, "dec");
  1050. }
  1051. ret = mbedtls_gcm_setkey(&ctx, cipher,
  1052. key_test_data[key_index_test_data[i]],
  1053. key_len);
  1054. if (ret != 0) {
  1055. goto exit;
  1056. }
  1057. ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT,
  1058. iv_test_data[iv_index_test_data[i]],
  1059. iv_len_test_data[i]);
  1060. if (ret != 0) {
  1061. goto exit;
  1062. }
  1063. ret = mbedtls_gcm_update_ad(&ctx,
  1064. additional_test_data[add_index_test_data[i]],
  1065. add_len_test_data[i]);
  1066. if (ret != 0) {
  1067. goto exit;
  1068. }
  1069. if (pt_len_test_data[i] > 32) {
  1070. size_t rest_len = pt_len_test_data[i] - 32;
  1071. ret = mbedtls_gcm_update(&ctx,
  1072. ct_test_data[j * 6 + i], 32,
  1073. buf, sizeof(buf), &olen);
  1074. if (ret != 0) {
  1075. goto exit;
  1076. }
  1077. if (olen != 32) {
  1078. goto exit;
  1079. }
  1080. ret = mbedtls_gcm_update(&ctx,
  1081. ct_test_data[j * 6 + i] + 32,
  1082. rest_len,
  1083. buf + 32, sizeof(buf) - 32, &olen);
  1084. if (ret != 0) {
  1085. goto exit;
  1086. }
  1087. if (olen != rest_len) {
  1088. goto exit;
  1089. }
  1090. } else {
  1091. ret = mbedtls_gcm_update(&ctx,
  1092. ct_test_data[j * 6 + i],
  1093. pt_len_test_data[i],
  1094. buf, sizeof(buf), &olen);
  1095. if (ret != 0) {
  1096. goto exit;
  1097. }
  1098. if (olen != pt_len_test_data[i]) {
  1099. goto exit;
  1100. }
  1101. }
  1102. ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
  1103. if (ret != 0) {
  1104. goto exit;
  1105. }
  1106. if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
  1107. pt_len_test_data[i]) != 0 ||
  1108. memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
  1109. ret = 1;
  1110. goto exit;
  1111. }
  1112. mbedtls_gcm_free(&ctx);
  1113. if (verbose != 0) {
  1114. mbedtls_printf("passed\n");
  1115. }
  1116. }
  1117. }
  1118. if (verbose != 0) {
  1119. mbedtls_printf("\n");
  1120. }
  1121. ret = 0;
  1122. exit:
  1123. if (ret != 0) {
  1124. if (verbose != 0) {
  1125. mbedtls_printf("failed\n");
  1126. }
  1127. mbedtls_gcm_free(&ctx);
  1128. }
  1129. return ret;
  1130. }
  1131. #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
  1132. #endif /* MBEDTLS_GCM_C */