X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/8ef2f81dfbf105ae89082a340ac56f46368387f0..1ba83484ee5bb486da9aa958576de4bc29ef0c1d:/keyutil.c diff --git a/keyutil.c b/keyutil.c index 1871c1a..0911021 100644 --- a/keyutil.c +++ b/keyutil.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: keyutil.c,v 1.16 2003/10/15 09:31:45 mdw Exp $ + * $Id: keyutil.c,v 1.17 2004/03/28 01:58:47 mdw Exp $ * * Simple key manager program * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: keyutil.c,v $ + * Revision 1.17 2004/03/28 01:58:47 mdw + * Generate, store and retreive elliptic curve keys. + * * Revision 1.16 2003/10/15 09:31:45 mdw * Fix help message. * @@ -108,6 +111,9 @@ #include "bbs.h" #include "dh.h" #include "dsa.h" +#include "ec.h" +#include "ec-keys.h" +#include "ectab.h" #include "fibrand.h" #include "getdate.h" #include "key.h" @@ -203,6 +209,7 @@ typedef struct keyopts { dstr tag; /* Full tag name for the key */ unsigned f; /* Flags for the new key */ unsigned bits, qbits; /* Bit length for the new key */ + const char *curve; /* Elliptic curve name/info */ key *p; /* Parameters key-data */ } keyopts; @@ -397,7 +404,7 @@ static void alg_des(keyopts *k) int i; if (!k->bits) - k->bits = 112; + k->bits = 168; if (k->p) die(EXIT_FAILURE, "no shared parameters for DES keys"); if (k->bits % 56 || k->bits > 168) @@ -691,6 +698,87 @@ static void alg_bbs(keyopts *k) bbs_privfree(&bp); } +static void alg_ecparam(keyopts *k) +{ + static const char *pl[] = { "curve", 0 }; + if (!copyparam(k, pl)) { + ec_info ei; + const char *e; + key_data *kd = &k->k->k; + + /* --- Decide on a curve --- */ + + if (!k->bits) k->bits = 256; + if (!k->curve) { + if (k->bits <= 56) k->curve = "secp112r1"; + else if (k->bits <= 64) k->curve = "secp128r1"; + else if (k->bits <= 80) k->curve = "secp160r1"; + else if (k->bits <= 96) k->curve = "secp192r1"; + else if (k->bits <= 112) k->curve = "secp224r1"; + else if (k->bits <= 128) k->curve = "secp256r1"; + else if (k->bits <= 192) k->curve = "secp384r1"; + else if (k->bits <= 256) k->curve = "secp521r1"; + else + die(EXIT_FAILURE, "no built-in curves provide %u-bit security", + k->bits); + } + + /* --- Check it --- */ + + if ((e = ec_getinfo(&ei, k->curve)) != 0) + die(EXIT_FAILURE, "error in curve spec: %s", e); + if (!(k->f & f_quiet) && (e = ec_checkinfo(&ei, &rand_global)) != 0) + moan("WARNING! curve check failed: %s", e); + ec_freeinfo(&ei); + + /* --- Write out the answer --- */ + + key_structure(kd); + kd = key_structcreate(kd, "curve"); + key_string(kd, k->curve); + kd->e |= KCAT_SHARE; + } +} + +static void alg_ec(keyopts *k) +{ + key_data *kd = &k->k->k; + key_data *kkd; + mp *x = MP_NEW; + ec p = EC_INIT; + const char *e; + ec_info ei; + + /* --- Get the curve --- */ + + alg_ecparam(k); + if ((kkd = key_structfind(kd, "curve")) == 0) + die(EXIT_FAILURE, "unexpected failure looking up subkey `curve')"); + if ((kkd->e & KF_ENCMASK) != KENC_STRING) + die(EXIT_FAILURE, "subkey `curve' is not a string"); + if ((e = ec_getinfo(&ei, kkd->u.p)) != 0) + die(EXIT_FAILURE, "error in curve spec: %s", e); + + /* --- Invent a private exponent and compute the public key --- */ + + x = mprand_range(MP_NEWSEC, ei.r, &rand_global, 0); + ec_mul(ei.c, &p, &ei.g, x); + + /* --- Store everything away --- */ + + kkd = key_structcreate(kd, "p"); + key_ec(kkd, &p); + kkd->e |= KCAT_PUB; + kkd = key_structcreate(kd, "private"); + key_structure(kkd); + mpkey(kkd, "x", x, KCAT_PRIV | KF_BURN); + + /* --- Done --- */ + + ec_freeinfo(&ei); + mp_drop(x); +} + /* --- The algorithm tables --- */ typedef struct keyalg { @@ -708,6 +796,8 @@ static keyalg algtab[] = { { "dh", alg_dh, "Diffie-Hellman key exchange" }, { "dh-param", alg_dhparam, "Diffie-Hellman parameters" }, { "bbs", alg_bbs, "Blum-Blum-Shub generator" }, + { "ec-param", alg_ecparam, "Elliptic curve parameters" }, + { "ec", alg_ec, "Elliptic curve crypto" }, { 0, 0 } }; @@ -735,13 +825,14 @@ static int cmd_add(int argc, char *argv[]) { "comment", OPTF_ARGREQ, 0, 'c' }, { "tag", OPTF_ARGREQ, 0, 't' }, { "rand-id", OPTF_ARGREQ, 0, 'R' }, + { "curve", OPTF_ARGREQ, 0, 'C' }, { "lock", 0, 0, 'l' }, { "quiet", 0, 0, 'q' }, { "lim-lee", 0, 0, 'L' }, { "subgroup", 0, 0, 'S' }, { 0, 0, 0, 0 } }; - int i = mdwopt(argc, argv, "+a:b:B:p:e:c:t:R:lqrLS", opt, 0, 0, 0); + int i = mdwopt(argc, argv, "+a:b:B:p:e:c:t:R:C:lqrLS", opt, 0, 0, 0); if (i < 0) break; @@ -819,6 +910,19 @@ static int cmd_add(int argc, char *argv[]) c = optarg; break; + /* --- Elliptic curve parameters --- */ + + case 'C': + if (strcmp(optarg, "list") == 0) { + const ecentry *ee; + printf("Built-in elliptic curves:\n"); + for (ee = ectab; ee->name; ee++) + printf(" %s\n", ee->name); + exit(0); + } + k.curve = optarg; + break; + /* --- Store tags --- */ case 't': @@ -1035,6 +1139,20 @@ static void showkeydata(key_data *k, int ind, listopts *o, dstr *d) putchar('\n'); break; + /* --- Strings --- */ + + case KENC_STRING: + printf(" `%s'\n", k->u.p); + break; + + /* --- Elliptic curve points --- */ + + case KENC_EC: + fputs(" 0x", stdout); mp_writefile(k->u.e.x, stdout, 16); + fputs(", 0x", stdout); mp_writefile(k->u.e.y, stdout, 16); + putchar('\n'); + break; + /* --- Structured keys --- * * * Just iterate over the subkeys. @@ -1623,6 +1741,7 @@ Options:\n\ -b, --bits=N Generate an N-bit key.\n\ -B, --qbits=N Use an N-bit subgroup or factors.\n\ -p, --parameters=TAG Get group parameters from TAG.\n\ +-C, --curve=CURVE Use elliptic curve CURVE.\n\ -e, --expire=TIME Make the key expire after TIME.\n\ -c, --comment=STRING Attach the command STRING to the key.\n\ -t, --tag=TAG Tag the key with the name TAG.\n\