@@ -28,6 +28,75 @@
#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) {
+ unsigned long ssl_error = ERR_get_error();
+
+ ERR_load_crypto_strings();
+ VLOG_FATAL("Encryption init failed. Error %s",
+ ERR_error_string(ssl_error, NULL));
+ }
+ 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)) {
+ unsigned long ssl_error = ERR_get_error();
+
+ ERR_load_crypto_strings();
+ VLOG_FATAL("Encryption failed. Error %s",
+ ERR_error_string(ssl_error, NULL));
+ }
+}
+
+#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 +459,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 +482,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 +579,4 @@ aes128_encrypt(const struct aes128 *aes, const void *input_, void *output_)
^ rk[3]);
put_u32(output + 12, s3);
}
+
@@ -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 */
@@ -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);
@@ -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]);
}