Skip to content

Commit 9a0a4d3

Browse files
mattcaswellt8m
authored andcommitted
Fix DH_check() excessive time with over sized modulus
The DH_check() function checks numerous aspects of the key or parameters that have been supplied. Some of those checks use the supplied modulus value even if it is excessively large. There is already a maximum DH modulus size (10,000 bits) over which OpenSSL will not generate or derive keys. DH_check() will however still perform various tests for validity on such a large modulus. We introduce a new maximum (32,768) over which DH_check() will just fail. An application that calls DH_check() and supplies a key or parameters obtained from an untrusted source could be vulnerable to a Denial of Service attack. The function DH_check() is itself called by a number of other OpenSSL functions. An application calling any of those other functions may similarly be affected. The other functions affected by this are DH_check_ex() and EVP_PKEY_param_check(). CVE-2023-3446 Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org>
1 parent fd31391 commit 9a0a4d3

File tree

3 files changed

+15
-3
lines changed

3 files changed

+15
-3
lines changed

crypto/dh/dh.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
# ifndef OPENSSL_DH_MAX_MODULUS_BITS
7777
# define OPENSSL_DH_MAX_MODULUS_BITS 10000
7878
# endif
79+
# ifndef OPENSSL_DH_CHECK_MAX_MODULUS_BITS
80+
# define OPENSSL_DH_CHECK_MAX_MODULUS_BITS 32768
81+
# endif
7982

8083
# define DH_FLAG_CACHE_MONT_P 0x01
8184

@@ -363,6 +366,7 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen,
363366
* The following lines are auto generated by the script mkerr.pl. Any changes
364367
* made after this point may be overwritten when the script is next run.
365368
*/
369+
366370
void ERR_load_DH_strings(void);
367371

368372
/* Error codes for the DH functions. */
@@ -371,6 +375,7 @@ void ERR_load_DH_strings(void);
371375
# define DH_F_COMPUTE_KEY 102
372376
# define DH_F_DHPARAMS_PRINT_FP 101
373377
# define DH_F_DH_BUILTIN_GENPARAMS 106
378+
# define DH_F_DH_CHECK 126
374379
# define DH_F_DH_CMS_DECRYPT 117
375380
# define DH_F_DH_CMS_SET_PEERKEY 118
376381
# define DH_F_DH_CMS_SET_SHARED_INFO 119
@@ -406,7 +411,7 @@ void ERR_load_DH_strings(void);
406411
# define DH_R_PEER_KEY_ERROR 113
407412
# define DH_R_SHARED_INFO_ERROR 114
408413

409-
#ifdef __cplusplus
414+
# ifdef __cplusplus
410415
}
411-
#endif
416+
# endif
412417
#endif

crypto/dh/dh_check.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ int DH_check(const DH *dh, int *ret)
7878
BN_ULONG l;
7979
BIGNUM *t1 = NULL, *t2 = NULL;
8080

81+
/* Don't do any checks at all with an excessively large modulus */
82+
if (BN_num_bits(dh->p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) {
83+
DHerr(DH_F_DH_CHECK, DH_R_MODULUS_TOO_LARGE);
84+
return 0;
85+
}
86+
8187
*ret = 0;
8288
ctx = BN_CTX_new();
8389
if (ctx == NULL)

crypto/dh/dh_err.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* crypto/dh/dh_err.c */
22
/* ====================================================================
3-
* Copyright (c) 1999-2013 The OpenSSL Project. All rights reserved.
3+
* Copyright (c) 1999-2023 The OpenSSL Project. All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
66
* modification, are permitted provided that the following conditions
@@ -73,6 +73,7 @@ static ERR_STRING_DATA DH_str_functs[] = {
7373
{ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"},
7474
{ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"},
7575
{ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"},
76+
{ERR_FUNC(DH_F_DH_CHECK), "DH_check"},
7677
{ERR_FUNC(DH_F_DH_CMS_DECRYPT), "DH_CMS_DECRYPT"},
7778
{ERR_FUNC(DH_F_DH_CMS_SET_PEERKEY), "DH_CMS_SET_PEERKEY"},
7879
{ERR_FUNC(DH_F_DH_CMS_SET_SHARED_INFO), "DH_CMS_SET_SHARED_INFO"},

0 commit comments

Comments
 (0)