Skip to content

Commit

Permalink
Merge pull request #230 from rogeliodh/openssl_1.1
Browse files Browse the repository at this point in the history
build with openssl 1.1.0b
  • Loading branch information
vgough committed Oct 17, 2016
2 parents 323d57c + 0573bc5 commit 441fa20
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 75 deletions.
155 changes: 80 additions & 75 deletions encfs/SSL_Cipher.cpp
Expand Up @@ -36,6 +36,7 @@
#include "Interface.h"
#include "Mutex.h"
#include "Range.h"
#include "SSL_Compat.h"
#include "SSL_Cipher.h"
#include "intl/gettext.h"

Expand Down Expand Up @@ -74,19 +75,19 @@ int BytesToKey(int keyLen, int ivLen, const EVP_MD *md,
int nkey = key ? keyLen : 0;
int niv = iv ? ivLen : 0;

EVP_MD_CTX cx;
EVP_MD_CTX_init(&cx);
EVP_MD_CTX *cx = EVP_MD_CTX_new();
EVP_MD_CTX_init(cx);

for (;;) {
EVP_DigestInit_ex(&cx, md, NULL);
if (addmd++) EVP_DigestUpdate(&cx, mdBuf, mds);
EVP_DigestUpdate(&cx, data, dataLen);
EVP_DigestFinal_ex(&cx, mdBuf, &mds);
EVP_DigestInit_ex(cx, md, NULL);
if (addmd++) EVP_DigestUpdate(cx, mdBuf, mds);
EVP_DigestUpdate(cx, data, dataLen);
EVP_DigestFinal_ex(cx, mdBuf, &mds);

for (unsigned int i = 1; i < rounds; ++i) {
EVP_DigestInit_ex(&cx, md, NULL);
EVP_DigestUpdate(&cx, mdBuf, mds);
EVP_DigestFinal_ex(&cx, mdBuf, &mds);
EVP_DigestInit_ex(cx, md, NULL);
EVP_DigestUpdate(cx, mdBuf, mds);
EVP_DigestFinal_ex(cx, mdBuf, &mds);
}

int offset = 0;
Expand All @@ -106,7 +107,7 @@ int BytesToKey(int keyLen, int ivLen, const EVP_MD *md,
}
if ((nkey == 0) && (niv == 0)) break;
}
EVP_MD_CTX_cleanup(&cx);
EVP_MD_CTX_free(cx);
OPENSSL_cleanse(mdBuf, sizeof(mdBuf));

return keyLen;
Expand Down Expand Up @@ -229,12 +230,12 @@ class SSLKey : public AbstractCipherKey {
// followed by iv of _ivLength bytes,
unsigned char *buffer;

EVP_CIPHER_CTX block_enc;
EVP_CIPHER_CTX block_dec;
EVP_CIPHER_CTX stream_enc;
EVP_CIPHER_CTX stream_dec;
EVP_CIPHER_CTX *block_enc;
EVP_CIPHER_CTX *block_dec;
EVP_CIPHER_CTX *stream_enc;
EVP_CIPHER_CTX *stream_dec;

HMAC_CTX mac_ctx;
HMAC_CTX *mac_ctx;

SSLKey(int keySize, int ivLength);
~SSLKey();
Expand All @@ -251,11 +252,16 @@ SSLKey::SSLKey(int keySize_, int ivLength_) {
// kernel patch is applied..
mlock(buffer, keySize + ivLength);

EVP_CIPHER_CTX_init(&block_enc);
EVP_CIPHER_CTX_init(&block_dec);
EVP_CIPHER_CTX_init(&stream_enc);
EVP_CIPHER_CTX_init(&stream_dec);
HMAC_CTX_init(&mac_ctx);
block_enc = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(block_enc);
block_dec = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(block_dec);
stream_enc = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(stream_enc);
stream_dec = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(stream_dec);
mac_ctx = HMAC_CTX_new();
HMAC_CTX_reset(mac_ctx);
}

SSLKey::~SSLKey() {
Expand All @@ -268,12 +274,11 @@ SSLKey::~SSLKey() {
ivLength = 0;
buffer = 0;

EVP_CIPHER_CTX_cleanup(&block_enc);
EVP_CIPHER_CTX_cleanup(&block_dec);
EVP_CIPHER_CTX_cleanup(&stream_enc);
EVP_CIPHER_CTX_cleanup(&stream_dec);

HMAC_CTX_cleanup(&mac_ctx);
EVP_CIPHER_CTX_free(block_enc);
EVP_CIPHER_CTX_free(block_dec);
EVP_CIPHER_CTX_free(stream_enc);
EVP_CIPHER_CTX_free(stream_dec);
HMAC_CTX_free(mac_ctx);

pthread_mutex_destroy(&mutex);
}
Expand All @@ -290,27 +295,27 @@ void initKey(const std::shared_ptr<SSLKey> &key, const EVP_CIPHER *_blockCipher,
Lock lock(key->mutex);
// initialize the cipher context once so that we don't have to do it for
// every block..
EVP_EncryptInit_ex(&key->block_enc, _blockCipher, NULL, NULL, NULL);
EVP_DecryptInit_ex(&key->block_dec, _blockCipher, NULL, NULL, NULL);
EVP_EncryptInit_ex(&key->stream_enc, _streamCipher, NULL, NULL, NULL);
EVP_DecryptInit_ex(&key->stream_dec, _streamCipher, NULL, NULL, NULL);

EVP_CIPHER_CTX_set_key_length(&key->block_enc, _keySize);
EVP_CIPHER_CTX_set_key_length(&key->block_dec, _keySize);
EVP_CIPHER_CTX_set_key_length(&key->stream_enc, _keySize);
EVP_CIPHER_CTX_set_key_length(&key->stream_dec, _keySize);

EVP_CIPHER_CTX_set_padding(&key->block_enc, 0);
EVP_CIPHER_CTX_set_padding(&key->block_dec, 0);
EVP_CIPHER_CTX_set_padding(&key->stream_enc, 0);
EVP_CIPHER_CTX_set_padding(&key->stream_dec, 0);

EVP_EncryptInit_ex(&key->block_enc, NULL, NULL, KeyData(key), NULL);
EVP_DecryptInit_ex(&key->block_dec, NULL, NULL, KeyData(key), NULL);
EVP_EncryptInit_ex(&key->stream_enc, NULL, NULL, KeyData(key), NULL);
EVP_DecryptInit_ex(&key->stream_dec, NULL, NULL, KeyData(key), NULL);

HMAC_Init_ex(&key->mac_ctx, KeyData(key), _keySize, EVP_sha1(), 0);
EVP_EncryptInit_ex(key->block_enc, _blockCipher, NULL, NULL, NULL);
EVP_DecryptInit_ex(key->block_dec, _blockCipher, NULL, NULL, NULL);
EVP_EncryptInit_ex(key->stream_enc, _streamCipher, NULL, NULL, NULL);
EVP_DecryptInit_ex(key->stream_dec, _streamCipher, NULL, NULL, NULL);

EVP_CIPHER_CTX_set_key_length(key->block_enc, _keySize);
EVP_CIPHER_CTX_set_key_length(key->block_dec, _keySize);
EVP_CIPHER_CTX_set_key_length(key->stream_enc, _keySize);
EVP_CIPHER_CTX_set_key_length(key->stream_dec, _keySize);

EVP_CIPHER_CTX_set_padding(key->block_enc, 0);
EVP_CIPHER_CTX_set_padding(key->block_dec, 0);
EVP_CIPHER_CTX_set_padding(key->stream_enc, 0);
EVP_CIPHER_CTX_set_padding(key->stream_dec, 0);

EVP_EncryptInit_ex(key->block_enc, NULL, NULL, KeyData(key), NULL);
EVP_DecryptInit_ex(key->block_dec, NULL, NULL, KeyData(key), NULL);
EVP_EncryptInit_ex(key->stream_enc, NULL, NULL, KeyData(key), NULL);
EVP_DecryptInit_ex(key->stream_dec, NULL, NULL, KeyData(key), NULL);

HMAC_Init_ex(key->mac_ctx, KeyData(key), _keySize, EVP_sha1(), 0);
}

SSL_Cipher::SSL_Cipher(const Interface &iface_, const Interface &realIface_,
Expand Down Expand Up @@ -451,8 +456,8 @@ 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;

HMAC_Init_ex(&key->mac_ctx, 0, 0, 0, 0);
HMAC_Update(&key->mac_ctx, data, dataLen);
HMAC_Init_ex(key->mac_ctx, 0, 0, 0, 0);
HMAC_Update(key->mac_ctx, data, dataLen);
if (chainedIV) {
// toss in the chained IV as well
uint64_t tmp = *chainedIV;
Expand All @@ -462,10 +467,10 @@ static uint64_t _checksum_64(SSLKey *key, const unsigned char *data,
tmp >>= 8;
}

HMAC_Update(&key->mac_ctx, h, 8);
HMAC_Update(key->mac_ctx, h, 8);
}

HMAC_Final(&key->mac_ctx, md, &mdLen);
HMAC_Final(key->mac_ctx, md, &mdLen);

rAssert(mdLen >= 8);

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

// combine ivec and seed with HMAC
HMAC_Init_ex(&key->mac_ctx, 0, 0, 0, 0);
HMAC_Update(&key->mac_ctx, ivec, _ivLength);
HMAC_Update(&key->mac_ctx, md, 8);
HMAC_Final(&key->mac_ctx, md, &mdLen);
HMAC_Init_ex(key->mac_ctx, 0, 0, 0, 0);
HMAC_Update(key->mac_ctx, ivec, _ivLength);
HMAC_Update(key->mac_ctx, md, 8);
HMAC_Final(key->mac_ctx, md, &mdLen);
rAssert(mdLen >= _ivLength);

memcpy(ivec, md, _ivLength);
Expand Down Expand Up @@ -731,17 +736,17 @@ bool SSL_Cipher::streamEncode(unsigned char *buf, int size, uint64_t iv64,
shuffleBytes(buf, size);

setIVec(ivec, iv64, key);
EVP_EncryptInit_ex(&key->stream_enc, NULL, NULL, NULL, ivec);
EVP_EncryptUpdate(&key->stream_enc, buf, &dstLen, buf, size);
EVP_EncryptFinal_ex(&key->stream_enc, buf + dstLen, &tmpLen);
EVP_EncryptInit_ex(key->stream_enc, NULL, NULL, NULL, ivec);
EVP_EncryptUpdate(key->stream_enc, buf, &dstLen, buf, size);
EVP_EncryptFinal_ex(key->stream_enc, buf + dstLen, &tmpLen);

flipBytes(buf, size);
shuffleBytes(buf, size);

setIVec(ivec, iv64 + 1, key);
EVP_EncryptInit_ex(&key->stream_enc, NULL, NULL, NULL, ivec);
EVP_EncryptUpdate(&key->stream_enc, buf, &dstLen, buf, size);
EVP_EncryptFinal_ex(&key->stream_enc, buf + dstLen, &tmpLen);
EVP_EncryptInit_ex(key->stream_enc, NULL, NULL, NULL, ivec);
EVP_EncryptUpdate(key->stream_enc, buf, &dstLen, buf, size);
EVP_EncryptFinal_ex(key->stream_enc, buf + dstLen, &tmpLen);

dstLen += tmpLen;
if (dstLen != size) {
Expand All @@ -765,17 +770,17 @@ bool SSL_Cipher::streamDecode(unsigned char *buf, int size, uint64_t iv64,
int dstLen = 0, tmpLen = 0;

setIVec(ivec, iv64 + 1, key);
EVP_DecryptInit_ex(&key->stream_dec, NULL, NULL, NULL, ivec);
EVP_DecryptUpdate(&key->stream_dec, buf, &dstLen, buf, size);
EVP_DecryptFinal_ex(&key->stream_dec, buf + dstLen, &tmpLen);
EVP_DecryptInit_ex(key->stream_dec, NULL, NULL, NULL, ivec);
EVP_DecryptUpdate(key->stream_dec, buf, &dstLen, buf, size);
EVP_DecryptFinal_ex(key->stream_dec, buf + dstLen, &tmpLen);

unshuffleBytes(buf, size);
flipBytes(buf, size);

setIVec(ivec, iv64, key);
EVP_DecryptInit_ex(&key->stream_dec, NULL, NULL, NULL, ivec);
EVP_DecryptUpdate(&key->stream_dec, buf, &dstLen, buf, size);
EVP_DecryptFinal_ex(&key->stream_dec, buf + dstLen, &tmpLen);
EVP_DecryptInit_ex(key->stream_dec, NULL, NULL, NULL, ivec);
EVP_DecryptUpdate(key->stream_dec, buf, &dstLen, buf, size);
EVP_DecryptFinal_ex(key->stream_dec, buf + dstLen, &tmpLen);

unshuffleBytes(buf, size);

Expand All @@ -796,7 +801,7 @@ bool SSL_Cipher::blockEncode(unsigned char *buf, int size, uint64_t iv64,
rAssert(key->ivLength == _ivLength);

// data must be integer number of blocks
const int blockMod = size % EVP_CIPHER_CTX_block_size(&key->block_enc);
const int blockMod = size % EVP_CIPHER_CTX_block_size(key->block_enc);
if (blockMod != 0)
throw Error("Invalid data size, not multiple of block size");

Expand All @@ -807,9 +812,9 @@ bool SSL_Cipher::blockEncode(unsigned char *buf, int size, uint64_t iv64,
int dstLen = 0, tmpLen = 0;
setIVec(ivec, iv64, key);

EVP_EncryptInit_ex(&key->block_enc, NULL, NULL, NULL, ivec);
EVP_EncryptUpdate(&key->block_enc, buf, &dstLen, buf, size);
EVP_EncryptFinal_ex(&key->block_enc, buf + dstLen, &tmpLen);
EVP_EncryptInit_ex(key->block_enc, NULL, NULL, NULL, ivec);
EVP_EncryptUpdate(key->block_enc, buf, &dstLen, buf, size);
EVP_EncryptFinal_ex(key->block_enc, buf + dstLen, &tmpLen);
dstLen += tmpLen;

if (dstLen != size) {
Expand All @@ -828,7 +833,7 @@ bool SSL_Cipher::blockDecode(unsigned char *buf, int size, uint64_t iv64,
rAssert(key->ivLength == _ivLength);

// data must be integer number of blocks
const int blockMod = size % EVP_CIPHER_CTX_block_size(&key->block_dec);
const int blockMod = size % EVP_CIPHER_CTX_block_size(key->block_dec);
if (blockMod != 0)
throw Error("Invalid data size, not multiple of block size");

Expand All @@ -839,9 +844,9 @@ bool SSL_Cipher::blockDecode(unsigned char *buf, int size, uint64_t iv64,
int dstLen = 0, tmpLen = 0;
setIVec(ivec, iv64, key);

EVP_DecryptInit_ex(&key->block_dec, NULL, NULL, NULL, ivec);
EVP_DecryptUpdate(&key->block_dec, buf, &dstLen, buf, size);
EVP_DecryptFinal_ex(&key->block_dec, buf + dstLen, &tmpLen);
EVP_DecryptInit_ex(key->block_dec, NULL, NULL, NULL, ivec);
EVP_DecryptUpdate(key->block_dec, buf, &dstLen, buf, size);
EVP_DecryptFinal_ex(key->block_dec, buf + dstLen, &tmpLen);
dstLen += tmpLen;

if (dstLen != size) {
Expand Down
52 changes: 52 additions & 0 deletions encfs/SSL_Compat.h
@@ -0,0 +1,52 @@
/*****************************************************************************
* Author: Rogelio Dominguez Hernandez <rogelio.dominguez@gmail.com>
*
*****************************************************************************
* Copyright (c) 2016, Rogelio Dominguez Hernandez
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _SSL_Compat_incl_
#define _SSL_Compat_incl_

// OpenSSL < 1.1.0
#if OPENSSL_VERSION_NUMBER < 0x10100000L

// Equivalent methods
#define EVP_MD_CTX_new EVP_MD_CTX_create
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
#define HMAC_CTX_reset HMAC_CTX_cleanup

// Missing methods (based on 1.1.0 versions)
HMAC_CTX *HMAC_CTX_new(void)
{
HMAC_CTX *ctx = (HMAC_CTX *)OPENSSL_malloc(sizeof(HMAC_CTX));
if (ctx != NULL) {
memset(ctx, 0, sizeof(HMAC_CTX));
HMAC_CTX_reset(ctx);
}
return ctx;
}

void HMAC_CTX_free(HMAC_CTX *ctx)
{
if (ctx != NULL) {
HMAC_CTX_cleanup(ctx);
OPENSSL_free(ctx);
}
}
#endif

#endif

0 comments on commit 441fa20

Please sign in to comment.