Skip to content

Commit ed20c3e

Browse files
committed
Remove internal AES implementation and replace it with use of libcrypto
1 parent ec4b275 commit ed20c3e

File tree

12 files changed

+128
-1099
lines changed

12 files changed

+128
-1099
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ if(BUILD_DOCS OR BUILD_DOCSONLY)
2424
add_subdirectory(docs)
2525
endif()
2626

27+
find_library(CRYPTO_LIB crypto)
28+
if(NOT CRYPTO_LIB)
29+
message(FATAL_ERROR "crypto library not found")
30+
endif()
31+
2732
if(NOT BUILD_DOCSONLY)
2833
include(CMake/_Include.cmake)
2934

include/libhashkit-1.0/hashkit.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#include <libhashkit-1.0/strerror.h>
3636
#include <libhashkit-1.0/string.h>
3737

38+
#include <openssl/evp.h>
39+
3840
struct hashkit_st {
3941
struct hashkit_function_st {
4042
hashkit_hash_fn function;
@@ -49,7 +51,9 @@ struct hashkit_st {
4951
bool is_allocated : 1;
5052
} options;
5153

52-
void *_key;
54+
bool use_encryption;
55+
EVP_CIPHER_CTX *encryption_context;
56+
EVP_CIPHER_CTX *decryption_context;
5357
};
5458

5559
#ifdef __cplusplus
@@ -75,7 +79,7 @@ HASHKIT_API
7579
hashkit_string_st *hashkit_decrypt(hashkit_st *, const char *source, size_t source_length);
7680

7781
HASHKIT_API
78-
bool hashkit_key(hashkit_st *, const char *key, const size_t key_length);
82+
bool hashkit_initialize_encryption(hashkit_st *kit, const char *key, const size_t key_length);
7983

8084
#ifdef __cplusplus
8185
} // extern "C"

