c02168c3096392ad7ccb2869d26c6907720d20b2
[openssl.git] / fips / fips_test_suite.c
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
15 #define OPENSSL_FIPSAPI
16
17 #include <stdio.h>
18 #include <assert.h>
19 #include <ctype.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <openssl/evp.h>
23 #include <openssl/hmac.h>
24 #include <openssl/sha.h>
25 #include <openssl/err.h>
26
27 #include <openssl/bn.h>
28 #include <openssl/rand.h>
29
30 #ifndef OPENSSL_FIPS
31 int main(int argc, char *argv[])
32     {
33     printf("No FIPS support\n");
34     return(0);
35     }
36 #else
37
38 #define ERR_clear_error() while(0)
39
40 #include <openssl/rsa.h>
41 #include <openssl/dsa.h>
42 #include <openssl/dh.h>
43
44 #include <openssl/fips.h>
45 #include "fips_utl.h"
46
47 /* AES: encrypt and decrypt known plaintext, verify result matches original plaintext
48 */
49 static int FIPS_aes_test(void)
50         {
51         int ret = 0;
52         unsigned char pltmp[16];
53         unsigned char citmp[16];
54         unsigned char key[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
55         unsigned char plaintext[16] = "etaonrishdlcu";
56         EVP_CIPHER_CTX ctx;
57         FIPS_cipher_ctx_init(&ctx);
58         if (FIPS_cipherinit(&ctx, EVP_aes_128_ecb(), key, NULL, 1) <= 0)
59                 goto err;
60         FIPS_cipher(&ctx, citmp, plaintext, 16);
61         if (FIPS_cipherinit(&ctx, EVP_aes_128_ecb(), key, NULL, 0) <= 0)
62                 goto err;
63         FIPS_cipher(&ctx, pltmp, citmp, 16);
64         if (memcmp(pltmp, plaintext, 16))
65                 goto err;
66         ret = 1;
67         err:
68         FIPS_cipher_ctx_cleanup(&ctx);
69         return ret;
70         }
71
72 static int FIPS_des3_test(void)
73         {
74         int ret = 0;
75         unsigned char pltmp[8];
76         unsigned char citmp[8];
77         unsigned char key[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
78                               19,20,21,22,23,24};
79         unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' };
80         EVP_CIPHER_CTX ctx;
81         FIPS_cipher_ctx_init(&ctx);
82         if (FIPS_cipherinit(&ctx, EVP_des_ede3_ecb(), key, NULL, 1) <= 0)
83                 goto err;
84         FIPS_cipher(&ctx, citmp, plaintext, 8);
85         if (FIPS_cipherinit(&ctx, EVP_des_ede3_ecb(), key, NULL, 0) <= 0)
86                 goto err;
87         FIPS_cipher(&ctx, pltmp, citmp, 8);
88         if (memcmp(pltmp, plaintext, 8))
89                 goto err;
90         ret = 1;
91         err:
92         FIPS_cipher_ctx_cleanup(&ctx);
93         return ret;
94         }
95
96 /*
97  * DSA: generate keys and sign, verify input plaintext.
98  */
99 static int FIPS_dsa_test(int bad)
100     {
101     DSA *dsa = NULL;
102     unsigned char dgst[] = "etaonrishdlc";
103     int r = 0;
104     EVP_MD_CTX mctx;
105     DSA_SIG *sig = NULL;
106
107     ERR_clear_error();
108     FIPS_md_ctx_init(&mctx);
109     dsa = FIPS_dsa_new();
110     if (!dsa)
111         goto end;
112     if (!DSA_generate_parameters_ex(dsa, 1024,NULL,0,NULL,NULL,NULL))
113         goto end;
114     if (!DSA_generate_key(dsa))
115         goto end;
116     if (bad)
117             BN_add_word(dsa->pub_key, 1);
118
119     if (!FIPS_digestinit(&mctx, EVP_sha256()))
120         goto end;
121     if (!FIPS_digestupdate(&mctx, dgst, sizeof(dgst) - 1))
122         goto end;
123     sig = FIPS_dsa_sign_ctx(dsa, &mctx);
124     if (!sig)
125         goto end;
126
127     if (!FIPS_digestinit(&mctx, EVP_sha256()))
128         goto end;
129     if (!FIPS_digestupdate(&mctx, dgst, sizeof(dgst) - 1))
130         goto end;
131     r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
132     end:
133     if (sig)
134         FIPS_dsa_sig_free(sig);
135     FIPS_md_ctx_cleanup(&mctx);
136     if (dsa)
137           FIPS_dsa_free(dsa);
138     if (r != 1)
139         return 0;
140     return 1;
141     }
142
143 /*
144  * RSA: generate keys and sign, verify input plaintext.
145  */
146 static int FIPS_rsa_test(int bad)
147     {
148     RSA *key;
149     unsigned char input_ptext[] = "etaonrishdlc";
150     unsigned char buf[256];
151     unsigned int slen;
152     BIGNUM *bn;
153     EVP_MD_CTX mctx;
154     int r = 0;
155
156     ERR_clear_error();
157     FIPS_md_ctx_init(&mctx);
158     key = FIPS_rsa_new();
159     bn = BN_new();
160     if (!key || !bn)
161         return 0;
162     BN_set_word(bn, 65537);
163     if (!RSA_generate_key_ex(key, 2048,bn,NULL))
164         return 0;
165     BN_free(bn);
166     if (bad)
167             BN_add_word(key->n, 1);
168
169     if (!FIPS_digestinit(&mctx, EVP_sha256()))
170         goto end;
171     if (!FIPS_digestupdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
172         goto end;
173     if (!FIPS_rsa_sign_ctx(key, &mctx, RSA_PKCS1_PADDING, 0, NULL, buf, &slen))
174         goto end;
175
176     if (!FIPS_digestinit(&mctx, EVP_sha256()))
177         goto end;
178     if (!FIPS_digestupdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
179         goto end;
180     r = FIPS_rsa_verify_ctx(key, &mctx, RSA_PKCS1_PADDING, 0, NULL, buf, slen);
181     end:
182     FIPS_md_ctx_cleanup(&mctx);
183     if (key)
184           FIPS_rsa_free(key);
185     if (r != 1)
186         return 0;
187     return 1;
188     }
189
190 /* SHA1: generate hash of known digest value and compare to known
191    precomputed correct hash
192 */
193 static int FIPS_sha1_test()
194     {
195     unsigned char digest[SHA_DIGEST_LENGTH] =
196         { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a, 0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 };
197     unsigned char str[] = "etaonrishd";
198
199     unsigned char md[SHA_DIGEST_LENGTH];
200
201     ERR_clear_error();
202     if (!FIPS_digest(str,sizeof(str) - 1,md, NULL, EVP_sha1())) return 0;
203     if (memcmp(md,digest,sizeof(md)))
204         return 0;
205     return 1;
206     }
207
208 /* SHA256: generate hash of known digest value and compare to known
209    precomputed correct hash
210 */
211 static int FIPS_sha256_test()
212     {
213     unsigned char digest[SHA256_DIGEST_LENGTH] =
214         {0xf5, 0x53, 0xcd, 0xb8, 0xcf, 0x1, 0xee, 0x17, 0x9b, 0x93, 0xc9, 0x68, 0xc0, 0xea, 0x40, 0x91,
215          0x6, 0xec, 0x8e, 0x11, 0x96, 0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6, 0x50, 0x4f, 0x47, 0x57};
216     unsigned char str[] = "etaonrishd";
217
218     unsigned char md[SHA256_DIGEST_LENGTH];
219
220     ERR_clear_error();
221     if (!FIPS_digest(str,sizeof(str) - 1,md, NULL, EVP_sha256())) return 0;
222     if (memcmp(md,digest,sizeof(md)))
223         return 0;
224     return 1;
225     }
226
227 /* SHA512: generate hash of known digest value and compare to known
228    precomputed correct hash
229 */
230 static int FIPS_sha512_test()
231     {
232     unsigned char digest[SHA512_DIGEST_LENGTH] =
233         {0x99, 0xc9, 0xe9, 0x5b, 0x88, 0xd4, 0x78, 0x88, 0xdf, 0x88, 0x5f, 0x94, 0x71, 0x64, 0x28, 0xca,
234          0x16, 0x1f, 0x3d, 0xf4, 0x1f, 0xf3, 0x0f, 0xc5, 0x03, 0x99, 0xb2, 0xd0, 0xe7, 0x0b, 0x94, 0x4a,
235          0x45, 0xd2, 0x6c, 0x4f, 0x20, 0x06, 0xef, 0x71, 0xa9, 0x25, 0x7f, 0x24, 0xb1, 0xd9, 0x40, 0x22,
236          0x49, 0x54, 0x10, 0xc2, 0x22, 0x9d, 0x27, 0xfe, 0xbd, 0xd6, 0xd6, 0xeb, 0x2d, 0x42, 0x1d, 0xa3};
237     unsigned char str[] = "etaonrishd";
238
239     unsigned char md[SHA512_DIGEST_LENGTH];
240
241     ERR_clear_error();
242     if (!FIPS_digest(str,sizeof(str) - 1,md, NULL, EVP_sha512())) return 0;
243     if (memcmp(md,digest,sizeof(md)))
244         return 0;
245     return 1;
246     }
247
248 /* HMAC-SHA1: generate hash of known digest value and compare to known
249    precomputed correct hash
250 */
251 static int FIPS_hmac_sha1_test()
252     {
253     unsigned char key[] = "etaonrishd";
254     unsigned char iv[] = "Sample text";
255     unsigned char kaval[EVP_MAX_MD_SIZE] =
256         {0x73, 0xf7, 0xa0, 0x48, 0xf8, 0x94, 0xed, 0xdd, 0x0a, 0xea, 0xea, 0x56, 0x1b, 0x61, 0x2e, 0x70,
257          0xb2, 0xfb, 0xec, 0xc6};
258
259     unsigned char out[EVP_MAX_MD_SIZE];
260     unsigned int outlen;
261
262     ERR_clear_error();
263     if (!HMAC(EVP_sha1(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
264     if (memcmp(out,kaval,outlen))
265         return 0;
266     return 1;
267     }
268
269 /* HMAC-SHA224: generate hash of known digest value and compare to known
270    precomputed correct hash
271 */
272 static int FIPS_hmac_sha224_test()
273     {
274     unsigned char key[] = "etaonrishd";
275     unsigned char iv[] = "Sample text";
276     unsigned char kaval[EVP_MAX_MD_SIZE] =
277         {0x75, 0x58, 0xd5, 0xbd, 0x55, 0x6d, 0x87, 0x0f, 0x75, 0xff, 0xbe, 0x1c, 0xb2, 0xf0, 0x20, 0x35,
278          0xe5, 0x62, 0x49, 0xb6, 0x94, 0xb9, 0xfc, 0x65, 0x34, 0x33, 0x3a, 0x19};
279
280     unsigned char out[EVP_MAX_MD_SIZE];
281     unsigned int outlen;
282
283     ERR_clear_error();
284     if (!HMAC(EVP_sha224(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
285     if (memcmp(out,kaval,outlen))
286         return 0;
287     return 1;
288     }
289
290 /* HMAC-SHA256: generate hash of known digest value and compare to known
291    precomputed correct hash
292 */
293 static int FIPS_hmac_sha256_test()
294     {
295     unsigned char key[] = "etaonrishd";
296     unsigned char iv[] = "Sample text";
297     unsigned char kaval[EVP_MAX_MD_SIZE] =
298         {0xe9, 0x17, 0xc1, 0x7b, 0x4c, 0x6b, 0x77, 0xda, 0xd2, 0x30, 0x36, 0x02, 0xf5, 0x72, 0x33, 0x87,
299          0x9f, 0xc6, 0x6e, 0x7b, 0x7e, 0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee, 0x51, 0xff, 0xda, 0x24, 0xf4};
300
301     unsigned char out[EVP_MAX_MD_SIZE];
302     unsigned int outlen;
303
304     ERR_clear_error();
305     if (!HMAC(EVP_sha256(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
306     if (memcmp(out,kaval,outlen))
307         return 0;
308     return 1;
309     }
310
311 /* HMAC-SHA384: generate hash of known digest value and compare to known
312    precomputed correct hash
313 */
314 static int FIPS_hmac_sha384_test()
315     {
316     unsigned char key[] = "etaonrishd";
317     unsigned char iv[] = "Sample text";
318     unsigned char kaval[EVP_MAX_MD_SIZE] =
319         {0xb2, 0x9d, 0x40, 0x58, 0x32, 0xc4, 0xe3, 0x31, 0xb6, 0x63, 0x08, 0x26, 0x99, 0xef, 0x3b, 0x10,
320          0xe2, 0xdf, 0xf8, 0xff, 0xc6, 0xe1, 0x03, 0x29, 0x81, 0x2a, 0x1b, 0xac, 0xb0, 0x07, 0x39, 0x08,
321          0xf3, 0x91, 0x35, 0x11, 0x76, 0xd6, 0x4c, 0x20, 0xfb, 0x4d, 0xc3, 0xf3, 0xb8, 0x9b, 0x88, 0x1c};
322
323     unsigned char out[EVP_MAX_MD_SIZE];
324     unsigned int outlen;
325
326     ERR_clear_error();
327     if (!HMAC(EVP_sha384(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
328     if (memcmp(out,kaval,outlen))
329         return 0;
330     return 1;
331     }
332
333 /* HMAC-SHA512: generate hash of known digest value and compare to known
334    precomputed correct hash
335 */
336 static int FIPS_hmac_sha512_test()
337     {
338     unsigned char key[] = "etaonrishd";
339     unsigned char iv[] = "Sample text";
340     unsigned char kaval[EVP_MAX_MD_SIZE] =
341         {0xcd, 0x3e, 0xb9, 0x51, 0xb8, 0xbc, 0x7f, 0x9a, 0x23, 0xaf, 0xf3, 0x77, 0x59, 0x85, 0xa9, 0xe6,
342          0xf7, 0xd1, 0x51, 0x96, 0x17, 0xe0, 0x92, 0xd8, 0xa6, 0x3b, 0xc1, 0xad, 0x7e, 0x24, 0xca, 0xb1,
343          0xd7, 0x79, 0x0a, 0xa5, 0xea, 0x2c, 0x02, 0x58, 0x0b, 0xa6, 0x52, 0x6b, 0x61, 0x7f, 0xeb, 0x9c,
344          0x47, 0x86, 0x5d, 0x74, 0x2b, 0x88, 0xdf, 0xee, 0x46, 0x69, 0x96, 0x3d, 0xa6, 0xd9, 0x2a, 0x53};
345
346     unsigned char out[EVP_MAX_MD_SIZE];
347     unsigned int outlen;
348
349     ERR_clear_error();
350     if (!HMAC(EVP_sha512(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
351     if (memcmp(out,kaval,outlen))
352         return 0;
353     return 1;
354     }
355
356
357 /* DH: generate shared parameters
358 */
359 static int dh_test()
360     {
361     DH *dh;
362     ERR_clear_error();
363     dh = FIPS_dh_new();
364     if (!dh)
365         return 0;
366     if (!DH_generate_parameters_ex(dh, 1024, 2, NULL))
367         return 0;
368     FIPS_dh_free(dh);
369     return 1;
370     }
371
372 /* Zeroize
373 */
374 static int Zeroize()
375     {
376     RSA *key;
377     BIGNUM *bn;
378     unsigned char userkey[16] = 
379         { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 };
380     size_t i;
381     int n;
382
383     key = FIPS_rsa_new();
384     bn = BN_new();
385     if (!key || !bn)
386         return 0;
387     BN_set_word(bn, 65537);
388     if (!RSA_generate_key_ex(key, 1024,bn,NULL))
389         return 0;
390     BN_free(bn);
391     
392     n = BN_num_bytes(key->d);
393     printf(" Generated %d byte RSA private key\n", n);
394     printf("\tBN key before overwriting:\n");
395     do_bn_print(stdout, key->d);
396     BN_rand(key->d,n*8,-1,0);
397     printf("\tBN key after overwriting:\n");
398     do_bn_print(stdout, key->d);
399
400     printf("\tchar buffer key before overwriting: \n\t\t");
401     for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
402         printf("\n");
403     RAND_bytes(userkey, sizeof userkey);
404     printf("\tchar buffer key after overwriting: \n\t\t");
405     for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
406         printf("\n");
407
408     return 1;
409     }
410
411 static int Error;
412 static const char * Fail(const char *msg)
413     {
414     Error++;
415     return msg; 
416     }
417
418 static void test_msg(const char *msg, int result)
419         {
420         printf("%s...%s\n", msg, result ? "successful" : Fail("Failed!"));
421         }
422
423 int main(int argc,char **argv)
424     {
425
426     int do_corrupt_rsa_keygen = 0, do_corrupt_dsa_keygen = 0;
427     int bad_rsa = 0, bad_dsa = 0;
428     int do_rng_stick = 0;
429     int no_exit = 0;
430
431     fips_set_error_print();
432
433     printf("\tFIPS-mode test application\n\n");
434
435     /* Load entropy from external file, if any */
436     RAND_load_file(".rnd", 1024);
437
438     if (argv[1]) {
439         /* Corrupted KAT tests */
440         if (!strcmp(argv[1], "aes")) {
441             FIPS_corrupt_aes();
442             printf("AES encryption/decryption with corrupted KAT...\n");
443         } else if (!strcmp(argv[1], "des")) {
444             FIPS_corrupt_des();
445             printf("DES3-ECB encryption/decryption with corrupted KAT...\n");
446         } else if (!strcmp(argv[1], "dsa")) {
447             FIPS_corrupt_dsa();
448             printf("DSA key generation and signature validation with corrupted KAT...\n");
449         } else if (!strcmp(argv[1], "rsa")) {
450             FIPS_corrupt_rsa();
451             printf("RSA key generation and signature validation with corrupted KAT...\n");
452         } else if (!strcmp(argv[1], "rsakey")) {
453             printf("RSA key generation and signature validation with corrupted key...\n");
454             bad_rsa = 1;
455             no_exit = 1;
456         } else if (!strcmp(argv[1], "rsakeygen")) {
457             do_corrupt_rsa_keygen = 1;
458             no_exit = 1;
459             printf("RSA key generation and signature validation with corrupted keygen...\n");
460         } else if (!strcmp(argv[1], "dsakey")) {
461             printf("DSA key generation and signature validation with corrupted key...\n");
462             bad_dsa = 1;
463             no_exit = 1;
464         } else if (!strcmp(argv[1], "dsakeygen")) {
465             do_corrupt_dsa_keygen = 1;
466             no_exit = 1;
467             printf("DSA key generation and signature validation with corrupted keygen...\n");
468         } else if (!strcmp(argv[1], "sha1")) {
469             FIPS_corrupt_sha1();
470             printf("SHA-1 hash with corrupted KAT...\n");
471         } else if (!strcmp(argv[1], "rng")) {
472             FIPS_corrupt_rng();
473         } else if (!strcmp(argv[1], "rngstick")) {
474             do_rng_stick = 1;
475             no_exit = 1;
476             printf("RNG test with stuck continuous test...\n");
477         } else {
478             printf("Bad argument \"%s\"\n", argv[1]);
479             exit(1);
480         }
481         if (!no_exit) {
482                 if (!FIPS_mode_set(1)) {
483                     printf("Power-up self test failed\n");
484                     exit(1);
485                 }
486                 printf("Power-up self test successful\n");
487                 exit(0);
488         }
489     }
490
491     /* Non-Approved cryptographic operation
492     */
493     printf("1. Non-Approved cryptographic operation test...\n");
494     test_msg("\ta. Included algorithm (D-H)...", dh_test());
495
496     /* Power-up self test
497     */
498     ERR_clear_error();
499     test_msg("2. Automatic power-up self test", FIPS_mode_set(1));
500     if (!FIPS_mode())
501         exit(1);
502     if (do_corrupt_dsa_keygen)
503             FIPS_corrupt_dsa_keygen();
504     if (do_corrupt_rsa_keygen)
505             FIPS_corrupt_rsa_keygen();
506     if (do_rng_stick)
507             FIPS_rng_stick();
508
509     /* AES encryption/decryption
510     */
511     test_msg("3. AES encryption/decryption", FIPS_aes_test());
512
513     /* RSA key generation and encryption/decryption
514     */
515     test_msg("4. RSA key generation and encryption/decryption",
516                                                 FIPS_rsa_test(bad_rsa));
517
518     /* DES-CBC encryption/decryption
519     */
520     test_msg("5. DES-ECB encryption/decryption", FIPS_des3_test());
521
522     /* DSA key generation and signature validation
523     */
524     test_msg("6. DSA key generation and signature validation",
525                                                 FIPS_dsa_test(bad_dsa));
526
527     /* SHA-1 hash
528     */
529     test_msg("7a. SHA-1 hash", FIPS_sha1_test());
530
531     /* SHA-256 hash
532     */
533     test_msg("7b. SHA-256 hash", FIPS_sha256_test());
534
535     /* SHA-512 hash
536     */
537     test_msg("7c. SHA-512 hash", FIPS_sha512_test());
538
539     /* HMAC-SHA-1 hash
540     */
541     test_msg("7d. HMAC-SHA-1 hash", FIPS_hmac_sha1_test());
542
543     /* HMAC-SHA-224 hash
544     */
545     test_msg("7e. HMAC-SHA-224 hash", FIPS_hmac_sha224_test());
546
547     /* HMAC-SHA-256 hash
548     */
549     test_msg("7f. HMAC-SHA-256 hash", FIPS_hmac_sha256_test());
550
551     /* HMAC-SHA-384 hash
552     */
553     test_msg("7g. HMAC-SHA-384 hash", FIPS_hmac_sha384_test());
554
555     /* HMAC-SHA-512 hash
556     */
557     test_msg("7h. HMAC-SHA-512 hash", FIPS_hmac_sha512_test());
558
559     /* Non-Approved cryptographic operation
560     */
561     printf("8. Non-Approved cryptographic operation test...\n");
562     printf("\ta. Included algorithm (D-H)...%s\n",
563                 dh_test() ? "successful as expected"
564                                                 : Fail("failed INCORRECTLY!") );
565
566     /* Zeroization
567     */
568     printf("9. Zero-ization...\n\t%s\n",
569                 Zeroize() ? "successful as expected"
570                                         : Fail("failed INCORRECTLY!") );
571
572     printf("\nAll tests completed with %d errors\n", Error);
573     return Error ? 1 : 0;
574     }
575
576 #endif