Move cipher/ into crypto/fipsmodule/

Change-Id: Id65e0988534056a72d9b40cc9ba5194e2d9b8a7c
Reviewed-on: https://boringssl-review.googlesource.com/15904
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt
index 596e793..e357a68 100644
--- a/crypto/CMakeLists.txt
+++ b/crypto/CMakeLists.txt
@@ -88,7 +88,7 @@
 
 # Level 1, depends only on 0.*
 add_subdirectory(digest_extra)
-add_subdirectory(cipher)
+add_subdirectory(cipher_extra)
 add_subdirectory(rand_extra)
 add_subdirectory(bio)
 add_subdirectory(bn_extra)
@@ -166,7 +166,7 @@
   $<TARGET_OBJECTS:pool>
   $<TARGET_OBJECTS:fipsmodule>
   $<TARGET_OBJECTS:digest_extra>
-  $<TARGET_OBJECTS:cipher>
+  $<TARGET_OBJECTS:cipher_extra>
   $<TARGET_OBJECTS:rc4>
   $<TARGET_OBJECTS:conf>
   $<TARGET_OBJECTS:chacha>
diff --git a/crypto/cipher/CMakeLists.txt b/crypto/cipher_extra/CMakeLists.txt
similarity index 94%
rename from crypto/cipher/CMakeLists.txt
rename to crypto/cipher_extra/CMakeLists.txt
index c1d483d..698161c 100644
--- a/crypto/cipher/CMakeLists.txt
+++ b/crypto/cipher_extra/CMakeLists.txt
@@ -10,19 +10,16 @@
 endif()
 
 add_library(
-  cipher
+  cipher_extra
 
   OBJECT
 
-  cipher.c
+  cipher_extra.c
   derive_key.c
-  aead.c
 
   e_null.c
   e_rc2.c
   e_rc4.c
-  e_des.c
-  e_aes.c
   e_aesgcmsiv.c
   e_aesctrhmac.c
   e_chacha20poly1305.c
diff --git a/crypto/cipher/aead_test.cc b/crypto/cipher_extra/aead_test.cc
similarity index 100%
rename from crypto/cipher/aead_test.cc
rename to crypto/cipher_extra/aead_test.cc
diff --git a/crypto/cipher/asm/aes128gcmsiv-x86_64.pl b/crypto/cipher_extra/asm/aes128gcmsiv-x86_64.pl
similarity index 100%
rename from crypto/cipher/asm/aes128gcmsiv-x86_64.pl
rename to crypto/cipher_extra/asm/aes128gcmsiv-x86_64.pl
diff --git a/crypto/cipher/asm/chacha20_poly1305_x86_64.pl b/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl
similarity index 100%
rename from crypto/cipher/asm/chacha20_poly1305_x86_64.pl
rename to crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl
diff --git a/crypto/cipher/e_null.c b/crypto/cipher_extra/cipher_extra.c
similarity index 68%
copy from crypto/cipher/e_null.c
copy to crypto/cipher_extra/cipher_extra.c
index 9f89308..fc8e24b 100644
--- a/crypto/cipher/e_null.c
+++ b/crypto/cipher_extra/cipher_extra.c
@@ -56,31 +56,59 @@
 
 #include <openssl/cipher.h>
 
+#include <assert.h>
 #include <string.h>
 
+#include <openssl/err.h>
+#include <openssl/mem.h>
 #include <openssl/nid.h>
 
-#include "../internal.h"
 #include "internal.h"
+#include "../internal.h"
 
 
-static int null_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
-                         const uint8_t *iv, int enc) {
-  return 1;
-}
-
-static int null_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
-                       const uint8_t *in, size_t in_len) {
-  if (in != out) {
-    OPENSSL_memcpy(out, in, in_len);
+const EVP_CIPHER *EVP_get_cipherbynid(int nid) {
+  switch (nid) {
+    case NID_rc2_cbc:
+      return EVP_rc2_cbc();
+    case NID_rc2_40_cbc:
+      return EVP_rc2_40_cbc();
+    case NID_des_ede3_cbc:
+      return EVP_des_ede3_cbc();
+    case NID_des_ede_cbc:
+      return EVP_des_cbc();
+    case NID_aes_128_cbc:
+      return EVP_aes_128_cbc();
+    case NID_aes_192_cbc:
+      return EVP_aes_192_cbc();
+    case NID_aes_256_cbc:
+      return EVP_aes_256_cbc();
+    default:
+      return NULL;
   }
-  return 1;
 }
 
-static const EVP_CIPHER n_cipher = {
-    NID_undef,        1 /* block size */, 0 /* key_len */,     0 /* iv_len */,
-    0 /* ctx_size */, 0 /* flags */,      NULL /* app_data */, null_init_key,
-    null_cipher,      NULL /* cleanup */, NULL /* ctrl */,
-};
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name) {
+  if (OPENSSL_strcasecmp(name, "rc4") == 0) {
+    return EVP_rc4();
+  } else if (OPENSSL_strcasecmp(name, "des-cbc") == 0) {
+    return EVP_des_cbc();
+  } else if (OPENSSL_strcasecmp(name, "des-ede3-cbc") == 0 ||
+             OPENSSL_strcasecmp(name, "3des") == 0) {
+    return EVP_des_ede3_cbc();
+  } else if (OPENSSL_strcasecmp(name, "aes-128-cbc") == 0) {
+    return EVP_aes_128_cbc();
+  } else if (OPENSSL_strcasecmp(name, "aes-256-cbc") == 0) {
+    return EVP_aes_256_cbc();
+  } else if (OPENSSL_strcasecmp(name, "aes-128-ctr") == 0) {
+    return EVP_aes_128_ctr();
+  } else if (OPENSSL_strcasecmp(name, "aes-256-ctr") == 0) {
+    return EVP_aes_256_ctr();
+  } else if (OPENSSL_strcasecmp(name, "aes-128-ecb") == 0) {
+    return EVP_aes_128_ecb();
+  } else if (OPENSSL_strcasecmp(name, "aes-256-ecb") == 0) {
+    return EVP_aes_256_ecb();
+  }
 
-const EVP_CIPHER *EVP_enc_null(void) { return &n_cipher; }
+  return NULL;
+}
diff --git a/crypto/cipher/cipher_test.cc b/crypto/cipher_extra/cipher_test.cc
similarity index 100%
rename from crypto/cipher/cipher_test.cc
rename to crypto/cipher_extra/cipher_test.cc
diff --git a/crypto/cipher/derive_key.c b/crypto/cipher_extra/derive_key.c
similarity index 99%
rename from crypto/cipher/derive_key.c
rename to crypto/cipher_extra/derive_key.c
index 9e1634a..ff5ae06 100644
--- a/crypto/cipher/derive_key.c
+++ b/crypto/cipher_extra/derive_key.c
@@ -61,8 +61,6 @@
 #include <openssl/digest.h>
 #include <openssl/mem.h>
 
-#include "internal.h"
-
 
 #define PKCS5_SALT_LEN 8
 
diff --git a/crypto/cipher/e_aesctrhmac.c b/crypto/cipher_extra/e_aesctrhmac.c
similarity index 99%
rename from crypto/cipher/e_aesctrhmac.c
rename to crypto/cipher_extra/e_aesctrhmac.c
index f7cd412..2372ef8 100644
--- a/crypto/cipher/e_aesctrhmac.c
+++ b/crypto/cipher_extra/e_aesctrhmac.c
@@ -18,7 +18,7 @@
 #include <openssl/err.h>
 #include <openssl/sha.h>
 
-#include "internal.h"
+#include "../fipsmodule/cipher/internal.h"
 
 
 #define EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN SHA256_DIGEST_LENGTH
diff --git a/crypto/cipher/e_aesgcmsiv.c b/crypto/cipher_extra/e_aesgcmsiv.c
similarity index 99%
rename from crypto/cipher/e_aesgcmsiv.c
rename to crypto/cipher_extra/e_aesgcmsiv.c
index 070f8cd..c7be11c 100644
--- a/crypto/cipher/e_aesgcmsiv.c
+++ b/crypto/cipher_extra/e_aesgcmsiv.c
@@ -18,7 +18,7 @@
 #include <openssl/crypto.h>
 #include <openssl/err.h>
 
-#include "internal.h"
+#include "../fipsmodule/cipher/internal.h"
 
 
 #if !defined(OPENSSL_SMALL)
diff --git a/crypto/cipher/e_chacha20poly1305.c b/crypto/cipher_extra/e_chacha20poly1305.c
similarity index 99%
rename from crypto/cipher/e_chacha20poly1305.c
rename to crypto/cipher_extra/e_chacha20poly1305.c
index c6e81ab..257663c 100644
--- a/crypto/cipher/e_chacha20poly1305.c
+++ b/crypto/cipher_extra/e_chacha20poly1305.c
@@ -23,7 +23,7 @@
 #include <openssl/mem.h>
 #include <openssl/poly1305.h>
 
-#include "internal.h"
+#include "../fipsmodule/cipher/internal.h"
 #include "../internal.h"
 
 
diff --git a/crypto/cipher/e_null.c b/crypto/cipher_extra/e_null.c
similarity index 99%
rename from crypto/cipher/e_null.c
rename to crypto/cipher_extra/e_null.c
index 9f89308..f5fe8fb 100644
--- a/crypto/cipher/e_null.c
+++ b/crypto/cipher_extra/e_null.c
@@ -61,7 +61,6 @@
 #include <openssl/nid.h>
 
 #include "../internal.h"
-#include "internal.h"
 
 
 static int null_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
diff --git a/crypto/cipher/e_rc2.c b/crypto/cipher_extra/e_rc2.c
similarity index 99%
rename from crypto/cipher/e_rc2.c
rename to crypto/cipher_extra/e_rc2.c
index e1b4301..a18229c 100644
--- a/crypto/cipher/e_rc2.c
+++ b/crypto/cipher_extra/e_rc2.c
@@ -57,8 +57,6 @@
 #include <openssl/cipher.h>
 #include <openssl/nid.h>
 
-#include "internal.h"
-
 
 #define c2l(c, l)                         \
   do {                                    \
diff --git a/crypto/cipher/e_rc4.c b/crypto/cipher_extra/e_rc4.c
similarity index 100%
rename from crypto/cipher/e_rc4.c
rename to crypto/cipher_extra/e_rc4.c
diff --git a/crypto/cipher/e_ssl3.c b/crypto/cipher_extra/e_ssl3.c
similarity index 99%
rename from crypto/cipher/e_ssl3.c
rename to crypto/cipher_extra/e_ssl3.c
index f1dad2b..03c2efa 100644
--- a/crypto/cipher/e_ssl3.c
+++ b/crypto/cipher_extra/e_ssl3.c
@@ -26,6 +26,7 @@
 
 #include "internal.h"
 #include "../internal.h"
+#include "../fipsmodule/cipher/internal.h"
 
 
 typedef struct {
diff --git a/crypto/cipher/e_tls.c b/crypto/cipher_extra/e_tls.c
similarity index 99%
rename from crypto/cipher/e_tls.c
rename to crypto/cipher_extra/e_tls.c
index bb80cc6..5b92ebc 100644
--- a/crypto/cipher/e_tls.c
+++ b/crypto/cipher_extra/e_tls.c
@@ -27,6 +27,7 @@
 
 #include "../internal.h"
 #include "internal.h"
+#include "../fipsmodule/cipher/internal.h"
 
 
 typedef struct {
diff --git a/crypto/cipher/internal.h b/crypto/cipher_extra/internal.h
similarity index 74%
rename from crypto/cipher/internal.h
rename to crypto/cipher_extra/internal.h
index 52dbac2..7136195 100644
--- a/crypto/cipher/internal.h
+++ b/crypto/cipher_extra/internal.h
@@ -54,56 +54,18 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.] */
 
-#ifndef OPENSSL_HEADER_CIPHER_INTERNAL_H
-#define OPENSSL_HEADER_CIPHER_INTERNAL_H
+#ifndef OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H
+#define OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H
 
 #include <openssl/base.h>
 
-#include <openssl/aead.h>
-#include <openssl/aes.h>
-
 #include "../internal.h"
-#include "../fipsmodule/modes/internal.h"
 
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
 
-/* EVP_CIPH_MODE_MASK contains the bits of |flags| that represent the mode. */
-#define EVP_CIPH_MODE_MASK 0x3f
-
-
-/* EVP_AEAD represents a specific AEAD algorithm. */
-struct evp_aead_st {
-  uint8_t key_len;
-  uint8_t nonce_len;
-  uint8_t overhead;
-  uint8_t max_tag_len;
-
-  /* init initialises an |EVP_AEAD_CTX|. If this call returns zero then
-   * |cleanup| will not be called for that context. */
-  int (*init)(EVP_AEAD_CTX *, const uint8_t *key, size_t key_len,
-              size_t tag_len);
-  int (*init_with_direction)(EVP_AEAD_CTX *, const uint8_t *key, size_t key_len,
-                             size_t tag_len, enum evp_aead_direction_t dir);
-  void (*cleanup)(EVP_AEAD_CTX *);
-
-  int (*seal)(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
-              size_t max_out_len, const uint8_t *nonce, size_t nonce_len,
-              const uint8_t *in, size_t in_len, const uint8_t *ad,
-              size_t ad_len);
-
-  int (*open)(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
-              size_t max_out_len, const uint8_t *nonce, size_t nonce_len,
-              const uint8_t *in, size_t in_len, const uint8_t *ad,
-              size_t ad_len);
-
-  int (*get_iv)(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
-                size_t *out_len);
-};
-
-
 /* EVP_tls_cbc_get_padding determines the padding from the decrypted, TLS, CBC
  * record in |in|. This decrypted record should not include any "decrypted"
  * explicit IV. If the record is publicly invalid, it returns zero. Otherwise,
@@ -158,18 +120,9 @@
                               const uint8_t *mac_secret,
                               unsigned mac_secret_length);
 
-/* aes_ctr_set_key initialises |*aes_key| using |key_bytes| bytes from |key|,
- * where |key_bytes| must either be 16, 24 or 32. If not NULL, |*out_block| is
- * set to a function that encrypts single blocks. If not NULL, |*gcm_ctx| is
- * initialised to do GHASH with the given key. It returns a function for
- * optimised CTR-mode, or NULL if CTR-mode should be built using
- * |*out_block|. */
-ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
-                         block128_f *out_block, const uint8_t *key,
-                         size_t key_bytes);
 
 #if defined(__cplusplus)
 } /* extern C */
 #endif
 
-#endif /* OPENSSL_HEADER_CIPHER_INTERNAL_H */
+#endif /* OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H */
diff --git a/crypto/cipher/test/aes_128_cbc_sha1_ssl3_tests.txt b/crypto/cipher_extra/test/aes_128_cbc_sha1_ssl3_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_128_cbc_sha1_ssl3_tests.txt
rename to crypto/cipher_extra/test/aes_128_cbc_sha1_ssl3_tests.txt
diff --git a/crypto/cipher/test/aes_128_cbc_sha1_tls_implicit_iv_tests.txt b/crypto/cipher_extra/test/aes_128_cbc_sha1_tls_implicit_iv_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_128_cbc_sha1_tls_implicit_iv_tests.txt
rename to crypto/cipher_extra/test/aes_128_cbc_sha1_tls_implicit_iv_tests.txt
diff --git a/crypto/cipher/test/aes_128_cbc_sha1_tls_tests.txt b/crypto/cipher_extra/test/aes_128_cbc_sha1_tls_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_128_cbc_sha1_tls_tests.txt
rename to crypto/cipher_extra/test/aes_128_cbc_sha1_tls_tests.txt
diff --git a/crypto/cipher/test/aes_128_cbc_sha256_tls_tests.txt b/crypto/cipher_extra/test/aes_128_cbc_sha256_tls_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_128_cbc_sha256_tls_tests.txt
rename to crypto/cipher_extra/test/aes_128_cbc_sha256_tls_tests.txt
diff --git a/crypto/cipher/test/aes_128_ctr_hmac_sha256.txt b/crypto/cipher_extra/test/aes_128_ctr_hmac_sha256.txt
similarity index 100%
rename from crypto/cipher/test/aes_128_ctr_hmac_sha256.txt
rename to crypto/cipher_extra/test/aes_128_ctr_hmac_sha256.txt
diff --git a/crypto/cipher/test/aes_128_gcm_fips_testonly_tests.txt b/crypto/cipher_extra/test/aes_128_gcm_fips_testonly_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_128_gcm_fips_testonly_tests.txt
rename to crypto/cipher_extra/test/aes_128_gcm_fips_testonly_tests.txt
diff --git a/crypto/cipher/test/aes_128_gcm_siv_tests.txt b/crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_128_gcm_siv_tests.txt
rename to crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt
diff --git a/crypto/cipher/test/aes_128_gcm_tests.txt b/crypto/cipher_extra/test/aes_128_gcm_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_128_gcm_tests.txt
rename to crypto/cipher_extra/test/aes_128_gcm_tests.txt
diff --git a/crypto/cipher/test/aes_256_cbc_sha1_ssl3_tests.txt b/crypto/cipher_extra/test/aes_256_cbc_sha1_ssl3_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_256_cbc_sha1_ssl3_tests.txt
rename to crypto/cipher_extra/test/aes_256_cbc_sha1_ssl3_tests.txt
diff --git a/crypto/cipher/test/aes_256_cbc_sha1_tls_implicit_iv_tests.txt b/crypto/cipher_extra/test/aes_256_cbc_sha1_tls_implicit_iv_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_256_cbc_sha1_tls_implicit_iv_tests.txt
rename to crypto/cipher_extra/test/aes_256_cbc_sha1_tls_implicit_iv_tests.txt
diff --git a/crypto/cipher/test/aes_256_cbc_sha1_tls_tests.txt b/crypto/cipher_extra/test/aes_256_cbc_sha1_tls_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_256_cbc_sha1_tls_tests.txt
rename to crypto/cipher_extra/test/aes_256_cbc_sha1_tls_tests.txt
diff --git a/crypto/cipher/test/aes_256_cbc_sha256_tls_tests.txt b/crypto/cipher_extra/test/aes_256_cbc_sha256_tls_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_256_cbc_sha256_tls_tests.txt
rename to crypto/cipher_extra/test/aes_256_cbc_sha256_tls_tests.txt
diff --git a/crypto/cipher/test/aes_256_cbc_sha384_tls_tests.txt b/crypto/cipher_extra/test/aes_256_cbc_sha384_tls_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_256_cbc_sha384_tls_tests.txt
rename to crypto/cipher_extra/test/aes_256_cbc_sha384_tls_tests.txt
diff --git a/crypto/cipher/test/aes_256_ctr_hmac_sha256.txt b/crypto/cipher_extra/test/aes_256_ctr_hmac_sha256.txt
similarity index 100%
rename from crypto/cipher/test/aes_256_ctr_hmac_sha256.txt
rename to crypto/cipher_extra/test/aes_256_ctr_hmac_sha256.txt
diff --git a/crypto/cipher/test/aes_256_gcm_fips_testonly_tests.txt b/crypto/cipher_extra/test/aes_256_gcm_fips_testonly_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_256_gcm_fips_testonly_tests.txt
rename to crypto/cipher_extra/test/aes_256_gcm_fips_testonly_tests.txt
diff --git a/crypto/cipher/test/aes_256_gcm_siv_tests.txt b/crypto/cipher_extra/test/aes_256_gcm_siv_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_256_gcm_siv_tests.txt
rename to crypto/cipher_extra/test/aes_256_gcm_siv_tests.txt
diff --git a/crypto/cipher/test/aes_256_gcm_tests.txt b/crypto/cipher_extra/test/aes_256_gcm_tests.txt
similarity index 100%
rename from crypto/cipher/test/aes_256_gcm_tests.txt
rename to crypto/cipher_extra/test/aes_256_gcm_tests.txt
diff --git a/crypto/cipher/test/chacha20_poly1305_tests.txt b/crypto/cipher_extra/test/chacha20_poly1305_tests.txt
similarity index 100%
rename from crypto/cipher/test/chacha20_poly1305_tests.txt
rename to crypto/cipher_extra/test/chacha20_poly1305_tests.txt
diff --git a/crypto/cipher/test/cipher_tests.txt b/crypto/cipher_extra/test/cipher_tests.txt
similarity index 100%
rename from crypto/cipher/test/cipher_tests.txt
rename to crypto/cipher_extra/test/cipher_tests.txt
diff --git a/crypto/cipher/test/des_ede3_cbc_sha1_ssl3_tests.txt b/crypto/cipher_extra/test/des_ede3_cbc_sha1_ssl3_tests.txt
similarity index 100%
rename from crypto/cipher/test/des_ede3_cbc_sha1_ssl3_tests.txt
rename to crypto/cipher_extra/test/des_ede3_cbc_sha1_ssl3_tests.txt
diff --git a/crypto/cipher/test/des_ede3_cbc_sha1_tls_implicit_iv_tests.txt b/crypto/cipher_extra/test/des_ede3_cbc_sha1_tls_implicit_iv_tests.txt
similarity index 100%
rename from crypto/cipher/test/des_ede3_cbc_sha1_tls_implicit_iv_tests.txt
rename to crypto/cipher_extra/test/des_ede3_cbc_sha1_tls_implicit_iv_tests.txt
diff --git a/crypto/cipher/test/des_ede3_cbc_sha1_tls_tests.txt b/crypto/cipher_extra/test/des_ede3_cbc_sha1_tls_tests.txt
similarity index 100%
rename from crypto/cipher/test/des_ede3_cbc_sha1_tls_tests.txt
rename to crypto/cipher_extra/test/des_ede3_cbc_sha1_tls_tests.txt
diff --git a/crypto/cipher/test/make_all_legacy_aead_tests.sh b/crypto/cipher_extra/test/make_all_legacy_aead_tests.sh
similarity index 100%
rename from crypto/cipher/test/make_all_legacy_aead_tests.sh
rename to crypto/cipher_extra/test/make_all_legacy_aead_tests.sh
diff --git a/crypto/cipher/test/make_legacy_aead_tests.go b/crypto/cipher_extra/test/make_legacy_aead_tests.go
similarity index 100%
rename from crypto/cipher/test/make_legacy_aead_tests.go
rename to crypto/cipher_extra/test/make_legacy_aead_tests.go
diff --git a/crypto/cipher/test/nist_cavp/aes_128_cbc.txt b/crypto/cipher_extra/test/nist_cavp/aes_128_cbc.txt
similarity index 100%
rename from crypto/cipher/test/nist_cavp/aes_128_cbc.txt
rename to crypto/cipher_extra/test/nist_cavp/aes_128_cbc.txt
diff --git a/crypto/cipher/test/nist_cavp/aes_128_ctr.txt b/crypto/cipher_extra/test/nist_cavp/aes_128_ctr.txt
similarity index 100%
rename from crypto/cipher/test/nist_cavp/aes_128_ctr.txt
rename to crypto/cipher_extra/test/nist_cavp/aes_128_ctr.txt
diff --git a/crypto/cipher/test/nist_cavp/aes_128_gcm.txt b/crypto/cipher_extra/test/nist_cavp/aes_128_gcm.txt
similarity index 100%
rename from crypto/cipher/test/nist_cavp/aes_128_gcm.txt
rename to crypto/cipher_extra/test/nist_cavp/aes_128_gcm.txt
diff --git a/crypto/cipher/test/nist_cavp/aes_192_cbc.txt b/crypto/cipher_extra/test/nist_cavp/aes_192_cbc.txt
similarity index 100%
rename from crypto/cipher/test/nist_cavp/aes_192_cbc.txt
rename to crypto/cipher_extra/test/nist_cavp/aes_192_cbc.txt
diff --git a/crypto/cipher/test/nist_cavp/aes_192_ctr.txt b/crypto/cipher_extra/test/nist_cavp/aes_192_ctr.txt
similarity index 100%
rename from crypto/cipher/test/nist_cavp/aes_192_ctr.txt
rename to crypto/cipher_extra/test/nist_cavp/aes_192_ctr.txt
diff --git a/crypto/cipher/test/nist_cavp/aes_256_cbc.txt b/crypto/cipher_extra/test/nist_cavp/aes_256_cbc.txt
similarity index 100%
rename from crypto/cipher/test/nist_cavp/aes_256_cbc.txt
rename to crypto/cipher_extra/test/nist_cavp/aes_256_cbc.txt
diff --git a/crypto/cipher/test/nist_cavp/aes_256_ctr.txt b/crypto/cipher_extra/test/nist_cavp/aes_256_ctr.txt
similarity index 100%
rename from crypto/cipher/test/nist_cavp/aes_256_ctr.txt
rename to crypto/cipher_extra/test/nist_cavp/aes_256_ctr.txt
diff --git a/crypto/cipher/test/nist_cavp/aes_256_gcm.txt b/crypto/cipher_extra/test/nist_cavp/aes_256_gcm.txt
similarity index 100%
rename from crypto/cipher/test/nist_cavp/aes_256_gcm.txt
rename to crypto/cipher_extra/test/nist_cavp/aes_256_gcm.txt
diff --git a/crypto/cipher/test/nist_cavp/make_cavp.go b/crypto/cipher_extra/test/nist_cavp/make_cavp.go
similarity index 100%
rename from crypto/cipher/test/nist_cavp/make_cavp.go
rename to crypto/cipher_extra/test/nist_cavp/make_cavp.go
diff --git a/crypto/cipher/test/nist_cavp/tdes_cbc.txt b/crypto/cipher_extra/test/nist_cavp/tdes_cbc.txt
similarity index 100%
rename from crypto/cipher/test/nist_cavp/tdes_cbc.txt
rename to crypto/cipher_extra/test/nist_cavp/tdes_cbc.txt
diff --git a/crypto/cipher/test/nist_cavp/tdes_ecb.txt b/crypto/cipher_extra/test/nist_cavp/tdes_ecb.txt
similarity index 100%
rename from crypto/cipher/test/nist_cavp/tdes_ecb.txt
rename to crypto/cipher_extra/test/nist_cavp/tdes_ecb.txt
diff --git a/crypto/cipher/tls_cbc.c b/crypto/cipher_extra/tls_cbc.c
similarity index 99%
rename from crypto/cipher/tls_cbc.c
rename to crypto/cipher_extra/tls_cbc.c
index 1d5006f..2372c5c 100644
--- a/crypto/cipher/tls_cbc.c
+++ b/crypto/cipher_extra/tls_cbc.c
@@ -59,6 +59,7 @@
 
 #include "../internal.h"
 #include "internal.h"
+#include "../fipsmodule/cipher/internal.h"
 
 
 /* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
diff --git a/crypto/fipsmodule/aes/aes.c b/crypto/fipsmodule/aes/aes.c
index edd866c..c68a5d5 100644
--- a/crypto/fipsmodule/aes/aes.c
+++ b/crypto/fipsmodule/aes/aes.c
@@ -49,10 +49,10 @@
 #include <openssl/aes.h>
 
 #include <assert.h>
-#include <stdlib.h>
 
 #include <openssl/cpu.h>
 
+#include "internal.h"
 #include "../modes/internal.h"
 
 
@@ -1060,44 +1060,6 @@
 
 #else
 
-#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
-
-static int hwaes_capable(void) {
-  return CRYPTO_is_ARMv8_AES_capable();
-}
-
-int aes_hw_set_encrypt_key(const uint8_t *user_key, const int bits,
-                           AES_KEY *key);
-int aes_hw_set_decrypt_key(const uint8_t *user_key, const int bits,
-                           AES_KEY *key);
-void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
-void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
-
-#else
-
-static int hwaes_capable(void) {
-  return 0;
-}
-
-static int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
-  abort();
-}
-
-static int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
-  abort();
-}
-
-static void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
-  abort();
-}
-
-static void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
-  abort();
-}
-
-#endif
-
-
 /* In this case several functions are provided by asm code. However, one cannot
  * control asm symbol visibility with command line flags and such so they are
  * always hidden and wrapped by these C functions, which can be so
diff --git a/crypto/fipsmodule/aes/internal.h b/crypto/fipsmodule/aes/internal.h
new file mode 100644
index 0000000..01cff84
--- /dev/null
+++ b/crypto/fipsmodule/aes/internal.h
@@ -0,0 +1,100 @@
+/* Copyright (c) 2017, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef OPENSSL_HEADER_AES_INTERNAL_H
+#define OPENSSL_HEADER_AES_INTERNAL_H
+
+#include <stdlib.h>
+
+#include <openssl/cpu.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#if !defined(OPENSSL_NO_ASM) && (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
+#define HWAES
+
+static int hwaes_capable(void) {
+  return CRYPTO_is_ARMv8_AES_capable();
+}
+#endif  /* !NO_ASM && (AES || AARCH64) */
+
+#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_PPC64LE)
+#define HWAES
+
+static int hwaes_capable(void) {
+  return CRYPTO_is_PPC64LE_vcrypto_capable();
+}
+#endif  /* !NO_ASM && PPC64LE */
+
+
+#if defined(HWAES)
+
+int aes_hw_set_encrypt_key(const uint8_t *user_key, const int bits,
+                           AES_KEY *key);
+int aes_hw_set_decrypt_key(const uint8_t *user_key, const int bits,
+                           AES_KEY *key);
+void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
+void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
+void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
+                        const AES_KEY *key, uint8_t *ivec, const int enc);
+void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
+                                 const AES_KEY *key, const uint8_t ivec[16]);
+
+#else
+
+/* If HWAES isn't defined then we provide dummy functions for each of the hwaes
+ * functions. */
+static int hwaes_capable(void) { return 0; }
+
+static int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits,
+                                  AES_KEY *key) {
+  abort();
+}
+
+static int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits,
+                                  AES_KEY *key) {
+  abort();
+}
+
+static void aes_hw_encrypt(const uint8_t *in, uint8_t *out,
+                           const AES_KEY *key) {
+  abort();
+}
+
+static void aes_hw_decrypt(const uint8_t *in, uint8_t *out,
+                           const AES_KEY *key) {
+  abort();
+}
+
+static void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
+                               const AES_KEY *key, uint8_t *ivec, int enc) {
+  abort();
+}
+
+static void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
+                                        size_t len, const AES_KEY *key,
+                                        const uint8_t ivec[16]) {
+  abort();
+}
+
+#endif  /* !HWAES */
+
+#if defined(__cplusplus)
+}  /* extern C */
+#endif
+
+#endif  /* OPENSSL_HEADER_AES_INTERNAL_H */
diff --git a/crypto/fipsmodule/bcm.c b/crypto/fipsmodule/bcm.c
index 692b57c..6dd5105 100644
--- a/crypto/fipsmodule/bcm.c
+++ b/crypto/fipsmodule/bcm.c
@@ -54,6 +54,10 @@
 #include "bn/rsaz_exp.c"
 #include "bn/shift.c"
 #include "bn/sqrt.c"
