Skip to content
Merged
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
4 changes: 2 additions & 2 deletions include/libhashkit-1.0/hashkit.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ struct hashkit_st {
bool is_allocated : 1;
} options;

void *_key;
void *_cryptographic_context;
};
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks the ABI, so either allocate a private struct and reuse _key, or this may only be targeted at v2.0


#ifdef __cplusplus
Expand All @@ -75,7 +75,7 @@ HASHKIT_API
hashkit_string_st *hashkit_decrypt(hashkit_st *, const char *source, size_t source_length);

HASHKIT_API
bool hashkit_key(hashkit_st *, const char *key, const size_t key_length);
bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length);

#ifdef __cplusplus
} // extern "C"
Expand Down
9 changes: 9 additions & 0 deletions src/libhashkit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ target_include_directories(libhashkit PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>)

find_package(OpenSSL)
if(NOT OPENSSL_FOUND)
message(WARNING "crypto library not found")
else()
add_compile_definitions(WITH_OPENSSL)
target_link_libraries(libhashkit PUBLIC OpenSSL::Crypto)
endif()

configure_file(hashkitcon.h.in hashkitcon.h @ONLY)

install(TARGETS libhashkit EXPORT libhashkit-targets
Expand Down
121 changes: 116 additions & 5 deletions src/libhashkit/aes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,122 @@

#include "libhashkit/common.h"

#include "libhashkit/rijndael.hpp"

#include <cstring>

#define AES_KEY_LENGTH 256 /* 128, 192, 256 */
#define AES_BLOCK_SIZE 16
#ifdef WITH_OPENSSL

#include <openssl/evp.h>

#define DIGEST_ROUNDS 5

#define AES_KEY_NBYTES 32
#define AES_IV_NBYTES 32

bool aes_initialize(const unsigned char *key, const size_t key_length,
encryption_context_t *crypto_context) {
unsigned char aes_key[AES_KEY_NBYTES];
unsigned char aes_iv[AES_IV_NBYTES];
if (aes_key == NULL || aes_iv == NULL) {
return false;
}

int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), NULL, key, key_length, DIGEST_ROUNDS,
aes_key, aes_iv);
if (i != AES_KEY_NBYTES) {
return false;
}

EVP_CIPHER_CTX_init(crypto_context->encryption_context);
EVP_CIPHER_CTX_init(crypto_context->decryption_context);
if (EVP_EncryptInit_ex(crypto_context->encryption_context, EVP_aes_256_cbc(), NULL, key, aes_iv)
!= 1
|| EVP_DecryptInit_ex(crypto_context->decryption_context, EVP_aes_256_cbc(), NULL, key,
aes_iv)
!= 1)
{
return false;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment from Remi: #114 (comment)

}
return true;
}

hashkit_string_st *aes_encrypt(encryption_context_t *crypto_context, const unsigned char *source,
size_t source_length) {
EVP_CIPHER_CTX *encryption_context = crypto_context->encryption_context;
int cipher_length = source_length + EVP_CIPHER_CTX_block_size(encryption_context);
int final_length = 0;
unsigned char *cipher_text = (unsigned char *) malloc(cipher_length);
if (cipher_text == NULL) {
return NULL;
}
if (EVP_EncryptInit_ex(encryption_context, NULL, NULL, NULL, NULL) != 1
|| EVP_EncryptUpdate(encryption_context, cipher_text, &cipher_length, source, source_length)
!= 1
|| EVP_EncryptFinal_ex(encryption_context, cipher_text + cipher_length, &final_length) != 1)
{
free(cipher_text);
return NULL;
}

hashkit_string_st *destination = hashkit_string_create(cipher_length + final_length);
if (destination == NULL) {
return NULL;
}
char *dest = hashkit_string_c_str_mutable(destination);
memcpy(dest, cipher_text, cipher_length + final_length);
hashkit_string_set_length(destination, cipher_length + final_length);
return destination;
}

hashkit_string_st *aes_decrypt(encryption_context_t *crypto_context, const unsigned char *source,
size_t source_length) {
EVP_CIPHER_CTX *decryption_context = crypto_context->decryption_context;
int plain_text_length = source_length;
int final_length = 0;
unsigned char *plain_text = (unsigned char *) malloc(plain_text_length);
if (plain_text == NULL) {
return NULL;
}
if (EVP_DecryptInit_ex(decryption_context, NULL, NULL, NULL, NULL) != 1
|| EVP_DecryptUpdate(decryption_context, plain_text, &plain_text_length, source, source_length)
!= 1
|| EVP_DecryptFinal_ex(decryption_context, plain_text + plain_text_length, &final_length) != 1)
{
free(plain_text);
return NULL;
}

hashkit_string_st *destination = hashkit_string_create(plain_text_length + final_length);
if (destination == NULL) {
return NULL;
}
char *dest = hashkit_string_c_str_mutable(destination);
memcpy(dest, plain_text, plain_text_length + final_length);
hashkit_string_set_length(destination, plain_text_length + final_length);
return destination;
}

