Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/freebl/hmacct.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
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 /* 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)) ) | |
30 | |
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 } | |
39 | |
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 } | |
48 | |
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; | |
89 | |
90 const unsigned int sslv3PadLen = hashObj->type == HASH_AlgMD5 ? 48 : 40; | |
91 | |
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; | |
151 | |
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 } | |
158 | |
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 } | |
173 | |
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 } | |
190 | |
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 } | |
217 | |
218 memset(macOut, 0, sizeof(macOut)); | |
219 | |
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++; | |
238 | |
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; | |
252 | |
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 } | |
261 | |
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 } | |
269 | |
270 hashObj->begin(mdState); | |
271 | |
272 if (isSSLv3) { | |
273 /* We repurpose |hmacPad| to contain the SSLv3 pad2 block. */ | |
274 for (i = 0; i < sslv3PadLen; i++) | |
275 hmacPad[i] = 0x5c; | |
276 | |
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; | |
284 | |
285 hashObj->update(mdState, hmacPad, mdBlockSize); | |
286 hashObj->update(mdState, macOut, mdSize); | |
287 } | |
288 | |
289 hashObj->end(mdState, mdOut, mdOutLen, mdOutMax); | |
290 hashObj->destroy(mdState, PR_TRUE); | |
291 | |
292 return SECSuccess; | |
293 } | |
294 | |
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 } | |
315 | |
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 } | |
336 |