]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Add specialized functions for cbc-aes.
authorNiels Möller <nisse@lysator.liu.se>
Wed, 8 Sep 2021 19:30:43 +0000 (21:30 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Thu, 9 Sep 2021 15:54:32 +0000 (17:54 +0200)
ChangeLog
Makefile.in
cbc-aes128-encrypt.c [new file with mode: 0644]
cbc-aes192-encrypt.c [new file with mode: 0644]
cbc-aes256-encrypt.c [new file with mode: 0644]
cbc.h
examples/nettle-benchmark.c
nettle-internal.c
nettle-internal.h
testsuite/cbc-test.c
testsuite/testutils.c

index e59aa4c7f5a0a65d8a9b33979b946e7ed24ef6f1..e6f95784736c3a2f0b8771bac1b6a2591c8112de 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2021-09-08  Niels Möller  <nisse@lysator.liu.se>
+
+       * cbc-aes128-encrypt.c (nettle_cbc_aes128_encrypt): New file and
+       function.
+       * cbc-aes192-encrypt.c (cbc_aes192_set_encrypt_key): New file.
+       * cbc-aes256-encrypt.c (cbc_aes256_set_encrypt_key): New file.
+       * cbc.h (cbc_aes128_ctx, struct cbc_aes192_ctx, cbc_aes256_ctx):
+       New context structs. Declare new functions.
+       * Makefile.in (nettle_SOURCES): Add new files.
+       * nettle-internal.c (nettle_cbc_aes128, nettle_cbc_aes192)
+       (nettle_cbc_aes256): New algorithm structs, for tests and
+       benchmarking.
+       * testsuite/testutils.c (test_aead): Skip tests of decryption and
+       authentication, if corresponding function pointers are NULL.
+       * testsuite/cbc-test.c (test_main): Add tests of new cbc
+       functions.
+       * examples/nettle-benchmark.c (time_aead): Skip decrypt benchmark,
+       if corresponding function pointer is NULL.
+
 2021-08-16  Niels Möller  <nisse@lysator.liu.se>
 
        S390x functions for sha1, sha256 and sha512, from Mamone Tarsha:
index fe2de5a87f0f04af3cc78666c87a5efb9fd7eef2..2edafd679710e7de78c3eb9e02dc26635ecea8aa 100644 (file)
@@ -102,7 +102,8 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c aes-decrypt-table.c \
                 camellia256-set-encrypt-key.c camellia256-crypt.c \
                 camellia256-set-decrypt-key.c \
                 camellia256-meta.c \
-                cast128.c cast128-meta.c cbc.c \
+                cast128.c cast128-meta.c \
+                cbc.c cbc-aes128-encrypt.c cbc-aes192-encrypt.c cbc-aes256-encrypt.c \
                 ccm.c ccm-aes128.c ccm-aes192.c ccm-aes256.c cfb.c \
                 siv-cmac.c siv-cmac-aes128.c siv-cmac-aes256.c \
                 cnd-memcpy.c \
diff --git a/cbc-aes128-encrypt.c b/cbc-aes128-encrypt.c
new file mode 100644 (file)
index 0000000..7b86645
--- /dev/null
@@ -0,0 +1,42 @@
+/* cbc-aes128-encrypt.c
+
+   Copyright (C) 2021 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "cbc.h"
+
+void
+cbc_aes128_encrypt(struct cbc_aes128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+{
+  CBC_ENCRYPT(ctx, aes128_encrypt, length, dst, src);
+}
diff --git a/cbc-aes192-encrypt.c b/cbc-aes192-encrypt.c
new file mode 100644 (file)
index 0000000..6226e36
--- /dev/null
@@ -0,0 +1,42 @@
+/* cbc-aes192-encrypt.c
+
+   Copyright (C) 2021 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "cbc.h"
+
+void
+cbc_aes192_encrypt(struct cbc_aes192_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+{
+  CBC_ENCRYPT(ctx, aes192_encrypt, length, dst, src);
+}
diff --git a/cbc-aes256-encrypt.c b/cbc-aes256-encrypt.c
new file mode 100644 (file)
index 0000000..49240b3
--- /dev/null
@@ -0,0 +1,42 @@
+/* cbc-aes256-encrypt.c
+
+   Copyright (C) 2021 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "cbc.h"
+
+void
+cbc_aes256_encrypt(struct cbc_aes256_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+{
+  CBC_ENCRYPT(ctx, aes256_encrypt, length, dst, src);
+}
diff --git a/cbc.h b/cbc.h
index 93b2e73900b67509390e00acfdbe5ec55094aad9..5fa670f3c5fa39c8b6c42baccdd653f262dc476a 100644 (file)
--- a/cbc.h
+++ b/cbc.h
@@ -35,6 +35,7 @@
 #define NETTLE_CBC_H_INCLUDED
 
 #include "nettle-types.h"
+#include "aes.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -43,6 +44,9 @@ extern "C" {
 /* Name mangling */
 #define cbc_encrypt nettle_cbc_encrypt
 #define cbc_decrypt nettle_cbc_decrypt
+#define cbc_aes128_encrypt nettle_cbc_aes128_encrypt
+#define cbc_aes192_encrypt nettle_cbc_aes192_encrypt
+#define cbc_aes256_encrypt nettle_cbc_aes256_encrypt
 
 void
 cbc_encrypt(const void *ctx, nettle_cipher_func *f,
@@ -79,6 +83,18 @@ memcpy((ctx)->iv, (data), sizeof((ctx)->iv))
                 sizeof((self)->iv), (self)->iv,        \
                 (length), (dst), (src)))
 
