Also, do what the commentary says and return zero and break the output
buffer if it's not big enough, rather than returning KSERR_DECRYPT.
The new error codes allow callers to make more sensible decisions about
whether to continue to search for other keys which might work better.
a_warn("KX", "?PEER", kx->p, "decrypt-failed", "%s", pkname[msg], A_END);
return (-1);
}
a_warn("KX", "?PEER", kx->p, "decrypt-failed", "%s", pkname[msg], A_END);
return (-1);
}
+ if (!BOK(&bb)) return (-1);
buf_init(b, BBASE(&bb), BLEN(&bb));
return (0);
}
buf_init(b, BBASE(&bb), BLEN(&bb));
return (0);
}
if (psz < ivsz + SEQSZ + tagsz) {
T( trace(T_KEYSET, "keyset: block too small for keyset %u", ks->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;
}
sz = psz - ivsz - SEQSZ - tagsz;
pmac = BCUR(b); pseq = pmac + tagsz; piv = pseq + SEQSZ; ppk = piv + ivsz;
* @buf *b@ = pointer to an input buffer
* @buf *bb@ = pointer to an output buffer
*
* @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).
*
* zero if there was insufficient buffer (but the output buffer
* is broken in this case).
*
{
time_t now = time(0);
uint32 seq;
{
time_t now = time(0);
uint32 seq;
- 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);
time_t now = time(0);
keyset *ks;
uint32 seq;
time_t now = time(0);
keyset *ks;
uint32 seq;
if (buf_ensure(bb, BLEN(b)))
if (buf_ensure(bb, BLEN(b)))
- return (KSERR_DECRYPT);
for (ks = *ksroot; ks; ks = ks->next) {
if (!KEYOK(ks, now))
continue;
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"))
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);
+ if (err != KSERR_DECRYPT) return (err);
}
T( trace(T_KEYSET, "keyset: no matching keys, or incorrect MAC"); )
return (KSERR_DECRYPT);
}
T( trace(T_KEYSET, "keyset: no matching keys, or incorrect MAC"); )
return (KSERR_DECRYPT);
#define KSERR_REGEN -1 /* Regenerate keys */
#define KSERR_NOKEYS -2 /* No keys left */
#define KSERR_DECRYPT -3 /* Unable to decrypt message */
#define KSERR_REGEN -1 /* Regenerate keys */
#define KSERR_NOKEYS -2 /* No keys left */
#define KSERR_DECRYPT -3 /* Unable to decrypt message */
+#define KSERR_SEQ -4 /* Incorrect sequence number */
+#define KSERR_MALFORMED -5 /* Input ciphertext is broken */
/* --- Key exchange --- *
*
/* --- Key exchange --- *
*