tor-browser

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

hmacct.c (12866B)


      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 
      5 #ifdef FREEBL_NO_DEPEND
      6 #include "stubs.h"
      7 #endif
      8 
      9 #include "secport.h"
     10 #include "hasht.h"
     11 #include "blapit.h"
     12 #include "hmacct.h"
     13 #include "secerr.h"
     14 
     15 /* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
     16 * field. (SHA-384/512 have 128-bit length.) */
     17 #define MAX_HASH_BIT_COUNT_BYTES 16
     18 
     19 /* constantTimeGE returns 0xff if a>=b and 0x00 otherwise, where a, b <
     20 * MAX_UINT/2. */
     21 static unsigned char
     22 constantTimeGE(unsigned int a, unsigned int b)
     23 {
     24    return PORT_CT_GE(a, b);
     25 }
     26 
     27 /* constantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */
     28 static unsigned char
     29 constantTimeEQ(unsigned char a, unsigned char b)
     30 {
     31    return PORT_CT_EQ(a, b);
     32 }
     33 
     34 /* MAC performs a constant time SSLv3/TLS MAC of |dataLen| bytes of |data|,
     35 * where |dataLen| includes both the authenticated bytes and the MAC tag from
     36 * the sender. |dataLen| must be >= the length of the MAC tag.
     37 *
     38 * |dataTotalLen| is >= |dataLen| and also accounts for any padding bytes
     39 * that may follow the sender's MAC. (Only a single block of padding may
     40 * follow in SSLv3, or up to 255 bytes in TLS.)
     41 *
     42 * Since the results of decryption are secret information (otherwise a
     43 * padding-oracle is created), this function is constant-time with respect to
     44 * |dataLen|.
     45 *
     46 * |header| contains either the 13-byte TLS header (containing the sequence
     47 * number, record type etc), or it contains the SSLv3 header with the SSLv3
     48 * padding bytes etc. */
     49 static SECStatus
     50 MAC(unsigned char *mdOut,
     51    unsigned int *mdOutLen,
     52    unsigned int mdOutMax,
     53    const SECHashObject *hashObj,
     54    const unsigned char *macSecret,
     55    unsigned int macSecretLen,
     56    const unsigned char *header,
     57    unsigned int headerLen,
     58    const unsigned char *data,
     59    unsigned int dataLen,
     60    unsigned int dataTotalLen,
     61    unsigned char isSSLv3)
     62 {
     63    void *mdState = hashObj->create();
     64    const unsigned int mdSize = hashObj->length;
     65    const unsigned int mdBlockSize = hashObj->blocklength;
     66    /* mdLengthSize is the number of bytes in the length field that terminates
     67     * the hash.
     68     *
     69     * This assumes that hash functions with a 64 byte block size use a 64-bit
     70     * length, and otherwise they use a 128-bit length. This is true of {MD5,
     71     * SHA*} (which are all of the hash functions specified for use with TLS
     72     * today). */
     73    const unsigned int mdLengthSize = mdBlockSize == 64 ? 8 : 16;
     74 
     75    const unsigned int sslv3PadLen = hashObj->type == HASH_AlgMD5 ? 48 : 40;
     76 
     77    /* varianceBlocks is the number of blocks of the hash that we have to
     78     * calculate in constant time because they could be altered by the
     79     * padding value.
     80     *
     81     * In SSLv3, the padding must be minimal so the end of the plaintext
     82     * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that
     83     * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash
     84     * termination (0x80 + 64-bit length) don't fit in the final block, we
     85     * say that the final two blocks can vary based on the padding.
     86     *
     87     * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
     88     * required to be minimal. Therefore we say that the final six blocks
     89     * can vary based on the padding.
     90     *
     91     * Later in the function, if the message is short and there obviously
     92     * cannot be this many blocks then varianceBlocks can be reduced. */
     93    unsigned int varianceBlocks = isSSLv3 ? 2 : 6;
     94    /* From now on we're dealing with the MAC, which conceptually has 13
     95     * bytes of `header' before the start of the data (TLS) or 71/75 bytes
     96     * (SSLv3) */
     97    const unsigned int len = dataTotalLen + headerLen;
     98    /* maxMACBytes contains the maximum bytes of bytes in the MAC, including
     99     * |header|, assuming that there's no padding. */
    100    const unsigned int maxMACBytes = len - mdSize - 1;
    101    /* numBlocks is the maximum number of hash blocks. */
    102    const unsigned int numBlocks =
    103        (maxMACBytes + 1 + mdLengthSize + mdBlockSize - 1) / mdBlockSize;
    104    /* macEndOffset is the index just past the end of the data to be
    105     * MACed. */
    106    const unsigned int macEndOffset = dataLen + headerLen - mdSize;
    107    /* c is the index of the 0x80 byte in the final hash block that
    108     * contains application data. */
    109    const unsigned int c = macEndOffset % mdBlockSize;
    110    /* indexA is the hash block number that contains the 0x80 terminating
    111     * value. */
    112    const unsigned int indexA = macEndOffset / mdBlockSize;
    113    /* indexB is the hash block number that contains the 64-bit hash
    114     * length, in bits. */
    115    const unsigned int indexB = (macEndOffset + mdLengthSize) / mdBlockSize;
    116    /* bits is the hash-length in bits. It includes the additional hash
    117     * block for the masked HMAC key, or whole of |header| in the case of
    118     * SSLv3. */
    119    unsigned int bits;
    120    /* In order to calculate the MAC in constant time we have to handle
    121     * the final blocks specially because the padding value could cause the
    122     * end to appear somewhere in the final |varianceBlocks| blocks and we
    123     * can't leak where. However, |numStartingBlocks| worth of data can
    124     * be hashed right away because no padding value can affect whether
    125     * they are plaintext. */
    126    unsigned int numStartingBlocks = 0;
    127    /* k is the starting byte offset into the conceptual header||data where
    128     * we start processing. */
    129    unsigned int k = 0;
    130    unsigned char lengthBytes[MAX_HASH_BIT_COUNT_BYTES];
    131    /* hmacPad is the masked HMAC key. */
    132    unsigned char hmacPad[HASH_BLOCK_LENGTH_MAX];
    133    unsigned char firstBlock[HASH_BLOCK_LENGTH_MAX];
    134    unsigned char macOut[HASH_LENGTH_MAX];
    135    unsigned i, j;
    136 
    137    /* For SSLv3, if we're going to have any starting blocks then we need
    138     * at least two because the header is larger than a single block. */
    139    if (numBlocks > varianceBlocks + (isSSLv3 ? 1 : 0)) {
    140        numStartingBlocks = numBlocks - varianceBlocks;
    141        k = mdBlockSize * numStartingBlocks;
    142    }
    143 
    144    bits = 8 * macEndOffset;
    145    hashObj->begin(mdState);
    146    if (!isSSLv3) {
    147        /* Compute the initial HMAC block. For SSLv3, the padding and
    148         * secret bytes are included in |header| because they take more
    149         * than a single block. */
    150        bits += 8 * mdBlockSize;
    151        memset(hmacPad, 0, mdBlockSize);
    152        PORT_Assert(macSecretLen <= sizeof(hmacPad));
    153        memcpy(hmacPad, macSecret, macSecretLen);
    154        for (i = 0; i < mdBlockSize; i++)
    155            hmacPad[i] ^= 0x36;
    156        hashObj->update(mdState, hmacPad, mdBlockSize);
    157    }
    158 
    159    j = 0;
    160    memset(lengthBytes, 0, sizeof(lengthBytes));
    161    if (mdLengthSize == 16) {
    162        j = 8;
    163    }
    164    if (hashObj->type == HASH_AlgMD5) {
    165        /* MD5 appends a little-endian length. */
    166        for (i = 0; i < 4; i++) {
    167            lengthBytes[i + j] = bits >> (8 * i);
    168        }
    169    } else {
    170        /* All other TLS hash functions use a big-endian length. */
    171        for (i = 0; i < 4; i++) {
    172            lengthBytes[4 + i + j] = bits >> (8 * (3 - i));
    173        }
    174    }
    175 
    176    if (k > 0) {
    177        if (isSSLv3) {
    178            /* The SSLv3 header is larger than a single block.
    179             * overhang is the number of bytes beyond a single
    180             * block that the header consumes: either 7 bytes
    181             * (SHA1) or 11 bytes (MD5). */
    182            const unsigned int overhang = headerLen - mdBlockSize;
    183            hashObj->update(mdState, header, mdBlockSize);
    184            memcpy(firstBlock, header + mdBlockSize, overhang);
    185            memcpy(firstBlock + overhang, data, mdBlockSize - overhang);
    186            hashObj->update(mdState, firstBlock, mdBlockSize);
    187            for (i = 1; i < k / mdBlockSize - 1; i++) {
    188                hashObj->update(mdState, data + mdBlockSize * i - overhang,
    189                                mdBlockSize);
    190            }
    191        } else {
    192            /* k is a multiple of mdBlockSize. */
    193            memcpy(firstBlock, header, 13);
    194            memcpy(firstBlock + 13, data, mdBlockSize - 13);
    195            hashObj->update(mdState, firstBlock, mdBlockSize);
    196            for (i = 1; i < k / mdBlockSize; i++) {
    197                hashObj->update(mdState, data + mdBlockSize * i - 13,
    198                                mdBlockSize);
    199            }
    200        }
    201    }
    202 
    203    memset(macOut, 0, sizeof(macOut));
    204 
    205    /* We now process the final hash blocks. For each block, we construct
    206     * it in constant time. If i == indexA then we'll include the 0x80
    207     * bytes and zero pad etc. For each block we selectively copy it, in
    208     * constant time, to |macOut|. */
    209    for (i = numStartingBlocks; i <= numStartingBlocks + varianceBlocks; i++) {
    210        unsigned char block[HASH_BLOCK_LENGTH_MAX];
    211        unsigned char isBlockA = constantTimeEQ(i, indexA);
    212        unsigned char isBlockB = constantTimeEQ(i, indexB);
    213        for (j = 0; j < mdBlockSize; j++) {
    214            unsigned char isPastC = isBlockA & constantTimeGE(j, c);
    215            unsigned char isPastCPlus1 = isBlockA & constantTimeGE(j, c + 1);
    216            unsigned char b = 0;
    217            if (k < headerLen) {
    218                b = header[k];
    219            } else if (k < dataTotalLen + headerLen) {
    220                b = data[k - headerLen];
    221            }
    222            k++;
    223 
    224            /* If this is the block containing the end of the
    225             * application data, and we are at the offset for the
    226             * 0x80 value, then overwrite b with 0x80. */
    227            b = (b & ~isPastC) | (0x80 & isPastC);
    228            /* If this the the block containing the end of the
    229             * application data and we're past the 0x80 value then
    230             * just write zero. */
    231            b = b & ~isPastCPlus1;
    232            /* If this is indexB (the final block), but not
    233             * indexA (the end of the data), then the 64-bit
    234             * length didn't fit into indexA and we're having to
    235             * add an extra block of zeros. */
    236            b &= ~isBlockB | isBlockA;
    237 
    238            /* The final bytes of one of the blocks contains the length. */
    239            if (j >= mdBlockSize - mdLengthSize) {
    240                /* If this is indexB, write a length byte. */
    241                b = (b & ~isBlockB) |
    242                    (isBlockB & lengthBytes[j - (mdBlockSize - mdLengthSize)]);
    243            }
    244            block[j] = b;
    245        }
    246 
    247        hashObj->update(mdState, block, mdBlockSize);
    248        hashObj->end_raw(mdState, block, NULL, mdSize);
    249        /* If this is indexB, copy the hash value to |macOut|. */
    250        for (j = 0; j < mdSize; j++) {
    251            macOut[j] |= block[j] & isBlockB;
    252        }
    253    }
    254 
    255    hashObj->begin(mdState);
    256 
    257    if (isSSLv3) {
    258        /* We repurpose |hmacPad| to contain the SSLv3 pad2 block. */
    259        for (i = 0; i < sslv3PadLen; i++)
    260            hmacPad[i] = 0x5c;
    261 
    262        hashObj->update(mdState, macSecret, macSecretLen);
    263        hashObj->update(mdState, hmacPad, sslv3PadLen);
    264        hashObj->update(mdState, macOut, mdSize);
    265    } else {
    266        /* Complete the HMAC in the standard manner. */
    267        for (i = 0; i < mdBlockSize; i++)
    268            hmacPad[i] ^= 0x6a;
    269 
    270        hashObj->update(mdState, hmacPad, mdBlockSize);
    271        hashObj->update(mdState, macOut, mdSize);
    272    }
    273 
    274    hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
    275    hashObj->destroy(mdState, PR_TRUE);
    276 
    277    PORT_SafeZero(lengthBytes, sizeof lengthBytes);
    278    PORT_SafeZero(hmacPad, sizeof hmacPad);
    279    PORT_SafeZero(firstBlock, sizeof firstBlock);
    280    PORT_SafeZero(macOut, sizeof macOut);
    281 
    282    return SECSuccess;
    283 }
    284 
    285 SECStatus
    286 HMAC_ConstantTime(
    287    unsigned char *result,
    288    unsigned int *resultLen,
    289    unsigned int maxResultLen,
    290    const SECHashObject *hashObj,
    291    const unsigned char *secret,
    292    unsigned int secretLen,
    293    const unsigned char *header,
    294    unsigned int headerLen,
    295    const unsigned char *body,
    296    unsigned int bodyLen,
    297    unsigned int bodyTotalLen)
    298 {
    299    if (hashObj->end_raw == NULL)
    300        return SECFailure;
    301    return MAC(result, resultLen, maxResultLen, hashObj, secret, secretLen,
    302               header, headerLen, body, bodyLen, bodyTotalLen,
    303               0 /* not SSLv3 */);
    304 }
    305 
    306 SECStatus
    307 SSLv3_MAC_ConstantTime(
    308    unsigned char *result,
    309    unsigned int *resultLen,
    310    unsigned int maxResultLen,
    311    const SECHashObject *hashObj,
    312    const unsigned char *secret,
    313    unsigned int secretLen,
    314    const unsigned char *header,
    315    unsigned int headerLen,
    316    const unsigned char *body,
    317    unsigned int bodyLen,
    318    unsigned int bodyTotalLen)
    319 {
    320    if (hashObj->end_raw == NULL)
    321        return SECFailure;
    322    return MAC(result, resultLen, maxResultLen, hashObj, secret, secretLen,
    323               header, headerLen, body, bodyLen, bodyTotalLen,
    324               1 /* SSLv3 */);
    325 }