/src/dropbear/src/kex-x25519.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "includes.h" |
2 | | #include "algo.h" |
3 | | #include "buffer.h" |
4 | | #include "session.h" |
5 | | #include "bignum.h" |
6 | | #include "dbrandom.h" |
7 | | #include "crypto_desc.h" |
8 | | #include "curve25519.h" |
9 | | #include "kex.h" |
10 | | |
11 | | /* PQ hybrids also use curve25519 internally */ |
12 | | #if DROPBEAR_CURVE25519_DEP |
13 | | |
14 | 0 | struct kex_curve25519_param *gen_kexcurve25519_param() { |
15 | | /* Per http://cr.yp.to/ecdh.html */ |
16 | 0 | struct kex_curve25519_param *param = m_malloc(sizeof(*param)); |
17 | 0 | const unsigned char basepoint[32] = {9}; |
18 | |
|
19 | 0 | genrandom(param->priv, CURVE25519_LEN); |
20 | 0 | dropbear_curve25519_scalarmult(param->pub, param->priv, basepoint); |
21 | |
|
22 | 0 | return param; |
23 | 0 | } |
24 | | |
25 | 0 | void free_kexcurve25519_param(struct kex_curve25519_param *param) { |
26 | 0 | m_burn(param->priv, CURVE25519_LEN); |
27 | 0 | m_free(param); |
28 | 0 | } |
29 | | |
30 | | /* out must be CURVE25519_LEN */ |
31 | | void kexcurve25519_derive(const struct kex_curve25519_param *param, const buffer *buf_pub_them, |
32 | 0 | unsigned char *out) { |
33 | 0 | char zeroes[CURVE25519_LEN] = {0}; |
34 | 0 | if (buf_pub_them->len != CURVE25519_LEN) |
35 | 0 | { |
36 | 0 | dropbear_exit("Bad curve25519"); |
37 | 0 | } |
38 | | |
39 | 0 | dropbear_curve25519_scalarmult(out, param->priv, buf_pub_them->data); |
40 | |
|
41 | 0 | if (constant_time_memcmp(zeroes, out, CURVE25519_LEN) == 0) { |
42 | 0 | dropbear_exit("Bad curve25519"); |
43 | 0 | } |
44 | 0 | } |
45 | | |
46 | | #endif /* DROPBEAR_CURVE25519_DEP */ |
47 | | |
48 | | #if DROPBEAR_CURVE25519 |
49 | | |
50 | | /* Only required for x25519 directly */ |
51 | | void kexcurve25519_comb_key(const struct kex_curve25519_param *param, const buffer *buf_pub_them, |
52 | 0 | sign_key *hostkey) { |
53 | 0 | unsigned char out[CURVE25519_LEN]; |
54 | 0 | const unsigned char* Q_C = NULL; |
55 | 0 | const unsigned char* Q_S = NULL; |
56 | |
|
57 | 0 | kexcurve25519_derive(param, buf_pub_them, out); |
58 | |
|
59 | 0 | m_mp_alloc_init_multi(&ses.dh_K, NULL); |
60 | 0 | bytes_to_mp(ses.dh_K, out, CURVE25519_LEN); |
61 | 0 | m_burn(out, sizeof(out)); |
62 | | |
63 | | /* Create the remainder of the hash buffer, to generate the exchange hash. |
64 | | See RFC5656 section 4 page 7 */ |
65 | 0 | if (IS_DROPBEAR_CLIENT) { |
66 | 0 | Q_C = param->pub; |
67 | 0 | Q_S = buf_pub_them->data; |
68 | 0 | } else { |
69 | 0 | Q_S = param->pub; |
70 | 0 | Q_C = buf_pub_them->data; |
71 | 0 | } |
72 | | |
73 | | /* K_S, the host key */ |
74 | 0 | buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey); |
75 | | /* Q_C, client's ephemeral public key octet string */ |
76 | 0 | buf_putstring(ses.kexhashbuf, (const char*)Q_C, CURVE25519_LEN); |
77 | | /* Q_S, server's ephemeral public key octet string */ |
78 | 0 | buf_putstring(ses.kexhashbuf, (const char*)Q_S, CURVE25519_LEN); |
79 | | /* K, the shared secret */ |
80 | 0 | buf_putmpint(ses.kexhashbuf, ses.dh_K); |
81 | | |
82 | | /* calculate the hash H to sign */ |
83 | 0 | finish_kexhashbuf(); |
84 | 0 | } |
85 | | |
86 | | #endif /* DROPBEAR_CURVE25519 */ |