Apologies, forgot to add the human readable error messages from OpenSSL.

V3 will address it.

A.

On 19/08/2021 14:35, [email protected] wrote:
From: Anton Ivanov <[email protected]>

This allows to leverage the openssl implementation which can use
hardware crypto on supported platforms.

UUID generation speed is improved by ~ 12% on an AMD Ryzen with
support for AES instructions.

Signed-off-by: Anton Ivanov <[email protected]>
---
  lib/aes128.c        | 71 +++++++++++++++++++++++++++++++++++++++++++--
  lib/aes128.h        | 13 +++++----
  lib/uuid.c          |  6 ++--
  tests/test-aes128.c |  6 ++--
  4 files changed, 82 insertions(+), 14 deletions(-)

diff --git a/lib/aes128.c b/lib/aes128.c
index 98447d14b..d2ae9dbab 100644
--- a/lib/aes128.c
+++ b/lib/aes128.c
@@ -28,6 +28,67 @@
#include "util.h" +#ifdef HAVE_OPENSSL
+
+#include <openssl/conf.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <string.h>
+#include "entropy.h"
+#include "openvswitch/vlog.h"
+
+VLOG_DEFINE_THIS_MODULE(aes);
+
+struct aes128 {
+    EVP_CIPHER_CTX *ctx;
+};
+
+void *aes128_schedule(const uint8_t key[16])
+{
+    uint8_t iv[16];
+
+    struct aes128 *aes = xmalloc(sizeof *aes);
+
+    aes->ctx = EVP_CIPHER_CTX_new();
+    memset(iv, 0, sizeof iv);
+    if (EVP_EncryptInit_ex(aes->ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1) {
+        VLOG_FATAL("Encryption init failed");
+    }
+    return aes;
+}
+
+void aes128_encrypt(void *aes, const void *plain, void *cipher)
+{
+    int len;
+    struct aes128 *aes_ctx = aes;
+
+    if (1 != EVP_EncryptUpdate(aes_ctx->ctx, cipher, &len, plain, 16)) {
+        VLOG_FATAL("Encryption failed");
+    }
+}
+
+#else
+
+struct aes128 {
+    uint32_t rk[128/8 + 28];
+};
+
+void *aes128_schedule(const uint8_t key[16])
+{
+    return ovs_aes128_schedule(key);
+}
+
+void aes128_encrypt(void *aes, const void *input_, void *output_)
+{
+    ovs_aes128_encrypt(aes, input_, output_);
+}
+
+#endif
+
+struct ovs_aes128 {
+    uint32_t rk[128/8 + 28];
+};
+
  static const uint32_t Te0[256] = {
      0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
      0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
@@ -390,8 +451,9 @@ put_u32(uint8_t *p, uint32_t x)
/* Expands 128-bit 'key' into the encryption key 'schedule'. */
  void
-aes128_schedule(struct aes128 *aes, const uint8_t key[16])
+*ovs_aes128_schedule(const uint8_t key[16])
  {
+    struct ovs_aes128 *aes = xmalloc(sizeof *aes);
      uint32_t *rk = aes->rk;
      int i;
@@ -412,14 +474,16 @@ aes128_schedule(struct aes128 *aes, const uint8_t key[16])
          rk[7] = rk[3] ^ rk[6];
      }
      ovs_assert(rk == &aes->rk[40]);
+    return aes;
  }
void
-aes128_encrypt(const struct aes128 *aes, const void *input_, void *output_)
+ovs_aes128_encrypt(void *aes, const void *input_, void *output_)
  {
      const uint8_t *input = input_;
      uint8_t *output = output_;
-    const uint32_t *rk = aes->rk;
+    struct ovs_aes128 *ovs_aes = aes;
+    const uint32_t *rk = ovs_aes->rk;
      uint32_t s0, s1, s2, s3;
      uint32_t t0, t1, t2, t3;
      int r;
@@ -507,3 +571,4 @@ aes128_encrypt(const struct aes128 *aes, const void 
*input_, void *output_)
            ^ rk[3]);
      put_u32(output + 12, s3);
  }
+
diff --git a/lib/aes128.h b/lib/aes128.h
index f0f55d7cf..3e04e00c4 100644
--- a/lib/aes128.h
+++ b/lib/aes128.h
@@ -27,11 +27,14 @@
#include <stdint.h> -struct aes128 {
-    uint32_t rk[128/8 + 28];
-};
-void aes128_schedule(struct aes128 *, const uint8_t key[16]);
-void aes128_encrypt(const struct aes128 *, const void *, void *);
+void *aes128_schedule(const uint8_t key[16]);
+void aes128_encrypt(void *, const void *, void *);
+
+/* These are exposed for unit test purposes. */
+
+
+void *ovs_aes128_schedule(const uint8_t key[16]);
+void ovs_aes128_encrypt(void *, const void *, void *);
#endif /* aes128.h */
diff --git a/lib/uuid.c b/lib/uuid.c
index 8a16606da..3e14dcb5f 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -36,7 +36,7 @@
VLOG_DEFINE_THIS_MODULE(uuid); -static struct aes128 key;
+static void *key;
  static uint64_t counter[2];
  BUILD_ASSERT_DECL(sizeof counter == 16);
@@ -164,7 +164,7 @@ uuid_generate(struct uuid *uuid)
      ovs_mutex_unlock(&mutex);
/* AES output is exactly 16 bytes, so we encrypt directly into 'uuid'. */
-    aes128_encrypt(&key, copy, uuid);
+    aes128_encrypt(key, copy, uuid);
uuid_set_bits_v4(uuid); @@ -370,7 +370,7 @@ do_init(void) /* Generate key. */
      BUILD_ASSERT(sizeof sha1 >= 16);
-    aes128_schedule(&key, sha1);
+    key = aes128_schedule(sha1);
/* Generate initial counter. */
      get_entropy_or_die(counter, sizeof counter);
diff --git a/tests/test-aes128.c b/tests/test-aes128.c
index 7960551be..8706a7c7c 100644
--- a/tests/test-aes128.c
+++ b/tests/test-aes128.c
@@ -46,7 +46,7 @@ error:
  static void
  test_aes128_main(int argc, char *argv[])
  {
-    struct aes128 aes;
+    void *aes;
      uint8_t plaintext[16];
      uint8_t ciphertext[16];
      uint8_t key[16];
@@ -60,8 +60,8 @@ test_aes128_main(int argc, char *argv[])
      hex_to_uint8(argv[1], key, 16);
      hex_to_uint8(argv[2], plaintext, 16);
- aes128_schedule(&aes, key);
-    aes128_encrypt(&aes, plaintext, ciphertext);
+    aes = ovs_aes128_schedule(key);
+    ovs_aes128_encrypt(aes, plaintext, ciphertext);
      for (i = 0; i < 16; i++) {
          printf("%02x", ciphertext[i]);
      }

--
Anton R. Ivanov
Cambridgegreys Limited. Registered in England. Company Number 10273661
https://www.cambridgegreys.com/

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to