[openssl] master update

shane.lontis at oracle.com shane.lontis at oracle.com
Mon Aug 26 07:06:49 UTC 2019


The branch master has been updated
       via  4a42e2640499ce46d2733c4316c5fe4594a37c54 (commit)
      from  37a830e729f56cfc7b893f321880ac52f1b35cdb (commit)


- Log -----------------------------------------------------------------
commit 4a42e2640499ce46d2733c4316c5fe4594a37c54
Author: Shane Lontis <shane.lontis at oracle.com>
Date:   Mon Aug 26 17:05:08 2019 +1000

    Cleanup ciphers and Add 3des ciphers.
    
    Moved the relevant ciphers into default and restructed headers to allow the move.
    This removed most of the cases of #ifdef NO_XXX (which are now specified in build.info)
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/9482)

-----------------------------------------------------------------------

Summary of changes:
 crypto/des/build.info                              |   9 +-
 crypto/err/openssl.txt                             |   1 +
 crypto/evp/evp_enc.c                               |  39 +++-
 crypto/include/internal/ciphermode_platform.h      |   7 +
 doc/man7/provider-cipher.pod                       |   6 +
 include/openssl/core_names.h                       |   1 +
 providers/common/ciphers/block.c                   |   1 +
 providers/common/ciphers/build.info                |  23 ++-
 providers/common/ciphers/cipher_aes.c              |   3 +-
 providers/common/ciphers/cipher_aes.h              |   1 +
 providers/common/ciphers/cipher_aes_ccm.c          |   2 +
 providers/common/ciphers/cipher_aes_ccm_hw.c       |  64 +++++++
 .../common/ciphers/cipher_aes_ccm_hw_aesni.inc     |   5 +-
 providers/common/ciphers/cipher_aes_ccm_hw_t4.inc  |   2 +-
 providers/common/ciphers/cipher_aes_gcm.c          |   2 +
 providers/common/ciphers/cipher_aes_gcm_hw.c       |  78 ++++++++
 .../common/ciphers/cipher_aes_gcm_hw_aesni.inc     |   5 +-
 providers/common/ciphers/cipher_aes_gcm_hw_t4.inc  |   2 +-
 providers/common/ciphers/cipher_aes_hw.c           |   3 +-
 providers/common/ciphers/cipher_ccm.c              |   2 +
 providers/common/ciphers/cipher_ccm_hw.c           |  76 ++------
 providers/common/ciphers/cipher_common.c           |  84 ++++-----
 providers/common/ciphers/cipher_common_hw.c        |   3 -
 providers/common/ciphers/cipher_gcm.c              |   2 +
 providers/common/ciphers/cipher_gcm_hw.c           | 101 +----------
 providers/common/ciphers/cipher_locl.h             | 194 ++------------------
 providers/common/ciphers/cipher_tdes.c             | 116 ++++++++++++
 providers/common/ciphers/cipher_tdes_hw.c          |  82 +++++++++
 .../common/include/internal/ciphers/cipher_aead.h  |  49 +++++
 .../{ => include/internal}/ciphers/cipher_ccm.h    |  27 ++-
 .../{ => include/internal}/ciphers/cipher_gcm.h    |  38 ++--
 .../common/include/internal/ciphers/cipher_tdes.h  |  96 ++++++++++
 .../internal/ciphers/ciphercommon.h}               |  86 +++------
 providers/common/include/internal/provider_algs.h  |  18 ++
 .../common/include/internal/providercommonerr.h    |   3 +-
 providers/common/provider_err.c                    |   2 +
 providers/default/build.info                       |   2 +-
 providers/default/ciphers/build.info               |  22 +++
 .../{common => default}/ciphers/cipher_aria.c      |   3 +-
 .../{common => default}/ciphers/cipher_aria.h      |   7 +-
 .../{common => default}/ciphers/cipher_aria_ccm.c  |   6 +-
 providers/default/ciphers/cipher_aria_ccm.h        |  22 +++
 .../ciphers/cipher_aria_ccm_hw.c}                  |   4 +-
 .../{common => default}/ciphers/cipher_aria_gcm.c  |   3 +-
 providers/default/ciphers/cipher_aria_gcm.h        |  22 +++
 .../ciphers/cipher_aria_gcm_hw.c}                  |   7 +-
 .../{common => default}/ciphers/cipher_aria_hw.c   |   2 +-
 .../{common => default}/ciphers/cipher_camellia.c  |   5 +-
 .../{common => default}/ciphers/cipher_camellia.h  |  11 +-
 .../ciphers/cipher_camellia_hw.c                   |   5 +-
 .../ciphers/cipher_camellia_hw_t4.inc              |   0
 providers/default/ciphers/cipher_desx.c            |  15 ++
 providers/default/ciphers/cipher_desx_hw.c         |  62 +++++++
 providers/default/ciphers/cipher_tdes_default.c    |  29 +++
 providers/default/ciphers/cipher_tdes_default.h    |  25 +++
 providers/default/ciphers/cipher_tdes_default_hw.c | 140 +++++++++++++++
 providers/default/ciphers/cipher_tdes_wrap.c       | 199 +++++++++++++++++++++
 providers/default/ciphers/cipher_tdes_wrap_hw.c    |  14 ++
 providers/default/defltprov.c                      |  12 ++
 providers/fips/fipsprov.c                          |   2 +
 test/recipes/30-test_evp_data/evpciph.txt          |  10 ++
 61 files changed, 1315 insertions(+), 547 deletions(-)
 create mode 100644 providers/common/ciphers/cipher_aes_ccm_hw.c
 create mode 100644 providers/common/ciphers/cipher_aes_gcm_hw.c
 create mode 100644 providers/common/ciphers/cipher_tdes.c
 create mode 100644 providers/common/ciphers/cipher_tdes_hw.c
 create mode 100644 providers/common/include/internal/ciphers/cipher_aead.h
 rename providers/common/{ => include/internal}/ciphers/cipher_ccm.h (87%)
 rename providers/common/{ => include/internal}/ciphers/cipher_gcm.h (83%)
 create mode 100644 providers/common/include/internal/ciphers/cipher_tdes.h
 copy providers/common/{ciphers/cipher_locl.h => include/internal/ciphers/ciphercommon.h} (61%)
 create mode 100644 providers/default/ciphers/build.info
 rename providers/{common => default}/ciphers/cipher_aria.c (97%)
 rename providers/{common => default}/ciphers/cipher_aria.h (92%)
 rename providers/{common => default}/ciphers/cipher_aria_ccm.c (94%)
 create mode 100644 providers/default/ciphers/cipher_aria_ccm.h
 rename providers/{common/ciphers/cipher_aria_ccm_hw.inc => default/ciphers/cipher_aria_ccm_hw.c} (89%)
 rename providers/{common => default}/ciphers/cipher_aria_gcm.c (94%)
 create mode 100644 providers/default/ciphers/cipher_aria_gcm.h
 rename providers/{common/ciphers/cipher_aria_gcm_hw.inc => default/ciphers/cipher_aria_gcm_hw.c} (84%)
 rename providers/{common => default}/ciphers/cipher_aria_hw.c (98%)
 rename providers/{common => default}/ciphers/cipher_camellia.c (97%)
 rename providers/{common => default}/ciphers/cipher_camellia.h (81%)
 rename providers/{common => default}/ciphers/cipher_camellia_hw.c (96%)
 rename providers/{common => default}/ciphers/cipher_camellia_hw_t4.inc (100%)
 create mode 100644 providers/default/ciphers/cipher_desx.c
 create mode 100644 providers/default/ciphers/cipher_desx_hw.c
 create mode 100644 providers/default/ciphers/cipher_tdes_default.c
 create mode 100644 providers/default/ciphers/cipher_tdes_default.h
 create mode 100644 providers/default/ciphers/cipher_tdes_default_hw.c
 create mode 100644 providers/default/ciphers/cipher_tdes_wrap.c
 create mode 100644 providers/default/ciphers/cipher_tdes_wrap_hw.c

diff --git a/crypto/des/build.info b/crypto/des/build.info
index 474d14e229..33dd90c89a 100644
--- a/crypto/des/build.info
+++ b/crypto/des/build.info
@@ -13,13 +13,14 @@ IF[{- !$disabled{asm} -}]
 ENDIF
 
 LIBS=../../libcrypto
-SOURCE[../../libcrypto]=\
-        set_key.c  ecb_enc.c  cbc_enc.c \
-        ecb3_enc.c cfb64enc.c cfb64ede.c cfb_enc.c \
+$COMMON=set_key.c ecb3_enc.c $DESASM
+SOURCE[../../libcrypto]=$COMMON\
+        ecb_enc.c  cbc_enc.c \
+        cfb64enc.c cfb64ede.c cfb_enc.c \
         ofb64ede.c ofb64enc.c ofb_enc.c \
         str2key.c  pcbc_enc.c qud_cksm.c rand_key.c \
-        $DESASM \
         fcrypt.c xcbc_enc.c cbc_cksm.c
+SOURCE[../../providers/fips]=$COMMON
 
 GENERATE[des_enc-sparc.S]=asm/des_enc.m4
 GENERATE[dest4-sparcv9.S]=asm/dest4-sparcv9.pl $(PERLASM_SCHEME)
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index a545636447..58f6c4894f 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -2708,6 +2708,7 @@ PROP_R_TRAILING_CHARACTERS:110:trailing characters
 PROV_R_AES_KEY_SETUP_FAILED:101:aes key setup failed
 PROV_R_BAD_DECRYPT:100:bad decrypt
 PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed
+PROV_R_FAILED_TO_GENERATE_KEY:121:failed to generate key
 PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter
 PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter
 PROV_R_INVALID_AAD:108:invalid aad
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index e67e20c7ba..5723fe888e 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -217,6 +217,18 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
         case NID_camellia_256_ctr:
         case NID_camellia_192_ctr:
         case NID_camellia_128_ctr:
+        case NID_des_ede3_cbc:
+        case NID_des_ede3_ecb:
+        case NID_des_ede3_ofb64:
+        case NID_des_ede3_cfb64:
+        case NID_des_ede3_cfb8:
+        case NID_des_ede3_cfb1:
+        case NID_des_ede_cbc:
+        case NID_des_ede_ecb:
+        case NID_des_ede_ofb64:
+        case NID_des_ede_cfb64:
+        case NID_desx_cbc:
+        case NID_id_smime_alg_CMS3DESwrap:
             break;
         default:
             goto legacy;
@@ -1030,6 +1042,12 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
         params[0] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_KEYLEN, &arg);
         break;
     case EVP_CTRL_RAND_KEY:      /* Used by DES */
+        set_params = 0;
+        params[0] =
+            OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY,
+                                              ptr, (size_t)arg);
+        break;
+
     case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS: /* Used by DASYNC */
     case EVP_CTRL_INIT: /* TODO(3.0) Purely legacy, no provider counterpart */
     default:
@@ -1141,19 +1159,24 @@ const OSSL_PARAM *EVP_CIPHER_CTX_gettable_params(const EVP_CIPHER *cipher)
     return NULL;
 }
 
-#if !defined(FIPS_MODE)
-/* TODO(3.0): No support for RAND yet in the FIPS module */
 int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
 {
-    int kl;
     if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
         return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
-    kl = EVP_CIPHER_CTX_key_length(ctx);
-    if (kl <= 0 || RAND_priv_bytes(key, kl) <= 0)
-        return 0;
-    return 1;
+
+#ifdef FIPS_MODE
+    return 0;
+#else
+    {
+        int kl;
+
+        kl = EVP_CIPHER_CTX_key_length(ctx);
+        if (kl <= 0 || RAND_priv_bytes(key, kl) <= 0)
+            return 0;
+        return 1;
+    }
+#endif /* FIPS_MODE */
 }
-#endif
 
 int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
 {
diff --git a/crypto/include/internal/ciphermode_platform.h b/crypto/include/internal/ciphermode_platform.h
index 934d8136d3..5db2e23eb9 100644
--- a/crypto/include/internal/ciphermode_platform.h
+++ b/crypto/include/internal/ciphermode_platform.h
@@ -223,6 +223,7 @@ void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
 
 
 #  define SPARC_AES_CAPABLE       (OPENSSL_sparcv9cap_P[1] & CFR_AES)
+#  define SPARC_DES_CAPABLE       (OPENSSL_sparcv9cap_P[1] & CFR_DES)
 #  define HWAES_CAPABLE           (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX)
 #  define HWAES_set_encrypt_key aes_fx_set_encrypt_key
 #  define HWAES_set_decrypt_key aes_fx_set_decrypt_key
@@ -237,6 +238,12 @@ void aes_t4_encrypt(const unsigned char *in, unsigned char *out,
                     const AES_KEY *key);
 void aes_t4_decrypt(const unsigned char *in, unsigned char *out,
                     const AES_KEY *key);
+void des_t4_key_expand(const void *key, DES_key_schedule *ks);
+void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len,
+                             const DES_key_schedule ks[3], unsigned char iv[8]);
+void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len,
+                             const DES_key_schedule ks[3], unsigned char iv[8]);
+
 /*
  * Key-length specific subroutines were chosen for following reason.
  * Each SPARC T4 core can execute up to 8 threads which share core's
diff --git a/doc/man7/provider-cipher.pod b/doc/man7/provider-cipher.pod
index 2e2e73b68b..040a34c126 100644
--- a/doc/man7/provider-cipher.pod
+++ b/doc/man7/provider-cipher.pod
@@ -302,6 +302,12 @@ IV length and the tag length.
 
 Sets the IV length to be used for an AEAD cipher for the associated cipher ctx.
 
+=item B<OSSL_CIPHER_PARAM_RANDOM_KEY> (octet_string)
+
+Gets a implementation specific randomly generated key for the associated
+cipher ctx. This is currently only supported by 3DES (which sets the key to
+odd parity).
+
 =back
 
 =head1 RETURN VALUES
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 11232cb177..448bc50e8a 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -54,6 +54,7 @@ extern "C" {
 #define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD  "tlsaadpad"  /* size_t */
 #define OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED "tlsivfixed" /* octet_string */
 #define OSSL_CIPHER_PARAM_AEAD_IVLEN         "aeadivlen"  /* size_t */
+#define OSSL_CIPHER_PARAM_RANDOM_KEY         "randkey"    /* octet_string */
 
 /* digest parameters */
 #define OSSL_DIGEST_PARAM_XOFLEN    "xoflen"
diff --git a/providers/common/ciphers/block.c b/providers/common/ciphers/block.c
index 73e17e1a11..a53e9255c9 100644
--- a/providers/common/ciphers/block.c
+++ b/providers/common/ciphers/block.c
@@ -9,6 +9,7 @@
 
 #include <assert.h>
 #include "cipher_locl.h"