+#include "cipher/aead.c"
+#include "cipher/cipher.c"
+#include "cipher/e_aes.c"
+#include "cipher/e_des.c"
 #include "des/des.c"
 #include "digest/digest.c"
 #include "digest/digests.c"
diff --git a/crypto/cipher/aead.c b/crypto/fipsmodule/cipher/aead.c
similarity index 99%
rename from crypto/cipher/aead.c
rename to crypto/fipsmodule/cipher/aead.c
index 40b0bbf..25c28bd 100644
--- a/crypto/cipher/aead.c
+++ b/crypto/fipsmodule/cipher/aead.c
@@ -21,7 +21,7 @@
 #include <openssl/mem.h>
 
 #include "internal.h"
-#include "../internal.h"
+#include "../../internal.h"
 
 
 size_t EVP_AEAD_key_length(const EVP_AEAD *aead) { return aead->key_len; }
diff --git a/crypto/cipher/cipher.c b/crypto/fipsmodule/cipher/cipher.c
similarity index 91%
rename from crypto/cipher/cipher.c
rename to crypto/fipsmodule/cipher/cipher.c
index e46e43e..d116715 100644
--- a/crypto/cipher/cipher.c
+++ b/crypto/fipsmodule/cipher/cipher.c
@@ -64,30 +64,9 @@
 #include <openssl/nid.h>
 
 #include "internal.h"