encryption_context_t *aes_clone_cryptographic_context(encryption_context_t *source) {
encryption_context_t *new_context = (encryption_context_t *) malloc(sizeof(encryption_context_t));
if (new_context == NULL)
return NULL;

new_context->encryption_context = EVP_CIPHER_CTX_new();
new_context->decryption_context = EVP_CIPHER_CTX_new();
if (new_context->encryption_context == NULL || new_context->decryption_context == NULL) {
free(new_context);
return NULL;
}
EVP_CIPHER_CTX_copy(new_context->encryption_context, source->encryption_context);
EVP_CIPHER_CTX_copy(new_context->decryption_context, source->decryption_context);
return new_context;
}

#else

# include "libhashkit/rijndael.hpp"

# define AES_KEY_LENGTH 256 /* 128, 192, 256 */
# define AES_BLOCK_SIZE 16

enum encrypt_t { AES_ENCRYPT, AES_DECRYPT };

Expand Down Expand Up @@ -49,7 +159,7 @@ aes_key_t *aes_create_key(const char *key, const size_t key_length) {
if (ptr == rkey_end) {
ptr = rkey; /* Just loop over tmp_key until we used all key */
}
*ptr ^= (uint8_t)(*sptr);
*ptr ^= (uint8_t) (*sptr);
}

_aes_key->decode_key.nr = rijndaelKeySetupDec(_aes_key->decode_key.rk, rkey, AES_KEY_LENGTH);
Expand Down Expand Up @@ -140,3 +250,4 @@ hashkit_string_st *aes_decrypt(aes_key_t *_aes_key, const char *source, size_t s

return destination;
}
#endif
22 changes: 22 additions & 0 deletions src/libhashkit/aes.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@

#pragma once

#ifdef WITH_OPENSSL

#include <openssl/evp.h>

typedef struct encryption_context {
EVP_CIPHER_CTX *encryption_context;
EVP_CIPHER_CTX *decryption_context;
} encryption_context_t;

hashkit_string_st *aes_encrypt(encryption_context_t *crypto_context, const unsigned char *source,
size_t source_length);

hashkit_string_st *aes_decrypt(encryption_context_t *crypto_context, const unsigned char *source,
size_t source_length);

bool aes_initialize(const unsigned char *key, const size_t key_length,
encryption_context_t *crypto_context);

encryption_context_t *aes_clone_cryptographic_context(encryption_context_t *source);
#else

struct aes_key_t;

