@@ -29,7 +29,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
2929
3030#include < openssl/aes.h>
3131#include < openssl/bio.h>
32+ #include < openssl/crypto.h>
3233#include < openssl/err.h>
34+ #include < openssl/evp.h>
3335
3436#include < openssl/sha.h>
3537
@@ -134,13 +136,10 @@ size_t get_ciphertext_size(size_t input_size, const Keyring_aes_opmode mode) {
134136 : input_size;
135137}
136138
137- aes_return_status aes_encrypt (const unsigned char *source,
138- unsigned int source_length, unsigned char *dest,
139- const unsigned char *key, unsigned int key_length,
140- Keyring_aes_opmode mode, const unsigned char *iv,
141- bool padding, size_t *encrypted_length) {
142- if (encrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
143-
139+ static aes_return_status aes_evp_encrypt (
140+ const unsigned char *source, unsigned int source_length,
141+ unsigned char *dest, const EVP_CIPHER *cipher, const unsigned char *raw_key,
142+ const unsigned char *iv, bool padding, size_t *encrypted_length) {
144143#if OPENSSL_VERSION_NUMBER < 0x10100000L
145144 EVP_CIPHER_CTX stack_ctx;
146145 EVP_CIPHER_CTX *ctx = &stack_ctx;
@@ -159,21 +158,11 @@ aes_return_status aes_encrypt(const unsigned char *source,
159158#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
160159 });
161160
162- const EVP_CIPHER *cipher = aes_evp_type (mode);
163- if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
164-
165- /* The real key to be used for encryption */
166- std::unique_ptr<unsigned char []> rkey;
167- size_t rkey_size;
168- if (!aes_create_key (key, key_length, rkey, &rkey_size, mode))
169- return AES_KEY_TRANSFORMATION_ERROR ;
170-
171161 if (EVP_CIPHER_iv_length (cipher) > 0 && !iv) return AES_IV_EMPTY ;
172162
173163 int u_len, f_len;
174164
175- if (!EVP_EncryptInit (ctx, cipher, rkey.get (), iv))
176- return AES_ENCRYPTION_ERROR ;
165+ if (!EVP_EncryptInit (ctx, cipher, raw_key, iv)) return AES_ENCRYPTION_ERROR ;
177166 if (!EVP_CIPHER_CTX_set_padding (ctx, padding)) return AES_ENCRYPTION_ERROR ;
178167 if (!EVP_EncryptUpdate (ctx, dest, &u_len, source, source_length))
179168 return AES_ENCRYPTION_ERROR ;
@@ -184,14 +173,10 @@ aes_return_status aes_encrypt(const unsigned char *source,
184173 return AES_OP_OK ;
185174}
186175
187- aes_return_status aes_decrypt (const unsigned char *source,
188- unsigned int source_length, unsigned char *dest,
189- const unsigned char *key, unsigned int key_length,
190- enum Keyring_aes_opmode mode,
191- const unsigned char *iv, bool padding,
192- size_t *decrypted_length) {
193- if (decrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
194-
176+ static aes_return_status aes_evp_decrypt (
177+ const unsigned char *source, unsigned int source_length,
178+ unsigned char *dest, const EVP_CIPHER *cipher, const unsigned char *raw_key,
179+ const unsigned char *iv, bool padding, size_t *decrypted_length) {
195180#if OPENSSL_VERSION_NUMBER < 0x10100000L
196181 EVP_CIPHER_CTX stack_ctx;
197182 EVP_CIPHER_CTX *ctx = &stack_ctx;
@@ -210,21 +195,11 @@ aes_return_status aes_decrypt(const unsigned char *source,
210195#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
211196 });
212197
213- const EVP_CIPHER *cipher = aes_evp_type (mode);
214- if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
215-
216- /* The real key to be used for encryption */
217- std::unique_ptr<unsigned char []> rkey;
218- size_t rkey_size;
219- if (!aes_create_key (key, key_length, rkey, &rkey_size, mode))
220- return AES_KEY_TRANSFORMATION_ERROR ;
221-
222198 if (EVP_CIPHER_iv_length (cipher) > 0 && !iv) return AES_IV_EMPTY ;
223199
224200 int u_len, f_len;
225201
226- if (!EVP_DecryptInit (ctx, aes_evp_type (mode), rkey.get (), iv))
227- return AES_DECRYPTION_ERROR ;
202+ if (!EVP_DecryptInit (ctx, cipher, raw_key, iv)) return AES_DECRYPTION_ERROR ;
228203 if (!EVP_CIPHER_CTX_set_padding (ctx, padding)) return AES_DECRYPTION_ERROR ;
229204 if (!EVP_DecryptUpdate (ctx, dest, &u_len, source, source_length))
230205 return AES_DECRYPTION_ERROR ;
@@ -236,4 +211,89 @@ aes_return_status aes_decrypt(const unsigned char *source,
236211 return AES_OP_OK ;
237212}
238213
214+ aes_return_status aes_encrypt (const unsigned char *source,
215+ unsigned int source_length, unsigned char *dest,
216+ const unsigned char *key, unsigned int key_length,
217+ Keyring_aes_opmode mode, const unsigned char *iv,
218+ bool padding, size_t *encrypted_length) {
219+ if (encrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
220+
221+ const EVP_CIPHER *cipher = aes_evp_type (mode);
222+ if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
223+
224+ /* The real key to be used for encryption */
225+ std::unique_ptr<unsigned char []> rkey;
226+ size_t rkey_size;
227+ if (!aes_create_key (key, key_length, rkey, &rkey_size, mode))
228+ return AES_KEY_TRANSFORMATION_ERROR ;
229+
230+ return aes_evp_encrypt (source, source_length, dest, cipher, rkey.get (), iv,
231+ padding, encrypted_length);
232+ }
233+
234+ aes_return_status aes_decrypt (const unsigned char *source,
235+ unsigned int source_length, unsigned char *dest,
236+ const unsigned char *key, unsigned int key_length,
237+ enum Keyring_aes_opmode mode,
238+ const unsigned char *iv, bool padding,
239+ size_t *decrypted_length) {
240+ if (decrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
241+
242+ const EVP_CIPHER *cipher = aes_evp_type (mode);
243+ if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
244+
245+ /* The real key to be used for encryption */
246+ std::unique_ptr<unsigned char []> rkey;
247+ size_t rkey_size;
248+ if (!aes_create_key (key, key_length, rkey, &rkey_size, mode))
249+ return AES_KEY_TRANSFORMATION_ERROR ;
250+
251+ return aes_evp_decrypt (source, source_length, dest, cipher, rkey.get (), iv,
252+ padding, decrypted_length);
253+ }
254+
255+ aes_return_status aes_encrypt_pbkdf2 (
256+ const unsigned char *source, unsigned int source_length,
257+ unsigned char *dest, const unsigned char *password, size_t password_len,
258+ const unsigned char *salt, size_t salt_len, unsigned int iterations,
259+ Keyring_aes_opmode mode, const unsigned char *iv, bool padding,
260+ size_t *encrypted_length) {
261+ if (encrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
262+ const EVP_CIPHER *cipher = aes_evp_type (mode);
263+ if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
264+ unsigned char raw_key[32 ];
265+ auto zero_key =
266+ create_scope_guard ([&] { OPENSSL_cleanse (raw_key, sizeof (raw_key)); });
267+ if (PKCS5_PBKDF2_HMAC (reinterpret_cast <const char *>(password),
268+ static_cast <int >(password_len), salt,
269+ static_cast <int >(salt_len),
270+ static_cast <int >(iterations), EVP_sha256 (),
271+ static_cast <int >(sizeof (raw_key)), raw_key) != 1 )
272+ return AES_KEY_TRANSFORMATION_ERROR ;
273+ return aes_evp_encrypt (source, source_length, dest, cipher, raw_key, iv,
274+ padding, encrypted_length);
275+ }
276+
277+ aes_return_status aes_decrypt_pbkdf2 (
278+ const unsigned char *source, unsigned int source_length,
279+ unsigned char *dest, const unsigned char *password, size_t password_len,
280+ const unsigned char *salt, size_t salt_len, unsigned int iterations,
281+ Keyring_aes_opmode mode, const unsigned char *iv, bool padding,
282+ size_t *decrypted_length) {
283+ if (decrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
284+ const EVP_CIPHER *cipher = aes_evp_type (mode);
285+ if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
286+ unsigned char raw_key[32 ];
287+ auto zero_key =
288+ create_scope_guard ([&] { OPENSSL_cleanse (raw_key, sizeof (raw_key)); });
289+ if (PKCS5_PBKDF2_HMAC (reinterpret_cast <const char *>(password),
290+ static_cast <int >(password_len), salt,
291+ static_cast <int >(salt_len),
292+ static_cast <int >(iterations), EVP_sha256 (),
293+ static_cast <int >(sizeof (raw_key)), raw_key) != 1 )
294+ return AES_KEY_TRANSFORMATION_ERROR ;
295+ return aes_evp_decrypt (source, source_length, dest, cipher, raw_key, iv,
296+ padding, decrypted_length);
297+ }
298+
239299} // namespace keyring_common::aes_encryption
0 commit comments