+struct cbc_aes128_ctx CBC_CTX(struct aes128_ctx, AES_BLOCK_SIZE);
+void
+cbc_aes128_encrypt(struct cbc_aes128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src);
+
+struct cbc_aes192_ctx CBC_CTX(struct aes192_ctx, AES_BLOCK_SIZE);
+void
+cbc_aes192_encrypt(struct cbc_aes192_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src);
+
+struct cbc_aes256_ctx CBC_CTX(struct aes256_ctx, AES_BLOCK_SIZE);
+void
+cbc_aes256_encrypt(struct cbc_aes256_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src);
+
 #ifdef __cplusplus
 }
 #endif
index 9ce3a733a0f094b31e2acf5ee2e61c22fad02c8b..50a5815adf7f64c69596fa3d2a5770bf42ce3176 100644 (file)
@@ -769,21 +769,22 @@ time_aead(const struct nettle_aead *aead)
     display(aead->name, "encrypt", aead->block_size,
            time_function(bench_aead_crypt, &info));
   }
-  
-  {
-    struct bench_aead_info info;
-    info.ctx = ctx;
-    info.crypt = aead->decrypt;
-    info.data = data;
+
+  if (aead->decrypt)
+    {
+      struct bench_aead_info info;
+      info.ctx = ctx;
+      info.crypt = aead->decrypt;
+      info.data = data;
     
-    init_key(aead->key_size, key);
-    aead->set_decrypt_key(ctx, key);
-    if (aead->set_nonce)
-      aead->set_nonce (ctx, nonce);
+      init_key(aead->key_size, key);
+      aead->set_decrypt_key(ctx, key);
+      if (aead->set_nonce)
+       aead->set_nonce (ctx, nonce);
 
-    display(aead->name, "decrypt", aead->block_size,
-           time_function(bench_aead_crypt, &info));
-  }
+      display(aead->name, "decrypt", aead->block_size,
+             time_function(bench_aead_crypt, &info));
+    }
 
   if (aead->update)
     {
@@ -933,6 +934,8 @@ main(int argc, char **argv)
       /* Stream ciphers */
       &nettle_arcfour128,
       &nettle_salsa20, &nettle_salsa20r12, &nettle_chacha,
+      /* CBC encrypt */
+      &nettle_cbc_aes128, &nettle_cbc_aes192, &nettle_cbc_aes256,
       /* Proper AEAD algorithme. */
       &nettle_gcm_aes128,
       &nettle_gcm_aes192,
index 2a809472636878e89a81333faeba461ccdb590be..e2422a5b2baed4c77c34f8c4fa073a27e4fc7710 100644 (file)
 
 #include <assert.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "nettle-internal.h"
 #include "arcfour.h"
 #include "blowfish.h"
-#include "des.h"
+#include "cbc.h"
 #include "chacha.h"
+#include "des.h"
 #include "salsa20.h"
 
 /* Wrapper functions discarding the return value. Needed for the
@@ -149,3 +151,75 @@ nettle_salsa20r12 = {
   (nettle_crypt_func *) salsa20r12_crypt,
   NULL,
 };
+
+static void
+cbc_aes128_set_encrypt_key(struct cbc_aes128_ctx *ctx, const uint8_t *key)
+{
+  aes128_set_encrypt_key(&ctx->ctx, key);
+}
+static void
+cbc_aes128_set_iv(struct cbc_aes128_ctx *ctx, const uint8_t *iv)
+{
+  CBC_SET_IV(ctx, iv);
+}
+const struct nettle_aead
+nettle_cbc_aes128 = {
+  "cbc_aes128", sizeof(struct cbc_aes128_ctx),
+  AES_BLOCK_SIZE, AES128_KEY_SIZE,
+  AES_BLOCK_SIZE, 0,
+  (nettle_set_key_func*) cbc_aes128_set_encrypt_key,
+  NULL,
+  (nettle_set_key_func*) cbc_aes128_set_iv,
+  NULL,
+  (nettle_crypt_func *) cbc_aes128_encrypt,
+  NULL,
+  NULL,
+};
+
+static void
+cbc_aes192_set_encrypt_key(struct cbc_aes192_ctx *ctx, const uint8_t *key)
+{
+  aes192_set_encrypt_key(&ctx->ctx, key);
+}
+static void
+cbc_aes192_set_iv(struct cbc_aes192_ctx *ctx, const uint8_t *iv)
+{
+  CBC_SET_IV(ctx, iv);
+}
+const struct nettle_aead
+nettle_cbc_aes192 = {
+  "cbc_aes192", sizeof(struct cbc_aes192_ctx),
+  AES_BLOCK_SIZE, AES192_KEY_SIZE,
+  AES_BLOCK_SIZE, 0,
+  (nettle_set_key_func*) cbc_aes192_set_encrypt_key,
+  NULL,
+  (nettle_set_key_func*) cbc_aes192_set_iv,
+  NULL,
+  (nettle_crypt_func *) cbc_aes192_encrypt,
+  NULL,
+  NULL,
+};
+
+static void
+cbc_aes256_set_encrypt_key(struct cbc_aes256_ctx *ctx, const uint8_t *key)
+{
+  aes256_set_encrypt_key(&ctx->ctx, key);
+}
+static void
+cbc_aes256_set_iv(struct cbc_aes256_ctx *ctx, const uint8_t *iv)
+{
+  CBC_SET_IV(ctx, iv);
+}
+const struct nettle_aead
+nettle_cbc_aes256 = {
+  "cbc_aes256", sizeof(struct cbc_aes256_ctx),
+  AES_BLOCK_SIZE, AES256_KEY_SIZE,
+  AES_BLOCK_SIZE, 0,
+  (nettle_set_key_func*) cbc_aes256_set_encrypt_key,
+  NULL,
+  (nettle_set_key_func*) cbc_aes256_set_iv,
+  NULL,
+  (nettle_crypt_func *) cbc_aes256_encrypt,
+  NULL,
+  NULL,
+};
index 9203a2322906428b84887a62bc361c95dcace71b..ddc483de23441ed4fda4451ef1f14452b5e43c3b 100644 (file)
@@ -97,10 +97,18 @@ extern const struct nettle_aead nettle_arcfour128;
 extern const struct nettle_aead nettle_chacha;
 extern const struct nettle_aead nettle_salsa20;
 extern const struct nettle_aead nettle_salsa20r12;
+
+/* All-in-one CBC encrypt fucntinos treated as AEAD with no
+   authentication and no decrypt method. */
+extern const struct nettle_aead nettle_cbc_aes128;
+extern const struct nettle_aead nettle_cbc_aes192;
+extern const struct nettle_aead nettle_cbc_aes256;
+
 extern const struct nettle_aead nettle_openssl_gcm_aes128;
 extern const struct nettle_aead nettle_openssl_gcm_aes192;
 extern const struct nettle_aead nettle_openssl_gcm_aes256;
 
+
 /* Glue to openssl, for comparative benchmarking. Code in
  * examples/nettle-openssl.c. */
 extern void nettle_openssl_init(void);
index 9394f1cb094c49aadb913ce9a571f1ec52ceeebe..d83b108b923bde59bce392c6bc243d8b1cffdda3 100644 (file)
@@ -2,6 +2,7 @@
 #include "aes.h"
 #include "cbc.h"
 #include "knuth-lfib.h"
+#include "nettle-internal.h"
 
 /* Test with more data and inplace decryption, to check that the
  * cbc_decrypt buffering works. */
@@ -114,6 +115,20 @@ test_main(void)
                       "73bed6b8e3c1743b7116e69e22229516"
                       "3ff1caa1681fac09120eca307586e1a7"),
                  SHEX("000102030405060708090a0b0c0d0e0f"));
