Chromium Code Reviews| 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 |