mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-01 03:22:48 -05:00
Spelling: standardise on "DSA", not "DSS".
This code base has always been a bit confused about which spelling it likes to use to refer to that signature algorithm. The SSH protocol id is "ssh-dss". But everyone I know refers to it as the Digital Signature _Algorithm_, not the Digital Signature _Standard_. When I moved everything down into the crypto subdir, I took the opportunity to rename sshdss.c to dsa.c. Now I'm doing the rest of the job: all internal identifiers and code comments refer to DSA, and the spelling "dss" only survives in externally visible identifiers that have to remain constant. (Such identifiers include the SSH protocol id, and also the string id used to identify the key type in PuTTY's own host key cache. We can't change the latter without causing everyone a backwards-compatibility headache, and if we _did_ ever decide to do that, we'd surely want to do a much more thorough job of making the cache format more sensible!)
This commit is contained in:
256
crypto/dsa.c
256
crypto/dsa.c
@ -10,49 +10,49 @@
|
||||
#include "mpint.h"
|
||||
#include "misc.h"
|
||||
|
||||
static void dss_freekey(ssh_key *key); /* forward reference */
|
||||
static void dsa_freekey(ssh_key *key); /* forward reference */
|
||||
|
||||
static ssh_key *dss_new_pub(const ssh_keyalg *self, ptrlen data)
|
||||
static ssh_key *dsa_new_pub(const ssh_keyalg *self, ptrlen data)
|
||||
{
|
||||
BinarySource src[1];
|
||||
struct dss_key *dss;
|
||||
struct dsa_key *dsa;
|
||||
|
||||
BinarySource_BARE_INIT_PL(src, data);
|
||||
if (!ptrlen_eq_string(get_string(src), "ssh-dss"))
|
||||
return NULL;
|
||||
|
||||
dss = snew(struct dss_key);
|
||||
dss->sshk.vt = &ssh_dss;
|
||||
dss->p = get_mp_ssh2(src);
|
||||
dss->q = get_mp_ssh2(src);
|
||||
dss->g = get_mp_ssh2(src);
|
||||
dss->y = get_mp_ssh2(src);
|
||||
dss->x = NULL;
|
||||
dsa = snew(struct dsa_key);
|
||||
dsa->sshk.vt = &ssh_dsa;
|
||||
dsa->p = get_mp_ssh2(src);
|
||||
dsa->q = get_mp_ssh2(src);
|
||||
dsa->g = get_mp_ssh2(src);
|
||||
dsa->y = get_mp_ssh2(src);
|
||||
dsa->x = NULL;
|
||||
|
||||
if (get_err(src) ||
|
||||
mp_eq_integer(dss->p, 0) || mp_eq_integer(dss->q, 0)) {
|
||||
mp_eq_integer(dsa->p, 0) || mp_eq_integer(dsa->q, 0)) {
|
||||
/* Invalid key. */
|
||||
dss_freekey(&dss->sshk);
|
||||
dsa_freekey(&dsa->sshk);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &dss->sshk;
|
||||
return &dsa->sshk;
|
||||
}
|
||||
|
||||
static void dss_freekey(ssh_key *key)
|
||||
static void dsa_freekey(ssh_key *key)
|
||||
{
|
||||
struct dss_key *dss = container_of(key, struct dss_key, sshk);
|
||||
if (dss->p)
|
||||
mp_free(dss->p);
|
||||
if (dss->q)
|
||||
mp_free(dss->q);
|
||||
if (dss->g)
|
||||
mp_free(dss->g);
|
||||
if (dss->y)
|
||||
mp_free(dss->y);
|
||||
if (dss->x)
|
||||
mp_free(dss->x);
|
||||
sfree(dss);
|
||||
struct dsa_key *dsa = container_of(key, struct dsa_key, sshk);
|
||||
if (dsa->p)
|
||||
mp_free(dsa->p);
|
||||
if (dsa->q)
|
||||
mp_free(dsa->q);
|
||||
if (dsa->g)
|
||||
mp_free(dsa->g);
|
||||
if (dsa->y)
|
||||
mp_free(dsa->y);
|
||||
if (dsa->x)
|
||||
mp_free(dsa->x);
|
||||
sfree(dsa);
|
||||
}
|
||||
|
||||
static void append_hex_to_strbuf(strbuf *sb, mp_int *x)
|
||||
@ -67,55 +67,55 @@ static void append_hex_to_strbuf(strbuf *sb, mp_int *x)
|
||||
sfree(hex);
|
||||
}
|
||||
|
||||
static char *dss_cache_str(ssh_key *key)
|
||||
static char *dsa_cache_str(ssh_key *key)
|
||||
{
|
||||
struct dss_key *dss = container_of(key, struct dss_key, sshk);
|
||||
struct dsa_key *dsa = container_of(key, struct dsa_key, sshk);
|
||||
strbuf *sb = strbuf_new();
|
||||
|
||||
if (!dss->p) {
|
||||
if (!dsa->p) {
|
||||
strbuf_free(sb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
append_hex_to_strbuf(sb, dss->p);
|
||||
append_hex_to_strbuf(sb, dss->q);
|
||||
append_hex_to_strbuf(sb, dss->g);
|
||||
append_hex_to_strbuf(sb, dss->y);
|
||||
append_hex_to_strbuf(sb, dsa->p);
|
||||
append_hex_to_strbuf(sb, dsa->q);
|
||||
append_hex_to_strbuf(sb, dsa->g);
|
||||
append_hex_to_strbuf(sb, dsa->y);
|
||||
|
||||
return strbuf_to_str(sb);
|
||||
}
|
||||
|
||||
static key_components *dss_components(ssh_key *key)
|
||||
static key_components *dsa_components(ssh_key *key)
|
||||
{
|
||||
struct dss_key *dss = container_of(key, struct dss_key, sshk);
|
||||
struct dsa_key *dsa = container_of(key, struct dsa_key, sshk);
|
||||
key_components *kc = key_components_new();
|
||||
|
||||
key_components_add_text(kc, "key_type", "DSA");
|
||||
assert(dss->p);
|
||||
key_components_add_mp(kc, "p", dss->p);
|
||||
key_components_add_mp(kc, "q", dss->q);
|
||||
key_components_add_mp(kc, "g", dss->g);
|
||||
key_components_add_mp(kc, "public_y", dss->y);
|
||||
if (dss->x)
|
||||
key_components_add_mp(kc, "private_x", dss->x);
|
||||
assert(dsa->p);
|
||||
key_components_add_mp(kc, "p", dsa->p);
|
||||
key_components_add_mp(kc, "q", dsa->q);
|
||||
key_components_add_mp(kc, "g", dsa->g);
|
||||
key_components_add_mp(kc, "public_y", dsa->y);
|
||||
if (dsa->x)
|
||||
key_components_add_mp(kc, "private_x", dsa->x);
|
||||
|
||||
return kc;
|
||||
}
|
||||
|
||||
static char *dss_invalid(ssh_key *key, unsigned flags)
|
||||
static char *dsa_invalid(ssh_key *key, unsigned flags)
|
||||
{
|
||||
/* No validity criterion will stop us from using a DSA key at all */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool dss_verify(ssh_key *key, ptrlen sig, ptrlen data)
|
||||
static bool dsa_verify(ssh_key *key, ptrlen sig, ptrlen data)
|
||||
{
|
||||
struct dss_key *dss = container_of(key, struct dss_key, sshk);
|
||||
struct dsa_key *dsa = container_of(key, struct dsa_key, sshk);
|
||||
BinarySource src[1];
|
||||
unsigned char hash[20];
|
||||
bool toret;
|
||||
|
||||
if (!dss->p)
|
||||
if (!dsa->p)
|
||||
return false;
|
||||
|
||||
BinarySource_BARE_INIT_PL(src, sig);
|
||||
@ -155,8 +155,8 @@ static bool dss_verify(ssh_key *key, ptrlen sig, ptrlen data)
|
||||
unsigned invalid = 0;
|
||||
invalid |= mp_eq_integer(r, 0);
|
||||
invalid |= mp_eq_integer(s, 0);
|
||||
invalid |= mp_cmp_hs(r, dss->q);
|
||||
invalid |= mp_cmp_hs(s, dss->q);
|
||||
invalid |= mp_cmp_hs(r, dsa->q);
|
||||
invalid |= mp_cmp_hs(s, dsa->q);
|
||||
if (invalid) {
|
||||
mp_free(r);
|
||||
mp_free(s);
|
||||
@ -166,7 +166,7 @@ static bool dss_verify(ssh_key *key, ptrlen sig, ptrlen data)
|
||||
/*
|
||||
* Step 1. w <- s^-1 mod q.
|
||||
*/
|
||||
mp_int *w = mp_invert(s, dss->q);
|
||||
mp_int *w = mp_invert(s, dsa->q);
|
||||
if (!w) {
|
||||
mp_free(r);
|
||||
mp_free(s);
|
||||
@ -178,20 +178,20 @@ static bool dss_verify(ssh_key *key, ptrlen sig, ptrlen data)
|
||||
*/
|
||||
hash_simple(&ssh_sha1, data, hash);
|
||||
mp_int *sha = mp_from_bytes_be(make_ptrlen(hash, 20));
|
||||
mp_int *u1 = mp_modmul(sha, w, dss->q);
|
||||
mp_int *u1 = mp_modmul(sha, w, dsa->q);
|
||||
|
||||
/*
|
||||
* Step 3. u2 <- r * w mod q.
|
||||
*/
|
||||
mp_int *u2 = mp_modmul(r, w, dss->q);
|
||||
mp_int *u2 = mp_modmul(r, w, dsa->q);
|
||||
|
||||
/*
|
||||
* Step 4. v <- (g^u1 * y^u2 mod p) mod q.
|
||||
*/
|
||||
mp_int *gu1p = mp_modpow(dss->g, u1, dss->p);
|
||||
mp_int *yu2p = mp_modpow(dss->y, u2, dss->p);
|
||||
mp_int *gu1yu2p = mp_modmul(gu1p, yu2p, dss->p);
|
||||
mp_int *v = mp_mod(gu1yu2p, dss->q);
|
||||
mp_int *gu1p = mp_modpow(dsa->g, u1, dsa->p);
|
||||
mp_int *yu2p = mp_modpow(dsa->y, u2, dsa->p);
|
||||
mp_int *gu1yu2p = mp_modmul(gu1p, yu2p, dsa->p);
|
||||
mp_int *v = mp_mod(gu1yu2p, dsa->q);
|
||||
|
||||
/*
|
||||
* Step 5. v should now be equal to r.
|
||||
@ -213,57 +213,57 @@ static bool dss_verify(ssh_key *key, ptrlen sig, ptrlen data)
|
||||
return toret;
|
||||
}
|
||||
|
||||
static void dss_public_blob(ssh_key *key, BinarySink *bs)
|
||||
static void dsa_public_blob(ssh_key *key, BinarySink *bs)
|
||||
{
|
||||
struct dss_key *dss = container_of(key, struct dss_key, sshk);
|
||||
struct dsa_key *dsa = container_of(key, struct dsa_key, sshk);
|
||||
|
||||
put_stringz(bs, "ssh-dss");
|
||||
put_mp_ssh2(bs, dss->p);
|
||||
put_mp_ssh2(bs, dss->q);
|
||||
put_mp_ssh2(bs, dss->g);
|
||||
put_mp_ssh2(bs, dss->y);
|
||||
put_mp_ssh2(bs, dsa->p);
|
||||
put_mp_ssh2(bs, dsa->q);
|
||||
put_mp_ssh2(bs, dsa->g);
|
||||
put_mp_ssh2(bs, dsa->y);
|
||||
}
|
||||
|
||||
static void dss_private_blob(ssh_key *key, BinarySink *bs)
|
||||
static void dsa_private_blob(ssh_key *key, BinarySink *bs)
|
||||
{
|
||||
struct dss_key *dss = container_of(key, struct dss_key, sshk);
|
||||
struct dsa_key *dsa = container_of(key, struct dsa_key, sshk);
|
||||
|
||||
put_mp_ssh2(bs, dss->x);
|
||||
put_mp_ssh2(bs, dsa->x);
|
||||
}
|
||||
|
||||
static ssh_key *dss_new_priv(const ssh_keyalg *self, ptrlen pub, ptrlen priv)
|
||||
static ssh_key *dsa_new_priv(const ssh_keyalg *self, ptrlen pub, ptrlen priv)
|
||||
{
|
||||
BinarySource src[1];
|
||||
ssh_key *sshk;
|
||||
struct dss_key *dss;
|
||||
struct dsa_key *dsa;
|
||||
ptrlen hash;
|
||||
unsigned char digest[20];
|
||||
mp_int *ytest;
|
||||
|
||||
sshk = dss_new_pub(self, pub);
|
||||
sshk = dsa_new_pub(self, pub);
|
||||
if (!sshk)
|
||||
return NULL;
|
||||
|
||||
dss = container_of(sshk, struct dss_key, sshk);
|
||||
dsa = container_of(sshk, struct dsa_key, sshk);
|
||||
BinarySource_BARE_INIT_PL(src, priv);
|
||||
dss->x = get_mp_ssh2(src);
|
||||
dsa->x = get_mp_ssh2(src);
|
||||
if (get_err(src)) {
|
||||
dss_freekey(&dss->sshk);
|
||||
dsa_freekey(&dsa->sshk);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the obsolete hash in the old DSS key format.
|
||||
* Check the obsolete hash in the old DSA key format.
|
||||
*/
|
||||
hash = get_string(src);
|
||||
if (hash.len == 20) {
|
||||
ssh_hash *h = ssh_hash_new(&ssh_sha1);
|
||||
put_mp_ssh2(h, dss->p);
|
||||
put_mp_ssh2(h, dss->q);
|
||||
put_mp_ssh2(h, dss->g);
|
||||
put_mp_ssh2(h, dsa->p);
|
||||
put_mp_ssh2(h, dsa->q);
|
||||
put_mp_ssh2(h, dsa->g);
|
||||
ssh_hash_final(h, digest);
|
||||
if (!smemeq(hash.ptr, digest, 20)) {
|
||||
dss_freekey(&dss->sshk);
|
||||
dsa_freekey(&dsa->sshk);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -271,75 +271,75 @@ static ssh_key *dss_new_priv(const ssh_keyalg *self, ptrlen pub, ptrlen priv)
|
||||
/*
|
||||
* Now ensure g^x mod p really is y.
|
||||
*/
|
||||
ytest = mp_modpow(dss->g, dss->x, dss->p);
|
||||
if (!mp_cmp_eq(ytest, dss->y)) {
|
||||
ytest = mp_modpow(dsa->g, dsa->x, dsa->p);
|
||||
if (!mp_cmp_eq(ytest, dsa->y)) {
|
||||
mp_free(ytest);
|
||||
dss_freekey(&dss->sshk);
|
||||
dsa_freekey(&dsa->sshk);
|
||||
return NULL;
|
||||
}
|
||||
mp_free(ytest);
|
||||
|
||||
return &dss->sshk;
|
||||
return &dsa->sshk;
|
||||
}
|
||||
|
||||
static ssh_key *dss_new_priv_openssh(const ssh_keyalg *self,
|
||||
static ssh_key *dsa_new_priv_openssh(const ssh_keyalg *self,
|
||||
BinarySource *src)
|
||||
{
|
||||
struct dss_key *dss;
|
||||
struct dsa_key *dsa;
|
||||
|
||||
dss = snew(struct dss_key);
|
||||
dss->sshk.vt = &ssh_dss;
|
||||
dsa = snew(struct dsa_key);
|
||||
dsa->sshk.vt = &ssh_dsa;
|
||||
|
||||
dss->p = get_mp_ssh2(src);
|
||||
dss->q = get_mp_ssh2(src);
|
||||
dss->g = get_mp_ssh2(src);
|
||||
dss->y = get_mp_ssh2(src);
|
||||
dss->x = get_mp_ssh2(src);
|
||||
dsa->p = get_mp_ssh2(src);
|
||||
dsa->q = get_mp_ssh2(src);
|
||||
dsa->g = get_mp_ssh2(src);
|
||||
dsa->y = get_mp_ssh2(src);
|
||||
dsa->x = get_mp_ssh2(src);
|
||||
|
||||
if (get_err(src) ||
|
||||
mp_eq_integer(dss->q, 0) || mp_eq_integer(dss->p, 0)) {
|
||||
mp_eq_integer(dsa->q, 0) || mp_eq_integer(dsa->p, 0)) {
|
||||
/* Invalid key. */
|
||||
dss_freekey(&dss->sshk);
|
||||
dsa_freekey(&dsa->sshk);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &dss->sshk;
|
||||
return &dsa->sshk;
|
||||
}
|
||||
|
||||
static void dss_openssh_blob(ssh_key *key, BinarySink *bs)
|
||||
static void dsa_openssh_blob(ssh_key *key, BinarySink *bs)
|
||||
{
|
||||
struct dss_key *dss = container_of(key, struct dss_key, sshk);
|
||||
struct dsa_key *dsa = container_of(key, struct dsa_key, sshk);
|
||||
|
||||
put_mp_ssh2(bs, dss->p);
|
||||
put_mp_ssh2(bs, dss->q);
|
||||
put_mp_ssh2(bs, dss->g);
|
||||
put_mp_ssh2(bs, dss->y);
|
||||
put_mp_ssh2(bs, dss->x);
|
||||
put_mp_ssh2(bs, dsa->p);
|
||||
put_mp_ssh2(bs, dsa->q);
|
||||
put_mp_ssh2(bs, dsa->g);
|
||||
put_mp_ssh2(bs, dsa->y);
|
||||
put_mp_ssh2(bs, dsa->x);
|
||||
}
|
||||
|
||||
static int dss_pubkey_bits(const ssh_keyalg *self, ptrlen pub)
|
||||
static int dsa_pubkey_bits(const ssh_keyalg *self, ptrlen pub)
|
||||
{
|
||||
ssh_key *sshk;
|
||||
struct dss_key *dss;
|
||||
struct dsa_key *dsa;
|
||||
int ret;
|
||||
|
||||
sshk = dss_new_pub(self, pub);
|
||||
sshk = dsa_new_pub(self, pub);
|
||||
if (!sshk)
|
||||
return -1;
|
||||
|
||||
dss = container_of(sshk, struct dss_key, sshk);
|
||||
ret = mp_get_nbits(dss->p);
|
||||
dss_freekey(&dss->sshk);
|
||||
dsa = container_of(sshk, struct dsa_key, sshk);
|
||||
ret = mp_get_nbits(dsa->p);
|
||||
dsa_freekey(&dsa->sshk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
mp_int *dss_gen_k(const char *id_string, mp_int *modulus,
|
||||
mp_int *dsa_gen_k(const char *id_string, mp_int *modulus,
|
||||
mp_int *private_key,
|
||||
unsigned char *digest, int digest_len)
|
||||
{
|
||||
/*
|
||||
* The basic DSS signing algorithm is:
|
||||
* The basic DSA signing algorithm is:
|
||||
*
|
||||
* - invent a random k between 1 and q-1 (exclusive).
|
||||
* - Compute r = (g^k mod p) mod q.
|
||||
@ -445,29 +445,29 @@ mp_int *dss_gen_k(const char *id_string, mp_int *modulus,
|
||||
return k;
|
||||
}
|
||||
|
||||
static void dss_sign(ssh_key *key, ptrlen data, unsigned flags, BinarySink *bs)
|
||||
static void dsa_sign(ssh_key *key, ptrlen data, unsigned flags, BinarySink *bs)
|
||||
{
|
||||
struct dss_key *dss = container_of(key, struct dss_key, sshk);
|
||||
struct dsa_key *dsa = container_of(key, struct dsa_key, sshk);
|
||||
unsigned char digest[20];
|
||||
int i;
|
||||
|
||||
hash_simple(&ssh_sha1, data, digest);
|
||||
|
||||
mp_int *k = dss_gen_k("DSA deterministic k generator", dss->q, dss->x,
|
||||
mp_int *k = dsa_gen_k("DSA deterministic k generator", dsa->q, dsa->x,
|
||||
digest, sizeof(digest));
|
||||
mp_int *kinv = mp_invert(k, dss->q); /* k^-1 mod q */
|
||||
mp_int *kinv = mp_invert(k, dsa->q); /* k^-1 mod q */
|
||||
|
||||
/*
|
||||
* Now we have k, so just go ahead and compute the signature.
|
||||
*/
|
||||
mp_int *gkp = mp_modpow(dss->g, k, dss->p); /* g^k mod p */
|
||||
mp_int *r = mp_mod(gkp, dss->q); /* r = (g^k mod p) mod q */
|
||||
mp_int *gkp = mp_modpow(dsa->g, k, dsa->p); /* g^k mod p */
|
||||
mp_int *r = mp_mod(gkp, dsa->q); /* r = (g^k mod p) mod q */
|
||||
mp_free(gkp);
|
||||
|
||||
mp_int *hash = mp_from_bytes_be(make_ptrlen(digest, 20));
|
||||
mp_int *xr = mp_mul(dss->x, r);
|
||||
mp_int *xr = mp_mul(dsa->x, r);
|
||||
mp_int *hxr = mp_add(xr, hash); /* hash + x*r */
|
||||
mp_int *s = mp_modmul(kinv, hxr, dss->q); /* s = k^-1 * (hash+x*r) mod q */
|
||||
mp_int *s = mp_modmul(kinv, hxr, dsa->q); /* s = k^-1 * (hash+x*r) mod q */
|
||||
mp_free(hxr);
|
||||
mp_free(xr);
|
||||
mp_free(kinv);
|
||||
@ -484,20 +484,20 @@ static void dss_sign(ssh_key *key, ptrlen data, unsigned flags, BinarySink *bs)
|
||||
mp_free(s);
|
||||
}
|
||||
|
||||
const ssh_keyalg ssh_dss = {
|
||||
.new_pub = dss_new_pub,
|
||||
.new_priv = dss_new_priv,
|
||||
.new_priv_openssh = dss_new_priv_openssh,
|
||||
.freekey = dss_freekey,
|
||||
.invalid = dss_invalid,
|
||||
.sign = dss_sign,
|
||||
.verify = dss_verify,
|
||||
.public_blob = dss_public_blob,
|
||||
.private_blob = dss_private_blob,
|
||||
.openssh_blob = dss_openssh_blob,
|
||||
.cache_str = dss_cache_str,
|
||||
.components = dss_components,
|
||||
.pubkey_bits = dss_pubkey_bits,
|
||||
const ssh_keyalg ssh_dsa = {
|
||||
.new_pub = dsa_new_pub,
|
||||
.new_priv = dsa_new_priv,
|
||||
.new_priv_openssh = dsa_new_priv_openssh,
|
||||
.freekey = dsa_freekey,
|
||||
.invalid = dsa_invalid,
|
||||
.sign = dsa_sign,
|
||||
.verify = dsa_verify,
|
||||
.public_blob = dsa_public_blob,
|
||||
.private_blob = dsa_private_blob,
|
||||
.openssh_blob = dsa_openssh_blob,
|
||||
.cache_str = dsa_cache_str,
|
||||
.components = dsa_components,
|
||||
.pubkey_bits = dsa_pubkey_bits,
|
||||
.ssh_id = "ssh-dss",
|
||||
.cache_id = "dss",
|
||||
};
|
||||
|
@ -1117,7 +1117,7 @@ static void ecdsa_sign(ssh_key *key, ptrlen data,
|
||||
{
|
||||
unsigned char digest[20];
|
||||
hash_simple(&ssh_sha1, data, digest);
|
||||
k = dss_gen_k(
|
||||
k = dsa_gen_k(
|
||||
"ECDSA deterministic k generator", ek->curve->w.G_order,
|
||||
ek->privateKey, digest, sizeof(digest));
|
||||
}
|
||||
|
Reference in New Issue
Block a user