+#include "internal/providercommonerr.h"
 
 /*
  * Fills a single block of buffered data from the input, and returns the amount
diff --git a/providers/common/ciphers/build.info b/providers/common/ciphers/build.info
index 4a816d0f4d..0302cf151e 100644
--- a/providers/common/ciphers/build.info
+++ b/providers/common/ciphers/build.info
@@ -1,21 +1,18 @@
 LIBS=../../../libcrypto
 
+IF[{- !$disabled{des} -}]
+  $COMMON_DES=cipher_tdes.c cipher_tdes_hw.c
+ENDIF
+
 $COMMON=cipher_common.c cipher_common_hw.c block.c \
         cipher_aes.c cipher_aes_hw.c \
-        cipher_gcm.c cipher_aes_gcm.c cipher_gcm_hw.c \
-        cipher_ccm.c cipher_aes_ccm.c cipher_ccm_hw.c
-
+        cipher_gcm.c cipher_gcm_hw.c \
+        cipher_aes_gcm.c cipher_aes_gcm_hw.c \
+        cipher_ccm.c cipher_ccm_hw.c \
+        cipher_aes_ccm.c cipher_aes_ccm_hw.c \
+        $COMMON_DES
+        
 SOURCE[../../../libcrypto]=$COMMON
-IF[{- !$disabled{aria} -}]
-  SOURCE[../../../libcrypto]=\
-      cipher_aria.c cipher_aria_hw.c \
-      cipher_aria_gcm.c cipher_aria_ccm.c 
-ENDIF
-
-IF[{- !$disabled{camellia} -}]
-  SOURCE[../../../libcrypto]=\
-      cipher_camellia.c cipher_camellia_hw.c
-ENDIF
 INCLUDE[../../../libcrypto]=. ../../../crypto
 
 SOURCE[../../fips]=$COMMON
diff --git a/providers/common/ciphers/cipher_aes.c b/providers/common/ciphers/cipher_aes.c
index 15433bf326..46880e0bf7 100644
--- a/providers/common/ciphers/cipher_aes.c
+++ b/providers/common/ciphers/cipher_aes.c
@@ -9,7 +9,8 @@
 
 /* Dispatch functions for AES cipher modes ecb, cbc, ofb, cfb, ctr */
 
-#include "cipher_locl.h"
+#include "cipher_aes.h"
+#include "internal/provider_algs.h"
 
 static OSSL_OP_cipher_freectx_fn aes_freectx;
 static OSSL_OP_cipher_dupctx_fn aes_dupctx;
diff --git a/providers/common/ciphers/cipher_aes.h b/providers/common/ciphers/cipher_aes.h
index 6c4a6237c0..741b20f6e3 100644
--- a/providers/common/ciphers/cipher_aes.h
+++ b/providers/common/ciphers/cipher_aes.h
@@ -8,6 +8,7 @@
  */
 
 #include <openssl/aes.h>
+#include "internal/ciphers/ciphercommon.h"
 
 typedef struct prov_aes_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
diff --git a/providers/common/ciphers/cipher_aes_ccm.c b/providers/common/ciphers/cipher_aes_ccm.c
index 26b508df29..75f6e3fc9d 100644
--- a/providers/common/ciphers/cipher_aes_ccm.c
+++ b/providers/common/ciphers/cipher_aes_ccm.c
@@ -10,6 +10,8 @@
 /* Dispatch functions for AES CCM mode */
 
 #include "cipher_locl.h"
+#include "internal/ciphers/cipher_ccm.h"
+#include "internal/provider_algs.h"
 
 static void *aes_ccm_newctx(void *provctx, size_t keybits)
 {
diff --git a/providers/common/ciphers/cipher_aes_ccm_hw.c b/providers/common/ciphers/cipher_aes_ccm_hw.c
new file mode 100644
index 0000000000..f445cb73b7
--- /dev/null
+++ b/providers/common/ciphers/cipher_aes_ccm_hw.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* AES CCM mode */
+
+#include "cipher_locl.h"
+#include "internal/ciphers/cipher_ccm.h"
+
+#define AES_HW_CCM_SET_KEY_FN(fn_set_enc_key, fn_blk, fn_ccm_enc, fn_ccm_dec)  \
+    fn_set_enc_key(key, keylen * 8, &actx->ccm.ks.ks);                         \
+    CRYPTO_ccm128_init(&ctx->ccm_ctx, ctx->m, ctx->l, &actx->ccm.ks.ks,        \
+                       (block128_f)fn_blk);                                    \
+    ctx->str = ctx->enc ? (ccm128_f)fn_ccm_enc : (ccm128_f)fn_ccm_dec;         \
+    ctx->key_set = 1;
+
+static int ccm_generic_aes_initkey(PROV_CCM_CTX *ctx, const unsigned char *key,
+                                   size_t keylen)
+{
+    PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx;
+
+#ifdef HWAES_CAPABLE
+    if (HWAES_CAPABLE) {
+        AES_HW_CCM_SET_KEY_FN(HWAES_set_encrypt_key, HWAES_encrypt, NULL, NULL);
+    } else
+#endif /* HWAES_CAPABLE */
+
+#ifdef VPAES_CAPABLE
+    if (VPAES_CAPABLE) {
+        AES_HW_CCM_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_encrypt, NULL, NULL);
+    } else
+#endif
+    {
+        AES_HW_CCM_SET_KEY_FN(AES_set_encrypt_key, AES_encrypt, NULL, NULL)
+    }
+    return 1;
+}
+
+static const PROV_CCM_HW aes_ccm = {
+    ccm_generic_aes_initkey,
+    ccm_generic_setiv,
+    ccm_generic_setaad,
+    ccm_generic_auth_encrypt,
+    ccm_generic_auth_decrypt,
+    ccm_generic_gettag
+};
+
+#if defined(S390X_aes_128_CAPABLE)
+# include "cipher_aes_ccm_hw_s390x.inc"
+#elif defined(AESNI_CAPABLE)
+# include "cipher_aes_ccm_hw_aesni.inc"
+#elif defined(SPARC_AES_CAPABLE)
+# include "cipher_aes_ccm_hw_t4.inc"
+#else
+const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits)
+{
+    return &aes_ccm;
+}
+#endif
diff --git a/providers/common/ciphers/cipher_aes_ccm_hw_aesni.inc b/providers/common/ciphers/cipher_aes_ccm_hw_aesni.inc
index 0ace026a89..3a5e4a740d 100644
--- a/providers/common/ciphers/cipher_aes_ccm_hw_aesni.inc
+++ b/providers/common/ciphers/cipher_aes_ccm_hw_aesni.inc
@@ -17,8 +17,9 @@ static int ccm_aesni_initkey(PROV_CCM_CTX *ctx, const unsigned char *key,
 {
     PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx;
 
-    AES_CCM_SET_KEY_FN(aesni_set_encrypt_key, aesni_encrypt,
-                       aesni_ccm64_encrypt_blocks, aesni_ccm64_decrypt_blocks);
+    AES_HW_CCM_SET_KEY_FN(aesni_set_encrypt_key, aesni_encrypt,
+                          aesni_ccm64_encrypt_blocks,
+                          aesni_ccm64_decrypt_blocks);
     return 1;
 }
 
diff --git a/providers/common/ciphers/cipher_aes_ccm_hw_t4.inc b/providers/common/ciphers/cipher_aes_ccm_hw_t4.inc
index 0dc6efcef4..21bf6861e0 100644
--- a/providers/common/ciphers/cipher_aes_ccm_hw_t4.inc
+++ b/providers/common/ciphers/cipher_aes_ccm_hw_t4.inc
@@ -17,7 +17,7 @@ static int ccm_t4_aes_initkey(PROV_CCM_CTX *ctx, const unsigned char *key,
 {
     PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx;
 
-    AES_CCM_SET_KEY_FN(aes_t4_set_encrypt_key, aes_t4_encrypt, NULL, NULL);
+    AES_HW_CCM_SET_KEY_FN(aes_t4_set_encrypt_key, aes_t4_encrypt, NULL, NULL);
     return 1;
 }
 
diff --git a/providers/common/ciphers/cipher_aes_gcm.c b/providers/common/ciphers/cipher_aes_gcm.c
index 60df02588f..69c98f4e13 100644
--- a/providers/common/ciphers/cipher_aes_gcm.c
+++ b/providers/common/ciphers/cipher_aes_gcm.c
@@ -10,6 +10,8 @@
 /* Dispatch functions for AES GCM mode */
 
 #include "cipher_locl.h"
+#include "internal/ciphers/cipher_gcm.h"
+#include "internal/provider_algs.h"
 
 static void *aes_gcm_newctx(void *provctx, size_t keybits)
 {
diff --git a/providers/common/ciphers/cipher_aes_gcm_hw.c b/providers/common/ciphers/cipher_aes_gcm_hw.c
new file mode 100644
index 0000000000..3f56e6861d
--- /dev/null
+++ b/providers/common/ciphers/cipher_aes_gcm_hw.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* Dispatch functions for AES GCM mode */
+
+#include "cipher_locl.h"
+#include "internal/ciphers/cipher_gcm.h"
+
+static int generic_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
+                                   size_t keylen)
+{
+    PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
+    AES_KEY *ks = &actx->ks.ks;
+
+# ifdef HWAES_CAPABLE
+    if (HWAES_CAPABLE) {
+#  ifdef HWAES_ctr32_encrypt_blocks
+        GCM_HW_SET_KEY_CTR_FN(ks, HWAES_set_encrypt_key, HWAES_encrypt,
+                              HWAES_ctr32_encrypt_blocks);
+#  else
+        GCM_HW_SET_KEY_CTR_FN(ks, HWAES_set_encrypt_key, HWAES_encrypt, NULL);
+#  endif /* HWAES_ctr32_encrypt_blocks */
+    } else
+# endif /* HWAES_CAPABLE */
+
+# ifdef BSAES_CAPABLE
+    if (BSAES_CAPABLE) {
+        GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt,
+                              bsaes_ctr32_encrypt_blocks);
+    } else
+# endif /* BSAES_CAPABLE */
+
+# ifdef VPAES_CAPABLE
+    if (VPAES_CAPABLE) {
+        GCM_HW_SET_KEY_CTR_FN(ks, vpaes_set_encrypt_key, vpaes_encrypt, NULL);
+    } else
+# endif /* VPAES_CAPABLE */
+
+    {
+# ifdef AES_CTR_ASM
+        GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt,
+                              AES_ctr32_encrypt);
+# else
+        GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt, NULL);
+# endif /* AES_CTR_ASM */
+    }
+    ctx->key_set = 1;
+    return 1;
+}
+
+static const PROV_GCM_HW aes_gcm = {
+    generic_aes_gcm_initkey,
+    gcm_setiv,
+    gcm_aad_update,
+    gcm_cipher_update,
+    gcm_cipher_final,
+    gcm_one_shot
+};
+
+#if defined(S390X_aes_128_CAPABLE)
+# include "cipher_aes_gcm_hw_s390x.inc"
+#elif defined(AESNI_CAPABLE)
+# include "cipher_aes_gcm_hw_aesni.inc"
+#elif defined(SPARC_AES_CAPABLE)
+# include "cipher_aes_gcm_hw_t4.inc"
+#else
+const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits)
+{
+    return &aes_gcm;
+}
+#endif
+
diff --git a/providers/common/ciphers/cipher_aes_gcm_hw_aesni.inc b/providers/common/ciphers/cipher_aes_gcm_hw_aesni.inc
index c0cb231ff4..eb2a3f343a 100644
--- a/providers/common/ciphers/cipher_aes_gcm_hw_aesni.inc
+++ b/providers/common/ciphers/cipher_aes_gcm_hw_aesni.inc
@@ -17,9 +17,8 @@ static int aesni_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
 {
     PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
     AES_KEY *ks = &actx->ks.ks;
-
-    SET_KEY_CTR_FN(ks, aesni_set_encrypt_key, aesni_encrypt,
-                   aesni_ctr32_encrypt_blocks);
+    GCM_HW_SET_KEY_CTR_FN(ks, aesni_set_encrypt_key, aesni_encrypt,
+                          aesni_ctr32_encrypt_blocks);
     return 1;
 }
 
diff --git a/providers/common/ciphers/cipher_aes_gcm_hw_t4.inc b/providers/common/ciphers/cipher_aes_gcm_hw_t4.inc
index 0cb3f811e1..19e9ccb760 100644
--- a/providers/common/ciphers/cipher_aes_gcm_hw_t4.inc
+++ b/providers/common/ciphers/cipher_aes_gcm_hw_t4.inc
@@ -34,7 +34,7 @@ static int t4_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
         return 0;
     }
 
-    SET_KEY_CTR_FN(ks, aes_t4_set_encrypt_key, aes_t4_encrypt, ctr);
+    GCM_HW_SET_KEY_CTR_FN(ks, aes_t4_set_encrypt_key, aes_t4_encrypt, ctr);
     return 1;
 }
 
diff --git a/providers/common/ciphers/cipher_aes_hw.c b/providers/common/ciphers/cipher_aes_hw.c
index d80c63ecf9..e9b6388300 100644
--- a/providers/common/ciphers/cipher_aes_hw.c
+++ b/providers/common/ciphers/cipher_aes_hw.c
@@ -7,7 +7,8 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "cipher_locl.h"
+#include "cipher_aes.h"
+#include "internal/providercommonerr.h"
 
 static int cipher_hw_aes_initkey(PROV_CIPHER_CTX *dat,
                                  const unsigned char *key, size_t keylen)
diff --git a/providers/common/ciphers/cipher_ccm.c b/providers/common/ciphers/cipher_ccm.c
index fcfef73197..211b64f768 100644
--- a/providers/common/ciphers/cipher_ccm.c
+++ b/providers/common/ciphers/cipher_ccm.c
@@ -10,6 +10,8 @@
 /* Dispatch functions for ccm mode */
 
 #include "cipher_locl.h"
+#include "internal/ciphers/cipher_ccm.h"
+#include "internal/providercommonerr.h"
 
 static int ccm_cipher_internal(PROV_CCM_CTX *ctx, unsigned char *out,
                                size_t *padlen, const unsigned char *in,
diff --git a/providers/common/ciphers/cipher_ccm_hw.c b/providers/common/ciphers/cipher_ccm_hw.c
index 3036bfaa2e..b093b768e7 100644
--- a/providers/common/ciphers/cipher_ccm_hw.c
+++ b/providers/common/ciphers/cipher_ccm_hw.c
@@ -7,58 +7,29 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "cipher_locl.h"
+#include "internal/ciphers/ciphercommon.h"
+#include "internal/ciphers/cipher_ccm.h"
 
-#define AES_CCM_SET_KEY_FN(fn_set_enc_key, fn_blk, fn_ccm_enc, fn_ccm_dec)     \
-    fn_set_enc_key(key, keylen * 8, &actx->ccm.ks.ks);                         \
-    CRYPTO_ccm128_init(&ctx->ccm_ctx, ctx->m, ctx->l, &actx->ccm.ks.ks,        \
-                       (block128_f)fn_blk);                                    \
-    ctx->str = ctx->enc ? (ccm128_f)fn_ccm_enc : (ccm128_f)fn_ccm_dec;         \
-    ctx->key_set = 1;
-
-static int ccm_generic_aes_initkey(PROV_CCM_CTX *ctx, const unsigned char *key,
-                                   size_t keylen)
-{
-    PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx;
-
-#ifdef HWAES_CAPABLE
-    if (HWAES_CAPABLE) {
-        AES_CCM_SET_KEY_FN(HWAES_set_encrypt_key, HWAES_encrypt, NULL, NULL);
-    } else
-#endif /* HWAES_CAPABLE */
-#ifdef VPAES_CAPABLE
-    if (VPAES_CAPABLE) {
-        AES_CCM_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_encrypt, NULL, NULL);
-    } else
-#endif
-    {
-        AES_CCM_SET_KEY_FN(AES_set_encrypt_key, AES_encrypt, NULL, NULL)
-    }
-    return 1;
-}
-
-static int ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce,
-                             size_t nlen, size_t mlen)
+int ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce,
+                      size_t nlen, size_t mlen)
 {
     return CRYPTO_ccm128_setiv(&ctx->ccm_ctx, nonce, nlen, mlen) == 0;
 }
 
-static int ccm_generic_setaad(PROV_CCM_CTX *ctx, const unsigned char *aad,
-                              size_t alen)
+int ccm_generic_setaad(PROV_CCM_CTX *ctx, const unsigned char *aad, size_t alen)
 {
     CRYPTO_ccm128_aad(&ctx->ccm_ctx, aad, alen);
     return 1;
 }
 
