OLD | NEW |
---|---|
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 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 | 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/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | 4 |
5 /* | 5 /* |
6 * Diffie-Hellman parameter generation, key generation, and secret derivation. | 6 * Diffie-Hellman parameter generation, key generation, and secret derivation. |
7 * KEA secret generation and verification. | 7 * KEA secret generation and verification. |
8 */ | 8 */ |
9 #ifdef FREEBL_NO_DEPEND | 9 #ifdef FREEBL_NO_DEPEND |
10 #include "stubs.h" | 10 #include "stubs.h" |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
198 | 198 |
199 SECStatus | 199 SECStatus |
200 DH_Derive(SECItem *publicValue, | 200 DH_Derive(SECItem *publicValue, |
201 SECItem *prime, | 201 SECItem *prime, |
202 SECItem *privateValue, | 202 SECItem *privateValue, |
203 SECItem *derivedSecret, | 203 SECItem *derivedSecret, |
204 unsigned int outBytes) | 204 unsigned int outBytes) |
205 { | 205 { |
206 mp_int p, Xa, Yb, ZZ, psub1; | 206 mp_int p, Xa, Yb, ZZ, psub1; |
207 mp_err err = MP_OKAY; | 207 mp_err err = MP_OKAY; |
208 int len = 0; | 208 unsigned int len = 0; |
209 unsigned int nb; | 209 unsigned int nb; |
210 unsigned char *secret = NULL; | 210 unsigned char *secret = NULL; |
211 if (!publicValue || !prime || !privateValue || !derivedSecret) { | 211 if (!publicValue || !prime || !privateValue || !derivedSecret) { |
212 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 212 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
213 return SECFailure; | 213 return SECFailure; |
214 } | 214 } |
215 memset(derivedSecret, 0, sizeof *derivedSecret); | 215 memset(derivedSecret, 0, sizeof *derivedSecret); |
216 MP_DIGITS(&p) = 0; | 216 MP_DIGITS(&p) = 0; |
217 MP_DIGITS(&Xa) = 0; | 217 MP_DIGITS(&Xa) = 0; |
218 MP_DIGITS(&Yb) = 0; | 218 MP_DIGITS(&Yb) = 0; |
(...skipping 26 matching lines...) Expand all Loading... | |
245 } | 245 } |
246 | 246 |
247 /* ZZ = (Yb)**Xa mod p */ | 247 /* ZZ = (Yb)**Xa mod p */ |
248 CHECK_MPI_OK( mp_exptmod(&Yb, &Xa, &p, &ZZ) ); | 248 CHECK_MPI_OK( mp_exptmod(&Yb, &Xa, &p, &ZZ) ); |
249 /* number of bytes in the derived secret */ | 249 /* number of bytes in the derived secret */ |
250 len = mp_unsigned_octet_size(&ZZ); | 250 len = mp_unsigned_octet_size(&ZZ); |
251 if (len <= 0) { | 251 if (len <= 0) { |
252 err = MP_BADARG; | 252 err = MP_BADARG; |
253 goto cleanup; | 253 goto cleanup; |
254 } | 254 } |
255 | |
256 /* | |
257 * We check to make sure that ZZ is not equal to 1 or -1 mod p. | |
Ryan Sleevi
2015/12/11 01:26:14
Of interest
davidben
2015/12/11 22:10:58
Meh. https://crbug.com/482950.
If I'm understandi
| |
258 * This helps guard against small subgroup attacks, since an attacker | |
259 * using a subgroup of size N will produce 1 or -1 with probability 1/N. | |
260 * When the protocol is executed within a properly large subgroup, the | |
261 * probability of this result will be negligibly small. For example, | |
262 * with a strong prime of the form 2p+1, the probability will be 1/p. | |
263 * | |
264 * We return MP_BADARG because this is probably the result of a bad | |
265 * public value or a bad prime having been provided. | |
266 */ | |
267 if (mp_cmp_d(&ZZ, 1) == 0 || | |
268 mp_cmp(&ZZ, &psub1) == 0) { | |
269 err = MP_BADARG; | |
270 goto cleanup; | |
271 } | |
272 | |
255 /* allocate a buffer which can hold the entire derived secret. */ | 273 /* allocate a buffer which can hold the entire derived secret. */ |
256 secret = PORT_Alloc(len); | 274 secret = PORT_Alloc(len); |
257 /* grab the derived secret */ | 275 /* grab the derived secret */ |
258 err = mp_to_unsigned_octets(&ZZ, secret, len); | 276 err = mp_to_unsigned_octets(&ZZ, secret, len); |
259 if (err >= 0) err = MP_OKAY; | 277 if (err >= 0) err = MP_OKAY; |
260 /* | 278 /* |
261 ** if outBytes is 0 take all of the bytes from the derived secret. | 279 ** if outBytes is 0 take all of the bytes from the derived secret. |
262 ** if outBytes is not 0 take exactly outBytes from the derived secret, zero | 280 ** if outBytes is not 0 take exactly outBytes from the derived secret, zero |
263 ** pad at the beginning if necessary, and truncate beginning bytes | 281 ** pad at the beginning if necessary, and truncate beginning bytes |
264 ** if necessary. | 282 ** if necessary. |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
403 mp_clear(&p); | 421 mp_clear(&p); |
404 mp_clear(&q); | 422 mp_clear(&q); |
405 mp_clear(&y); | 423 mp_clear(&y); |
406 mp_clear(&r); | 424 mp_clear(&r); |
407 if (err) { | 425 if (err) { |
408 MP_TO_SEC_ERROR(err); | 426 MP_TO_SEC_ERROR(err); |
409 return PR_FALSE; | 427 return PR_FALSE; |
410 } | 428 } |
411 return (cmp == 0) ? PR_TRUE : PR_FALSE; | 429 return (cmp == 0) ? PR_TRUE : PR_FALSE; |
412 } | 430 } |
OLD | NEW |