Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support OpenSSL 3.0 #658

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions encfs/SSL_Cipher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
#include <sys/mman.h>
#include <sys/time.h>

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/core_names.h>
#include <openssl/provider.h>
#endif

#include "Cipher.h"
#include "Error.h"
#include "Interface.h"
Expand All @@ -48,6 +53,13 @@ const int MAX_KEYLENGTH = 32; // in bytes (256 bit)
const int MAX_IVLENGTH = 16; // 128 bit (AES block size, Blowfish has 64)
const int KEY_CHECKSUM_BYTES = 4;

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
const OSSL_PARAM HMAC_PARAMS[2] = {
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, OSSL_DIGEST_NAME_SHA1, 0),
OSSL_PARAM_construct_end()
};
#endif

/**
This produces the same result as OpenSSL's EVP_BytesToKey. The difference
is that here we can explicitly specify the key size, instead of relying on
Expand Down Expand Up @@ -159,6 +171,11 @@ static Interface BlowfishInterface("ssl/blowfish", 3, 0, 2);
static Interface AESInterface("ssl/aes", 3, 0, 2);
static Interface CAMELLIAInterface("ssl/camellia", 3, 0, 2);

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
static OSSL_PROVIDER *default_provider = NULL;
static OSSL_PROVIDER *legacy_provider = NULL;
#endif

#ifndef OPENSSL_NO_CAMELLIA

static Range CAMELLIAKeyRange(128, 256, 64);
Expand Down Expand Up @@ -207,6 +224,23 @@ static Range BFKeyRange(128, 256, 32);
static Range BFBlockRange(64, 4096, 8);

static std::shared_ptr<Cipher> NewBFCipher(const Interface &iface, int keyLen) {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
/**
With OpenSSL 3.0, Blowfish is considered a legacy cipher.
The legacy provider is not normally loaded, and loading it
also disables the default fallback provider, so we load
them both here.

We should also unload these providers when we finish
with them, but for encfs, that happens when the library
exits anyway.
*/
if (legacy_provider == NULL) {
default_provider = OSSL_PROVIDER_load(NULL, "default");
legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
}
#endif

