Skip to content

Commit 2aab181

Browse files
committed
Add possibility to use libcrypto for encryption
1 parent ec4b275 commit 2aab181

File tree

8 files changed

+225
-20
lines changed

8 files changed

+225
-20
lines changed

include/libhashkit-1.0/hashkit.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct hashkit_st {
4949
bool is_allocated : 1;
5050
} options;
5151

52-
void *_key;
52+
void *_cryptographic_context;
5353
};
5454

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

7777
HASHKIT_API
78-
bool hashkit_key(hashkit_st *, const char *key, const size_t key_length);
78+
bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length);
7979

8080
#ifdef __cplusplus
8181
} // extern "C"

src/libhashkit/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ target_include_directories(libhashkit PUBLIC
3939
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
4040
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>
4141
$<INSTALL_INTERFACE:include>)
42+
43+
find_package(OpenSSL)
44+
if(NOT OPENSSL_FOUND)
45+
message(WARNING "crypto library not found")
46+
else()
47+
add_compile_definitions(WITH_OPENSSL)
48+
target_link_libraries(libhashkit PUBLIC OpenSSL::Crypto)
49+
endif()
50+
4251
configure_file(hashkitcon.h.in hashkitcon.h @ONLY)
4352

4453
install(TARGETS libhashkit EXPORT libhashkit-targets

src/libhashkit/aes.cc

Lines changed: 116 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,122 @@
1515

1616
#include "libhashkit/common.h"
1717

18-
#include "libhashkit/rijndael.hpp"
19-
2018
#include <cstring>
2119

22-
#define AES_KEY_LENGTH 256 /* 128, 192, 256 */
23-
#define AES_BLOCK_SIZE 16
20+
#ifdef WITH_OPENSSL
21+
22+
#include <openssl/evp.h>
23+
24+
#define DIGEST_ROUNDS 5
25+
26+
#define AES_KEY_NBYTES 32
27+
#define AES_IV_NBYTES 32
28+
29+
bool aes_initialize(const unsigned char *key, const size_t key_length,
30+
encryption_context_t *crypto_context) {
31+
unsigned char aes_key[AES_KEY_NBYTES];
32+
unsigned char aes_iv[AES_IV_NBYTES];
33+
if (aes_key == NULL || aes_iv == NULL) {
34+
return false;
35+
}
36+
37+
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), NULL, key, key_length, DIGEST_ROUNDS,
38+
aes_key, aes_iv);
39+
if (i != AES_KEY_NBYTES) {
40+
return false;
41+
}
42+
43+
EVP_CIPHER_CTX_init(crypto_context->encryption_context);
44+
EVP_CIPHER_CTX_init(crypto_context->decryption_context);
45+
if (EVP_EncryptInit_ex(crypto_context->encryption_context, EVP_aes_256_cbc(), NULL, key, aes_iv)
46+
!= 1
47+
|| EVP_DecryptInit_ex(crypto_context->decryption_context, EVP_aes_256_cbc(), NULL, key,
48+
aes_iv)
49+
!= 1)
50+
{
51+
return false;
52+
}
53+
return true;
54+
}
55+
56+
hashkit_string_st *aes_encrypt(encryption_context_t *crypto_context, const unsigned char *source,
57+
size_t source_length) {
58+
EVP_CIPHER_CTX *encryption_context = crypto_context->encryption_context;
59+
int cipher_length = source_length + EVP_CIPHER_CTX_block_size(encryption_context);
60+
int final_length = 0;
61+
unsigned char *cipher_text = (unsigned char *) malloc(cipher_length);
62+
if (cipher_text == NULL) {
63+
return NULL;
64+
}
65+
if (EVP_EncryptInit_ex(encryption_context, NULL, NULL, NULL, NULL) != 1
66+
|| EVP_EncryptUpdate(encryption_context, cipher_text, &cipher_length, source, source_length)
67+
!= 1
68+
|| EVP_EncryptFinal_ex(encryption_context, cipher_text + cipher_length, &final_length) != 1)
69+
{
70+
free(cipher_text);
71+
return NULL;
72+
}
73+
74+
hashkit_string_st *destination = hashkit_string_create(cipher_length + final_length);
75+
if (destination == NULL) {
76+
return NULL;
77+
}
78+
char *dest = hashkit_string_c_str_mutable(destination);
79+
memcpy(dest, cipher_text, cipher_length + final_length);
80+
hashkit_string_set_length(destination, cipher_length + final_length);
81+
return destination;
82+
}
83+
84+
hashkit_string_st *aes_decrypt(encryption_context_t *crypto_context, const unsigned char *source,
85+
size_t source_length) {
86+
EVP_CIPHER_CTX *decryption_context = crypto_context->decryption_context;
87+
int plain_text_length = source_length;
88+
int final_length = 0;
89+
unsigned char *plain_text = (unsigned char *) malloc(plain_text_length);
90+
if (plain_text == NULL) {
91+
return NULL;
92+
}
93+
if (EVP_DecryptInit_ex(decryption_context, NULL, NULL, NULL, NULL) != 1
94+
|| EVP_DecryptUpdate(decryption_context, plain_text, &plain_text_length, source, source_length)
95+
!= 1
96+
|| EVP_DecryptFinal_ex(decryption_context, plain_text + plain_text_length, &final_length) != 1)
97+
{
98+
free(plain_text);
99+
return NULL;
100+
}
101+
102+
hashkit_string_st *destination = hashkit_string_create(plain_text_length + final_length);
103+
if (destination == NULL) {
104+
return NULL;
105+
}
106+
char *dest = hashkit_string_c_str_mutable(destination);
107+
memcpy(dest, plain_text, plain_text_length + final_length);
108+
hashkit_string_set_length(destination, plain_text_length + final_length);
109+
return destination;
110+
}
111+
112+
encryption_context_t *aes_clone_cryptographic_context(encryption_context_t *source) {
113+
encryption_context_t *new_context = (encryption_context_t *) malloc(sizeof(encryption_context_t));
114+
if (new_context == NULL)
115+
return NULL;
116+
117+
new_context->encryption_context = EVP_CIPHER_CTX_new();
118+
new_context->decryption_context = EVP_CIPHER_CTX_new();
119+
if (new_context->encryption_context == NULL || new_context->decryption_context == NULL) {
120+
free(new_context);
121+
return NULL;
122+
}
123+
EVP_CIPHER_CTX_copy(new_context->encryption_context, source->encryption_context);
124+
EVP_CIPHER_CTX_copy(new_context->decryption_context, source->decryption_context);
125+
return new_context;
126+
}
127+
128+
#else
129+
130+
# include "libhashkit/rijndael.hpp"
131+
132+
# define AES_KEY_LENGTH 256 /* 128, 192, 256 */
133+
# define AES_BLOCK_SIZE 16
24134