-#include "../internal.h"
+#include "../../internal.h"
 
 
-const EVP_CIPHER *EVP_get_cipherbynid(int nid) {
-  switch (nid) {
-    case NID_rc2_cbc:
-      return EVP_rc2_cbc();
-    case NID_rc2_40_cbc:
-      return EVP_rc2_40_cbc();
-    case NID_des_ede3_cbc:
-      return EVP_des_ede3_cbc();
-    case NID_des_ede_cbc:
-      return EVP_des_cbc();
-    case NID_aes_128_cbc:
-      return EVP_aes_128_cbc();
-    case NID_aes_192_cbc:
-      return EVP_aes_192_cbc();
-    case NID_aes_256_cbc:
-      return EVP_aes_256_cbc();
-    default:
-      return NULL;
-  }
-}
-
 void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) {
   OPENSSL_memset(ctx, 0, sizeof(EVP_CIPHER_CTX));
 }
@@ -630,28 +609,3 @@
 int EVP_add_cipher_alias(const char *a, const char *b) {
   return 1;
 }
-
-const EVP_CIPHER *EVP_get_cipherbyname(const char *name) {
-  if (OPENSSL_strcasecmp(name, "rc4") == 0) {
-    return EVP_rc4();
-  } else if (OPENSSL_strcasecmp(name, "des-cbc") == 0) {
-    return EVP_des_cbc();
-  } else if (OPENSSL_strcasecmp(name, "des-ede3-cbc") == 0 ||
-             OPENSSL_strcasecmp(name, "3des") == 0) {
-    return EVP_des_ede3_cbc();
-  } else if (OPENSSL_strcasecmp(name, "aes-128-cbc") == 0) {
-    return EVP_aes_128_cbc();
-  } else if (OPENSSL_strcasecmp(name, "aes-256-cbc") == 0) {
-    return EVP_aes_256_cbc();
-  } else if (OPENSSL_strcasecmp(name, "aes-128-ctr") == 0) {
-    return EVP_aes_128_ctr();
-  } else if (OPENSSL_strcasecmp(name, "aes-256-ctr") == 0) {
-    return EVP_aes_256_ctr();
-  } else if (OPENSSL_strcasecmp(name, "aes-128-ecb") == 0) {
-    return EVP_aes_128_ecb();
-  } else if (OPENSSL_strcasecmp(name, "aes-256-ecb") == 0) {
-    return EVP_aes_256_ecb();
-  }
-
-  return NULL;
-}
diff --git a/crypto/cipher/e_aes.c b/crypto/fipsmodule/cipher/e_aes.c
similarity index 69%
rename from crypto/cipher/e_aes.c
rename to crypto/fipsmodule/cipher/e_aes.c
index a16956e..423ae02 100644
--- a/crypto/cipher/e_aes.c
+++ b/crypto/fipsmodule/cipher/e_aes.c
@@ -58,8 +58,9 @@
 #include <openssl/rand.h>
 
 #include "internal.h"
