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 |