25135
enum encrypt_t { AES_ENCRYPT, AES_DECRYPT };
26136

@@ -49,7 +159,7 @@ aes_key_t *aes_create_key(const char *key, const size_t key_length) {
49159
if (ptr == rkey_end) {
50160
ptr = rkey; /* Just loop over tmp_key until we used all key */
51161
}
52-
*ptr ^= (uint8_t)(*sptr);
162+
*ptr ^= (uint8_t) (*sptr);
53163
}
54164

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

141251
return destination;
142252
}
253+
#endif

src/libhashkit/aes.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,27 @@
1515

1616
#pragma once
1717

18+
#ifdef WITH_OPENSSL
19+
20+
#include <openssl/evp.h>
21+
22+
typedef struct encryption_context {
23+
EVP_CIPHER_CTX *encryption_context;
24+
EVP_CIPHER_CTX *decryption_context;
25+
} encryption_context_t;
26+
27+
hashkit_string_st *aes_encrypt(encryption_context_t *crypto_context, const unsigned char *source,
28+
size_t source_length);
29+
30+
hashkit_string_st *aes_decrypt(encryption_context_t *crypto_context, const unsigned char *source,
31+
size_t source_length);
32+
33+
bool aes_initialize(const unsigned char *key, const size_t key_length,
34+
encryption_context_t *crypto_context);
35+
36+
encryption_context_t *aes_clone_cryptographic_context(encryption_context_t *source);
37+
#else
38+
1839
struct aes_key_t;
1940

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

2647
aes_key_t *aes_clone_key(aes_key_t *_aes_key);
48+
#endif

src/libhashkit/encrypt.cc

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,50 @@
1515

1616
#include "libhashkit/common.h"
1717

18+
#ifdef WITH_OPENSSL
19+
# include <openssl/evp.h>
20+
#endif
21+
1822
hashkit_string_st *hashkit_encrypt(hashkit_st *kit, const char *source, size_t source_length) {
19-
return aes_encrypt(static_cast<aes_key_t *>(kit->_key), source, source_length);
23+
#ifdef WITH_OPENSSL
24+
return aes_encrypt((encryption_context_t *) kit->_cryptographic_context,
25+
(const unsigned char *) source, source_length);
26+
#else
27+
return aes_encrypt((aes_key_t *) kit->_cryptographic_context, source,
28+
source_length);
29+
#endif
2030
}
2131

2232
hashkit_string_st *hashkit_decrypt(hashkit_st *kit, const char *source, size_t source_length) {
23-
return aes_decrypt(static_cast<aes_key_t *>(kit->_key), source, source_length);
33+
#ifdef WITH_OPENSSL
34+
return aes_decrypt((encryption_context_t *) kit->_cryptographic_context,
35+
(const unsigned char *) source, source_length);
36+
#else
37+
return aes_decrypt((aes_key_t *)kit->_cryptographic_context, source, source_length);
38+
#endif
2439
}
2540

