* additional data isn't necessary). Good options include
* `chacha20-poly1305' or `rijndael-ocb3'.
*
- * To be acceptable, the scheme must accept at least a 64-bit nonce. (All of
+ * To be acceptable, the scheme must accept at least a 40-bit nonce. (All of
* Catacomb's current AEAD schemes are suitable.) The low 32 bits are the
- * sequence number, and the high 32 bits are the type, both big-endian.
+ * sequence number. The type is written to the next 8--32 bytes: if the
+ * nonce size is 64 bits or more (preferred, for compatibility reasons) then
+ * the type is written as 32 bits, and the remaining space is padded with
+ * zero bytes; otherwise, the type is right-aligned in the remaining space.
+ * Both fields are big-endian.
*
- * +--------+--------+
- * | seq | type |
- * +--------+--------+
- * 32 32
+ * +--------+--+
+ * | seq |ty|
+ * +--------+--+
+ * 32 8
+ *
+ * +--------+----+
+ * | seq | ty |
+ * +--------+----+
+ * 32 16
+ *
+ * +--------+------+
+ * | seq | type |
+ * +--------+------+
+ * 32 24
+ *
+ * +--------+--------+---...---+
+ * | seq | type | 0 |
+ * +--------+--------+---...---+
+ * 32 32 nsz - 64
*
* The ciphertext is formatted as
*
goto fail;
}
a->nsz = keysz_pad(8, a->c->noncesz);
+ if (!a->nsz) a->nsz = keysz_pad(5, a->c->noncesz);
if (!a->nsz) {
a_format(e, "unsuitable-aead-cipher", "%s", p, "nonce-too-small", A_END);
goto fail;
static void aead_fmtnonce(aead_ctx *bc, octet *n, uint32 seq, unsigned ty)
{
- assert(bc->nsz <= AEAD_NONCEMAX);
- STORE32(n, seq); STORE32(n + SEQSZ, ty);
- if (bc->nsz > 8) memset(n + 8, 0, bc->nsz - 8);
+ assert(bc->nsz <= AEAD_NONCEMAX); assert(ty <= 255);
+ STORE32(n, seq);
+ switch (bc->nsz) {
+ case 5: STORE8(n + SEQSZ, ty); break;
+ case 6: STORE16(n + SEQSZ, ty); break;
+ case 7: STORE24(n + SEQSZ, ty); break;
+ default: memset(n + 8, 0, bc->nsz - 8); /* and continue */
+ case 8: STORE32(n + SEQSZ, ty); break;
+ }
TRACE_IV(n, bc->nsz);
}