@@ -125,62 +125,52 @@ size_t encrypt(std::string_view plaintext, char * ciphertext_and_tag, Encryption
125125{
126126 int out_len;
127127 int ciphertext_len;
128- EVP_CIPHER_CTX * ctx;
129- EVP_CIPHER * cipher;
130128
131- ctx = EVP_CIPHER_CTX_new ();
129+ using EVP_CIPHER_CTX_ptr = std::unique_ptr<EVP_CIPHER_CTX, decltype (&EVP_CIPHER_CTX_free)>;
130+ const auto ctx = EVP_CIPHER_CTX_ptr (EVP_CIPHER_CTX_new (), EVP_CIPHER_CTX_free);
132131 if (!ctx)
133132 throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_CTX_new failed: {}" , getOpenSSLErrors ());
134133
135- try
136- {
137- cipher = EVP_CIPHER_fetch (nullptr , getMethod (method), nullptr );
138- if (!cipher)
139- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_fetch failed: {}" , getOpenSSLErrors ());
134+ using EVP_CIPHER_ptr = std::unique_ptr<EVP_CIPHER, decltype (&EVP_CIPHER_free)>;
135+ const auto cipher = EVP_CIPHER_ptr (EVP_CIPHER_fetch (nullptr , getMethod (method), nullptr ), EVP_CIPHER_free);
136+ if (!cipher)
137+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_fetch failed: {}" , getOpenSSLErrors ());
140138
141- if (!EVP_EncryptInit_ex (ctx, cipher, nullptr , nullptr , nullptr ))
142- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_EncryptInit_ex failed: {}" , getOpenSSLErrors ());
139+ if (!EVP_EncryptInit_ex (ctx. get () , cipher. get () , nullptr , nullptr , nullptr ))
140+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_EncryptInit_ex failed: {}" , getOpenSSLErrors ());
143141
144- if (!EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_IVLEN, static_cast <int32_t >(nonce.size ()), nullptr ))
145- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_CTX_ctrl failed: {}" , getOpenSSLErrors ());
142+ if (!EVP_CIPHER_CTX_ctrl (ctx. get () , EVP_CTRL_GCM_SET_IVLEN, static_cast <int32_t >(nonce.size ()), nullptr ))
143+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_CTX_ctrl failed: {}" , getOpenSSLErrors ());
146144
147- if (!EVP_EncryptInit_ex (ctx, nullptr , nullptr ,
148- reinterpret_cast <const uint8_t *>(key.data ()),
149- reinterpret_cast <const uint8_t *>(nonce.data ())))
150- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_EncryptInit_ex failed: {}" , getOpenSSLErrors ());
145+ if (!EVP_EncryptInit_ex (ctx. get () , nullptr , nullptr ,
146+ reinterpret_cast <const uint8_t *>(key.data ()),
147+ reinterpret_cast <const uint8_t *>(nonce.data ())))
148+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_EncryptInit_ex failed: {}" , getOpenSSLErrors ());
151149
152- if (!EVP_EncryptUpdate (ctx,
153- reinterpret_cast <uint8_t *>(ciphertext_and_tag),
154- &out_len,
155- reinterpret_cast <const uint8_t *>(plaintext.data ()),
156- static_cast <int32_t >(plaintext.size ())))
157- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_EncryptUpdate failed: {}" , getOpenSSLErrors ());
150+ if (!EVP_EncryptUpdate (ctx. get () ,
151+ reinterpret_cast <uint8_t *>(ciphertext_and_tag),
152+ &out_len,
153+ reinterpret_cast <const uint8_t *>(plaintext.data ()),
154+ static_cast <int32_t >(plaintext.size ())))
155+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_EncryptUpdate failed: {}" , getOpenSSLErrors ());
158156
159- __msan_unpoison (ciphertext_and_tag, out_len); // / OpenSSL uses assembly which evades msan's analysis
157+ __msan_unpoison (ciphertext_and_tag, out_len); // / OpenSSL uses assembly which evades msan's analysis
160158
161- ciphertext_len = out_len;
159+ ciphertext_len = out_len;
162160
163- if (!EVP_EncryptFinal_ex (ctx,
164- reinterpret_cast <uint8_t *>(ciphertext_and_tag) + out_len,
165- reinterpret_cast <int32_t *>(&out_len)))
166- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_EncryptFinal_ex failed: {}" , getOpenSSLErrors ());
161+ if (!EVP_EncryptFinal_ex (ctx. get () ,
162+ reinterpret_cast <uint8_t *>(ciphertext_and_tag) + out_len,
163+ reinterpret_cast <int32_t *>(&out_len)))
164+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_EncryptFinal_ex failed: {}" , getOpenSSLErrors ());
167165
168- __msan_unpoison (ciphertext_and_tag, out_len); // / OpenSSL uses assembly which evades msan's analysis
166+ __msan_unpoison (ciphertext_and_tag, out_len); // / OpenSSL uses assembly which evades msan's analysis
169167
170- ciphertext_len += out_len;
168+ ciphertext_len += out_len;
169+
170+ // / Get the tag
171+ if (!EVP_CIPHER_CTX_ctrl (ctx.get (), EVP_CTRL_GCM_GET_TAG, tag_size, reinterpret_cast <uint8_t *>(ciphertext_and_tag) + plaintext.size ()))
172+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_CTX_ctrl failed: {}" , getOpenSSLErrors ());
171173
172- // / Get the tag
173- if (!EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_GET_TAG, tag_size, reinterpret_cast <uint8_t *>(ciphertext_and_tag) + plaintext.size ()))
174- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_CTX_ctrl failed: {}" , getOpenSSLErrors ());
175- }
176- catch (...)
177- {
178- EVP_CIPHER_free (cipher);
179- EVP_CIPHER_CTX_free (ctx);
180- throw ;
181- }
182- EVP_CIPHER_free (cipher);
183- EVP_CIPHER_CTX_free (ctx);
184174 return ciphertext_len + tag_size;
185175}
186176
@@ -192,62 +182,51 @@ size_t decrypt(std::string_view ciphertext, char * plaintext, EncryptionMethod m
192182{
193183 int out_len;
194184 int plaintext_len;
195- EVP_CIPHER_CTX * ctx;
196- EVP_CIPHER * cipher;
197185
198- ctx = EVP_CIPHER_CTX_new ();
186+ using EVP_CIPHER_CTX_ptr = std::unique_ptr<EVP_CIPHER_CTX, decltype (&EVP_CIPHER_CTX_free)>;
187+ const auto ctx = EVP_CIPHER_CTX_ptr (EVP_CIPHER_CTX_new (), EVP_CIPHER_CTX_free);
199188 if (!ctx)
200189 throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_CTX_new failed: {}" , getOpenSSLErrors ());
201190
202- try
203- {
204- cipher = EVP_CIPHER_fetch (nullptr , getMethod (method), nullptr );
205- if (!cipher)
206- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_fetch failed: {}" , getOpenSSLErrors ());
191+ using EVP_CIPHER_ptr = std::unique_ptr<EVP_CIPHER, decltype (&EVP_CIPHER_free)>;
192+ const auto cipher = EVP_CIPHER_ptr (EVP_CIPHER_fetch (nullptr , getMethod (method), nullptr ), EVP_CIPHER_free);
193+ if (!cipher)
194+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_fetch failed: {}" , getOpenSSLErrors ());
207195
208- if (!EVP_DecryptInit_ex (ctx, cipher, nullptr , nullptr , nullptr ))
209- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_DecryptInit_ex failed: {}" , getOpenSSLErrors ());
196+ if (!EVP_DecryptInit_ex (ctx. get () , cipher. get () , nullptr , nullptr , nullptr ))
197+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_DecryptInit_ex failed: {}" , getOpenSSLErrors ());
210198
211- if (!EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_IVLEN, static_cast <int32_t >(nonce.size ()), nullptr ))
212- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_CTX_ctrl failed: {}" , getOpenSSLErrors ());
199+ if (!EVP_CIPHER_CTX_ctrl (ctx. get () , EVP_CTRL_GCM_SET_IVLEN, static_cast <int32_t >(nonce.size ()), nullptr ))
200+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_CTX_ctrl failed: {}" , getOpenSSLErrors ());
213201
214- if (!EVP_DecryptInit_ex (ctx, nullptr , nullptr ,
215- reinterpret_cast <const uint8_t *>(key.data ()),
216- reinterpret_cast <const uint8_t *>(nonce.data ())))
217- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_DecryptInit_ex failed: {}" , getOpenSSLErrors ());
202+ if (!EVP_DecryptInit_ex (ctx. get () , nullptr , nullptr ,
203+ reinterpret_cast <const uint8_t *>(key.data ()),
204+ reinterpret_cast <const uint8_t *>(nonce.data ())))
205+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_DecryptInit_ex failed: {}" , getOpenSSLErrors ());
218206
219- if (!EVP_CIPHER_CTX_ctrl (ctx,
220- EVP_CTRL_GCM_SET_TAG,
221- tag_size,
222- reinterpret_cast <uint8_t *>(const_cast <char *>(ciphertext.data ())) + ciphertext.size () - tag_size))
223- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_CTX_ctrl failed: {}" , getOpenSSLErrors ());
207+ if (!EVP_CIPHER_CTX_ctrl (ctx. get () ,
208+ EVP_CTRL_GCM_SET_TAG,
209+ tag_size,
210+ reinterpret_cast <uint8_t *>(const_cast <char *>(ciphertext.data ())) + ciphertext.size () - tag_size))
211+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_CIPHER_CTX_ctrl failed: {}" , getOpenSSLErrors ());
224212
225- if (!EVP_DecryptUpdate (ctx,
226- reinterpret_cast <uint8_t *>(plaintext),
227- reinterpret_cast <int32_t *>(&out_len),
228- reinterpret_cast <const uint8_t *>(ciphertext.data ()),
229- static_cast <int32_t >(ciphertext.size ()) - tag_size))
230- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_DecryptUpdate failed: {}" , getOpenSSLErrors ());
213+ if (!EVP_DecryptUpdate (ctx. get () ,
214+ reinterpret_cast <uint8_t *>(plaintext),
215+ reinterpret_cast <int32_t *>(&out_len),
216+ reinterpret_cast <const uint8_t *>(ciphertext.data ()),
217+ static_cast <int32_t >(ciphertext.size ()) - tag_size))
218+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_DecryptUpdate failed: {}" , getOpenSSLErrors ());
231219
232- __msan_unpoison (plaintext, out_len); // / OpenSSL uses assembly which evades msan's analysis
220+ __msan_unpoison (plaintext, out_len); // / OpenSSL uses assembly which evades msan's analysis
233221
234- plaintext_len = out_len;
222+ plaintext_len = out_len;
235223
236- if (!EVP_DecryptFinal_ex (ctx,
237- reinterpret_cast <uint8_t *>(plaintext) + out_len,
238- reinterpret_cast <int32_t *>(&out_len)))
239- throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_DecryptFinal_ex failed: {}" , getOpenSSLErrors ());
224+ if (!EVP_DecryptFinal_ex (ctx. get () ,
225+ reinterpret_cast <uint8_t *>(plaintext) + out_len,
226+ reinterpret_cast <int32_t *>(&out_len)))
227+ throw Exception (ErrorCodes::OPENSSL_ERROR, " EVP_DecryptFinal_ex failed: {}" , getOpenSSLErrors ());
240228
241- __msan_unpoison (plaintext, out_len); // / OpenSSL uses assembly which evades msan's analysis
242- }
243- catch (...)
244- {
245- EVP_CIPHER_free (cipher);
246- EVP_CIPHER_CTX_free (ctx);
247- throw ;
248- }
249- EVP_CIPHER_free (cipher);
250- EVP_CIPHER_CTX_free (ctx);
229+ __msan_unpoison (plaintext, out_len); // / OpenSSL uses assembly which evades msan's analysis
251230
252231 return plaintext_len + out_len;
253232}
0 commit comments