-static int ccm_generic_gettag(PROV_CCM_CTX *ctx, unsigned char *tag,
-                              size_t tlen)
+int ccm_generic_gettag(PROV_CCM_CTX *ctx, unsigned char *tag, size_t tlen)
 {
     return CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, tlen) > 0;
 }
 
-static int ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
-                                    unsigned char *out, size_t len,
-                                    unsigned char *tag, size_t taglen)
+int ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
+                             unsigned char *out, size_t len,
+                             unsigned char *tag, size_t taglen)
 {
     int rv;
 
@@ -73,10 +44,9 @@ static int ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
     return rv;
 }
 
-static int ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
-                                    unsigned char *out, size_t len,
-                                    unsigned char *expected_tag,
-                                    size_t taglen)
+int ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
+                             unsigned char *out, size_t len,
+                             unsigned char *expected_tag, size_t taglen)
 {
     int rv = 0;
 
@@ -97,25 +67,3 @@ static int ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
     return rv;
 }
 
-static const PROV_CCM_HW aes_ccm = {
-    ccm_generic_aes_initkey,
-    ccm_generic_setiv,
-    ccm_generic_setaad,
-    ccm_generic_auth_encrypt,
-    ccm_generic_auth_decrypt,
-    ccm_generic_gettag
-};
-#if defined(S390X_aes_128_CAPABLE)
-# include "cipher_aes_ccm_hw_s390x.inc"
-#elif defined(AESNI_CAPABLE)
-# include "cipher_aes_ccm_hw_aesni.inc"
-#elif defined(SPARC_AES_CAPABLE)
-# include "cipher_aes_ccm_hw_t4.inc"
-#else
-const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits)
-{
-    return &aes_ccm;
-}
-#endif
-
-#include "cipher_aria_ccm_hw.inc"
diff --git a/providers/common/ciphers/cipher_common.c b/providers/common/ciphers/cipher_common.c
index 9c9047ca52..5abd2c0010 100644
--- a/providers/common/ciphers/cipher_common.c
+++ b/providers/common/ciphers/cipher_common.c
@@ -12,12 +12,11 @@
  */
 
 #include "cipher_locl.h"
-
-#define MAXCHUNK    ((size_t)1 << (sizeof(long) * 8 - 2))
-#define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4))
+#include "internal/provider_ctx.h"
+#include "internal/providercommonerr.h"
 
 /*-
- * Default cipher functions for OSSL_PARAM gettables and settables
+ * Generic cipher functions for OSSL_PARAM gettables and settables
  */
 static const OSSL_PARAM cipher_known_gettable_params[] = {
     OSSL_PARAM_int(OSSL_CIPHER_PARAM_MODE, NULL),
@@ -26,12 +25,12 @@ static const OSSL_PARAM cipher_known_gettable_params[] = {
     OSSL_PARAM_int(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL),
     OSSL_PARAM_END
 };
-const OSSL_PARAM *cipher_default_gettable_params(void)
+const OSSL_PARAM *cipher_generic_gettable_params(void)
 {
     return cipher_known_gettable_params;
 }
 
-int cipher_default_get_params(OSSL_PARAM params[], int md, unsigned long flags,
+int cipher_generic_get_params(OSSL_PARAM params[], int md, unsigned long flags,
                               int kbits, int blkbits, int ivbits)
 {
     OSSL_PARAM *p;
@@ -64,18 +63,8 @@ int cipher_default_get_params(OSSL_PARAM params[], int md, unsigned long flags,
     return 1;
 }
 
-static const OSSL_PARAM cipher_known_gettable_ctx_params[] = {
-    OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL),
-    OSSL_PARAM_int(OSSL_CIPHER_PARAM_IVLEN, NULL),
-    OSSL_PARAM_int(OSSL_CIPHER_PARAM_PADDING, NULL),
-    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_NUM, NULL),
-    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
-    OSSL_PARAM_END
-};
-const OSSL_PARAM *cipher_default_gettable_ctx_params(void)
-{
-    return cipher_known_gettable_ctx_params;
-}
+CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(cipher_generic)
+CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(cipher_generic)
 
 static const OSSL_PARAM cipher_known_settable_ctx_params[] = {
     OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL),
@@ -83,7 +72,7 @@ static const OSSL_PARAM cipher_known_settable_ctx_params[] = {
     OSSL_PARAM_int(OSSL_CIPHER_PARAM_NUM, NULL),
     OSSL_PARAM_END
 };
-const OSSL_PARAM *cipher_default_settable_ctx_params(void)
+const OSSL_PARAM *cipher_generic_settable_ctx_params(void)
 {
     return cipher_known_settable_ctx_params;
 }
@@ -125,11 +114,11 @@ static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx,
     ctx->enc = enc;
 
     if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) {
-        if (ivlen != GENERIC_BLOCK_SIZE) {
+        if (ivlen != ctx->ivlen) {
             ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
             return 0;
         }
-        memcpy(ctx->iv, iv, GENERIC_BLOCK_SIZE);
+        memcpy(ctx->iv, iv, ctx->ivlen);
     }
     if (key != NULL) {
         if (keylen != ctx->keylen) {
@@ -161,34 +150,34 @@ int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl,
 {
     size_t outlint = 0;
     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
-    size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, GENERIC_BLOCK_SIZE, &in,
-                                  &inl);
+    size_t blksz = ctx->blocksize;
+    size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, blksz, &in, &inl);
 
     /*
      * If we're decrypting and we end an update on a block boundary we hold
      * the last block back in case this is the last update call and the last
      * block is padded.
      */
-    if (ctx->bufsz == GENERIC_BLOCK_SIZE && (ctx->enc || inl > 0 || !ctx->pad)) {
-        if (outsize < GENERIC_BLOCK_SIZE) {
+    if (ctx->bufsz == blksz && (ctx->enc || inl > 0 || !ctx->pad)) {
+        if (outsize < blksz) {
             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
             return 0;
         }
-        if (!ctx->hw->cipher(ctx, out, ctx->buf, GENERIC_BLOCK_SIZE)) {
+        if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
             return 0;
         }
         ctx->bufsz = 0;
-        outlint = GENERIC_BLOCK_SIZE;
-        out += GENERIC_BLOCK_SIZE;
+        outlint = blksz;
+        out += blksz;
     }
     if (nextblocks > 0) {
         if (!ctx->enc && ctx->pad && nextblocks == inl) {
-            if (!ossl_assert(inl >= GENERIC_BLOCK_SIZE)) {
+            if (!ossl_assert(inl >= blksz)) {
                 ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
                 return 0;
             }
-            nextblocks -= GENERIC_BLOCK_SIZE;
+            nextblocks -= blksz;
         }
         outlint += nextblocks;
         if (outsize < outlint) {
@@ -202,7 +191,7 @@ int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl,
         in += nextblocks;
         inl -= nextblocks;
     }
-    if (!trailingdata(ctx->buf, &ctx->bufsz, GENERIC_BLOCK_SIZE, &in, &inl)) {
+    if (!trailingdata(ctx->buf, &ctx->bufsz, blksz, &in, &inl)) {
         /* ERR_raise already called */
         return 0;
     }
@@ -215,33 +204,34 @@ int cipher_generic_block_final(void *vctx, unsigned char *out, size_t *outl,
                                size_t outsize)
 {
     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+    size_t blksz = ctx->blocksize;
 
     if (ctx->enc) {
         if (ctx->pad) {
-            padblock(ctx->buf, &ctx->bufsz, GENERIC_BLOCK_SIZE);
+            padblock(ctx->buf, &ctx->bufsz, blksz);
         } else if (ctx->bufsz == 0) {
             *outl = 0;
             return 1;
-        } else if (ctx->bufsz != GENERIC_BLOCK_SIZE) {
+        } else if (ctx->bufsz != blksz) {
             ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
             return 0;
         }
 
-        if (outsize < GENERIC_BLOCK_SIZE) {
+        if (outsize < blksz) {
             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
             return 0;
         }
-        if (!ctx->hw->cipher(ctx, out, ctx->buf, GENERIC_BLOCK_SIZE)) {
+        if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
             return 0;
         }
         ctx->bufsz = 0;
-        *outl = GENERIC_BLOCK_SIZE;
+        *outl = blksz;
         return 1;
     }
 
     /* Decrypting */
-    if (ctx->bufsz != GENERIC_BLOCK_SIZE) {
+    if (ctx->bufsz != blksz) {
         if (ctx->bufsz == 0 && !ctx->pad) {
             *outl = 0;
             return 1;
@@ -250,12 +240,12 @@ int cipher_generic_block_final(void *vctx, unsigned char *out, size_t *outl,
         return 0;
     }
 
-    if (!ctx->hw->cipher(ctx, ctx->buf, ctx->buf, GENERIC_BLOCK_SIZE)) {
+    if (!ctx->hw->cipher(ctx, ctx->buf, ctx->buf, blksz)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
         return 0;
     }
 
-    if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, GENERIC_BLOCK_SIZE)) {
+    if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, blksz)) {
         /* ERR_raise already called */
         return 0;
     }
@@ -322,7 +312,7 @@ int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
     OSSL_PARAM *p;
 
     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
-    if (p != NULL && !OSSL_PARAM_set_int(p, GENERIC_BLOCK_SIZE)) {
+    if (p != NULL && !OSSL_PARAM_set_int(p, ctx->ivlen)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
@@ -333,8 +323,8 @@ int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
     }
     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
     if (p != NULL
-        && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, GENERIC_BLOCK_SIZE)
-        && !OSSL_PARAM_set_octet_string(p, &ctx->iv, GENERIC_BLOCK_SIZE)) {
+        && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)
+        && !OSSL_PARAM_set_octet_string(p, &ctx->iv, ctx->ivlen)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
@@ -390,14 +380,18 @@ int cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[])
     return 1;
 }
 
-void cipher_generic_initkey(void *vctx, int kbits, int blkbits, int mode,
-                            const PROV_CIPHER_HW *hw)
+void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
+                            size_t ivbits, int mode,
+                            const PROV_CIPHER_HW *hw, void *provctx)
 {
     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
 
     ctx->pad = 1;
     ctx->keylen = ((kbits) / 8);
+    ctx->ivlen = ((ivbits) / 8);
     ctx->hw = hw;
     ctx->mode = mode;
-    ctx->blocksize = blkbits/8;
+    ctx->blocksize = blkbits / 8;
+    if (provctx != NULL)
+        ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); /* used for rand */
 }
diff --git a/providers/common/ciphers/cipher_common_hw.c b/providers/common/ciphers/cipher_common_hw.c
index 47e14afbbb..5a3fb3060b 100644
--- a/providers/common/ciphers/cipher_common_hw.c
+++ b/providers/common/ciphers/cipher_common_hw.c
@@ -9,9 +9,6 @@
 
 #include "cipher_locl.h"
 
-#define MAXCHUNK    ((size_t)1 << (sizeof(long) * 8 - 2))
-#define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4))
-
 /*-
  * The generic cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr.
  * Used if there is no special hardware implementations.
diff --git a/providers/common/ciphers/cipher_gcm.c b/providers/common/ciphers/cipher_gcm.c
index 40c8845eca..7d0e47b823 100644
--- a/providers/common/ciphers/cipher_gcm.c
+++ b/providers/common/ciphers/cipher_gcm.c
@@ -10,6 +10,8 @@
 /* Dispatch functions for gcm mode */
 
 #include "cipher_locl.h"
+#include "internal/ciphers/cipher_gcm.h"
+#include "internal/providercommonerr.h"
 #include "internal/rand_int.h"
 #include "internal/provider_ctx.h"
 
diff --git a/providers/common/ciphers/cipher_gcm_hw.c b/providers/common/ciphers/cipher_gcm_hw.c
index f9ddc4d8a6..4ef5190b5f 100644
--- a/providers/common/ciphers/cipher_gcm_hw.c
+++ b/providers/common/ciphers/cipher_gcm_hw.c
@@ -8,94 +8,22 @@
  */
 
 #include "cipher_locl.h"
+#include "internal/ciphers/cipher_gcm.h"
 
-static const PROV_GCM_HW aes_gcm;
 
-static int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen);
-static int gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad,
-                          size_t aad_len);
-static int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag);
-static int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len,
-                        const unsigned char *in, size_t in_len,
-                        unsigned char *out, unsigned char *tag, size_t tag_len);
-static int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in,
-                             size_t len, unsigned char *out);
-
-#define SET_KEY_CTR_FN(ks, fn_set_enc_key, fn_block, fn_ctr)                   \
-    ctx->ks = ks;                                                              \
-    fn_set_enc_key(key, keylen * 8, ks);                                       \
-    CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)fn_block);                   \
-    ctx->ctr = (ctr128_f)fn_ctr;                                               \
-    ctx->key_set = 1;
-
-#if defined(AESNI_CAPABLE)
-# include "cipher_aes_gcm_hw_aesni.inc"
-#elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
-# include "cipher_aes_gcm_hw_t4.inc"
-#elif defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
-# include "cipher_aes_gcm_hw_s390x.inc"
-#else
-const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits)
-{
-    return &aes_gcm;
-}
-#endif
-
-static int generic_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
-                                   size_t keylen)
-{
-    PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
-    AES_KEY *ks = &actx->ks.ks;
-
-# ifdef HWAES_CAPABLE
-    if (HWAES_CAPABLE) {
-#  ifdef HWAES_ctr32_encrypt_blocks
-        SET_KEY_CTR_FN(ks, HWAES_set_encrypt_key, HWAES_encrypt,
-                       HWAES_ctr32_encrypt_blocks);
-#  else
-        SET_KEY_CTR_FN(ks, HWAES_set_encrypt_key, HWAES_encrypt, NULL);
-#  endif /* HWAES_ctr32_encrypt_blocks */
-    } else
-# endif /* HWAES_CAPABLE */
-
-# ifdef BSAES_CAPABLE
-    if (BSAES_CAPABLE) {
-        SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt,
-                       bsaes_ctr32_encrypt_blocks);
-    } else
-# endif /* BSAES_CAPABLE */
-
-# ifdef VPAES_CAPABLE
-    if (VPAES_CAPABLE) {
-        SET_KEY_CTR_FN(ks, vpaes_set_encrypt_key, vpaes_encrypt, NULL);
-    } else
-# endif /* VPAES_CAPABLE */
-
-    {
-# ifdef AES_CTR_ASM
-        SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt, AES_ctr32_encrypt);
-# else
-        SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt, NULL);
-# endif /* AES_CTR_ASM */
-    }
-    ctx->key_set = 1;
-    return 1;
-}
-
-static int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen)
+int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen)
 {
     CRYPTO_gcm128_setiv(&ctx->gcm, iv, ivlen);
     return 1;
 }
 
-static int gcm_aad_update(PROV_GCM_CTX *ctx,
-                          const unsigned char *aad, size_t aad_len)
+int gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad, size_t aad_len)
 {
     return CRYPTO_gcm128_aad(&ctx->gcm, aad, aad_len) == 0;
 }
 
-static int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in,
-                             size_t len, unsigned char *out)
+int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in,
+                      size_t len, unsigned char *out)
 {
     if (ctx->enc) {
         if (ctx->ctr != NULL) {
@@ -156,7 +84,7 @@ static int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in,
     return 1;
 }
 
-static int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag)
+int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag)
 {
     if (ctx->enc) {
         CRYPTO_gcm128_tag(&ctx->gcm, tag, GCM_TAG_MAX_SIZE);
@@ -169,9 +97,9 @@ static int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag)
     return 1;
 }
 
-static int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len,
-                        const unsigned char *in, size_t in_len,
-                        unsigned char *out, unsigned char *tag, size_t tag_len)
+int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len,
+                 const unsigned char *in, size_t in_len,
+                 unsigned char *out, unsigned char *tag, size_t tag_len)
 {
     int ret = 0;
 
@@ -188,14 +116,3 @@ static int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len,
 err:
     return ret;
 }