src/libhashkit/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ set(libhashkit_sources
1717
murmur3.cc
1818
murmur3_api.cc
1919
one_at_a_time.cc
20-
rijndael.cc
2120
str_algorithm.cc
2221
strerror.cc
2322
string.cc
@@ -39,6 +38,8 @@ target_include_directories(libhashkit PUBLIC
3938
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
4039
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>
4140
$<INSTALL_INTERFACE:include>)
41+
target_link_libraries(libhashkit PUBLIC -lcrypto)
42+
4243
configure_file(hashkitcon.h.in hashkitcon.h @ONLY)
4344

4445
install(TARGETS libhashkit EXPORT libhashkit-targets

src/libhashkit/aes.cc

Lines changed: 66 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -15,128 +15,95 @@
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
24-
25-
enum encrypt_t { AES_ENCRYPT, AES_DECRYPT };
26-
27-
struct _key_t {
28-
int nr;
29-
uint32_t rk[4 * (AES_MAXNR + 1)];
30-
};
31-
32-
struct aes_key_t {
33-
_key_t encode_key;
34-
_key_t decode_key;
35-
};
20+
#define DIGEST_ROUNDS 5
3621

37-
aes_key_t *aes_create_key(const char *key, const size_t key_length) {
38-
aes_key_t *_aes_key = (aes_key_t *) (calloc(1, sizeof(aes_key_t)));
39-
if (_aes_key) {
40-
uint8_t rkey[AES_KEY_LENGTH / 8];
41-
uint8_t *rkey_end = rkey + AES_KEY_LENGTH / 8;
42-
const char *key_end = key + key_length;
22+
#define AES_KEY_NBYTES 32
23+
#define AES_IV_NBYTES 32
4324

44-
memset(rkey, 0, sizeof(rkey)); /* Set initial key */
45-
46-
uint8_t *ptr = rkey;
47-
const char *sptr = key;
48-
for (; sptr < key_end; ptr++, sptr++) {
49-
if (ptr == rkey_end) {
50-
ptr = rkey; /* Just loop over tmp_key until we used all key */
51-
}
52-
*ptr ^= (uint8_t)(*sptr);
53-
}
54-
55-
_aes_key->decode_key.nr = rijndaelKeySetupDec(_aes_key->decode_key.rk, rkey, AES_KEY_LENGTH);
56-
_aes_key->encode_key.nr = rijndaelKeySetupEnc(_aes_key->encode_key.rk, rkey, AES_KEY_LENGTH);
25+
bool aes_initialize(const unsigned char *key, const size_t key_length,
26+
EVP_CIPHER_CTX *encryption_context,
27+
EVP_CIPHER_CTX *decryption_context) {
28+
unsigned char aes_key[AES_KEY_NBYTES];
29+
unsigned char aes_iv[AES_IV_NBYTES];
30+
if (aes_key == NULL || aes_iv == NULL) {
31+
return false;
5732
}
5833

59-
return _aes_key;
60-
}
61-
62-
aes_key_t *aes_clone_key(aes_key_t *_aes_key) {
63-
if (_aes_key == NULL) {
64-
return NULL;
34+
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), NULL, key, key_length,
35+
DIGEST_ROUNDS, aes_key, aes_iv);
36+
if (i != AES_KEY_NBYTES) {
37+
return false;
6538
}
6639

67-
aes_key_t *_aes_clone_key = (aes_key_t *) (calloc(1, sizeof(aes_key_t)));
68-
if (_aes_clone_key) {
69-
memcpy(_aes_clone_key, _aes_key, sizeof(aes_key_t));
40+
if (EVP_CIPHER_CTX_init(encryption_context) != 1 ||
41+
EVP_EncryptInit_ex(encryption_context, EVP_aes_256_cbc(), NULL, key,
42+
aes_iv) != 1 ||
43+
EVP_CIPHER_CTX_init(decryption_context) != 1 ||
44+
EVP_DecryptInit_ex(decryption_context, EVP_aes_256_cbc(), NULL, key,
45+
aes_iv) != 1) {
46+
return false;
7047
}
71-
72-
return _aes_clone_key;
48+
return true;
7349
}
7450

75-
hashkit_string_st *aes_encrypt(aes_key_t *_aes_key, const char *source, size_t source_length) {
76-
if (_aes_key == NULL) {
51+
hashkit_string_st *aes_encrypt(EVP_CIPHER_CTX *encryption_context,
52+
const unsigned char *source,
53+
size_t source_length) {
54+
int cipher_length =
55+
source_length + EVP_CIPHER_CTX_block_size(encryption_context);
56+
int final_length = 0;
57+
unsigned char *cipher_text = (unsigned char *)malloc(cipher_length);
58+
if (cipher_text == NULL) {
7759
return NULL;
7860
}
79-
80-
size_t num_blocks = source_length / AES_BLOCK_SIZE;
81-
82-
hashkit_string_st *destination = hashkit_string_create(source_length);
83-
if (destination) {
84-
char *dest = hashkit_string_c_str_mutable(destination);
85-
86-
for (size_t x = num_blocks; x > 0; x--) /* Encode complete blocks */ {
87-
rijndaelEncrypt(_aes_key->encode_key.rk, _aes_key->encode_key.nr, (const uint8_t *) (source),
88-
(uint8_t *) (dest));
89-
source += AES_BLOCK_SIZE;
90-
dest += AES_BLOCK_SIZE;
91-
}
92-
93-
uint8_t block[AES_BLOCK_SIZE];
94-
char pad_len = AES_BLOCK_SIZE - (source_length - AES_BLOCK_SIZE * num_blocks);
95-
memcpy(block, source, 16 - pad_len);
96-
memset(block + AES_BLOCK_SIZE - pad_len, pad_len, pad_len);
97-
rijndaelEncrypt(_aes_key->encode_key.rk, _aes_key->encode_key.nr, block, (uint8_t *) (dest));
98-
hashkit_string_set_length(destination, AES_BLOCK_SIZE * (num_blocks + 1));
61+
if (EVP_EncryptInit_ex(encryption_context, NULL, NULL, NULL, NULL) != 1 ||
62+
EVP_EncryptUpdate(encryption_context, cipher_text, &cipher_length, source,
63+
source_length) != 1 ||
64+
EVP_EncryptFinal_ex(encryption_context, cipher_text + cipher_length,
65+
&final_length) != 1) {
66+
free(cipher_text);
67+
return NULL;
9968
}
10069

70+
hashkit_string_st *destination =
71+
hashkit_string_create(cipher_length + final_length);
72+
if (destination == NULL) {
73+
return NULL;
74+
}
75+
char *dest = hashkit_string_c_str_mutable(destination);
76+
memcpy(dest, cipher_text, cipher_length + final_length);
77+
hashkit_string_set_length(destination, cipher_length + final_length);
10178
return destination;
10279
}
10380

104-
hashkit_string_st *aes_decrypt(aes_key_t *_aes_key, const char *source, size_t source_length) {
105-
if (_aes_key == NULL) {
81+
hashkit_string_st *aes_decrypt(EVP_CIPHER_CTX *decryption_context,
82+
const unsigned char *source,
83+
size_t source_length) {
84+
int plain_text_length = source_length;
85+
int final_length = 0;
86+
unsigned char *plain_text = (unsigned char *)malloc(plain_text_length);
87+
if (plain_text == NULL) {
10688
return NULL;
10789
}
108-
109-
size_t num_blocks = source_length / AES_BLOCK_SIZE;
110-
if ((source_length != num_blocks * AES_BLOCK_SIZE) or num_blocks == 0) {
90+
if (EVP_DecryptInit_ex(decryption_context, NULL, NULL, NULL, NULL) != 1 ||
91+
EVP_DecryptUpdate(decryption_context, plain_text, &plain_text_length,
92+
source, source_length) != 1 ||
93+
EVP_DecryptFinal_ex(decryption_context, plain_text + plain_text_length,
94+
&final_length) != 1) {
95+
free(plain_text);
11196
return NULL;
11297
}
11398

114-
hashkit_string_st *destination = hashkit_string_create(source_length);
115-
if (destination) {
116-
char *dest = hashkit_string_c_str_mutable(destination);
117-
118-
for (size_t x = num_blocks - 1; x > 0; x--) {
119-
rijndaelDecrypt(_aes_key->decode_key.rk, _aes_key->decode_key.nr, (const uint8_t *) (source),
120-
(uint8_t *) (dest));
121-
source += AES_BLOCK_SIZE;
122-
dest += AES_BLOCK_SIZE;
123-
}
124-
125-
uint8_t block[AES_BLOCK_SIZE];
126-
rijndaelDecrypt(_aes_key->decode_key.rk, _aes_key->decode_key.nr, (const uint8_t *) (source),
127-
block);
128-
/* Use last char in the block as size */
129-
unsigned int pad_len = (unsigned int) (unsigned char) (block[AES_BLOCK_SIZE - 1]);
130-
if (pad_len > AES_BLOCK_SIZE) {
131-
hashkit_string_free(destination);
132-
return NULL;
133-
}
134-
135-
/* We could also check whole padding but we do not really need this */
136-
137-
memcpy(dest, block, AES_BLOCK_SIZE - pad_len);
138-
hashkit_string_set_length(destination, AES_BLOCK_SIZE * num_blocks - pad_len);
99+
hashkit_string_st *destination =
100+
hashkit_string_create(plain_text_length + final_length);
101+
if (destination == NULL) {
102+
return NULL;
139103
}
140-
104+
char *dest = hashkit_string_c_str_mutable(destination);
105+
memcpy(dest, plain_text, plain_text_length + final_length);
106+
hashkit_string_set_length(destination, plain_text_length + final_length);
141107
return destination;
142108
}
109+

src/libhashkit/aes.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515

1616
#pragma once
1717

18-
struct aes_key_t;
18+
hashkit_string_st *aes_encrypt(EVP_CIPHER_CTX *encryption_context,
19+
const unsigned char *source,
20+
size_t source_length);
1921

20-
hashkit_string_st *aes_encrypt(aes_key_t *_aes_key, const char *source, size_t source_length);
22+
hashkit_string_st *aes_decrypt(EVP_CIPHER_CTX *decryption_context,
23+
const unsigned char *source,
24+
size_t source_length);
2125

22-
hashkit_string_st *aes_decrypt(aes_key_t *_aes_key, const char *source, size_t source_length);
23-
24-
aes_key_t *aes_create_key(const char *key, const size_t key_length);
25-
26-
aes_key_t *aes_clone_key(aes_key_t *_aes_key);
26+
bool aes_initialize(const unsigned char *key, const size_t key_length,
27+
EVP_CIPHER_CTX *encryption_context,
28+
EVP_CIPHER_CTX *decryption_context);

src/libhashkit/encrypt.cc

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,26 @@
1515

1616
#include "libhashkit/common.h"
1717

18-
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);
18+
hashkit_string_st *hashkit_encrypt(hashkit_st *kit, const char *source,
19+
size_t source_length) {
20+
return aes_encrypt(kit->encryption_context, (const unsigned char *)source,
21+
source_length);
2022
}
2123

22-
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);
24+
hashkit_string_st *hashkit_decrypt(hashkit_st *kit, const char *source,
25+
size_t source_length) {
26+
return aes_decrypt(kit->decryption_context, (const unsigned char *)source,
27+
source_length);
2428
}
2529

26-
bool hashkit_key(hashkit_st *kit, const char *key, const size_t key_length) {
27-
if (kit->_key) {
28-
free(kit->_key);
30+
bool hashkit_initialize_encryption(hashkit_st *kit, const char *key,
31+
const size_t key_length) {
32+
kit->encryption_context = EVP_CIPHER_CTX_new();
33+
kit->decryption_context = EVP_CIPHER_CTX_new();
34+
if (kit->encryption_context == NULL || kit->decryption_context == NULL) {
35+
return false;
2936
}
30-
31-
kit->_key = aes_create_key(key, key_length);
32-
33-
return bool(kit->_key);
34-
}
37+
return kit->use_encryption =
38+
aes_initialize((const unsigned char *)key, key_length,
39+
kit->encryption_context, kit->decryption_context);
40+
}

src/libhashkit/hashkit.cc

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

1616
#include "libhashkit/common.h"
1717

18+
#include <openssl/evp.h>
19+
1820
static inline void _hashkit_init(hashkit_st *self) {
1921
self->base_hash.function = hashkit_one_at_a_time;
2022
self->base_hash.context = NULL;
@@ -23,7 +25,7 @@ static inline void _hashkit_init(hashkit_st *self) {
2325
self->distribution_hash.context = NULL;
2426

2527
self->flags.is_base_same_distributed = true;
26-
self->_key = NULL;
28+
self->use_encryption = false;
2729
}
2830

2931
static inline hashkit_st *_hashkit_create(hashkit_st *self) {
@@ -53,9 +55,10 @@ hashkit_st *hashkit_create(hashkit_st *self) {
5355
}
5456

5557
void hashkit_free(hashkit_st *self) {
56-
if (self and self->_key) {
57-
free(self->_key);
58-
self->_key = NULL;
58+
if (self and self->use_encryption) {
59+
EVP_CIPHER_CTX_free(self->encryption_context);
60+
EVP_CIPHER_CTX_free(self->decryption_context);
61+
self->use_encryption = false;
5962
}
6063

6164
if (hashkit_is_allocated(self)) {
@@ -79,7 +82,18 @@ hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *source) {
7982
destination->base_hash = source->base_hash;
8083
destination->distribution_hash = source->distribution_hash;
8184
destination->flags = source->flags;
82-
destination->_key = aes_clone_key(static_cast<aes_key_t *>(source->_key));
85+
destination->use_encryption = source->use_encryption;
86+
if (destination->use_encryption) {
87+
destination->encryption_context = EVP_CIPHER_CTX_new();
88+
destination->decryption_context = EVP_CIPHER_CTX_new();
89+
if (destination->encryption_context == NULL ||
90+
destination->decryption_context == NULL)
91+
return NULL;
92+
EVP_CIPHER_CTX_copy(destination->encryption_context,
93+
source->encryption_context);
94+
EVP_CIPHER_CTX_copy(destination->decryption_context,
95+
source->decryption_context);
96+
}
8397

8498
return destination;
8599
}

0 commit comments

Comments
 (0)