-#include "../internal.h"
-#include "../fipsmodule/modes/internal.h"
+#include "../../internal.h"
+#include "../aes/internal.h"
+#include "../modes/internal.h"
 
 #if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
 #include <openssl/arm_arch.h>
@@ -119,19 +120,7 @@
 }
 #endif
 
-#define HWAES
-static int hwaes_capable(void) {
-  return CRYPTO_is_ARMv8_AES_capable();
-}
-
-#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_PPC64LE)
-
-#define HWAES
-static int hwaes_capable(void) {
-  return CRYPTO_is_PPC64LE_vcrypto_capable();
-}
-
-#endif  /* OPENSSL_PPC64LE */
+#endif
 
 
 #if defined(BSAES)
@@ -198,56 +187,6 @@
 }
 #endif
 
-#if defined(HWAES)
-int aes_hw_set_encrypt_key(const uint8_t *user_key, const int bits,
-                           AES_KEY *key);
-int aes_hw_set_decrypt_key(const uint8_t *user_key, const int bits,
-                           AES_KEY *key);
-void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
-void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
-void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
-                        const AES_KEY *key, uint8_t *ivec, const int enc);
-void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
-                                 const AES_KEY *key, const uint8_t ivec[16]);
-#else
-/* If HWAES isn't defined then we provide dummy functions for each of the hwaes
- * functions. */
-static int hwaes_capable(void) {
-  return 0;
-}
-
-static int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits,
-                                  AES_KEY *key) {
-  abort();
-}
-
-static int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits,
-                                  AES_KEY *key) {
-  abort();
-}
-
-static void aes_hw_encrypt(const uint8_t *in, uint8_t *out,
-                           const AES_KEY *key) {
-  abort();
-}
-
-static void aes_hw_decrypt(const uint8_t *in, uint8_t *out,
-                           const AES_KEY *key) {
-  abort();
-}
-
-static void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
-                               const AES_KEY *key, uint8_t *ivec, int enc) {
-  abort();
-}
-
-static void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
-                                        size_t len, const AES_KEY *key,
-                                        const uint8_t ivec[16]) {
-  abort();
-}
-#endif
-
 #if !defined(OPENSSL_NO_ASM) && \
     (defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
 int aesni_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
@@ -679,100 +618,196 @@
   }
 }
 
-static const EVP_CIPHER aes_128_cbc = {
-    NID_aes_128_cbc,     16 /* block_size */, 16 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
-    NULL /* app_data */, aes_init_key,        aes_cbc_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_cbc_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aes_128_ctr = {
-    NID_aes_128_ctr,     1 /* block_size */,  16 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
-    NULL /* app_data */, aes_init_key,        aes_ctr_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+  out->nid = NID_aes_128_cbc;
+  out->block_size = 16;
+  out->key_len = 16;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_CBC_MODE;
+  out->init = aes_init_key;
+  out->cipher = aes_cbc_cipher;
+}
 
-static const EVP_CIPHER aes_128_ecb = {
-    NID_aes_128_ecb,     16 /* block_size */, 16 /* key_size */,
-    0 /* iv_len */,      sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
-    NULL /* app_data */, aes_init_key,        aes_ecb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ctr_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aes_128_ofb = {
-    NID_aes_128_ofb128,  1 /* block_size */,  16 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_OFB_MODE,
-    NULL /* app_data */, aes_init_key,        aes_ofb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+  out->nid = NID_aes_128_ctr;
+  out->block_size = 1;
+  out->key_len = 16;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_CTR_MODE;
+  out->init = aes_init_key;
+  out->cipher = aes_ctr_cipher;
+}
 
-static const EVP_CIPHER aes_128_gcm = {
-    NID_aes_128_gcm, 1 /* block_size */, 16 /* key_size */, 12 /* iv_len */,
-    sizeof(EVP_AES_GCM_CTX),
-    EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
-        EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
-        EVP_CIPH_FLAG_AEAD_CIPHER,
-    NULL /* app_data */, aes_gcm_init_key, aes_gcm_cipher, aes_gcm_cleanup,
-    aes_gcm_ctrl};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ecb_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
+  out->nid = NID_aes_128_ecb;
+  out->block_size = 16;
+  out->key_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_ECB_MODE;
+  out->init = aes_init_key;
+  out->cipher = aes_ecb_cipher;
+}
 
-static const EVP_CIPHER aes_192_cbc = {
-    NID_aes_192_cbc,     16 /* block_size */, 24 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
-    NULL /* app_data */, aes_init_key,        aes_cbc_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ofb_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aes_192_ctr = {
-    NID_aes_192_ctr,     1 /* block_size */,  24 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
-    NULL /* app_data */, aes_init_key,        aes_ctr_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+  out->nid = NID_aes_128_ofb128;
+  out->block_size = 1;
+  out->key_len = 16;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_OFB_MODE;
+  out->init = aes_init_key;
+  out->cipher = aes_ofb_cipher;
+}
 
-static const EVP_CIPHER aes_192_ecb = {
-    NID_aes_192_ecb,     16 /* block_size */, 24 /* key_size */,
-    0 /* iv_len */,      sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
-    NULL /* app_data */, aes_init_key,        aes_ecb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_gcm_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aes_192_gcm = {
-    NID_aes_192_gcm, 1 /* block_size */, 24 /* key_size */, 12 /* iv_len */,
-    sizeof(EVP_AES_GCM_CTX),
-    EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
-        EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
-        EVP_CIPH_FLAG_AEAD_CIPHER,
-    NULL /* app_data */, aes_gcm_init_key, aes_gcm_cipher, aes_gcm_cleanup,
-    aes_gcm_ctrl};
+  out->nid = NID_aes_128_gcm;
+  out->block_size = 1;
+  out->key_len = 16;
+  out->iv_len = 12;
+  out->ctx_size = sizeof(EVP_AES_GCM_CTX);
+  out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
+               EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
+               EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
+  out->init = aes_gcm_init_key;
+  out->cipher = aes_gcm_cipher;
+  out->cleanup = aes_gcm_cleanup;
+  out->ctrl = aes_gcm_ctrl;
+}
 
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_cbc_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aes_256_cbc = {
-    NID_aes_256_cbc,     16 /* block_size */, 32 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
-    NULL /* app_data */, aes_init_key,        aes_cbc_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+  out->nid = NID_aes_192_cbc;
+  out->block_size = 16;
+  out->key_len = 24;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_CBC_MODE;
+  out->init = aes_init_key;
+  out->cipher = aes_cbc_cipher;
+}
 
-static const EVP_CIPHER aes_256_ctr = {
-    NID_aes_256_ctr,     1 /* block_size */,  32 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
-    NULL /* app_data */, aes_init_key,        aes_ctr_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ctr_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aes_256_ecb = {
-    NID_aes_256_ecb,     16 /* block_size */, 32 /* key_size */,
-    0 /* iv_len */,      sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
-    NULL /* app_data */, aes_init_key,        aes_ecb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+  out->nid = NID_aes_192_ctr;
+  out->block_size = 1;
+  out->key_len = 24;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_CTR_MODE;
+  out->init = aes_init_key;
+  out->cipher = aes_ctr_cipher;
+}
 
-static const EVP_CIPHER aes_256_ofb = {
-    NID_aes_256_ofb128,  1 /* block_size */,  32 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_OFB_MODE,
-    NULL /* app_data */, aes_init_key,        aes_ofb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ecb_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aes_256_gcm = {
-    NID_aes_256_gcm, 1 /* block_size */, 32 /* key_size */, 12 /* iv_len */,
-    sizeof(EVP_AES_GCM_CTX),
-    EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
-        EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
-        EVP_CIPH_FLAG_AEAD_CIPHER,
-    NULL /* app_data */, aes_gcm_init_key, aes_gcm_cipher, aes_gcm_cleanup,
-    aes_gcm_ctrl};
+  out->nid = NID_aes_192_ecb;
+  out->block_size = 16;
+  out->key_len = 24;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_ECB_MODE;
+  out->init = aes_init_key;
+  out->cipher = aes_ecb_cipher;
+}
+
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_gcm_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+
+  out->nid = NID_aes_192_gcm;
+  out->block_size = 1;
+  out->key_len = 24;
+  out->iv_len = 12;
+  out->ctx_size = sizeof(EVP_AES_GCM_CTX);
+  out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
+               EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
+               EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
+  out->init = aes_gcm_init_key;
+  out->cipher = aes_gcm_cipher;
+  out->cleanup = aes_gcm_cleanup;
+  out->ctrl = aes_gcm_ctrl;
+}
+
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_cbc_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+
+  out->nid = NID_aes_256_cbc;
+  out->block_size = 16;
+  out->key_len = 32;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_CBC_MODE;
+  out->init = aes_init_key;
+  out->cipher = aes_cbc_cipher;
+}
+
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ctr_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+
+  out->nid = NID_aes_256_ctr;
+  out->block_size = 1;
+  out->key_len = 32;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_CTR_MODE;
+  out->init = aes_init_key;
+  out->cipher = aes_ctr_cipher;
+}
+
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ecb_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+
+  out->nid = NID_aes_256_ecb;
+  out->block_size = 16;
+  out->key_len = 32;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_ECB_MODE;
+  out->init = aes_init_key;
+  out->cipher = aes_ecb_cipher;
+}
+
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ofb_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+
+  out->nid = NID_aes_256_ofb128;
+  out->block_size = 1;
+  out->key_len = 32;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_OFB_MODE;
+  out->init = aes_init_key;
+  out->cipher = aes_ofb_cipher;
+}
+
+DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_gcm_generic) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+
+  out->nid = NID_aes_256_gcm;
+  out->block_size = 1;
+  out->key_len = 32;
+  out->iv_len = 12;
+  out->ctx_size = sizeof(EVP_AES_GCM_CTX);
+  out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
+               EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
+               EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
+  out->init = aes_gcm_init_key;
+  out->cipher = aes_gcm_cipher;
+  out->cleanup = aes_gcm_cleanup;
+  out->ctrl = aes_gcm_ctrl;
+}
 
 #if !defined(OPENSSL_NO_ASM) && \
     (defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
@@ -867,107 +902,204 @@
   return 1;
 }
 