-
-static const PROV_GCM_HW aes_gcm = {
-    generic_aes_gcm_initkey,
-    gcm_setiv,
-    gcm_aad_update,
-    gcm_cipher_update,
-    gcm_cipher_final,
-    gcm_one_shot
-};
-
-#include "cipher_aria_gcm_hw.inc"
diff --git a/providers/common/ciphers/cipher_locl.h b/providers/common/ciphers/cipher_locl.h
index 9d95a7c482..8313498e5e 100644
--- a/providers/common/ciphers/cipher_locl.h
+++ b/providers/common/ciphers/cipher_locl.h
@@ -7,84 +7,23 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include <stdio.h>
-#include <openssl/opensslconf.h>
-#include <openssl/params.h>
-#include <openssl/core_numbers.h>
-#include <openssl/core_names.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-#include "internal/cryptlib.h"
-#include "internal/modes_int.h"
-#include "internal/provider_algs.h"
-#include "internal/providercommonerr.h"
-#include "internal/ciphermode_platform.h"
-
-#define GENERIC_BLOCK_SIZE 16
-#define IV_STATE_UNINITIALISED 0  /* initial state is not initialized */
-#define IV_STATE_BUFFERED      1  /* iv has been copied to the iv buffer */
-#define IV_STATE_COPIED        2  /* iv has been copied from the iv buffer */
-#define IV_STATE_FINISHED      3  /* the iv has been used - so don't reuse it */
-
-#define PROV_CIPHER_FUNC(type, name, args) typedef type (* OSSL_##name##_fn)args
-
-typedef struct prov_cipher_hw_st PROV_CIPHER_HW;
-typedef struct prov_cipher_ctx_st PROV_CIPHER_CTX;
-
-typedef int (PROV_CIPHER_HW_FN)(PROV_CIPHER_CTX *dat, unsigned char *out,
-                                const unsigned char *in, size_t len);
-
-struct prov_cipher_ctx_st {
-    block128_f block;
-    union {
-        cbc128_f cbc;
-        ctr128_f ctr;
-    } stream;
-
-    /*
-     * num contains the number of bytes of |iv| which are valid for modes that
-     * manage partial blocks themselves.
-     */
-    size_t num;
-
-    int mode;
-    int enc;              /* Set to 1 for encrypt, or 0 otherwise */
-    size_t bufsz;         /* Number of bytes in buf */
-    size_t keylen;        /* key size (in bytes) */
-    size_t blocksize;
-    uint64_t flags;
-    unsigned int pad : 1; /* Whether padding should be used or not */
-
-    /* Buffer of partial blocks processed via update calls */
-    unsigned char buf[GENERIC_BLOCK_SIZE];
-    unsigned char iv[GENERIC_BLOCK_SIZE];
-    const PROV_CIPHER_HW *hw; /* hardware specific functions */
-    const void *ks; /* Pointer to algorithm specific key data */
-};
-
-struct prov_cipher_hw_st {
-    int (*init)(PROV_CIPHER_CTX *dat, const uint8_t *key, size_t keylen);
-    PROV_CIPHER_HW_FN *cipher;
-};
-
-OSSL_OP_cipher_encrypt_init_fn cipher_generic_einit;
-OSSL_OP_cipher_decrypt_init_fn cipher_generic_dinit;
-OSSL_OP_cipher_update_fn cipher_generic_block_update;
-OSSL_OP_cipher_final_fn cipher_generic_block_final;
-OSSL_OP_cipher_update_fn cipher_generic_stream_update;
-OSSL_OP_cipher_final_fn cipher_generic_stream_final;
-OSSL_OP_cipher_cipher_fn cipher_generic_cipher;
-OSSL_OP_cipher_get_ctx_params_fn cipher_generic_get_ctx_params;
-OSSL_OP_cipher_set_ctx_params_fn cipher_generic_set_ctx_params;
-OSSL_OP_cipher_gettable_params_fn     cipher_default_gettable_params;
-OSSL_OP_cipher_gettable_ctx_params_fn cipher_default_gettable_ctx_params;
-OSSL_OP_cipher_settable_ctx_params_fn cipher_default_settable_ctx_params;
-OSSL_OP_cipher_gettable_ctx_params_fn cipher_aead_gettable_ctx_params;
-OSSL_OP_cipher_settable_ctx_params_fn cipher_aead_settable_ctx_params;
-int cipher_default_get_params(OSSL_PARAM params[], int md, unsigned long flags,
-                              int kbits, int blkbits, int ivbits);
-void cipher_generic_initkey(void *vctx, int kbits, int blkbits, int mode,
-                            const PROV_CIPHER_HW *ciph);
+#include "internal/ciphers/ciphercommon.h"
+
+#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name)                         \
+static const OSSL_PARAM name##_known_gettable_ctx_params[] = {                 \
+    OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL),                            \
+    OSSL_PARAM_int(OSSL_CIPHER_PARAM_IVLEN, NULL),                             \
+    OSSL_PARAM_int(OSSL_CIPHER_PARAM_PADDING, NULL),                           \
+    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_NUM, NULL),                            \
+    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
+
+#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name)                           \
+    OSSL_PARAM_END                                                             \
+};                                                                             \
+const OSSL_PARAM * name##_gettable_ctx_params(void)                            \
+{                                                                              \
+    return name##_known_gettable_ctx_params;                                   \
+}
 
 size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
                  const unsigned char **in, size_t *inlen);
@@ -92,102 +31,3 @@ int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
                  const unsigned char **in, size_t *inlen);
 void padblock(unsigned char *buf, size_t *buflen, size_t blocksize);
 int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize);
-
-#include "cipher_aes.h"
-#include "cipher_aria.h"
-#include "cipher_camellia.h"
-#include "cipher_gcm.h"
-#include "cipher_ccm.h"
-
-#define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits,     \
-                                 blkbits, ivbits, typ)                         \
-static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params;     \
-static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[])          \
-{                                                                              \
-    return cipher_default_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags,  \
-                                     kbits, blkbits, ivbits);                  \
-}                                                                              \
-static OSSL_OP_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx;             \
-static void * alg##_##kbits##_##lcmode##_newctx(void *provctx)                 \
-{                                                                              \
-     PROV_##UCALG##_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));                   \
-     if (ctx != NULL) {                                                        \
-         cipher_generic_initkey(ctx, kbits, blkbits, EVP_CIPH_##UCMODE##_MODE, \
-                                PROV_CIPHER_HW_##alg##_##lcmode(kbits));       \
-     }                                                                         \
-     return ctx;                                                               \
-}                                                                              \
-const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = {                       \
-    { OSSL_FUNC_CIPHER_NEWCTX,                                                 \
-      (void (*)(void)) alg##_##kbits##_##lcmode##_newctx },                    \
-    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx },              \
-    { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx },                \
-    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit },   \
-    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit },   \
-    { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))cipher_generic_##typ##_update },\
-    { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##typ##_final },  \
-    { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher },        \
-    { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
-      (void (*)(void)) alg##_##kbits##_##lcmode##_get_params },                \
-    { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                         \
-      (void (*)(void))cipher_generic_get_ctx_params },                         \
-    { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
-      (void (*)(void))cipher_generic_set_ctx_params },                         \
-    { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
-      (void (*)(void))cipher_default_gettable_params },                        \
-    { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
-      (void (*)(void))cipher_default_gettable_ctx_params },                    \
-    { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
-     (void (*)(void))cipher_default_settable_ctx_params },                     \
-    { 0, NULL }                                                                \
-};
-
-#define IMPLEMENT_aead_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits)  \
-static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lc##_get_params;         \
-static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[])              \
-{                                                                              \
-    return cipher_default_get_params(params, EVP_CIPH_##UCMODE##_MODE,         \
-                                     flags, kbits, blkbits, ivbits);           \
-}                                                                              \
-static OSSL_OP_cipher_newctx_fn alg##kbits##lc##_newctx;                       \
-static void * alg##kbits##lc##_newctx(void *provctx)                           \
-{                                                                              \
-    return alg##_##lc##_newctx(provctx, kbits);                                \
-}                                                                              \
-const OSSL_DISPATCH alg##kbits##lc##_functions[] = {                           \
-    { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx },      \
-    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx },        \
-    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) lc##_einit },            \
-    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void)) lc##_dinit },            \
-    { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void)) lc##_stream_update },          \
-    { OSSL_FUNC_CIPHER_FINAL, (void (*)(void)) lc##_stream_final },            \
-    { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void)) lc##_cipher },                 \
-    { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
-      (void (*)(void)) alg##_##kbits##_##lc##_get_params },                    \
-    { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                         \
-      (void (*)(void)) lc##_get_ctx_params },                                  \
-    { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
-      (void (*)(void)) lc##_set_ctx_params },                                  \
-    { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
-      (void (*)(void))cipher_default_gettable_params },                        \
-    { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
-      (void (*)(void))cipher_aead_gettable_ctx_params },                       \
-    { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
-      (void (*)(void))cipher_aead_settable_ctx_params },                       \
-    { 0, NULL }                                                                \
-}
-
-PROV_CIPHER_HW_FN cipher_hw_generic_cbc;
-PROV_CIPHER_HW_FN cipher_hw_generic_ecb;
-PROV_CIPHER_HW_FN cipher_hw_generic_ofb128;
-PROV_CIPHER_HW_FN cipher_hw_generic_cfb128;
-PROV_CIPHER_HW_FN cipher_hw_generic_cfb8;
-PROV_CIPHER_HW_FN cipher_hw_generic_cfb1;
-PROV_CIPHER_HW_FN cipher_hw_generic_ctr;
-PROV_CIPHER_HW_FN cipher_hw_chunked_cbc;
-PROV_CIPHER_HW_FN cipher_hw_chunked_cfb8;
-PROV_CIPHER_HW_FN cipher_hw_chunked_cfb128;
-PROV_CIPHER_HW_FN cipher_hw_chunked_ofb128;
-#define cipher_hw_chunked_ecb  cipher_hw_generic_ecb
-#define cipher_hw_chunked_ctr  cipher_hw_generic_ctr
-#define cipher_hw_chunked_cfb1 cipher_hw_generic_cfb1
diff --git a/providers/common/ciphers/cipher_tdes.c b/providers/common/ciphers/cipher_tdes.c
new file mode 100644
index 0000000000..91df2ce194
--- /dev/null
+++ b/providers/common/ciphers/cipher_tdes.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "cipher_locl.h"
+#include "internal/ciphers/cipher_tdes.h"
+#include "internal/rand_int.h"
+#include "internal/provider_algs.h"
+#include "internal/providercommonerr.h"
+
+void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
+                  size_t ivbits, const PROV_CIPHER_HW *hw)
+{
+    PROV_TDES_CTX *tctx = OPENSSL_zalloc(sizeof(*tctx));
+
+    if (tctx != NULL)
+        cipher_generic_initkey(tctx, kbits, blkbits, ivbits, mode, hw, provctx);
+    return tctx;
+}
+
+void tdes_freectx(void *vctx)
+{
+    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+
+    OPENSSL_clear_free(ctx,  sizeof(*ctx));
+}
+
+static int tdes_init(void *vctx, const unsigned char *key, size_t keylen,
+                     const unsigned char *iv, size_t ivlen, int enc)
+{
+    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+
+    ctx->enc = enc;
+
+    if (iv != NULL) {
+        if (ivlen != TDES_IVLEN) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
+            return 0;
+        }
+        memcpy(ctx->iv, iv, TDES_IVLEN);
+    }
+
+    if (key != NULL) {
+        if (keylen != ctx->keylen) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEYLEN);
+            return 0;
+        }
+        return ctx->hw->init(ctx, key, ctx->keylen);
+    }
+    return 1;
+}
+
+int tdes_einit(void *vctx, const unsigned char *key, size_t keylen,
+               const unsigned char *iv, size_t ivlen)
+{
+    return tdes_init(vctx, key, keylen, iv, ivlen, 1);
+}
+
+int tdes_dinit(void *vctx, const unsigned char *key, size_t keylen,
+               const unsigned char *iv, size_t ivlen)
+{
+    return tdes_init(vctx, key, keylen, iv, ivlen, 0);
+}
+
+static int tdes_generatekey(PROV_CIPHER_CTX *ctx, void *ptr)
+{
+
+    DES_cblock *deskey = ptr;
+    size_t kl = ctx->keylen;
+
+    if (kl == 0 || rand_priv_bytes_ex(ctx->libctx, ptr, kl) <= 0)
+        return 0;
+    DES_set_odd_parity(deskey);
+    if (kl >= 16)
+        DES_set_odd_parity(deskey + 1);
+    if (kl >= 24) {
+        DES_set_odd_parity(deskey + 2);
+        return 1;
+    }
+    return 0;
+}
+
+CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(tdes)
+    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0),
+CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(tdes)
+
+int tdes_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+    PROV_CIPHER_CTX  *ctx = (PROV_CIPHER_CTX *)vctx;
+    OSSL_PARAM *p;
+
+    if (!cipher_generic_get_ctx_params(vctx, params))
+        return 0;
+
+    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RANDOM_KEY);
+    if (p != NULL && !tdes_generatekey(ctx, p->data)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY);
+        return 0;
+    }
+    return 1;
+}
+
+/*
+ * TODO(3.0) - ECB mode does not use an IV - but existing test code is setting
+ * an IV. Fixing this could potentially make applications break.
+ */
+
+/* tdes_ede3_ecb_functions */
+IMPLEMENT_tdes_cipher(ede3, EDE3, ecb, ECB, TDES_FLAGS, 64*3, 64, 64, block);
+/* tdes_ede3_cbc_functions */
+IMPLEMENT_tdes_cipher(ede3, EDE3, cbc, CBC, TDES_FLAGS, 64*3, 64, 64, block);
diff --git a/providers/common/ciphers/cipher_tdes_hw.c b/providers/common/ciphers/cipher_tdes_hw.c
new file mode 100644
index 0000000000..980201267b
--- /dev/null
+++ b/providers/common/ciphers/cipher_tdes_hw.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "cipher_locl.h"
+#include "internal/ciphers/cipher_tdes.h"
+
+#define ks1 tks.ks[0]
+#define ks2 tks.ks[1]
+#define ks3 tks.ks[2]
+
+int cipher_hw_tdes_ede3_initkey(PROV_CIPHER_CTX *ctx, const unsigned char *key,
+                                size_t keylen)
+{
+    PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
+    DES_cblock *deskey = (DES_cblock *)key;
+
+    tctx->tstream.cbc = NULL;
+# if defined(SPARC_DES_CAPABLE)
+    if (SPARC_DES_CAPABLE) {
+        if (ctx->mode == EVP_CIPH_CBC_MODE) {
+            des_t4_key_expand(&deskey[0], &tctx->ks1);
+            des_t4_key_expand(&deskey[1], &tctx->ks2);
+            des_t4_key_expand(&deskey[2], &tctx->ks3);
+            dat->tstream.cbc = enc ? des_t4_ede3_cbc_encrypt :
+                                     des_t4_ede3_cbc_decrypt;
+            return 1;
+        }
+    }
+# endif
+    DES_set_key_unchecked(&deskey[0], &tctx->ks1);
+    DES_set_key_unchecked(&deskey[1], &tctx->ks2);
+    DES_set_key_unchecked(&deskey[2], &tctx->ks3);
+    return 1;
+}
+
+int cipher_hw_tdes_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
+                       const unsigned char *in, size_t inl)
+{
+    PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
+
+    if (tctx->tstream.cbc != NULL) {
+        (*tctx->tstream.cbc) (in, out, inl, tctx->tks.ks, ctx->iv);
+        return 1;
+    }
+
+    while (inl >= MAXCHUNK) {
+        DES_ede3_cbc_encrypt(in, out, (long)MAXCHUNK, &tctx->ks1, &tctx->ks2,
+                             &tctx->ks3, (DES_cblock *)ctx->iv, ctx->enc);
+        inl -= MAXCHUNK;
+        in += MAXCHUNK;
+        out += MAXCHUNK;
+    }
+    if (inl > 0)
+        DES_ede3_cbc_encrypt(in, out, (long)inl, &tctx->ks1, &tctx->ks2,
+                             &tctx->ks3, (DES_cblock *)ctx->iv, ctx->enc);
+    return 1;
+}
+
+int cipher_hw_tdes_ecb(PROV_CIPHER_CTX *ctx, unsigned char *out,
+                       const unsigned char *in, size_t len)
+{
+    size_t i;
+    PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
+
+    if (len < DES_BLOCK_SIZE)
+        return 1;
+
+    for (i = 0, len -= DES_BLOCK_SIZE; i <= len; i += DES_BLOCK_SIZE) {
+        DES_ecb3_encrypt((const_DES_cblock *)(in + i), (DES_cblock *)(out + i),
+                         &tctx->ks1, &tctx->ks2, &tctx->ks3, ctx->enc);
+    }
+    return 1;
+}
+
+PROV_CIPHER_HW_tdes_mode(ede3, ecb)
+PROV_CIPHER_HW_tdes_mode(ede3, cbc)
diff --git a/providers/common/include/internal/ciphers/cipher_aead.h b/providers/common/include/internal/ciphers/cipher_aead.h
new file mode 100644
index 0000000000..a2fe87e967
--- /dev/null
+++ b/providers/common/include/internal/ciphers/cipher_aead.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* TODO(3.0) Figure out what flags are really needed */
+#define AEAD_FLAGS (EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_DEFAULT_ASN1     \
+                       | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER      \
+                       | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT        \
+                       | EVP_CIPH_CUSTOM_COPY)
+
+#define IMPLEMENT_aead_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits)  \
+static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lc##_get_params;         \
+static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[])              \
+{                                                                              \
+    return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE,         \
+                                     flags, kbits, blkbits, ivbits);           \
+}                                                                              \
+static OSSL_OP_cipher_newctx_fn alg##kbits##lc##_newctx;                       \
+static void * alg##kbits##lc##_newctx(void *provctx)                           \
+{                                                                              \
+    return alg##_##lc##_newctx(provctx, kbits);                                \
+}                                                                              \
+const OSSL_DISPATCH alg##kbits##lc##_functions[] = {                           \
+    { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx },      \
+    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx },        \
+    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) lc##_einit },            \
+    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void)) lc##_dinit },            \
+    { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void)) lc##_stream_update },          \
+    { OSSL_FUNC_CIPHER_FINAL, (void (*)(void)) lc##_stream_final },            \
+    { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void)) lc##_cipher },                 \
+    { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
+      (void (*)(void)) alg##_##kbits##_##lc##_get_params },                    \
+    { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                         \
+      (void (*)(void)) lc##_get_ctx_params },                                  \
+    { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
+      (void (*)(void)) lc##_set_ctx_params },                                  \
+    { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
+      (void (*)(void))cipher_generic_gettable_params },                        \
+    { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
+      (void (*)(void))cipher_aead_gettable_ctx_params },                       \
+    { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
+      (void (*)(void))cipher_aead_settable_ctx_params },                       \
+    { 0, NULL }                                                                \
+}
diff --git a/providers/common/ciphers/cipher_ccm.h b/providers/common/include/internal/ciphers/cipher_ccm.h
similarity index 87%
rename from providers/common/ciphers/cipher_ccm.h
rename to providers/common/include/internal/ciphers/cipher_ccm.h
index d91ad0013e..503d077def 100644
--- a/providers/common/ciphers/cipher_ccm.h
+++ b/providers/common/include/internal/ciphers/cipher_ccm.h
@@ -7,6 +7,8 @@
  * https://www.openssl.org/source/license.html
  */
 
+#include "cipher_aead.h"
+
 typedef struct prov_ccm_hw_st PROV_CCM_HW;
 
 #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
@@ -111,20 +113,6 @@ struct prov_ccm_hw_st {
 
 const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keylen);
 
-#if !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE)
-# include "internal/aria.h"
-typedef struct prov_aria_ccm_ctx_st {
-    PROV_CCM_CTX base; /* Must be first */
-    union {
-        OSSL_UNION_ALIGN;
-        ARIA_KEY ks;
-    } ks;                       /* ARIA key schedule to use */
-} PROV_ARIA_CCM_CTX;
-
-const PROV_CCM_HW *PROV_ARIA_HW_ccm(size_t keylen);
-
-#endif /* !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE) */
-
 OSSL_OP_cipher_encrypt_init_fn ccm_einit;
 OSSL_OP_cipher_decrypt_init_fn ccm_dinit;
 OSSL_OP_cipher_get_ctx_params_fn ccm_get_ctx_params;
@@ -134,3 +122,14 @@ OSSL_OP_cipher_final_fn ccm_stream_final;
 OSSL_OP_cipher_cipher_fn ccm_cipher;
 void ccm_initctx(PROV_CCM_CTX *ctx, size_t keybits, const PROV_CCM_HW *hw);
 void ccm_finalctx(PROV_CCM_CTX *ctx);
+
+int ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce,
+                      size_t nlen, size_t mlen);
+int ccm_generic_setaad(PROV_CCM_CTX *ctx, const unsigned char *aad, size_t alen);
+int ccm_generic_gettag(PROV_CCM_CTX *ctx, unsigned char *tag, size_t tlen);
+int ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
+                             unsigned char *out, size_t len,
+                             unsigned char *tag, size_t taglen);
+int ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
+                             unsigned char *out, size_t len,
+                             unsigned char *expected_tag, size_t taglen);
diff --git a/providers/common/ciphers/cipher_gcm.h b/providers/common/include/internal/ciphers/cipher_gcm.h
similarity index 83%
rename from providers/common/ciphers/cipher_gcm.h
rename to providers/common/include/internal/ciphers/cipher_gcm.h
index 59bbeee04a..63600c38e7 100644
--- a/providers/common/ciphers/cipher_gcm.h
+++ b/providers/common/include/internal/ciphers/cipher_gcm.h
@@ -9,6 +9,7 @@
  */
 
 #include <openssl/aes.h>
