1/* ==================================================================== 2 * Copyright (c) 2003 The OpenSSL Project. All rights reserved. 3 * 4 * 5 * This command is intended as a test driver for the FIPS-140 testing 6 * lab performing FIPS-140 validation. It demonstrates the use of the 7 * OpenSSL library ito perform a variety of common cryptographic 8 * functions. A power-up self test is demonstrated by deliberately 9 * pointing to an invalid executable hash 10 * 11 * Contributed by Steve Marquess. 12 * 13 */ 14#include <stdio.h> 15#include <assert.h> 16#include <ctype.h> 17#include <string.h> 18#include <stdlib.h> 19#include <openssl/aes.h> 20#include <openssl/des.h> 21#include <openssl/rsa.h> 22#include <openssl/dsa.h> 23#include <openssl/sha.h> 24#include <openssl/md5.h> 25#include <openssl/err.h> 26#include <openssl/fips.h> 27#include <openssl/bn.h> 28#include <openssl/rand.h> 29#ifndef OPENSSL_FIPS 30int main(int argc, char *argv[]) 31 { 32 printf("No FIPS support\n"); 33 return(0); 34 } 35#else 36 37/* AES: encrypt and decrypt known plaintext, verify result matches original plaintext 38*/ 39static int FIPS_aes_test() 40 { 41 unsigned char userkey[16] = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xf0, 0x0d }; 42 unsigned char plaintext[16] = "etaonrishdlcu"; 43 unsigned char ciphertext[16]; 44 unsigned char buf[16]; 45 AES_KEY key; 46 AES_KEY dkey; 47 48 ERR_clear_error(); 49 if (AES_set_encrypt_key( userkey, 128, &key )) 50 return 0; 51 AES_encrypt( plaintext, ciphertext, &key); 52 if (AES_set_decrypt_key( userkey, 128, &dkey )) 53 return 0; 54 AES_decrypt( ciphertext, buf, &dkey); 55 if (memcmp(buf, plaintext, sizeof(buf))) 56 return 0; 57 return 1; 58 } 59 60/* DES: encrypt and decrypt known plaintext, verify result matches original plaintext 61*/ 62static int FIPS_des_test() 63 { 64 DES_cblock userkey = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xf0, 0x0d }; 65 DES_cblock plaintext = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' }; 66 67 DES_key_schedule key; 68 DES_cblock ciphertext; 69 DES_cblock buf; 70 71 ERR_clear_error(); 72 if (DES_set_key(&userkey, &key) < 0) 73 return 0; 74 DES_ecb_encrypt( &plaintext, &ciphertext, &key, 1); 75 DES_ecb_encrypt( &ciphertext, &buf, &key, 0); 76 if (memcmp(buf, plaintext, sizeof(buf))) 77 return 0; 78 return 1; 79 } 80 81/* DSA: generate key and sign a known digest, then verify the signature 82 * against the digest 83*/ 84static int FIPS_dsa_test() 85 { 86 DSA *dsa = NULL; 87 unsigned char dgst[] = "etaonrishdlc"; 88 unsigned char sig[256]; 89 unsigned int siglen; 90 91 ERR_clear_error(); 92 dsa = DSA_generate_parameters(512,NULL,0,NULL,NULL,NULL,NULL); 93 if (!dsa) 94 return 0; 95 if (!DSA_generate_key(dsa)) 96 return 0; 97 if ( DSA_sign(0,dgst,sizeof(dgst) - 1,sig,&siglen,dsa) != 1 ) 98 return 0; 99 if ( DSA_verify(0,dgst,sizeof(dgst) - 1,sig,siglen,dsa) != 1 ) 100 return 0; 101 DSA_free(dsa); 102 return 1; 103 } 104 105/* RSA: generate keys and encrypt and decrypt known plaintext, verify result 106 * matches the original plaintext 107*/ 108static int FIPS_rsa_test() 109 { 110 RSA *key; 111 unsigned char input_ptext[] = "etaonrishdlc"; 112 unsigned char ctext[256]; 113 unsigned char ptext[256]; 114 int n; 115 116 ERR_clear_error(); 117 key = RSA_generate_key(1024,65537,NULL,NULL); 118 if (!key) 119 return 0; 120 n = RSA_size(key); 121 n = RSA_public_encrypt(sizeof(input_ptext) - 1,input_ptext,ctext,key,RSA_PKCS1_PADDING); 122 if (n < 0) 123 return 0; 124 n = RSA_private_decrypt(n,ctext,ptext,key,RSA_PKCS1_PADDING); 125 if (n < 0) 126 return 0; 127 RSA_free(key); 128 if (memcmp(input_ptext,ptext,sizeof(input_ptext) - 1)) 129 return 0; 130 return 1; 131 } 132 133/* SHA1: generate hash of known digest value and compare to known 134 precomputed correct hash 135*/ 136static int FIPS_sha1_test() 137 { 138 unsigned char digest[SHA_DIGEST_LENGTH] = 139 { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a, 0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 }; 140 unsigned char str[] = "etaonrishd"; 141 142 unsigned char md[SHA_DIGEST_LENGTH]; 143 144 ERR_clear_error(); 145 if (!SHA1(str,sizeof(str) - 1,md)) return 0; 146 if (memcmp(md,digest,sizeof(md))) 147 return 0; 148 return 1; 149 } 150 151/* MD5: generate hash of known digest value and compare to known 152 precomputed correct hash 153*/ 154static int md5_test() 155 { 156 unsigned char digest[MD5_DIGEST_LENGTH] = 157 { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 }; 158 unsigned char str[] = "etaonrishd"; 159 160 unsigned char md[MD5_DIGEST_LENGTH]; 161 162 ERR_clear_error(); 163 if (!MD5(str,sizeof(str) - 1,md)) 164 return 0; 165 if (memcmp(md,digest,sizeof(md))) 166 return 0; 167 return 1; 168 } 169 170/* DH: generate shared parameters 171*/ 172static int dh_test() 173 { 174 DH *dh; 175 176 ERR_clear_error(); 177 dh = DH_generate_parameters(256, 2, NULL, NULL); 178 if (dh) 179 return 1; 180 return 0; 181 } 182 183/* Zeroize 184*/ 185static int Zeroize() 186 { 187 RSA *key; 188 unsigned char userkey[16] = 189 { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 }; 190 int i, n; 191 192 key = RSA_generate_key(1024,65537,NULL,NULL); 193 if (!key) 194 return 0; 195 n = BN_num_bytes(key->d); 196 printf(" Generated %d byte RSA private key\n", n); 197 printf("\tBN key before overwriting:\n%s\n", BN_bn2hex(key->d)); 198 BN_rand(key->d,n*8,-1,0); 199 printf("\tBN key after overwriting:\n%s\n", BN_bn2hex(key->d)); 200 201 printf("\tchar buffer key before overwriting: \n\t\t"); 202 for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]); 203 printf("\n"); 204 RAND_bytes(userkey, sizeof userkey); 205 printf("\tchar buffer key after overwriting: \n\t\t"); 206 for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]); 207 printf("\n"); 208 209 return 1; 210 } 211 212static int Error; 213const char * Fail(const char *msg) 214 { 215 Error++; 216 return msg; 217 } 218 219int main(int argc,char **argv) 220 { 221 222 printf("\tFIPS-mode test application\n\n"); 223 224 /* Load entropy from external file, if any */ 225 RAND_load_file(".rnd", 1024); 226 227 if (argv[1]) { 228 /* Corrupted KAT tests */ 229 if (!strcmp(argv[1], "aes")) { 230 FIPS_corrupt_aes(); 231 printf("3. AES encryption/decryption with corrupted KAT...\n"); 232 } else if (!strcmp(argv[1], "des")) { 233 FIPS_corrupt_des(); 234 printf("5. DES-ECB encryption/decryption with corrupted KAT...\n"); 235 } else if (!strcmp(argv[1], "dsa")) { 236 FIPS_corrupt_dsa(); 237 printf("6. DSA key generation and signature validation with corrupted KAT...\n"); 238 } else if (!strcmp(argv[1], "rsa")) { 239 FIPS_corrupt_rsa(); 240 printf("4. RSA key generation and encryption/decryption with corrupted KAT...\n"); 241 } else if (!strcmp(argv[1], "sha1")) { 242 FIPS_corrupt_sha1(); 243 printf("7. SHA-1 hash with corrupted KAT...\n"); 244 } else { 245 printf("Bad argument \"%s\"\n", argv[1]); 246 exit(1); 247 } 248 if (!FIPS_mode_set(1,argv[0])) 249 { 250 ERR_load_crypto_strings(); 251 ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE)); 252 printf("Power-up self test failed\n"); 253 exit(1); 254 } 255 printf("Power-up self test successful\n"); 256 exit(0); 257 } 258 259 /* Non-Approved cryptographic operation 260 */ 261 printf("0. Non-Approved cryptographic operation test...\n"); 262 printf("\ta. Excluded algorithm (MD5)..."); 263 printf( md5_test() ? "successful\n" : Fail("FAILED!\n") ); 264 printf("\tb. Included algorithm (D-H)..."); 265 printf( dh_test() ? "successful\n" : Fail("FAILED!\n") ); 266 267 /* Power-up self test failure 268 */ 269 printf("1. Automatic power-up self test..."); 270 printf( FIPS_mode_set(1,"/dev/null") ? Fail("passed INCORRECTLY!\n") : "failed as expected\n" ); 271 272 /* Algorithm call when uninitialized failure 273 */ 274 printf("\ta. AES API failure on failed power-up self test..."); 275 printf( FIPS_aes_test() ? Fail("passed INCORRECTLY!\n") :"failed as expected\n" ); 276 printf("\tb. RSA API failure on failed power-up self test..."); 277 printf( FIPS_rsa_test() ? Fail("passed INCORRECTLY!\n") : "failed as expected\n" ); 278 printf("\tc. DES API failure on failed power-up self test..."); 279 printf( FIPS_des_test() ? Fail("passed INCORRECTLY!\n") : "failed as expected\n" ); 280 printf("\td. DSA API failure on failed power-up self test..."); 281 printf( FIPS_dsa_test() ? Fail("passed INCORRECTLY!\n") : "failed as expected\n" ); 282 printf("\te. SHA1 API failure on failed power-up self test..."); 283 printf( FIPS_sha1_test() ? Fail("passed INCORRECTLY!\n") : "failed as expected\n" ); 284 285 /* Power-up self test retry 286 */ 287 ERR_clear_error(); 288 printf("2. Automatic power-up self test retry..."); 289 if (!FIPS_mode_set(1,argv[0])) 290 { 291 ERR_load_crypto_strings(); 292 ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE)); 293 printf(Fail("FAILED!\n")); 294 exit(1); 295 } 296 printf("successful\n"); 297 298 /* AES encryption/decryption 299 */ 300 printf("3. AES encryption/decryption..."); 301 printf( FIPS_aes_test() ? "successful\n" : Fail("FAILED!\n") ); 302 303 /* RSA key generation and encryption/decryption 304 */ 305 printf("4. RSA key generation and encryption/decryption..."); 306 printf( FIPS_rsa_test() ? "successful\n" : Fail("FAILED!\n") ); 307 308 /* DES-CBC encryption/decryption 309 */ 310 printf("5. DES-ECB encryption/decryption..."); 311 printf( FIPS_des_test() ? "successful\n" : Fail("FAILED!\n") ); 312 313 /* DSA key generation and signature validation 314 */ 315 printf("6. DSA key generation and signature validation..."); 316 printf( FIPS_dsa_test() ? "successful\n" : Fail("FAILED!\n") ); 317 318 /* SHA-1 hash 319 */ 320 printf("7. SHA-1 hash..."); 321 printf( FIPS_sha1_test() ? "successful\n" : Fail("FAILED!\n") ); 322 323 /* Non-Approved cryptographic operation 324 */ 325 printf("8. Non-Approved cryptographic operation test...\n"); 326 printf("\ta. Excluded algorithm (MD5)..."); 327 printf( md5_test() ? Fail("passed INCORRECTLY!\n") 328 : "failed as expected\n" ); 329 printf("\tb. Included algorithm (D-H)..."); 330 printf( dh_test() ? "successful as expected\n" 331 : Fail("failed INCORRECTLY!\n") ); 332 333 /* Zeroization 334 */ 335 printf("9. Zero-ization...\n"); 336 Zeroize(); 337 338 printf("\nAll tests completed with %d errors\n", Error); 339 return 0; 340 } 341#endif 342