2525#include <openssl/objects.h>
2626#include "openssl/err.h"
2727
28+ /* Expose FIPS_mode */
29+ #include <openssl/crypto.h>
30+
2831#include "clinic/_hashopenssl.c.h"
2932/*[clinic input]
3033module _hashlib
@@ -987,6 +990,38 @@ GEN_CONSTRUCTOR(sha256)
987990GEN_CONSTRUCTOR (sha384 )
988991GEN_CONSTRUCTOR (sha512 )
989992
993+ /*[clinic input]
994+ _hashlib.get_fips_mode
995+
996+ Determine the OpenSSL FIPS mode of operation.
997+
998+ Effectively any non-zero return value indicates FIPS mode;
999+ values other than 1 may have additional significance.
1000+
1001+ See OpenSSL documentation for the FIPS_mode() function for details.
1002+ [clinic start generated code]*/
1003+
1004+ static PyObject *
1005+ _hashlib_get_fips_mode_impl (PyObject * module )
1006+ /*[clinic end generated code: output=ad8a7793310d3f98 input=f42a2135df2a5e11]*/
1007+ {
1008+ int result = FIPS_mode ();
1009+ if (result == 0 ) {
1010+ // "If the library was built without support of the FIPS Object Module,
1011+ // then the function will return 0 with an error code of
1012+ // CRYPTO_R_FIPS_MODE_NOT_SUPPORTED (0x0f06d065)."
1013+ // But 0 is also a valid result value.
1014+
1015+ unsigned long errcode = ERR_peek_last_error ();
1016+ if (errcode ) {
1017+ _setException (PyExc_ValueError );
1018+ return NULL ;
1019+ }
1020+ }
1021+ return PyLong_FromLong (result );
1022+ }
1023+
1024+
9901025/* List of functions exported by this module */
9911026
9921027static struct PyMethodDef EVP_functions [] = {
@@ -996,6 +1031,7 @@ static struct PyMethodDef EVP_functions[] = {
9961031 pbkdf2_hmac__doc__ },
9971032#endif
9981033 _HASHLIB_SCRYPT_METHODDEF
1034+ _HASHLIB_GET_FIPS_MODE_METHODDEF
9991035 CONSTRUCTOR_METH_DEF (md5 ),
10001036 CONSTRUCTOR_METH_DEF (sha1 ),
10011037 CONSTRUCTOR_METH_DEF (sha224 ),
0 commit comments