hashkit_string_st *aes_encrypt(aes_key_t *_aes_key, const char *source, size_t source_length);
Expand All @@ -24,3 +45,4 @@ hashkit_string_st *aes_decrypt(aes_key_t *_aes_key, const char *source, size_t s
aes_key_t *aes_create_key(const char *key, const size_t key_length);

aes_key_t *aes_clone_key(aes_key_t *_aes_key);
#endif
42 changes: 36 additions & 6 deletions src/libhashkit/encrypt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,50 @@

#include "libhashkit/common.h"

#ifdef WITH_OPENSSL
# include <openssl/evp.h>
#endif

hashkit_string_st *hashkit_encrypt(hashkit_st *kit, const char *source, size_t source_length) {
return aes_encrypt(static_cast<aes_key_t *>(kit->_key), source, source_length);
#ifdef WITH_OPENSSL
return aes_encrypt((encryption_context_t *) kit->_cryptographic_context,
(const unsigned char *) source, source_length);
#else
return aes_encrypt((aes_key_t *) kit->_cryptographic_context, source,
source_length);
#endif
}

hashkit_string_st *hashkit_decrypt(hashkit_st *kit, const char *source, size_t source_length) {
return aes_decrypt(static_cast<aes_key_t *>(kit->_key), source, source_length);
#ifdef WITH_OPENSSL
return aes_decrypt((encryption_context_t *) kit->_cryptographic_context,
(const unsigned char *) source, source_length);
#else
return aes_decrypt((aes_key_t *)kit->_cryptographic_context, source, source_length);
#endif
}

#ifdef WITH_OPENSSL
bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) {
kit->_cryptographic_context = (encryption_context_t *) malloc(sizeof(encryption_context_t));
((encryption_context_t *) kit->_cryptographic_context)->encryption_context = EVP_CIPHER_CTX_new();
((encryption_context_t *) kit->_cryptographic_context)->decryption_context = EVP_CIPHER_CTX_new();
if (((encryption_context_t *) kit->_cryptographic_context)->encryption_context == NULL
|| ((encryption_context_t *) kit->_cryptographic_context)->decryption_context == NULL)
{
return false;
}
return aes_initialize((const unsigned char *) key, key_length,
(encryption_context_t *) kit->_cryptographic_context);
}
#else
bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) {
if (kit->_key) {
free(kit->_key);
if (kit->_cryptographic_context) {
free(kit->_cryptographic_context);
}

kit->_key = aes_create_key(key, key_length);
kit->_cryptographic_context = aes_create_key(key, key_length);

return bool(kit->_key);
return bool(kit->_cryptographic_context);
}
#endif
43 changes: 38 additions & 5 deletions src/libhashkit/hashkit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@

#include "libhashkit/common.h"

#ifdef WITH_OPENSSL
# include <openssl/evp.h>
#endif

static inline void _hashkit_init(hashkit_st *self) {
self->base_hash.function = hashkit_one_at_a_time;
self->base_hash.context = NULL;
Expand All @@ -23,7 +27,7 @@ static inline void _hashkit_init(hashkit_st *self) {
self->distribution_hash.context = NULL;

self->flags.is_base_same_distributed = true;
self->_key = NULL;
self->_cryptographic_context = NULL;
}

static inline hashkit_st *_hashkit_create(hashkit_st *self) {
Expand Down Expand Up @@ -52,11 +56,26 @@ hashkit_st *hashkit_create(hashkit_st *self) {
return self;
}

#ifdef WITH_OPENSSL
static void cryptographic_context_free(encryption_context_t *context) {
EVP_CIPHER_CTX_free(context->encryption_context);
EVP_CIPHER_CTX_free(context->decryption_context);
free(context);
}
#endif

void hashkit_free(hashkit_st *self) {
if (self and self->_key) {
free(self->_key);
self->_key = NULL;
#ifdef WITH_OPENSSL
if (self and self->_cryptographic_context) {
cryptographic_context_free((encryption_context_t *)self->_cryptographic_context);
self->_cryptographic_context = NULL;
}
#else
if (self and self->_cryptographic_context) {
free(self->_cryptographic_context);
self->_cryptographic_context = NULL;
}
#endif

if (hashkit_is_allocated(self)) {
free(self);
Expand All @@ -79,7 +98,21 @@ hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *source) {
destination->base_hash = source->base_hash;
destination->distribution_hash = source->distribution_hash;
destination->flags = source->flags;
destination->_key = aes_clone_key(static_cast<aes_key_t *>(source->_key));
#ifdef WITH_OPENSSL
if (destination->_cryptographic_context) {
cryptographic_context_free((encryption_context_t *)destination->_cryptographic_context);
destination->_cryptographic_context = NULL;
}
if (source->_cryptographic_context) {
destination->_cryptographic_context =
aes_clone_cryptographic_context(((encryption_context_t *) source->_cryptographic_context));
if (destination->_cryptographic_context) {

}
}
#else
destination->_cryptographic_context = aes_clone_key(static_cast<aes_key_t *>(source->_cryptographic_context));
#endif

return destination;
}
Expand Down
2 changes: 1 addition & 1 deletion src/libhashkit/rijndael.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 p
#ifdef INTERMEDIATE_VALUE_KAT
void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds);
void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds);
#endif /* INTERMEDIATE_VALUE_KAT */
#endif /* INTERMEDIATE_VALUE_KAT */
2 changes: 1 addition & 1 deletion src/libmemcached/is.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

/* These are private */
#define memcached_is_allocated(__object) ((__object)->options.is_allocated)
#define memcached_is_encrypted(__object) ((__object)->hashkit._key)
#define memcached_is_encrypted(__object) (!!(__object)->hashkit._cryptographic_context)
#define memcached_is_initialized(__object) ((__object)->options.is_initialized)
#define memcached_is_purging(__object) ((__object)->state.is_purging)
#define memcached_is_processing_input(__object) ((__object)->state.is_processing_input)
Expand Down