X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/blobdiff_plain/a50f9a0eaed03dfe85ff3d7a4c24da20ac705dae..46401b81fe5fab9b0d3d3a5f5764bafa3f9c0b86:/server/keyset.c diff --git a/server/keyset.c b/server/keyset.c index 9dd17fac..1f580ff7 100644 --- a/server/keyset.c +++ b/server/keyset.c @@ -30,18 +30,8 @@ /*----- 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 ------------------------------------------------------*/ @@ -153,7 +143,7 @@ static int doencrypt(keyset *ks, unsigned ty, buf *b, buf *bb) 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; @@ -198,7 +188,7 @@ static int dodecrypt(keyset *ks, unsigned ty, buf *b, buf *bb, uint32 *seq) 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; @@ -357,7 +347,8 @@ keyset *ks_gen(const void *k, size_t x, size_t y, size_t z, peer *p) 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; @@ -430,7 +421,7 @@ int ks_encrypt(keyset *ks, unsigned ty, buf *b, buf *bb) * @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). * @@ -443,12 +434,12 @@ int ks_decrypt(keyset *ks, unsigned ty, buf *b, buf *bb) { 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); } @@ -583,24 +574,26 @@ int ksl_decrypt(keyset **ksroot, unsigned ty, buf *b, buf *bb) 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);