]> git.codecow.com Git - Monocypher.git/commitdiff
chacha20_*_ctr functions now return the new ctr
authorLoup Vaillant <loup@loup-vaillant.fr>
Sat, 30 Nov 2019 23:08:08 +0000 (00:08 +0100)
committerLoup Vaillant <loup@loup-vaillant.fr>
Sat, 30 Nov 2019 23:08:08 +0000 (00:08 +0100)
This should facilitate building piecemeal streams.  Normally you'd just
increment the nonce, but in some (admittedly rare) cases we may want to
increment the counter instead.

Incrementing the counter is fairly dangerous, because we may overlap the
streams, thus revealing the XOR of two pieces of plain text. Using the
new return value makes sure this doesn't happen.

src/monocypher.c
src/monocypher.h
tests/test.c

index d1bbadbd42c3a9d0dcf97a5852923b3da4f1b6ed..2e70c61848a9f3783e8105f4d5abc160abe4440b 100644 (file)
@@ -136,8 +136,8 @@ static void chacha20_init_key(u32 block[16], const u8 key[32])
     }
 }
 
-static void chacha20_core(u32 input[16], u8 *cipher_text, const u8 *plain_text,
-                          size_t text_size)
+static u64 chacha20_core(u32 input[16], u8 *cipher_text, const u8 *plain_text,
+                         size_t text_size)
 {
     // Whole blocks
     u32    pool[16];
@@ -181,6 +181,7 @@ static void chacha20_core(u32 input[16], u8 *cipher_text, const u8 *plain_text,
         WIPE_BUFFER(tmp);
     }
     WIPE_BUFFER(pool);
+    return input[12] + ((u64)input[13] << 32) + (text_size > 0);
 }
 
 void crypto_hchacha20(u8 out[32], const u8 key[32], const u8 in [16])
@@ -200,9 +201,9 @@ void crypto_hchacha20(u8 out[32], const u8 key[32], const u8 in [16])
     WIPE_BUFFER(block);
 }
 