+
+  test_aead(&nettle_cbc_aes128, NULL,
+           SHEX("2b7e151628aed2a6abf7158809cf4f3c"),
+           NULL,
+           SHEX("6bc1bee22e409f96e93d7e117393172a"
+                "ae2d8a571e03ac9c9eb76fac45af8e51"
+                "30c81c46a35ce411e5fbc1191a0a52ef"
+                "f69f2445df4f9b17ad2b417be66c3710"),
+           SHEX("7649abac8119b246cee98e9b12e9197d"
+                "5086cb9b507219ee95db113a917678b2"
+                "73bed6b8e3c1743b7116e69e22229516"
+                "3ff1caa1681fac09120eca307586e1a7"),
+           SHEX("000102030405060708090a0b0c0d0e0f"),
+           NULL);
   
   /* F.2.3 CBC-AES192.Encrypt */
   
@@ -137,6 +152,21 @@ test_main(void)
                       "571b242012fb7ae07fa9baac3df102e0"
                       "08b0e27988598881d920a9e64f5615cd"),
                  SHEX("000102030405060708090a0b0c0d0e0f"));
+
+  test_aead(&nettle_cbc_aes192, NULL,
+           SHEX("8e73b0f7da0e6452c810f32b809079e5"
+                "62f8ead2522c6b7b"),
+           NULL,
+           SHEX("6bc1bee22e409f96e93d7e117393172a"
+                "ae2d8a571e03ac9c9eb76fac45af8e51"
+                "30c81c46a35ce411e5fbc1191a0a52ef"
+                "f69f2445df4f9b17ad2b417be66c3710"),
+           SHEX("4f021db243bc633d7178183a9fa071e8"
+                "b4d9ada9ad7dedf4e5e738763f69145a"
+                "571b242012fb7ae07fa9baac3df102e0"
+                "08b0e27988598881d920a9e64f5615cd"),
+           SHEX("000102030405060708090a0b0c0d0e0f"),
+           NULL);
    
   /* F.2.5 CBC-AES256.Encrypt */
 
