/* -*-c-*-
- *
- * $Id$
*
* Handling of symmetric keysets
*
/*----- 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 ------------------------------------------------------*/
* @buf *b@ = pointer to an input buffer
* @buf *bb@ = pointer to an output buffer
*
- * Returns: Zero if OK, nonzero if a new key is required.
+ * Returns: Zero if OK; @KSERR_REGEN@ if it's time to generate new keys.
+ * Also returns zero if there was insufficient buffer space, but
+ * the buffer is broken in this case.
*
* Use: Encrypts a message with the given key. We assume that the
* keyset is OK to use.
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 = -1;
+ rc = KSERR_REGEN;
}
ks->sz_exp = nsz;
return (rc);
* @buf *bb@ = pointer to an output buffer
* @uint32 *seq@ = where to store the sequence number
*
- * Returns: Zero if OK, nonzero if it failed.
+ * Returns: Zero on success; @KSERR_DECRYPT@ on failure.
*
* Use: Attempts to decrypt a message with the given key. No other
* checking (e.g., sequence number checks) is performed. We
if (psz < ivsz + SEQSZ + tagsz) {
T( trace(T_KEYSET, "keyset: block too small for keyset %u", ks->seq); )
- return (-1);
+ return (KSERR_DECRYPT);
}
sz = psz - ivsz - SEQSZ - tagsz;
pmac = BCUR(b); pseq = pmac + tagsz; piv = pseq + SEQSZ; ppk = piv + ivsz;
trace(T_KEYSET, "keyset: incorrect MAC: decryption failed");
trace_block(T_CRYPTO, "crypto: expected MAC", pmac, tagsz);
})
- return (-1);
+ return (KSERR_DECRYPT);
}
}
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;
* @buf *b@ = pointer to input buffer
* @buf *bb@ = pointer to output buffer
*
- * Returns: Zero if OK, nonzero if the key needs replacing. If the
- * encryption failed, the output buffer is broken and zero is
- * returned.
+ * Returns: Zero if successful; @KSERR_REGEN@ if we should negotiate a
+ * new key; @KSERR_NOKEYS@ if the key is not usable. Also
+ * returns zero if there was insufficient buffer (but the output
+ * buffer is broken in this case).
*
* Use: Encrypts a block of data using the key. Note that the `key
* ought to be replaced' notification is only ever given once
if (!KEYOK(ks, now)) {
buf_break(bb);
- return (0);
+ return (KSERR_NOKEYS);
}
return (doencrypt(ks, ty, b, bb));
}
* @buf *b@ = pointer to an input buffer
* @buf *bb@ = pointer to an output buffer
*
- * Returns: Zero on success, or nonzero if there was some problem.
+ * Returns: Zero on success; @KSERR_DECRYPT@ on failure. Also returns
+ * zero if there was insufficient buffer (but the output buffer
+ * is broken in this case).
*
* Use: Attempts to decrypt a message using a given key. Note that
* requesting decryption with a key directly won't clear a
buf_ensure(bb, BLEN(b)) ||
dodecrypt(ks, ty, b, bb, &seq) ||
seq_check(&ks->iseq, seq, "SYMM"))
- return (-1);
+ return (KSERR_DECRYPT);
return (0);
}
* @buf *b@ = pointer to input buffer
* @buf *bb@ = pointer to output buffer
*
- * Returns: Nonzero if a new key is needed.
+ * Returns: Zero if successful; @KSERR_REGEN@ if it's time to negotiate a
+ * new key; @KSERR_NOKEYS@ if there are no suitable keys
+ * available. Also returns zero if there was insufficient
+ * buffer space (but the output buffer is broken in this case).
*
* Use: Encrypts a packet.
*/
if (!ks) {
T( trace(T_KEYSET, "keyset: no suitable keysets found"); )
buf_break(bb);
- return (-1);
+ return (KSERR_NOKEYS);
}
if (KEYOK(ks, now) && !(ks->f & KSF_LISTEN))
break;
* @buf *b@ = pointer to input buffer
* @buf *bb@ = pointer to output buffer
*
- * Returns: Nonzero if the packet couldn't be decrypted.
+ * Returns: Zero on success; @KSERR_DECRYPT@ on failure. Also returns
+ * zero if there was insufficient buffer (but the output buffer
+ * is broken in this case).
*
* Use: Decrypts a packet.
*/
uint32 seq;
if (buf_ensure(bb, BLEN(b)))
- return (-1);
+ return (KSERR_DECRYPT);
for (ks = *ksroot; ks; ks = ks->next) {
if (!KEYOK(ks, now))
ks->seq); )
ks->f &= ~KSF_LISTEN;
}
- return (seq_check(&ks->iseq, seq, "SYMM"));
+ if (seq_check(&ks->iseq, seq, "SYMM"))
+ return (KSERR_DECRYPT);
+ else
+ return (0);
}
}
T( trace(T_KEYSET, "keyset: no matching keys, or incorrect MAC"); )
- return (-1);
+ return (KSERR_DECRYPT);
}
/*----- That's all, folks -------------------------------------------------*/