-void crypto_chacha20_ctr(u8 *cipher_text, const u8 *plain_text,
-                         size_t text_size, const u8 key[32], const u8 nonce[8],
-                         u64 ctr)
+u64 crypto_chacha20_ctr(u8 *cipher_text, const u8 *plain_text,
+                        size_t text_size, const u8 key[32], const u8 nonce[8],
+                        u64 ctr)
 {
     u32 input[16];
     chacha20_init_key(input, key);
@@ -210,13 +211,14 @@ void crypto_chacha20_ctr(u8 *cipher_text, const u8 *plain_text,
     input[13] = (u32)(ctr >> 32);
     input[14] = load32_le(nonce);
     input[15] = load32_le(nonce + 4);
-    chacha20_core(input, cipher_text, plain_text, text_size);
+    ctr = chacha20_core(input, cipher_text, plain_text, text_size);
     WIPE_BUFFER(input);
+    return ctr;
 }
 
-void crypto_ietf_chacha20_ctr(u8 *cipher_text, const u8 *plain_text,
-                              size_t text_size,
-                              const u8 key[32], const u8 nonce[12], u32 ctr)
+u32 crypto_ietf_chacha20_ctr(u8 *cipher_text, const u8 *plain_text,
+                             size_t text_size,
+                             const u8 key[32], const u8 nonce[12], u32 ctr)
 {
     u32 input[16];
     chacha20_init_key(input, key);
@@ -224,19 +226,21 @@ void crypto_ietf_chacha20_ctr(u8 *cipher_text, const u8 *plain_text,
     input[13] = load32_le(nonce);
     input[14] = load32_le(nonce + 4);
     input[15] = load32_le(nonce + 8);
-    chacha20_core(input, cipher_text, plain_text, text_size);
+    ctr = chacha20_core(input, cipher_text, plain_text, text_size);
     WIPE_BUFFER(input);
+    return ctr;
 }
 
-void crypto_xchacha20_ctr(u8 *cipher_text, const u8 *plain_text,
-                          size_t text_size,
-                          const u8 key[32], const u8 nonce[24], u64 ctr)
+u64 crypto_xchacha20_ctr(u8 *cipher_text, const u8 *plain_text,
+                         size_t text_size,
+                         const u8 key[32], const u8 nonce[24], u64 ctr)
 {
     u8 sub_key[32];
     crypto_hchacha20(sub_key, key, nonce);
-    crypto_chacha20_ctr(cipher_text, plain_text, text_size,
-                        sub_key, nonce+16, ctr);
+    ctr = crypto_chacha20_ctr(cipher_text, plain_text, text_size,
+                              sub_key, nonce+16, ctr);
     WIPE_BUFFER(sub_key);
+    return ctr;
 }
 
 void crypto_chacha20(u8 *cipher_text, const u8 *plain_text, size_t text_size,
index 0b9cec9d89c92e9bc7564ded355df9380cbb74a2..5378676d9a97c77cf1952dd0a59ac8693b70c952 100644 (file)
@@ -228,24 +228,24 @@ void crypto_ietf_chacha20(uint8_t       *cipher_text,
                           size_t         text_size,
                           const uint8_t  key[32],
                           const uint8_t  nonce[12]);
-void crypto_chacha20_ctr(uint8_t       *cipher_text,
-                         const uint8_t *plain_text,
-                         size_t         text_size,
-                         const uint8_t  key[32],
-                         const uint8_t  nonce[8],
-                         uint64_t       ctr);
-void crypto_xchacha20_ctr(uint8_t       *cipher_text,
-                          const uint8_t *plain_text,
-                          size_t         text_size,
-                          const uint8_t  key[32],
-                          const uint8_t  nonce[24],
-                          uint64_t       ctr);
-void crypto_ietf_chacha20_ctr(uint8_t       *cipher_text,
+uint64_t crypto_chacha20_ctr(uint8_t       *cipher_text,
+                             const uint8_t *plain_text,
+                             size_t         text_size,
+                             const uint8_t  key[32],
+                             const uint8_t  nonce[8],
+                             uint64_t       ctr);
+uint64_t crypto_xchacha20_ctr(uint8_t       *cipher_text,
                               const uint8_t *plain_text,
                               size_t         text_size,
                               const uint8_t  key[32],
-                              const uint8_t  nonce[12],
-                              uint32_t       ctr);
+                              const uint8_t  nonce[24],
+                              uint64_t       ctr);
+uint32_t crypto_ietf_chacha20_ctr(uint8_t       *cipher_text,
+                                  const uint8_t *plain_text,
+                                  size_t         text_size,
+                                  const uint8_t  key[32],
+                                  const uint8_t  nonce[12],
+                                  uint32_t       ctr);
 
 
 // Poly 1305
index 7b6dcb7b6e14ec738c20d2b57b53f4a4073c7c31..9b3b72426c1f9c07dd8b5d272f87aa05ac918025 100644 (file)
@@ -20,9 +20,13 @@ static void chacha20(const vector in[], vector *out)
     const vector *key   = in;
     const vector *nonce = in + 1;
     const vector *plain = in + 2;
-    u64 ctr = load64_le(in[3].buf);
-    crypto_chacha20_ctr(out->buf, plain->buf, plain->size,
-                        key->buf, nonce->buf, ctr);
+    u64 ctr       = load64_le(in[3].buf);
+    u64 new_ctr   = crypto_chacha20_ctr(out->buf, plain->buf, plain->size,
+                                        key->buf, nonce->buf, ctr);
+    u64 nb_blocks = plain->size / 64 + (plain->size % 64 != 0);
+    if (new_ctr - ctr != nb_blocks) {
+        printf("FAILURE: Chacha20 returned counter not correct: ");
+    }
 }
 
 static void hchacha20(const vector in[], vector *out)
@@ -37,9 +41,13 @@ static void xchacha20(const vector in[], vector *out)
     const vector *key   = in;
     const vector *nonce = in + 1;
     const vector *plain = in + 2;
-    u64 ctr = load64_le(in[3].buf);
-    crypto_xchacha20_ctr(out->buf, plain->buf, plain->size,
-                         key->buf, nonce->buf, ctr);
+    u64 ctr       = load64_le(in[3].buf);
+    u64 new_ctr   = crypto_xchacha20_ctr(out->buf, plain->buf, plain->size,
+                                         key->buf, nonce->buf, ctr);
+    u64 nb_blocks = plain->size / 64 + (plain->size % 64 != 0);
+    if (new_ctr - ctr != nb_blocks) {
+        printf("FAILURE: Chacha20 returned counter not correct: ");
+    }
 }
 
 static void poly1305(const vector in[], vector *out)