1 /*

2 * Copyright (C) 1998-2002 D. Hugh Redelmeier.

3 * Copyright (C) 1999, 2000, 2001 Henry Spencer.

4 * Copyright (C) 2005-2008 Martin Willi

5 * Copyright (C) 2005 Jan Hutter

6 * Hochschule fuer Technik Rapperswil

7 *

8 * This program is free software; you can redistribute it and/or modify it

9 * under the terms of the GNU General Public License as published by the

10 * Free Software Foundation; either version 2 of the License, or (at your

11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.

12 *

13 * This program is distributed in the hope that it will be useful, but

14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY

15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License

16 * for more details.

17 *

18 * $Id$

19 */

21 #include <gmp.h>

25 #include <debug.h>

28 /**

29 * Modulus of Group 1 (MODP_768_BIT).

30 */

38 };

40 /**

41 * Modulus of Group 2 (MODP_1024_BIT).

42 */

52 };

54 /**

55 * Modulus of Group 5 (MODP_1536_BIT).

56 */

70 };

71 /**

72 * Modulus of Group 14 (MODP_2048_BIT).

73 */

91 };

93 /**

94 * Modulus of Group 15 (MODP_3072_BIT).

95 */

121 };

123 /**

124 * Modulus of Group 16 (MODP_4096_BIT).

125 */

159 };

161 /**

162 * Modulus of Group 17 (MODP_6144_BIT).

163 */

213 };

215 /**

216 * Modulus of Group 18 (MODP_8192_BIT).

217 */

283 };

287 /**

288 * Entry of the modulus list.

289 */

291 /**

292 * Group number as it is defined in file transform_substructure.h.

293 */

294 diffie_hellman_group_t group;

296 /**

297 * Pointer to first byte of modulus (network order).

298 */

301 /*

302 * Length of modulus in bytes.

303 */

306 /*

307 * Generator value.

308 */

309 u_int16_t generator;

310 };

312 /**

313 * All supported modulus values.

314 */

324 };

328 /**

329 * Private data of an gmp_diffie_hellman_t object.

330 */

332 /**

333 * Public gmp_diffie_hellman_t interface.

334 */

337 /**

338 * Diffie Hellman group number.

339 */

340 u_int16_t group;

342 /*

343 * Generator value.

344 */

345 mpz_t g;

347 /**

348 * My private value.

349 */

350 mpz_t xa;

352 /**

353 * My public value.

354 */

355 mpz_t ya;

357 /**

358 * Other public value.

359 */

360 mpz_t yb;

362 /**

363 * Shared secret.

364 */

365 mpz_t zz;

367 /**

368 * Modulus.

369 */

370 mpz_t p;

372 /**

373 * Modulus length.

374 */

377 /**

378 * True if shared secret is computed and stored in my_public_value.

379 */

381 };

383 /**

384 * Implementation of gmp_diffie_hellman_t.set_other_public_value.

385 */

387 {

388 mpz_t p_min_1;

395 /* check public value:

396 * 1. 0 or 1 is invalid as 0^a = 0 and 1^a = 1

397 * 2. a public value larger or equal the modulus is invalid */

400 {

401 #ifdef EXTENDED_DH_TEST

402 /* 3. test if y ^ q mod p = 1, where q = (p - 1)/2. */

411 {

414 }

415 else

416 {

418 }

420 #else

423 #endif

424 }

425 else

426 {

428 }

430 }

432 /**

433 * Implementation of gmp_diffie_hellman_t.get_other_public_value.

434 */

437 {

439 {

441 }

445 {

447 }

449 }

451 /**

452 * Implementation of gmp_diffie_hellman_t.get_my_public_value.

453 */

455 {

459 {

461 }

462 }

464 /**

465 * Implementation of gmp_diffie_hellman_t.get_shared_secret.

466 */

468 {

470 {

472 }

476 {

478 }

480 }

482 /**

483 * Implementation of gmp_diffie_hellman_t.get_dh_group.

484 */

486 {

488 }

490 /**

491 * Lookup the modulus in modulo table

492 */

494 {

499 {

501 {

502 chunk_t chunk;

510 }

511 }

513 }

515 /**

516 * Implementation of gmp_diffie_hellman_t.destroy.

517 */

519 {

527 }

529 /*

530 * Described in header.

531 */

533 {

536 chunk_t random;

538 /* public functions */

539 this->public.dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;

540 this->public.dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;

541 this->public.dh.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;

542 this->public.dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;

546 /* private variables */

557 /* find a modulus according to group */

559 {

562 }

565 {

569 }

578 }