Move legacy ciphers into the legacy provider
authorShane Lontis <shane.lontis@oracle.com>
Thu, 9 Apr 2020 02:47:46 +0000 (12:47 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Thu, 9 Apr 2020 02:47:46 +0000 (12:47 +1000)
DES, idea, seed, rc2, rc4, rc5, cast and blowfish have been moved out of the default provider.
Code shared between desx and tdes has been moved into a seperate file (cipher_tdes_common.c).
3 test recipes failed due to using app/openssl calls that used legacy ciphers.
These calls have been updated to supply both the default and legacy providers.
Fixed openssl app '-provider' memory leak

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11419)

21 files changed:
apps/include/apps.h
apps/include/opt.h
apps/lib/app_provider.c
apps/openssl.c
crypto/bf/build.info
crypto/cast/build.info
crypto/des/build.info
crypto/idea/build.info
crypto/rc2/build.info
crypto/rc4/build.info
crypto/rc5/build.info
crypto/seed/build.info
providers/build.info
providers/defltprov.c
providers/implementations/ciphers/build.info
providers/implementations/ciphers/cipher_tdes.c
providers/implementations/ciphers/cipher_tdes_common.c [new file with mode: 0644]
providers/legacyprov.c
test/recipes/20-test_enc.t
test/recipes/20-test_enc_more.t
test/recipes/80-test_cms.t

index 90f9c2b..f43c12d 100644 (file)
@@ -286,5 +286,6 @@ extern VERIFY_CB_ARGS verify_args;
 OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts,
                                      const OSSL_PARAM *paramdefs);
 void app_params_free(OSSL_PARAM *params);
+void app_providers_cleanup(void);
 
 #endif
index b4257cc..9f82b6f 100644 (file)
 
 # define OPT_PROV_OPTIONS \
         OPT_SECTION("Provider"), \
-        { "provider", OPT_PROV_PROVIDER, 's', "Provder to load (can be specified multiple times)" }, \
-        { "provider_path", OPT_PROV_PROVIDER_PATH, 's', "Provider load path" }
+        { "provider_path", OPT_PROV_PROVIDER_PATH, 's', "Provider load path (must be before 'provider' argument if required)" }, \
+        { "provider", OPT_PROV_PROVIDER, 's', "Provider to load (can be specified multiple times)" }
 
 # define OPT_PROV_CASES \
         OPT_PROV__FIRST: case OPT_PROV__LAST: break; \
index ac01e88..ca24328 100644 (file)
 #include "apps.h"
 #include <openssl/err.h>
 #include <openssl/provider.h>
+#include <openssl/safestack.h>
+
+DEFINE_STACK_OF(OSSL_PROVIDER)
 
 /*
  * See comments in opt_verify for explanation of this.
  */
 enum prov_range { OPT_PROV_ENUM };
 
+static STACK_OF(OSSL_PROVIDER) *app_providers = NULL;
+
 static int opt_provider_load(const char *provider)
 {
     OSSL_PROVIDER *prov;
@@ -26,9 +31,27 @@ static int opt_provider_load(const char *provider)
                           opt_getprog(), provider);
         return 0;
     }
+    if (app_providers == NULL)
+        app_providers = sk_OSSL_PROVIDER_new_null();
+    if (app_providers == NULL
+        || !sk_OSSL_PROVIDER_push(app_providers, prov)) {
+        app_providers_cleanup();
+        return 0;
+    }
     return 1;
 }
 
+static void provider_free(OSSL_PROVIDER *prov)
+{
+    OSSL_PROVIDER_unload(prov);
+}
+
+void app_providers_cleanup(void)
+{
+    sk_OSSL_PROVIDER_pop_free(app_providers, provider_free);
+    app_providers = NULL;
+}
+
 static int opt_provider_path(const char *path)
 {
     if (path != NULL && *path == '\0')
index cafe404..558f662 100644 (file)
@@ -368,6 +368,7 @@ int main(int argc, char *argv[])
     }
     ret = 1;
  end:
