mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Support ECDH key exchange using the 'curve25519' curve.
This is the kex protocol id "curve25519-sha256@libssh.org", so called because it's over the prime field of order 2^255 - 19. Arithmetic in this curve is done using the Montgomery representation, rather than the Weierstrass representation. So 'struct ec_curve' has grown a discriminant field and a union of subtypes.
This commit is contained in:
parent
7d6bf4a6ca
commit
541abf9258
9
ssh.c
9
ssh.c
@ -6845,14 +6845,7 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen,
|
||||
ssh->kex->hash->text_name);
|
||||
ssh->pkt_kctx = SSH2_PKTCTX_ECDHKEX;
|
||||
|
||||
s->eckey = NULL;
|
||||
if (!strcmp(ssh->kex->name, "ecdh-sha2-nistp256")) {
|
||||
s->eckey = ssh_ecdhkex_newkey(ec_p256());
|
||||
} else if (!strcmp(ssh->kex->name, "ecdh-sha2-nistp384")) {
|
||||
s->eckey = ssh_ecdhkex_newkey(ec_p384());
|
||||
} else if (!strcmp(ssh->kex->name, "ecdh-sha2-nistp521")) {
|
||||
s->eckey = ssh_ecdhkex_newkey(ec_p521());
|
||||
}
|
||||
s->eckey = ssh_ecdhkex_newkey(ssh->kex->name);
|
||||
if (!s->eckey) {
|
||||
bombout(("Unable to generate key for ECDH"));
|
||||
crStopV;
|
||||
|
32
ssh.h
32
ssh.h
@ -110,27 +110,51 @@ struct ec_point {
|
||||
|
||||
void ec_point_free(struct ec_point *point);
|
||||
|
||||
struct ec_curve {
|
||||
unsigned int fieldBits;
|
||||
Bignum p, a, b, n;
|
||||
/* Weierstrass form curve */
|
||||
struct ec_wcurve
|
||||
{
|
||||
Bignum a, b, n;
|
||||
struct ec_point G;
|
||||
};
|
||||
|
||||
/* Montgomery form curve */
|
||||
struct ec_mcurve
|
||||
{
|
||||
Bignum a, b;
|
||||
struct ec_point G;
|
||||
};
|
||||
|
||||
struct ec_curve {
|
||||
enum { EC_WEIERSTRASS, EC_MONTGOMERY } type;
|
||||
unsigned int fieldBits;
|
||||
Bignum p;
|
||||
union {
|
||||
struct ec_wcurve w;
|
||||
struct ec_mcurve m;
|
||||
};
|
||||
};
|
||||
|
||||
extern unsigned char nistp256_oid[];
|
||||
extern unsigned char nistp384_oid[];
|
||||
extern unsigned char nistp521_oid[];
|
||||
extern unsigned char curve25519_oid[];
|
||||
extern int nistp256_oid_len;
|
||||
extern int nistp384_oid_len;
|
||||
extern int nistp521_oid_len;
|
||||
extern int curve25519_oid_len;
|
||||
struct ec_curve *ec_p256(void);
|
||||
struct ec_curve *ec_p384(void);
|
||||
struct ec_curve *ec_p521(void);
|
||||
struct ec_curve *ec_ed25519(void);
|
||||
struct ec_curve *ec_curve25519(void);
|
||||
|
||||
struct ec_key {
|
||||
struct ec_point publicKey;
|
||||
Bignum privateKey;
|
||||
};
|
||||
|
||||
struct ec_point *ec_public(const Bignum privateKey, const struct ec_curve *curve);
|
||||
|
||||
int makekey(const unsigned char *data, int len, struct RSAKey *result,
|
||||
const unsigned char **keystr, int order);
|
||||
int makeprivate(const unsigned char *data, int len, struct RSAKey *result);
|
||||
@ -176,7 +200,7 @@ void ssh_rsakex_encrypt(const struct ssh_hash *h, unsigned char *in, int inlen,
|
||||
/*
|
||||
* SSH2 ECDH key exchange functions
|
||||
*/
|
||||
void *ssh_ecdhkex_newkey(struct ec_curve *curve);
|
||||
void *ssh_ecdhkex_newkey(const char *name);
|
||||
void ssh_ecdhkex_freekey(void *key);
|
||||
char *ssh_ecdhkex_getpublic(void *key, int *len);
|
||||
Bignum ssh_ecdhkex_getkey(void *key, char *remoteKey, int remoteKeyLen);
|
||||
|
@ -22,10 +22,10 @@ int ec_generate(struct ec_key *key, int bits, progfn_t pfn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
key->privateKey = bignum_random_in_range(One, key->publicKey.curve->n);
|
||||
key->privateKey = bignum_random_in_range(One, key->publicKey.curve->w.n);
|
||||
if (!key->privateKey) return 0;
|
||||
|
||||
publicKey = ecp_mul(&key->publicKey.curve->G, key->privateKey);
|
||||
publicKey = ec_public(key->privateKey, key->publicKey.curve);
|
||||
if (!publicKey) {
|
||||
freebn(key->privateKey);
|
||||
key->privateKey = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user