+#include "cipher_aead.h"
 
 typedef struct prov_gcm_hw_st PROV_GCM_HW;
 
@@ -16,12 +17,6 @@ typedef struct prov_gcm_hw_st PROV_GCM_HW;
 #define GCM_IV_MAX_SIZE     64
 #define GCM_TAG_MAX_SIZE    16
 
-/* TODO(3.0) Figure out what flags are really needed */
-#define AEAD_FLAGS (EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_DEFAULT_ASN1     \
-                       | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER      \
-                       | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT        \
-                       | EVP_CIPH_CUSTOM_COPY)
-
 #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
 /*-
  * KMA-GCM-AES parameter block - begin
@@ -137,21 +132,6 @@ struct prov_gcm_hw_st {
 };
 const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits);
 
-#if !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE)
-
-#include "internal/aria.h"
-
-typedef struct prov_aria_gcm_ctx_st {
-    PROV_GCM_CTX base;              /* must be first entry in struct */
-    union {
-        OSSL_UNION_ALIGN;
-        ARIA_KEY ks;
-    } ks;
-} PROV_ARIA_GCM_CTX;
-const PROV_GCM_HW *PROV_ARIA_HW_gcm(size_t keybits);
-
-#endif /* !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE) */
-
 OSSL_OP_cipher_encrypt_init_fn gcm_einit;
 OSSL_OP_cipher_decrypt_init_fn gcm_dinit;
 OSSL_OP_cipher_get_ctx_params_fn gcm_get_ctx_params;
@@ -163,3 +143,19 @@ void gcm_deinitctx(PROV_GCM_CTX *ctx);
 void gcm_initctx(void *provctx, PROV_GCM_CTX *ctx, size_t keybits,
                  const PROV_GCM_HW *hw, size_t ivlen_min);
 
+int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen);
+int gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad,
+                   size_t aad_len);
+int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag);
+int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len,
+                 const unsigned char *in, size_t in_len,
+                 unsigned char *out, unsigned char *tag, size_t tag_len);
+int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in,
+                      size_t len, unsigned char *out);
+
+#define GCM_HW_SET_KEY_CTR_FN(ks, fn_set_enc_key, fn_block, fn_ctr)     \
+    ctx->ks = ks;                                                              \
+    fn_set_enc_key(key, keylen * 8, ks);                                       \
+    CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)fn_block);                   \
+    ctx->ctr = (ctr128_f)fn_ctr;                                               \
+    ctx->key_set = 1;
diff --git a/providers/common/include/internal/ciphers/cipher_tdes.h b/providers/common/include/internal/ciphers/cipher_tdes.h
new file mode 100644
index 0000000000..0d3c90c0af
--- /dev/null
+++ b/providers/common/include/internal/ciphers/cipher_tdes.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/des.h>
+#include <openssl/core_numbers.h>
+
+#define DES_BLOCK_SIZE 8
+#define TDES_IVLEN 8
+
+/* TODO(3.0) Figure out what flags need to be here */
+#define TDES_FLAGS (EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1)
+
+typedef struct prov_tdes_ctx_st {
+    PROV_CIPHER_CTX base;      /* Must be first */
+    union {
+        OSSL_UNION_ALIGN;
+        DES_key_schedule ks[3];
+    } tks;
+    union {
+        void (*cbc) (const void *, void *, size_t,
+                     const DES_key_schedule *, unsigned char *);
+    } tstream;
+
+} PROV_TDES_CTX;
+
+#define IMPLEMENT_tdes_cipher(type, UCTYPE, lcmode, UCMODE, flags,             \
+                              kbits, blkbits, ivbits, block)                   \
+static OSSL_OP_cipher_newctx_fn tdes_##type##_##lcmode##_newctx;               \
+static void *tdes_##type##_##lcmode##_newctx(void *provctx)                    \
+{                                                                              \
+    return tdes_newctx(provctx, EVP_CIPH_##UCMODE##_MODE, kbits, blkbits,      \
+                       ivbits, PROV_CIPHER_HW_tdes_##type##_##lcmode());       \
+}                                                                              \
+static OSSL_OP_cipher_get_params_fn tdes_##type##_##lcmode##_get_params;       \
+static int tdes_##type##_##lcmode##_get_params(OSSL_PARAM params[])            \
+{                                                                              \
+    return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags,  \
+                                     kbits, blkbits, ivbits);                  \
+}                                                                              \
+const OSSL_DISPATCH tdes_##type##_##lcmode##_functions[] = {                   \
+    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))tdes_einit },             \
+    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))tdes_dinit },             \
+    { OSSL_FUNC_CIPHER_UPDATE,                                                 \
+      (void (*)(void))cipher_generic_##block##_update },                       \
+    { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##block##_final },\
+    { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher },        \
+    { OSSL_FUNC_CIPHER_NEWCTX,                                                 \
+      (void (*)(void))tdes_##type##_##lcmode##_newctx },                       \
+    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))tdes_freectx },                \
+    { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
+      (void (*)(void))tdes_##type##_##lcmode##_get_params },                   \
+    { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
+      (void (*)(void))cipher_generic_gettable_params },                        \
+    { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))tdes_get_ctx_params },  \
+    { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
+      (void (*)(void))tdes_gettable_ctx_params },                              \
+    { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
+     (void (*)(void))cipher_generic_set_ctx_params },                          \
+    { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
+     (void (*)(void))cipher_generic_settable_ctx_params },                     \
+    { 0, NULL }                                                                \
+}
+
+void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
+                  size_t ivbits, const PROV_CIPHER_HW *hw);
+OSSL_OP_cipher_freectx_fn tdes_freectx;
+OSSL_OP_cipher_encrypt_init_fn tdes_einit;
+OSSL_OP_cipher_decrypt_init_fn tdes_dinit;
+OSSL_OP_cipher_get_ctx_params_fn tdes_get_ctx_params;
+OSSL_OP_cipher_gettable_ctx_params_fn tdes_gettable_ctx_params;
+
+#define PROV_CIPHER_HW_tdes_mode(type, mode)                                   \
+static const PROV_CIPHER_HW type##_##mode = {                                  \
+    cipher_hw_tdes_##type##_initkey,                                           \
+    cipher_hw_tdes_##mode                                                      \
+};                                                                             \
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_##type##_##mode(void)                \
+{                                                                              \
+    return &type##_##mode;                                                     \
+}
+
+int cipher_hw_tdes_ede3_initkey(PROV_CIPHER_CTX *ctx, const unsigned char *key,
+                                size_t keylen);
+int cipher_hw_tdes_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
+                       const unsigned char *in, size_t inl);
+int cipher_hw_tdes_ecb(PROV_CIPHER_CTX *ctx, unsigned char *out,
+                       const unsigned char *in, size_t len);
+
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cbc(void);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_ecb(void);
diff --git a/providers/common/ciphers/cipher_locl.h b/providers/common/include/internal/ciphers/ciphercommon.h
similarity index 61%
copy from providers/common/ciphers/cipher_locl.h
copy to providers/common/include/internal/ciphers/ciphercommon.h
index 9d95a7c482..38d0396902 100644
--- a/providers/common/ciphers/cipher_locl.h
+++ b/providers/common/include/internal/ciphers/ciphercommon.h
@@ -7,19 +7,17 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include <stdio.h>
-#include <openssl/opensslconf.h>
 #include <openssl/params.h>
 #include <openssl/core_numbers.h>
 #include <openssl/core_names.h>
 #include <openssl/evp.h>
-#include <openssl/err.h>
 #include "internal/cryptlib.h"
 #include "internal/modes_int.h"
-#include "internal/provider_algs.h"
-#include "internal/providercommonerr.h"
 #include "internal/ciphermode_platform.h"
 
+#define MAXCHUNK    ((size_t)1 << (sizeof(long) * 8 - 2))
+#define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4))
+
 #define GENERIC_BLOCK_SIZE 16
 #define IV_STATE_UNINITIALISED 0  /* initial state is not initialized */
 #define IV_STATE_BUFFERED      1  /* iv has been copied to the iv buffer */