+    app_providers_cleanup();
     OPENSSL_free(default_config_file);
     lh_FUNCTION_free(prog);
     OPENSSL_free(arg.argv);
index 59d5bbc..9fa8187 100644 (file)
@@ -11,7 +11,15 @@ IF[{- !$disabled{asm} -}]
   ENDIF
 ENDIF
 
-SOURCE[../../libcrypto]=bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c $BFASM
+$ALL=bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c $BFASM
+
+SOURCE[../../libcrypto]=$ALL
+
+# When all deprecated symbols are removed, libcrypto doesn't export the
+# blowfish functions, so we must include them directly in liblegacy.a
+IF[{- $disabled{'deprecated-3.0'} -}]
+  SOURCE[../../providers/liblegacy.a]=$ALL
+ENDIF
 
 GENERATE[bf-586.s]=asm/bf-586.pl
 DEPEND[bf-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl
index e21e6d5..8763f22 100644 (file)
@@ -12,7 +12,15 @@ IF[{- !$disabled{asm} && !$disabled{pic} -}]
   ENDIF
 ENDIF
 
-SOURCE[../../libcrypto]=c_skey.c c_ecb.c $CASTASM c_cfb64.c c_ofb64.c
+$ALL=c_skey.c c_ecb.c $CASTASM c_cfb64.c c_ofb64.c
+
+SOURCE[../../libcrypto]=$ALL
+
+# When all deprecated symbols are removed, libcrypto doesn't export the
+# cast functions, so we must include them directly in liblegacy.a
+IF[{- $disabled{'deprecated-3.0'} -}]
+  SOURCE[../../providers/liblegacy.a]=$ALL
+ENDIF
 
 GENERATE[cast-586.s]=asm/cast-586.pl
 DEPEND[cast-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl
index 1fbbcdf..0e5fd17 100644 (file)
@@ -15,20 +15,23 @@ ENDIF
 
 LIBS=../../libcrypto
 $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 \
-        fcrypt.c xcbc_enc.c cbc_cksm.c
+$ALL=$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 \
+     fcrypt.c xcbc_enc.c cbc_cksm.c
+
+SOURCE[../../libcrypto]=$ALL
 SOURCE[../../providers/libfips.a]=$COMMON
 DEFINE[../../libcrypto]=$DESDEF
 DEFINE[../../providers/libfips.a]=$DESDEF
+DEFINE[../../providers/liblegacy.a]=$DESDEF
 
 # When all deprecated symbols are removed, libcrypto doesn't export the
 # DES functions, so we must include them directly in liblegacy.a
 IF[{- $disabled{'deprecated-3.0'} && !$disabled{"mdc2"} -}]
-  SOURCE[../../providers/liblegacy.a]=set_key.c $DESASM
+  SOURCE[../../providers/liblegacy.a]=$ALL
   DEFINE[../../providers/liblegacy.a]=$DESDEF
 ENDIF
 
index 2326123..5441351 100644 (file)
@@ -1,3 +1,10 @@
 LIBS=../../libcrypto
-SOURCE[../../libcrypto]=\
-        i_cbc.c i_cfb64.c i_ofb64.c i_ecb.c i_skey.c
+$ALL=i_cbc.c i_cfb64.c i_ofb64.c i_ecb.c i_skey.c
+
+SOURCE[../../libcrypto]=$ALL
+
+# When all deprecated symbols are removed, libcrypto doesn't export the
+# idea functions, so we must include them directly in liblegacy.a
+IF[{- $disabled{'deprecated-3.0'} -}]
+  SOURCE[../../providers/liblegacy.a]=$ALL
+ENDIF
index 47a3fd0..b6d60d6 100644 (file)
@@ -1,3 +1,11 @@
 LIBS=../../libcrypto
-SOURCE[../../libcrypto]=\
-        rc2_ecb.c rc2_skey.c rc2_cbc.c rc2cfb64.c rc2ofb64.c
+
+$ALL=rc2_ecb.c rc2_skey.c rc2_cbc.c rc2cfb64.c rc2ofb64.c
+
+SOURCE[../../libcrypto]=$ALL
+
+# When all deprecated symbols are removed, libcrypto doesn't export the
+# rc2 functions, so we must include them directly in liblegacy.a
+IF[{- $disabled{'deprecated-3.0'} -}]
+  SOURCE[../../providers/liblegacy.a]=$ALL
+ENDIF
index abc0c52..c7f17ca 100644 (file)
@@ -19,6 +19,12 @@ ENDIF
 
 SOURCE[../../libcrypto]=$RC4ASM
 
+# When all deprecated symbols are removed, libcrypto doesn't export the
+# rc4 functions, so we must include them directly in liblegacy.a
+IF[{- $disabled{'deprecated-3.0'} -}]
+  SOURCE[../../providers/liblegacy.a]=$RC4ASM
+ENDIF
+
 GENERATE[rc4-586.s]=asm/rc4-586.pl
 DEPEND[rc4-586.s]=../perlasm/x86asm.pl
 
index c684d1e..3e2def8 100644 (file)
@@ -12,8 +12,15 @@ IF[{- !$disabled{asm} -}]
   ENDIF
 ENDIF
 
-SOURCE[../../libcrypto]=\
-        rc5_skey.c rc5_ecb.c $RC5ASM rc5cfb64.c rc5ofb64.c
+$ALL=rc5_skey.c rc5_ecb.c $RC5ASM rc5cfb64.c rc5ofb64.c
+
+SOURCE[../../libcrypto]=$ALL
+
+# When all deprecated symbols are removed, libcrypto doesn't export the
+# rc5 functions, so we must include them directly in liblegacy.a
+IF[{- $disabled{'deprecated-3.0'} -}]
+  SOURCE[../../providers/liblegacy.a]=$ALL
+ENDIF
 
 GENERATE[rc5-586.s]=asm/rc5-586.pl
 DEPEND[rc5-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl
index abdcbca..5336f03 100644 (file)
@@ -1,2 +1,10 @@
 LIBS=../../libcrypto
-SOURCE[../../libcrypto]=seed.c seed_ecb.c seed_cbc.c seed_cfb.c seed_ofb.c
+$ALL=seed.c seed_ecb.c seed_cbc.c seed_cfb.c seed_ofb.c
+
+SOURCE[../../libcrypto]=$ALL
+
+# When all deprecated symbols are removed, libcrypto doesn't export the
+# seed functions, so we must include them directly in liblegacy.a
+IF[{- $disabled{'deprecated-3.0'} -}]
+  SOURCE[../../providers/liblegacy.a]=$ALL
+ENDIF
index a58c8ea..54c3381 100644 (file)
@@ -47,7 +47,7 @@ $COMMON_INCLUDES=../crypto ../include implementations/include common/include
 
 INCLUDE[$LIBCOMMON]=$COMMON_INCLUDES
 INCLUDE[$LIBIMPLEMENTATIONS]=.. $COMMON_INCLUDES
-INCLUDE[$LIBLEGACY]=$COMMON_INCLUDES
+INCLUDE[$LIBLEGACY]=.. $COMMON_INCLUDES
 INCLUDE[$LIBNONFIPS]=$COMMON_INCLUDES
 INCLUDE[$LIBFIPS]=.. $COMMON_INCLUDES
 DEFINE[$LIBFIPS]=FIPS_MODE
index 2ec229e..f93bd31 100644 (file)
@@ -254,43 +254,12 @@ static const OSSL_ALGORITHM_CAPABLE deflt_ciphers[] = {
     ALG("DES-EDE3-CFB", tdes_ede3_cfb_functions),
     ALG("DES-EDE3-CFB8", tdes_ede3_cfb8_functions),
     ALG("DES-EDE3-CFB1", tdes_ede3_cfb1_functions),
+    ALG("DES3-WRAP:id-smime-alg-CMS3DESwrap", tdes_wrap_cbc_functions),
     ALG("DES-EDE-ECB:DES-EDE", tdes_ede2_ecb_functions),
     ALG("DES-EDE-CBC", tdes_ede2_cbc_functions),
     ALG("DES-EDE-OFB", tdes_ede2_ofb_functions),
     ALG("DES-EDE-CFB", tdes_ede2_cfb_functions),
-    ALG("DESX-CBC:DESX", tdes_desx_cbc_functions),
-    ALG("DES3-WRAP:id-smime-alg-CMS3DESwrap", tdes_wrap_cbc_functions),
-    ALG("DES-ECB", des_ecb_functions),
-    ALG("DES-CBC:DES", des_cbc_functions),
-    ALG("DES-OFB", des_ofb64_functions),
-    ALG("DES-CFB", des_cfb64_functions),
-    ALG("DES-CFB1", des_cfb1_functions),
-    ALG("DES-CFB8", des_cfb8_functions),
 #endif /* OPENSSL_NO_DES */
-#ifndef OPENSSL_NO_BF
-    ALG("BF-ECB", blowfish128ecb_functions),
-    ALG("BF-CBC:BF:BLOWFISH", blowfish128cbc_functions),
-    ALG("BF-OFB", blowfish64ofb64_functions),
-    ALG("BF-CFB", blowfish64cfb64_functions),
-#endif /* OPENSSL_NO_BF */
-#ifndef OPENSSL_NO_IDEA
-    ALG("IDEA-ECB", idea128ecb_functions),
-    ALG("IDEA-CBC:IDEA", idea128cbc_functions),
-    ALG("IDEA-OFB:IDEA-OFB64", idea128ofb64_functions),
-    ALG("IDEA-CFB:IDEA-CFB64", idea128cfb64_functions),
-#endif /* OPENSSL_NO_IDEA */
-#ifndef OPENSSL_NO_CAST
-    ALG("CAST5-ECB", cast5128ecb_functions),
-    ALG("CAST5-CBC:CAST-CBC:CAST", cast5128cbc_functions),
-    ALG("CAST5-OFB", cast564ofb64_functions),
-    ALG("CAST5-CFB", cast564cfb64_functions),
-#endif /* OPENSSL_NO_CAST */
-#ifndef OPENSSL_NO_SEED
-    ALG("SEED-ECB", seed128ecb_functions),
-    ALG("SEED-CBC:SEED", seed128cbc_functions),
-    ALG("SEED-OFB:SEED-OFB128", seed128ofb128_functions),
-    ALG("SEED-CFB:SEED-CFB128", seed128cfb128_functions),
-#endif /* OPENSSL_NO_SEED */
 #ifndef OPENSSL_NO_SM4
     ALG("SM4-ECB", sm4128ecb_functions),
     ALG("SM4-CBC:SM4", sm4128cbc_functions),
@@ -298,27 +267,6 @@ static const OSSL_ALGORITHM_CAPABLE deflt_ciphers[] = {
     ALG("SM4-OFB:SM4-OFB128", sm4128ofb128_functions),
     ALG("SM4-CFB:SM4-CFB128", sm4128cfb128_functions),
 #endif /* OPENSSL_NO_SM4 */
-#ifndef OPENSSL_NO_RC4
-    ALG("RC4", rc4128_functions),
-    ALG("RC4-40", rc440_functions),
-# ifndef OPENSSL_NO_MD5
-    ALG("RC4-HMAC-MD5", rc4_hmac_md5_functions),
-# endif /* OPENSSL_NO_MD5 */
-#endif /* OPENSSL_NO_RC4 */
-#ifndef OPENSSL_NO_RC5
-    ALG("RC5-ECB", rc5128ecb_functions),
-    ALG("RC5-CBC", rc5128cbc_functions),
-    ALG("RC5-OFB", rc5128ofb64_functions),
-    ALG("RC5-CFB", rc5128cfb64_functions),
-#endif /* OPENSSL_NO_RC5 */
-#ifndef OPENSSL_NO_RC2
-    ALG("RC2-ECB", rc2128ecb_functions),
-    ALG("RC2-CBC", rc2128cbc_functions),
-    ALG("RC2-40-CBC", rc240cbc_functions),
-    ALG("RC2-64-CBC", rc264cbc_functions),
-    ALG("RC2-CFB", rc2128cfb128_functions),
-    ALG("RC2-OFB", rc2128ofb128_functions),
-#endif /* OPENSSL_NO_RC2 */
 #ifndef OPENSSL_NO_CHACHA
     ALG("ChaCha20", chacha20_functions),
 # ifndef OPENSSL_NO_POLY1305
index c45ea00..c97008c 100644 (file)
@@ -11,17 +11,17 @@ $NULL_GOAL=../../libimplementations.a
 $AES_GOAL=../../libimplementations.a
 $TDES_1_GOAL=../../libimplementations.a
 $TDES_2_GOAL=../../libimplementations.a
-$DES_GOAL=../../libimplementations.a
 $ARIA_GOAL=../../libimplementations.a
 $CAMELLIA_GOAL=../../libimplementations.a
-$BLOWFISH_GOAL=../../libimplementations.a
-$IDEA_GOAL=../../libimplementations.a
-$CAST5_GOAL=../../libimplementations.a
-$SEED_GOAL=../../libimplementations.a
+$DES_GOAL=../../liblegacy.a
+$BLOWFISH_GOAL=../../liblegacy.a
+$IDEA_GOAL=../../liblegacy.a
+$CAST5_GOAL=../../liblegacy.a
+$RC2_GOAL=../../liblegacy.a
+$RC4_GOAL=../../liblegacy.a
+$RC5_GOAL=../../liblegacy.a
+$SEED_GOAL=../../liblegacy.a
 $SM4_GOAL=../../libimplementations.a
-$RC4_GOAL=../../libimplementations.a
-$RC5_GOAL=../../libimplementations.a
-$RC2_GOAL=../../libimplementations.a
 $CHACHA_GOAL=../../libimplementations.a
 $CHACHAPOLY_GOAL=../../libimplementations.a
 $SIV_GOAL=../../libimplementations.a
@@ -33,7 +33,7 @@ SOURCE[$COMMON_GOAL]=\
         ciphercommon_ccm.c ciphercommon_ccm_hw.c
 
 IF[{- !$disabled{des} -}]
-  SOURCE[$TDES_1_GOAL]=cipher_tdes.c cipher_tdes_hw.c
+  SOURCE[$TDES_1_GOAL]=cipher_tdes.c cipher_tdes_common.c cipher_tdes_hw.c
 ENDIF
 
 SOURCE[$NULL_GOAL]=\
@@ -63,7 +63,7 @@ IF[{- !$disabled{des} -}]
       cipher_tdes_default.c cipher_tdes_default_hw.c \
       cipher_tdes_wrap.c cipher_tdes_wrap_hw.c
   SOURCE[$DES_GOAL]=\
-      cipher_desx.c cipher_desx_hw.c \
+      cipher_desx.c cipher_desx_hw.c cipher_tdes_common.c\
       cipher_des.c cipher_des_hw.c
 ENDIF
 
index ea0c987..82af8bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2020 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
 #include "prov/implementations.h"
 #include "prov/providercommonerr.h"
 
-void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
-                  size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw)
-{
-    PROV_TDES_CTX *tctx = OPENSSL_zalloc(sizeof(*tctx));
-
-    if (tctx != NULL)
-        cipher_generic_initkey(tctx, kbits, blkbits, ivbits, mode, flags, hw,
-                               provctx);
-    return tctx;
-}
-
-void tdes_freectx(void *vctx)
-{
-    PROV_TDES_CTX *ctx = (PROV_TDES_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 (!cipher_generic_initiv(ctx, iv, ivlen))
-            return 0;
-    }
-
-    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 */
diff --git a/providers/implementations/ciphers/cipher_tdes_common.c b/providers/implementations/ciphers/cipher_tdes_common.c
new file mode 100644 (file)
index 0000000..36a8962
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2019-2020 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
+ */
+
+/*
+ * DES low level APIs are deprecated for public use, but still ok for internal
+ * use.
+ */
+#include "internal/deprecated.h"
+
+#include "prov/ciphercommon.h"
+#include "cipher_tdes.h"
+#include <openssl/rand.h>
+#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
+
+void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
+                  size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw)
+{
+    PROV_TDES_CTX *tctx = OPENSSL_zalloc(sizeof(*tctx));
+
+    if (tctx != NULL)
+        cipher_generic_initkey(tctx, kbits, blkbits, ivbits, mode, flags, hw,
+                               provctx);
+    return tctx;
+}
+
+void tdes_freectx(void *vctx)
+{
+    PROV_TDES_CTX *ctx = (PROV_TDES_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 (!cipher_generic_initiv(ctx, iv, ivlen))
+            return 0;
+    }
+
+    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);
+}
+
+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)
+
+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;
+}
+
+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;
+}
index 3494a88..a439cfd 100644 (file)
@@ -15,6 +15,8 @@
 #include <openssl/params.h>
 #include "prov/implementations.h"
 
