| 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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 return rv; | 196 return rv; |
| 197 } | 197 } |
| 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; | 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 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; |
| 219 MP_DIGITS(&ZZ) = 0; | 219 MP_DIGITS(&ZZ) = 0; |
| 220 MP_DIGITS(&psub1) = 0; |
| 220 CHECK_MPI_OK( mp_init(&p) ); | 221 CHECK_MPI_OK( mp_init(&p) ); |
| 221 CHECK_MPI_OK( mp_init(&Xa) ); | 222 CHECK_MPI_OK( mp_init(&Xa) ); |
| 222 CHECK_MPI_OK( mp_init(&Yb) ); | 223 CHECK_MPI_OK( mp_init(&Yb) ); |
| 223 CHECK_MPI_OK( mp_init(&ZZ) ); | 224 CHECK_MPI_OK( mp_init(&ZZ) ); |
| 225 CHECK_MPI_OK( mp_init(&psub1) ); |
| 224 SECITEM_TO_MPINT(*publicValue, &Yb); | 226 SECITEM_TO_MPINT(*publicValue, &Yb); |
| 225 SECITEM_TO_MPINT(*privateValue, &Xa); | 227 SECITEM_TO_MPINT(*privateValue, &Xa); |
| 226 SECITEM_TO_MPINT(*prime, &p); | 228 SECITEM_TO_MPINT(*prime, &p); |
| 229 CHECK_MPI_OK( mp_sub_d(&p, 1, &psub1) ); |
| 230 |
| 231 /* We assume that the modulus, p, is a safe prime. That is, p = 2q+1 where |
| 232 * q is also a prime. Thus the orders of the subgroups are factors of 2q: |
| 233 * namely 1, 2, q and 2q. |
| 234 * |
| 235 * We check that the peer's public value isn't zero (which isn't in the |
| 236 * group), one (subgroup of order one) or p-1 (subgroup of order 2). We |
| 237 * also check that the public value is less than p, to avoid being fooled |
| 238 * by values like p+1 or 2*p-1. |
| 239 * |
| 240 * Thus we must be operating in the subgroup of size q or 2q. */ |
| 241 if (mp_cmp_d(&Yb, 1) <= 0 || |
| 242 mp_cmp(&Yb, &psub1) >= 0) { |
| 243 err = MP_BADARG; |
| 244 goto cleanup; |
| 245 } |
| 246 |
| 227 /* ZZ = (Yb)**Xa mod p */ | 247 /* ZZ = (Yb)**Xa mod p */ |
| 228 CHECK_MPI_OK( mp_exptmod(&Yb, &Xa, &p, &ZZ) ); | 248 CHECK_MPI_OK( mp_exptmod(&Yb, &Xa, &p, &ZZ) ); |
| 229 /* number of bytes in the derived secret */ | 249 /* number of bytes in the derived secret */ |
| 230 len = mp_unsigned_octet_size(&ZZ); | 250 len = mp_unsigned_octet_size(&ZZ); |
| 231 if (len <= 0) { | 251 if (len <= 0) { |
| 232 err = MP_BADARG; | 252 err = MP_BADARG; |
| 233 goto cleanup; | 253 goto cleanup; |
| 234 } | 254 } |
| 235 /* allocate a buffer which can hold the entire derived secret. */ | 255 /* allocate a buffer which can hold the entire derived secret. */ |
| 236 secret = PORT_Alloc(len); | 256 secret = PORT_Alloc(len); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 253 memset(derivedSecret->data, 0, offset); | 273 memset(derivedSecret->data, 0, offset); |
| 254 memcpy(derivedSecret->data + offset, secret, len); | 274 memcpy(derivedSecret->data + offset, secret, len); |
| 255 } else { | 275 } else { |
| 256 memcpy(derivedSecret->data, secret + len - nb, nb); | 276 memcpy(derivedSecret->data, secret + len - nb, nb); |
| 257 } | 277 } |
| 258 cleanup: | 278 cleanup: |
| 259 mp_clear(&p); | 279 mp_clear(&p); |
| 260 mp_clear(&Xa); | 280 mp_clear(&Xa); |
| 261 mp_clear(&Yb); | 281 mp_clear(&Yb); |
| 262 mp_clear(&ZZ); | 282 mp_clear(&ZZ); |
| 283 mp_clear(&psub1); |
| 263 if (secret) { | 284 if (secret) { |
| 264 /* free the buffer allocated for the full secret. */ | 285 /* free the buffer allocated for the full secret. */ |
| 265 PORT_ZFree(secret, len); | 286 PORT_ZFree(secret, len); |
| 266 } | 287 } |
| 267 if (err) { | 288 if (err) { |
| 268 MP_TO_SEC_ERROR(err); | 289 MP_TO_SEC_ERROR(err); |
| 269 if (derivedSecret->data) | 290 if (derivedSecret->data) |
| 270 PORT_ZFree(derivedSecret->data, derivedSecret->len); | 291 PORT_ZFree(derivedSecret->data, derivedSecret->len); |
| 271 return SECFailure; | 292 return SECFailure; |
| 272 } | 293 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 mp_clear(&p); | 403 mp_clear(&p); |
| 383 mp_clear(&q); | 404 mp_clear(&q); |
| 384 mp_clear(&y); | 405 mp_clear(&y); |
| 385 mp_clear(&r); | 406 mp_clear(&r); |
| 386 if (err) { | 407 if (err) { |
| 387 MP_TO_SEC_ERROR(err); | 408 MP_TO_SEC_ERROR(err); |
| 388 return PR_FALSE; | 409 return PR_FALSE; |
| 389 } | 410 } |
| 390 return (cmp == 0) ? PR_TRUE : PR_FALSE; | 411 return (cmp == 0) ? PR_TRUE : PR_FALSE; |
| 391 } | 412 } |
| OLD | NEW |