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>
chromium-stable
David Benjamin 1 year ago committed by Boringssl LUCI CQ
parent ad57528d2c
commit c5a99415cc
  1. 7
      include/openssl/sha.h

@ -97,11 +97,12 @@ OPENSSL_EXPORT void SHA1_Transform(SHA_CTX *sha,
const uint8_t block[SHA_CBLOCK]); const uint8_t block[SHA_CBLOCK]);
struct sha_state_st { struct sha_state_st {
#if defined(OPENSSL_WINDOWS) #if defined(__cplusplus) || defined(OPENSSL_WINDOWS)
uint32_t h[5]; uint32_t h[5];
#else #else
// wpa_supplicant accesses |h0|..|h4| so we must support those names // wpa_supplicant accesses |h0|..|h4| so we must support those names for
// for compatibility with it until it can be updated. // compatibility with it until it can be updated. Anonymous unions are only
// standard in C11, so disable this workaround in C++.
union { union {
uint32_t h[5]; uint32_t h[5];
struct { struct {

Loading…
Cancel
Save