X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/d56fd9d102115283485493dbe56b0d320ac99097..7b0d1a63587f3cb1ae3bb8b248bbb1b82bdca7bd:/progs/key.c diff --git a/progs/key.c b/progs/key.c index b2b90800..0c817d4d 100644 --- a/progs/key.c +++ b/progs/key.c @@ -63,6 +63,7 @@ #include "gfreduce.h" #include "key.h" #include "mp.h" +#include "mpint.h" #include "mpmont.h" #include "mprand.h" #include "mptext.h" @@ -70,7 +71,9 @@ #include "ptab.h" #include "rsa.h" #include "x25519.h" +#include "x448.h" #include "ed25519.h" +#include "ed448.h" #include "cc.h" #include "sha-mgf.h" @@ -195,6 +198,7 @@ typedef struct keyopts { unsigned bits, qbits; /* Bit length for the new key */ const char *curve; /* Elliptic curve name/info */ grand *r; /* Random number source */ + mp *e; /* Public exponent */ key *p; /* Parameters key-data */ } keyopts; @@ -442,11 +446,15 @@ static void alg_rsa(keyopts *k) copyparam(k, 0); if (!k->bits) k->bits = 1024; + if (k->bits < 64) + die(EXIT_FAILURE, "RSA key too tiny"); + if (!k->e) + k->e = mp_fromulong(MP_NEW, 65537); /* --- Generate the RSA parameters --- */ - if (rsa_gen(&rp, k->bits, k->r, 0, - (k->f & f_quiet) ? 0 : pgen_ev, 0)) + if (rsa_gen_e(&rp, k->bits, k->e, k->r, 0, + (k->f & f_quiet) ? 0 : pgen_ev, 0)) die(EXIT_FAILURE, "RSA key generation failed"); /* --- Run a test encryption --- */ @@ -938,41 +946,63 @@ static void alg_ec(keyopts *k) mp_drop(x); } -static void alg_x25519(keyopts *k) -{ - key_data *kd, *kkd; - octet priv[X25519_KEYSZ], pub[X25519_PUBSZ]; - - copyparam(k, 0); - k->r->ops->fill(k->r, priv, sizeof(priv)); - x25519(pub, priv, x25519_base); - kkd = key_newstruct(); - key_structsteal(kkd, "priv", - key_newbinary(KCAT_PRIV | KF_BURN, priv, sizeof(priv))); - kd = key_newstruct(); - key_structsteal(kd, "private", kkd); - key_structsteal(kd, "pub", key_newbinary(KCAT_PUB, pub, sizeof(pub))); - - key_setkeydata(k->kf, k->k, kd); -} - -static void alg_ed25519(keyopts *k) -{ - key_data *kd, *kkd; - octet priv[ED25519_KEYSZ], pub[ED25519_PUBSZ]; +#define XDHS(_) \ + _(x25519, X25519, "X25519") \ + _(x448, X448, "X448") + +#define XDHALG(xdh, XDH, name) \ + \ + static void alg_##xdh(keyopts *k) \ + { \ + key_data *kd, *kkd; \ + octet priv[XDH##_KEYSZ], pub[XDH##_PUBSZ]; \ + \ + copyparam(k, 0); \ + k->r->ops->fill(k->r, priv, sizeof(priv)); \ + xdh(pub, priv, xdh##_base); \ + kkd = key_newstruct(); \ + key_structsteal(kkd, "priv", \ + key_newbinary(KCAT_PRIV | KF_BURN, \ + priv, sizeof(priv))); \ + kd = key_newstruct(); \ + key_structsteal(kd, "private", kkd); \ + key_structsteal(kd, "pub", \ + key_newbinary(KCAT_PUB, pub, sizeof(pub))); \ + \ + key_setkeydata(k->kf, k->k, kd); \ + } - copyparam(k, 0); - k->r->ops->fill(k->r, priv, sizeof(priv)); - ed25519_pubkey(pub, priv, sizeof(priv)); - kkd = key_newstruct(); - key_structsteal(kkd, "priv", - key_newbinary(KCAT_PRIV | KF_BURN, priv, sizeof(priv))); - kd = key_newstruct(); - key_structsteal(kd, "private", kkd); - key_structsteal(kd, "pub", key_newbinary(KCAT_PUB, pub, sizeof(pub))); +XDHS(XDHALG) +#undef XDHALG + +#define EDDSAS(_) \ + _(ed25519, ED25519, "Ed25519") \ + _(ed448, ED448, "Ed448") + +#define EDDSAALG(ed, ED, name) \ + \ + static void alg_##ed(keyopts *k) \ + { \ + key_data *kd, *kkd; \ + octet priv[ED##_KEYSZ], pub[ED##_PUBSZ]; \ + \ + copyparam(k, 0); \ + k->r->ops->fill(k->r, priv, sizeof(priv)); \ + ed##_pubkey(pub, priv, sizeof(priv)); \ + kkd = key_newstruct(); \ + key_structsteal(kkd, "priv", \ + key_newbinary(KCAT_PRIV | KF_BURN, \ + priv, sizeof(priv))); \ + kd = key_newstruct(); \ + key_structsteal(kd, "private", kkd); \ + key_structsteal(kd, "pub", \ + key_newbinary(KCAT_PUB, pub, sizeof(pub))); \ + \ + key_setkeydata(k->kf, k->k, kd); \ + } - key_setkeydata(k->kf, k->k, kd); -} +EDDSAS(EDDSAALG) +#undef EDDSAALG /* --- The algorithm tables --- */ @@ -995,8 +1025,14 @@ static keyalg algtab[] = { { "bindh-param", alg_binparam, "Binary-field DH parameters" }, { "ec-param", alg_ecparam, "Elliptic curve parameters" }, { "ec", alg_ec, "Elliptic curve crypto" }, - { "x25519", alg_x25519, "X25519 key exchange" }, - { "ed25519", alg_ed25519, "Ed25519 digital signatures" }, +#define XDHTAB(xdh, XDH, name) \ + { #xdh, alg_##xdh, "" name " key exchange" }, + XDHS(XDHTAB) +#undef XDHTAB +#define EDDSATAB(ed, ED, name) \ + { #ed, alg_##ed, "" name " digital signatures" }, + EDDSAS(EDDSATAB) +#undef EDDSATAB { "empty", alg_empty, "Empty parametrs-only key" }, { 0, 0 } }; @@ -1013,7 +1049,7 @@ static int cmd_add(int argc, char *argv[]) keyalg *alg = algtab; const char *rtag = 0; const struct seedalg *sa = SEEDALG_DEFAULT; - keyopts k = { 0, 0, DSTR_INIT, 0, 0, 0, 0, 0 }; + keyopts k = { 0, 0, DSTR_INIT, 0, 0, 0, 0, 0, 0 }; const char *seed = 0; k.r = &rand_global; @@ -1034,6 +1070,7 @@ static int cmd_add(int argc, char *argv[]) { "seedalg", OPTF_ARGREQ, 0, 'A' }, { "seed", OPTF_ARGREQ, 0, 's' }, { "newseed", OPTF_ARGREQ, 0, 'n' }, + { "public-exponent", OPTF_ARGREQ, 0, 'E' }, { "lock", 0, 0, 'l' }, { "quiet", 0, 0, 'q' }, { "lim-lee", 0, 0, 'L' }, @@ -1041,7 +1078,7 @@ static int cmd_add(int argc, char *argv[]) { "kcdsa", 0, 0, 'K' }, { 0, 0, 0, 0 } }; - int i = mdwopt(argc, argv, "+a:b:B:p:e:c:t:R:I:C:A:s:n:lqrLKS", + int i = mdwopt(argc, argv, "+a:b:B:p:e:c:t:R:I:C:A:s:n:E:lqrLKS", opt, 0, 0, 0); if (i < 0) break; @@ -1203,6 +1240,15 @@ static int cmd_add(int argc, char *argv[]) kid = id; } break; + /* --- Public exponent --- */ + + case 'E': { + char *p; + k.e = mp_readstring(k.e, optarg, &p, 0); + if (!k.e || *p || MP_CMP(k.e, <, MP_THREE) || MP_EVENP(k.e)) + die(EXIT_FAILURE, "bad exponent `%s'", optarg); + } break; + /* --- Other flags --- */ case 'R':