Limit the SHA_CTX workaround to C
Anonymous unions are now standard in C, as of C11, but not in C++.
Enabling sufficiently strict warnings in GCC and Clang flag this.
I considered whether we should just remove this and go back to the
OpenSSL formulation, but we actually rely on this being an array when
calling sha1_block_data_order. Upstream types these as taking pointers
to the context, which would work, but taking a pointer to the state is a
bit more accurate. (The assembly function should not touch the buffering
inside the context.)
This anonymous union does mean wpa_supplicant's behavior is slightly
questionable from a strict aliasing perspective, but ah well.
wpa_supplicant uses this to implement an old FIPS 186-2 PRF, which was
based on SHA-1's underlying permutation. Ideally we would either
implement this PRF for them, or have them use their own SHA-1
implementation. They've actually done the latter for OpenSSL 3.0, but
it's a little silly to duplicate the code.
strongswan and go/another-fips-186-2-prf seems to do this too. I'm not
positive what strongswan is doing. I've filed crbug.com/boringssl/667
for follow-up work.
Bug: 667
Fixed: 566
Change-Id: Ife32cc8c278e0dbbd95401ccdd3bd62945e10cf2
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/63967
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/include/openssl/sha.h b/include/openssl/sha.h
index b113798..1a3247f 100644
--- a/include/openssl/sha.h
+++ b/include/openssl/sha.h
@@ -97,11 +97,12 @@
const uint8_t block[SHA_CBLOCK]);
struct sha_state_st {
-#if defined(OPENSSL_WINDOWS)
+#if defined(__cplusplus) || defined(OPENSSL_WINDOWS)
uint32_t h[5];
#else
- // wpa_supplicant accesses |h0|..|h4| so we must support those names
- // for compatibility with it until it can be updated.
+ // wpa_supplicant accesses |h0|..|h4| so we must support those names for
+ // compatibility with it until it can be updated. Anonymous unions are only
+ // standard in C11, so disable this workaround in C++.
union {
uint32_t h[5];
struct {