tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

gcm.c (41680B)


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