1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /* Thanks to Thomas Pornin for the ideas how to implement the constat time
5 * binary multiplication. */
6
7 #ifdef FREEBL_NO_DEPEND
8 #include "stubs.h"
9 #endif
10 #include "blapii.h"
11 #include "blapit.h"
12 #include "blapi.h"
13 #include "gcm.h"
14 #include "ctr.h"
15 #include "secerr.h"
16 #include "prtypes.h"
17 #include "pkcs11t.h"
18
19 #include <limits.h>
20
21 /* old gcc doesn't support some poly64x2_t intrinsic */
22 #if defined(__aarch64__) && defined(IS_LITTLE_ENDIAN) && \
23 (defined(__clang__) || defined(__GNUC__) && __GNUC__ > 6)
24 #define USE_ARM_GCM
25 #elif defined(__arm__) && defined(IS_LITTLE_ENDIAN) && \
26 !defined(NSS_DISABLE_ARM32_NEON)
27 /* We don't test on big endian platform, so disable this on big endian. */
28 #define USE_ARM_GCM
29 #endif
30
31 /* Forward declarations */
32 SECStatus gcm_HashInit_hw(gcmHashContext *ghash);
33 SECStatus gcm_HashWrite_hw(gcmHashContext *ghash, unsigned char *outbuf);
34 SECStatus gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf,
35 unsigned int count);
36 SECStatus gcm_HashZeroX_hw(gcmHashContext *ghash);
37 SECStatus gcm_HashMult_sftw(gcmHashContext *ghash, const unsigned char *buf,
38 unsigned int count);
39 SECStatus gcm_HashMult_sftw32(gcmHashContext *ghash, const unsigned char *buf,
40 unsigned int count);
41
42 /* Stub definitions for the above *_hw functions, which shouldn't be
43 * used unless NSS_X86_OR_X64 is defined */
44 #if !defined(NSS_X86_OR_X64) && !defined(USE_ARM_GCM) && !defined(USE_PPC_CRYPTO)
45 SECStatus
gcm_HashWrite_hw(gcmHashContext * ghash,unsigned char * outbuf)46 gcm_HashWrite_hw(gcmHashContext *ghash, unsigned char *outbuf)
47 {
48 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
49 return SECFailure;
50 }
51
52 SECStatus
gcm_HashMult_hw(gcmHashContext * ghash,const unsigned char * buf,unsigned int count)53 gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf,
54 unsigned int count)
55 {
56 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
57 return SECFailure;
58 }
59
60 SECStatus
gcm_HashInit_hw(gcmHashContext * ghash)61 gcm_HashInit_hw(gcmHashContext *ghash)
62 {
63 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
64 return SECFailure;
65 }
66
67 SECStatus
gcm_HashZeroX_hw(gcmHashContext * ghash)68 gcm_HashZeroX_hw(gcmHashContext *ghash)
69 {
70 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
71 return SECFailure;
72 }
73 #endif /* !NSS_X86_OR_X64 && !USE_ARM_GCM && !USE_PPC_CRYPTO */
74
75 uint64_t
get64(const unsigned char * bytes)76 get64(const unsigned char *bytes)
77 {
78 return ((uint64_t)bytes[0]) << 56 |
79 ((uint64_t)bytes[1]) << 48 |
80 ((uint64_t)bytes[2]) << 40 |
81 ((uint64_t)bytes[3]) << 32 |
82 ((uint64_t)bytes[4]) << 24 |
83 ((uint64_t)bytes[5]) << 16 |
84 ((uint64_t)bytes[6]) << 8 |
85 ((uint64_t)bytes[7]);
86 }
87
88 /* Initialize a gcmHashContext */
89 SECStatus
gcmHash_InitContext(gcmHashContext * ghash,const unsigned char * H,PRBool sw)90 gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H, PRBool sw)
91 {
92 SECStatus rv = SECSuccess;
93
94 ghash->cLen = 0;
95 ghash->bufLen = 0;
96 PORT_Memset(ghash->counterBuf, 0, sizeof(ghash->counterBuf));
97
98 ghash->h_low = get64(H + 8);
99 ghash->h_high = get64(H);
100 #ifdef USE_ARM_GCM
101 #if defined(__aarch64__)
102 if (arm_pmull_support() && !sw) {
103 #else
104 if (arm_neon_support() && !sw) {
105 #endif
106 #elif defined(USE_PPC_CRYPTO)
107 if (ppc_crypto_support() && !sw) {
108 #else
109 if (clmul_support() && !sw) {
110 #endif
111 rv = gcm_HashInit_hw(ghash);
112 } else {
113 /* We fall back to the software implementation if we can't use / don't
114 * want to use pclmul. */
115 #ifdef HAVE_INT128_SUPPORT
116 ghash->ghash_mul = gcm_HashMult_sftw;
117 #else
118 ghash->ghash_mul = gcm_HashMult_sftw32;
119 #endif
120 ghash->x_high = ghash->x_low = 0;
121 ghash->hw = PR_FALSE;
122 }
123 return rv;
124 }
125
126 #ifdef HAVE_INT128_SUPPORT
127 /* Binary multiplication x * y = r_high << 64 | r_low. */
128 void
129 bmul(uint64_t x, uint64_t y, uint64_t *r_high, uint64_t *r_low)
130 {
131 uint128_t x1, x2, x3, x4, x5;
132 uint128_t y1, y2, y3, y4, y5;
133 uint128_t r, z;
134
135 uint128_t m1 = (uint128_t)0x2108421084210842 << 64 | 0x1084210842108421;
136 uint128_t m2 = (uint128_t)0x4210842108421084 << 64 | 0x2108421084210842;
137 uint128_t m3 = (uint128_t)0x8421084210842108 << 64 | 0x4210842108421084;
138 uint128_t m4 = (uint128_t)0x0842108421084210 << 64 | 0x8421084210842108;
139 uint128_t m5 = (uint128_t)0x1084210842108421 << 64 | 0x0842108421084210;
140
141 x1 = x & m1;
142 y1 = y & m1;
143 x2 = x & m2;
144 y2 = y & m2;
145 x3 = x & m3;
146 y3 = y & m3;
147 x4 = x & m4;
148 y4 = y & m4;
149 x5 = x & m5;
150 y5 = y & m5;
151
152 z = (x1 * y1) ^ (x2 * y5) ^ (x3 * y4) ^ (x4 * y3) ^ (x5 * y2);
153 r = z & m1;
154 z = (x1 * y2) ^ (x2 * y1) ^ (x3 * y5) ^ (x4 * y4) ^ (x5 * y3);
155 r |= z & m2;
156 z = (x1 * y3) ^ (x2 * y2) ^ (x3 * y1) ^ (x4 * y5) ^ (x5 * y4);
157 r |= z & m3;
158 z = (x1 * y4) ^ (x2 * y3) ^ (x3 * y2) ^ (x4 * y1) ^ (x5 * y5);
159 r |= z & m4;
160 z = (x1 * y5) ^ (x2 * y4) ^ (x3 * y3) ^ (x4 * y2) ^ (x5 * y1);
161 r |= z & m5;
162
163 *r_high = (uint64_t)(r >> 64);
164 *r_low = (uint64_t)r;
165 }
166
167 SECStatus
168 gcm_HashMult_sftw(gcmHashContext *ghash, const unsigned char *buf,
169 unsigned int count)
170 {
171 uint64_t ci_low, ci_high;
172 size_t i;
173 uint64_t z2_low, z2_high, z0_low, z0_high, z1a_low, z1a_high;
174 uint128_t z_high = 0, z_low = 0;
175
176 ci_low = ghash->x_low;
177 ci_high = ghash->x_high;
178 for (i = 0; i < count; i++, buf += 16) {
179 ci_low ^= get64(buf + 8);
180 ci_high ^= get64(buf);
181
182 /* Do binary mult ghash->X = C * ghash->H (Karatsuba). */
183 bmul(ci_high, ghash->h_high, &z2_high, &z2_low);
184 bmul(ci_low, ghash->h_low, &z0_high, &z0_low);
185 bmul(ci_high ^ ci_low, ghash->h_high ^ ghash->h_low, &z1a_high, &z1a_low);
186 z1a_high ^= z2_high ^ z0_high;
187 z1a_low ^= z2_low ^ z0_low;
188 z_high = ((uint128_t)z2_high << 64) | (z2_low ^ z1a_high);
189 z_low = (((uint128_t)z0_high << 64) | z0_low) ^ (((uint128_t)z1a_low) << 64);
190
191 /* Shift one (multiply by x) as gcm spec is stupid. */
192 z_high = (z_high << 1) | (z_low >> 127);
193 z_low <<= 1;
194
195 /* Reduce */
196 z_low ^= (z_low << 127) ^ (z_low << 126) ^ (z_low << 121);
197 z_high ^= z_low ^ (z_low >> 1) ^ (z_low >> 2) ^ (z_low >> 7);
198 ci_low = (uint64_t)z_high;
199 ci_high = (uint64_t)(z_high >> 64);
200 }
201 ghash->x_low = ci_low;
202 ghash->x_high = ci_high;
203 return SECSuccess;
204 }
205 #else
206 /* Binary multiplication x * y = r_high << 32 | r_low. */
207 void
208 bmul32(uint32_t x, uint32_t y, uint32_t *r_high, uint32_t *r_low)
209 {
210 uint32_t x0, x1, x2, x3;
211 uint32_t y0, y1, y2, y3;
212 uint32_t m1 = (uint32_t)0x11111111;
213 uint32_t m2 = (uint32_t)0x22222222;
214 uint32_t m4 = (uint32_t)0x44444444;
215 uint32_t m8 = (uint32_t)0x88888888;
216 uint64_t z0, z1, z2, z3;
217 uint64_t z;
218
219 x0 = x & m1;
220 x1 = x & m2;
221 x2 = x & m4;
222 x3 = x & m8;
223 y0 = y & m1;
224 y1 = y & m2;
225 y2 = y & m4;
226 y3 = y & m8;
227 z0 = ((uint64_t)x0 * y0) ^ ((uint64_t)x1 * y3) ^
228 ((uint64_t)x2 * y2) ^ ((uint64_t)x3 * y1);
229 z1 = ((uint64_t)x0 * y1) ^ ((uint64_t)x1 * y0) ^
230 ((uint64_t)x2 * y3) ^ ((uint64_t)x3 * y2);
231 z2 = ((uint64_t)x0 * y2) ^ ((uint64_t)x1 * y1) ^
232 ((uint64_t)x2 * y0) ^ ((uint64_t)x3 * y3);
233 z3 = ((uint64_t)x0 * y3) ^ ((uint64_t)x1 * y2) ^
234 ((uint64_t)x2 * y1) ^ ((uint64_t)x3 * y0);
235 z0 &= ((uint64_t)m1 << 32) | m1;
236 z1 &= ((uint64_t)m2 << 32) | m2;
237 z2 &= ((uint64_t)m4 << 32) | m4;
238 z3 &= ((uint64_t)m8 << 32) | m8;
239 z = z0 | z1 | z2 | z3;
240 *r_high = (uint32_t)(z >> 32);
241 *r_low = (uint32_t)z;
242 }
243
244 SECStatus
245 gcm_HashMult_sftw32(gcmHashContext *ghash, const unsigned char *buf,
246 unsigned int count)
247 {
248 size_t i;
249 uint64_t ci_low, ci_high;
250 uint64_t z_high_h, z_high_l, z_low_h, z_low_l;
251 uint32_t ci_high_h, ci_high_l, ci_low_h, ci_low_l;
252 uint32_t b_a_h, b_a_l, a_a_h, a_a_l, b_b_h, b_b_l;
253 uint32_t a_b_h, a_b_l, b_c_h, b_c_l, a_c_h, a_c_l, c_c_h, c_c_l;
254 uint32_t ci_highXlow_h, ci_highXlow_l, c_a_h, c_a_l, c_b_h, c_b_l;
255
256 uint32_t h_high_h = (uint32_t)(ghash->h_high >> 32);
257 uint32_t h_high_l = (uint32_t)ghash->h_high;
258 uint32_t h_low_h = (uint32_t)(ghash->h_low >> 32);
259 uint32_t h_low_l = (uint32_t)ghash->h_low;
260 uint32_t h_highXlow_h = h_high_h ^ h_low_h;
261 uint32_t h_highXlow_l = h_high_l ^ h_low_l;
262 uint32_t h_highX_xored = h_highXlow_h ^ h_highXlow_l;
263
264 for (i = 0; i < count; i++, buf += 16) {
265 ci_low = ghash->x_low ^ get64(buf + 8);
266 ci_high = ghash->x_high ^ get64(buf);
267 ci_low_h = (uint32_t)(ci_low >> 32);
268 ci_low_l = (uint32_t)ci_low;
269 ci_high_h = (uint32_t)(ci_high >> 32);
270 ci_high_l = (uint32_t)ci_high;
271 ci_highXlow_h = ci_high_h ^ ci_low_h;
272 ci_highXlow_l = ci_high_l ^ ci_low_l;
273
274 /* Do binary mult ghash->X = C * ghash->H (recursive Karatsuba). */
275 bmul32(ci_high_h, h_high_h, &a_a_h, &a_a_l);
276 bmul32(ci_high_l, h_high_l, &a_b_h, &a_b_l);
277 bmul32(ci_high_h ^ ci_high_l, h_high_h ^ h_high_l, &a_c_h, &a_c_l);
278 a_c_h ^= a_a_h ^ a_b_h;
279 a_c_l ^= a_a_l ^ a_b_l;
280 a_a_l ^= a_c_h;
281 a_b_h ^= a_c_l;
282 /* ci_high * h_high = a_a_h:a_a_l:a_b_h:a_b_l */
283
284 bmul32(ci_low_h, h_low_h, &b_a_h, &b_a_l);
285 bmul32(ci_low_l, h_low_l, &b_b_h, &b_b_l);
286 bmul32(ci_low_h ^ ci_low_l, h_low_h ^ h_low_l, &b_c_h, &b_c_l);
287 b_c_h ^= b_a_h ^ b_b_h;
288 b_c_l ^= b_a_l ^ b_b_l;
289 b_a_l ^= b_c_h;
290 b_b_h ^= b_c_l;
291 /* ci_low * h_low = b_a_h:b_a_l:b_b_h:b_b_l */
292
293 bmul32(ci_highXlow_h, h_highXlow_h, &c_a_h, &c_a_l);
294 bmul32(ci_highXlow_l, h_highXlow_l, &c_b_h, &c_b_l);
295 bmul32(ci_highXlow_h ^ ci_highXlow_l, h_highX_xored, &c_c_h, &c_c_l);
296 c_c_h ^= c_a_h ^ c_b_h;
297 c_c_l ^= c_a_l ^ c_b_l;
298 c_a_l ^= c_c_h;
299 c_b_h ^= c_c_l;
300 /* (ci_high ^ ci_low) * (h_high ^ h_low) = c_a_h:c_a_l:c_b_h:c_b_l */
301
302 c_a_h ^= b_a_h ^ a_a_h;
303 c_a_l ^= b_a_l ^ a_a_l;
304 c_b_h ^= b_b_h ^ a_b_h;
305 c_b_l ^= b_b_l ^ a_b_l;
306 z_high_h = ((uint64_t)a_a_h << 32) | a_a_l;
307 z_high_l = (((uint64_t)a_b_h << 32) | a_b_l) ^
308 (((uint64_t)c_a_h << 32) | c_a_l);
309 z_low_h = (((uint64_t)b_a_h << 32) | b_a_l) ^
310 (((uint64_t)c_b_h << 32) | c_b_l);
311 z_low_l = ((uint64_t)b_b_h << 32) | b_b_l;
312
313 /* Shift one (multiply by x) as gcm spec is stupid. */
314 z_high_h = z_high_h << 1 | z_high_l >> 63;
315 z_high_l = z_high_l << 1 | z_low_h >> 63;
316 z_low_h = z_low_h << 1 | z_low_l >> 63;
317 z_low_l <<= 1;
318
319 /* Reduce */
320 z_low_h ^= (z_low_l << 63) ^ (z_low_l << 62) ^ (z_low_l << 57);
321 z_high_h ^= z_low_h ^ (z_low_h >> 1) ^ (z_low_h >> 2) ^ (z_low_h >> 7);
322 z_high_l ^= z_low_l ^ (z_low_l >> 1) ^ (z_low_l >> 2) ^ (z_low_l >> 7) ^
323 (z_low_h << 63) ^ (z_low_h << 62) ^ (z_low_h << 57);
324 ghash->x_high = z_high_h;
325 ghash->x_low = z_high_l;
326 }
327 return SECSuccess;
328 }
329 #endif /* HAVE_INT128_SUPPORT */
330
331 static SECStatus
332 gcm_zeroX(gcmHashContext *ghash)
333 {
334 SECStatus rv = SECSuccess;
335
336 if (ghash->hw) {
337 rv = gcm_HashZeroX_hw(ghash);
338 }
339
340 ghash->x_high = ghash->x_low = 0;
341 return rv;
342 }
343
344 /*
345 * implement GCM GHASH using the freebl GHASH function. The gcm_HashMult
346 * function always takes AES_BLOCK_SIZE lengths of data. gcmHash_Update will
347 * format the data properly.
348 */
349 SECStatus
350 gcmHash_Update(gcmHashContext *ghash, const unsigned char *buf,
351 unsigned int len)
352 {
353 unsigned int blocks;
354 SECStatus rv;
355
356 ghash->cLen += (len * PR_BITS_PER_BYTE);
357
358 /* first deal with the current buffer of data. Try to fill it out so
359 * we can hash it */
360 if (ghash->bufLen) {
361 unsigned int needed = PR_MIN(len, AES_BLOCK_SIZE - ghash->bufLen);
362 if (needed != 0) {
363 PORT_Memcpy(ghash->buffer + ghash->bufLen, buf, needed);
364 }
365 buf += needed;
366 len -= needed;
367 ghash->bufLen += needed;
368 if (len == 0) {
369 /* didn't add enough to hash the data, nothing more do do */
370 return SECSuccess;
371 }
372 PORT_Assert(ghash->bufLen == AES_BLOCK_SIZE);
373 /* hash the buffer and clear it */
374 rv = ghash->ghash_mul(ghash, ghash->buffer, 1);
375 PORT_Memset(ghash->buffer, 0, AES_BLOCK_SIZE);
376 ghash->bufLen = 0;
377 if (rv != SECSuccess) {
378 return SECFailure;
379 }
380 }
381 /* now hash any full blocks remaining in the data stream */
382 blocks = len / AES_BLOCK_SIZE;
383 if (blocks) {
384 rv = ghash->ghash_mul(ghash, buf, blocks);
385 if (rv != SECSuccess) {
386 return SECFailure;
387 }
388 buf += blocks * AES_BLOCK_SIZE;
389 len -= blocks * AES_BLOCK_SIZE;
390 }
391
392 /* save any remainder in the buffer to be hashed with the next call */
393 if (len != 0) {
394 PORT_Memcpy(ghash->buffer, buf, len);
395 ghash->bufLen = len;
396 }
397 return SECSuccess;
398 }
399
400 /*
401 * write out any partial blocks zero padded through the GHASH engine,
402 * save the lengths for the final completion of the hash
403 */
404 static SECStatus
405 gcmHash_Sync(gcmHashContext *ghash)
406 {
407 int i;
408 SECStatus rv;
409
410 /* copy the previous counter to the upper block */
411 PORT_Memcpy(ghash->counterBuf, &ghash->counterBuf[GCM_HASH_LEN_LEN],
412 GCM_HASH_LEN_LEN);
413 /* copy the current counter in the lower block */
414 for (i = 0; i < GCM_HASH_LEN_LEN; i++) {
415 ghash->counterBuf[GCM_HASH_LEN_LEN + i] =
416 (ghash->cLen >> ((GCM_HASH_LEN_LEN - 1 - i) * PR_BITS_PER_BYTE)) & 0xff;
417 }
418 ghash->cLen = 0;
419
420 /* now zero fill the buffer and hash the last block */
421 if (ghash->bufLen) {
422 PORT_Memset(ghash->buffer + ghash->bufLen, 0, AES_BLOCK_SIZE - ghash->bufLen);
423 rv = ghash->ghash_mul(ghash, ghash->buffer, 1);
424 PORT_Memset(ghash->buffer, 0, AES_BLOCK_SIZE);
425 ghash->bufLen = 0;
426 if (rv != SECSuccess) {
427 return SECFailure;
428 }
429 }
430 return SECSuccess;
431 }
432
433 #define WRITE64(x, bytes) \
434 (bytes)[0] = (x) >> 56; \
435 (bytes)[1] = (x) >> 48; \
436 (bytes)[2] = (x) >> 40; \
437 (bytes)[3] = (x) >> 32; \
438 (bytes)[4] = (x) >> 24; \
439 (bytes)[5] = (x) >> 16; \
440 (bytes)[6] = (x) >> 8; \
441 (bytes)[7] = (x);
442
443 /*
444 * This does the final sync, hashes the lengths, then returns
445 * "T", the hashed output.
446 */
447 SECStatus
448 gcmHash_Final(gcmHashContext *ghash, unsigned char *outbuf,
449 unsigned int *outlen, unsigned int maxout)
450 {
451 unsigned char T[MAX_BLOCK_SIZE];
452 SECStatus rv;
453
454 rv = gcmHash_Sync(ghash);
455 if (rv != SECSuccess) {
456 goto cleanup;
457 }
458
459 rv = ghash->ghash_mul(ghash, ghash->counterBuf,
460 (GCM_HASH_LEN_LEN * 2) / AES_BLOCK_SIZE);
461 if (rv != SECSuccess) {
462 goto cleanup;
463 }
464
465 if (ghash->hw) {
466 rv = gcm_HashWrite_hw(ghash, T);
467 if (rv != SECSuccess) {
468 goto cleanup;
469 }
470 } else {
471 WRITE64(ghash->x_low, T + 8);
472 WRITE64(ghash->x_high, T);
473 }
474
475 if (maxout > AES_BLOCK_SIZE) {
476 maxout = AES_BLOCK_SIZE;
477 }
478 PORT_Memcpy(outbuf, T, maxout);
479 *outlen = maxout;
480 rv = SECSuccess;
481
482 cleanup:
483 PORT_Memset(T, 0, sizeof(T));
484 return rv;
485 }
486
487 SECStatus
488 gcmHash_Reset(gcmHashContext *ghash, const unsigned char *AAD,
489 unsigned int AADLen)
490 {
491 SECStatus rv;
492
493 // Limit AADLen in accordance with SP800-38D
494 if (sizeof(AADLen) >= 8 && AADLen > (1ULL << 61) - 1) {
495 PORT_SetError(SEC_ERROR_INPUT_LEN);
496 return SECFailure;
497 }
498
499 ghash->cLen = 0;
500 PORT_Memset(ghash->counterBuf, 0, GCM_HASH_LEN_LEN * 2);
501 ghash->bufLen = 0;
502 rv = gcm_zeroX(ghash);
503 if (rv != SECSuccess) {
504 return rv;
505 }
506
507 /* now kick things off by hashing the Additional Authenticated Data */
508 if (AADLen != 0) {
509 rv = gcmHash_Update(ghash, AAD, AADLen);
510 if (rv != SECSuccess) {
511 return SECFailure;
512 }
513 rv = gcmHash_Sync(ghash);
514 if (rv != SECSuccess) {
515 return SECFailure;
516 }
517 }
518 return SECSuccess;
519 }
520
521 /**************************************************************************
522 * Now implement the GCM using gcmHash and CTR *
523 **************************************************************************/
524
525 /* state to handle the full GCM operation (hash and counter) */
526 struct GCMContextStr {
527 gcmHashContext *ghash_context;
528 CTRContext ctr_context;
529 freeblCipherFunc cipher;
530 void *cipher_context;
531 unsigned long tagBits;
532 unsigned char tagKey[MAX_BLOCK_SIZE];
533 PRBool ctr_context_init;
534 gcmIVContext gcm_iv;
535 };
536
537 SECStatus gcm_InitCounter(GCMContext *gcm, const unsigned char *iv,
538 unsigned int ivLen, unsigned int tagBits,
539 const unsigned char *aad, unsigned int aadLen);
540
541 GCMContext *
542 GCM_CreateContext(void *context, freeblCipherFunc cipher,
543 const unsigned char *params)
544 {
545 GCMContext *gcm = NULL;
546 gcmHashContext *ghash = NULL;
547 unsigned char H[MAX_BLOCK_SIZE];
548 unsigned int tmp;
549 const CK_NSS_GCM_PARAMS *gcmParams = (const CK_NSS_GCM_PARAMS *)params;
550 SECStatus rv;
551 #ifdef DISABLE_HW_GCM
552 const PRBool sw = PR_TRUE;
553 #else
554 const PRBool sw = PR_FALSE;
555 #endif
556
557 gcm = PORT_ZNew(GCMContext);
558 if (gcm == NULL) {
559 return NULL;
560 }
561 gcm->cipher = cipher;
562 gcm->cipher_context = context;
563 ghash = PORT_ZNewAligned(gcmHashContext, 16, mem);
564
565 /* first plug in the ghash context */
566 gcm->ghash_context = ghash;
567 PORT_Memset(H, 0, AES_BLOCK_SIZE);
568 rv = (*cipher)(context, H, &tmp, AES_BLOCK_SIZE, H, AES_BLOCK_SIZE, AES_BLOCK_SIZE);
569 if (rv != SECSuccess) {
570 goto loser;
571 }
572 rv = gcmHash_InitContext(ghash, H, sw);
573 if (rv != SECSuccess) {
574 goto loser;
575 }
576
577 gcm_InitIVContext(&gcm->gcm_iv);
578 gcm->ctr_context_init = PR_FALSE;
579
580 /* if gcmPara/ms is NULL, then we are creating an PKCS #11 MESSAGE
581 * style context, in which we initialize the key once, then do separate
582 * iv/aad's for each message. In that case we only initialize the key
583 * and ghash. We initialize the counter in each separate message */
584 if (gcmParams == NULL) {
585 /* OK we are finished with init, if we are doing MESSAGE interface,
586 * return from here */
587 return gcm;
588 }
589
590 rv = gcm_InitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen,
591 gcmParams->ulTagBits, gcmParams->pAAD,
592 gcmParams->ulAADLen);
593 if (rv != SECSuccess) {
594 goto loser;
595 }
596 PORT_Memset(H, 0, AES_BLOCK_SIZE);
597 gcm->ctr_context_init = PR_TRUE;
598 return gcm;
599
600 loser:
601 PORT_Memset(H, 0, AES_BLOCK_SIZE);
602 if (ghash && ghash->mem) {
603 void *mem = ghash->mem;
604 PORT_Memset(ghash, 0, sizeof(gcmHashContext));
605 PORT_Free(mem);
606 }
607 if (gcm) {
608 PORT_ZFree(gcm, sizeof(GCMContext));
609 }
610 return NULL;
611 }
612
613 SECStatus
614 gcm_InitCounter(GCMContext *gcm, const unsigned char *iv, unsigned int ivLen,
615 unsigned int tagBits, const unsigned char *aad,
616 unsigned int aadLen)
617 {
618 gcmHashContext *ghash = gcm->ghash_context;
619 unsigned int tmp;
620 PRBool freeCtr = PR_FALSE;
621 CK_AES_CTR_PARAMS ctrParams;
622 SECStatus rv;
623
624 /* Verify our parameters here */
625 if (ivLen == 0) {
626 PORT_SetError(SEC_ERROR_INVALID_ARGS);
627 goto loser;
628 }
629
630 if (tagBits != 128 && tagBits != 120 &&
631 tagBits != 112 && tagBits != 104 &&
632 tagBits != 96 && tagBits != 64 &&
633 tagBits != 32) {
634 PORT_SetError(SEC_ERROR_INVALID_ARGS);
635 goto loser;
636 }
637
638 /* fill in the Counter context */
639 ctrParams.ulCounterBits = 32;
640 PORT_Memset(ctrParams.cb, 0, sizeof(ctrParams.cb));
641 if (ivLen == 12) {
642 PORT_Memcpy(ctrParams.cb, iv, ivLen);
643 ctrParams.cb[AES_BLOCK_SIZE - 1] = 1;
644 } else {
645 rv = gcmHash_Reset(ghash, NULL, 0);
646 if (rv != SECSuccess) {
647 goto loser;
648 }
649 rv = gcmHash_Update(ghash, iv, ivLen);
650 if (rv != SECSuccess) {
651 goto loser;
652 }
653 rv = gcmHash_Final(ghash, ctrParams.cb, &tmp, AES_BLOCK_SIZE);
654 if (rv != SECSuccess) {
655 goto loser;
656 }
657 }
658 rv = CTR_InitContext(&gcm->ctr_context, gcm->cipher_context, gcm->cipher,
659 (unsigned char *)&ctrParams);
660 if (rv != SECSuccess) {
661 goto loser;
662 }
663 freeCtr = PR_TRUE;
664
665 /* fill in the gcm structure */
666 gcm->tagBits = tagBits; /* save for final step */
667 /* calculate the final tag key. NOTE: gcm->tagKey is zero to start with.
668 * if this assumption changes, we would need to explicitly clear it here */
669 PORT_Memset(gcm->tagKey, 0, sizeof(gcm->tagKey));
670 rv = CTR_Update(&gcm->ctr_context, gcm->tagKey, &tmp, AES_BLOCK_SIZE,
671 gcm->tagKey, AES_BLOCK_SIZE, AES_BLOCK_SIZE);
672 if (rv != SECSuccess) {
673 goto loser;
674 }
675
676 /* finally mix in the AAD data */
677 rv = gcmHash_Reset(ghash, aad, aadLen);
678 if (rv != SECSuccess) {
679 goto loser;
680 }
681
682 PORT_Memset(&ctrParams, 0, sizeof ctrParams);
683 return SECSuccess;
684
685 loser:
686 PORT_Memset(&ctrParams, 0, sizeof ctrParams);
687 if (freeCtr) {
688 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
689 }
690 return SECFailure;
691 }
692
693 void
694 GCM_DestroyContext(GCMContext *gcm, PRBool freeit)
695 {
696 void *mem = gcm->ghash_context->mem;
697 /* ctr_context is statically allocated and will be freed when we free
698 * gcm. call their destroy functions to free up any locally
699 * allocated data (like mp_int's) */
700 if (gcm->ctr_context_init) {
701 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
702 }
703 PORT_Memset(gcm->ghash_context, 0, sizeof(gcmHashContext));
704 PORT_Free(mem);
705 PORT_Memset(&gcm->tagBits, 0, sizeof(gcm->tagBits));
706 PORT_Memset(gcm->tagKey, 0, sizeof(gcm->tagKey));
707 if (freeit) {
708 PORT_Free(gcm);
709 }
710 }
711
712 static SECStatus
713 gcm_GetTag(GCMContext *gcm, unsigned char *outbuf,
714 unsigned int *outlen, unsigned int maxout)
715 {
716 unsigned int tagBytes;
717 unsigned int extra;
718 unsigned int i;
719 SECStatus rv;
720
721 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
722 extra = tagBytes * PR_BITS_PER_BYTE - gcm->tagBits;
723
724 if (outbuf == NULL) {
725 *outlen = tagBytes;
726 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
727 return SECFailure;
728 }
729
730 if (maxout < tagBytes) {
731 *outlen = tagBytes;
732 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
733 return SECFailure;
734 }
735 maxout = tagBytes;
736 rv = gcmHash_Final(gcm->ghash_context, outbuf, outlen, maxout);
737 if (rv != SECSuccess) {
738 return SECFailure;
739 }
740
741 for (i = 0; i < *outlen; i++) {
742 outbuf[i] ^= gcm->tagKey[i];
743 }
744 /* mask off any extra bits we got */
745 if (extra) {
746 outbuf[tagBytes - 1] &= ~((1 << extra) - 1);
747 }
748 return SECSuccess;
749 }
750
751 /*
752 * See The Galois/Counter Mode of Operation, McGrew and Viega.
753 * GCM is basically counter mode with a specific initialization and
754 * built in macing operation.
755 */
756 SECStatus
757 GCM_EncryptUpdate(GCMContext *gcm, unsigned char *outbuf,
758 unsigned int *outlen, unsigned int maxout,
759 const unsigned char *inbuf, unsigned int inlen,
760 unsigned int blocksize)
761 {
762 SECStatus rv;
763 unsigned int tagBytes;
764 unsigned int len;
765
766 PORT_Assert(blocksize == AES_BLOCK_SIZE);
767 if (blocksize != AES_BLOCK_SIZE) {
768 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
769 return SECFailure;
770 }
771
772 if (!gcm->ctr_context_init) {
773 PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
774 return SECFailure;
775 }
776
777 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
778 if (UINT_MAX - inlen < tagBytes) {
779 PORT_SetError(SEC_ERROR_INPUT_LEN);
780 return SECFailure;
781 }
782 if (maxout < inlen + tagBytes) {
783 *outlen = inlen + tagBytes;
784 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
785 return SECFailure;
786 }
787
788 rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
789 inbuf, inlen, AES_BLOCK_SIZE);
790 if (rv != SECSuccess) {
791 return SECFailure;
792 }
793 rv = gcmHash_Update(gcm->ghash_context, outbuf, *outlen);
794 if (rv != SECSuccess) {
795 PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */
796 *outlen = 0;
797 return SECFailure;
798 }
799 rv = gcm_GetTag(gcm, outbuf + *outlen, &len, maxout - *outlen);
800 if (rv != SECSuccess) {
801 PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */
802 *outlen = 0;
803 return SECFailure;
804 };
805 *outlen += len;
806 return SECSuccess;
807 }
808
809 /*
810 * See The Galois/Counter Mode of Operation, McGrew and Viega.
811 * GCM is basically counter mode with a specific initialization and
812 * built in macing operation. NOTE: the only difference between Encrypt
813 * and Decrypt is when we calculate the mac. That is because the mac must
814 * always be calculated on the cipher text, not the plain text, so for
815 * encrypt, we do the CTR update first and for decrypt we do the mac first.
816 */
817 SECStatus
818 GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
819 unsigned int *outlen, unsigned int maxout,
820 const unsigned char *inbuf, unsigned int inlen,
821 unsigned int blocksize)
822 {
823 SECStatus rv;
824 unsigned int tagBytes;
825 unsigned char tag[MAX_BLOCK_SIZE];
826 const unsigned char *intag;
827 unsigned int len;
828
829 PORT_Assert(blocksize == AES_BLOCK_SIZE);
830 if (blocksize != AES_BLOCK_SIZE) {
831 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
832 return SECFailure;
833 }
834
835 if (!gcm->ctr_context_init) {
836 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
837 return SECFailure;
838 }
839
840 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
841
842 /* get the authentication block */
843 if (inlen < tagBytes) {
844 PORT_SetError(SEC_ERROR_INPUT_LEN);
845 return SECFailure;
846 }
847
848 inlen -= tagBytes;
849 intag = inbuf + inlen;
850
851 /* verify the block */
852 rv = gcmHash_Update(gcm->ghash_context, inbuf, inlen);
853 if (rv != SECSuccess) {
854 return SECFailure;
855 }
856 rv = gcm_GetTag(gcm, tag, &len, AES_BLOCK_SIZE);
857 if (rv != SECSuccess) {
858 return SECFailure;
859 }
860 /* Don't decrypt if we can't authenticate the encrypted data!
861 * This assumes that if tagBits is not a multiple of 8, intag will
862 * preserve the masked off missing bits. */
863 if (NSS_SecureMemcmp(tag, intag, tagBytes) != 0) {
864 /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
865 PORT_SetError(SEC_ERROR_BAD_DATA);
866 PORT_Memset(tag, 0, sizeof(tag));
867 return SECFailure;
868 }
869 PORT_Memset(tag, 0, sizeof(tag));
870 /* finish the decryption */
871 return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
872 inbuf, inlen, AES_BLOCK_SIZE);
873 }
874
875 void
876 gcm_InitIVContext(gcmIVContext *gcmIv)
877 {
878 gcmIv->counter = 0;
879 gcmIv->max_count = 0;
880 gcmIv->ivGen = CKG_GENERATE;
881 gcmIv->ivLen = 0;
882 gcmIv->fixedBits = 0;
883 }
884
885 /*
886 * generate the IV on the fly and return it to the application.
887 * This function keeps a counter, which may be used in the IV
888 * generation, or may be used in simply to make sure we don't
889 * generate to many IV's from this same key.
890 * PKCS #11 defines 4 generating values:
891 * 1) CKG_NO_GENERATE: just use the passed in IV as it.
892 * 2) CKG_GENERATE: the application doesn't care what generation
893 * scheme is use (we default to counter in this code).
894 * 3) CKG_GENERATE_COUNTER: The IV is the value of a counter.
895 * 4) CKG_GENERATE_RANDOM: The IV is randomly generated.
896 * We add a fifth rule:
897 * 5) CKG_GENERATE_COUNTER_XOR: The Counter value is xor'ed with
898 * the IV.
899 * The value fixedBits specifies the number of bits that will be passed
900 * on from the original IV. The counter or the random data is is loaded
901 * in the remainder of the IV not covered by fixedBits, overwriting any
902 * data there. In the xor case the counter is xor'ed with the data in the
903 * IV. In all cases only bits outside of fixedBits is modified.
904 * The number of IV's we can generate is restricted by the size of the
905 * variable part of the IV and the generation algorithm used. Because of
906 * this, we require subsequent calls on this context to use the same
907 * generator, IV len, and fixed bits as the first call.
908 */
909 SECStatus
910 gcm_GenerateIV(gcmIVContext *gcmIv, unsigned char *iv, unsigned int ivLen,
911 unsigned int fixedBits, CK_GENERATOR_FUNCTION ivGen)
912 {
913 unsigned int i;
914 unsigned int flexBits;
915 unsigned int ivOffset;
916 unsigned int ivNewCount;
917 unsigned char ivMask;
918 unsigned char ivSave;
919 SECStatus rv;
920
921 if (gcmIv->counter != 0) {
922 /* If we've already generated a message, make sure all subsequent
923 * messages are using the same generator */
924 if ((gcmIv->ivGen != ivGen) || (gcmIv->fixedBits != fixedBits) ||
925 (gcmIv->ivLen != ivLen)) {
926 PORT_SetError(SEC_ERROR_INVALID_ARGS);
927 return SECFailure;
928 }
929 } else {
930 /* remember these values */
931 gcmIv->ivGen = ivGen;
932 gcmIv->fixedBits = fixedBits;
933 gcmIv->ivLen = ivLen;
934 /* now calculate how may bits of IV we have to supply */
935 flexBits = ivLen * PR_BITS_PER_BYTE; /* bytes->bits */
936 /* first make sure we aren't going to overflow */
937 if (flexBits < fixedBits) {
938 PORT_SetError(SEC_ERROR_INVALID_ARGS);
939 return SECFailure;
940 }
941 flexBits -= fixedBits;
942 /* if we are generating a random number reduce the acceptable bits to
943 * avoid birthday attacks */
944 if (ivGen == CKG_GENERATE_RANDOM) {
945 if (flexBits <= GCMIV_RANDOM_BIRTHDAY_BITS) {
946 PORT_SetError(SEC_ERROR_INVALID_ARGS);
947 return SECFailure;
948 }
949 /* see freebl/blapit.h for how we calculate
950 * GCMIV_RANDOM_BIRTHDAY_BITS */
951 flexBits -= GCMIV_RANDOM_BIRTHDAY_BITS;
952 flexBits = flexBits >> 1;
953 }
954 if (flexBits == 0) {
955 PORT_SetError(SEC_ERROR_INVALID_ARGS);
956 return SECFailure;
957 }
958 /* Turn those bits into the number of IV's we can safely return */
959 if (flexBits >= sizeof(gcmIv->max_count) * PR_BITS_PER_BYTE) {
960 gcmIv->max_count = PR_UINT64(0xffffffffffffffff);
961 } else {
962 gcmIv->max_count = PR_UINT64(1) << flexBits;
963 }
964 }
965
966 /* no generate, accept the IV from the source */
967 if (ivGen == CKG_NO_GENERATE) {
968 gcmIv->counter = 1;
969 return SECSuccess;
970 }
971
972 /* make sure we haven't exceeded the number of IVs we can return
973 * for this key, generator, and IV size */
974 if (gcmIv->counter >= gcmIv->max_count) {
975 /* use a unique error from just bad user input */
976 PORT_SetError(SEC_ERROR_EXTRA_INPUT);
977 return SECFailure;
978 }
979
980 /* build to mask to handle the first byte of the IV */
981 ivOffset = fixedBits / PR_BITS_PER_BYTE;
982 ivMask = 0xff >> ((8 - (fixedBits & 7)) & 7);
983 ivNewCount = ivLen - ivOffset;
984
985 /* finally generate the IV */
986 switch (ivGen) {
987 case CKG_GENERATE: /* default to counter */
988 case CKG_GENERATE_COUNTER:
989 iv[ivOffset] = (iv[ivOffset] & ~ivMask) |
990 (PORT_GET_BYTE_BE(gcmIv->counter, 0, ivNewCount) & ivMask);
991 for (i = 1; i < ivNewCount; i++) {
992 iv[ivOffset + i] = PORT_GET_BYTE_BE(gcmIv->counter, i, ivNewCount);
993 }
994 break;
995 /* for TLS 1.3 */
996 case CKG_GENERATE_COUNTER_XOR:
997 iv[ivOffset] ^=
998 (PORT_GET_BYTE_BE(gcmIv->counter, 0, ivNewCount) & ivMask);
999 for (i = 1; i < ivNewCount; i++) {
1000 iv[ivOffset + i] ^= PORT_GET_BYTE_BE(gcmIv->counter, i, ivNewCount);
1001 }
1002 break;
1003 case CKG_GENERATE_RANDOM:
1004 ivSave = iv[ivOffset] & ~ivMask;
1005 rv = RNG_GenerateGlobalRandomBytes(iv + ivOffset, ivNewCount);
1006 iv[ivOffset] = ivSave | (iv[ivOffset] & ivMask);
1007 if (rv != SECSuccess) {
1008 return rv;
1009 }
1010 break;
1011 }
1012 gcmIv->counter++;
1013 return SECSuccess;
1014 }
1015
1016 SECStatus
1017 GCM_EncryptAEAD(GCMContext *gcm, unsigned char *outbuf,
1018 unsigned int *outlen, unsigned int maxout,
1019 const unsigned char *inbuf, unsigned int inlen,
1020 void *params, unsigned int paramLen,
1021 const unsigned char *aad, unsigned int aadLen,
1022 unsigned int blocksize)
1023 {
1024 SECStatus rv;
1025 unsigned int tagBytes;
1026 unsigned int len;
1027 const CK_GCM_MESSAGE_PARAMS *gcmParams =
1028 (const CK_GCM_MESSAGE_PARAMS *)params;
1029
1030 PORT_Assert(blocksize == AES_BLOCK_SIZE);
1031 if (blocksize != AES_BLOCK_SIZE) {
1032 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1033 return SECFailure;
1034 }
1035
1036 /* paramLen comes all the way from the application layer, make sure
1037 * it's correct */
1038 if (paramLen != sizeof(CK_GCM_MESSAGE_PARAMS)) {
1039 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1040 return SECFailure;
1041 }
1042 /* if we were initialized with the C_EncryptInit, we shouldn't be in this
1043 * function */
1044 if (gcm->ctr_context_init) {
1045 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1046 return SECFailure;
1047 }
1048
1049 if (maxout < inlen) {
1050 *outlen = inlen;
1051 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1052 return SECFailure;
1053 }
1054
1055 rv = gcm_GenerateIV(&gcm->gcm_iv, gcmParams->pIv, gcmParams->ulIvLen,
1056 gcmParams->ulIvFixedBits, gcmParams->ivGenerator);
1057 if (rv != SECSuccess) {
1058 return SECFailure;
1059 }
1060
1061 rv = gcm_InitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen,
1062 gcmParams->ulTagBits, aad, aadLen);
1063 if (rv != SECSuccess) {
1064 return SECFailure;
1065 }
1066
1067 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
1068
1069 rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
1070 inbuf, inlen, AES_BLOCK_SIZE);
1071 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
1072 if (rv != SECSuccess) {
1073 return SECFailure;
1074 }
1075 rv = gcmHash_Update(gcm->ghash_context, outbuf, *outlen);
1076 if (rv != SECSuccess) {
1077 PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */
1078 *outlen = 0;
1079 return SECFailure;
1080 }
1081 rv = gcm_GetTag(gcm, gcmParams->pTag, &len, tagBytes);
1082 if (rv != SECSuccess) {
1083 PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */
1084 *outlen = 0;
1085 return SECFailure;
1086 };
1087 return SECSuccess;
1088 }
1089
1090 SECStatus
1091 GCM_DecryptAEAD(GCMContext *gcm, unsigned char *outbuf,
1092 unsigned int *outlen, unsigned int maxout,
1093 const unsigned char *inbuf, unsigned int inlen,
1094 void *params, unsigned int paramLen,
1095 const unsigned char *aad, unsigned int aadLen,
1096 unsigned int blocksize)
1097 {
1098 SECStatus rv;
1099 unsigned int tagBytes;
1100 unsigned char tag[MAX_BLOCK_SIZE];
1101 const unsigned char *intag;
1102 unsigned int len;
1103 const CK_GCM_MESSAGE_PARAMS *gcmParams =
1104 (const CK_GCM_MESSAGE_PARAMS *)params;
1105
1106 PORT_Assert(blocksize == AES_BLOCK_SIZE);
1107 if (blocksize != AES_BLOCK_SIZE) {
1108 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1109 return SECFailure;
1110 }
1111
1112 /* paramLen comes all the way from the application layer, make sure
1113 * it's correct */
1114 if (paramLen != sizeof(CK_GCM_MESSAGE_PARAMS)) {
1115 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1116 return SECFailure;
1117 }
1118 /* if we were initialized with the C_DecryptInit, we shouldn't be in this
1119 * function */
1120 if (gcm->ctr_context_init) {
1121 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1122 return SECFailure;
1123 }
1124
1125 if (maxout < inlen) {
1126 *outlen = inlen;
1127 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1128 return SECFailure;
1129 }
1130
1131 rv = gcm_InitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen,
1132 gcmParams->ulTagBits, aad, aadLen);
1133 if (rv != SECSuccess) {
1134 return SECFailure;
1135 }
1136
1137 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
1138 intag = gcmParams->pTag;
1139 PORT_Assert(tagBytes != 0);
1140
1141 /* verify the block */
1142 rv = gcmHash_Update(gcm->ghash_context, inbuf, inlen);
1143 if (rv != SECSuccess) {
1144 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
1145 return SECFailure;
1146 }
1147 rv = gcm_GetTag(gcm, tag, &len, AES_BLOCK_SIZE);
1148 if (rv != SECSuccess) {
1149 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
1150 return SECFailure;
1151 }
1152 /* Don't decrypt if we can't authenticate the encrypted data!
1153 * This assumes that if tagBits is may not be a multiple of 8, intag will
1154 * preserve the masked off missing bits. */
1155 if (NSS_SecureMemcmp(tag, intag, tagBytes) != 0) {
1156 /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
1157 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
1158 PORT_SetError(SEC_ERROR_BAD_DATA);
1159 PORT_Memset(tag, 0, sizeof(tag));
1160 return SECFailure;
1161 }
1162 PORT_Memset(tag, 0, sizeof(tag));
1163 /* finish the decryption */
1164 rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
1165 inbuf, inlen, AES_BLOCK_SIZE);
1166 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
1167 return rv;
1168 }
1169