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