openssl/openssl
Legacy provider
Active contributors: Pauli, Tomas Mraz
Purpose
The legacy provider contains old or weak algorithms that were available before OpenSSL 3.0 but are not recommended for new use. It is not loaded by default — applications upgrading from older OpenSSL versions must load it explicitly to get back the old behavior.
It is built as a shared module (legacy.so / legacy.dll), distinct from the default provider, so that applications can refuse to load it as a security measure.
Entry point: providers/legacyprov.c (~10 KB).
What it offers
From providers/legacyprov.c:
Digests:
- MD2 (provider-only via
legacy_md2.c) - MD4
- MDC2
- RIPEMD-160 (RMD160)
- Whirlpool
- (BLAKE2 is not in legacy — it remains in default.)
Symmetric ciphers:
- Blowfish (BF) in CBC/CFB/CTR/ECB/OFB
- CAST5 in CBC/CFB/ECB/OFB
- DES (single, not 3DES) in CBC/CFB/ECB/OFB
- Two-key 3DES (
DES-EDEfamily) - IDEA in CBC/CFB/ECB/OFB
- RC2 in CBC/CFB/ECB/OFB and 40-bit RC2
- RC4 (and
RC4-HMAC-MD5) - RC5 in CBC/CFB/ECB/OFB
- SEED in CBC/CFB/ECB/OFB
KDFs:
- PBKDF1 (the SHA-1-only PBKDF from PKCS #5 v1.5)
The actual implementations are shared with the default provider — they live in providers/implementations/{ciphers,digests,kdfs}/. The split is in which provider exposes them, not in where the code lives.
Loading
OSSL_PROVIDER *legacy = OSSL_PROVIDER_load(NULL, "legacy");
OSSL_PROVIDER *deflt = OSSL_PROVIDER_load(NULL, "default");
/* Once you load any provider explicitly, the default is no longer auto-loaded.
Load it back if you want both. */Or via openssl.cnf:
[provider_sect]
default = default_sect
legacy = legacy_sect
[default_sect]
activate = 1
[legacy_sect]
activate = 1Why split it out
Three reasons:
- Default-deny security posture. Code that uses MD4 or RC4 should opt in. A scanner can flag any application that loads
legacy.soand check whether the use is justified. - Reduced attack surface. Embedded systems can ship
libcrypto.sowithoutlegacy.soand be guaranteed they cannot be tricked into using a weak primitive. - FIPS compatibility. When you use the FIPS provider you typically combine it with
base(encoders/decoders) but neverlegacy. The split makes the policy unambiguous.
Property
Legacy algorithms are typically registered with provider=legacy. To filter them out, set the libctx default property to provider!=legacy or provider=default,?fips=yes.
Where the implementations live (subset map)
| Algorithm | File |
|---|---|
| MD2 | providers/implementations/digests/md2_prov.c (and the deprecated wrapper in crypto/evp/legacy_md2.c) |
| MD4 | providers/implementations/digests/md4_prov.c |
| MDC2 | providers/implementations/digests/mdc2_prov.c |
| RIPEMD-160 | providers/implementations/digests/ripemd_prov.c |
| Whirlpool | providers/implementations/digests/wp_prov.c |
| Blowfish | providers/implementations/ciphers/cipher_blowfish.c |
| CAST5 | providers/implementations/ciphers/cipher_cast5.c |
| DES (single) | providers/implementations/ciphers/cipher_des.c |
| IDEA | providers/implementations/ciphers/cipher_idea.c |
| RC2/RC4/RC5 | providers/implementations/ciphers/cipher_rc{2,4,5}.c |
| SEED | providers/implementations/ciphers/cipher_seed.c |
| PBKDF1 | providers/implementations/kdfs/pbkdf1.c |
Each has its own OSSL_DISPATCH[] table; legacyprov.c references those tables in the rows of its legacy_digests[] and legacy_ciphers[] arrays.
Entry points for modification
- Removing an algorithm from legacy: delete its row in
legacyprov.cand remove the source files fromproviders/build.info. The wrapper incrypto/evp/legacy_*.cmay also need to go. - Adding an algorithm to legacy: write the implementation under
providers/implementations/<area>/, add the row to the appropriate table inlegacyprov.c, write tests.
Documentation
doc/man7/OSSL_PROVIDER-legacy.pod— the canonical algorithm list and rationale.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.