static int algs_get(algswitch *a, dstr *e, key_file *kf, key *k)
{
const char *p;
+ const bulkcrypto *bulk;
char *q, *qq;
- dstr d = DSTR_INIT;
+ dstr d = DSTR_INIT, dd = DSTR_INIT;
int rc = -1;
- /* --- Symmetric encryption for bulk data --- */
-
- 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;
- }
-
/* --- Hash function --- */
if ((p = key_getattr(kf, k, "hash")) == 0) p = "rmd160";
goto done;
}
- /* --- Message authentication for bulk data --- */
+ /* --- 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) {
+ a_format(e, "unknown-bulk-transform", "%s", p, A_END);
+ goto done;
+ }
+ a->bulk = bulk;
- if ((p = key_getattr(kf, k, "mac")) != 0) {
+ /* --- 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_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);
+ 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;
}
- 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);
+ }
+
+ /* --- 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 (n%8 || n/8 > a->m->hashsz) {
- a_format(e, "bad-tag-length", "%lu", n, A_END);
+ 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 = n/8;
+ a->tagsz = a->h->hashsz/2;
}
- } 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;
}
+ /* --- All done --- */
+
rc = 0;
done:
dstr_destroy(&d);
+ dstr_destroy(&dd);
return (rc);
}
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
*/
a->hashsz = a->h->hashsz;
- if ((a->cksz = keysz(a->hashsz, a->c->keysz)) == 0) {
+ 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->mksz = keysz(a->hashsz, a->m->keysz)) == 0) {
+ 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->blksz < 16) a->expsz = MEG(64);
+ if (a->c && a->c->blksz < 16) a->expsz = MEG(64);
else a->expsz = MEG(2048);
/* --- Ensure the MGF accepts hashes as keys --- */
{
const algswitch *a = &kdx->algs, *aa = &kdy->algs;
- return (group_samep(kdx->g, kdy->g) && a->c == aa->c &&
+ 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);
}
if ((rc = ko->loadpub(d, kd, t, e)) != 0)
goto fail_0;
if (group_check(kd->g, kd->kpub)) {
- a_format(e, "bad-public-group-element");
+ a_format(e, "bad-public-group-element", A_END);
goto fail_1;
}
kd->kpriv = 0;