-static const EVP_CIPHER aesni_128_cbc = {
-    NID_aes_128_cbc,     16 /* block_size */, 16 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
-    NULL /* app_data */, aesni_init_key,      aesni_cbc_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_cbc) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aesni_128_ctr = {
-    NID_aes_128_ctr,     1 /* block_size */,  16 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
-    NULL /* app_data */, aesni_init_key,      aes_ctr_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+  out->nid = NID_aes_128_cbc;
+  out->block_size = 16;
+  out->key_len = 16;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_CBC_MODE;
+  out->init = aesni_init_key;
+  out->cipher = aesni_cbc_cipher;
+}
 
-static const EVP_CIPHER aesni_128_ecb = {
-    NID_aes_128_ecb,     16 /* block_size */, 16 /* key_size */,
-    0 /* iv_len */,      sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
-    NULL /* app_data */, aesni_init_key,      aesni_ecb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_ctr) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aesni_128_ofb = {
-    NID_aes_128_ofb128,  1 /* block_size */,  16 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_OFB_MODE,
-    NULL /* app_data */, aesni_init_key,      aes_ofb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+  out->nid = NID_aes_128_ctr;
+  out->block_size = 1;
+  out->key_len = 16;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_CTR_MODE;
+  out->init = aesni_init_key;
+  out->cipher = aes_ctr_cipher;
+}
 
-static const EVP_CIPHER aesni_128_gcm = {
-    NID_aes_128_gcm, 1 /* block_size */, 16 /* key_size */, 12 /* iv_len */,
-    sizeof(EVP_AES_GCM_CTX),
-    EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
-        EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
-        EVP_CIPH_FLAG_AEAD_CIPHER,
-    NULL /* app_data */, aesni_gcm_init_key, aes_gcm_cipher, aes_gcm_cleanup,
-    aes_gcm_ctrl};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_ecb) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
+  out->nid = NID_aes_128_ecb;
+  out->block_size = 16;
+  out->key_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_ECB_MODE;
+  out->init = aesni_init_key;
+  out->cipher = aesni_ecb_cipher;
+}
 
-static const EVP_CIPHER aesni_192_cbc = {
-    NID_aes_192_cbc,     16 /* block_size */, 24 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
-    NULL /* app_data */, aesni_init_key,      aesni_cbc_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_ofb) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aesni_192_ctr = {
-    NID_aes_192_ctr,     1 /* block_size */,  24 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
-    NULL /* app_data */, aesni_init_key,      aes_ctr_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+  out->nid = NID_aes_128_ofb128;
+  out->block_size = 1;
+  out->key_len = 16;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_OFB_MODE;
+  out->init = aesni_init_key;
+  out->cipher = aes_ofb_cipher;
+}
 
-static const EVP_CIPHER aesni_192_ecb = {
-    NID_aes_192_ecb,     16 /* block_size */, 24 /* key_size */,
-    0 /* iv_len */,      sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
-    NULL /* app_data */, aesni_init_key,      aesni_ecb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_gcm) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aesni_192_gcm = {
-    NID_aes_192_gcm, 1 /* block_size */, 24 /* key_size */, 12 /* iv_len */,
-    sizeof(EVP_AES_GCM_CTX),
-    EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
-        EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
-        EVP_CIPH_FLAG_AEAD_CIPHER,
-    NULL /* app_data */, aesni_gcm_init_key, aes_gcm_cipher, aes_gcm_cleanup,
-    aes_gcm_ctrl};
+  out->nid = NID_aes_128_gcm;
+  out->block_size = 1;
+  out->key_len = 16;
+  out->iv_len = 12;
+  out->ctx_size = sizeof(EVP_AES_GCM_CTX);
+  out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
+               EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
+               EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
+  out->init = aesni_gcm_init_key;
+  out->cipher = aes_gcm_cipher;
+  out->cleanup = aes_gcm_cleanup;
+  out->ctrl = aes_gcm_ctrl;
+}
 
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_cbc) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aesni_256_cbc = {
-    NID_aes_256_cbc,     16 /* block_size */, 32 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
-    NULL /* app_data */, aesni_init_key,      aesni_cbc_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+  out->nid = NID_aes_192_cbc;
+  out->block_size = 16;
+  out->key_len = 24;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_CBC_MODE;
+  out->init = aesni_init_key;
+  out->cipher = aesni_cbc_cipher;
+}
 
-static const EVP_CIPHER aesni_256_ctr = {
-    NID_aes_256_ctr,     1 /* block_size */,  32 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
-    NULL /* app_data */, aesni_init_key,      aes_ctr_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_ctr) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aesni_256_ecb = {
-    NID_aes_256_ecb,     16 /* block_size */, 32 /* key_size */,
-    0 /* iv_len */,      sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
-    NULL /* app_data */, aesni_init_key,      aesni_ecb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+  out->nid = NID_aes_192_ctr;
+  out->block_size = 1;
+  out->key_len = 24;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_CTR_MODE;
+  out->init = aesni_init_key;
+  out->cipher = aes_ctr_cipher;
+}
 