@@ -51,6 +49,7 @@ struct prov_cipher_ctx_st {
     int enc;              /* Set to 1 for encrypt, or 0 otherwise */
     size_t bufsz;         /* Number of bytes in buf */
     size_t keylen;        /* key size (in bytes) */
+    size_t ivlen;
     size_t blocksize;
     uint64_t flags;
     unsigned int pad : 1; /* Whether padding should be used or not */
@@ -60,6 +59,7 @@ struct prov_cipher_ctx_st {
     unsigned char iv[GENERIC_BLOCK_SIZE];
     const PROV_CIPHER_HW *hw; /* hardware specific functions */
     const void *ks; /* Pointer to algorithm specific key data */
+    OPENSSL_CTX *libctx;
 };
 
 struct prov_cipher_hw_st {
@@ -76,35 +76,23 @@ OSSL_OP_cipher_final_fn cipher_generic_stream_final;
 OSSL_OP_cipher_cipher_fn cipher_generic_cipher;
 OSSL_OP_cipher_get_ctx_params_fn cipher_generic_get_ctx_params;
 OSSL_OP_cipher_set_ctx_params_fn cipher_generic_set_ctx_params;
-OSSL_OP_cipher_gettable_params_fn     cipher_default_gettable_params;
-OSSL_OP_cipher_gettable_ctx_params_fn cipher_default_gettable_ctx_params;
-OSSL_OP_cipher_settable_ctx_params_fn cipher_default_settable_ctx_params;
+OSSL_OP_cipher_gettable_params_fn     cipher_generic_gettable_params;
+OSSL_OP_cipher_gettable_ctx_params_fn cipher_generic_gettable_ctx_params;
+OSSL_OP_cipher_settable_ctx_params_fn cipher_generic_settable_ctx_params;
 OSSL_OP_cipher_gettable_ctx_params_fn cipher_aead_gettable_ctx_params;
 OSSL_OP_cipher_settable_ctx_params_fn cipher_aead_settable_ctx_params;
-int cipher_default_get_params(OSSL_PARAM params[], int md, unsigned long flags,
+int cipher_generic_get_params(OSSL_PARAM params[], int md, unsigned long flags,
                               int kbits, int blkbits, int ivbits);
-void cipher_generic_initkey(void *vctx, int kbits, int blkbits, int mode,
-                            const PROV_CIPHER_HW *ciph);
-
-size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
-                 const unsigned char **in, size_t *inlen);
-int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
-                 const unsigned char **in, size_t *inlen);
-void padblock(unsigned char *buf, size_t *buflen, size_t blocksize);
-int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize);
-
-#include "cipher_aes.h"
-#include "cipher_aria.h"
-#include "cipher_camellia.h"
-#include "cipher_gcm.h"
-#include "cipher_ccm.h"
+void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
+                            size_t ivbits, int mode,
+                            const PROV_CIPHER_HW *hw, void *provctx);
 
 #define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits,     \
                                  blkbits, ivbits, typ)                         \
 static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params;     \
 static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[])          \
 {                                                                              \
-    return cipher_default_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags,  \
+    return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags,  \
                                      kbits, blkbits, ivbits);                  \
 }                                                                              \
 static OSSL_OP_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx;             \
@@ -112,8 +100,9 @@ static void * alg##_##kbits##_##lcmode##_newctx(void *provctx)                 \
 {                                                                              \
      PROV_##UCALG##_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));                   \
      if (ctx != NULL) {                                                        \
-         cipher_generic_initkey(ctx, kbits, blkbits, EVP_CIPH_##UCMODE##_MODE, \
-                                PROV_CIPHER_HW_##alg##_##lcmode(kbits));       \
+         cipher_generic_initkey(ctx, kbits, blkbits, ivbits,                   \
+                                EVP_CIPH_##UCMODE##_MODE,                      \
+                                PROV_CIPHER_HW_##alg##_##lcmode(kbits), NULL); \
      }                                                                         \
      return ctx;                                                               \
 }                                                                              \
@@ -134,49 +123,14 @@ const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = {                       \
     { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
       (void (*)(void))cipher_generic_set_ctx_params },                         \
     { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
-      (void (*)(void))cipher_default_gettable_params },                        \
+      (void (*)(void))cipher_generic_gettable_params },                        \
     { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
-      (void (*)(void))cipher_default_gettable_ctx_params },                    \
+      (void (*)(void))cipher_generic_gettable_ctx_params },                    \
     { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
-     (void (*)(void))cipher_default_settable_ctx_params },                     \
+     (void (*)(void))cipher_generic_settable_ctx_params },                     \
     { 0, NULL }                                                                \
 };
 
-#define IMPLEMENT_aead_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits)  \
-static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lc##_get_params;         \
-static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[])              \
-{                                                                              \
-    return cipher_default_get_params(params, EVP_CIPH_##UCMODE##_MODE,         \
-                                     flags, kbits, blkbits, ivbits);           \
-}                                                                              \
-static OSSL_OP_cipher_newctx_fn alg##kbits##lc##_newctx;                       \
-static void * alg##kbits##lc##_newctx(void *provctx)                           \
-{                                                                              \
-    return alg##_##lc##_newctx(provctx, kbits);                                \
-}                                                                              \
-const OSSL_DISPATCH alg##kbits##lc##_functions[] = {                           \
-    { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx },      \
-    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx },        \
-    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) lc##_einit },            \
-    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void)) lc##_dinit },            \
-    { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void)) lc##_stream_update },          \
-    { OSSL_FUNC_CIPHER_FINAL, (void (*)(void)) lc##_stream_final },            \
-    { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void)) lc##_cipher },                 \
-    { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
-      (void (*)(void)) alg##_##kbits##_##lc##_get_params },                    \
-    { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                         \
-      (void (*)(void)) lc##_get_ctx_params },                                  \
-    { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
-      (void (*)(void)) lc##_set_ctx_params },                                  \
-    { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
-      (void (*)(void))cipher_default_gettable_params },                        \
-    { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
-      (void (*)(void))cipher_aead_gettable_ctx_params },                       \
-    { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
-      (void (*)(void))cipher_aead_settable_ctx_params },                       \
-    { 0, NULL }                                                                \
-}
-
 PROV_CIPHER_HW_FN cipher_hw_generic_cbc;
 PROV_CIPHER_HW_FN cipher_hw_generic_ecb;
 PROV_CIPHER_HW_FN cipher_hw_generic_ofb128;
@@ -191,3 +145,5 @@ PROV_CIPHER_HW_FN cipher_hw_chunked_ofb128;
 #define cipher_hw_chunked_ecb  cipher_hw_generic_ecb
 #define cipher_hw_chunked_ctr  cipher_hw_generic_ctr
 #define cipher_hw_chunked_cfb1 cipher_hw_generic_cfb1
+
+
diff --git a/providers/common/include/internal/provider_algs.h b/providers/common/include/internal/provider_algs.h
index cfa88dff42..e66c0523e7 100644
--- a/providers/common/include/internal/provider_algs.h
+++ b/providers/common/include/internal/provider_algs.h
@@ -126,6 +126,24 @@ extern const OSSL_DISPATCH kmac256_functions[];
 extern const OSSL_DISPATCH siphash_functions[];
 extern const OSSL_DISPATCH poly1305_functions[];
 
+extern const OSSL_DISPATCH tdes_ede3_ecb_functions[];
+extern const OSSL_DISPATCH tdes_ede3_cbc_functions[];
+
+#ifndef FIPS_MODE
+extern const OSSL_DISPATCH tdes_ede3_ofb_functions[];
+extern const OSSL_DISPATCH tdes_ede3_cfb_functions[];
+extern const OSSL_DISPATCH tdes_ede3_cfb8_functions[];
+extern const OSSL_DISPATCH tdes_ede3_cfb1_functions[];
+
+extern const OSSL_DISPATCH tdes_ede2_ecb_functions[];
+extern const OSSL_DISPATCH tdes_ede2_cbc_functions[];
+extern const OSSL_DISPATCH tdes_ede2_ofb_functions[];
+extern const OSSL_DISPATCH tdes_ede2_cfb_functions[];
+
+extern const OSSL_DISPATCH tdes_desx_cbc_functions[];
+extern const OSSL_DISPATCH tdes_wrap_cbc_functions[];
+#endif /* FIPS_MODE */
+
 /* Key management */
 extern const OSSL_DISPATCH dh_keymgmt_functions[];
 
diff --git a/providers/common/include/internal/providercommonerr.h b/providers/common/include/internal/providercommonerr.h
index da5644b50d..c436495a5b 100644
--- a/providers/common/include/internal/providercommonerr.h
+++ b/providers/common/include/internal/providercommonerr.h
@@ -41,7 +41,7 @@ int ERR_load_PROV_strings(void);
 #  define PROV_F_GMAC_SET_PARAMS                           0
 #  define PROV_F_KMAC_SET_PARAMS                           0
 #  define PROV_F_POLY1305_SET_PARAMS                       0
-#  define PROV_F_PROV_AES_CTX_GENERIC_INIT                 0
+#  define PROV_F_PROV_AES_KEY_GENERIC_INIT                 0
 #  define PROV_F_TRAILINGDATA                              0
 #  define PROV_F_UNPADBLOCK                                0
 # endif
@@ -52,6 +52,7 @@ int ERR_load_PROV_strings(void);
 # define PROV_R_AES_KEY_SETUP_FAILED                      101
 # define PROV_R_BAD_DECRYPT                               100
 # define PROV_R_CIPHER_OPERATION_FAILED                   102
+# define PROV_R_FAILED_TO_GENERATE_KEY                    121
 # define PROV_R_FAILED_TO_GET_PARAMETER                   103
 # define PROV_R_FAILED_TO_SET_PARAMETER                   104
 # define PROV_R_INVALID_AAD                               108
diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c
index 9d9f484e42..ed1d930712 100644
--- a/providers/common/provider_err.c
+++ b/providers/common/provider_err.c
@@ -19,6 +19,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_DECRYPT), "bad decrypt"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_CIPHER_OPERATION_FAILED),
     "cipher operation failed"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_GENERATE_KEY),
+    "failed to generate key"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_GET_PARAMETER),
     "failed to get parameter"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SET_PARAMETER),
diff --git a/providers/default/build.info b/providers/default/build.info
index dd133388fc..f0a6c5c742 100644
--- a/providers/default/build.info
+++ b/providers/default/build.info
@@ -1,4 +1,4 @@
-SUBDIRS=digests macs
+SUBDIRS=digests macs ciphers
 LIBS=../../libcrypto
 SOURCE[../../libcrypto]=\
         defltprov.c
diff --git a/providers/default/ciphers/build.info b/providers/default/ciphers/build.info
new file mode 100644
index 0000000000..92f87e0301
--- /dev/null
+++ b/providers/default/ciphers/build.info
@@ -0,0 +1,22 @@
+LIBS=../../../libcrypto
+
+IF[{- !$disabled{des} -}]
+  SOURCE[../../../libcrypto]=\
+      cipher_tdes_default.c cipher_tdes_default_hw.c \
+      cipher_tdes_wrap.c cipher_tdes_wrap_hw.c \
+      cipher_desx.c cipher_desx_hw.c
+ENDIF
+
+IF[{- !$disabled{aria} -}]
+  SOURCE[../../../libcrypto]=\
+      cipher_aria.c cipher_aria_hw.c \
+      cipher_aria_gcm.c cipher_aria_gcm_hw.c \
+      cipher_aria_ccm.c cipher_aria_ccm_hw.c
+ENDIF
+
+IF[{- !$disabled{camellia} -}]
+  SOURCE[../../../libcrypto]=\
+      cipher_camellia.c cipher_camellia_hw.c
+ENDIF
+
+INCLUDE[../../../libcrypto]=. ../../../crypto
diff --git a/providers/common/ciphers/cipher_aria.c b/providers/default/ciphers/cipher_aria.c
similarity index 97%
rename from providers/common/ciphers/cipher_aria.c
rename to providers/default/ciphers/cipher_aria.c
index 5b7e8398bc..861b28268b 100644
--- a/providers/common/ciphers/cipher_aria.c
+++ b/providers/default/ciphers/cipher_aria.c
@@ -9,7 +9,8 @@
 
 /* Dispatch functions for ARIA cipher modes ecb, cbc, ofb, cfb, ctr */
 
-#include "cipher_locl.h"
+#include "cipher_aria.h"
+#include "internal/provider_algs.h"
 
 static OSSL_OP_cipher_freectx_fn aria_freectx;
 static OSSL_OP_cipher_dupctx_fn aria_dupctx;
diff --git a/providers/common/ciphers/cipher_aria.h b/providers/default/ciphers/cipher_aria.h
similarity index 92%
rename from providers/common/ciphers/cipher_aria.h
rename to providers/default/ciphers/cipher_aria.h
index 2b8015f6d7..984be8f4aa 100644
--- a/providers/common/ciphers/cipher_aria.h
+++ b/providers/default/ciphers/cipher_aria.h
@@ -7,8 +7,8 @@
  * https://www.openssl.org/source/license.html
  */
 
-#if !defined(OPENSSL_NO_ARIA)
-# include "internal/aria.h"
+#include "internal/aria.h"
+#include "internal/ciphers/ciphercommon.h"
 
 typedef struct prov_aria_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
@@ -18,6 +18,7 @@ typedef struct prov_aria_ctx_st {
     } ks;
 } PROV_ARIA_CTX;
 
+
 # define PROV_CIPHER_HW_aria_ofb PROV_CIPHER_HW_aria_ofb128
 # define PROV_CIPHER_HW_aria_cfb PROV_CIPHER_HW_aria_cfb128
 const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_ecb(size_t keybits);
@@ -27,5 +28,3 @@ const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_cfb128(size_t keybits);
 const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_cfb1(size_t keybits);
 const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_cfb8(size_t keybits);
 const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_ctr(size_t keybits);
-
-#endif /* OPENSSL_NO_ARIA */
diff --git a/providers/common/ciphers/cipher_aria_ccm.c b/providers/default/ciphers/cipher_aria_ccm.c
similarity index 94%
rename from providers/common/ciphers/cipher_aria_ccm.c
rename to providers/default/ciphers/cipher_aria_ccm.c
index 061ce53176..53b3defa9d 100644
--- a/providers/common/ciphers/cipher_aria_ccm.c
+++ b/providers/default/ciphers/cipher_aria_ccm.c
@@ -9,7 +9,10 @@
 
 /* Dispatch functions for ARIA CCM mode */
 
-#include "cipher_locl.h"
+#include "cipher_aria_ccm.h"
+#include "internal/provider_algs.h"
+
+static OSSL_OP_cipher_freectx_fn aria_ccm_freectx;
 
 static void *aria_ccm_newctx(void *provctx, size_t keybits)
 {
@@ -20,7 +23,6 @@ static void *aria_ccm_newctx(void *provctx, size_t keybits)
     return ctx;
 }
 
