security/nss/lib/freebl/hmacct.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/lib/freebl/hmacct.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,336 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#ifdef FREEBL_NO_DEPEND
     1.9 +#include "stubs.h"
    1.10 +#endif
    1.11 +
    1.12 +#include "secport.h"
    1.13 +#include "hasht.h"
    1.14 +#include "blapit.h"
    1.15 +#include "hmacct.h"
    1.16 +#include "secerr.h"
    1.17 +
    1.18 +/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
    1.19 + * field. (SHA-384/512 have 128-bit length.) */
    1.20 +#define MAX_HASH_BIT_COUNT_BYTES 16
    1.21 +
    1.22 +/* Some utility functions are needed:
    1.23 + *
    1.24 + * These macros return the given value with the MSB copied to all the other
    1.25 + * bits. They use the fact that an arithmetic shift shifts-in the sign bit.
    1.26 + * However, this is not ensured by the C standard so you may need to replace
    1.27 + * them with something else on odd CPUs.
    1.28 + *
    1.29 + * Note: the argument to these macros must be an unsigned int.
    1.30 + * */
    1.31 +#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned int)( (int)(x) >> (sizeof(int)*8-1) ) )
    1.32 +#define DUPLICATE_MSB_TO_ALL_8(x) ( (unsigned char)(DUPLICATE_MSB_TO_ALL(x)) )
    1.33 +
    1.34 +/* constantTimeGE returns 0xff if a>=b and 0x00 otherwise, where a, b <
    1.35 + * MAX_UINT/2. */
    1.36 +static unsigned char
    1.37 +constantTimeGE(unsigned int a, unsigned int b)
    1.38 +{
    1.39 +    a -= b;
    1.40 +    return DUPLICATE_MSB_TO_ALL(~a);
    1.41 +}
    1.42 +
    1.43 +/* constantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */
    1.44 +static unsigned char
    1.45 +constantTimeEQ8(unsigned char a, unsigned char b)
    1.46 +{
    1.47 +    unsigned int c = a ^ b;
    1.48 +    c--;
    1.49 +    return DUPLICATE_MSB_TO_ALL_8(c);
    1.50 +}
    1.51 +
    1.52 +/* MAC performs a constant time SSLv3/TLS MAC of |dataLen| bytes of |data|,
    1.53 + * where |dataLen| includes both the authenticated bytes and the MAC tag from
    1.54 + * the sender. |dataLen| must be >= the length of the MAC tag.
    1.55 + *
    1.56 + * |dataTotalLen| is >= |dataLen| and also accounts for any padding bytes
    1.57 + * that may follow the sender's MAC. (Only a single block of padding may
    1.58 + * follow in SSLv3, or up to 255 bytes in TLS.)
    1.59 + *
    1.60 + * Since the results of decryption are secret information (otherwise a
    1.61 + * padding-oracle is created), this function is constant-time with respect to
    1.62 + * |dataLen|.
    1.63 + *
    1.64 + * |header| contains either the 13-byte TLS header (containing the sequence
    1.65 + * number, record type etc), or it contains the SSLv3 header with the SSLv3
    1.66 + * padding bytes etc. */
    1.67 +static SECStatus
    1.68 +MAC(unsigned char *mdOut,
    1.69 +    unsigned int *mdOutLen,
    1.70 +    unsigned int mdOutMax,
    1.71 +    const SECHashObject *hashObj,
    1.72 +    const unsigned char *macSecret,
    1.73 +    unsigned int macSecretLen,
    1.74 +    const unsigned char *header,
    1.75 +    unsigned int headerLen,
    1.76 +    const unsigned char *data,
    1.77 +    unsigned int dataLen,
    1.78 +    unsigned int dataTotalLen,
    1.79 +    unsigned char isSSLv3)
    1.80 +{
    1.81 +    void *mdState = hashObj->create();
    1.82 +    const unsigned int mdSize = hashObj->length;
    1.83 +    const unsigned int mdBlockSize = hashObj->blocklength;
    1.84 +    /* mdLengthSize is the number of bytes in the length field that terminates
    1.85 +     * the hash.
    1.86 +     *
    1.87 +     * This assumes that hash functions with a 64 byte block size use a 64-bit
    1.88 +     * length, and otherwise they use a 128-bit length. This is true of {MD5,
    1.89 +     * SHA*} (which are all of the hash functions specified for use with TLS
    1.90 +     * today). */
    1.91 +    const unsigned int mdLengthSize = mdBlockSize == 64 ? 8 : 16;
    1.92 +
    1.93 +    const unsigned int sslv3PadLen = hashObj->type == HASH_AlgMD5 ? 48 : 40;
    1.94 +
    1.95 +    /* varianceBlocks is the number of blocks of the hash that we have to
    1.96 +     * calculate in constant time because they could be altered by the
    1.97 +     * padding value.
    1.98 +     *
    1.99 +     * In SSLv3, the padding must be minimal so the end of the plaintext
   1.100 +     * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that
   1.101 +     * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash
   1.102 +     * termination (0x80 + 64-bit length) don't fit in the final block, we
   1.103 +     * say that the final two blocks can vary based on the padding.
   1.104 +     *
   1.105 +     * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
   1.106 +     * required to be minimal. Therefore we say that the final six blocks
   1.107 +     * can vary based on the padding.
   1.108 +     *
   1.109 +     * Later in the function, if the message is short and there obviously
   1.110 +     * cannot be this many blocks then varianceBlocks can be reduced. */
   1.111 +    unsigned int varianceBlocks = isSSLv3 ? 2 : 6;
   1.112 +    /* From now on we're dealing with the MAC, which conceptually has 13
   1.113 +     * bytes of `header' before the start of the data (TLS) or 71/75 bytes
   1.114 +     * (SSLv3) */
   1.115 +    const unsigned int len = dataTotalLen + headerLen;
   1.116 +    /* maxMACBytes contains the maximum bytes of bytes in the MAC, including
   1.117 +     * |header|, assuming that there's no padding. */
   1.118 +    const unsigned int maxMACBytes = len - mdSize - 1;
   1.119 +    /* numBlocks is the maximum number of hash blocks. */
   1.120 +    const unsigned int numBlocks =
   1.121 +	(maxMACBytes + 1 + mdLengthSize + mdBlockSize - 1) / mdBlockSize;
   1.122 +    /* macEndOffset is the index just past the end of the data to be
   1.123 +     * MACed. */
   1.124 +    const unsigned int macEndOffset = dataLen + headerLen - mdSize;
   1.125 +    /* c is the index of the 0x80 byte in the final hash block that
   1.126 +     * contains application data. */
   1.127 +    const unsigned int c = macEndOffset % mdBlockSize;
   1.128 +    /* indexA is the hash block number that contains the 0x80 terminating
   1.129 +     * value. */
   1.130 +    const unsigned int indexA = macEndOffset / mdBlockSize;
   1.131 +    /* indexB is the hash block number that contains the 64-bit hash
   1.132 +     * length, in bits. */
   1.133 +    const unsigned int indexB = (macEndOffset + mdLengthSize) / mdBlockSize;
   1.134 +    /* bits is the hash-length in bits. It includes the additional hash
   1.135 +     * block for the masked HMAC key, or whole of |header| in the case of
   1.136 +     * SSLv3. */
   1.137 +    unsigned int bits;
   1.138 +    /* In order to calculate the MAC in constant time we have to handle
   1.139 +     * the final blocks specially because the padding value could cause the
   1.140 +     * end to appear somewhere in the final |varianceBlocks| blocks and we
   1.141 +     * can't leak where. However, |numStartingBlocks| worth of data can
   1.142 +     * be hashed right away because no padding value can affect whether
   1.143 +     * they are plaintext. */
   1.144 +    unsigned int numStartingBlocks = 0;
   1.145 +    /* k is the starting byte offset into the conceptual header||data where
   1.146 +     * we start processing. */
   1.147 +    unsigned int k = 0;
   1.148 +    unsigned char lengthBytes[MAX_HASH_BIT_COUNT_BYTES];
   1.149 +    /* hmacPad is the masked HMAC key. */
   1.150 +    unsigned char hmacPad[HASH_BLOCK_LENGTH_MAX];
   1.151 +    unsigned char firstBlock[HASH_BLOCK_LENGTH_MAX];
   1.152 +    unsigned char macOut[HASH_LENGTH_MAX];
   1.153 +    unsigned i, j;
   1.154 +
   1.155 +    /* For SSLv3, if we're going to have any starting blocks then we need
   1.156 +     * at least two because the header is larger than a single block. */
   1.157 +    if (numBlocks > varianceBlocks + (isSSLv3 ? 1 : 0)) {
   1.158 +	numStartingBlocks = numBlocks - varianceBlocks;
   1.159 +	k = mdBlockSize*numStartingBlocks;
   1.160 +    }
   1.161 +
   1.162 +    bits = 8*macEndOffset;
   1.163 +    hashObj->begin(mdState);
   1.164 +    if (!isSSLv3) {
   1.165 +	/* Compute the initial HMAC block. For SSLv3, the padding and
   1.166 +	 * secret bytes are included in |header| because they take more
   1.167 +	 * than a single block. */
   1.168 +	bits += 8*mdBlockSize;
   1.169 +	memset(hmacPad, 0, mdBlockSize);
   1.170 +	PORT_Assert(macSecretLen <= sizeof(hmacPad));
   1.171 +	memcpy(hmacPad, macSecret, macSecretLen);
   1.172 +	for (i = 0; i < mdBlockSize; i++)
   1.173 +	    hmacPad[i] ^= 0x36;
   1.174 +	hashObj->update(mdState, hmacPad, mdBlockSize);
   1.175 +    }
   1.176 +
   1.177 +    j = 0;
   1.178 +    memset(lengthBytes, 0, sizeof(lengthBytes));
   1.179 +    if (mdLengthSize == 16) {
   1.180 +	j = 8;
   1.181 +    }
   1.182 +    if (hashObj->type == HASH_AlgMD5) {
   1.183 +	/* MD5 appends a little-endian length. */
   1.184 +	for (i = 0; i < 4; i++) {
   1.185 +	    lengthBytes[i+j] = bits >> (8*i);
   1.186 +	}
   1.187 +    } else {
   1.188 +	/* All other TLS hash functions use a big-endian length. */
   1.189 +	for (i = 0; i < 4; i++) {
   1.190 +	    lengthBytes[4+i+j] = bits >> (8*(3-i));
   1.191 +	}
   1.192 +    }
   1.193 +
   1.194 +    if (k > 0) {
   1.195 +	if (isSSLv3) {
   1.196 +	    /* The SSLv3 header is larger than a single block.
   1.197 +	     * overhang is the number of bytes beyond a single
   1.198 +	     * block that the header consumes: either 7 bytes
   1.199 +	     * (SHA1) or 11 bytes (MD5). */
   1.200 +	    const unsigned int overhang = headerLen-mdBlockSize;
   1.201 +	    hashObj->update(mdState, header, mdBlockSize);
   1.202 +	    memcpy(firstBlock, header + mdBlockSize, overhang);
   1.203 +	    memcpy(firstBlock + overhang, data, mdBlockSize-overhang);
   1.204 +	    hashObj->update(mdState, firstBlock, mdBlockSize);
   1.205 +	    for (i = 1; i < k/mdBlockSize - 1; i++) {
   1.206 +		hashObj->update(mdState, data + mdBlockSize*i - overhang,
   1.207 +				mdBlockSize);
   1.208 +	    }
   1.209 +	} else {
   1.210 +	    /* k is a multiple of mdBlockSize. */
   1.211 +	    memcpy(firstBlock, header, 13);
   1.212 +	    memcpy(firstBlock+13, data, mdBlockSize-13);
   1.213 +	    hashObj->update(mdState, firstBlock, mdBlockSize);
   1.214 +	    for (i = 1; i < k/mdBlockSize; i++) {
   1.215 +		hashObj->update(mdState, data + mdBlockSize*i - 13,
   1.216 +				mdBlockSize);
   1.217 +	    }
   1.218 +	}
   1.219 +    }
   1.220 +
   1.221 +    memset(macOut, 0, sizeof(macOut));
   1.222 +
   1.223 +    /* We now process the final hash blocks. For each block, we construct
   1.224 +     * it in constant time. If i == indexA then we'll include the 0x80
   1.225 +     * bytes and zero pad etc. For each block we selectively copy it, in
   1.226 +     * constant time, to |macOut|. */
   1.227 +    for (i = numStartingBlocks; i <= numStartingBlocks+varianceBlocks; i++) {
   1.228 +	unsigned char block[HASH_BLOCK_LENGTH_MAX];
   1.229 +	unsigned char isBlockA = constantTimeEQ8(i, indexA);
   1.230 +	unsigned char isBlockB = constantTimeEQ8(i, indexB);
   1.231 +	for (j = 0; j < mdBlockSize; j++) {
   1.232 +	    unsigned char isPastC = isBlockA & constantTimeGE(j, c);
   1.233 +	    unsigned char isPastCPlus1 = isBlockA & constantTimeGE(j, c+1);
   1.234 +	    unsigned char b = 0;
   1.235 +	    if (k < headerLen) {
   1.236 +		b = header[k];
   1.237 +	    } else if (k < dataTotalLen + headerLen) {
   1.238 +		b = data[k-headerLen];
   1.239 +	    }
   1.240 +	    k++;
   1.241 +
   1.242 +	    /* If this is the block containing the end of the
   1.243 +	     * application data, and we are at the offset for the
   1.244 +	     * 0x80 value, then overwrite b with 0x80. */
   1.245 +	    b = (b&~isPastC) | (0x80&isPastC);
   1.246 +	    /* If this the the block containing the end of the
   1.247 +	     * application data and we're past the 0x80 value then
   1.248 +	     * just write zero. */
   1.249 +	    b = b&~isPastCPlus1;
   1.250 +	    /* If this is indexB (the final block), but not
   1.251 +	     * indexA (the end of the data), then the 64-bit
   1.252 +	     * length didn't fit into indexA and we're having to
   1.253 +	     * add an extra block of zeros. */
   1.254 +	    b &= ~isBlockB | isBlockA;
   1.255 +
   1.256 +	    /* The final bytes of one of the blocks contains the length. */
   1.257 +	    if (j >= mdBlockSize - mdLengthSize) {
   1.258 +		/* If this is indexB, write a length byte. */
   1.259 +		b = (b&~isBlockB) |
   1.260 +		    (isBlockB&lengthBytes[j-(mdBlockSize-mdLengthSize)]);
   1.261 +	    }
   1.262 +	    block[j] = b;
   1.263 +	}
   1.264 +
   1.265 +	hashObj->update(mdState, block, mdBlockSize);
   1.266 +	hashObj->end_raw(mdState, block, NULL, mdSize);
   1.267 +	/* If this is indexB, copy the hash value to |macOut|. */
   1.268 +	for (j = 0; j < mdSize; j++) {
   1.269 +	    macOut[j] |= block[j]&isBlockB;
   1.270 +	}
   1.271 +    }
   1.272 +
   1.273 +    hashObj->begin(mdState);
   1.274 +
   1.275 +    if (isSSLv3) {
   1.276 +	/* We repurpose |hmacPad| to contain the SSLv3 pad2 block. */
   1.277 +	for (i = 0; i < sslv3PadLen; i++)
   1.278 +	    hmacPad[i] = 0x5c;
   1.279 +
   1.280 +	hashObj->update(mdState, macSecret, macSecretLen);
   1.281 +	hashObj->update(mdState, hmacPad, sslv3PadLen);
   1.282 +	hashObj->update(mdState, macOut, mdSize);
   1.283 +    } else {
   1.284 +	/* Complete the HMAC in the standard manner. */
   1.285 +	for (i = 0; i < mdBlockSize; i++)
   1.286 +	    hmacPad[i] ^= 0x6a;
   1.287 +
   1.288 +	hashObj->update(mdState, hmacPad, mdBlockSize);
   1.289 +	hashObj->update(mdState, macOut, mdSize);
   1.290 +    }
   1.291 +
   1.292 +    hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
   1.293 +    hashObj->destroy(mdState, PR_TRUE);
   1.294 +
   1.295 +    return SECSuccess;
   1.296 +}
   1.297 +
   1.298 +SECStatus
   1.299 +HMAC_ConstantTime(
   1.300 +    unsigned char *result,
   1.301 +    unsigned int *resultLen,
   1.302 +    unsigned int maxResultLen,
   1.303 +    const SECHashObject *hashObj,
   1.304 +    const unsigned char *secret,
   1.305 +    unsigned int secretLen,
   1.306 +    const unsigned char *header,
   1.307 +    unsigned int headerLen,
   1.308 +    const unsigned char *body,
   1.309 +    unsigned int bodyLen,
   1.310 +    unsigned int bodyTotalLen)
   1.311 +{
   1.312 +    if (hashObj->end_raw == NULL)
   1.313 +	return SECFailure;
   1.314 +    return MAC(result, resultLen, maxResultLen, hashObj, secret, secretLen,
   1.315 +	       header, headerLen, body, bodyLen, bodyTotalLen,
   1.316 +	       0 /* not SSLv3 */);
   1.317 +}
   1.318 +
   1.319 +SECStatus
   1.320 +SSLv3_MAC_ConstantTime(
   1.321 +    unsigned char *result,
   1.322 +    unsigned int *resultLen,
   1.323 +    unsigned int maxResultLen,
   1.324 +    const SECHashObject *hashObj,
   1.325 +    const unsigned char *secret,
   1.326 +    unsigned int secretLen,
   1.327 +    const unsigned char *header,
   1.328 +    unsigned int headerLen,
   1.329 +    const unsigned char *body,
   1.330 +    unsigned int bodyLen,
   1.331 +    unsigned int bodyTotalLen)
   1.332 +{
   1.333 +    if (hashObj->end_raw == NULL)
   1.334 +	return SECFailure;
   1.335 +    return MAC(result, resultLen, maxResultLen, hashObj, secret, secretLen,
   1.336 +	       header, headerLen, body, bodyLen, bodyTotalLen,
   1.337 +	       1 /* SSLv3 */);
   1.338 +}
   1.339 +

mercurial