@@ -161,6 +191,21 @@ test_main(void)
                       "b2eb05e2c39be9fcda6c19078c6a9d1b"),
                  SHEX("000102030405060708090a0b0c0d0e0f"));
 
+  test_aead(&nettle_cbc_aes256, NULL,
+           SHEX("603deb1015ca71be2b73aef0857d7781"
+                "1f352c073b6108d72d9810a30914dff4"),
+           NULL,
+           SHEX("6bc1bee22e409f96e93d7e117393172a"
+                "ae2d8a571e03ac9c9eb76fac45af8e51"
+                "30c81c46a35ce411e5fbc1191a0a52ef"
+                "f69f2445df4f9b17ad2b417be66c3710"),
+           SHEX("f58c4c04d6e5f1ba779eabfb5f7bfbd6"
+                "9cfc4e967edb808d679f777bc6702c7d"
+                "39f23369a9d9bacfa530e26304231461"
+                "b2eb05e2c39be9fcda6c19078c6a9d1b"),
+           SHEX("000102030405060708090a0b0c0d0e0f"),
+           NULL);
+
   test_cbc_bulk();
 }
 
index 2c6cac409359c4d99c8cf6447d0678676e9bfe6a..b46a6abf9656cd8625c0d568641b9e087b79cd0c 100644 (file)
@@ -804,7 +804,6 @@ test_aead(const struct nettle_aead *aead,
   length = cleartext->length;
 
   ASSERT (key->length == aead->key_size);
-  ASSERT (digest->length <= aead->digest_size);
 
   data = xalloc(length);
   
@@ -820,41 +819,49 @@ test_aead(const struct nettle_aead *aead,
   else
     aead->set_nonce(ctx, nonce->data);
 
-  if (authtext->length)
+  if (aead->update && authtext->length)
     aead->update(ctx, authtext->length, authtext->data);
-    
+
   if (length)
     aead->encrypt(ctx, length, data, cleartext->data);
 
-  aead->digest(ctx, digest->length, buffer);
+  if (digest)
+    {
+      ASSERT (digest->length <= aead->digest_size);
+      aead->digest(ctx, digest->length, buffer);
+      ASSERT(MEMEQ(digest->length, buffer, digest->data));
+    }
+  else
+    ASSERT(!aead->digest);
 
   ASSERT(MEMEQ(length, data, ciphertext->data));
-  ASSERT(MEMEQ(digest->length, buffer, digest->data));
 
   /* decryption */
-  memset(buffer, 0, aead->digest_size);
+  if (aead->set_decrypt_key)
+    {
+      memset(buffer, 0, aead->digest_size);
 
-  aead->set_decrypt_key(ctx, key->data);
+      aead->set_decrypt_key(ctx, key->data);
 
-  if (nonce->length != aead->nonce_size)
-    {
-      ASSERT (set_nonce);
-      set_nonce (ctx, nonce->length, nonce->data);
-    }
-  else
-    aead->set_nonce(ctx, nonce->data);
+      if (nonce->length != aead->nonce_size)
+       {
+         ASSERT (set_nonce);
+         set_nonce (ctx, nonce->length, nonce->data);
+       }
+      else
+       aead->set_nonce(ctx, nonce->data);
 
-  if (authtext->length)
-    aead->update(ctx, authtext->length, authtext->data);
+      if (authtext->length)
+       aead->update(ctx, authtext->length, authtext->data);
     
-  if (length)
-    aead->decrypt(ctx, length, data, data);
+      if (length)
+       aead->decrypt(ctx, length, data, data);
 
-  aead->digest(ctx, digest->length, buffer);
-
-  ASSERT(MEMEQ(length, data, cleartext->data));
-  ASSERT(MEMEQ(digest->length, buffer, digest->data));
+      aead->digest(ctx, digest->length, buffer);
 
+      ASSERT(MEMEQ(length, data, cleartext->data));
+      ASSERT(MEMEQ(digest->length, buffer, digest->data));
+    }
   free(ctx);
   free(data);
   free(buffer);