From 3133dc60763c5d2f24badf8cba7103304824efbc Mon Sep 17 00:00:00 2001 From: WillChilds-Klein Date: Mon, 25 Mar 2024 21:10:12 +0000 Subject: [PATCH 1/5] Detect crypto library BLAKE2 support While OpenSSL supports both "b" and "s" variants of the BLAKE2 hash function, other cryptographic libraries may lack support for one or both of the variants. This commit modifies `hashlib`'s C code to detect whether or not the linked libcrypto supports each BLAKE2 variant, and elides references to each variant's NID accordingly. In cases where the underlying libcrypto doesn't fully support BLAKE2, CPython's `./configure` script can be given the following flag to use CPython's interned BLAKE2 implementation: `--with-builtin-hashlib-hashes=blake2`. --- Modules/_hashopenssl.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 0e230f332ff6cb..f118543d4025cf 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -47,7 +47,9 @@ #define PY_OPENSSL_HAS_SCRYPT 1 #define PY_OPENSSL_HAS_SHA3 1 #define PY_OPENSSL_HAS_SHAKE 1 +#if defined(NID_blake2s256) || defined(NID_blake2b512) #define PY_OPENSSL_HAS_BLAKE2 1 +#endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L #define PY_EVP_MD EVP_MD @@ -102,8 +104,12 @@ typedef struct { #define Py_hash_sha3_512 "sha3_512" #define Py_hash_shake_128 "shake_128" #define Py_hash_shake_256 "shake_256" +#if defined(NID_blake2s256) #define Py_hash_blake2s "blake2s" +#endif +#if defined(NID_blake2b512) #define Py_hash_blake2b "blake2b" +#endif #define PY_HASH_ENTRY(py_name, py_alias, ossl_name, ossl_nid) \ {py_name, py_alias, ossl_name, ossl_nid, 0, NULL, NULL} @@ -130,8 +136,12 @@ static const py_hashentry_t py_hashes[] = { PY_HASH_ENTRY(Py_hash_shake_128, NULL, SN_shake128, NID_shake128), PY_HASH_ENTRY(Py_hash_shake_256, NULL, SN_shake256, NID_shake256), /* blake2 digest */ +#if defined(NID_blake2s256) PY_HASH_ENTRY(Py_hash_blake2s, "blake2s256", SN_blake2s256, NID_blake2s256), +#endif +#if defined(NID_blake2s256) PY_HASH_ENTRY(Py_hash_blake2b, "blake2b512", SN_blake2b512, NID_blake2b512), +#endif PY_HASH_ENTRY(NULL, NULL, NULL, 0), }; From f50160814a9f1e7cfdffef449b8fc743e9951215 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 21:25:29 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Security/2024-03-25-21-25-28.gh-issue-117233.E4CyI_.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Security/2024-03-25-21-25-28.gh-issue-117233.E4CyI_.rst diff --git a/Misc/NEWS.d/next/Security/2024-03-25-21-25-28.gh-issue-117233.E4CyI_.rst b/Misc/NEWS.d/next/Security/2024-03-25-21-25-28.gh-issue-117233.E4CyI_.rst new file mode 100644 index 00000000000000..196b7794237431 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2024-03-25-21-25-28.gh-issue-117233.E4CyI_.rst @@ -0,0 +1 @@ +Detect BLAKE2 support in linked cryptography library. This change now allows CPython to build against cryptography/SSL libraries that don't fully support BLAKE2. From da67c39dc425120d6575832f136cae314e28dc8d Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google LLC]" Date: Thu, 28 Mar 2024 14:33:28 -0700 Subject: [PATCH 3/5] Expand build time detection to SHA3, Shake, & truncated SHA512. Detect BLAKE2, SHA3, Shake, & truncated SHA512 support in the OpenSSL-ish libcrypto library at build time. This helps allow hashlib's \_hashopenssl to be used with libraries that do not to support every algorithm that upstream OpenSSL does. Such as AWS-LC & BoringSSL. --- ...-03-25-21-25-28.gh-issue-117233.E4CyI_.rst | 4 +- Modules/_hashopenssl.c | 68 +++++++++++++++---- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/Misc/NEWS.d/next/Security/2024-03-25-21-25-28.gh-issue-117233.E4CyI_.rst b/Misc/NEWS.d/next/Security/2024-03-25-21-25-28.gh-issue-117233.E4CyI_.rst index 196b7794237431..a4142ec21b7e5d 100644 --- a/Misc/NEWS.d/next/Security/2024-03-25-21-25-28.gh-issue-117233.E4CyI_.rst +++ b/Misc/NEWS.d/next/Security/2024-03-25-21-25-28.gh-issue-117233.E4CyI_.rst @@ -1 +1,3 @@ -Detect BLAKE2 support in linked cryptography library. This change now allows CPython to build against cryptography/SSL libraries that don't fully support BLAKE2. +Detect BLAKE2, SHA3, Shake, & truncated SHA512 support in the OpenSSL-ish +libcrypto library at build time. This allows :mod:`hashlib` to be used with +libraries that do not to support every algorithm that upstream OpenSSL does. diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index f118543d4025cf..0d4b2745c81ce7 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -45,9 +45,16 @@ #define MUNCH_SIZE INT_MAX #define PY_OPENSSL_HAS_SCRYPT 1 +#if defined(NID_sha512_224) && defined(NID_sha512_256) +#define PY_OPENSSL_HAS_SHA512_2XX 1 +#endif +#if defined(NID_sha3_224) && defined(NID_sha3_256) && defined(NID_sha3_384) && defined(NID_sha3_512) #define PY_OPENSSL_HAS_SHA3 1 +#endif +#if defined(NID_shake128) && defined(NID_shake256) #define PY_OPENSSL_HAS_SHAKE 1 -#if defined(NID_blake2s256) || defined(NID_blake2b512) +#endif +#if defined(NID_blake2s256) && defined(NID_blake2b512) #define PY_OPENSSL_HAS_BLAKE2 1 #endif @@ -90,25 +97,44 @@ typedef struct { PY_EVP_MD *evp_nosecurity; } py_hashentry_t; +// Fundamental to TLS, assumed always present in any libcrypto: #define Py_hash_md5 "md5" #define Py_hash_sha1 "sha1" #define Py_hash_sha224 "sha224" #define Py_hash_sha256 "sha256" #define Py_hash_sha384 "sha384" #define Py_hash_sha512 "sha512" -#define Py_hash_sha512_224 "sha512_224" -#define Py_hash_sha512_256 "sha512_256" -#define Py_hash_sha3_224 "sha3_224" -#define Py_hash_sha3_256 "sha3_256" -#define Py_hash_sha3_384 "sha3_384" -#define Py_hash_sha3_512 "sha3_512" -#define Py_hash_shake_128 "shake_128" -#define Py_hash_shake_256 "shake_256" + +// Not all OpenSSL-like libcrypto libraries provide these: +#if defined(NID_sha512_224) +# define Py_hash_sha512_224 "sha512_224" +#endif +#if defined(NID_sha512_512) +# define Py_hash_sha512_256 "sha512_256" +#endif +#if defined(NID_sha3_224) +# define Py_hash_sha3_224 "sha3_224" +#endif +#if defined(NID_sha3_256) +# define Py_hash_sha3_256 "sha3_256" +#endif +#if defined(NID_sha3_384) +# define Py_hash_sha3_384 "sha3_384" +#endif +#if defined(NID_sha3_512) +# define Py_hash_sha3_512 "sha3_512" +#endif +#if defined(NID_shake128) +# define Py_hash_shake_128 "shake_128" +#endif +#if defined(NID_shake256) +# define Py_hash_shake_256 "shake_256" +#endif #if defined(NID_blake2s256) -#define Py_hash_blake2s "blake2s" +# define Py_hash_blake2s "blake2s" #endif #if defined(NID_blake2b512) -#define Py_hash_blake2b "blake2b" +# define Py_hash_blake2b "blake2b" #endif #define PY_HASH_ENTRY(py_name, py_alias, ossl_name, ossl_nid) \ @@ -125,21 +151,37 @@ static const py_hashentry_t py_hashes[] = { PY_HASH_ENTRY(Py_hash_sha384, "SHA384", SN_sha384, NID_sha384), PY_HASH_ENTRY(Py_hash_sha512, "SHA512", SN_sha512, NID_sha512), /* truncated sha2 */ +#ifdef Py_hash_sha512_224 PY_HASH_ENTRY(Py_hash_sha512_224, "SHA512_224", SN_sha512_224, NID_sha512_224), +#endif +#ifdef Py_hash_sha512_256 PY_HASH_ENTRY(Py_hash_sha512_256, "SHA512_256", SN_sha512_256, NID_sha512_256), +#endif /* sha3 */ +#ifdef Py_hash_sha3_224 PY_HASH_ENTRY(Py_hash_sha3_224, NULL, SN_sha3_224, NID_sha3_224), +#endif +#ifdef Py_hash_sha3_256 PY_HASH_ENTRY(Py_hash_sha3_256, NULL, SN_sha3_256, NID_sha3_256), +#endif +#ifdef Py_hash_sha3_384 PY_HASH_ENTRY(Py_hash_sha3_384, NULL, SN_sha3_384, NID_sha3_384), +#endif +#ifdef Py_hash_sha3_512 PY_HASH_ENTRY(Py_hash_sha3_512, NULL, SN_sha3_512, NID_sha3_512), +#endif /* sha3 shake */ +#ifdef Py_hash_shake_128 PY_HASH_ENTRY(Py_hash_shake_128, NULL, SN_shake128, NID_shake128), +#endif +#ifdef Py_hash_shake_256 PY_HASH_ENTRY(Py_hash_shake_256, NULL, SN_shake256, NID_shake256), +#endif /* blake2 digest */ -#if defined(NID_blake2s256) +#ifdef Py_hash_blake2s PY_HASH_ENTRY(Py_hash_blake2s, "blake2s256", SN_blake2s256, NID_blake2s256), #endif -#if defined(NID_blake2s256) +#ifdef Py_hash_blake2b PY_HASH_ENTRY(Py_hash_blake2b, "blake2b512", SN_blake2b512, NID_blake2b512), #endif PY_HASH_ENTRY(NULL, NULL, NULL, 0), From 5fa77c4143963b4ed1505df45887fc4d960fbea8 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google LLC]" Date: Thu, 28 Mar 2024 14:42:12 -0700 Subject: [PATCH 4/5] go back to || for blake2 and shake, remove unused define. --- Modules/_hashopenssl.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 0d4b2745c81ce7..2d3f0e1085ba99 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -45,16 +45,13 @@ #define MUNCH_SIZE INT_MAX #define PY_OPENSSL_HAS_SCRYPT 1 -#if defined(NID_sha512_224) && defined(NID_sha512_256) -#define PY_OPENSSL_HAS_SHA512_2XX 1 -#endif #if defined(NID_sha3_224) && defined(NID_sha3_256) && defined(NID_sha3_384) && defined(NID_sha3_512) #define PY_OPENSSL_HAS_SHA3 1 #endif -#if defined(NID_shake128) && defined(NID_shake256) +#if defined(NID_shake128) || defined(NID_shake256) #define PY_OPENSSL_HAS_SHAKE 1 #endif -#if defined(NID_blake2s256) && defined(NID_blake2b512) +#if defined(NID_blake2s256) || defined(NID_blake2b512) #define PY_OPENSSL_HAS_BLAKE2 1 #endif From b8c52725c2dc05f2c63e2ea3e5300221737b5462 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Thu, 4 Apr 2024 07:49:58 -0700 Subject: [PATCH 5/5] typo fix, gate sha512-256 on NID_sha512_256 Co-authored-by: Petr Viktorin --- Modules/_hashopenssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 2d3f0e1085ba99..d0b46810dc1489 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -106,7 +106,7 @@ typedef struct { #if defined(NID_sha512_224) # define Py_hash_sha512_224 "sha512_224" #endif -#if defined(NID_sha512_512) +#if defined(NID_sha512_256) # define Py_hash_sha512_256 "sha512_256" #endif #if defined(NID_sha3_224)