Skip to content

Commit 566bb4e

Browse files
committed
fixup: use templates to further reduce boilerplate
1 parent ade8da2 commit 566bb4e

File tree

1 file changed

+44
-107
lines changed

1 file changed

+44
-107
lines changed

Diff for: addon/openssl-crypto.cc

+44-107
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,15 @@ static bool set_status_from_openssl(mongocrypt_status_t* status, const char* bas
9090
}
9191

9292
/* encrypt_with_cipher encrypts @in with the OpenSSL cipher specified by
93-
* @cipher.
93+
* @Cipher.
9494
* @key is the input key. @iv is the input IV.
9595
* @out is the output ciphertext. @out must be allocated by the caller with
9696
* enough room for the ciphertext.
9797
* @bytes_written is the number of bytes that were written to @out.
9898
* Returns false and sets @status on error. @status is required. */
99-
static bool encrypt_with_cipher(
100-
const EVP_CIPHER* cipher,
99+
template<typename Cipher>
100+
bool encrypt_with_cipher(
101+
void* unused_ctx,
101102
mongocrypt_binary_t* key,
102103
mongocrypt_binary_t* iv,
103104
mongocrypt_binary_t* in,
@@ -106,6 +107,7 @@ static bool encrypt_with_cipher(
106107
mongocrypt_status_t* status) {
107108
int intermediate_bytes_written = 0;
108109

110+
const EVP_CIPHER* cipher = Cipher::Get();
109111
EVP_CIPHER_CTX* ctx = S(EVP_CIPHER_CTX_new)();
110112
auto cleanup_ctx = Cleanup([&]() { S(EVP_CIPHER_CTX_free)(ctx); });
111113

@@ -155,14 +157,15 @@ static bool encrypt_with_cipher(
155157
}
156158

157159
/* decrypt_with_cipher decrypts @in with the OpenSSL cipher specified by
158-
* @cipher.
160+
* @Cipher.
159161
* @key is the input key. @iv is the input IV.
160162
* @out is the output plaintext. @out must be allocated by the caller with
161163
* enough room for the plaintext.
162164
* @bytes_written is the number of bytes that were written to @out.
163165
* Returns false and sets @status on error. @status is required. */
164-
static bool decrypt_with_cipher(
165-
const EVP_CIPHER *cipher,
166+
template<typename Cipher>
167+
bool decrypt_with_cipher(
168+
void* unused_ctx,
166169
mongocrypt_binary_t* key,
167170
mongocrypt_binary_t* iv,
168171
mongocrypt_binary_t* in,
@@ -171,6 +174,7 @@ static bool decrypt_with_cipher(
171174
mongocrypt_status_t* status) {
172175
int intermediate_bytes_written = 0;
173176

177+
const EVP_CIPHER* cipher = Cipher::Get();
174178
EVP_CIPHER_CTX* ctx = S(EVP_CIPHER_CTX_new)();
175179
auto cleanup_ctx = Cleanup([&]() { S(EVP_CIPHER_CTX_free)(ctx); });
176180
ASSERT(ctx);
@@ -220,51 +224,20 @@ static bool decrypt_with_cipher(
220224
return true;
221225
}
222226

223-
bool aes_256_cbc_encrypt(
224-
void* ctx,
225-
mongocrypt_binary_t* key,
226-
mongocrypt_binary_t* iv,
227-
mongocrypt_binary_t* in,
228-
mongocrypt_binary_t* out,
229-
uint32_t* bytes_written,
230-
mongocrypt_status_t* status) {
231-
return encrypt_with_cipher(S(EVP_aes_256_cbc)(), key, iv, in, out, bytes_written, status);
232-
}
233-
234-
bool aes_256_cbc_decrypt(
235-
void* ctx,
236-
mongocrypt_binary_t* key,
237-
mongocrypt_binary_t* iv,
238-
mongocrypt_binary_t* in,
239-
mongocrypt_binary_t* out,
240-
uint32_t* bytes_written,
241-
mongocrypt_status_t* status) {
242-
return decrypt_with_cipher(S(EVP_aes_256_cbc)(), key, iv, in, out, bytes_written, status);
243-
}
244-
245-
bool aes_256_ecb_encrypt(
246-
void* ctx,
247-
mongocrypt_binary_t* key,
248-
mongocrypt_binary_t* iv,
249-
mongocrypt_binary_t* in,
250-
mongocrypt_binary_t* out,
251-
uint32_t* bytes_written,
252-
mongocrypt_status_t* status) {
253-
return encrypt_with_cipher(S(EVP_aes_256_ecb)(), key, iv, in, out, bytes_written, status);
254-
}
255-
256227
/* hmac_with_hash computes an HMAC of @in with the OpenSSL hash specified by
257-
* @hash.
228+
* @Hash.
258229
* @key is the input key.
259230
* @out is the output. @out must be allocated by the caller with
260231
* the exact length for the output. E.g. for HMAC 256, @out->len must be 32.
261232
* Returns false and sets @status on error. @status is required. */
262-
static bool hmac_with_hash(
263-
const EVP_MD* hash,
233+
template<typename Hash>
234+
bool hmac_with_hash(
235+
void* unused_ctx,
264236
mongocrypt_binary_t *key,
265237
mongocrypt_binary_t *in,
266238
mongocrypt_binary_t *out,
267239
mongocrypt_status_t *status) {
240+
const EVP_MD* hash = Hash::Get();
268241
ASSERT(hash);
269242
ASSERT(key);
270243
ASSERT(in);
@@ -283,26 +256,8 @@ static bool hmac_with_hash(
283256
return true;
284257
}
285258

286-
bool hmac_sha_512(
287-
void* ctx,
288-
mongocrypt_binary_t* key,
289-
mongocrypt_binary_t* in,
290-
mongocrypt_binary_t* out,
291-
mongocrypt_status_t* status) {
292-
return hmac_with_hash(S(EVP_sha512)(), key, in, out, status);
293-
}
294-
295-
bool hmac_sha_256(
296-
void* ctx,
297-
mongocrypt_binary_t* key,
298-
mongocrypt_binary_t* in,
299-
mongocrypt_binary_t* out,
300-
mongocrypt_status_t* status) {
301-
return hmac_with_hash(S(EVP_sha256)(), key, in, out, status);
302-
}
303-
304259
bool random_fn(
305-
void* ctx,
260+
void* unused_ctx,
306261
mongocrypt_binary_t* out,
307262
uint32_t count,
308263
mongocrypt_status_t* status) {
@@ -321,46 +276,19 @@ bool random_fn(
321276
return true;
322277
}
323278

324-
bool aes_256_ctr_encrypt(
325-
void* ctx,
326-
mongocrypt_binary_t* key,
327-
mongocrypt_binary_t* iv,
328-
mongocrypt_binary_t* in,
329-
mongocrypt_binary_t* out,
330-
uint32_t* bytes_written,
331-
mongocrypt_status_t* status) {
332-
return encrypt_with_cipher(S(EVP_aes_256_ctr)(), key, iv, in, out, bytes_written, status);
333-
}
334-
335-
bool aes_256_ctr_decrypt(
336-
void* ctx,
337-
mongocrypt_binary_t* key,
338-
mongocrypt_binary_t* iv,
339-
mongocrypt_binary_t* in,
340-
mongocrypt_binary_t* out,
341-
uint32_t* bytes_written,
342-
mongocrypt_status_t* status) {
343-
return decrypt_with_cipher(S(EVP_aes_256_ctr)(), key, iv, in, out, bytes_written, status);
344-
}
345-
346-
bool native_crypto_hmac_sha_256(
347-
void* ctx,
348-
mongocrypt_binary_t* key,
279+
template<typename Hash>
280+
bool compute_hash (
281+
void* unused_ctx,
349282
mongocrypt_binary_t* in,
350283
mongocrypt_binary_t* out,
351284
mongocrypt_status_t* status) {
352-
return hmac_with_hash(S(EVP_sha256)(), key, in, out, status);
353-
}
285+
const EVP_MD* hash = Hash::Get();
286+
ASSERT(hash);
354287

355-
bool sha_256 (
356-
void* ctx,
357-
mongocrypt_binary_t* in,
358-
mongocrypt_binary_t* out,
359-
mongocrypt_status_t* status) {
360288
EVP_MD_CTX* digest_ctxp = S(EVP_MD_CTX_new)();
361289
auto cleanup_ctx = Cleanup([&]() { S(EVP_MD_CTX_free)(digest_ctxp); });
362290

363-
if (!S(EVP_DigestInit_ex)(digest_ctxp, S(EVP_sha256) (), nullptr)) {
291+
if (!S(EVP_DigestInit_ex)(digest_ctxp, hash, nullptr)) {
364292
return set_status_from_openssl(status, "error in EVP_DigestInit_ex");
365293
}
366294

@@ -375,12 +303,16 @@ bool sha_256 (
375303
return true;
376304
}
377305

378-
bool sign_rsa_sha256 (
306+
template<typename Hash>
307+
bool sign_rsa (
379308
void* unused_ctx,
380309
mongocrypt_binary_t* key,
381310
mongocrypt_binary_t* in,
382311
mongocrypt_binary_t* out,
383312
mongocrypt_status_t* status) {
313+
const EVP_MD* hash = Hash::Get();
314+
315+
ASSERT(hash);
384316
ASSERT(key);
385317
ASSERT(in);
386318
ASSERT(out);
@@ -389,7 +321,7 @@ bool sign_rsa_sha256 (
389321
EVP_PKEY* pkey = nullptr;
390322
size_t signature_out_len = 256;
391323

392-
EVP_MD_CTX*ctx = S(EVP_MD_CTX_new)();
324+
EVP_MD_CTX* ctx = S(EVP_MD_CTX_new)();
393325
auto cleanup_ctx = Cleanup([&]() { S(EVP_MD_CTX_free)(ctx); });
394326
ASSERT(key->len <= LONG_MAX);
395327
const unsigned char* key_data = static_cast<unsigned char*>(key->data);
@@ -403,7 +335,7 @@ bool sign_rsa_sha256 (
403335
return set_status_from_openssl(status, "error in d2i_PrivateKey");
404336
}
405337

406-
if (!S(EVP_DigestSignInit)(ctx, nullptr, S(EVP_sha256)(), nullptr /* engine */, pkey)) {
338+
if (!S(EVP_DigestSignInit)(ctx, nullptr, hash, nullptr /* engine */, pkey)) {
407339
return set_status_from_openssl(status, "error in EVP_DigestSignInit");
408340
}
409341

@@ -418,7 +350,6 @@ bool sign_rsa_sha256 (
418350
return true;
419351
}
420352

421-
422353
void* opensslsym(const char* name) {
423354
static struct OwnProcessDylib {
424355
bool initialized = false;
@@ -462,18 +393,24 @@ std::unique_ptr<CryptoHooks> createOpenSSLCryptoHooks() {
462393
// Check that OpenSSL version is in [3.0.0, 4.0.0)
463394
if (openssl_version < 0x30000000L || openssl_version >= 0x40000000L) return {};
464395

396+
struct AES256CBC { static const EVP_CIPHER* Get() { return S(EVP_aes_256_cbc)(); } };
397+
struct AES256ECB { static const EVP_CIPHER* Get() { return S(EVP_aes_256_ecb)(); } };
398+
struct AES256CTR { static const EVP_CIPHER* Get() { return S(EVP_aes_256_ctr)(); } };
399+
struct SHA512 { static const EVP_MD* Get() { return S(EVP_sha512)(); } };
400+
struct SHA256 { static const EVP_MD* Get() { return S(EVP_sha256)(); } };
401+
465402
return std::make_unique<CryptoHooks>(CryptoHooks {
466403
"native_openssl",
467-
aes_256_cbc_encrypt,
468-
aes_256_cbc_decrypt,
404+
encrypt_with_cipher<AES256CBC>,
405+
decrypt_with_cipher<AES256CBC>,
469406
random_fn,
470-
hmac_sha_512,
471-
hmac_sha_256,
472-
sha_256,
473-
aes_256_ctr_encrypt,
474-
aes_256_ctr_decrypt,
475-
aes_256_ecb_encrypt,
476-
sign_rsa_sha256,
407+
hmac_with_hash<SHA512>,
408+
hmac_with_hash<SHA256>,
409+
compute_hash<SHA256>,
410+
encrypt_with_cipher<AES256CTR>,
411+
decrypt_with_cipher<AES256CTR>,
412+
encrypt_with_cipher<AES256ECB>,
413+
sign_rsa<SHA256>,
477414
nullptr
478415
});
479416
}

0 commit comments

Comments
 (0)