+#define ALG(NAMES, FUNC) { NAMES, "provider=legacy", FUNC }
+
 #ifdef STATIC_LEGACY
 OSSL_provider_init_fn ossl_legacy_provider_init;
 # define OSSL_provider_init ossl_legacy_provider_init
@@ -56,25 +58,78 @@ static int legacy_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
 
 static const OSSL_ALGORITHM legacy_digests[] = {
 #ifndef OPENSSL_NO_MD2
-    { "MD2", "provider=legacy", md2_functions },
+    ALG("MD2", md2_functions),
 #endif
-
 #ifndef OPENSSL_NO_MD4
-    { "MD4", "provider=legacy", md4_functions },
+    ALG("MD4", md4_functions),
 #endif
-
 #ifndef OPENSSL_NO_MDC2
-    { "MDC2", "provider=legacy", mdc2_functions },
+    ALG("MDC2", mdc2_functions),
 #endif /* OPENSSL_NO_MDC2 */
-
 #ifndef OPENSSL_NO_WHIRLPOOL
-    { "WHIRLPOOL", "provider=legacy", wp_functions },
+    ALG("WHIRLPOOL", wp_functions),
 #endif /* OPENSSL_NO_WHIRLPOOL */
-
 #ifndef OPENSSL_NO_RMD160
-    { "RIPEMD-160:RIPEMD160:RIPEMD:RMD160", "provider=legacy", ripemd160_functions },
+    ALG("RIPEMD-160:RIPEMD160:RIPEMD:RMD160", ripemd160_functions),
 #endif /* OPENSSL_NO_RMD160 */
+    { NULL, NULL, NULL }
+};
 