41+
#ifdef WITH_OPENSSL
42+
bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) {
43+
kit->_cryptographic_context = (encryption_context_t *) malloc(sizeof(encryption_context_t));
44+
((encryption_context_t *) kit->_cryptographic_context)->encryption_context = EVP_CIPHER_CTX_new();
45+
((encryption_context_t *) kit->_cryptographic_context)->decryption_context = EVP_CIPHER_CTX_new();
46+
if (((encryption_context_t *) kit->_cryptographic_context)->encryption_context == NULL
47+
|| ((encryption_context_t *) kit->_cryptographic_context)->decryption_context == NULL)
48+
{
49+
return false;
50+
}
51+
return aes_initialize((const unsigned char *) key, key_length,
52+
(encryption_context_t *) kit->_cryptographic_context);
53+
}
54+
#else
2655
bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) {
27-
if (kit->_key) {
28-
free(kit->_key);
56+
if (kit->_cryptographic_context) {
57+
free(kit->_cryptographic_context);
2958
}
3059

31-
kit->_key = aes_create_key(key, key_length);
60+
kit->_cryptographic_context = aes_create_key(key, key_length);
3261

33-
return bool(kit->_key);
62+
return bool(kit->_cryptographic_context);
3463
}
64+
#endif

src/libhashkit/hashkit.cc

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515

1616
#include "libhashkit/common.h"
1717

18+
#ifdef WITH_OPENSSL
19+
# include <openssl/evp.h>
20+
#endif
21+
1822
static inline void _hashkit_init(hashkit_st *self) {
1923
self->base_hash.function = hashkit_one_at_a_time;
2024
self->base_hash.context = NULL;
@@ -23,7 +27,7 @@ static inline void _hashkit_init(hashkit_st *self) {
2327
self->distribution_hash.context = NULL;
2428

2529
self->flags.is_base_same_distributed = true;
26-
self->_key = NULL;
30+
self->_cryptographic_context = NULL;
2731
}
2832

2933
static inline hashkit_st *_hashkit_create(hashkit_st *self) {
@@ -52,11 +56,26 @@ hashkit_st *hashkit_create(hashkit_st *self) {
5256
return self;
5357
}
5458

59+
#ifdef WITH_OPENSSL
60+
static void cryptographic_context_free(encryption_context_t *context) {
61+
EVP_CIPHER_CTX_free(context->encryption_context);
62+
EVP_CIPHER_CTX_free(context->decryption_context);
63+
free(context);
64+
}
65+
#endif
66+
5567
void hashkit_free(hashkit_st *self) {
56-
if (self and self->_key) {
57-
free(self->_key);
58-
self->_key = NULL;
68+
#ifdef WITH_OPENSSL
69+
if (self and self->_cryptographic_context) {
70+
cryptographic_context_free((encryption_context_t *)self->_cryptographic_context);
71+
self->_cryptographic_context = NULL;
72+
}
73+
#else
74+
if (self and self->_cryptographic_context) {
75+
free(self->_cryptographic_context);
76+
self->_cryptographic_context = NULL;
5977
}
78+
#endif
6079

6180
if (hashkit_is_allocated(self)) {
6281
free(self);
@@ -79,7 +98,21 @@ hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *source) {
7998
destination->base_hash = source->base_hash;
8099
destination->distribution_hash = source->distribution_hash;
81100
destination->flags = source->flags;
82-
destination->_key = aes_clone_key(static_cast<aes_key_t *>(source->_key));
101+
#ifdef WITH_OPENSSL
102+
if (destination->_cryptographic_context) {
103+
cryptographic_context_free((encryption_context_t *)destination->_cryptographic_context);
104+
destination->_cryptographic_context = NULL;
105+
}
106+
if (source->_cryptographic_context) {
107+
destination->_cryptographic_context =
108+
aes_clone_cryptographic_context(((encryption_context_t *) source->_cryptographic_context));
109+
if (destination->_cryptographic_context) {
110+
111+
}
112+
}
113+
#else
114+
destination->_cryptographic_context = aes_clone_key(static_cast<aes_key_t *>(source->_cryptographic_context));
115+
#endif
83116

84117
return destination;
85118
}

src/libhashkit/rijndael.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 p
3535
#ifdef INTERMEDIATE_VALUE_KAT
3636
void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds);
3737
void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds);
38-
#endif /* INTERMEDIATE_VALUE_KAT */
38+
#endif /* INTERMEDIATE_VALUE_KAT */

src/libmemcached/is.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
/* These are private */
1919
#define memcached_is_allocated(__object) ((__object)->options.is_allocated)
20-
#define memcached_is_encrypted(__object) ((__object)->hashkit._key)
20+
#define memcached_is_encrypted(__object) (!!(__object)->hashkit._cryptographic_context)
2121
#define memcached_is_initialized(__object) ((__object)->options.is_initialized)
2222
#define memcached_is_purging(__object) ((__object)->state.is_purging)
2323
#define memcached_is_processing_input(__object) ((__object)->state.is_processing_input)

0 commit comments

Comments
 (0)