mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
7db526c730
The ec_name_to_curve and ec_curve_to_name functions shouldn't really have had to exist at all: whenever any part of the PuTTY codebase starts using sshecc.c, it's starting from an ssh_signkey or ssh_kex pointer already found by some other means. So if we make sure not to lose that pointer, we should never need to do any string-based lookups to find the curve we want, and conversely, when we need to know the name of our curve or our algorithm, we should be able to look it up as a straightforward const char * starting from the algorithm pointer. This commit cleans things up so that that is indeed what happens. The ssh_signkey and ssh_kex structures defined in sshecc.c now have 'extra' fields containing pointers to all the necessary stuff; ec_name_to_curve and ec_curve_to_name have been completely removed; struct ec_curve has a string field giving the curve's name (but only for those curves which _have_ a name exposed in the wire protocol, i.e. the three NIST ones); struct ec_key keeps a pointer to the ssh_signkey it started from, and uses that to remember the algorithm name rather than reconstructing it from the curve. And I think I've got rid of all the ad-hockery scattered around the code that switches on curve->fieldBits or manually constructs curve names using stuff like sprintf("nistp%d"); the only remaining switch on fieldBits (necessary because that's the UI for choosing a curve in PuTTYgen) is at least centralised into one place in sshecc.c. One user-visible result is that the format of ed25519 host keys in the registry has changed: there's now no curve name prefix on them, because I think it's not really right to make up a name to use. So any early adopters who've been using snapshot PuTTY in the last week will be inconvenienced; sorry about that.
72 lines
1.8 KiB
C
72 lines
1.8 KiB
C
/*
|
|
* EC key generation.
|
|
*/
|
|
|
|
#include "ssh.h"
|
|
|
|
/* Forward reference from sshecc.c */
|
|
struct ec_point *ecp_mul(const struct ec_point *a, const Bignum b);
|
|
|
|
int ec_generate(struct ec_key *key, int bits, progfn_t pfn,
|
|
void *pfnparam)
|
|
{
|
|
struct ec_point *publicKey;
|
|
|
|
if (!ec_nist_alg_and_curve_by_bits(bits, &key->publicKey.curve,
|
|
&key->signalg))
|
|
return 0;
|
|
|
|
key->privateKey = bignum_random_in_range(One, key->publicKey.curve->w.n);
|
|
if (!key->privateKey) return 0;
|
|
|
|
publicKey = ec_public(key->privateKey, key->publicKey.curve);
|
|
if (!publicKey) {
|
|
freebn(key->privateKey);
|
|
key->privateKey = NULL;
|
|
return 0;
|
|
}
|
|
|
|
key->publicKey.x = publicKey->x;
|
|
key->publicKey.y = publicKey->y;
|
|
key->publicKey.z = NULL;
|
|
sfree(publicKey);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int ec_edgenerate(struct ec_key *key, int bits, progfn_t pfn,
|
|
void *pfnparam)
|
|
{
|
|
struct ec_point *publicKey;
|
|
|
|
if (!ec_ed_alg_and_curve_by_bits(bits, &key->publicKey.curve,
|
|
&key->signalg))
|
|
return 0;
|
|
|
|
{
|
|
/* EdDSA secret keys are just 32 bytes of hash preimage; the
|
|
* 64-byte SHA-512 hash of that key will be used when signing,
|
|
* but the form of the key stored on disk is the preimage
|
|
* only. */
|
|
Bignum privMax = bn_power_2(bits);
|
|
if (!privMax) return 0;
|
|
key->privateKey = bignum_random_in_range(Zero, privMax);
|
|
freebn(privMax);
|
|
if (!key->privateKey) return 0;
|
|
}
|
|
|
|
publicKey = ec_public(key->privateKey, key->publicKey.curve);
|
|
if (!publicKey) {
|
|
freebn(key->privateKey);
|
|
key->privateKey = NULL;
|
|
return 0;
|
|
}
|
|
|
|
key->publicKey.x = publicKey->x;
|
|
key->publicKey.y = publicKey->y;
|
|
key->publicKey.z = NULL;
|
|
sfree(publicKey);
|
|
|
|
return 1;
|
|
}
|