|
15 | 15 |
|
16 | 16 | #include "libhashkit/common.h" |
17 | 17 |
|
18 | | -#include "libhashkit/rijndael.hpp" |
19 | | - |
20 | 18 | #include <cstring> |
21 | 19 |
|
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 |
36 | 21 |
|
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 |
43 | 24 |
|
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; |
57 | 32 | } |
58 | 33 |
|
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; |
65 | 38 | } |
66 | 39 |
|
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; |
70 | 47 | } |
71 | | - |
72 | | - return _aes_clone_key; |
| 48 | + return true; |
73 | 49 | } |
74 | 50 |
|
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) { |
77 | 59 | return NULL; |
78 | 60 | } |
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; |
99 | 68 | } |
100 | 69 |
|
| 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); |
101 | 78 | return destination; |
102 | 79 | } |
103 | 80 |
|
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) { |
106 | 88 | return NULL; |
107 | 89 | } |
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); |
111 | 96 | return NULL; |
112 | 97 | } |
113 | 98 |
|
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; |
139 | 103 | } |
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); |
141 | 107 | return destination; |
142 | 108 | } |
| 109 | + |
0 commit comments