15
15
16
16
#include "crypto/s2n_hash.h"
17
17
18
- #include "crypto/s2n_evp_signing .h"
18
+ #include "crypto/s2n_fips .h"
19
19
#include "crypto/s2n_hmac.h"
20
20
#include "crypto/s2n_openssl.h"
21
21
#include "error/s2n_errno.h"
22
22
#include "utils/s2n_safety.h"
23
23
24
+ static bool s2n_use_custom_md5_sha1 ()
25
+ {
26
+ #if defined(S2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH )
27
+ return false;
28
+ #else
29
+ return true;
30
+ #endif
31
+ }
32
+
24
33
static bool s2n_use_evp_impl ()
25
34
{
26
- /* Our current EVP signing implementation requires EVP hashing.
27
- *
28
- * We could use the EVP hashing impl with legacy signing, but that would
29
- * unnecessarily complicate the logic. The only known libcrypto that
30
- * doesn't support EVP signing is openssl-1.0.2. Just let legacy
31
- * libcryptos use legacy methods.
32
- */
33
- return s2n_evp_signing_supported ();
35
+ return s2n_is_in_fips_mode ();
36
+ }
37
+
38
+ bool s2n_hash_evp_fully_supported ()
39
+ {
40
+ return s2n_use_evp_impl () && !s2n_use_custom_md5_sha1 ();
34
41
}
35
42
36
43
const EVP_MD * s2n_hash_alg_to_evp_md (s2n_hash_algorithm alg )
@@ -282,8 +289,13 @@ static int s2n_low_level_hash_free(struct s2n_hash_state *state)
282
289
static int s2n_evp_hash_new (struct s2n_hash_state * state )
283
290
{
284
291
POSIX_ENSURE_REF (state -> digest .high_level .evp .ctx = S2N_EVP_MD_CTX_NEW ());
292
+ if (s2n_use_custom_md5_sha1 ()) {
293
+ POSIX_ENSURE_REF (state -> digest .high_level .evp_md5_secondary .ctx = S2N_EVP_MD_CTX_NEW ());
294
+ }
295
+
285
296
state -> is_ready_for_input = 0 ;
286
297
state -> currently_in_hash = 0 ;
298
+
287
299
return S2N_SUCCESS ;
288
300
}
289
301
@@ -299,6 +311,13 @@ static int s2n_evp_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm al
299
311
return S2N_SUCCESS ;
300
312
}
301
313
314
+ if (alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1 ()) {
315
+ POSIX_ENSURE_REF (state -> digest .high_level .evp_md5_secondary .ctx );
316
+ POSIX_GUARD_OSSL (EVP_DigestInit_ex (state -> digest .high_level .evp .ctx , EVP_sha1 (), NULL ), S2N_ERR_HASH_INIT_FAILED );
317
+ POSIX_GUARD_OSSL (EVP_DigestInit_ex (state -> digest .high_level .evp_md5_secondary .ctx , EVP_md5 (), NULL ), S2N_ERR_HASH_INIT_FAILED );
318
+ return S2N_SUCCESS ;
319
+ }
320
+
302
321
POSIX_ENSURE_REF (s2n_hash_alg_to_evp_md (alg ));
303
322
POSIX_GUARD_OSSL (EVP_DigestInit_ex (state -> digest .high_level .evp .ctx , s2n_hash_alg_to_evp_md (alg ), NULL ), S2N_ERR_HASH_INIT_FAILED );
304
323
return S2N_SUCCESS ;
@@ -316,6 +335,12 @@ static int s2n_evp_hash_update(struct s2n_hash_state *state, const void *data, u
316
335
317
336
POSIX_ENSURE_REF (EVP_MD_CTX_md (state -> digest .high_level .evp .ctx ));
318
337
POSIX_GUARD_OSSL (EVP_DigestUpdate (state -> digest .high_level .evp .ctx , data , size ), S2N_ERR_HASH_UPDATE_FAILED );
338
+
339
+ if (state -> alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1 ()) {
340
+ POSIX_ENSURE_REF (EVP_MD_CTX_md (state -> digest .high_level .evp_md5_secondary .ctx ));
341
+ POSIX_GUARD_OSSL (EVP_DigestUpdate (state -> digest .high_level .evp_md5_secondary .ctx , data , size ), S2N_ERR_HASH_UPDATE_FAILED );
342
+ }
343
+
319
344
return S2N_SUCCESS ;
320
345
}
321
346
@@ -337,6 +362,23 @@ static int s2n_evp_hash_digest(struct s2n_hash_state *state, void *out, uint32_t
337
362
338
363
POSIX_ENSURE_REF (EVP_MD_CTX_md (state -> digest .high_level .evp .ctx ));
339
364
365
+ if (state -> alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1 ()) {
366
+ POSIX_ENSURE_REF (EVP_MD_CTX_md (state -> digest .high_level .evp_md5_secondary .ctx ));
367
+
368
+ uint8_t sha1_digest_size = 0 ;
369
+ POSIX_GUARD (s2n_hash_digest_size (S2N_HASH_SHA1 , & sha1_digest_size ));
370
+
371
+ unsigned int sha1_primary_digest_size = sha1_digest_size ;
372
+ unsigned int md5_secondary_digest_size = digest_size - sha1_primary_digest_size ;
373
+
374
+ POSIX_ENSURE (EVP_MD_CTX_size (state -> digest .high_level .evp .ctx ) <= sha1_digest_size , S2N_ERR_HASH_DIGEST_FAILED );
375
+ POSIX_ENSURE ((size_t ) EVP_MD_CTX_size (state -> digest .high_level .evp_md5_secondary .ctx ) <= md5_secondary_digest_size , S2N_ERR_HASH_DIGEST_FAILED );
376
+
377
+ POSIX_GUARD_OSSL (EVP_DigestFinal_ex (state -> digest .high_level .evp .ctx , ((uint8_t * ) out ) + MD5_DIGEST_LENGTH , & sha1_primary_digest_size ), S2N_ERR_HASH_DIGEST_FAILED );
378
+ POSIX_GUARD_OSSL (EVP_DigestFinal_ex (state -> digest .high_level .evp_md5_secondary .ctx , out , & md5_secondary_digest_size ), S2N_ERR_HASH_DIGEST_FAILED );
379
+ return S2N_SUCCESS ;
380
+ }
381
+
340
382
POSIX_ENSURE ((size_t ) EVP_MD_CTX_size (state -> digest .high_level .evp .ctx ) <= digest_size , S2N_ERR_HASH_DIGEST_FAILED );
341
383
POSIX_GUARD_OSSL (EVP_DigestFinal_ex (state -> digest .high_level .evp .ctx , out , & digest_size ), S2N_ERR_HASH_DIGEST_FAILED );
342
384
return S2N_SUCCESS ;
@@ -355,12 +397,21 @@ static int s2n_evp_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *f
355
397
356
398
POSIX_ENSURE_REF (to -> digest .high_level .evp .ctx );
357
399
POSIX_GUARD_OSSL (EVP_MD_CTX_copy_ex (to -> digest .high_level .evp .ctx , from -> digest .high_level .evp .ctx ), S2N_ERR_HASH_COPY_FAILED );
400
+
401
+ if (from -> alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1 ()) {
402
+ POSIX_ENSURE_REF (to -> digest .high_level .evp_md5_secondary .ctx );
403
+ POSIX_GUARD_OSSL (EVP_MD_CTX_copy_ex (to -> digest .high_level .evp_md5_secondary .ctx , from -> digest .high_level .evp_md5_secondary .ctx ), S2N_ERR_HASH_COPY_FAILED );
404
+ }
405
+
358
406
return S2N_SUCCESS ;
359
407
}
360
408
361
409
static int s2n_evp_hash_reset (struct s2n_hash_state * state )
362
410
{
363
411
POSIX_GUARD_OSSL (S2N_EVP_MD_CTX_RESET (state -> digest .high_level .evp .ctx ), S2N_ERR_HASH_WIPE_FAILED );
412
+ if (state -> alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1 ()) {
413
+ POSIX_GUARD_OSSL (S2N_EVP_MD_CTX_RESET (state -> digest .high_level .evp_md5_secondary .ctx ), S2N_ERR_HASH_WIPE_FAILED );
414
+ }
364
415
365
416
/* hash_init resets the ready_for_input and currently_in_hash fields. */
366
417
return s2n_evp_hash_init (state , state -> alg );
@@ -370,6 +421,12 @@ static int s2n_evp_hash_free(struct s2n_hash_state *state)
370
421
{
371
422
S2N_EVP_MD_CTX_FREE (state -> digest .high_level .evp .ctx );
372
423
state -> digest .high_level .evp .ctx = NULL ;
424
+
425
+ if (s2n_use_custom_md5_sha1 ()) {
426
+ S2N_EVP_MD_CTX_FREE (state -> digest .high_level .evp_md5_secondary .ctx );
427
+ state -> digest .high_level .evp_md5_secondary .ctx = NULL ;
428
+ }
429
+
373
430
state -> is_ready_for_input = 0 ;
374
431
return S2N_SUCCESS ;
375
432
}
0 commit comments