-/*----- Key groups --------------------------------------------------------*/
-
-/* The key-loading functions here must fill in the kdata slot @g@ and
- * either @kpriv@ or @kpub@ as appropriate. The caller will take care of
- * determining @kpub@ given a private key, and of ensuring that @kpriv@ is
- * null for a public key.
- */
-
-typedef struct kgops {
- const char *ty;
- int (*loadpriv)(key_data *, kdata *, dstr *, dstr *);
- int (*loadpub)(key_data *, kdata *, dstr *, dstr *);
-} kgops;
-
-/* --- Diffie-Hellman --- */
-
-static int kgdh_priv(key_data *d, kdata *kd, dstr *t, dstr *e)
-{
- key_packstruct kps[DH_PRIVFETCHSZ];
- key_packdef *kp;
- dh_priv dp;
- int rc;
-
- kp = key_fetchinit(dh_privfetch, kps, &dp);
- if ((rc = key_unpack(kp, d, t)) != 0) {
- a_format(e, "unpack-failed", "%s", key_strerror(rc), A_END);
- goto fail_0;
- }
- kd->g = group_prime(&dp.dp);
- kd->kpriv = MP_COPY(dp.x);
- rc = 0;
- goto done;
-fail_0:
- rc = -1;
-done:
- key_fetchdone(kp);
- return (rc);
-}
-
-static int kgdh_pub(key_data *d, kdata *kd, dstr *t, dstr *e)
-{
- key_packstruct kps[DH_PUBFETCHSZ];
- key_packdef *kp;
- dh_pub dp;
- int rc;
-
- kp = key_fetchinit(dh_pubfetch, kps, &dp);
- if ((rc = key_unpack(kp, d, t)) != 0) {
- a_format(e, "unpack-failed", "%s", key_strerror(rc), A_END);
- goto fail_0;
- }
- kd->g = group_prime(&dp.dp);
- kd->kpub = G_CREATE(kd->g);
- if (G_FROMINT(kd->g, kd->kpub, dp.y)) {
- a_format(e, "bad-public-vector", A_END);
- goto fail_1;
- }
- rc = 0;
- goto done;
-fail_1:
- G_DESTROY(kd->g, kd->kpub);
- G_DESTROYGROUP(kd->g);
-fail_0:
- rc = -1;
-done:
- key_fetchdone(kp);
- return (rc);
-}
-
-static const kgops kgdh_ops = { "dh", kgdh_priv, kgdh_pub };
-
-/* --- Elliptic curve --- */
-
-static int kgec_priv(key_data *d, kdata *kd, dstr *t, dstr *e)
-{
- key_packstruct kps[EC_PRIVFETCHSZ];
- key_packdef *kp;
- ec_priv ep;
- ec_info ei;
- const char *err;
- int rc;
-
- kp = key_fetchinit(ec_privfetch, kps, &ep);
- if ((rc = key_unpack(kp, d, t)) != 0) {
- a_format(e, "unpack-failed", "%s", key_strerror(rc), A_END);
- goto fail_0;
- }
- if ((err = ec_getinfo(&ei, ep.cstr)) != 0) {
- a_format(e, "decode-failed", "%s", err, A_END);
- goto fail_0;
- }
- kd->g = group_ec(&ei);
- kd->kpriv = MP_COPY(ep.x);
- rc = 0;
- goto done;
-fail_0:
- rc = -1;
-done:
- key_fetchdone(kp);
- return (rc);
-}
-
-static int kgec_pub(key_data *d, kdata *kd, dstr *t, dstr *e)
-{
- key_packstruct kps[EC_PUBFETCHSZ];
- key_packdef *kp;
- ec_pub ep;
- ec_info ei;
- const char *err;
- int rc;
-
- kp = key_fetchinit(ec_pubfetch, kps, &ep);
- if ((rc = key_unpack(kp, d, t)) != 0) {
- a_format(e, "unpack-failed", "%s", key_strerror(rc), A_END);
- goto fail_0;
- }
- if ((err = ec_getinfo(&ei, ep.cstr)) != 0) {
- a_format(e, "decode-failed", "%s", err, A_END);
- goto fail_0;
- }
- kd->g = group_ec(&ei);
- kd->kpub = G_CREATE(kd->g);
- if (G_FROMEC(kd->g, kd->kpub, &ep.p)) {
- a_format(e, "bad-public-vector", A_END);
- goto fail_1;
- }
- rc = 0;
- goto done;
-fail_1:
- G_DESTROY(kd->g, kd->kpub);
- G_DESTROYGROUP(kd->g);
-fail_0:
- rc = -1;
-done:
- key_fetchdone(kp);
- return (rc);
-}
-
-static const kgops kgec_ops = { "ec", kgec_priv, kgec_pub };
-
-/* --- Table of supported key types --- */
-
-static const kgops *kgtab[] = { &kgdh_ops, &kgec_ops, 0 };
-