@@ -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,14 @@ 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 ;
139+ namespace {
143140
141+ aes_return_status aes_evp_encrypt (const unsigned char *source,
142+ unsigned int source_length,
143+ unsigned char *dest, const EVP_CIPHER *cipher,
144+ const unsigned char *raw_key,
145+ const unsigned char *iv, bool padding,
146+ size_t *encrypted_length) {
144147#if OPENSSL_VERSION_NUMBER < 0x10100000L
145148 EVP_CIPHER_CTX stack_ctx;
146149 EVP_CIPHER_CTX *ctx = &stack_ctx;
@@ -159,39 +162,30 @@ aes_return_status aes_encrypt(const unsigned char *source,
159162#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
160163 });
161164
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-
171165 if (EVP_CIPHER_iv_length (cipher) > 0 && !iv) return AES_IV_EMPTY ;
172166
173167 int u_len, f_len;
174168
175- if (!EVP_EncryptInit (ctx, cipher, rkey.get (), iv))
169+ if (EVP_EncryptInit (ctx, cipher, raw_key, iv) == 0 )
170+ return AES_ENCRYPTION_ERROR ;
171+ if (EVP_CIPHER_CTX_set_padding (ctx, padding) == 0 )
172+ return AES_ENCRYPTION_ERROR ;
173+ if (EVP_EncryptUpdate (ctx, dest, &u_len, source, source_length) == 0 )
176174 return AES_ENCRYPTION_ERROR ;
177- if (!EVP_CIPHER_CTX_set_padding (ctx, padding)) return AES_ENCRYPTION_ERROR ;
178- if (!EVP_EncryptUpdate (ctx, dest, &u_len, source, source_length))
175+ if (EVP_EncryptFinal (ctx, dest + u_len, &f_len) == 0 )
179176 return AES_ENCRYPTION_ERROR ;
180- if (!EVP_EncryptFinal (ctx, dest + u_len, &f_len)) return AES_ENCRYPTION_ERROR ;
181177
182178 /* All is well */
183179 *encrypted_length = static_cast <size_t >(u_len + f_len);
184180 return AES_OP_OK ;
185181}
186182
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-
183+ aes_return_status aes_evp_decrypt (const unsigned char *source,
184+ unsigned int source_length,
185+ unsigned char *dest, const EVP_CIPHER *cipher,
186+ const unsigned char *raw_key,
187+ const unsigned char *iv, bool padding,
188+ size_t *decrypted_length) {
195189#if OPENSSL_VERSION_NUMBER < 0x10100000L
196190 EVP_CIPHER_CTX stack_ctx;
197191 EVP_CIPHER_CTX *ctx = &stack_ctx;
@@ -210,30 +204,109 @@ aes_return_status aes_decrypt(const unsigned char *source,
210204#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
211205 });
212206
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-
222207 if (EVP_CIPHER_iv_length (cipher) > 0 && !iv) return AES_IV_EMPTY ;
223208
224209 int u_len, f_len;
225210
226- if (!EVP_DecryptInit (ctx, aes_evp_type (mode), rkey.get (), iv))
211+ if (EVP_DecryptInit (ctx, cipher, raw_key, iv) == 0 )
212+ return AES_DECRYPTION_ERROR ;
213+ if (EVP_CIPHER_CTX_set_padding (ctx, padding) == 0 )
227214 return AES_DECRYPTION_ERROR ;
228- if (!EVP_CIPHER_CTX_set_padding (ctx, padding)) return AES_DECRYPTION_ERROR ;
229- if (!EVP_DecryptUpdate (ctx, dest, &u_len, source, source_length))
215+ if (EVP_DecryptUpdate (ctx, dest, &u_len, source, source_length) == 0 )
230216 return AES_DECRYPTION_ERROR ;
231- if (! EVP_DecryptFinal_ex (ctx, dest + u_len, &f_len))
217+ if (EVP_DecryptFinal_ex (ctx, dest + u_len, &f_len) == 0 )
232218 return AES_DECRYPTION_ERROR ;
233219
234220 /* All is well */
235221 *decrypted_length = static_cast <size_t >(u_len + f_len);
236222 return AES_OP_OK ;
237223}
238224
225+ } // namespace
226+
227+ aes_return_status aes_encrypt (const unsigned char *source,
228+ unsigned int source_length, unsigned char *dest,
229+ const unsigned char *key, unsigned int key_length,
230+ Keyring_aes_opmode mode, const unsigned char *iv,
231+ bool padding, size_t *encrypted_length) {
232+ if (encrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
233+
234+ const EVP_CIPHER *cipher = aes_evp_type (mode);
235+ if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
236+
237+ /* The real key to be used for encryption */
238+ std::unique_ptr<unsigned char []> rkey;
239+ size_t rkey_size = 0 ;
240+ if (!aes_create_key (key, key_length, rkey, &rkey_size, mode))
241+ return AES_KEY_TRANSFORMATION_ERROR ;
242+
243+ return aes_evp_encrypt (source, source_length, dest, cipher, rkey.get (), iv,
244+ padding, encrypted_length);
245+ }
246+
247+ aes_return_status aes_decrypt (const unsigned char *source,
248+ unsigned int source_length, unsigned char *dest,
249+ const unsigned char *key, unsigned int key_length,
250+ enum Keyring_aes_opmode mode,
251+ const unsigned char *iv, bool padding,
252+ size_t *decrypted_length) {
253+ if (decrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
254+
255+ const EVP_CIPHER *cipher = aes_evp_type (mode);
256+ if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
257+
258+ /* The real key to be used for encryption */
259+ std::unique_ptr<unsigned char []> rkey;
260+ size_t rkey_size = 0 ;
261+ if (!aes_create_key (key, key_length, rkey, &rkey_size, mode))
262+ return AES_KEY_TRANSFORMATION_ERROR ;
263+
264+ return aes_evp_decrypt (source, source_length, dest, cipher, rkey.get (), iv,
265+ padding, decrypted_length);
266+ }
267+
268+ aes_return_status aes_encrypt_pbkdf2 (
269+ const unsigned char *source, unsigned int source_length,
270+ unsigned char *dest, const unsigned char *password, size_t password_len,
271+ const unsigned char *salt, size_t salt_len, unsigned int iterations,
272+ Keyring_aes_opmode mode, const unsigned char *iv, bool padding,
273+ size_t *encrypted_length) {
274+ if (encrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
275+ const EVP_CIPHER *cipher = aes_evp_type (mode);
276+ if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
277+ unsigned char raw_key[32 ];
278+ auto zero_key =
279+ create_scope_guard ([&] { OPENSSL_cleanse (raw_key, sizeof (raw_key)); });
280+ if (PKCS5_PBKDF2_HMAC (reinterpret_cast <const char *>(password),
281+ static_cast <int >(password_len), salt,
282+ static_cast <int >(salt_len),
283+ static_cast <int >(iterations), EVP_sha256 (),
284+ static_cast <int >(sizeof (raw_key)), raw_key) != 1 )
285+ return AES_KEY_TRANSFORMATION_ERROR ;
286+ return aes_evp_encrypt (source, source_length, dest, cipher, raw_key, iv,
287+ padding, encrypted_length);
288+ }
289+
290+ aes_return_status aes_decrypt_pbkdf2 (
291+ const unsigned char *source, unsigned int source_length,
292+ unsigned char *dest, const unsigned char *password, size_t password_len,
293+ const unsigned char *salt, size_t salt_len, unsigned int iterations,
294+ Keyring_aes_opmode mode, const unsigned char *iv, bool padding,
295+ size_t *decrypted_length) {
296+ if (decrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
297+ const EVP_CIPHER *cipher = aes_evp_type (mode);
298+ if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
299+ unsigned char raw_key[32 ];
300+ auto zero_key =
301+ create_scope_guard ([&] { OPENSSL_cleanse (raw_key, sizeof (raw_key)); });
302+ if (PKCS5_PBKDF2_HMAC (reinterpret_cast <const char *>(password),
303+ static_cast <int >(password_len), salt,
304+ static_cast <int >(salt_len),
305+ static_cast <int >(iterations), EVP_sha256 (),
306+ static_cast <int >(sizeof (raw_key)), raw_key) != 1 )
307+ return AES_KEY_TRANSFORMATION_ERROR ;
308+ return aes_evp_decrypt (source, source_length, dest, cipher, raw_key, iv,
309+ padding, decrypted_length);
310+ }
311+
239312} // namespace keyring_common::aes_encryption
0 commit comments