+static const OSSL_ALGORITHM legacy_ciphers[] = {
+#ifndef OPENSSL_NO_CAST
+    ALG("CAST5-ECB", cast5128ecb_functions),
+    ALG("CAST5-CBC:CAST-CBC:CAST", cast5128cbc_functions),
+    ALG("CAST5-OFB", cast564ofb64_functions),
+    ALG("CAST5-CFB", cast564cfb64_functions),
+#endif /* OPENSSL_NO_CAST */
+#ifndef OPENSSL_NO_BF
+    ALG("BF-ECB", blowfish128ecb_functions),
+    ALG("BF-CBC:BF:BLOWFISH", blowfish128cbc_functions),
+    ALG("BF-OFB", blowfish64ofb64_functions),
+    ALG("BF-CFB", blowfish64cfb64_functions),
+#endif /* OPENSSL_NO_BF */
+#ifndef OPENSSL_NO_IDEA
+    ALG("IDEA-ECB", idea128ecb_functions),
+    ALG("IDEA-CBC:IDEA", idea128cbc_functions),
+    ALG("IDEA-OFB:IDEA-OFB64", idea128ofb64_functions),
+    ALG("IDEA-CFB:IDEA-CFB64", idea128cfb64_functions),
+#endif /* OPENSSL_NO_IDEA */
+#ifndef OPENSSL_NO_SEED
+    ALG("SEED-ECB", seed128ecb_functions),
+    ALG("SEED-CBC:SEED", seed128cbc_functions),
+    ALG("SEED-OFB:SEED-OFB128", seed128ofb128_functions),
+    ALG("SEED-CFB:SEED-CFB128", seed128cfb128_functions),
+#endif /* OPENSSL_NO_SEED */
+#ifndef OPENSSL_NO_RC2
+    ALG("RC2-ECB", rc2128ecb_functions),
+    ALG("RC2-CBC", rc2128cbc_functions),
+    ALG("RC2-40-CBC", rc240cbc_functions),
+    ALG("RC2-64-CBC", rc264cbc_functions),
+    ALG("RC2-CFB", rc2128cfb128_functions),
+    ALG("RC2-OFB", rc2128ofb128_functions),
+#endif /* OPENSSL_NO_RC2 */
+#ifndef OPENSSL_NO_RC4
+    ALG("RC4", rc4128_functions),
+    ALG("RC4-40", rc440_functions),
+# ifndef OPENSSL_NO_MD5
+    ALG("RC4-HMAC-MD5", rc4_hmac_md5_functions),
+# endif /* OPENSSL_NO_MD5 */
+#endif /* OPENSSL_NO_RC4 */
+#ifndef OPENSSL_NO_RC5
+    ALG("RC5-ECB", rc5128ecb_functions),
+    ALG("RC5-CBC", rc5128cbc_functions),
+    ALG("RC5-OFB", rc5128ofb64_functions),
+    ALG("RC5-CFB", rc5128cfb64_functions),
+#endif /* OPENSSL_NO_RC5 */
+#ifndef OPENSSL_NO_DES
+    ALG("DESX-CBC:DESX", tdes_desx_cbc_functions),
+    ALG("DES-ECB", des_ecb_functions),
+    ALG("DES-CBC:DES", des_cbc_functions),
+    ALG("DES-OFB", des_ofb64_functions),
+    ALG("DES-CFB", des_cfb64_functions),
+    ALG("DES-CFB1", des_cfb1_functions),
+    ALG("DES-CFB8", des_cfb8_functions),
+#endif /* OPENSSL_NO_DES */
     { NULL, NULL, NULL }
 };
 
