1
0
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:
Chris Staite 2015-05-09 15:02:52 +01:00 committed by Simon Tatham
parent 7d6bf4a6ca
commit 541abf9258
4 changed files with 934 additions and 258 deletions

9
ssh.c
View File

@ -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
View File

@ -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);

1147
sshecc.c

File diff suppressed because it is too large Load Diff

View File

@ -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;