I'm trying to develop an extremely simple application in C in order to verify my FIPS Object Module installation, but I'm having trouble.
Here is my exact build information and results:
On Windows XP 32bit Operating System
Download & Extract openssl-1.0.1c and openssl-fips-2.0
$cd C:\openssl-fips-2.0
$ms\do_fips
>FIPS BUILD SUCCESS
$out32dll\fips_test_suite
>All tests completed with 0 errors
$cd C:\openssl-1.0.1c
$perl Configure VC-WIN32 fips
>Configured for VC-WIN32
$ms\do_nasm
>completes with no errors
$nmake -f ms\ntdll.mak
>completes with no errors
$nmake -f ms\ntdll.mak test
>passed all tests
$nmake -f ms\ntdll.mak install
>completes with no errors
$cd C:\usr\local\ssl\bin
$openssl version -a
>OpenSSL 1.0.1c-fips...
$echo Hello World > hello.txt
$openssl md5 hello.txt
>works
$set OPENSSL_FIPS=1
$openssl md5 hello.txt
>Error disabled for fips
$openssl sha1 hello.txt
>works
------------------------
At this point, I am confident that my installation is correct.
------------------------
Next, I wanted to create a sample program using C to demonstrate how to call the FIPS_mode_set() function. After searching around, I found some simple code here:
http://old.nabble.com/AES-cbc--How-to-Init-Openssl--td12475822.html and adapted it slightly for my needs.
--Begin C code--
#include <stdio.h>
#include <string.h>
#include <openssl\err.h>
#include <openssl\fips.h>
#include <openssl\aes.h>
int main(int argc, char *argv[])
{
//32byte key
unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
//16byte Initialization Vector
unsigned char iv[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
//plain txt input with padding buffer. Since the AES Block Size is 16bytes and 'crypto' is only 6 bytes, it needs 10 bytes of padding
unsigned char plaintxt[1024]="crypto\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a";
//output
unsigned char encrypted[1024];
AES_KEY aeskey;
//direct the output of the program to out.txt
freopen ("out.txt","w",stdout);
//Setting up FIPS MODE:
if(FIPS_mode()) //Check if FIPS MODE is enabled already
{
printf("FIPS MODE is already engaged\n");
}
else
{
printf("Attempting to enable FIPS MODE\n");
if(FIPS_mode_set(1))
{
printf("FIPS mode set successful\n");
}
else
{
printf("FIPS mode set failure\n");
ERR_load_crypto_strings();
printf("Loaded Crypto Strings\n");
ERR_print_errors_fp(stderr);
printf("Printed Errors \n");
exit(3);
}
}
memset(encrypted, 0, sizeof(encrypted));
AES_set_encrypt_key(key, 256, &aeskey);
AES_cbc_encrypt(plaintxt, encrypted, 16, &aeskey, iv, AES_ENCRYPT);
printf("%s", encrypted);
fclose (stdout);
return(0);
}
--End C code--
I am using Visual Studio C++ to debug this program. To the search directories for include I have added C:\usr\local\ssl\include and C:\usr\local\ssl\fips-2.0\include. To the search directories for libraries I have added C:\usr\local\ssl\lib and C:\usr\local\ssl\fips-2.0\lib. To the additional dependencies I have added the paths to ssleay32.lib, libeay32.lib, and fipscanister.lib.
On running the program without the FIPS section, I get a nice encrypted message in out.txt which I am successfully able to decrypt from the command line using: openssl aes-256-cbc -d -in out.txt -K 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F -iv 000102030405060708090A0B0C0D0E0F
I took the block that calls the fips methods directly from the FIPS User Manual 2.0 and added the header files that I thought were necessary.
When I run the program as it appears here, the build is successful, but it exits with an error code of 1.
out.txt reads:
Attempting to enable FIPS MODE
FIPS mode set failure
Loaded Crypto Strings
So Fips_mode() returns 0, then FIPS_mode_set(1) returns 0, then ERR_load_crypto_strings() executes, and the program dies at ERR_print_errors_fp(stderr). It never makes it to the print statement which is directly after ERR_print_errors_fp(stderr).
I've spent days looking around online and debugging this program but, at this point, I'm stumped.