@@ -86,6 +141,8 @@ static const OSSL_ALGORITHM *legacy_query(OSSL_PROVIDER *prov,
     switch (operation_id) {
     case OSSL_OP_DIGEST:
         return legacy_digests;
+    case OSSL_OP_CIPHER:
+        return legacy_ciphers;
     }
     return NULL;
 }
index b4a8e01..896de8c 100644 (file)
@@ -14,7 +14,7 @@ use File::Spec::Functions qw/catfile/;
 use File::Copy;
 use File::Compare qw/compare_text/;
 use File::Basename;
-use OpenSSL::Test qw/:DEFAULT srctop_file/;
+use OpenSSL::Test qw/:DEFAULT srctop_file bldtop_dir/;
 
 setup("test_enc");
 
@@ -26,6 +26,8 @@ my $testsrc = srctop_file("test","recipes",basename($0));
 my $test = catfile(".", "p");
 
 my $cmd = "openssl";
+my $provpath = bldtop_dir("providers");
+my @prov = ("-provider_path", $provpath, "-provider", "default", "-provider", "legacy");
 
 my $ciphersstatus = undef;
 my @ciphers =
@@ -59,8 +61,8 @@ plan tests => 2 + (scalar @ciphers)*2;
                 @d = ( "enc", @{$variant{$t}}, "-d" );
             }
 
