1 /**

2 * @file diffie_hellman.c

3 *

4 * @brief Implementation of diffie_hellman_t.

5 *

6 */

8 /*

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

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

11 * Copyright (C) 2005-2007 Martin Willi

12 * Copyright (C) 2005 Jan Hutter

13 * Hochschule fuer Technik Rapperswil

14 *

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

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

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

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

19 *

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

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

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

23 * for more details.

24 */

26 #include <gmp.h>

30 #include <utils/randomizer.h>

31 #include <debug.h>

48 /**

49 * Modulus of Group 1 (MODP_768_BIT).

50 */

58 };

60 /**

61 * Modulus of Group 2 (MODP_1024_BIT).

62 */

72 };

74 /**

75 * Modulus of Group 5 (MODP_1536_BIT).

76 */

90 };

91 /**

92 * Modulus of Group 14 (MODP_2048_BIT).

93 */

111 };

113 /**

114 * Modulus of Group 15 (MODP_3072_BIT).

115 */

141 };

143 /**

144 * Modulus of Group 16 (MODP_4096_BIT).

145 */

179 };

181 /**

182 * Modulus of Group 17 (MODP_6144_BIT).

183 */

233 };

235 /**

236 * Modulus of Group 18 (MODP_8192_BIT).

237 */

303 };

307 /**

308 * Entry of the modulus list.

309 */

311 /**

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

313 */

314 diffie_hellman_group_t group;

316 /**

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

318 */

321 /*

322 * Length of modulus in bytes.

323 */

326 /*

327 * Generator value.

328 */

329 u_int16_t generator;

330 };

332 /**

333 * All supported modulus values.

334 */

344 };

348 /**

349 * Private data of an diffie_hellman_t object.

350 *

351 */

353 /**

354 * Public diffie_hellman_t interface.

355 */

358 /**

359 * Diffie Hellman group number.

360 */

361 u_int16_t group;

363 /*

364 * Generator value.

365 */

366 mpz_t g;

368 /**

369 * My private value.

370 */

371 mpz_t xa;

373 /**

374 * My public value.

375 */

376 mpz_t ya;

378 /**

379 * Other public value.

380 */

381 mpz_t yb;

383 /**

384 * Shared secret.

385 */

386 mpz_t zz;

388 /**

389 * Modulus.

390 */

391 mpz_t p;

393 /**

394 * Modulus length.

395 */

398 /**

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

400 */

402 };

404 /**

405 * Implementation of diffie_hellman_t.set_other_public_value.

406 */

408 {

409 mpz_t p_min_1;

416 /* check public value:

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

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

421 {

422 #ifdef EXTENDED_DH_TEST

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

432 {

435 }

436 else

437 {

439 }

441 #else

444 #endif

445 }

446 else

447 {

449 }

451 }

453 /**

454 * Implementation of diffie_hellman_t.get_other_public_value.

455 */

458 {

460 {

462 }

466 }

468 /**

469 * Implementation of diffie_hellman_t.get_my_public_value.

470 */

472 {

475 }

477 /**

478 * Implementation of diffie_hellman_t.get_shared_secret.

479 */

481 {

483 {

485 }

489 }

491 /**

492 * Implementation of diffie_hellman_t.get_dh_group.

493 */

495 {

497 }

499 /**

500 * Lookup the modulus in modulo table

501 */

503 {

508 {

510 {

511 chunk_t chunk;

519 }

520 }

522 }

524 /**

525 * Implementation of diffie_hellman_t.destroy.

526 */

528 {

536 }

538 /*

539 * Described in header.

540 */

542 {

545 chunk_t random;

546 status_t status;

548 /* public functions */

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

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

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

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

556 /* private variables */

567 /* find a modulus according to group */

569 {

572 }

578 {

581 }

588 }