@@ -90,14 +90,15 @@ static bool set_status_from_openssl(mongocrypt_status_t* status, const char* bas
90
90
}
91
91
92
92
/* encrypt_with_cipher encrypts @in with the OpenSSL cipher specified by
93
- * @cipher .
93
+ * @Cipher .
94
94
* @key is the input key. @iv is the input IV.
95
95
* @out is the output ciphertext. @out must be allocated by the caller with
96
96
* enough room for the ciphertext.
97
97
* @bytes_written is the number of bytes that were written to @out.
98
98
* 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,
101
102
mongocrypt_binary_t * key,
102
103
mongocrypt_binary_t * iv,
103
104
mongocrypt_binary_t * in,
@@ -106,6 +107,7 @@ static bool encrypt_with_cipher(
106
107
mongocrypt_status_t * status) {
107
108
int intermediate_bytes_written = 0 ;
108
109
110
+ const EVP_CIPHER* cipher = Cipher::Get ();
109
111
EVP_CIPHER_CTX* ctx = S (EVP_CIPHER_CTX_new)();
110
112
auto cleanup_ctx = Cleanup ([&]() { S (EVP_CIPHER_CTX_free)(ctx); });
111
113
@@ -155,14 +157,15 @@ static bool encrypt_with_cipher(
155
157
}
156
158
157
159
/* decrypt_with_cipher decrypts @in with the OpenSSL cipher specified by
158
- * @cipher .
160
+ * @Cipher .
159
161
* @key is the input key. @iv is the input IV.
160
162
* @out is the output plaintext. @out must be allocated by the caller with
161
163
* enough room for the plaintext.
162
164
* @bytes_written is the number of bytes that were written to @out.
163
165
* 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,
166
169
mongocrypt_binary_t * key,
167
170
mongocrypt_binary_t * iv,
168
171
mongocrypt_binary_t * in,
@@ -171,6 +174,7 @@ static bool decrypt_with_cipher(
171
174
mongocrypt_status_t * status) {
172
175
int intermediate_bytes_written = 0 ;
173
176
177
+ const EVP_CIPHER* cipher = Cipher::Get ();
174
178
EVP_CIPHER_CTX* ctx = S (EVP_CIPHER_CTX_new)();
175
179
auto cleanup_ctx = Cleanup ([&]() { S (EVP_CIPHER_CTX_free)(ctx); });
176
180
ASSERT (ctx);
@@ -220,51 +224,20 @@ static bool decrypt_with_cipher(
220
224
return true ;
221
225
}
222
226
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
-
256
227
/* hmac_with_hash computes an HMAC of @in with the OpenSSL hash specified by
257
- * @hash .
228
+ * @Hash .
258
229
* @key is the input key.
259
230
* @out is the output. @out must be allocated by the caller with
260
231
* the exact length for the output. E.g. for HMAC 256, @out->len must be 32.
261
232
* 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,
264
236
mongocrypt_binary_t *key,
265
237
mongocrypt_binary_t *in,
266
238
mongocrypt_binary_t *out,
267
239
mongocrypt_status_t *status) {
240
+ const EVP_MD* hash = Hash::Get ();
268
241
ASSERT (hash);
269
242
ASSERT (key);
270
243
ASSERT (in);
@@ -283,26 +256,8 @@ static bool hmac_with_hash(
283
256
return true ;
284
257
}
285
258
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
-
304
259
bool random_fn (
305
- void * ctx ,
260
+ void * unused_ctx ,
306
261
mongocrypt_binary_t * out,
307
262
uint32_t count,
308
263
mongocrypt_status_t * status) {
@@ -321,46 +276,19 @@ bool random_fn(
321
276
return true ;
322
277
}
323
278
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,
349
282
mongocrypt_binary_t * in,
350
283
mongocrypt_binary_t * out,
351
284
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);
354
287
355
- bool sha_256 (
356
- void * ctx,
357
- mongocrypt_binary_t * in,
358
- mongocrypt_binary_t * out,
359
- mongocrypt_status_t * status) {
360
288
EVP_MD_CTX* digest_ctxp = S (EVP_MD_CTX_new)();
361
289
auto cleanup_ctx = Cleanup ([&]() { S (EVP_MD_CTX_free)(digest_ctxp); });
362
290
363
- if (!S (EVP_DigestInit_ex)(digest_ctxp, S (EVP_sha256) () , nullptr )) {
291
+ if (!S (EVP_DigestInit_ex)(digest_ctxp, hash , nullptr )) {
364
292
return set_status_from_openssl (status, " error in EVP_DigestInit_ex" );
365
293
}
366
294
@@ -375,12 +303,16 @@ bool sha_256 (
375
303
return true ;
376
304
}
377
305
378
- bool sign_rsa_sha256 (
306
+ template <typename Hash>
307
+ bool sign_rsa (
379
308
void * unused_ctx,
380
309
mongocrypt_binary_t * key,
381
310
mongocrypt_binary_t * in,
382
311
mongocrypt_binary_t * out,
383
312
mongocrypt_status_t * status) {
313
+ const EVP_MD* hash = Hash::Get ();
314
+
315
+ ASSERT (hash);
384
316
ASSERT (key);
385
317
ASSERT (in);
386
318
ASSERT (out);
@@ -389,7 +321,7 @@ bool sign_rsa_sha256 (
389
321
EVP_PKEY* pkey = nullptr ;
390
322
size_t signature_out_len = 256 ;
391
323
392
- EVP_MD_CTX*ctx = S (EVP_MD_CTX_new)();
324
+ EVP_MD_CTX* ctx = S (EVP_MD_CTX_new)();
393
325
auto cleanup_ctx = Cleanup ([&]() { S (EVP_MD_CTX_free)(ctx); });
394
326
ASSERT (key->len <= LONG_MAX);
395
327
const unsigned char * key_data = static_cast <unsigned char *>(key->data );
@@ -403,7 +335,7 @@ bool sign_rsa_sha256 (
403
335
return set_status_from_openssl (status, " error in d2i_PrivateKey" );
404
336
}
405
337
406
- if (!S (EVP_DigestSignInit)(ctx, nullptr , S (EVP_sha256)() , nullptr /* engine */ , pkey)) {
338
+ if (!S (EVP_DigestSignInit)(ctx, nullptr , hash , nullptr /* engine */ , pkey)) {
407
339
return set_status_from_openssl (status, " error in EVP_DigestSignInit" );
408
340
}
409
341
@@ -418,7 +350,6 @@ bool sign_rsa_sha256 (
418
350
return true ;
419
351
}
420
352
421
-
422
353
void * opensslsym (const char * name) {
423
354
static struct OwnProcessDylib {
424
355
bool initialized = false ;
@@ -462,18 +393,24 @@ std::unique_ptr<CryptoHooks> createOpenSSLCryptoHooks() {
462
393
// Check that OpenSSL version is in [3.0.0, 4.0.0)
463
394
if (openssl_version < 0x30000000L || openssl_version >= 0x40000000L ) return {};
464
395
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
+
465
402
return std::make_unique<CryptoHooks>(CryptoHooks {
466
403
" native_openssl" ,
467
- aes_256_cbc_encrypt ,
468
- aes_256_cbc_decrypt ,
404
+ encrypt_with_cipher<AES256CBC> ,
405
+ decrypt_with_cipher<AES256CBC> ,
469
406
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> ,
477
414
nullptr
478
415
});
479
416
}
0 commit comments