security/nss/lib/freebl/hmacct.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial