Search code examples
opensslsha256fips

Calculating SHA256 hash with OpenSSL in FIPS mode


The background
I've compiled OpenSSL with the OpenSSL FIPS Object Module (following the instructions for cross compiling to Android).

Now in my code I want to use SHA256 (from what I can see at least some sha256 algorithms are FIPS approved).

The problem
After calling set_mode(1) to enable FIPS in runtime, the following code crashes in OpenSSLDie (presumably means disabled by FIPS)

SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, data, len);
SHA256_Final(outputBuffer, &sha256);

The questions

  1. It seems that calling private_SHA256_Init instead works, but is it the correct way or does it circumvent the FIPS compliance? If it isn't the correct way how can I calculate SHA256 in FIPS mode?

  2. Since usage of non-approved algorithms is allowed if not for cryptography (by FIPS-140.2), would calling the private function be good then (for example to calculate SHA1, which seems out of the question at all in FIPS mode, but it's not to be used for crypto)

More info
versions used: openssl-1.0.1q, openssl-fips-2.0.11


Solution

  • Usage of low-level functions such as SHA256_Init is deprecated, as far as I know.

    Currently approved method for calculating digests using OpenSSL is via EVP. An example for SHA-256, taken from https://wiki.openssl.org/index.php/EVP_Message_Digests :

    void digest_message(unsigned char *message, unsigned char **digest, unsigned int *digest_len)
    {
        EVP_MD_CTX *mdctx;
    
        if((mdctx = EVP_MD_CTX_create()) == NULL)
            handleErrors();
    
        if(1 != EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL))
            handleErrors();
    
        if(1 != EVP_DigestUpdate(mdctx, message, strlen(message)))
            handleErrors();
    
        if((*digest = (unsigned char *)OPENSSL_malloc(EVP_MD_size(EVP_sha256()))) == NULL)
            handleErrors();
    
        if(1 != EVP_DigestFinal_ex(mdctx, *digest, digest_len))
            handleErrors();
    
        EVP_MD_CTX_destroy(mdctx);
    }