X-Git-Url: https://git.distorted.org.uk/~mdw/tripe/blobdiff_plain/3071201d3de1cc9dd92ee66a261da4920d85626f..5891679d126ad426ed4250aeec75901bc854bf41:/server/bulkcrypto.c diff --git a/server/bulkcrypto.c b/server/bulkcrypto.c index 4e98ea12..f4d37c16 100644 --- a/server/bulkcrypto.c +++ b/server/bulkcrypto.c @@ -303,6 +303,14 @@ static void gencomp_freechal(bulkchal *bc) * * Decryption: checks the overall size, verifies the tag, then decrypts the * ciphertext and extracts the sequence number. + * + * Challenge tags are calculated by applying the MAC to the sequence number + * and message, concatenated as follows. + * + * +--------+---...---+ + * | seq | m | + * +--------+---...---+ + * 32 msz */ typedef struct v0_algs { @@ -538,6 +546,14 @@ static int v0_decrypt(bulkctx *bbc, unsigned ty, * | tag | seq | ciphertext | * +---...---+------+------...------+ * tagsz 32 sz + * + * Challenge tags are calculated by applying the MAC to the sequence number + * and message, concatenated as follows. + * + * +--------+---...---+ + * | seq | m | + * +--------+---...---+ + * 32 msz */ typedef struct iiv_algs { @@ -816,17 +832,18 @@ static int iiv_decrypt(bulkctx *bbc, unsigned ty, /*----- The AEAD transform ------------------------------------------------* * - * This transform uses a general authenticated encryption scheme (the - * additional data isn't necessary). Good options include - * `chacha20-poly1305' or `rijndael-ocb3'. + * This transform uses a general authenticated encryption scheme. Processing + * additional authenticated data isn't needed for encrypting messages, but it + * is required for challenge generation. Good options include `chacha20- + * poly1305' or `rijndael-ocb3'; alas, `salsa20-naclbox' isn't acceptable. * * 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. 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. + * Catacomb's current AEAD schemes are suitable in this respect.) The low 32 + * bits are the 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 |ty| @@ -855,6 +872,14 @@ static int iiv_decrypt(bulkctx *bbc, unsigned ty, * +---...---+--------+------...------+ * tagsz 32 sz * + * Challenge tags are calculated by encrypting the message, using the + * sequence number as a nonce (as a big-endian integer, padding with leading + * zeroes as needed to fill the space), and discarding the ciphertext. + * + * +---...---+--------+ +-----...------+ + * | 0 | seq | | message | + * +---...---+--------+ +-----...------+ + * nsz - 32 32 msz */ #define AEAD_NONCEMAX 64 @@ -1207,6 +1232,21 @@ static int aead_decrypt(bulkctx *bbc, unsigned ty, * Note that there is no need to authenticate the type separately, since it * was used to select the cipher nonce, and hence the Poly1305 key. The * Poly1305 tag length is fixed. + * + * Challenge formation is rather tricky. We can't use Poly1305 directly + * because we need a random mask. So we proceed as follows. The challenge + * generator has a Salsa20 or ChaCha key. The sequence number is used as the + * Salsa20 message number/nonce, padded at the start with zeroes to form, + * effectively, a 64-bit big-endian integer. + * + * +--------+--------+ + * | 0 | seq | + * +--------+--------+ + * 32 32 + * + * 256 bits (32 bytes) of keystream are generated and used as a Poly1305 hash + * key r and mask s. These are then used to hash the message, and the + * resulting tag is the challenge. */ typedef struct naclbox_algs { @@ -1321,7 +1361,8 @@ static int naclbox_chaltag(bulkchal *bc, const void *m, size_t msz, poly1305_ctx pm; octet b[POLY1305_KEYSZ + POLY1305_MASKSZ]; - assert(SALSA20_NONCESZ <= sizeof(b)); + STATIC_ASSERT(SALSA20_NONCESZ <= sizeof(b), "Need more space for nonce"); + memset(b, 0, SALSA20_NONCESZ - 4); STORE32(b + SALSA20_NONCESZ - 4, seq); GC_SETIV(c->c, b); GC_ENCRYPT(c->c, 0, b, sizeof(b)); poly1305_keyinit(&pk, b, POLY1305_KEYSZ); @@ -1339,13 +1380,15 @@ static int naclbox_chalvrf(bulkchal *bc, const void *m, size_t msz, poly1305_ctx pm; octet b[POLY1305_KEYSZ + POLY1305_MASKSZ]; - assert(SALSA20_NONCESZ <= sizeof(b)); + STATIC_ASSERT(SALSA20_NONCESZ <= sizeof(b), "Need more space for nonce"); + STATIC_ASSERT(POLY1305_TAGSZ <= sizeof(b), "Need more space for tag"); + memset(b, 0, SALSA20_NONCESZ - 4); STORE32(b + SALSA20_NONCESZ - 4, seq); GC_SETIV(c->c, b); GC_ENCRYPT(c->c, 0, b, sizeof(b)); poly1305_keyinit(&pk, b, POLY1305_KEYSZ); poly1305_macinit(&pm, &pk, b + POLY1305_KEYSZ); if (msz) poly1305_hash(&pm, m, msz); - assert(POLY1305_TAGSZ <= sizeof(b)); poly1305_done(&pm, b); + poly1305_done(&pm, b); return (ct_memeq(t, b, POLY1305_TAGSZ) ? 0 : -1); }