-static const EVP_CIPHER aesni_256_ofb = {
-    NID_aes_256_ofb128,  1 /* block_size */,  32 /* key_size */,
-    16 /* iv_len */,     sizeof(EVP_AES_KEY), EVP_CIPH_OFB_MODE,
-    NULL /* app_data */, aesni_init_key,      aes_ofb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */};
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_ecb) {
+  memset(out, 0, sizeof(EVP_CIPHER));
 
-static const EVP_CIPHER aesni_256_gcm = {
-    NID_aes_256_gcm, 1 /* block_size */, 32 /* key_size */, 12 /* iv_len */,
-    sizeof(EVP_AES_GCM_CTX),
-    EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
-        EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY |
-        EVP_CIPH_FLAG_AEAD_CIPHER,
-    NULL /* app_data */, aesni_gcm_init_key, aes_gcm_cipher, aes_gcm_cleanup,
-    aes_gcm_ctrl};
+  out->nid = NID_aes_192_ecb;
+  out->block_size = 16;
+  out->key_len = 24;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_ECB_MODE;
+  out->init = aesni_init_key;
+  out->cipher = aesni_ecb_cipher;
+}
+
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_gcm) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+
+  out->nid = NID_aes_192_gcm;
+  out->block_size = 1;
+  out->key_len = 24;
+  out->iv_len = 12;
+  out->ctx_size = sizeof(EVP_AES_GCM_CTX);
+  out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
+               EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
+               EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
+  out->init = aesni_gcm_init_key;
+  out->cipher = aes_gcm_cipher;
+  out->cleanup = aes_gcm_cleanup;
+  out->ctrl = aes_gcm_ctrl;
+}
+
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_cbc) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+
+  out->nid = NID_aes_256_cbc;
+  out->block_size = 16;
+  out->key_len = 32;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_CBC_MODE;
+  out->init = aesni_init_key;
+  out->cipher = aesni_cbc_cipher;
+}
+
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_ctr) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+
+  out->nid = NID_aes_256_ctr;
+  out->block_size = 1;
+  out->key_len = 32;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_CTR_MODE;
+  out->init = aesni_init_key;
+  out->cipher = aes_ctr_cipher;
+}
+
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_ecb) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+
+  out->nid = NID_aes_256_ecb;
+  out->block_size = 16;
+  out->key_len = 32;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_ECB_MODE;
+  out->init = aesni_init_key;
+  out->cipher = aesni_ecb_cipher;
+}
+
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_ofb) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+
+  out->nid = NID_aes_256_ofb128;
+  out->block_size = 1;
+  out->key_len = 32;
+  out->iv_len = 16;
+  out->ctx_size = sizeof(EVP_AES_KEY);
+  out->flags = EVP_CIPH_OFB_MODE;
+  out->init = aesni_init_key;
+  out->cipher = aes_ofb_cipher;
+}
+
+DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_gcm) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+
+  out->nid = NID_aes_256_gcm;
+  out->block_size = 1;
+  out->key_len = 32;
+  out->iv_len = 12;
+  out->ctx_size = sizeof(EVP_AES_GCM_CTX);
+  out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
+               EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
+               EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY |
+               EVP_CIPH_FLAG_AEAD_CIPHER;
+  out->init = aesni_gcm_init_key;
+  out->cipher = aes_gcm_cipher;
+  out->cleanup = aes_gcm_cleanup;
+  out->ctrl = aes_gcm_ctrl;
+}
 
 #define EVP_CIPHER_FUNCTION(keybits, mode)             \
   const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \
     if (aesni_capable()) {                             \
-      return &aesni_##keybits##_##mode;                \
+      return aesni_##keybits##_##mode();               \
     } else {                                           \
-      return &aes_##keybits##_##mode;                  \
+      return aes_##keybits##_##mode##_generic();       \
     }                                                  \
   }
 
@@ -979,7 +1111,7 @@
 
 #define EVP_CIPHER_FUNCTION(keybits, mode)             \
   const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \
-    return &aes_##keybits##_##mode;                    \
+    return aes_##keybits##_##mode##_generic();         \
   }
 
 #endif
@@ -1147,35 +1279,31 @@
   return 1;
 }
 
-static const EVP_AEAD aead_aes_128_gcm = {
-    16,                       /* key len */
-    12,                       /* nonce len */
-    EVP_AEAD_AES_GCM_TAG_LEN, /* overhead */
-    EVP_AEAD_AES_GCM_TAG_LEN, /* max tag length */
-    aead_aes_gcm_init,
-    NULL, /* init_with_direction */
-    aead_aes_gcm_cleanup,
-    aead_aes_gcm_seal,
-    aead_aes_gcm_open,
-    NULL,                     /* get_iv */
-};
+DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm) {
+  memset(out, 0, sizeof(EVP_AEAD));
 
-static const EVP_AEAD aead_aes_256_gcm = {
-    32,                       /* key len */
-    12,                       /* nonce len */
-    EVP_AEAD_AES_GCM_TAG_LEN, /* overhead */
-    EVP_AEAD_AES_GCM_TAG_LEN, /* max tag length */
-    aead_aes_gcm_init,
-    NULL, /* init_with_direction */
-    aead_aes_gcm_cleanup,
-    aead_aes_gcm_seal,
-    aead_aes_gcm_open,
-    NULL,                     /* get_iv */
-};
+  out->key_len = 16;
+  out->nonce_len = 12;
+  out->overhead = EVP_AEAD_AES_GCM_TAG_LEN;
+  out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN;
+  out->init = aead_aes_gcm_init;
+  out->cleanup = aead_aes_gcm_cleanup;
+  out->seal = aead_aes_gcm_seal;
+  out->open = aead_aes_gcm_open;
+}
 
-const EVP_AEAD *EVP_aead_aes_128_gcm(void) { return &aead_aes_128_gcm; }
+DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm) {
+  memset(out, 0, sizeof(EVP_AEAD));
 
-const EVP_AEAD *EVP_aead_aes_256_gcm(void) { return &aead_aes_256_gcm; }
+  out->key_len = 32;
+  out->nonce_len = 12;
+  out->overhead = EVP_AEAD_AES_GCM_TAG_LEN;
+  out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN;
+  out->init = aead_aes_gcm_init;
+  out->cleanup = aead_aes_gcm_cleanup;
+  out->seal = aead_aes_gcm_seal;
+  out->open = aead_aes_gcm_open;
+}
 
 #if defined(BORINGSSL_FIPS)
 #define FIPS_AES_GCM_IV_LEN 12
@@ -1246,39 +1374,32 @@
   return ret;
 }
 
-static const EVP_AEAD aead_aes_128_gcm_fips_testonly = {
-    16,                                             /* key len */
-    0,                                              /* nonce len */
-    EVP_AEAD_AES_GCM_TAG_LEN + FIPS_AES_GCM_IV_LEN, /* overhead */
-    EVP_AEAD_AES_GCM_TAG_LEN, /* max tag length */
-    aead_aes_gcm_init,
-    NULL, /* init_with_direction */
-    aead_aes_gcm_cleanup,
-    aead_aes_gcm_fips_testonly_seal,
-    aead_aes_gcm_fips_testonly_open,
-    NULL, /* get_iv */
-};
+DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm_fips_testonly) {
+  memset(out, 0, sizeof(EVP_AEAD));
 
-static const EVP_AEAD aead_aes_256_gcm_fips_testonly = {
-    32,                                             /* key len */
-    0,                                              /* nonce len */
-    EVP_AEAD_AES_GCM_TAG_LEN + FIPS_AES_GCM_IV_LEN, /* overhead */
-    EVP_AEAD_AES_GCM_TAG_LEN, /* max tag length */
-    aead_aes_gcm_init,
-    NULL, /* init_with_direction */
-    aead_aes_gcm_cleanup,
-    aead_aes_gcm_fips_testonly_seal,
-    aead_aes_gcm_fips_testonly_open,
-    NULL, /* get_iv */
-};
-
-const EVP_AEAD *EVP_aead_aes_128_gcm_fips_testonly(void) {
-  return &aead_aes_128_gcm_fips_testonly;
+  out->key_len = 16;
+  out->nonce_len = 0;
+  out->overhead = EVP_AEAD_AES_GCM_TAG_LEN + FIPS_AES_GCM_IV_LEN;
+  out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN;
+  out->init = aead_aes_gcm_init;
+  out->cleanup = aead_aes_gcm_cleanup;
+  out->seal = aead_aes_gcm_fips_testonly_seal;
+  out->open = aead_aes_gcm_fips_testonly_open;
 }
 
-const EVP_AEAD *EVP_aead_aes_256_gcm_fips_testonly(void) {
-  return &aead_aes_256_gcm_fips_testonly;
+DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm_fips_testonly) {
+  memset(out, 0, sizeof(EVP_AEAD));
+
+  out->key_len = 32;
+  out->nonce_len = 0;
+  out->overhead = EVP_AEAD_AES_GCM_TAG_LEN + FIPS_AES_GCM_IV_LEN;
+  out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN;
+  out->init = aead_aes_gcm_init;
+  out->cleanup = aead_aes_gcm_cleanup;
+  out->seal = aead_aes_gcm_fips_testonly_seal;
+  out->open = aead_aes_gcm_fips_testonly_open;
 }
+
 #endif  /* BORINGSSL_FIPS */
 
 int EVP_has_aes_hardware(void) {
diff --git a/crypto/cipher/e_des.c b/crypto/fipsmodule/cipher/e_des.c
similarity index 74%
rename from crypto/cipher/e_des.c
rename to crypto/fipsmodule/cipher/e_des.c
index e72f003..eaba6d7 100644
--- a/crypto/cipher/e_des.c
+++ b/crypto/fipsmodule/cipher/e_des.c
@@ -59,6 +59,7 @@
 #include <openssl/nid.h>
 
 #include "internal.h"
+#include "../delocate.h"
 
 
 typedef struct {
@@ -87,14 +88,17 @@
   return 1;
 }
 
-static const EVP_CIPHER des_cbc = {
-    NID_des_cbc,         8 /* block_size */,  8 /* key_size */,
-    8 /* iv_len */,      sizeof(EVP_DES_KEY), EVP_CIPH_CBC_MODE,
-    NULL /* app_data */, des_init_key,        des_cbc_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */, };
-
-const EVP_CIPHER *EVP_des_cbc(void) { return &des_cbc; }
-
+DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_cbc) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+  out->nid = NID_des_cbc;
+  out->block_size = 8;
+  out->key_len = 8;
+  out->iv_len = 8;
+  out->ctx_size = sizeof(EVP_DES_KEY);
+  out->flags = EVP_CIPH_CBC_MODE;
+  out->init = des_init_key;
+  out->cipher = des_cbc_cipher;
+}
 
 static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
                           size_t in_len) {
@@ -111,14 +115,17 @@
   return 1;
 }
 
-static const EVP_CIPHER des_ecb = {
-    NID_des_ecb,         8 /* block_size */,  8 /* key_size */,
-    0 /* iv_len */,      sizeof(EVP_DES_KEY), EVP_CIPH_ECB_MODE,
-    NULL /* app_data */, des_init_key,        des_ecb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */, };
-
-const EVP_CIPHER *EVP_des_ecb(void) { return &des_ecb; }
-
+DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ecb) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+  out->nid = NID_des_ecb;
+  out->block_size = 8;
+  out->key_len = 8;
+  out->iv_len = 0;
+  out->ctx_size = sizeof(EVP_DES_KEY);
+  out->flags = EVP_CIPH_ECB_MODE;
+  out->init = des_init_key;
+  out->cipher = des_ecb_cipher;
+}
 
 typedef struct {
   union {
@@ -127,7 +134,6 @@
   } ks;
 } DES_EDE_KEY;
 
-
 static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
                              const uint8_t *iv, int enc) {
   DES_cblock *deskey = (DES_cblock *)key;
@@ -150,14 +156,17 @@
   return 1;
 }
 
