On Mon, 2022-12-05 at 16:14 -0800, Benjamin Kaduk via openssl-users wrote: > On Mon, Dec 05, 2022 at 11:31:18AM -0800, Thomas Dwyer III wrote: > > Why does EVP_get_digestbyname("md4") return non-NULL if the legacy > > provider > > isn't loaded? Similarly, why does it return non-NULL for "md5" > > after doing > > EVP_set_default_properties(NULL, "fips=yes")? This seems > > unintuitive. Legacy > > code that does not know about EVP_MD_fetch() checks the return > > value of > > EVP_get_digestbyname(). Isn't that where the error should be > > detected? Why > > let it get all the way to BIO_set_md() (or EVP_DigestInit() or > > whatever) > > before the error is detected? > > To do so would introduce a time-of-check/time-of-use race, as the set > of > providers available may change in the intervening period. Not just that. IMO the primary motivation was to keep the digests (and similarly ciphers) returned by the EVP_md4() (and similar) or EVP_get_digestbyname() calls still constant. I.e., they would not change based on the providers involved, etc. This implied the implicit fetching done inside the EVP_DigestInit() and similar init routines. As any correct code required checking result of EVP_DigestInit() and thus also the result of BIO_set_md(), it was the least of all evils in how to implement these legacy EVP_MD functions returning constant EVP_MDs. -- Tomáš Mráz, OpenSSL