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-2006 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>

27 #include <stdio.h>

31 #include <utils/randomizer.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 };

333 /**

334 * All supported modulus values.

335 */

345 };

349 /**

350 * Private data of an diffie_hellman_t object.

351 *

352 */

354 /**

355 * Public diffie_hellman_t interface.

356 */

359 /**

360 * Diffie Hellman group number.

361 */

362 u_int16_t dh_group_number;

364 /**

365 * Modulus.

366 */

367 mpz_t modulus;

369 /**

370 * Modulus length.

371 */

374 /*

375 * Generator value.

376 */

377 u_int16_t generator;

379 /**

380 * My private value .

381 */

382 mpz_t my_private_value;

384 /**

385 * My public value.

386 */

387 mpz_t my_public_value;

389 /**

390 * Other public value.

391 */

392 mpz_t other_public_value;

394 /**

395 * Shared secret.

396 */

397 mpz_t shared_secret;

399 /**

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

401 */

404 /**

405 * Sets the modulus for a specific diffie hellman group.

406 *

407 * @param this calling object

408 * @return

409 * SUCCESS if modulus could be found

410 * NOT_FOUND if modulus not supported

411 */

414 /**

415 * Makes sure my public value is computed.

416 *

417 * @param this calling object

418 */

421 /**

422 * Computes shared secret (other public value must be available).

423 *

424 * @param this calling object

425 */

427 };

429 /**

430 * Implementation of private_diffie_hellman_t.set_modulus.

431 */

433 {

438 {

440 {

441 chunk_t modulus_chunk;

449 }

450 }

452 }

454 /**

455 * Implementation of diffie_hellman_t.set_other_public_value.

456 */

458 {

461 }

463 /**

464 * Implementation of diffie_hellman_t.get_other_public_value.

465 */

467 {

469 {

471 }

473 public_value->ptr = mpz_export(NULL, NULL, 1, public_value->len, 1, 0, this->other_public_value);

475 }

477 /**

478 * Implementation of private_diffie_hellman_t.compute_shared_secret.

479 */

481 {

482 /* initialize my public value */

484 /* calculate my public value */

488 }

490 /**

491 * Implementation of private_diffie_hellman_t.compute_public_value.

492 */

494 {

495 mpz_t generator;

496 /* initialize generator and set it*/

498 /* initialize my public value */

500 /* calculate my public value */

502 /* generator not used anymore */

504 }

506 /**

507 * Implementation of diffie_hellman_t.get_my_public_value.

508 */

510 {

513 }

515 /**

516 * Implementation of diffie_hellman_t.get_shared_secret.

517 */

519 {

521 {

523 }

527 }

529 /**

530 * Implementation of diffie_hellman_t.get_dh_group.

531 */

533 {

535 }

537 /**

538 * Implementation of diffie_hellman_t.destroy.

539 */

541 {

548 {

549 /* other public value gets initialized together with shared secret */

551 }

553 }

555 /*

556 * Described in header.

557 */

559 {

562 chunk_t random_bytes;

564 /* public functions */

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

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

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

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

572 /* private functions */

577 /* private variables */

583 /* set this->modulus */

585 {

588 }

591 {

594 }

595 if (randomizer->allocate_pseudo_random_bytes(randomizer, this->modulus_length, &random_bytes) != SUCCESS)

596 {

600 }

612 }