-static OSSL_OP_cipher_freectx_fn aria_ccm_freectx;
 static void aria_ccm_freectx(void *vctx)
 {
     PROV_ARIA_CCM_CTX *ctx = (PROV_ARIA_CCM_CTX *)vctx;
diff --git a/providers/default/ciphers/cipher_aria_ccm.h b/providers/default/ciphers/cipher_aria_ccm.h
new file mode 100644
index 0000000000..b3e990766d
--- /dev/null
+++ b/providers/default/ciphers/cipher_aria_ccm.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/aria.h"
+#include "internal/ciphers/ciphercommon.h"
+#include "internal/ciphers/cipher_ccm.h"
+
+typedef struct prov_aria_ccm_ctx_st {
+    PROV_CCM_CTX base; /* Must be first */
+    union {
+        OSSL_UNION_ALIGN;
+        ARIA_KEY ks;
+    } ks;                       /* ARIA key schedule to use */
+} PROV_ARIA_CCM_CTX;
+
+const PROV_CCM_HW *PROV_ARIA_HW_ccm(size_t keylen);
diff --git a/providers/common/ciphers/cipher_aria_ccm_hw.inc b/providers/default/ciphers/cipher_aria_ccm_hw.c
similarity index 89%
rename from providers/common/ciphers/cipher_aria_ccm_hw.inc
rename to providers/default/ciphers/cipher_aria_ccm_hw.c
index d980fa9b97..db3a9c8ea8 100644
--- a/providers/common/ciphers/cipher_aria_ccm_hw.inc
+++ b/providers/default/ciphers/cipher_aria_ccm_hw.c
@@ -9,10 +9,9 @@
 
 /*-
  * Generic support for ARIA CCM.
- * This file is included by cipher_ccm_hw.c
  */
 
-#if !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE)
+#include "cipher_aria_ccm.h"
 
 static int ccm_aria_initkey(PROV_CCM_CTX *ctx,
                             const unsigned char *key, size_t keylen)
@@ -39,4 +38,3 @@ const PROV_CCM_HW *PROV_ARIA_HW_ccm(size_t keybits)
 {
     return &ccm_aria;
 }
-#endif /* OPENSSL_NO_ARIA */
diff --git a/providers/common/ciphers/cipher_aria_gcm.c b/providers/default/ciphers/cipher_aria_gcm.c
similarity index 94%
rename from providers/common/ciphers/cipher_aria_gcm.c
rename to providers/default/ciphers/cipher_aria_gcm.c
index c68ad2c3ae..213fc147c8 100644
--- a/providers/common/ciphers/cipher_aria_gcm.c
+++ b/providers/default/ciphers/cipher_aria_gcm.c
@@ -9,7 +9,8 @@
 
 /* Dispatch functions for ARIA GCM mode */
 
-#include "cipher_locl.h"
+#include "cipher_aria_gcm.h"
+#include "internal/provider_algs.h"
 
 static void *aria_gcm_newctx(void *provctx, size_t keybits)
 {
diff --git a/providers/default/ciphers/cipher_aria_gcm.h b/providers/default/ciphers/cipher_aria_gcm.h
new file mode 100644
index 0000000000..3499ceaaf7
--- /dev/null
+++ b/providers/default/ciphers/cipher_aria_gcm.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/aria.h"
+#include "internal/ciphers/ciphercommon.h"
+#include "internal/ciphers/cipher_gcm.h"
+
+typedef struct prov_aria_gcm_ctx_st {
+    PROV_GCM_CTX base;              /* must be first entry in struct */
+    union {
+        OSSL_UNION_ALIGN;
+        ARIA_KEY ks;
+    } ks;
+} PROV_ARIA_GCM_CTX;
+
+const PROV_GCM_HW *PROV_ARIA_HW_gcm(size_t keybits);
diff --git a/providers/common/ciphers/cipher_aria_gcm_hw.inc b/providers/default/ciphers/cipher_aria_gcm_hw.c
similarity index 84%
rename from providers/common/ciphers/cipher_aria_gcm_hw.inc
rename to providers/default/ciphers/cipher_aria_gcm_hw.c
index fcb9bfce2b..ed1e1851dc 100644
--- a/providers/common/ciphers/cipher_aria_gcm_hw.inc
+++ b/providers/default/ciphers/cipher_aria_gcm_hw.c
@@ -9,10 +9,9 @@
 
 /*-
  * Generic support for ARIA GCM.
- * This file is included by cipher_gcm_hw.c
  */
 
-#if !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE)
+#include "cipher_aria_gcm.h"
 
 static int aria_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
                             size_t keylen)
@@ -20,7 +19,7 @@ static int aria_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
     PROV_ARIA_GCM_CTX *actx = (PROV_ARIA_GCM_CTX *)ctx;
     ARIA_KEY *ks = &actx->ks.ks;
 
-    SET_KEY_CTR_FN(ks, aria_set_encrypt_key, aria_encrypt, NULL);
+    GCM_HW_SET_KEY_CTR_FN(ks, aria_set_encrypt_key, aria_encrypt, NULL);
     return 1;
 }
 
@@ -49,5 +48,3 @@ const PROV_GCM_HW *PROV_ARIA_HW_gcm(size_t keybits)
 {
     return &aria_gcm;
 }
-
-#endif /* !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE) */
diff --git a/providers/common/ciphers/cipher_aria_hw.c b/providers/default/ciphers/cipher_aria_hw.c
similarity index 98%
rename from providers/common/ciphers/cipher_aria_hw.c
rename to providers/default/ciphers/cipher_aria_hw.c
index 2a89573521..b644be8dda 100644
--- a/providers/common/ciphers/cipher_aria_hw.c
+++ b/providers/default/ciphers/cipher_aria_hw.c
@@ -7,7 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "cipher_locl.h"
+#include "cipher_aria.h"
 
 static int cipher_hw_aria_initkey(PROV_CIPHER_CTX *dat,
                                   const unsigned char *key, size_t keylen)
diff --git a/providers/common/ciphers/cipher_camellia.c b/providers/default/ciphers/cipher_camellia.c
similarity index 97%
rename from providers/common/ciphers/cipher_camellia.c
rename to providers/default/ciphers/cipher_camellia.c
index 9215346924..68c0e91355 100644
--- a/providers/common/ciphers/cipher_camellia.c
+++ b/providers/default/ciphers/cipher_camellia.c
@@ -9,9 +9,9 @@
 
 /* Dispatch functions for CAMELLIA cipher modes ecb, cbc, ofb, cfb, ctr */
 
-#include "cipher_locl.h"
+#include "cipher_camellia.h"
+#include "internal/provider_algs.h"
 
-#if !defined(OPENSSL_NO_CAMELLIA)
 static OSSL_OP_cipher_freectx_fn camellia_freectx;
 static OSSL_OP_cipher_dupctx_fn camellia_dupctx;
 
@@ -79,4 +79,3 @@ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ctr, CTR, 0, 192, 8, 128, stream)
 /* camellia128ctr_functions */
 IMPLEMENT_generic_cipher(camellia, CAMELLIA, ctr, CTR, 0, 128, 8, 128, stream)
 
-#endif /* OPENSSL_NO_CAMELLIA */
diff --git a/providers/common/ciphers/cipher_camellia.h b/providers/default/ciphers/cipher_camellia.h
similarity index 81%
rename from providers/common/ciphers/cipher_camellia.h
rename to providers/default/ciphers/cipher_camellia.h
index e8e96bad81..521c03e261 100644
--- a/providers/common/ciphers/cipher_camellia.h
+++ b/providers/default/ciphers/cipher_camellia.h
@@ -7,9 +7,8 @@
  * https://www.openssl.org/source/license.html
  */
 
-#ifndef OPENSSL_NO_CAMELLIA
-
-# include <openssl/camellia.h>
+#include "openssl/camellia.h"
+#include "internal/ciphers/ciphercommon.h"
 
 typedef struct prov_camellia_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
@@ -19,8 +18,8 @@ typedef struct prov_camellia_ctx_st {
     } ks;
 } PROV_CAMELLIA_CTX;
 
-# define PROV_CIPHER_HW_camellia_ofb PROV_CIPHER_HW_camellia_ofb128
-# define PROV_CIPHER_HW_camellia_cfb PROV_CIPHER_HW_camellia_cfb128
+#define PROV_CIPHER_HW_camellia_ofb PROV_CIPHER_HW_camellia_ofb128
+#define PROV_CIPHER_HW_camellia_cfb PROV_CIPHER_HW_camellia_cfb128
 const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_ecb(size_t keybits);
 const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_cbc(size_t keybits);
 const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_ofb128(size_t keybits);
@@ -28,5 +27,3 @@ const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_cfb128(size_t keybits);
 const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_cfb1(size_t keybits);
 const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_cfb8(size_t keybits);
 const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_ctr(size_t keybits);
-
-#endif /* OPENSSL_NO_CAMELLIA */
diff --git a/providers/common/ciphers/cipher_camellia_hw.c b/providers/default/ciphers/cipher_camellia_hw.c
similarity index 96%
rename from providers/common/ciphers/cipher_camellia_hw.c
rename to providers/default/ciphers/cipher_camellia_hw.c
index dd65b31aef..39ba4bd0ac 100644
--- a/providers/common/ciphers/cipher_camellia_hw.c
+++ b/providers/default/ciphers/cipher_camellia_hw.c
@@ -7,9 +7,9 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "cipher_locl.h"
+#include "cipher_camellia.h"
+#include <openssl/camellia.h>
 
