]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
New test helper test_aead_message.
authorNiels Möller <nisse@lysator.liu.se>
Sun, 12 Feb 2023 15:26:00 +0000 (16:26 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Fri, 21 Apr 2023 13:04:45 +0000 (15:04 +0200)
testsuite/ocb-test.c
testsuite/siv-gcm-test.c
testsuite/siv-test.c
testsuite/testutils.c
testsuite/testutils.h

index d377b3ec0c3ddfc078c2178a97eb3bdfc54b585f..7a952a620a1f5ed4ac00394f643ffae6be6c078a 100644 (file)
@@ -4,18 +4,18 @@
 /* FIXME: Lots of almost duplicated code with siv tests. */
 /* AEAD ciphers */
 typedef void
-nettle_encrypt_message_func(const void *ctx,
-                           size_t nlength, const uint8_t *nonce,
-                           size_t alength, const uint8_t *adata,
-                           size_t tlength,
-                           size_t clength, uint8_t *dst, const uint8_t *src);
+ocb_encrypt_message_func(const void *ctx,
+                        size_t nlength, const uint8_t *nonce,
+                        size_t alength, const uint8_t *adata,
+                        size_t tlength,
+                        size_t clength, uint8_t *dst, const uint8_t *src);
 
 typedef int
-nettle_decrypt_message_func(const void *encrypt_ctx, const void *decrypt_ctx,
-                           size_t nlength, const uint8_t *nonce,
-                           size_t alength, const uint8_t *adata,
-                           size_t tlength,
-                           size_t mlength, uint8_t *dst, const uint8_t *src);
+ocb_decrypt_message_func(const void *encrypt_ctx, const void *decrypt_ctx,
+                        size_t nlength, const uint8_t *nonce,
+                        size_t alength, const uint8_t *adata,
+                        size_t tlength,
+                        size_t mlength, uint8_t *dst, const uint8_t *src);
 
 static void
 test_compare_results(const char *name,
@@ -59,8 +59,8 @@ static void
 test_ocb_message(const char *name,
                 nettle_set_key_func *set_encrypt_key,
                 nettle_set_key_func *set_decrypt_key,
-                nettle_encrypt_message_func *encrypt,
-                nettle_decrypt_message_func *decrypt,
+                ocb_encrypt_message_func *encrypt,
+                ocb_decrypt_message_func *decrypt,
                 size_t encrypt_context_size, size_t decrypt_context_size,
                 size_t key_size, size_t digest_size,
                 const struct tstring *key,
@@ -138,8 +138,8 @@ test_ocb_message(const char *name,
   test_ocb_message("ocb_aes128",                                       \
                   (nettle_set_key_func*)ocb_aes128_set_encrypt_key,    \
                   (nettle_set_key_func*)aes128_set_decrypt_key,        \
-                  (nettle_encrypt_message_func*)ocb_aes128_encrypt_message, \
-                  (nettle_decrypt_message_func*)ocb_aes128_decrypt_message, \
+                  (ocb_encrypt_message_func*)ocb_aes128_encrypt_message, \
+                  (ocb_decrypt_message_func*)ocb_aes128_decrypt_message, \
                   sizeof(struct ocb_aes128_ctx), sizeof(struct aes128_ctx), \
                   AES128_KEY_SIZE, OCB_DIGEST_SIZE,                    \
                   key, nonce, authdata, cleartext, ciphertext)
index eba03f231aab51d1cac9c8826c585ef68a1f6669..6b697443676184d5426b2e97eb31afe20606b5de 100644 (file)
 #include "aes.h"
 #include "siv-gcm.h"
 
-/* AEAD ciphers */
-typedef void
-nettle_encrypt_message_func(void *ctx,
-                           size_t nlength, const uint8_t *nonce,
-                           size_t alength, const uint8_t *adata,
-                           size_t clength, uint8_t *dst, const uint8_t *src);
-
-typedef int
-nettle_decrypt_message_func(void *ctx,
-                           size_t nlength, const uint8_t *nonce,
-                           size_t alength, const uint8_t *adata,
-                           size_t mlength, uint8_t *dst, const uint8_t *src);
-
 static void
 test_compare_results (const char *name,
                      const struct tstring *adata,
index 64f1ac5d7668e1b3011078a97a72bc3044d0886f..3d2ec8654bc236dd3b0a59f9a73f53ef198b4fa9 100644 (file)
 #include "siv-cmac.h"
 #include "knuth-lfib.h"
 
-/* AEAD ciphers */
-typedef void
-nettle_encrypt_message_func(void *ctx,
-                           size_t nlength, const uint8_t *nonce,
-                           size_t alength, const uint8_t *adata,
-                           size_t clength, uint8_t *dst, const uint8_t *src);
-
-typedef int
-nettle_decrypt_message_func(void *ctx,
-                           size_t nlength, const uint8_t *nonce,
-                           size_t alength, const uint8_t *adata,
-                           size_t mlength, uint8_t *dst, const uint8_t *src);
-
-static void
-test_compare_results(const char *name,
-        const struct tstring *adata,
-        /* Expected results. */
-        const struct tstring *e_clear,
-       const struct tstring *e_cipher,
-        /* Actual results. */
-        const void *clear,
-        const void *cipher)
-{
-  if (!MEMEQ(e_cipher->length, e_cipher->data, cipher))
-    {
-      fprintf(stderr, "%s: encryption failed\nAdata: ", name);
-      tstring_print_hex(adata);
-      fprintf(stderr, "\nInput: ");
-      tstring_print_hex(e_clear);
-      fprintf(stderr, "\nOutput: ");
-      print_hex(e_cipher->length, cipher);
-      fprintf(stderr, "\nExpected:");
-      tstring_print_hex(e_cipher);
-      fprintf(stderr, "\n");
-      FAIL();
-    }
-  if (!MEMEQ(e_clear->length, e_clear->data, clear))
-    {
-      fprintf(stderr, "%s decrypt failed:\nAdata:", name);
-      tstring_print_hex(adata);
-      fprintf(stderr, "\nInput: ");
-      tstring_print_hex(e_cipher);
-      fprintf(stderr, "\nOutput: ");
-      print_hex(e_clear->length, clear);
-      fprintf(stderr, "\nExpected:");
-      tstring_print_hex(e_clear);
-      fprintf(stderr, "\n");
-      FAIL();
-    }
-} /* test_compare_results */
-
-static void
-test_cipher_siv(const char *name,
-               nettle_set_key_func *siv_set_key,
-               nettle_encrypt_message_func *siv_encrypt,
-               nettle_decrypt_message_func *siv_decrypt,
-               size_t context_size, size_t key_size,
-               const struct tstring *key,
-               const struct tstring *nonce,
-               const struct tstring *authdata,
-               const struct tstring *cleartext,
-               const struct tstring *ciphertext)
-{
-  void *ctx = xalloc(context_size);
-  uint8_t *en_data;
-  uint8_t *de_data;
-  int ret;
-
-  ASSERT (key->length == key_size);
-  ASSERT (cleartext->length + SIV_DIGEST_SIZE == ciphertext->length);
-
-  de_data = xalloc(cleartext->length);
-  en_data = xalloc(ciphertext->length);
-
-  /* Ensure we get the same answers using the all-in-one API. */
-  memset(de_data, 0, cleartext->length);
-  memset(en_data, 0, ciphertext->length);
-
-  siv_set_key(ctx, key->data);
-  siv_encrypt(ctx, nonce->length, nonce->data,
-             authdata->length, authdata->data,
-             ciphertext->length, en_data, cleartext->data);
-
-  ret = siv_decrypt(ctx, nonce->length, nonce->data,
-                   authdata->length, authdata->data,
-                   cleartext->length, de_data, ciphertext->data);
-
-  if (ret != 1)
-    {
-      fprintf(stderr, "siv_decrypt_message failed to validate message\n");
-      FAIL();
-    }
-  test_compare_results(name, authdata,
-                      cleartext, ciphertext, de_data, en_data);
-
-  /* Ensure that we can detect corrupted message or tag data. */
-  en_data[0] ^= 1;
-  ret = siv_decrypt(ctx, nonce->length, nonce->data,
-                   authdata->length, authdata->data,
-                   cleartext->length, de_data, en_data);
-  if (ret != 0)
-    {
-      fprintf(stderr, "siv_decrypt_message failed to detect corrupted message\n");
-      FAIL();
-    }
-
-  /* Ensure we can detect corrupted adata. */
-  if (authdata->length) {
-    en_data[0] ^= 1;
-    ret = siv_decrypt(ctx, nonce->length, nonce->data,
-                     authdata->length-1, authdata->data,
-                     cleartext->length, de_data, en_data);
-    if (ret != 0)
-      {
-       fprintf(stderr, "siv_decrypt_message failed to detect corrupted message\n");
-       FAIL();
-      }
-  }
-
-  free(ctx);
-  free(en_data);
-  free(de_data);
-}
-
-#define test_siv_aes128(name, key, nonce, authdata, cleartext, ciphertext) \
-  test_cipher_siv(name, (nettle_set_key_func*)siv_cmac_aes128_set_key, \
-                 (nettle_encrypt_message_func*)siv_cmac_aes128_encrypt_message, \
-                 (nettle_decrypt_message_func*)siv_cmac_aes128_decrypt_message, \
-                 sizeof(struct siv_cmac_aes128_ctx), SIV_CMAC_AES128_KEY_SIZE, \
-                 key, nonce, authdata, cleartext, ciphertext)
-
-#define test_siv_aes256(name, key, nonce, authdata, cleartext, ciphertext) \
-  test_cipher_siv(name, (nettle_set_key_func*)siv_cmac_aes256_set_key, \
-                 (nettle_encrypt_message_func*)siv_cmac_aes256_encrypt_message, \
-                 (nettle_decrypt_message_func*)siv_cmac_aes256_decrypt_message, \
-                 sizeof(struct siv_cmac_aes256_ctx), SIV_CMAC_AES256_KEY_SIZE, \
-                 key, nonce, authdata, cleartext, ciphertext)
+static const struct nettle_aead_message
+siv_cmac_aes128 = {
+  "siv_cmac_aes128",
+  sizeof(struct siv_cmac_aes128_ctx),
+  SIV_CMAC_AES128_KEY_SIZE,
+  SIV_DIGEST_SIZE,
+  (nettle_set_key_func*) siv_cmac_aes128_set_key,
+  (nettle_set_key_func*) siv_cmac_aes128_set_key,
+  (nettle_encrypt_message_func*) siv_cmac_aes128_encrypt_message,
+  (nettle_decrypt_message_func*) siv_cmac_aes128_decrypt_message,
+};
+
+static const struct nettle_aead_message
+siv_cmac_aes256 = {
+  "siv_cmac_aes256",
+  sizeof(struct siv_cmac_aes256_ctx),
+  SIV_CMAC_AES256_KEY_SIZE,
+  SIV_DIGEST_SIZE,
+  (nettle_set_key_func*) siv_cmac_aes256_set_key,
+  (nettle_set_key_func*) siv_cmac_aes256_set_key,
+  (nettle_encrypt_message_func*) siv_cmac_aes256_encrypt_message,
+  (nettle_decrypt_message_func*) siv_cmac_aes256_decrypt_message,
+};
 
 void
 test_main(void)
@@ -188,7 +74,7 @@ test_main(void)
   /*
    * Example with small nonce, no AD and no plaintext
    */
-  test_siv_aes128("SIV_CMAC_AES128",
+  test_aead_message(&siv_cmac_aes128,
                  SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0"
                       "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"),
                  SHEX("01"),
@@ -198,7 +84,7 @@ test_main(void)
   /*
    * Example with small nonce, no AD and plaintext
    */
-  test_siv_aes128("SIV_CMAC_AES128",
+  test_aead_message(&siv_cmac_aes128,
                  SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0"
                       "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"),
                  SHEX("02"),
@@ -210,7 +96,7 @@ test_main(void)
   /*
    * Example with length < 16
    */
-  test_siv_aes128("SIV_CMAC_AES128",
+  test_aead_message(&siv_cmac_aes128,
                  SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0"
                       "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"),
                  SHEX("02"),
@@ -223,7 +109,7 @@ test_main(void)
   /*
    * Example with length > 16
    */
-  test_siv_aes128("SIV_CMAC_AES128",
+  test_aead_message(&siv_cmac_aes128,
                  SHEX("7f7e7d7c 7b7a7978 77767574 73727170"
                       "40414243 44454647 48494a4b 4c4d4e4f"),
                  SHEX("020304"),
@@ -241,7 +127,7 @@ test_main(void)
   /*
    * Example with single AAD, length > 16
    */
-  test_siv_aes128("SIV_CMAC_AES128",
+  test_aead_message(&siv_cmac_aes128,
                  SHEX("7f7e7d7c 7b7a7978 77767574 73727170"
                       "40414243 44454647 48494a4b 4c4d4e4f"),
                  SHEX("09f91102 9d74e35b d84156c5 635688c0"),
@@ -259,7 +145,7 @@ test_main(void)
   /*
    * Example with single AAD, length < 16
    */
-  test_siv_aes128("SIV_CMAC_AES128",
+  test_aead_message(&siv_cmac_aes128,
                  SHEX("7f7e7d7c 7b7a7978 77767574 73727170"
                       "40414243 44454647 48494a4b 4c4d4e4f"),
                  SHEX("09f91102 9d74e35b d84156c5 635688c0"),
@@ -272,7 +158,7 @@ test_main(void)
 
   /* AES-SIV-CMAC-512 (AES-256) from dchest/siv repo
    */
-  test_siv_aes256("SIV_CMAC_AES256",
+  test_aead_message(&siv_cmac_aes256,
                  SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0"
                       "6f6e6d6c 6b6a6968 67666564 63626160"
                       "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"
@@ -287,7 +173,7 @@ test_main(void)
 
   /* AES-SIV-CMAC-512 (AES-256)
    */
-  test_siv_aes256("SIV_CMAC_AES256",
+  test_aead_message(&siv_cmac_aes256,
                  SHEX("c27df2fd aec35d4a 2a412a50 c3e8c47d"
                       "2d568e91 a38e5414 8abdc0b6 e86caf87"
                       "695c0a8a df4c5f8e b2c6c8b1 36529864"
@@ -302,7 +188,7 @@ test_main(void)
   /*
    * Example with length > 16
    */
-  test_siv_aes256("SIV_CMAC_AES256",
+  test_aead_message(&siv_cmac_aes256,
                  SHEX("c27df2fd aec35d4a 2a412a50 c3e8c47d"
                       "2d568e91 a38e5414 8abdc0b6 e86caf87"
                       "695c0a8a df4c5f8e b2c6c8b1 36529864"
@@ -322,7 +208,7 @@ test_main(void)
   /*
    * Example with single AAD, length > 16
    */
-  test_siv_aes256("SIV_CMAC_AES256",
+  test_aead_message(&siv_cmac_aes256,
                  SHEX("c27df2fd aec35d4a 2a412a50 c3e8c47d"
                       "2d568e91 a38e5414 8abdc0b6 e86caf87"
                       "695c0a8a df4c5f8e b2c6c8b1 36529864"
@@ -345,7 +231,7 @@ test_main(void)
    * Example from miscreant.js with no AD
    * https://github.com/miscreant/miscreant.js/blob/master/vectors/aes_siv_aead.tjson
    */
-  test_siv_aes128("SIV_CMAC_AES128",
+  test_aead_message(&siv_cmac_aes128,
                  SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0"
                       "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"),
                  SHEX("10111213 1415161718191a1b1 c1d1e1f2"
@@ -358,7 +244,7 @@ test_main(void)
   /*
    * Example from miscreant.js with AD
    */
-  test_siv_aes128("SIV_CMAC_AES128",
+  test_aead_message(&siv_cmac_aes128,
                  SHEX("7f7e7d7c 7b7a7978 77767574 73727170"
                       "40414243 44454647 48494a4b 4c4d4e4f"),
                  SHEX("09f91102 9d74e35b d84156c5 635688c0"),
index 391f7b588f893a71388daef0878de023ed3b2f2e..74059c5357d334bc92cf3747136f231b72a4a5b3 100644 (file)
@@ -907,6 +907,127 @@ test_aead(const struct nettle_aead *aead,
   free(buffer);
 }
 
+void
+test_aead_message (const struct nettle_aead_message *aead,
+                  const struct tstring *key,
+                  const struct tstring *nonce,
+                  const struct tstring *adata,
+                  const struct tstring *clear,
+                  const struct tstring *cipher)
+{
+  void *ctx = xalloc (aead->context_size);
+  uint8_t *buf = xalloc (cipher->length + 1);
+  int res;
+
+  ASSERT (key->length == aead->key_size);
+  ASSERT (cipher->length > clear->length);
+  ASSERT (cipher->length - clear->length == aead->digest_size);
+
+  aead->set_encrypt_key (ctx, key->data);
+  buf[cipher->length] = 0xae;
+  aead->encrypt (ctx,
+                nonce->length, nonce->data,
+                adata->length, adata->data,
+                cipher->length, buf, clear->data);
+  if (!MEMEQ (cipher->length, cipher->data, buf))
+    {
+      fprintf(stderr, "aead->encrypt (message) failed:\n  got: ");
+      print_hex (cipher->length, buf);
+      fprintf (stderr, "  exp: ");
+      tstring_print_hex (cipher);
+      FAIL();
+    }
+  if (buf[cipher->length] != 0xae)
+    {
+      fprintf (stderr, "aead->encrypt (message) wrote too much.\n ");
+      FAIL();
+    }
+  aead->set_decrypt_key (ctx, key->data);
+#if 0
+  /* First try in-place decrypt. FIXME: Not supported for SIV. */
+  res = aead->decrypt (ctx,
+                      nonce->length, nonce->data,
+                      adata->length, adata->data,
+                      clear->length, buf, buf);
+  if (!res)
+    {
+      fprintf (stderr, "in-place decrypting valid ciphertext failed:\n  ");
+      tstring_print_hex (cipher);
+    }
+  if (!MEMEQ (clear->length, clear->data, buf))
+    {
+      fprintf(stderr, "aead->decrypt (in place message) failed:\n  got: ");
+      print_hex (clear->length, buf);
+      fprintf (stderr, "  exp: ");
+      tstring_print_hex (clear);
+      FAIL();
+    }
+#endif
+  memset (buf, 0xae, clear->length + 1);
+
+  res = aead->decrypt (ctx,
+                      nonce->length, nonce->data,
+                      adata->length, adata->data,
+                      clear->length, buf, cipher->data);
+  if (!res)
+    {
+      fprintf (stderr, "decrypting valid ciphertext failed:\n  ");
+      tstring_print_hex (cipher);
+    }
+  if (!MEMEQ (clear->length, clear->data, buf))
+    {
+      fprintf(stderr, "aead->decrypt (message) failed:\n  got: ");
+      print_hex (clear->length, buf);
+      fprintf (stderr, "  exp: ");
+      tstring_print_hex (clear);
+      FAIL();
+    }
+
+  /* Invalid messages */
+  if (clear->length > 0
+      && aead->decrypt (ctx,
+                       nonce->length, nonce->data,
+                       adata->length, adata->data,
+                       clear->length - 1, buf, cipher->data))
+    {
+      fprintf (stderr, "Invalid message (truncated) not rejected\n");
+      FAIL();
+    }
+  memcpy (buf, cipher->data, cipher->length);
+  buf[0] ^= 4;
+  if (aead->decrypt (ctx,
+                    nonce->length, nonce->data,
+                    adata->length, adata->data,
+                    clear->length, buf, buf))
+    {
+      fprintf (stderr, "Invalid message (first byte modified) not rejected\n");
+      FAIL();
+    }
+
+  memcpy (buf, cipher->data, cipher->length);
+  buf[cipher->length - 1] ^= 4;
+  if (aead->decrypt (ctx,
+                    nonce->length, nonce->data,
+                    adata->length, adata->data,
+                    clear->length, buf, buf))
+    {
+      fprintf (stderr, "Invalid message (last byte modified) not rejected\n");
+      FAIL();
+    }
+
+  memcpy (buf, adata->data, adata->length);
+  if (adata->length == 0)
+    buf[0] = 0;
+  if (aead->decrypt (ctx,
+                    nonce->length, nonce->data,
+                    adata->length ? adata->length /* - 1 */ : 1, buf,
+                    clear->length, buf, cipher->data))
+    {
+      fprintf (stderr, "Invalid adata not rejected\n");
+      FAIL();
+    }
+}
+
 void
 test_hash(const struct nettle_hash *hash,
          const struct tstring *msg,
index 00555b3a60accaa59b44d7e14baf40c6547c15aa..7606cc3a5015da15debbde94f8c7d1f8e997cdbf 100644 (file)
@@ -37,9 +37,6 @@
 
 #include "nettle-meta.h"
 
-/* Forward declare */
-struct nettle_aead;
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -82,7 +79,30 @@ test_main(void);
 
 extern int verbose;
 
-/* Test functions deallocate their inputs when finished.*/
+typedef void
+nettle_encrypt_message_func(void *ctx,
+                           size_t nlength, const uint8_t *nonce,
+                           size_t alength, const uint8_t *adata,
+                           size_t clength, uint8_t *dst, const uint8_t *src);
+
+typedef int
+nettle_decrypt_message_func(void *ctx,
+                           size_t nlength, const uint8_t *nonce,
+                           size_t alength, const uint8_t *adata,
+                           size_t mlength, uint8_t *dst, const uint8_t *src);
+
+struct nettle_aead_message
+{
+  const char *name;
+  unsigned context_size;
+  unsigned key_size;
+  unsigned digest_size;
+  nettle_set_key_func *set_encrypt_key;
+  nettle_set_key_func *set_decrypt_key;
+  nettle_encrypt_message_func *encrypt;
+  nettle_decrypt_message_func *decrypt;
+};
+
 void
 test_cipher(const struct nettle_cipher *cipher,
            const struct tstring *key,
@@ -133,6 +153,14 @@ test_aead(const struct nettle_aead *aead,
          const struct tstring *nonce,
          const struct tstring *digest);
 
+void
+test_aead_message(const struct nettle_aead_message *aead,
+                 const struct tstring *key,
+                 const struct tstring *adata,
+                 const struct tstring *nonce,
+                 const struct tstring *clear,
+                 const struct tstring *cipher);
+
 void
 test_hash(const struct nettle_hash *hash,
          const struct tstring *msg,