* (c) 2004 Straylight/Edgeware
*/
-/*----- Licensing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of Catacomb.
*
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
- *
+ *
* Catacomb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Library General Public
* License along with Catacomb; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
ge *y;
} dh_encctx;
-static dh_encctx *dh_doinit(key *k, const gprime_param *gp, mp *y,
+static dh_encctx *dh_doinit(key *k, const gprime_param *gp, mp *y,
group *(*makegroup)(const gprime_param *),
const char *what)
{
ge *y = G_CREATE(de->g);
size_t n = de->g->noctets;
buf b;
-
+
G_EXP(de->g, x, de->g->g, r);
G_EXP(de->g, y, de->y, r);
dstr_ensure(d, n);
ec_decinit, dh_decdoit, dh_enccheck, dh_encdestroy
};
+/* --- Symmetric --- */
+
+typedef struct symm_ctx {
+ kem k;
+ key_packdef kp;
+ key_bin kb;
+} symm_ctx;
+
+static kem *symm_init(key *k, void *kd)
+{
+ symm_ctx *s;
+ dstr d = DSTR_INIT;
+ int err;
+
+ s = CREATE(symm_ctx);
+
+ key_fulltag(k, &d);
+ s->kp.e = KENC_BINARY;
+ s->kp.p = &s->kb;
+ s->kp.kd = 0;
+
+ if ((err = key_unpack(&s->kp, kd, &d)) != 0) {
+ die(EXIT_FAILURE, "failed to unpack symmetric key `%s': %s",
+ d.buf, key_strerror(err));
+ }
+ dstr_destroy(&d);
+ return (&s->k);
+}
+
+static int symm_decdoit(kem *k, dstr *d, ghash *h)
+{
+ symm_ctx *s = (symm_ctx *)k;
+
+ GH_HASH(h, s->kb.k, s->kb.sz);
+ GH_HASH(h, d->buf, d->len);
+ return (0);
+}
+
+static int symm_encdoit(kem *k, dstr *d, ghash *h)
+{
+ dstr_ensure(d, h->ops->c->hashsz);
+ d->len += h->ops->c->hashsz;
+ rand_get(RAND_GLOBAL, d->buf, d->len);
+ return (symm_decdoit(k, d, h));
+}
+
+static const char *symm_check(kem *k) { return (0); }
+
+static void symm_destroy(kem *k)
+ { symm_ctx *s = (symm_ctx *)k; key_unpackdone(&s->kp); }
+
+static const kemops symm_encops = {
+ 0, 0,
+ symm_init, symm_encdoit, symm_check, symm_destroy
+};
+
+static const kemops symm_decops = {
+ 0, 0,
+ symm_init, symm_decdoit, symm_check, symm_destroy
+};
+
/* --- The switch table --- */
const struct kemtab kemtab[] = {
{ "dh", &dh_encops, &dh_decops },
{ "bindh", &bindh_encops, &bindh_decops },
{ "ec", &ec_encops, &ec_decops },
+ { "symm", &symm_encops, &symm_decops },
{ 0, 0, 0 }
};
kalg, t.buf);
k_found:;
ko = wantpriv ? kt->decops : kt->encops;
- kd = xmalloc(ko->kdsz);
- kp = key_fetchinit(ko->kf, 0, kd);
- if ((e = key_fetch(kp, k)) != 0)
- die(EXIT_FAILURE, "error fetching key `%s': %s", t.buf, key_strerror(e));
+ if (!ko->kf) {
+ kd = k->k;
+ key_incref(kd);
+ } else {
+ kd = xmalloc(ko->kdsz);
+ kp = key_fetchinit(ko->kf, 0, kd);
+ if ((e = key_fetch(kp, k)) != 0) {
+ die(EXIT_FAILURE, "error fetching key `%s': %s",
+ t.buf, key_strerror(e));
+ }
+ }
kk = ko->init(k, kd);
kk->kp = kp;
kk->ops = ko;
die(EXIT_FAILURE, "encryption scheme (KDF) `%s' not found in key `%s'",
q, t.buf);
}
-
+
dstr_reset(&d);
if ((q = key_getattr(0, k, "mac")) == 0) {
dstr_putf(&d, "%s-hmac", kk->h->name);
void freekem(kem *k)
{
- key_fetchdone(k->kp);
- xfree(k->kd);
+ if (!k->ops->kf)
+ key_drop(k->kd);
+ else {
+ key_fetchdone(k->kp);
+ xfree(k->kd);
+ }
k->ops->destroy(k);
}