-            ok(run(app([$cmd, @e, "-in", $test, "-out", $cipherfile]))
-               && run(app([$cmd, @d, "-in", $cipherfile, "-out", $clearfile]))
+            ok(run(app([$cmd, @e, @prov, "-in", $test, "-out", $cipherfile]))
+               && run(app([$cmd, @d, @prov, "-in", $cipherfile, "-out", $clearfile]))
                && compare_text($test,$clearfile) == 0, $t);
         }
      }
index a596634..7edcff0 100644 (file)
@@ -15,7 +15,7 @@ use File::Spec::Functions qw/catfile/;
 use File::Copy;
 use File::Compare qw/compare_text/;
 use File::Basename;
-use OpenSSL::Test qw/:DEFAULT srctop_file/;
+use OpenSSL::Test qw/:DEFAULT srctop_file bldtop_dir/;
 
 setup("test_evp_more");
 
@@ -25,6 +25,8 @@ my $cipherlist = undef;
 my $plaintext = catfile(".", "testdatafile");
 my $fail = "";
 my $cmd = "openssl";
+my $provpath = bldtop_dir("providers");
+my @prov = ("-provider_path", $provpath, "-provider", "default", "-provider", "legacy");
 
 my $ciphersstatus = undef;
 my @ciphers =
@@ -49,9 +51,9 @@ SKIP: {
         my $clearfile = "$plaintext.$ciphername.clear";
         my @common = ( $cmd, "enc", "$cipher", "-k", "test" );
 
-        ok(run(app([@common, "-e", "-in", $plaintext, "-out", $cipherfile]))
+        ok(run(app([@common, @prov, "-e", "-in", $plaintext, "-out", $cipherfile]))
            && compare_text($plaintext, $cipherfile) != 0
-           && run(app([@common, "-d", "-in", $cipherfile, "-out", $clearfile]))
+           && run(app([@common, @prov, "-d", "-in", $cipherfile, "-out", $clearfile]))
            && compare_text($plaintext, $clearfile) == 0
            , $ciphername);
     }
index fd66557..0e2969d 100644 (file)
@@ -13,7 +13,7 @@ use warnings;
 use POSIX;
 use File::Spec::Functions qw/catfile/;
 use File::Compare qw/compare_text/;
-use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file/;
+use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir/;
 use OpenSSL::Test::Utils;
 
 setup("test_cms");
@@ -21,6 +21,9 @@ setup("test_cms");
 plan skip_all => "CMS is not supported by this OpenSSL build"
     if disabled("cms");
 
+my $provpath = bldtop_dir("providers");
+my @prov = ("-provider_path", $provpath, "-provider", "default", "-provider", "legacy");
+
 my $datadir = srctop_dir("test", "recipes", "80-test_cms_data");
 my $smdir    = srctop_dir("test", "smime-certs");
 my $smcont   = srctop_file("test", "smcont.txt");
@@ -311,10 +314,11 @@ my @smime_cms_tests = (
     ],
 
     [ "encrypted content test streaming PEM format, 128 bit RC2 key",
-      [ "{cmd1}", "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
+      [ "{cmd1}", @prov, "-EncryptedData_encrypt",
+        "-in", $smcont, "-outform", "PEM",
         "-rc2", "-secretkey", "000102030405060708090A0B0C0D0E0F",
         "-stream", "-out", "{output}.cms" ],
-      [ "{cmd2}", "-EncryptedData_decrypt", "-in", "{output}.cms",
+      [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
         "-inform", "PEM",
         "-secretkey", "000102030405060708090A0B0C0D0E0F",
         "-out", "{output}.txt" ],
@@ -322,10 +326,11 @@ my @smime_cms_tests = (
     ],
 
     [ "encrypted content test streaming PEM format, 40 bit RC2 key",
-      [ "{cmd1}", "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
+      [ "{cmd1}", @prov, "-EncryptedData_encrypt",
+        "-in", $smcont, "-outform", "PEM",
         "-rc2", "-secretkey", "0001020304",
         "-stream", "-out", "{output}.cms" ],
-      [ "{cmd2}", "-EncryptedData_decrypt", "-in", "{output}.cms",
+      [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
         "-inform", "PEM",
         "-secretkey", "0001020304", "-out", "{output}.txt" ],
       \&final_compare