-static const EVP_CIPHER des_ede3_cbc = {
-    NID_des_ede3_cbc,    8 /* block_size */,  24 /* key_size */,
-    8 /* iv_len */,      sizeof(DES_EDE_KEY), EVP_CIPH_CBC_MODE,
-    NULL /* app_data */, des_ede3_init_key,   des_ede3_cbc_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */, };
-
-const EVP_CIPHER *EVP_des_ede3_cbc(void) { return &des_ede3_cbc; }
-
+DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede3_cbc) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+  out->nid = NID_des_ede3_cbc;
+  out->block_size = 8;
+  out->key_len = 24;
+  out->iv_len = 8;
+  out->ctx_size = sizeof(DES_EDE_KEY);
+  out->flags = EVP_CIPH_CBC_MODE;
+  out->init = des_ede3_init_key;
+  out->cipher = des_ede3_cbc_cipher;
+}
 
 static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
                              const uint8_t *iv, int enc) {
@@ -171,14 +180,17 @@
   return 1;
 }
 
-static const EVP_CIPHER des_ede_cbc = {
-    NID_des_ede_cbc,     8 /* block_size */,  16 /* key_size */,
-    8 /* iv_len */,      sizeof(DES_EDE_KEY), EVP_CIPH_CBC_MODE,
-    NULL /* app_data */, des_ede_init_key ,   des_ede3_cbc_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */, };
-
-const EVP_CIPHER *EVP_des_ede_cbc(void) { return &des_ede_cbc; }
-
+DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede_cbc) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+  out->nid = NID_des_ede_cbc;
+  out->block_size = 8;
+  out->key_len = 16;
+  out->iv_len = 8;
+  out->ctx_size = sizeof(DES_EDE_KEY);
+  out->flags = EVP_CIPH_CBC_MODE;
+  out->init = des_ede_init_key;
+  out->cipher = des_ede3_cbc_cipher;
+}
 
 static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
                               const uint8_t *in, size_t in_len) {
@@ -196,20 +208,26 @@
   return 1;
 }
 
-static const EVP_CIPHER des_ede_ecb = {
-    NID_des_ede_cbc,     8 /* block_size */,  16 /* key_size */,
-    0 /* iv_len */,      sizeof(DES_EDE_KEY), EVP_CIPH_ECB_MODE,
-    NULL /* app_data */, des_ede_init_key ,   des_ede_ecb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */, };
+DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+  out->nid = NID_des_ede_ecb;
+  out->block_size = 8;
+  out->key_len = 16;
+  out->iv_len = 0;
+  out->ctx_size = sizeof(DES_EDE_KEY);
+  out->flags = EVP_CIPH_ECB_MODE;
+  out->init = des_ede_init_key;
+  out->cipher = des_ede_ecb_cipher;
+}
 
-const EVP_CIPHER *EVP_des_ede(void) { return &des_ede_ecb; }
-
-
-static const EVP_CIPHER des_ede3_ecb = {
-    NID_des_ede3_cbc,    8 /* block_size */,  24 /* key_size */,
-    0 /* iv_len */,      sizeof(DES_EDE_KEY), EVP_CIPH_ECB_MODE,
-    NULL /* app_data */, des_ede3_init_key,   des_ede_ecb_cipher,
-    NULL /* cleanup */,  NULL /* ctrl */,
-};
-
-const EVP_CIPHER *EVP_des_ede3(void) { return &des_ede3_ecb; }
+DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede3) {
+  memset(out, 0, sizeof(EVP_CIPHER));
+  out->nid = NID_des_ede3_ecb;
+  out->block_size = 8;
+  out->key_len = 24;
+  out->iv_len = 0;
+  out->ctx_size = sizeof(DES_EDE_KEY);
+  out->flags = EVP_CIPH_ECB_MODE;
+  out->init = des_ede3_init_key;
+  out->cipher = des_ede_ecb_cipher;
+}
diff --git a/crypto/cipher/internal.h b/crypto/fipsmodule/cipher/internal.h
similarity index 64%
copy from crypto/cipher/internal.h
copy to crypto/fipsmodule/cipher/internal.h
index 52dbac2..9a01f52 100644
--- a/crypto/cipher/internal.h
+++ b/crypto/fipsmodule/cipher/internal.h
@@ -62,8 +62,8 @@
 #include <openssl/aead.h>
 #include <openssl/aes.h>
 
-#include "../internal.h"
-#include "../fipsmodule/modes/internal.h"
+#include "../../internal.h"
+#include "../modes/internal.h"
 
 #if defined(__cplusplus)
 extern "C" {
@@ -73,7 +73,6 @@
 /* EVP_CIPH_MODE_MASK contains the bits of |flags| that represent the mode. */
 #define EVP_CIPH_MODE_MASK 0x3f
 
-
 /* EVP_AEAD represents a specific AEAD algorithm. */
 struct evp_aead_st {
   uint8_t key_len;
@@ -103,61 +102,6 @@
                 size_t *out_len);
 };
 
