server/bulkcrypto.c: Support smaller nonce spaces, down to 40 bits.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 22 Sep 2019 13:40:13 +0000 (14:40 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 22 Sep 2019 14:00:40 +0000 (15:00 +0100)
Pack the type into the available space, however small it is.

server/bulkcrypto.c

index 2e1cb81..4e98ea1 100644 (file)
@@ -820,14 +820,33 @@ static int iiv_decrypt(bulkctx *bbc, unsigned ty,
  * 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
  *
@@ -873,6 +892,7 @@ static bulkalgs *aead_getalgs(const algswitch *asw, dstr *e,
     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;
@@ -1074,9 +1094,15 @@ static void aead_freectx(bulkctx *bbc)
 
 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);
 }