@@ -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
@@ -138,13 +140,14 @@ size_t get_ciphertext_size(size_t input_size, const Keyring_aes_opmode mode) {
138140 : input_size;
139141}
140142
141- aes_return_status aes_encrypt (const unsigned char *source,
142- unsigned int source_length, unsigned char *dest,
143- const unsigned char *key, unsigned int key_length,
144- Keyring_aes_opmode mode, const unsigned char *iv,
145- bool padding, size_t *encrypted_length) {
146- if (encrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
143+ namespace {
147144
145+ aes_return_status aes_evp_encrypt (const unsigned char *source,
146+ unsigned int source_length,
147+ unsigned char *dest, const EVP_CIPHER *cipher,
148+ const unsigned char *raw_key,
149+ const unsigned char *iv, bool padding,
150+ size_t *encrypted_length) {
148151#if OPENSSL_VERSION_NUMBER < 0x10100000L
149152 EVP_CIPHER_CTX stack_ctx;
150153 EVP_CIPHER_CTX *ctx = &stack_ctx;
@@ -163,39 +166,30 @@ aes_return_status aes_encrypt(const unsigned char *source,
163166#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
164167 });
165168
166- const EVP_CIPHER *cipher = aes_evp_type (mode);
167- if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
168-
169- /* The real key to be used for encryption */
170- std::unique_ptr<unsigned char []> rkey;
171- size_t rkey_size;
172- if (aes_create_key (key, key_length, rkey, &rkey_size, mode) == false )
173- return AES_KEY_TRANSFORMATION_ERROR ;
174-
175169 if (EVP_CIPHER_iv_length (cipher) > 0 && !iv) return AES_IV_EMPTY ;
176170
177171 int u_len, f_len;
178172
179- if (!EVP_EncryptInit (ctx, cipher, rkey.get (), iv))
173+ if (EVP_EncryptInit (ctx, cipher, raw_key, iv) == 0 )
174+ return AES_ENCRYPTION_ERROR ;
175+ if (EVP_CIPHER_CTX_set_padding (ctx, padding) == 0 )
176+ return AES_ENCRYPTION_ERROR ;
177+ if (EVP_EncryptUpdate (ctx, dest, &u_len, source, source_length) == 0 )
180178 return AES_ENCRYPTION_ERROR ;
181- if (!EVP_CIPHER_CTX_set_padding (ctx, padding)) return AES_ENCRYPTION_ERROR ;
182- if (!EVP_EncryptUpdate (ctx, dest, &u_len, source, source_length))
179+ if (EVP_EncryptFinal (ctx, dest + u_len, &f_len) == 0 )
183180 return AES_ENCRYPTION_ERROR ;
184- if (!EVP_EncryptFinal (ctx, dest + u_len, &f_len)) return AES_ENCRYPTION_ERROR ;
185181
186182 /* All is well */
187183 *encrypted_length = static_cast <size_t >(u_len + f_len);
188184 return AES_OP_OK ;
189185}
190186
191- aes_return_status aes_decrypt (const unsigned char *source,
192- unsigned int source_length, unsigned char *dest,
193- const unsigned char *key, unsigned int key_length,
194- enum Keyring_aes_opmode mode,
195- const unsigned char *iv, bool padding,
196- size_t *decrypted_length) {
197- if (decrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
198-
187+ aes_return_status aes_evp_decrypt (const unsigned char *source,
188+ unsigned int source_length,
189+ unsigned char *dest, const EVP_CIPHER *cipher,
190+ const unsigned char *raw_key,
191+ const unsigned char *iv, bool padding,
192+ size_t *decrypted_length) {
199193#if OPENSSL_VERSION_NUMBER < 0x10100000L
200194 EVP_CIPHER_CTX stack_ctx;
201195 EVP_CIPHER_CTX *ctx = &stack_ctx;
@@ -214,31 +208,110 @@ aes_return_status aes_decrypt(const unsigned char *source,
214208#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
215209 });
216210
217- const EVP_CIPHER *cipher = aes_evp_type (mode);
218- if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
219-
220- /* The real key to be used for encryption */
221- std::unique_ptr<unsigned char []> rkey;
222- size_t rkey_size;
223- if (aes_create_key (key, key_length, rkey, &rkey_size, mode) == false )
224- return AES_KEY_TRANSFORMATION_ERROR ;
225-
226211 if (EVP_CIPHER_iv_length (cipher) > 0 && !iv) return AES_IV_EMPTY ;
227212
228213 int u_len, f_len;
229214
230- if (! EVP_DecryptInit (ctx, aes_evp_type (mode), rkey. get () , iv))
215+ if (EVP_DecryptInit (ctx, cipher, raw_key , iv) == 0 )
231216 return AES_DECRYPTION_ERROR ;
232- if (!EVP_CIPHER_CTX_set_padding (ctx, padding)) return AES_DECRYPTION_ERROR ;
233- if (!EVP_DecryptUpdate (ctx, dest, &u_len, source, source_length))
217+ if (EVP_CIPHER_CTX_set_padding (ctx, padding) == 0 )
234218 return AES_DECRYPTION_ERROR ;
235- if (!EVP_DecryptFinal_ex (ctx, dest + u_len, &f_len))
219+ if (EVP_DecryptUpdate (ctx, dest, &u_len, source, source_length) == 0 )
220+ return AES_DECRYPTION_ERROR ;
221+ if (EVP_DecryptFinal_ex (ctx, dest + u_len, &f_len) == 0 )
236222 return AES_DECRYPTION_ERROR ;
237223
238224 /* All is well */
239225 *decrypted_length = static_cast <size_t >(u_len + f_len);
240226 return AES_OP_OK ;
241227}
242228
229+ } // namespace
230+
231+ aes_return_status aes_encrypt (const unsigned char *source,
232+ unsigned int source_length, unsigned char *dest,
233+ const unsigned char *key, unsigned int key_length,
234+ Keyring_aes_opmode mode, const unsigned char *iv,
235+ bool padding, size_t *encrypted_length) {
236+ if (encrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
237+
238+ const EVP_CIPHER *cipher = aes_evp_type (mode);
239+ if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
240+
241+ /* The real key to be used for encryption */
242+ std::unique_ptr<unsigned char []> rkey;
243+ size_t rkey_size = 0 ;
244+ if (!aes_create_key (key, key_length, rkey, &rkey_size, mode))
245+ return AES_KEY_TRANSFORMATION_ERROR ;
246+
247+ return aes_evp_encrypt (source, source_length, dest, cipher, rkey.get (), iv,
248+ padding, encrypted_length);
249+ }
250+
251+ aes_return_status aes_decrypt (const unsigned char *source,
252+ unsigned int source_length, unsigned char *dest,
253+ const unsigned char *key, unsigned int key_length,
254+ enum Keyring_aes_opmode mode,
255+ const unsigned char *iv, bool padding,
256+ size_t *decrypted_length) {
257+ if (decrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
258+
259+ const EVP_CIPHER *cipher = aes_evp_type (mode);
260+ if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
261+
262+ /* The real key to be used for encryption */
263+ std::unique_ptr<unsigned char []> rkey;
264+ size_t rkey_size = 0 ;
265+ if (!aes_create_key (key, key_length, rkey, &rkey_size, mode))
266+ return AES_KEY_TRANSFORMATION_ERROR ;
267+
268+ return aes_evp_decrypt (source, source_length, dest, cipher, rkey.get (), iv,
269+ padding, decrypted_length);
270+ }
271+
272+ aes_return_status aes_encrypt_pbkdf2 (
273+ const unsigned char *source, unsigned int source_length,
274+ unsigned char *dest, const unsigned char *password, size_t password_len,
275+ const unsigned char *salt, size_t salt_len, unsigned int iterations,
276+ Keyring_aes_opmode mode, const unsigned char *iv, bool padding,
277+ size_t *encrypted_length) {
278+ if (encrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
279+ const EVP_CIPHER *cipher = aes_evp_type (mode);
280+ if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
281+ unsigned char raw_key[32 ];
282+ auto zero_key =
283+ create_scope_guard ([&] { OPENSSL_cleanse (raw_key, sizeof (raw_key)); });
284+ if (PKCS5_PBKDF2_HMAC (reinterpret_cast <const char *>(password),
285+ static_cast <int >(password_len), salt,
286+ static_cast <int >(salt_len),
287+ static_cast <int >(iterations), EVP_sha256 (),
288+ static_cast <int >(sizeof (raw_key)), raw_key) != 1 )
289+ return AES_KEY_TRANSFORMATION_ERROR ;
290+ return aes_evp_encrypt (source, source_length, dest, cipher, raw_key, iv,
291+ padding, encrypted_length);
292+ }
293+
294+ aes_return_status aes_decrypt_pbkdf2 (
295+ const unsigned char *source, unsigned int source_length,
296+ unsigned char *dest, const unsigned char *password, size_t password_len,
297+ const unsigned char *salt, size_t salt_len, unsigned int iterations,
298+ Keyring_aes_opmode mode, const unsigned char *iv, bool padding,
299+ size_t *decrypted_length) {
300+ if (decrypted_length == nullptr ) return AES_OUTPUT_SIZE_NULL ;
301+ const EVP_CIPHER *cipher = aes_evp_type (mode);
302+ if (cipher == nullptr ) return AES_INVALID_BLOCK_MODE ;
303+ unsigned char raw_key[32 ];
304+ auto zero_key =
305+ create_scope_guard ([&] { OPENSSL_cleanse (raw_key, sizeof (raw_key)); });
306+ if (PKCS5_PBKDF2_HMAC (reinterpret_cast <const char *>(password),
307+ static_cast <int >(password_len), salt,
308+ static_cast <int >(salt_len),
309+ static_cast <int >(iterations), EVP_sha256 (),
310+ static_cast <int >(sizeof (raw_key)), raw_key) != 1 )
311+ return AES_KEY_TRANSFORMATION_ERROR ;
312+ return aes_evp_decrypt (source, source_length, dest, cipher, raw_key, iv,
313+ padding, decrypted_length);
314+ }
315+
243316} // namespace aes_encryption
244317} // namespace keyring_common
0 commit comments