-#if !defined(OPENSSL_NO_CAMELLIA)
 static int cipher_hw_camellia_initkey(PROV_CIPHER_CTX *dat,
                                       const unsigned char *key, size_t keylen)
 {
@@ -62,4 +62,3 @@ PROV_CIPHER_HW_camellia_mode(cfb128)
 PROV_CIPHER_HW_camellia_mode(cfb1)
 PROV_CIPHER_HW_camellia_mode(cfb8)
 PROV_CIPHER_HW_camellia_mode(ctr)
-#endif /* OPENSSL_NO_CAMELLIA */
diff --git a/providers/common/ciphers/cipher_camellia_hw_t4.inc b/providers/default/ciphers/cipher_camellia_hw_t4.inc
similarity index 100%
rename from providers/common/ciphers/cipher_camellia_hw_t4.inc
rename to providers/default/ciphers/cipher_camellia_hw_t4.inc
diff --git a/providers/default/ciphers/cipher_desx.c b/providers/default/ciphers/cipher_desx.c
new file mode 100644
index 0000000000..4a232cd080
--- /dev/null
+++ b/providers/default/ciphers/cipher_desx.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "cipher_tdes_default.h"
+#include "internal/provider_algs.h"
+
+/* desx_cbc_functions */
+IMPLEMENT_tdes_cipher(desx, DESX, cbc, CBC, TDES_FLAGS, 64*3, 64, 64, block);
+
diff --git a/providers/default/ciphers/cipher_desx_hw.c b/providers/default/ciphers/cipher_desx_hw.c
new file mode 100644
index 0000000000..ef1b3b0694
--- /dev/null
+++ b/providers/default/ciphers/cipher_desx_hw.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/des.h>
+#include "cipher_tdes_default.h"
+
+/*
+ * Note the PROV_TDES_CTX has been used for the DESX cipher, just to reduce
+ * code size.
+ */
+#define ks1 tks.ks[0]
+#define ks2 tks.ks[1].ks[0].cblock
+#define ks3 tks.ks[2].ks[0].cblock
+
+static int cipher_hw_desx_cbc_initkey(PROV_CIPHER_CTX *ctx,
+                                      const unsigned char *key, size_t keylen)
+{
+    PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
+    DES_cblock *deskey = (DES_cblock *)key;
+
+    DES_set_key_unchecked(deskey, &tctx->ks1);
+    memcpy(&tctx->ks2, &key[8], 8);
+    memcpy(&tctx->ks3, &key[16], 8);
+
+    return 1;
+}
+
+static int cipher_hw_desx_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t inl)
+{
+    PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
+
+    while (inl >= MAXCHUNK) {
+        DES_xcbc_encrypt(in, out, (long)MAXCHUNK, &tctx->ks1,
+                         (DES_cblock *)ctx->iv, &tctx->ks2, &tctx->ks3,
+                         ctx->enc);
+        inl -= MAXCHUNK;
+        in += MAXCHUNK;
+        out += MAXCHUNK;
+    }
+    if (inl > 0)
+        DES_xcbc_encrypt(in, out, (long)inl, &tctx->ks1,
+                         (DES_cblock *)ctx->iv, &tctx->ks2, &tctx->ks3,
+                         ctx->enc);
+    return 1;
+}
+
+static const PROV_CIPHER_HW desx_cbc =
+{
+    cipher_hw_desx_cbc_initkey,
+    cipher_hw_desx_cbc
+};
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_desx_cbc(void)
+{
+    return &desx_cbc;
+}
diff --git a/providers/default/ciphers/cipher_tdes_default.c b/providers/default/ciphers/cipher_tdes_default.c
new file mode 100644
index 0000000000..73a78e8089
--- /dev/null
+++ b/providers/default/ciphers/cipher_tdes_default.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "cipher_tdes_default.h"
+#include "internal/provider_algs.h"
+
+/* tdes_ede3_ofb_functions */
+IMPLEMENT_tdes_cipher(ede3, EDE3,  ofb, OFB, TDES_FLAGS, 64*3,  8, 64, stream);
+/* tdes_ede3_cfb_functions */
+IMPLEMENT_tdes_cipher(ede3, EDE3,  cfb, CFB, TDES_FLAGS, 64*3,  8, 64, stream);
+/* tdes_ede3_cfb1_functions */
+IMPLEMENT_tdes_cipher(ede3, EDE3, cfb1, CFB, TDES_FLAGS, 64*3,  8, 64, stream);
+/* tdes_ede3_cfb8_functions */
+IMPLEMENT_tdes_cipher(ede3, EDE3, cfb8, CFB, TDES_FLAGS, 64*3,  8, 64, stream);
+
+/* tdes_ede2_ecb_functions */
+IMPLEMENT_tdes_cipher(ede2, EDE2, ecb, ECB, TDES_FLAGS, 64*2, 64, 64, block);
+/* tdes_ede2_cbc_functions */
+IMPLEMENT_tdes_cipher(ede2, EDE2, cbc, CBC, TDES_FLAGS, 64*2, 64, 64, block);
+/* tdes_ede2_ofb_functions */
+IMPLEMENT_tdes_cipher(ede2, EDE2, ofb, OFB, TDES_FLAGS, 64*2,  8, 64, stream);
+/* tdes_ede2_cfb_functions */
+IMPLEMENT_tdes_cipher(ede2, EDE2, cfb, CFB, TDES_FLAGS, 64*2,  8, 64, stream);
diff --git a/providers/default/ciphers/cipher_tdes_default.h b/providers/default/ciphers/cipher_tdes_default.h
new file mode 100644
index 0000000000..c809993795
--- /dev/null
+++ b/providers/default/ciphers/cipher_tdes_default.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/ciphers/ciphercommon.h"
+#include "internal/ciphers/cipher_tdes.h"
+
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_ofb(void);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cfb(void);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cfb1(void);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cfb8(void);
+
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede2_cbc(void);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede2_ecb(void);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede2_ofb(void);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede2_cfb(void);
+
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_desx_cbc(void);
+
+const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_wrap_cbc(void);
diff --git a/providers/default/ciphers/cipher_tdes_default_hw.c b/providers/default/ciphers/cipher_tdes_default_hw.c
new file mode 100644
index 0000000000..73169a0e56
--- /dev/null
+++ b/providers/default/ciphers/cipher_tdes_default_hw.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "cipher_tdes_default.h"
+
+#define ks1 tks.ks[0]
+#define ks2 tks.ks[1]
+#define ks3 tks.ks[2]
+
+static int cipher_hw_tdes_ede2_initkey(PROV_CIPHER_CTX *ctx,
+                                       const unsigned char *key, size_t keylen)
+{
+    PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
+    DES_cblock *deskey = (DES_cblock *)key;
+
+    tctx->tstream.cbc = NULL;
+# if defined(SPARC_DES_CAPABLE)
+    if (SPARC_DES_CAPABLE) {
+        if (ctx->mode == EVP_CIPH_CBC_MODE) {
+            des_t4_key_expand(&deskey[0], &tctx->ks1);
+            des_t4_key_expand(&deskey[1], &tctx->ks2);
+            memcpy(&tctx->ks3, &tctx->ks1, sizeof(tctx->ks1));
+            tctx->tstream.cbc = ctx->enc ? des_t4_ede3_cbc_encrypt :
+                                           des_t4_ede3_cbc_decrypt;
+            return 1;
+        }
+    }
+# endif
+    DES_set_key_unchecked(&deskey[0], &tctx->ks1);
+    DES_set_key_unchecked(&deskey[1], &tctx->ks2);
+    memcpy(&tctx->ks3, &tctx->ks1, sizeof(tctx->ks1));
+    return 1;
+}
+
+static int cipher_hw_tdes_ofb(PROV_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t inl)
+{
+    PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
+    int num = ctx->num;
+
+    while (inl >= MAXCHUNK) {
+        DES_ede3_ofb64_encrypt(in, out, (long)MAXCHUNK, &tctx->ks1, &tctx->ks2,
+                               &tctx->ks3, (DES_cblock *)ctx->iv, &num);
+        inl -= MAXCHUNK;
+        in += MAXCHUNK;
+        out += MAXCHUNK;
+    }
+    if (inl > 0) {
+        DES_ede3_ofb64_encrypt(in, out, (long)inl, &tctx->ks1, &tctx->ks2,
+                               &tctx->ks3, (DES_cblock *)ctx->iv, &num);
+    }
+    ctx->num = num;
+    return 1;
+}
+
+static int cipher_hw_tdes_cfb(PROV_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t inl)
+{
+    PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
+    int num = ctx->num;
+
+    while (inl >= MAXCHUNK) {
+
+        DES_ede3_cfb64_encrypt(in, out, (long)MAXCHUNK,
+                               &tctx->ks1, &tctx->ks2, &tctx->ks3,
+                               (DES_cblock *)ctx->iv, &num, ctx->enc);
+        inl -= MAXCHUNK;
+        in += MAXCHUNK;
+        out += MAXCHUNK;
+    }
+    if (inl > 0) {
+        DES_ede3_cfb64_encrypt(in, out, (long)inl,
+                               &tctx->ks1, &tctx->ks2, &tctx->ks3,
+                               (DES_cblock *)ctx->iv, &num, ctx->enc);
+    }
+    ctx->num = num;
+    return 1;
+}
+
+/*
+ * Although we have a CFB-r implementation for 3-DES, it doesn't pack the
+ * right way, so wrap it here
+ */
+static int cipher_hw_tdes_cfb1(PROV_CIPHER_CTX *ctx, unsigned char *out,
+                               const unsigned char *in, size_t inl)
+{
+    PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
+    size_t n;
+    unsigned char c[1], d[1];
+
+    if ((ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) == 0)
+        inl *= 8;
+    for (n = 0; n < inl; ++n) {
+        c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
+        DES_ede3_cfb_encrypt(c, d, 1, 1,
+                             &tctx->ks1, &tctx->ks2, &tctx->ks3,
+                             (DES_cblock *)ctx->iv, ctx->enc);
+        out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8)))
+            | ((d[0] & 0x80) >> (unsigned int)(n % 8));
+    }
+
+    return 1;
+}
+
+static int cipher_hw_tdes_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out,
+                               const unsigned char *in, size_t inl)
+{
+    PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
+
+    while (inl >= MAXCHUNK) {
+        DES_ede3_cfb_encrypt(in, out, 8, (long)MAXCHUNK,
+                             &tctx->ks1, &tctx->ks2, &tctx->ks3,
+                             (DES_cblock *)ctx->iv, ctx->enc);
+        inl -= MAXCHUNK;
+        in += MAXCHUNK;
+        out += MAXCHUNK;
+    }
+    if (inl > 0)
+        DES_ede3_cfb_encrypt(in, out, 8, (long)inl,
+                             &tctx->ks1, &tctx->ks2, &tctx->ks3,
+                             (DES_cblock *)ctx->iv, ctx->enc);
+    return 1;
+}
+
+PROV_CIPHER_HW_tdes_mode(ede3, ofb)
+PROV_CIPHER_HW_tdes_mode(ede3, cfb)
+PROV_CIPHER_HW_tdes_mode(ede3, cfb1)
+PROV_CIPHER_HW_tdes_mode(ede3, cfb8)
+
+PROV_CIPHER_HW_tdes_mode(ede2, ecb)
+PROV_CIPHER_HW_tdes_mode(ede2, cbc)
+PROV_CIPHER_HW_tdes_mode(ede2, ofb)
+PROV_CIPHER_HW_tdes_mode(ede2, cfb)
+
diff --git a/providers/default/ciphers/cipher_tdes_wrap.c b/providers/default/ciphers/cipher_tdes_wrap.c
new file mode 100644
index 0000000000..833e18190a
--- /dev/null
+++ b/providers/default/ciphers/cipher_tdes_wrap.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/sha.h>
+#include "cipher_tdes_default.h"
+#include "internal/evp_int.h"
+#include "internal/rand_int.h"
+#include "internal/provider_algs.h"
+#include "internal/providercommonerr.h"
+
+/* TODO (3.0) Figure out what flags are requred */
+#define TDES_WRAP_FLAGS (EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV               \
+                        | EVP_CIPH_FLAG_CUSTOM_CIPHER                          \
+                        | EVP_CIPH_FLAG_DEFAULT_ASN1)
+
+
+static OSSL_OP_cipher_update_fn tdes_wrap_update;
+static OSSL_OP_cipher_cipher_fn tdes_wrap_cipher;
+
+static const unsigned char wrap_iv[8] =
+{
+    0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05
+};
+
+static int des_ede3_unwrap(PROV_CIPHER_CTX *ctx, unsigned char *out,
+                           const unsigned char *in, size_t inl)
+{
+    unsigned char icv[8], iv[TDES_IVLEN], sha1tmp[SHA_DIGEST_LENGTH];
+    int rv = -1;
+
+    if (inl < 24)
+        return -1;
+    if (out == NULL)
+        return inl - 16;
+
+    memcpy(ctx->iv, wrap_iv, 8);
+    /* Decrypt first block which will end up as icv */
+    ctx->hw->cipher(ctx, icv, in, 8);
+    /* Decrypt central blocks */
+    /*
+     * If decrypting in place move whole output along a block so the next
+     * des_ede_cbc_cipher is in place.
+     */
+    if (out == in) {
+        memmove(out, out + 8, inl - 8);
+        in -= 8;
+    }
+    ctx->hw->cipher(ctx, out, in + 8, inl - 16);
+    /* Decrypt final block which will be IV */
+    ctx->hw->cipher(ctx, iv, in + inl - 8, 8);
+    /* Reverse order of everything */
+    BUF_reverse(icv, NULL, 8);
+    BUF_reverse(out, NULL, inl - 16);
+    BUF_reverse(ctx->iv, iv, 8);
+    /* Decrypt again using new IV */
+    ctx->hw->cipher(ctx, out, out, inl - 16);
+    ctx->hw->cipher(ctx, icv, icv, 8);
+    /* Work out SHA1 hash of first portion */
+    SHA1(out, inl - 16, sha1tmp);
+
+    if (!CRYPTO_memcmp(sha1tmp, icv, 8))
+        rv = inl - 16;
+    OPENSSL_cleanse(icv, 8);
+    OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH);
+    OPENSSL_cleanse(iv, 8);
+    OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv));
+    if (rv == -1)
+        OPENSSL_cleanse(out, inl - 16);
+
+    return rv;
+}
+
+static int des_ede3_wrap(PROV_CIPHER_CTX *ctx, unsigned char *out,
+                         const unsigned char *in, size_t inl)
+{
+    unsigned char sha1tmp[SHA_DIGEST_LENGTH];
+    size_t ivlen = TDES_IVLEN;
+    size_t icvlen = TDES_IVLEN;
+    size_t len = inl + ivlen + icvlen;
+
+    if (out == NULL)
+        return len;
+
+    /* Copy input to output buffer + 8 so we have space for IV */
+    memmove(out + ivlen, in, inl);
+    /* Work out ICV */
+    SHA1(in, inl, sha1tmp);
+    memcpy(out + inl + ivlen, sha1tmp, icvlen);
+    OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH);
+    /* Generate random IV */
+    if (rand_bytes_ex(ctx->libctx, ctx->iv, ivlen) <= 0)
+        return 0;
+    memcpy(out, ctx->iv, ivlen);
+    /* Encrypt everything after IV in place */
+    ctx->hw->cipher(ctx, out + ivlen, out + ivlen, inl + ivlen);
+    BUF_reverse(out, NULL, len);
+    memcpy(ctx->iv, wrap_iv, ivlen);
+    ctx->hw->cipher(ctx, out, out, len);
+    return len;
+}
+
+static int tdes_wrap_cipher_internal(PROV_CIPHER_CTX *ctx, unsigned char *out,
+                                     const unsigned char *in, size_t inl)
+{
+    /*
+     * Sanity check input length: we typically only wrap keys so EVP_MAXCHUNK
+     * is more than will ever be needed. Also input length must be a multiple
+     * of 8 bits.
+     */
+    if (inl >= EVP_MAXCHUNK || inl % 8)
+        return -1;
+    if (ctx->enc)
+        return des_ede3_wrap(ctx, out, in, inl);
+    else
+        return des_ede3_unwrap(ctx, out, in, inl);
+}
+
+static int tdes_wrap_cipher(void *vctx,
+                            unsigned char *out, size_t *outl, size_t outsize,
+                            const unsigned char *in, size_t inl)
+{
+    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+    int ret;
+
+    *outl = 0;
+    if (outsize < inl) {
+        PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
+        return -1;
+    }
+
+    ret = tdes_wrap_cipher_internal(ctx, out, in, inl);
+    if (ret <= 0)
+        return 0;
+
+    *outl = ret;
+    return 1;
+}
+
+static int tdes_wrap_update(void *vctx, unsigned char *out, size_t *outl,
+                            size_t outsize, const unsigned char *in,
+                            size_t inl)
+{
+    *outl = 0;
+    if (outsize < inl) {
+        PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
+        return 0;
+    }
+
+    if (!tdes_wrap_cipher(vctx, out, outl, outsize, in, inl)) {
+        PROVerr(0, PROV_R_CIPHER_OPERATION_FAILED);
+        return 0;
+    }
+    return 1;
+}
+
+
+# define IMPLEMENT_WRAP_CIPHER(flags, kbits, blkbits, ivbits)                  \
+static OSSL_OP_cipher_newctx_fn tdes_wrap_newctx;                              \
+static void *tdes_wrap_newctx(void *provctx)                                   \
+{                                                                              \
+    return tdes_newctx(provctx, EVP_CIPH_WRAP_MODE, kbits, blkbits, ivbits,    \
+                       PROV_CIPHER_HW_tdes_wrap_cbc());                        \
+}                                                                              \
+static OSSL_OP_cipher_get_params_fn tdes_wrap_get_params;                      \
+static int tdes_wrap_get_params(OSSL_PARAM params[])                           \
+{                                                                              \
+    return cipher_generic_get_params(params, EVP_CIPH_WRAP_MODE, flags,        \
+                                     kbits, blkbits, ivbits);                  \
+}                                                                              \
+const OSSL_DISPATCH tdes_wrap_cbc_functions[] =                                \
+{                                                                              \
+    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) tdes_einit },            \
+    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void)) tdes_dinit },            \
+    { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))tdes_wrap_cipher },             \
+    { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))tdes_wrap_newctx },             \
+    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))tdes_freectx },                \
+    { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))tdes_wrap_update },             \
+    { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_stream_final },   \
+    { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))tdes_wrap_get_params },     \
+    { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
+      (void (*)(void))cipher_generic_gettable_params },                        \
+    { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))tdes_get_ctx_params },  \
+    { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
+      (void (*)(void))tdes_gettable_ctx_params },                              \
+    { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
+      (void (*)(void))cipher_generic_set_ctx_params },                         \
+    { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
+      (void (*)(void))cipher_generic_settable_ctx_params },                    \
+    { 0, NULL }                                                                \
+}
+
+/* tdes_wrap_cbc_functions */
+IMPLEMENT_WRAP_CIPHER(TDES_WRAP_FLAGS, 64*3, 64, 0);
diff --git a/providers/default/ciphers/cipher_tdes_wrap_hw.c b/providers/default/ciphers/cipher_tdes_wrap_hw.c
new file mode 100644
index 0000000000..09155b6f48
--- /dev/null
+++ b/providers/default/ciphers/cipher_tdes_wrap_hw.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "cipher_tdes_default.h"
+
+#define cipher_hw_tdes_wrap_initkey cipher_hw_tdes_ede3_initkey
+
+PROV_CIPHER_HW_tdes_mode(wrap, cbc)
diff --git a/providers/default/defltprov.c b/providers/default/defltprov.c
index 5664fbe3b2..2498d068df 100644
--- a/providers/default/defltprov.c
+++ b/providers/default/defltprov.c
@@ -173,6 +173,18 @@ static const OSSL_ALGORITHM deflt_ciphers[] = {
     { "CAMELLIA-192-CTR", "default=yes", camellia192ctr_functions },
     { "CAMELLIA-128-CTR", "default=yes", camellia128ctr_functions },
 #endif /* OPENSSL_NO_CAMELLIA */
+    { "DES-EDE3", "default=yes", tdes_ede3_ecb_functions },
+    { "DES-EDE3-CBC", "default=yes", tdes_ede3_cbc_functions },
+    { "DES-EDE3-OFB", "default=yes", tdes_ede3_ofb_functions },
+    { "DES-EDE3-CFB", "default=yes", tdes_ede3_cfb_functions },
+    { "DES-EDE3-CFB8", "default=yes", tdes_ede3_cfb8_functions },
+    { "DES-EDE3-CFB1", "default=yes", tdes_ede3_cfb1_functions },
+    { "DES-EDE", "default=yes", tdes_ede2_ecb_functions },
+    { "DES-EDE-CBC", "default=yes", tdes_ede2_cbc_functions },
+    { "DES-EDE-OFB", "default=yes", tdes_ede2_ofb_functions },
+    { "DES-EDE-CFB", "default=yes", tdes_ede2_cfb_functions },
+    { "DESX-CBC", "default=yes", tdes_desx_cbc_functions },
+    { "id-smime-alg-CMS3DESwrap", "default=yes", tdes_wrap_cbc_functions },
     { NULL, NULL, NULL }
 };
 
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 839581bbe9..8e68a6c843 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -324,6 +324,8 @@ static const OSSL_ALGORITHM fips_ciphers[] = {
     { "id-aes256-CCM", "fips=yes", aes256ccm_functions },
     { "id-aes192-CCM", "fips=yes", aes192ccm_functions },
     { "id-aes128-CCM", "fips=yes", aes128ccm_functions },
+    { "DES-EDE3", "fips=yes", tdes_ede3_ecb_functions },
+    { "DES-EDE3-CBC", "fips=yes", tdes_ede3_cbc_functions },
     { NULL, NULL, NULL }
 };
 
diff --git a/test/recipes/30-test_evp_data/evpciph.txt b/test/recipes/30-test_evp_data/evpciph.txt
index bd2778e398..28820ecf52 100644
--- a/test/recipes/30-test_evp_data/evpciph.txt
+++ b/test/recipes/30-test_evp_data/evpciph.txt
@@ -22,12 +22,14 @@
 Title = DES Tests (various sources)
 
 Cipher = DES-EDE3-CFB1
+Availablein = default
 Key = 000102030405060708090A0B0C0D0E0F1011121314151617
 IV = 0001020304050607
 Plaintext = "Hello World"
 Ciphertext = 3CF55D656E9C0664513358
 
 Cipher = DES-EDE3-CFB1
+Availablein = default
 Key = 000102030405060708090A0B0C0D0E0F1011121314151617
 IV = 0001020304050607
 Operation = DECRYPT
@@ -35,6 +37,7 @@ Plaintext = "Hello World"
 Ciphertext = 3CF55D656E9C0664513358
 
 Cipher = DESX-CBC
+Availablein = default
 Key = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210
 IV = fedcba9876543210
 Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
@@ -50,36 +53,43 @@ Ciphertext = 3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
 # DES ECB tests (from destest)
 
 Cipher = DES-ECB
+Availablein = default
 Key = 0000000000000000
 Plaintext = 0000000000000000
 Ciphertext = 8CA64DE9C1B123A7
 
 Cipher = DES-ECB
+Availablein = default
 Key = FFFFFFFFFFFFFFFF
 Plaintext = FFFFFFFFFFFFFFFF
 Ciphertext = 7359B2163E4EDC58
 
 Cipher = DES-ECB
+Availablein = default
 Key = 3000000000000000
 Plaintext = 1000000000000001
 Ciphertext = 958E6E627A05557B
 
 Cipher = DES-ECB
+Availablein = default
 Key = 1111111111111111
 Plaintext = 1111111111111111
 Ciphertext = F40379AB9E0EC533
 
 Cipher = DES-ECB
+Availablein = default
 Key = 0123456789ABCDEF
 Plaintext = 1111111111111111
 Ciphertext = 17668DFC7292532D
 
 Cipher = DES-ECB
+Availablein = default
 Key = 1111111111111111
 Plaintext = 0123456789ABCDEF
 Ciphertext = 8A5AE1F81AB8F2DD
 
 Cipher = DES-ECB
+Availablein = default
 Key = FEDCBA9876543210
 Plaintext = 0123456789ABCDEF
 Ciphertext = ED39D950FA74BCC4


More information about the openssl-commits mailing list