static int algs_get(algswitch *a, dstr *e, key_file *kf, key *k)
{
const char *p;
- const bulkops *bulk;
- char *q, *qq;
+ const bulkops *bops;
dstr d = DSTR_INIT, dd = DSTR_INIT;
int rc = -1;
/* --- Bulk crypto transform --- */
if ((p = key_getattr(kf, k, "bulk")) == 0) p = "v0";
- for (bulk = bulktab; bulk->name && strcmp(p, bulk->name) != 0; bulk++);
- if (!bulk->name) {
+ for (bops = bulktab; bops->name && strcmp(p, bops->name) != 0; bops++);
+ if (!bops->name) {
a_format(e, "unknown-bulk-transform", "%s", p, A_END);
goto done;
}
- a->bulk = bulk;
-
- /* --- Symmetric encryption for bulk data --- */
-
- if (!(a->bulk->prim & BCP_CIPHER))
- a->c = 0;
- else {
- if ((p = key_getattr(kf, k, "cipher")) == 0) p = "blowfish-cbc";
- if ((a->c = gcipher_byname(p)) == 0) {
- a_format(e, "unknown-cipher", "%s", p, A_END);
- goto done;
- }
- }
-
- /* --- Block cipher for miscellaneous use --- */
-
- if (!(a->bulk->prim & BCP_BLKC))
- a->b = 0;
- else {
- if ((p = key_getattr(kf, k, "blkc")) == 0) {
- dstr_reset(&dd);
- dstr_puts(&dd, a->c ? a->c->name : "rijndael-");
- if ((q = strrchr(dd.buf, '-')) != 0) *q = 0;
- p = dd.buf;
- }
- dstr_reset(&d);
- dstr_putf(&d, "%s-ecb", p);
- if ((a->b = gcipher_byname(d.buf)) == 0) {
- a_format(e, "unknown-blkc", "%s", p, A_END);
- goto done;
- }
- }
-
- /* --- Message authentication for bulk data --- */
-
- if (!(a->bulk->prim & BCP_MAC)) {
- a->m = 0;
- a->tagsz = 0;
- } else {
- if ((p = key_getattr(kf, k, "mac")) != 0) {
- dstr_reset(&d);
- dstr_puts(&d, p);
- if ((q = strchr(d.buf, '/')) != 0)
- *q++ = 0;
- if ((a->m = gmac_byname(d.buf)) == 0) {
- a_format(e, "unknown-mac", "%s", d.buf, A_END);
- goto done;
- }
- if (!q)
- a->tagsz = a->m->hashsz;
- else {
- unsigned long n = strtoul(q, &qq, 0);
- if (*qq) {
- a_format(e, "bad-tag-length-string", "%s", q, A_END);
- goto done;
- }
- if (n%8 || n/8 > a->m->hashsz) {
- a_format(e, "bad-tag-length", "%lu", n, A_END);
- goto done;
- }
- a->tagsz = n/8;
- }
- } else {
- dstr_reset(&d);
- dstr_putf(&d, "%s-hmac", a->h->name);
- if ((a->m = gmac_byname(d.buf)) == 0) {
- a_format(e, "no-hmac-for-hash", "%s", a->h->name, A_END);
- goto done;
- }
- a->tagsz = a->h->hashsz/2;
- }
- }
+ if ((a->bulk = bops->getalgs(a, e, kf, k)) == 0) goto done;
+ a->bulk->ops = bops;
/* --- All done --- */
static int algs_check(algswitch *a, dstr *e, const group *g)
{
- /* --- Check the bulk crypto transform --- */
-
- if (a->bulk->check(a, e)) return (-1);
-
- /* --- Derive the key sizes --- *
- *
- * Must ensure that we have non-empty keys. This isn't ideal, but it
- * provides a handy sanity check. Also must be based on a 64- or 128-bit
- * block cipher or we can't do the data expiry properly.
- */
-
a->hashsz = a->h->hashsz;
- if (a->c && (a->cksz = keysz(a->hashsz, a->c->keysz)) == 0) {
- a_format(e, "cipher", "%s", a->c->name,
- "no-key-size", "%lu", (unsigned long)a->hashsz,
- A_END);
- return (-1);
- }
- if (a->m && (a->mksz = keysz(a->hashsz, a->m->keysz)) == 0) {
- a_format(e, "mac", "%s", a->m->name,
- "no-key-size", "%lu", (unsigned long)a->hashsz,
- A_END);
- return (-1);
- }
- if (a->b && (a->bksz = keysz(a->hashsz, a->b->keysz)) == 0) {
- a_format(e, "blkc", "%.*s", strlen(a->b->name) - 4, a->b->name,
- "no-key-size", "%lu", (unsigned long)a->hashsz,
- A_END);
- return (-1);
- }
-
- /* --- Derive the data limit --- */
-
- if (a->c && a->c->blksz < 16) a->expsz = MEG(64);
- else a->expsz = MEG(2048);
-
- /* --- Ensure the MGF accepts hashes as keys --- */
if (keysz(a->hashsz, a->mgf->keysz) != a->hashsz) {
a_format(e, "mgf", "%s", a->mgf->name,
return (-1);
}
- /* --- All ship-shape and Bristol-fashion --- */
+ if (a->bulk->ops->checkalgs(a->bulk, a, e)) return (-1);
return (0);
}
const algswitch *a = &kdx->algs, *aa = &kdy->algs;
return (group_samep(kdx->g, kdy->g) &&
- a->bulk == aa->bulk &&
- a->c == aa->c && a->b == aa->b &&
a->mgf == aa->mgf && a->h == aa->h &&
- a->m == aa->m && a->tagsz == aa->tagsz);
+ a->bulk->ops == aa->bulk->ops &&
+ a->bulk->ops->samealgsp(a->bulk, aa->bulk));
}
/*----- Key data and key nodes --------------------------------------------*/
trace(T_CRYPTO, "crypto: h = %s", mpstr(kd->g->h));
if (kd->kpriv)
trace(T_CRYPTO, "crypto: x = %s", mpstr(kd->kpriv));
- trace(T_CRYPTO, "crypto: cipher = %s", kd->algs.c->name);
- trace(T_CRYPTO, "crypto: mgf = %s", kd->algs.mgf->name);
- trace(T_CRYPTO, "crypto: hash = %s", kd->algs.h->name);
- trace(T_CRYPTO, "crypto: mac = %s/%lu",
- kd->algs.m->name, (unsigned long)kd->algs.tagsz * 8);
+ kd->algs.bulk->ops->tracealgs(kd->algs.bulk);
})
})