/*----- Tunable parameters ------------------------------------------------*/
-/* --- Note on size limits --- *
- *
- * For a 64-bit block cipher (e.g., Blowfish), the probability of a collision
- * occurring after 32 MB is less than %$2^{-21}$%, and the probability of a
- * collision occurring after 64 MB is less than %$2^{-19}$%. These could be
- * adjusted dependent on the encryption scheme, but it's too much pain.
- */
-
#define T_EXP MIN(60) /* Expiry time for a key */
#define T_REGEN MIN(45) /* Regeneration time for a key */
-#define SZ_EXP MEG(64) /* Expiry data size for a key */
-#define SZ_REGEN MEG(32) /* Data size threshold for regen */
/*----- Handy macros ------------------------------------------------------*/
nsz = osz - sz;
else
nsz = 0;
- if (osz >= SZ_REGEN && nsz < SZ_REGEN) {
+ if (osz >= ks->sz_regen && ks->sz_regen > nsz) {
T( trace(T_KEYSET, "keyset: keyset %u data regen limit exceeded -- "
"forcing exchange", ks->seq); )
rc = KSERR_REGEN;
if (psz < ivsz + SEQSZ + tagsz) {
T( trace(T_KEYSET, "keyset: block too small for keyset %u", ks->seq); )
- return (KSERR_DECRYPT);
+ return (KSERR_MALFORMED);
}
sz = psz - ivsz - SEQSZ - tagsz;
pmac = BCUR(b); pseq = pmac + tagsz; piv = pseq + SEQSZ; ppk = piv + ivsz;
keyset *ks = CREATE(keyset);
time_t now = time(0);
const octet *pp = k;
+ const algswitch *algs = &p->kx.kpriv->algs;
T( static unsigned seq = 0; )
T( trace(T_KEYSET, "keyset: adding new keyset %u", seq); )
#define HASH_in MINE; YOURS; OURS
#define HASH_out YOURS; MINE; OURS
-#define INIT_c(k) GC_INIT(algs.c, (k), algs.cksz)
-#define INIT_m(k) GM_KEY(algs.m, (k), algs.mksz)
+#define INIT_c(k) GC_INIT(algs->c, (k), algs->cksz)
+#define INIT_m(k) GM_KEY(algs->m, (k), algs->mksz)
#define STR_c "encryption"
#define STR_m "integrity"
#define STR_in "incoming"
#define STR_out "outgoing"
#define SETKEY(a, dir) do { \
- h = GH_INIT(algs.h); \
+ h = GH_INIT(algs->h); \
HASH_STRING(h, "tripe-" STR_##a); \
HASH_##dir; \
hh = GH_DONE(h, 0); \
IF_TRACING(T_KEYSET, { \
trace_block(T_CRYPTO, "crypto: " STR_##dir " key " STR_##a, \
- hh, algs.a##ksz); \
+ hh, algs->a##ksz); \
}) \
ks->a##dir = INIT_##a(hh); \
GH_DESTROY(h); \
T( ks->seq = seq++; )
ks->ref = 1;
ks->t_exp = now + T_EXP;
- ks->sz_exp = SZ_EXP;
+ ks->sz_exp = algs->expsz;
+ ks->sz_regen = algs->expsz/2;
ks->oseq = 0;
seq_reset(&ks->iseq);
ks->next = 0;
ks->p = p;
ks->f = KSF_LISTEN;
- ks->tagsz = algs.tagsz;
+ ks->tagsz = algs->tagsz;
return (ks);
}
* @buf *b@ = pointer to an input buffer
* @buf *bb@ = pointer to an output buffer
*
- * Returns: Zero on success; @KSERR_DECRYPT@ on failure. Also returns
+ * Returns: Zero on success; @KSERR_...@ on failure. Also returns
* zero if there was insufficient buffer (but the output buffer
* is broken in this case).
*
{
time_t now = time(0);
uint32 seq;
+ int err;
- if (!KEYOK(ks, now) ||
- buf_ensure(bb, BLEN(b)) ||
- dodecrypt(ks, ty, b, bb, &seq) ||
- seq_check(&ks->iseq, seq, "SYMM"))
- return (KSERR_DECRYPT);
+ if (!KEYOK(ks, now)) return (KSERR_DECRYPT);
+ if (buf_ensure(bb, BLEN(b))) return (0);
+ if ((err = dodecrypt(ks, ty, b, bb, &seq)) != 0) return (err);
+ if (seq_check(&ks->iseq, seq, "SYMM")) return (KSERR_SEQ);
return (0);
}
time_t now = time(0);
keyset *ks;
uint32 seq;
+ int err;
if (buf_ensure(bb, BLEN(b)))
- return (KSERR_DECRYPT);
+ return (0);
for (ks = *ksroot; ks; ks = ks->next) {
if (!KEYOK(ks, now))
continue;
- if (!dodecrypt(ks, ty, b, bb, &seq)) {
+ if ((err = dodecrypt(ks, ty, b, bb, &seq)) == 0) {
if (ks->f & KSF_LISTEN) {
T( trace(T_KEYSET, "keyset: implicitly activating keyset %u",
ks->seq); )
ks->f &= ~KSF_LISTEN;
}
if (seq_check(&ks->iseq, seq, "SYMM"))
- return (KSERR_DECRYPT);
+ return (KSERR_SEQ);
else
return (0);
}
+ if (err != KSERR_DECRYPT) return (err);
}
T( trace(T_KEYSET, "keyset: no matching keys, or incorrect MAC"); )
return (KSERR_DECRYPT);