Coverage Report

Created: 2025-08-29 06:35

/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 */