-
-/* EVP_tls_cbc_get_padding determines the padding from the decrypted, TLS, CBC
- * record in |in|. This decrypted record should not include any "decrypted"
- * explicit IV. If the record is publicly invalid, it returns zero. Otherwise,
- * it returns one and sets |*out_padding_ok| to all ones (0xfff..f) if the
- * padding is valid and zero otherwise. It then sets |*out_len| to the length
- * with the padding removed or |in_len| if invalid.
- *
- * If the function returns one, it runs in time independent of the contents of
- * |in|. It is also guaranteed that |*out_len| >= |mac_size|, satisfying
- * |EVP_tls_cbc_copy_mac|'s precondition. */
-int EVP_tls_cbc_remove_padding(crypto_word_t *out_padding_ok, size_t *out_len,
-                               const uint8_t *in, size_t in_len,
-                               size_t block_size, size_t mac_size);
-
-/* EVP_tls_cbc_copy_mac copies |md_size| bytes from the end of the first
- * |in_len| bytes of |in| to |out| in constant time (independent of the concrete
- * value of |in_len|, which may vary within a 256-byte window). |in| must point
- * to a buffer of |orig_len| bytes.
- *
- * On entry:
- *   orig_len >= in_len >= md_size
- *   md_size <= EVP_MAX_MD_SIZE */
-void EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in,
-                          size_t in_len, size_t orig_len);
-
-/* EVP_tls_cbc_record_digest_supported returns 1 iff |md| is a hash function
- * which EVP_tls_cbc_digest_record supports. */
-int EVP_tls_cbc_record_digest_supported(const EVP_MD *md);
-
-/* EVP_tls_cbc_digest_record computes the MAC of a decrypted, padded TLS
- * record.
- *
- *   md: the hash function used in the HMAC.
- *     EVP_tls_cbc_record_digest_supported must return true for this hash.
- *   md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written.
- *   md_out_size: the number of output bytes is written here.
- *   header: the 13-byte, TLS record header.
- *   data: the record data itself
- *   data_plus_mac_size: the secret, reported length of the data and MAC
- *     once the padding has been removed.
- *   data_plus_mac_plus_padding_size: the public length of the whole
- *     record, including padding.
- *
- * On entry: by virtue of having been through one of the remove_padding
- * functions, above, we know that data_plus_mac_size is large enough to contain
- * a padding byte and MAC. (If the padding was invalid, it might contain the
- * padding too. ) */
-int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out,
-                              size_t *md_out_size, const uint8_t header[13],
-                              const uint8_t *data, size_t data_plus_mac_size,
-                              size_t data_plus_mac_plus_padding_size,
-                              const uint8_t *mac_secret,
-                              unsigned mac_secret_length);
-
 /* aes_ctr_set_key initialises |*aes_key| using |key_bytes| bytes from |key|,
  * where |key_bytes| must either be 16, 24 or 32. If not NULL, |*out_block| is
  * set to a function that encrypts single blocks. If not NULL, |*gcm_ctx| is
diff --git a/crypto/fipsmodule/delocate.go b/crypto/fipsmodule/delocate.go
index 7483fc7..c8ea063 100644
--- a/crypto/fipsmodule/delocate.go
+++ b/crypto/fipsmodule/delocate.go
@@ -248,6 +248,8 @@
 			break
 		}
 
+		orig := line
+
 		if strings.Contains(line, "OPENSSL_ia32cap_get@PLT") {
 			ia32capGetNeeded = true
 		}
@@ -307,7 +309,7 @@
 			ret = append(ret, line)
 			continue
 
-		case "leaq", "movq", "cmpq":
+		case "leaq", "movq", "cmpq", "cmovneq", "cmoveq":
 			if instr == "movq" && strings.Contains(line, "@GOTTPOFF(%rip)") {
 				// GOTTPOFF are offsets into the thread-local
 				// storage that are stored in the GOT. We have
@@ -332,13 +334,15 @@
 			}
 
 			target := args[0]
+			invertedCondition := ""
+
 			if strings.HasSuffix(target, "(%rip)") {
 				target = target[:len(target)-6]
 				if isGlobal := symbols[target]; isGlobal {
 					line = strings.Replace(line, target, localTargetName(target), 1)
 				}
 
-				if strings.Contains(line, "@GOTPCREL") && instr == "movq" {
+				if strings.Contains(line, "@GOTPCREL") && (instr == "movq" || instr == "cmoveq" || instr == "cmovneq") {
 					line = strings.Replace(line, "@GOTPCREL", "", -1)
 					target = strings.Replace(target, "@GOTPCREL", "", -1)
 
@@ -351,12 +355,24 @@
 						target = redirectorName
 					}
 
+					switch instr {
+					case "cmoveq":
+						invertedCondition = "ne"
+					case "cmovneq":
+						invertedCondition = "e"
+					}
+
+					if len(invertedCondition) > 0 {
+						ret = append(ret, "\t# Was " + orig)
+						ret = append(ret, "\tj" + invertedCondition + " 1f")
+					}
+
 					// Nobody actually wants to read the
 					// code of a function. This is a load
 					// from the GOT which, now that we're
 					// referencing the symbol directly,
 					// needs to be transformed into an LEA.
-					line = strings.Replace(line, "movq", "leaq", 1)
+					line = strings.Replace(line, instr, "leaq", 1)
 					instr = "leaq"
 				}
 
@@ -390,6 +406,9 @@
 			}
 
 			ret = append(ret, line)
+			if len(invertedCondition) > 0 {
+				ret = append(ret, "1:")
+			}
 			continue
 
 		case ".comm":
diff --git a/crypto/fipsmodule/rand/ctrdrbg.c b/crypto/fipsmodule/rand/ctrdrbg.c
index 5920837..2b22f5d 100644
--- a/crypto/fipsmodule/rand/ctrdrbg.c
+++ b/crypto/fipsmodule/rand/ctrdrbg.c
@@ -18,7 +18,7 @@
 #include <openssl/mem.h>
 
 #include "internal.h"
-#include "../../cipher/internal.h"
+#include "../cipher/internal.h"
 
 
 /* Section references in this file refer to SP 800-90Ar1:
diff --git a/util/all_tests.go b/util/all_tests.go
index 3e47ed2..1b912dc 100644
--- a/util/all_tests.go
+++ b/util/all_tests.go
@@ -252,7 +252,7 @@
 func shortTestName(test test) string {
 	var args []string
 	for _, arg := range test.args {
-		if test.args[0] == "crypto/evp/evp_test" || test.args[0] == "crypto/cipher/cipher_test" || test.args[0] == "crypto/cipher/aead_test" || !strings.HasSuffix(arg, ".txt") {
+		if test.args[0] == "crypto/evp/evp_test" || test.args[0] == "crypto/cipher_extra/cipher_test" || test.args[0] == "crypto/cipher_extra/aead_test" || !strings.HasSuffix(arg, ".txt") {
 			args = append(args, arg)
 		}
 	}
diff --git a/util/all_tests.json b/util/all_tests.json
index a3b2ed6..c9cddc0 100644
--- a/util/all_tests.json
+++ b/util/all_tests.json
@@ -1,36 +1,36 @@
 [
-	["crypto/cipher/aead_test", "aes-128-cbc-sha1-ssl3", "crypto/cipher/test/aes_128_cbc_sha1_ssl3_tests.txt"],
-	["crypto/cipher/aead_test", "aes-128-cbc-sha1-tls", "crypto/cipher/test/aes_128_cbc_sha1_tls_tests.txt"],
-	["crypto/cipher/aead_test", "aes-128-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/aes_128_cbc_sha1_tls_implicit_iv_tests.txt"],
-	["crypto/cipher/aead_test", "aes-128-cbc-sha256-tls", "crypto/cipher/test/aes_128_cbc_sha256_tls_tests.txt"],
-	["crypto/cipher/aead_test", "aes-128-ctr-hmac-sha256", "crypto/cipher/test/aes_128_ctr_hmac_sha256.txt"],
-	["crypto/cipher/aead_test", "aes-128-gcm", "crypto/cipher/test/aes_128_gcm_tests.txt"],
-	["crypto/cipher/aead_test", "aes-128-gcm", "crypto/cipher/test/nist_cavp/aes_128_gcm.txt"],
-	["crypto/cipher/aead_test", "aes-128-gcm-fips-testonly", "crypto/cipher/test/aes_128_gcm_fips_testonly_tests.txt"],
-	["crypto/cipher/aead_test", "aes-128-gcm-siv", "crypto/cipher/test/aes_128_gcm_siv_tests.txt"],
-	["crypto/cipher/aead_test", "aes-256-cbc-sha1-ssl3", "crypto/cipher/test/aes_256_cbc_sha1_ssl3_tests.txt"],
-	["crypto/cipher/aead_test", "aes-256-cbc-sha1-tls", "crypto/cipher/test/aes_256_cbc_sha1_tls_tests.txt"],
-	["crypto/cipher/aead_test", "aes-256-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/aes_256_cbc_sha1_tls_implicit_iv_tests.txt"],
-	["crypto/cipher/aead_test", "aes-256-cbc-sha256-tls", "crypto/cipher/test/aes_256_cbc_sha256_tls_tests.txt"],
-	["crypto/cipher/aead_test", "aes-256-cbc-sha384-tls", "crypto/cipher/test/aes_256_cbc_sha384_tls_tests.txt"],
-	["crypto/cipher/aead_test", "aes-256-ctr-hmac-sha256", "crypto/cipher/test/aes_256_ctr_hmac_sha256.txt"],
-	["crypto/cipher/aead_test", "aes-256-gcm", "crypto/cipher/test/aes_256_gcm_tests.txt"],
-	["crypto/cipher/aead_test", "aes-256-gcm", "crypto/cipher/test/nist_cavp/aes_256_gcm.txt"],
-	["crypto/cipher/aead_test", "aes-256-gcm-fips-testonly", "crypto/cipher/test/aes_256_gcm_fips_testonly_tests.txt"],
-	["crypto/cipher/aead_test", "aes-256-gcm-siv", "crypto/cipher/test/aes_256_gcm_siv_tests.txt"],
-	["crypto/cipher/aead_test", "chacha20-poly1305", "crypto/cipher/test/chacha20_poly1305_tests.txt"],
-	["crypto/cipher/aead_test", "des-ede3-cbc-sha1-ssl3", "crypto/cipher/test/des_ede3_cbc_sha1_ssl3_tests.txt"],
-	["crypto/cipher/aead_test", "des-ede3-cbc-sha1-tls", "crypto/cipher/test/des_ede3_cbc_sha1_tls_tests.txt"],
-	["crypto/cipher/aead_test", "des-ede3-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/des_ede3_cbc_sha1_tls_implicit_iv_tests.txt"],
-	["crypto/cipher/cipher_test", "crypto/cipher/test/cipher_tests.txt"],
-	["crypto/cipher/cipher_test", "crypto/cipher/test/nist_cavp/aes_128_cbc.txt"],
-	["crypto/cipher/cipher_test", "crypto/cipher/test/nist_cavp/aes_128_ctr.txt"],
-	["crypto/cipher/cipher_test", "crypto/cipher/test/nist_cavp/aes_192_cbc.txt"],
-	["crypto/cipher/cipher_test", "crypto/cipher/test/nist_cavp/aes_192_ctr.txt"],
-	["crypto/cipher/cipher_test", "crypto/cipher/test/nist_cavp/aes_256_cbc.txt"],
-	["crypto/cipher/cipher_test", "crypto/cipher/test/nist_cavp/aes_256_ctr.txt"],
-	["crypto/cipher/cipher_test", "crypto/cipher/test/nist_cavp/tdes_cbc.txt"],
-	["crypto/cipher/cipher_test", "crypto/cipher/test/nist_cavp/tdes_ecb.txt"],
+	["crypto/cipher_extra/aead_test", "aes-128-cbc-sha1-ssl3", "crypto/cipher_extra/test/aes_128_cbc_sha1_ssl3_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-128-cbc-sha1-tls", "crypto/cipher_extra/test/aes_128_cbc_sha1_tls_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-128-cbc-sha1-tls-implicit-iv", "crypto/cipher_extra/test/aes_128_cbc_sha1_tls_implicit_iv_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-128-cbc-sha256-tls", "crypto/cipher_extra/test/aes_128_cbc_sha256_tls_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-128-ctr-hmac-sha256", "crypto/cipher_extra/test/aes_128_ctr_hmac_sha256.txt"],
+	["crypto/cipher_extra/aead_test", "aes-128-gcm", "crypto/cipher_extra/test/aes_128_gcm_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-128-gcm", "crypto/cipher_extra/test/nist_cavp/aes_128_gcm.txt"],
+	["crypto/cipher_extra/aead_test", "aes-128-gcm-fips-testonly", "crypto/cipher_extra/test/aes_128_gcm_fips_testonly_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-128-gcm-siv", "crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-256-cbc-sha1-ssl3", "crypto/cipher_extra/test/aes_256_cbc_sha1_ssl3_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-256-cbc-sha1-tls", "crypto/cipher_extra/test/aes_256_cbc_sha1_tls_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-256-cbc-sha1-tls-implicit-iv", "crypto/cipher_extra/test/aes_256_cbc_sha1_tls_implicit_iv_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-256-cbc-sha256-tls", "crypto/cipher_extra/test/aes_256_cbc_sha256_tls_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-256-cbc-sha384-tls", "crypto/cipher_extra/test/aes_256_cbc_sha384_tls_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-256-ctr-hmac-sha256", "crypto/cipher_extra/test/aes_256_ctr_hmac_sha256.txt"],
+	["crypto/cipher_extra/aead_test", "aes-256-gcm", "crypto/cipher_extra/test/aes_256_gcm_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-256-gcm", "crypto/cipher_extra/test/nist_cavp/aes_256_gcm.txt"],
+	["crypto/cipher_extra/aead_test", "aes-256-gcm-fips-testonly", "crypto/cipher_extra/test/aes_256_gcm_fips_testonly_tests.txt"],
+	["crypto/cipher_extra/aead_test", "aes-256-gcm-siv", "crypto/cipher_extra/test/aes_256_gcm_siv_tests.txt"],
+	["crypto/cipher_extra/aead_test", "chacha20-poly1305", "crypto/cipher_extra/test/chacha20_poly1305_tests.txt"],
+	["crypto/cipher_extra/aead_test", "des-ede3-cbc-sha1-ssl3", "crypto/cipher_extra/test/des_ede3_cbc_sha1_ssl3_tests.txt"],
+	["crypto/cipher_extra/aead_test", "des-ede3-cbc-sha1-tls", "crypto/cipher_extra/test/des_ede3_cbc_sha1_tls_tests.txt"],
+	["crypto/cipher_extra/aead_test", "des-ede3-cbc-sha1-tls-implicit-iv", "crypto/cipher_extra/test/des_ede3_cbc_sha1_tls_implicit_iv_tests.txt"],
+	["crypto/cipher_extra/cipher_test", "crypto/cipher_extra/test/cipher_tests.txt"],
+	["crypto/cipher_extra/cipher_test", "crypto/cipher_extra/test/nist_cavp/aes_128_cbc.txt"],
+	["crypto/cipher_extra/cipher_test", "crypto/cipher_extra/test/nist_cavp/aes_128_ctr.txt"],
+	["crypto/cipher_extra/cipher_test", "crypto/cipher_extra/test/nist_cavp/aes_192_cbc.txt"],
+	["crypto/cipher_extra/cipher_test", "crypto/cipher_extra/test/nist_cavp/aes_192_ctr.txt"],
+	["crypto/cipher_extra/cipher_test", "crypto/cipher_extra/test/nist_cavp/aes_256_cbc.txt"],
+	["crypto/cipher_extra/cipher_test", "crypto/cipher_extra/test/nist_cavp/aes_256_ctr.txt"],
+	["crypto/cipher_extra/cipher_test", "crypto/cipher_extra/test/nist_cavp/tdes_cbc.txt"],
+	["crypto/cipher_extra/cipher_test", "crypto/cipher_extra/test/nist_cavp/tdes_ecb.txt"],
 	["crypto/crypto_test"],
 	["crypto/curve25519/ed25519_test", "crypto/curve25519/ed25519_tests.txt"],
 	["crypto/digest_extra/digest_test"],