if (keyLen <= 0) {
keyLen = 160;
}
Expand Down Expand Up @@ -286,7 +320,12 @@ class SSLKey : public AbstractCipherKey {
EVP_CIPHER_CTX *stream_enc;
EVP_CIPHER_CTX *stream_dec;

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_MAC *evp_mac;
EVP_MAC_CTX *evp_mac_ctx;
#else
HMAC_CTX *mac_ctx;
#endif

SSLKey(int keySize, int ivLength);

Expand Down Expand Up @@ -318,8 +357,14 @@ SSLKey::SSLKey(int keySize_, int ivLength_) {
EVP_CIPHER_CTX_init(stream_enc);
stream_dec = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(stream_dec);

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
evp_mac = EVP_MAC_fetch(NULL, OSSL_MAC_NAME_HMAC, NULL);
evp_mac_ctx = EVP_MAC_CTX_new(evp_mac);
#else
mac_ctx = HMAC_CTX_new();
HMAC_CTX_reset(mac_ctx);
#endif
}

SSLKey::~SSLKey() {
Expand All @@ -336,7 +381,13 @@ SSLKey::~SSLKey() {
EVP_CIPHER_CTX_free(block_dec);
EVP_CIPHER_CTX_free(stream_enc);
EVP_CIPHER_CTX_free(stream_dec);

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_MAC_CTX_free(evp_mac_ctx);
EVP_MAC_free(evp_mac);
#else
HMAC_CTX_free(mac_ctx);
#endif

pthread_mutex_destroy(&mutex);
}
Expand Down Expand Up @@ -373,7 +424,11 @@ void initKey(const std::shared_ptr<SSLKey> &key, const EVP_CIPHER *_blockCipher,
EVP_EncryptInit_ex(key->stream_enc, nullptr, nullptr, KeyData(key), nullptr);
EVP_DecryptInit_ex(key->stream_dec, nullptr, nullptr, KeyData(key), nullptr);

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_MAC_init(key->evp_mac_ctx, KeyData(key), _keySize, HMAC_PARAMS);
#else
HMAC_Init_ex(key->mac_ctx, KeyData(key), _keySize, EVP_sha1(), nullptr);
#endif
}

SSL_Cipher::SSL_Cipher(const Interface &iface_, const Interface &realIface_,
Expand Down Expand Up @@ -515,8 +570,17 @@ static uint64_t _checksum_64(SSLKey *key, const unsigned char *data,
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int mdLen = EVP_MAX_MD_SIZE;

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#if OPENSSL_VERSION_NUMBER >= 0x30000030L
EVP_MAC_init(key->evp_mac_ctx, NULL, 0, NULL);
#else
EVP_MAC_init(key->evp_mac_ctx, key->buffer, key->keySize, HMAC_PARAMS);
#endif
EVP_MAC_update(key->evp_mac_ctx, data, dataLen);
#else
HMAC_Init_ex(key->mac_ctx, nullptr, 0, nullptr, nullptr);
HMAC_Update(key->mac_ctx, data, dataLen);
#endif
if (chainedIV != nullptr) {
// toss in the chained IV as well
uint64_t tmp = *chainedIV;
Expand All @@ -526,10 +590,18 @@ static uint64_t _checksum_64(SSLKey *key, const unsigned char *data,
tmp >>= 8;
}

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_MAC_update(key->evp_mac_ctx, h, 8);
#else
HMAC_Update(key->mac_ctx, h, 8);
#endif
}

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_MAC_final(key->evp_mac_ctx, md, (size_t *)&mdLen, sizeof(md));
#else
HMAC_Final(key->mac_ctx, md, &mdLen);
#endif

rAssert(mdLen >= 8);

Expand Down Expand Up @@ -698,10 +770,21 @@ void SSL_Cipher::setIVec(unsigned char *ivec, uint64_t seed,
}

// combine ivec and seed with HMAC
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#if OPENSSL_VERSION_NUMBER >= 0x30000030L
EVP_MAC_init(key->evp_mac_ctx, NULL, 0, NULL);
#else
EVP_MAC_init(key->evp_mac_ctx, key->buffer, key->keySize, HMAC_PARAMS);
#endif
EVP_MAC_update(key->evp_mac_ctx, ivec, _ivLength);
EVP_MAC_update(key->evp_mac_ctx, md, 8);
EVP_MAC_final(key->evp_mac_ctx, md, (size_t *)&mdLen, sizeof(md));
#else
HMAC_Init_ex(key->mac_ctx, nullptr, 0, nullptr, nullptr);
HMAC_Update(key->mac_ctx, ivec, _ivLength);
HMAC_Update(key->mac_ctx, md, 8);
HMAC_Final(key->mac_ctx, md, &mdLen);
#endif
rAssert(mdLen >= _ivLength);

memcpy(ivec, md, _ivLength);
Expand Down
6 changes: 3 additions & 3 deletions encfs/openssl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#define NO_DES
#include <openssl/rand.h>
#include <openssl/ssl.h>
#ifndef OPENSSL_NO_ENGINE
#if OPENSSL_VERSION_NUMBER < 0x30000000L && !defined(OPENSSL_NO_ENGINE)
#include <openssl/engine.h>
#endif

Expand Down Expand Up @@ -77,7 +77,7 @@ void openssl_init(bool threaded) {
RAND_bytes((unsigned char *)&randSeed, sizeof(randSeed));
srand(randSeed);

#ifndef OPENSSL_NO_ENGINE
#if OPENSSL_VERSION_NUMBER < 0x30000000L && !defined(OPENSSL_NO_ENGINE)
/* Load all bundled ENGINEs into memory and make them visible */
ENGINE_load_builtin_engines();
/* Register all of them for every algorithm they collectively implement */
Expand All @@ -93,7 +93,7 @@ void openssl_init(bool threaded) {
}

void openssl_shutdown(bool threaded) {
#ifndef OPENSSL_NO_ENGINE
#if OPENSSL_VERSION_NUMBER < 0x30000000L && !defined(OPENSSL_NO_ENGINE)
ENGINE_cleanup();
#endif

Expand Down
4 changes: 2 additions & 2 deletions encfs/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

#define NO_DES
#include <openssl/ssl.h>
#ifndef OPENSSL_NO_ENGINE
#if OPENSSL_VERSION_NUMBER < 0x30000000L && !defined(OPENSSL_NO_ENGINE)
#include <openssl/engine.h>
#endif

Expand Down Expand Up @@ -402,7 +402,7 @@ int main(int argc, char *argv[]) {
SSL_load_error_strings();
SSL_library_init();

#ifndef OPENSSL_NO_ENGINE
#if OPENSSL_VERSION_NUMBER < 0x30000000L && !defined(OPENSSL_NO_ENGINE)
ENGINE_load_builtin_engines();
ENGINE_register_all_ciphers();
ENGINE_register_all_digests();
Expand Down