-
Notifications
You must be signed in to change notification settings - Fork 16
/
dh.c
executable file
·89 lines (68 loc) · 2.61 KB
/
dh.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
Diffie Hellman key exchange algorithm - RFC 2631
*/
#include <stdlib.h>
#include "log.h"
#include "ssh.h"
#define CRYPTO_INTERNAL
#include "crypto.h"
/* Well known oakley group 2 & 14 primes (rfc 3526 & 2049) */
const char *oakley2_prime =
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
"FFFFFFFF" "FFFFFFFF";
const char *oakley14_prime =
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
"C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
"83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
"670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
"E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
"DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
"15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
mpz_t oakley_2, oakley_14;
void dh_init() {
mpz_init(oakley_2);
mpz_init(oakley_14);
mpz_set_str(oakley_2, oakley2_prime, 16);
mpz_set_str(oakley_14, oakley14_prime, 16);
}
/**
client_public_key - g^a mod p from client
dh_group - the Diffie Hellman Oakley Group (used to select/preseed, prime & generator)
cipher - the symmetric cipher for which keying material has to be generated. The secret
DH key (g^a mod p)^b should be suitable keying material for the cipher. Knowing the cipher
to be used allows to select a wide enough private exponent 'b' (cipher key size * 2 bits).
**/
int dh_kex(mpz_t *e, int algo, unsigned long want_keylen, mpz_t *f, mpz_t *K) {
mpz_t p, y, g;
gmp_randstate_t *rand = crypto_randctx();
unsigned long client_keylen;
if (algo == DH1)
mpz_init_set(p, oakley_2);
else if (algo == DH14)
mpz_init_set(p, oakley_14);
else
return 1;
client_keylen = (unsigned long)mpz_sizeinbase(*e, 2) / 8;
want_keylen = (client_keylen > want_keylen) ? client_keylen : want_keylen;
/* generator = 2 */
mpz_init_set_ui(g, 2UL);
/* private exponent */
mpz_init(y);
mpz_urandomb(y, *rand, want_keylen);
/* f = g^y mod p */
mpz_powm(*f, g, y, p);
/* K = e^y mod p */
mpz_powm(*K, *e, y, p);
mpz_clear(p);
mpz_clear(y);
mpz_clear(g);
return 0;
}