447d1088bd8aea74d9e93d7ca8c0b9daecbee616
[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/cmac.h>
25 #include <openssl/sha.h>
26 #include <openssl/err.h>
27
28 #include <openssl/bn.h>
29 #include <openssl/rand.h>
30
31 #ifndef OPENSSL_FIPS
32 int main(int argc, char *argv[])
33     {
34     printf("No FIPS support\n");
35     return(0);
36     }
37 #else
38
39 #define ERR_clear_error() while(0)
40
41 #include <openssl/rsa.h>
42 #include <openssl/dsa.h>
43 #include <openssl/dh.h>
44
45 #include <openssl/fips.h>
46 #include <openssl/fips_rand.h>
47 #include "fips_utl.h"
48
49 /* AES: encrypt and decrypt known plaintext, verify result matches original plaintext
50 */
51 static int FIPS_aes_test(void)
52         {
53         int ret = 0;
54         unsigned char pltmp[16];
55         unsigned char citmp[16];
56         unsigned char key[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
57         unsigned char plaintext[16] = "etaonrishdlcu";
58         EVP_CIPHER_CTX ctx;
59         FIPS_cipher_ctx_init(&ctx);
60         if (FIPS_cipherinit(&ctx, EVP_aes_128_ecb(), key, NULL, 1) <= 0)
61                 goto err;
62         FIPS_cipher(&ctx, citmp, plaintext, 16);
63         if (FIPS_cipherinit(&ctx, EVP_aes_128_ecb(), key, NULL, 0) <= 0)
64                 goto err;
65         FIPS_cipher(&ctx, pltmp, citmp, 16);
66         if (memcmp(pltmp, plaintext, 16))
67                 goto err;
68         ret = 1;
69         err:
70         FIPS_cipher_ctx_cleanup(&ctx);
71         return ret;
72         }
73
74 static int FIPS_aes_gcm_test(void)
75         {
76         int ret = 0;
77         unsigned char pltmp[16];
78         unsigned char citmp[16];
79         unsigned char tagtmp[16];
80         unsigned char key[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
81         unsigned char iv[16] = {21,22,23,24,25,26,27,28,29,30,31,32};
82         unsigned char aad[] = "Some text AAD";
83         unsigned char plaintext[16] = "etaonrishdlcu";
84         EVP_CIPHER_CTX ctx;
85         FIPS_cipher_ctx_init(&ctx);
86         if (FIPS_cipherinit(&ctx, EVP_aes_128_gcm(), key, iv, 1) <= 0)
87                 goto err;
88         FIPS_cipher(&ctx, NULL, aad, sizeof(aad));
89         FIPS_cipher(&ctx, citmp, plaintext, 16);
90         FIPS_cipher(&ctx, NULL, NULL, 0);
91         if (!FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, 16, tagtmp))
92                 goto err;
93
94         if (FIPS_cipherinit(&ctx, EVP_aes_128_gcm(), key, iv, 0) <= 0)
95                 goto err;
96         if (!FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, 16, tagtmp))
97                 goto err;
98
99         FIPS_cipher(&ctx, NULL, aad, sizeof(aad));
100
101         FIPS_cipher(&ctx, pltmp, citmp, 16);
102
103         if (FIPS_cipher(&ctx, NULL, NULL, 0) < 0)
104                 goto err;
105
106         if (memcmp(pltmp, plaintext, 16))
107                 goto err;
108
109         ret = 1;
110         err:
111         FIPS_cipher_ctx_cleanup(&ctx);
112         return ret;
113         }
114
115 static int FIPS_des3_test(void)
116         {
117         int ret = 0;
118         unsigned char pltmp[8];
119         unsigned char citmp[8];
120         unsigned char key[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
121                               19,20,21,22,23,24};
122         unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' };
123         EVP_CIPHER_CTX ctx;
124         FIPS_cipher_ctx_init(&ctx);
125         if (FIPS_cipherinit(&ctx, EVP_des_ede3_ecb(), key, NULL, 1) <= 0)
126                 goto err;
127         FIPS_cipher(&ctx, citmp, plaintext, 8);
128         if (FIPS_cipherinit(&ctx, EVP_des_ede3_ecb(), key, NULL, 0) <= 0)
129                 goto err;
130         FIPS_cipher(&ctx, pltmp, citmp, 8);
131         if (memcmp(pltmp, plaintext, 8))
132                 goto err;
133         ret = 1;
134         err:
135         FIPS_cipher_ctx_cleanup(&ctx);
136         return ret;
137         }
138
139 /*
140  * DSA: generate keys and sign, verify input plaintext.
141  */
142 static int FIPS_dsa_test(int bad)
143     {
144     DSA *dsa = NULL;
145     unsigned char dgst[] = "etaonrishdlc";
146     int r = 0;
147     EVP_MD_CTX mctx;
148     DSA_SIG *sig = NULL;
149
150     ERR_clear_error();
151     FIPS_md_ctx_init(&mctx);
152     dsa = FIPS_dsa_new();
153     if (!dsa)
154         goto end;
155     if (!DSA_generate_parameters_ex(dsa, 1024,NULL,0,NULL,NULL,NULL))
156         goto end;
157     if (!DSA_generate_key(dsa))
158         goto end;
159     if (bad)
160             BN_add_word(dsa->pub_key, 1);
161
162     if (!FIPS_digestinit(&mctx, EVP_sha256()))
163         goto end;
164     if (!FIPS_digestupdate(&mctx, dgst, sizeof(dgst) - 1))
165         goto end;
166     sig = FIPS_dsa_sign_ctx(dsa, &mctx);
167     if (!sig)
168         goto end;
169
170     if (!FIPS_digestinit(&mctx, EVP_sha256()))
171         goto end;
172     if (!FIPS_digestupdate(&mctx, dgst, sizeof(dgst) - 1))
173         goto end;
174     r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
175     end:
176     if (sig)
177         FIPS_dsa_sig_free(sig);
178     FIPS_md_ctx_cleanup(&mctx);
179     if (dsa)
180           FIPS_dsa_free(dsa);
181     if (r != 1)
182         return 0;
183     return 1;
184     }
185
186 /*
187  * RSA: generate keys and sign, verify input plaintext.
188  */
189 static int FIPS_rsa_test(int bad)
190     {
191     RSA *key;
192     unsigned char input_ptext[] = "etaonrishdlc";
193     unsigned char buf[256];
194     unsigned int slen;
195     BIGNUM *bn;
196     EVP_MD_CTX mctx;
197     int r = 0;
198
199     ERR_clear_error();
200     FIPS_md_ctx_init(&mctx);
201     key = FIPS_rsa_new();
202     bn = BN_new();
203     if (!key || !bn)
204         return 0;
205     BN_set_word(bn, 65537);
206     if (!RSA_generate_key_ex(key, 2048,bn,NULL))
207         return 0;
208     BN_free(bn);
209     if (bad)
210             BN_add_word(key->n, 1);
211
212     if (!FIPS_digestinit(&mctx, EVP_sha256()))
213         goto end;
214     if (!FIPS_digestupdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
215         goto end;
216     if (!FIPS_rsa_sign_ctx(key, &mctx, RSA_PKCS1_PADDING, 0, NULL, buf, &slen))
217         goto end;
218
219     if (!FIPS_digestinit(&mctx, EVP_sha256()))
220         goto end;
221     if (!FIPS_digestupdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
222         goto end;
223     r = FIPS_rsa_verify_ctx(key, &mctx, RSA_PKCS1_PADDING, 0, NULL, buf, slen);
224     end:
225     FIPS_md_ctx_cleanup(&mctx);
226     if (key)
227           FIPS_rsa_free(key);
228     if (r != 1)
229         return 0;
230     return 1;
231     }
232
233 /* SHA1: generate hash of known digest value and compare to known
234    precomputed correct hash
235 */
236 static int FIPS_sha1_test()
237     {
238     unsigned char digest[SHA_DIGEST_LENGTH] =
239         { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a, 0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 };
240     unsigned char str[] = "etaonrishd";
241
242     unsigned char md[SHA_DIGEST_LENGTH];
243
244     ERR_clear_error();
245     if (!FIPS_digest(str,sizeof(str) - 1,md, NULL, EVP_sha1())) return 0;
246     if (memcmp(md,digest,sizeof(md)))
247         return 0;
248     return 1;
249     }
250
251 /* SHA256: generate hash of known digest value and compare to known
252    precomputed correct hash
253 */
254 static int FIPS_sha256_test()
255     {
256     unsigned char digest[SHA256_DIGEST_LENGTH] =
257         {0xf5, 0x53, 0xcd, 0xb8, 0xcf, 0x1, 0xee, 0x17, 0x9b, 0x93, 0xc9, 0x68, 0xc0, 0xea, 0x40, 0x91,
258          0x6, 0xec, 0x8e, 0x11, 0x96, 0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6, 0x50, 0x4f, 0x47, 0x57};
259     unsigned char str[] = "etaonrishd";
260
261     unsigned char md[SHA256_DIGEST_LENGTH];
262
263     ERR_clear_error();
264     if (!FIPS_digest(str,sizeof(str) - 1,md, NULL, EVP_sha256())) return 0;
265     if (memcmp(md,digest,sizeof(md)))
266         return 0;
267     return 1;
268     }
269
270 /* SHA512: generate hash of known digest value and compare to known
271    precomputed correct hash
272 */
273 static int FIPS_sha512_test()
274     {
275     unsigned char digest[SHA512_DIGEST_LENGTH] =
276         {0x99, 0xc9, 0xe9, 0x5b, 0x88, 0xd4, 0x78, 0x88, 0xdf, 0x88, 0x5f, 0x94, 0x71, 0x64, 0x28, 0xca,
277          0x16, 0x1f, 0x3d, 0xf4, 0x1f, 0xf3, 0x0f, 0xc5, 0x03, 0x99, 0xb2, 0xd0, 0xe7, 0x0b, 0x94, 0x4a,
278          0x45, 0xd2, 0x6c, 0x4f, 0x20, 0x06, 0xef, 0x71, 0xa9, 0x25, 0x7f, 0x24, 0xb1, 0xd9, 0x40, 0x22,
279          0x49, 0x54, 0x10, 0xc2, 0x22, 0x9d, 0x27, 0xfe, 0xbd, 0xd6, 0xd6, 0xeb, 0x2d, 0x42, 0x1d, 0xa3};
280     unsigned char str[] = "etaonrishd";
281
282     unsigned char md[SHA512_DIGEST_LENGTH];
283
284     ERR_clear_error();
285     if (!FIPS_digest(str,sizeof(str) - 1,md, NULL, EVP_sha512())) return 0;
286     if (memcmp(md,digest,sizeof(md)))
287         return 0;
288     return 1;
289     }
290
291 /* HMAC-SHA1: generate hash of known digest value and compare to known
292    precomputed correct hash
293 */
294 static int FIPS_hmac_sha1_test()
295     {
296     unsigned char key[] = "etaonrishd";
297     unsigned char iv[] = "Sample text";
298     unsigned char kaval[EVP_MAX_MD_SIZE] =
299         {0x73, 0xf7, 0xa0, 0x48, 0xf8, 0x94, 0xed, 0xdd, 0x0a, 0xea, 0xea, 0x56, 0x1b, 0x61, 0x2e, 0x70,
300          0xb2, 0xfb, 0xec, 0xc6};
301
302     unsigned char out[EVP_MAX_MD_SIZE];
303     unsigned int outlen;
304
305     ERR_clear_error();
306     if (!HMAC(EVP_sha1(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
307     if (memcmp(out,kaval,outlen))
308         return 0;
309     return 1;
310     }
311
312 /* HMAC-SHA224: generate hash of known digest value and compare to known
313    precomputed correct hash
314 */
315 static int FIPS_hmac_sha224_test()
316     {
317     unsigned char key[] = "etaonrishd";
318     unsigned char iv[] = "Sample text";
319     unsigned char kaval[EVP_MAX_MD_SIZE] =
320         {0x75, 0x58, 0xd5, 0xbd, 0x55, 0x6d, 0x87, 0x0f, 0x75, 0xff, 0xbe, 0x1c, 0xb2, 0xf0, 0x20, 0x35,
321          0xe5, 0x62, 0x49, 0xb6, 0x94, 0xb9, 0xfc, 0x65, 0x34, 0x33, 0x3a, 0x19};
322
323     unsigned char out[EVP_MAX_MD_SIZE];
324     unsigned int outlen;
325
326     ERR_clear_error();
327     if (!HMAC(EVP_sha224(),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-SHA256: generate hash of known digest value and compare to known
334    precomputed correct hash
335 */
336 static int FIPS_hmac_sha256_test()
337     {
338     unsigned char key[] = "etaonrishd";
339     unsigned char iv[] = "Sample text";
340     unsigned char kaval[EVP_MAX_MD_SIZE] =
341         {0xe9, 0x17, 0xc1, 0x7b, 0x4c, 0x6b, 0x77, 0xda, 0xd2, 0x30, 0x36, 0x02, 0xf5, 0x72, 0x33, 0x87,
342          0x9f, 0xc6, 0x6e, 0x7b, 0x7e, 0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee, 0x51, 0xff, 0xda, 0x24, 0xf4};
343
344     unsigned char out[EVP_MAX_MD_SIZE];
345     unsigned int outlen;
346
347     ERR_clear_error();
348     if (!HMAC(EVP_sha256(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
349     if (memcmp(out,kaval,outlen))
350         return 0;
351     return 1;
352     }
353
354 /* HMAC-SHA384: generate hash of known digest value and compare to known
355    precomputed correct hash
356 */
357 static int FIPS_hmac_sha384_test()
358     {
359     unsigned char key[] = "etaonrishd";
360     unsigned char iv[] = "Sample text";
361     unsigned char kaval[EVP_MAX_MD_SIZE] =
362         {0xb2, 0x9d, 0x40, 0x58, 0x32, 0xc4, 0xe3, 0x31, 0xb6, 0x63, 0x08, 0x26, 0x99, 0xef, 0x3b, 0x10,
363          0xe2, 0xdf, 0xf8, 0xff, 0xc6, 0xe1, 0x03, 0x29, 0x81, 0x2a, 0x1b, 0xac, 0xb0, 0x07, 0x39, 0x08,
364          0xf3, 0x91, 0x35, 0x11, 0x76, 0xd6, 0x4c, 0x20, 0xfb, 0x4d, 0xc3, 0xf3, 0xb8, 0x9b, 0x88, 0x1c};
365
366     unsigned char out[EVP_MAX_MD_SIZE];
367     unsigned int outlen;
368
369     ERR_clear_error();
370     if (!HMAC(EVP_sha384(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
371     if (memcmp(out,kaval,outlen))
372         return 0;
373     return 1;
374     }
375
376 /* HMAC-SHA512: generate hash of known digest value and compare to known
377    precomputed correct hash
378 */
379 static int FIPS_hmac_sha512_test()
380     {
381     unsigned char key[] = "etaonrishd";
382     unsigned char iv[] = "Sample text";
383     unsigned char kaval[EVP_MAX_MD_SIZE] =
384         {0xcd, 0x3e, 0xb9, 0x51, 0xb8, 0xbc, 0x7f, 0x9a, 0x23, 0xaf, 0xf3, 0x77, 0x59, 0x85, 0xa9, 0xe6,
385          0xf7, 0xd1, 0x51, 0x96, 0x17, 0xe0, 0x92, 0xd8, 0xa6, 0x3b, 0xc1, 0xad, 0x7e, 0x24, 0xca, 0xb1,
386          0xd7, 0x79, 0x0a, 0xa5, 0xea, 0x2c, 0x02, 0x58, 0x0b, 0xa6, 0x52, 0x6b, 0x61, 0x7f, 0xeb, 0x9c,
387          0x47, 0x86, 0x5d, 0x74, 0x2b, 0x88, 0xdf, 0xee, 0x46, 0x69, 0x96, 0x3d, 0xa6, 0xd9, 0x2a, 0x53};
388
389     unsigned char out[EVP_MAX_MD_SIZE];
390     unsigned int outlen;
391
392     ERR_clear_error();
393     if (!HMAC(EVP_sha512(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
394     if (memcmp(out,kaval,outlen))
395         return 0;
396     return 1;
397     }
398
399 /* CMAC-AES128: generate hash of known digest value and compare to known
400    precomputed correct hash
401 */
402 static int FIPS_cmac_aes128_test()
403     {
404     unsigned char key[16] = { 0x2b,0x7e,0x15,0x16, 0x28,0xae,0xd2,0xa6,
405                               0xab,0xf7,0x15,0x88, 0x09,0xcf,0x4f,0x3c, };
406     unsigned char data[] = "Sample text";
407     unsigned char kaval[EVP_MAX_MD_SIZE] =
408             { 0x16,0x83,0xfe,0xac, 0x52,0x9b,0xae,0x23,
409               0xd7,0xd5,0x66,0xf5, 0xd2,0x8d,0xbd,0x2a, };
410
411     unsigned char *out = NULL;
412     size_t outlen;
413     CMAC_CTX *ctx = CMAC_CTX_new();
414     int r = 0;
415
416     ERR_clear_error();
417
418     if (!ctx)
419             goto end;
420     if (!CMAC_Init(ctx,key,sizeof(key),EVP_aes_128_cbc(),NULL))
421             goto end;
422     if (!CMAC_Update(ctx,data,sizeof(data)-1))
423             goto end;
424     /* This should return 1.  If not, there's a programming error... */
425     if (!CMAC_Final(ctx, out, &outlen))
426             goto end;
427     out = OPENSSL_malloc(outlen);
428     if (!CMAC_Final(ctx, out, &outlen))
429             goto end;
430 #if 0
431     {
432     char *hexout = OPENSSL_malloc(outlen * 2 + 1);
433     bin2hex(out, outlen, hexout);
434     printf("CMAC-AES128: res = %s\n", hexout);
435     OPENSSL_free(hexout);
436     }
437     r = 1;
438 #else
439     if (!memcmp(out,kaval,outlen))
440             r = 1;
441 #endif
442     end:
443     CMAC_CTX_free(ctx);
444     if (out)
445           OPENSSL_free(out);
446     return r;
447     }
448
449 /* CMAC-AES192: generate hash of known digest value and compare to known
450    precomputed correct hash
451 */
452 static int FIPS_cmac_aes192_test()
453     {
454     unsigned char key[] = { 0x8e,0x73,0xb0,0xf7, 0xda,0x0e,0x64,0x52,
455                             0xc8,0x10,0xf3,0x2b, 0x80,0x90,0x79,0xe5,
456                             0x62,0xf8,0xea,0xd2, 0x52,0x2c,0x6b,0x7b, };
457     unsigned char data[] = "Sample text";
458     unsigned char kaval[] =
459             { 0xd6,0x99,0x19,0x25, 0xe5,0x1d,0x95,0x48,
460               0xb1,0x4a,0x0b,0xf2, 0xc6,0x3c,0x47,0x1f, };
461
462     unsigned char *out = NULL;
463     size_t outlen;
464     CMAC_CTX *ctx = CMAC_CTX_new();
465     int r = 0;
466
467     ERR_clear_error();
468
469     if (!ctx)
470             goto end;
471     if (!CMAC_Init(ctx,key,sizeof(key),EVP_aes_192_cbc(),NULL))
472             goto end;
473     if (!CMAC_Update(ctx,data,sizeof(data)-1))
474             goto end;
475     /* This should return 1.  If not, there's a programming error... */
476     if (!CMAC_Final(ctx, out, &outlen))
477             goto end;
478     out = OPENSSL_malloc(outlen);
479     if (!CMAC_Final(ctx, out, &outlen))
480             goto end;
481 #if 0
482     {
483     char *hexout = OPENSSL_malloc(outlen * 2 + 1);
484     bin2hex(out, outlen, hexout);
485     printf("CMAC-AES192: res = %s\n", hexout);
486     OPENSSL_free(hexout);
487     }
488     r = 1;
489 #else
490     if (!memcmp(out,kaval,outlen))
491             r = 1;
492 #endif
493     end:
494     CMAC_CTX_free(ctx);
495     if (out)
496           OPENSSL_free(out);
497     return r;
498     }
499
500 /* CMAC-AES256: generate hash of known digest value and compare to known
501    precomputed correct hash
502 */
503 static int FIPS_cmac_aes256_test()
504     {
505     unsigned char key[] = { 0x60,0x3d,0xeb,0x10, 0x15,0xca,0x71,0xbe,
506                             0x2b,0x73,0xae,0xf0, 0x85,0x7d,0x77,0x81,
507                             0x1f,0x35,0x2c,0x07, 0x3b,0x61,0x08,0xd7,
508                             0x2d,0x98,0x10,0xa3, 0x09,0x14,0xdf,0xf4, };
509     unsigned char data[] = "Sample text";
510     unsigned char kaval[] =
511             { 0xec,0xc2,0xcf,0x63, 0xc7,0xce,0xfc,0xa4,
512               0xb0,0x86,0x37,0x5f, 0x15,0x60,0xba,0x1f, };
513
514     unsigned char *out = NULL;
515     size_t outlen;
516     CMAC_CTX *ctx = CMAC_CTX_new();
517     int r = 0;
518
519     ERR_clear_error();
520
521     if (!ctx)
522             goto end;
523     if (!CMAC_Init(ctx,key,sizeof(key),EVP_aes_256_cbc(),NULL))
524             goto end;
525     if (!CMAC_Update(ctx,data,sizeof(data)-1))
526             goto end;
527     /* This should return 1.  If not, there's a programming error... */
528     if (!CMAC_Final(ctx, out, &outlen))
529             goto end;
530     out = OPENSSL_malloc(outlen);
531     if (!CMAC_Final(ctx, out, &outlen))
532             goto end;
533 #if 0
534     {
535     char *hexout = OPENSSL_malloc(outlen * 2 + 1);
536     bin2hex(out, outlen, hexout);
537     printf("CMAC-AES256: res = %s\n", hexout);
538     OPENSSL_free(hexout);
539     }
540     r = 1;
541 #else
542     if (!memcmp(out,kaval,outlen))
543             r = 1;
544 #endif
545     end:
546     CMAC_CTX_free(ctx);
547     if (out)
548           OPENSSL_free(out);
549     return r;
550     }
551
552 /* CMAC-TDEA3: generate hash of known digest value and compare to known
553    precomputed correct hash
554 */
555 static int FIPS_cmac_tdea3_test()
556     {
557     unsigned char key[] = { 0x8a,0xa8,0x3b,0xf8, 0xcb,0xda,0x10,0x62,
558                             0x0b,0xc1,0xbf,0x19, 0xfb,0xb6,0xcd,0x58,
559                             0xbc,0x31,0x3d,0x4a, 0x37,0x1c,0xa8,0xb5, };
560     unsigned char data[] = "Sample text";
561     unsigned char kaval[EVP_MAX_MD_SIZE] =
562             { 0xb4,0x06,0x4e,0xbf, 0x59,0x89,0xba,0x68, };
563
564     unsigned char *out = NULL;
565     size_t outlen;
566     CMAC_CTX *ctx = CMAC_CTX_new();
567     int r = 0;
568
569     ERR_clear_error();
570
571     if (!ctx)
572             goto end;
573     if (!CMAC_Init(ctx,key,sizeof(key),EVP_des_ede3_cbc(),NULL))
574             goto end;
575     if (!CMAC_Update(ctx,data,sizeof(data)-1))
576             goto end;
577     /* This should return 1.  If not, there's a programming error... */
578     if (!CMAC_Final(ctx, out, &outlen))
579             goto end;
580     out = OPENSSL_malloc(outlen);
581     if (!CMAC_Final(ctx, out, &outlen))
582             goto end;
583 #if 0
584     {
585     char *hexout = OPENSSL_malloc(outlen * 2 + 1);
586     bin2hex(out, outlen, hexout);
587     printf("CMAC-TDEA3: res = %s\n", hexout);
588     OPENSSL_free(hexout);
589     }
590     r = 1;
591 #else
592     if (!memcmp(out,kaval,outlen))
593             r = 1;
594 #endif
595     end:
596     CMAC_CTX_free(ctx);
597     if (out)
598           OPENSSL_free(out);
599     return r;
600     }
601
602
603 /* DH: generate shared parameters
604 */
605 static int dh_test()
606     {
607     DH *dh;
608     ERR_clear_error();
609     dh = FIPS_dh_new();
610     if (!dh)
611         return 0;
612     if (!DH_generate_parameters_ex(dh, 1024, 2, NULL))
613         return 0;
614     FIPS_dh_free(dh);
615     return 1;
616     }
617
618 /* Zeroize
619 */
620 static int Zeroize()
621     {
622     RSA *key;
623     BIGNUM *bn;
624     unsigned char userkey[16] = 
625         { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 };
626     size_t i;
627     int n;
628
629     key = FIPS_rsa_new();
630     bn = BN_new();
631     if (!key || !bn)
632         return 0;
633     BN_set_word(bn, 65537);
634     if (!RSA_generate_key_ex(key, 1024,bn,NULL))
635         return 0;
636     BN_free(bn);
637     
638     n = BN_num_bytes(key->d);
639     printf(" Generated %d byte RSA private key\n", n);
640     printf("\tBN key before overwriting:\n");
641     do_bn_print(stdout, key->d);
642     BN_rand(key->d,n*8,-1,0);
643     printf("\tBN key after overwriting:\n");
644     do_bn_print(stdout, key->d);
645
646     printf("\tchar buffer key before overwriting: \n\t\t");
647     for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
648         printf("\n");
649     RAND_bytes(userkey, sizeof userkey);
650     printf("\tchar buffer key after overwriting: \n\t\t");
651     for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
652         printf("\n");
653
654     return 1;
655     }
656
657 /* Dummy Entropy for DRBG tests. WARNING: THIS IS TOTALLY BOGUS
658  * HAS ZERO SECURITY AND MUST NOT BE USED IN REAL APPLICATIONS.
659  */
660
661 static unsigned char dummy_drbg_entropy[1024];
662
663 static size_t drbg_test_cb(DRBG_CTX *ctx, unsigned char **pout,
664                                 int entropy, size_t min_len, size_t max_len)
665         {
666         *pout = dummy_drbg_entropy;
667         /* Round up to multiple of block size */
668         return (min_len + 0xf) & ~0xf;
669         }
670
671 /* DRBG test: just generate lots of data and trigger health checks */
672
673 static int do_drbg_test(int type, int flags)
674     {
675     DRBG_CTX *dctx;
676     int rv = 0;
677     size_t i;
678     unsigned char randout[1024];
679     dctx = FIPS_drbg_new(type, flags);
680     if (!dctx)
681         return 0;
682     FIPS_drbg_set_callbacks(dctx, drbg_test_cb, 0, 0x10, drbg_test_cb, 0);
683     for (i = 0; i < sizeof(dummy_drbg_entropy); i++)
684         {
685         dummy_drbg_entropy[i] = i & 0xff;
686         }
687     if (!FIPS_drbg_instantiate(dctx, dummy_drbg_entropy, 10))
688         goto err;
689     FIPS_drbg_set_check_interval(dctx, 10);
690     for (i = 0; i < 32; i++)
691         {
692         if (!FIPS_drbg_generate(dctx, randout, sizeof(randout), 0, NULL, 0))
693                 goto err;
694         if (!FIPS_drbg_generate(dctx, randout, sizeof(randout), 0, dummy_drbg_entropy, 1))
695                 goto err;
696         }
697     rv = 1;
698     err:
699     FIPS_drbg_uninstantiate(dctx);
700     return rv;
701     }
702
703 typedef struct 
704     {
705     int type, flags;
706     } DRBG_LIST;
707
708 static int do_drbg_all(void)
709     {
710     static DRBG_LIST drbg_types[] =
711         {
712                 {NID_sha1, 0},
713                 {NID_sha224, 0},
714                 {NID_sha256, 0},
715                 {NID_sha384, 0},
716                 {NID_sha512, 0},
717                 {NID_hmacWithSHA1, 0},
718                 {NID_hmacWithSHA224, 0},
719                 {NID_hmacWithSHA256, 0},
720                 {NID_hmacWithSHA384, 0},
721                 {NID_hmacWithSHA512, 0},
722                 {NID_aes_128_ctr, 0},
723                 {NID_aes_192_ctr, 0},
724                 {NID_aes_256_ctr, 0},
725                 {NID_aes_128_ctr, DRBG_FLAG_CTR_USE_DF},
726                 {NID_aes_192_ctr, DRBG_FLAG_CTR_USE_DF},
727                 {NID_aes_256_ctr, DRBG_FLAG_CTR_USE_DF},
728                 {(NID_X9_62_prime256v1 << 16)|NID_sha1, 0},
729                 {(NID_X9_62_prime256v1 << 16)|NID_sha224, 0},
730                 {(NID_X9_62_prime256v1 << 16)|NID_sha256, 0},
731                 {(NID_X9_62_prime256v1 << 16)|NID_sha384, 0},
732                 {(NID_X9_62_prime256v1 << 16)|NID_sha512, 0},
733                 {(NID_secp384r1 << 16)|NID_sha224, 0},
734                 {(NID_secp384r1 << 16)|NID_sha256, 0},
735                 {(NID_secp384r1 << 16)|NID_sha384, 0},
736                 {(NID_secp384r1 << 16)|NID_sha512, 0},
737                 {(NID_secp521r1 << 16)|NID_sha256, 0},
738                 {(NID_secp521r1 << 16)|NID_sha384, 0},
739                 {(NID_secp521r1 << 16)|NID_sha512, 0},
740                 {0, 0}
741         };
742     DRBG_LIST *lst;
743     int rv = 1;
744     for (lst = drbg_types;; lst++)
745         {
746         if (lst->type == 0)
747                 break;
748         if (!do_drbg_test(lst->type, lst->flags))
749                 rv = 0;
750         }
751     return rv;
752     }
753
754 static int Error;
755 static const char * Fail(const char *msg)
756     {
757     Error++;
758     return msg; 
759     }
760
761 static void test_msg(const char *msg, int result)
762         {
763         printf("%s...%s\n", msg, result ? "successful" : Fail("Failed!"));
764         }
765
766 /* Table of IDs for POST translating between NIDs and names */
767
768 typedef struct 
769         {
770         int id;
771         const char *name;
772         } POST_ID;
773
774 POST_ID id_list[] = {
775         {NID_sha1, "SHA1"},
776         {NID_sha224, "SHA224"},
777         {NID_sha256, "SHA256"},
778         {NID_sha384, "SHA384"},
779         {NID_sha512, "SHA512"},
780         {NID_hmacWithSHA1, "HMAC-SHA1"},
781         {NID_hmacWithSHA224, "HMAC-SHA224"},
782         {NID_hmacWithSHA256, "HMAC-SHA256"},
783         {NID_hmacWithSHA384, "HMAC-SHA384"},
784         {NID_hmacWithSHA512, "HMAC-SHA512"},
785         {EVP_PKEY_RSA, "RSA"},
786         {EVP_PKEY_DSA, "DSA"},
787         {EVP_PKEY_EC, "ECDSA"},
788         {NID_aes_128_cbc, "AES-128-CBC"},
789         {NID_aes_192_cbc, "AES-192-CBC"},
790         {NID_aes_256_cbc, "AES-256-CBC"},
791         {NID_aes_128_ctr, "AES-128-CTR"},
792         {NID_aes_192_ctr, "AES-192-CTR"},
793         {NID_aes_256_ctr, "AES-256-CTR"},
794         {NID_aes_128_ecb, "AES-128-ECB"},
795         {NID_aes_128_xts, "AES-128-XTS"},
796         {NID_aes_256_xts, "AES-256-XTS"},
797         {NID_des_ede3_cbc, "DES-EDE3-CBC"},
798         {NID_des_ede3_ecb, "DES-EDE3-ECB"},
799         {NID_X9_62_prime256v1, "P-256"},
800         {NID_secp384r1, "P-384"},
801         {NID_secp521r1, "P-521"},
802         {0, NULL}
803 };
804
805 static const char *lookup_id(int id)
806         {
807         POST_ID *n;
808         static char out[40];
809         for (n = id_list; n->name; n++)
810                 {
811                 if (n->id == id)
812                         return n->name;
813                 }
814         sprintf(out, "ID=%d", id);
815         return out;
816         }
817
818 static int fail_id = -1;
819 static int fail_sub = -1;
820 static int fail_key = -1;
821
822 static int post_cb(int op, int id, int subid, void *ex)
823         {
824         const char *idstr, *exstr = "";
825         char asctmp[20];
826         int keytype = -1;
827 #ifdef FIPS_POST_TIME
828         static struct timespec start, end, tstart, tend;
829 #endif
830         switch(id)
831                 {
832                 case FIPS_TEST_INTEGRITY:
833                 idstr = "Integrity";
834                 break;
835
836                 case FIPS_TEST_DIGEST:
837                 idstr = "Digest";
838                 exstr = lookup_id(subid);
839                 break;
840
841                 case FIPS_TEST_CIPHER:
842                 exstr = lookup_id(subid);
843                 idstr = "Cipher";
844                 break;
845
846                 case FIPS_TEST_SIGNATURE:
847                 if (ex)
848                         {
849                         EVP_PKEY *pkey = ex;
850                         keytype = pkey->type;
851                         exstr = lookup_id(keytype);
852                         }
853                 idstr = "Signature";
854                 break;
855
856                 case FIPS_TEST_HMAC:
857                 exstr = lookup_id(subid);
858                 idstr = "HMAC";
859                 break;
860
861                 case FIPS_TEST_CMAC:
862                 idstr = "CMAC";
863                 exstr = lookup_id(subid);
864                 break;
865
866                 case FIPS_TEST_GCM:
867                 idstr = "GCM";
868                 break;
869
870                 case FIPS_TEST_XTS:
871                 idstr = "XTS";
872                 exstr = lookup_id(subid);
873                 break;
874
875                 case FIPS_TEST_CCM:
876                 idstr = "CCM";
877                 break;
878
879                 case FIPS_TEST_X931:
880                 idstr = "X9.31 PRNG";
881                 sprintf(asctmp, "keylen=%d", subid);
882                 exstr = asctmp;
883                 break;
884
885                 case FIPS_TEST_DRBG:
886                 idstr = "DRBG";
887                 if (*(int *)ex & DRBG_FLAG_CTR_USE_DF)
888                         {
889                         sprintf(asctmp, "%s DF", lookup_id(subid));
890                         exstr = asctmp;
891                         }
892                 else if (subid >> 16)
893                         {
894                         sprintf(asctmp, "%s %s",
895                                         lookup_id(subid >> 16),
896                                         lookup_id(subid & 0xFFFF));
897                         exstr = asctmp;
898                         }
899                 else
900                         exstr = lookup_id(subid);
901                 break;
902
903                 case FIPS_TEST_PAIRWISE:
904                 if (ex)
905                         {
906                         EVP_PKEY *pkey = ex;
907                         keytype = pkey->type;
908                         exstr = lookup_id(keytype);
909                         }
910                 idstr = "Pairwise Consistency";
911                 break;
912
913                 case FIPS_TEST_CONTINUOUS:
914                 idstr = "Continuous PRNG";
915                 break;
916
917                 default:
918                 idstr = "Unknown";
919                 break;
920
921                 }
922
923         switch(op)
924                 {
925                 case FIPS_POST_BEGIN:
926 #ifdef FIPS_POST_TIME
927                 clock_getres(CLOCK_REALTIME, &tstart);
928                 printf("\tTimer resolution %ld s, %ld ns\n",
929                                 (long)tstart.tv_sec, (long)tstart.tv_nsec);
930                 clock_gettime(CLOCK_REALTIME, &tstart);
931 #endif
932                 printf("\tPOST started\n");
933                 break;
934
935                 case FIPS_POST_END:
936                 printf("\tPOST %s\n", id ? "Success" : "Failed");
937 #ifdef FIPS_POST_TIME
938                 clock_gettime(CLOCK_REALTIME, &tend);
939                 printf("\t\tTook %f seconds\n",
940                         (double)((tend.tv_sec+tend.tv_nsec*1e-9)
941                         - (tstart.tv_sec+tstart.tv_nsec*1e-9)));
942 #endif
943                 break;
944
945                 case FIPS_POST_STARTED:
946                 printf("\t\t%s %s test started\n", idstr, exstr);
947 #ifdef FIPS_POST_TIME
948                 clock_gettime(CLOCK_REALTIME, &start);
949 #endif
950                 break;
951
952                 case FIPS_POST_SUCCESS:
953                 printf("\t\t%s %s test OK\n", idstr, exstr);
954 #ifdef FIPS_POST_TIME
955                 clock_gettime(CLOCK_REALTIME, &end);
956                 printf("\t\t\tTook %f seconds\n",
957                         (double)((end.tv_sec+end.tv_nsec*1e-9)
958                         - (start.tv_sec+start.tv_nsec*1e-9)));
959 #endif
960                 break;
961
962                 case FIPS_POST_FAIL:
963                 printf("\t\t%s %s test FAILED!!\n", idstr, exstr);
964                 break;
965
966                 case FIPS_POST_CORRUPT:
967                 if (fail_id == id
968                         && (fail_key == -1 || fail_key == keytype)
969                         && (fail_sub == -1 || fail_sub == subid))
970                         {
971                         printf("\t\t%s %s test failure induced\n", idstr, exstr);
972                         return 0;
973                         }
974                 break;
975
976                 }
977         return 1;
978         }
979
980 int main(int argc,char **argv)
981     {
982     int bad_rsa = 0, bad_dsa = 0;
983     int do_rng_stick = 0;
984     int do_drbg_stick = 0;
985     int no_exit = 0;
986     int no_dh = 0;
987
988     FIPS_post_set_callback(post_cb);
989
990     printf("\tFIPS-mode test application\n");
991
992     printf("\t%s\n\n", FIPS_module_version_text());
993
994     if (argv[1]) {
995         /* Corrupted KAT tests */
996         if (!strcmp(argv[1], "integrity")) {
997             fail_id = FIPS_TEST_INTEGRITY;
998         } else if (!strcmp(argv[1], "aes")) {
999             fail_id = FIPS_TEST_CIPHER;
1000             fail_sub = NID_aes_128_ecb; 
1001         } else if (!strcmp(argv[1], "aes-ccm")) {
1002             fail_id = FIPS_TEST_CCM;
1003         } else if (!strcmp(argv[1], "aes-gcm")) {
1004             fail_id = FIPS_TEST_GCM;
1005         } else if (!strcmp(argv[1], "aes-xts")) {
1006             fail_id = FIPS_TEST_XTS;
1007         } else if (!strcmp(argv[1], "des")) {
1008             fail_id = FIPS_TEST_CIPHER;
1009             fail_sub = NID_des_ede3_ecb;        
1010         } else if (!strcmp(argv[1], "dsa")) {
1011             fail_id = FIPS_TEST_SIGNATURE;
1012             fail_key = EVP_PKEY_DSA;    
1013         } else if (!strcmp(argv[1], "ecdsa")) {
1014             fail_id = FIPS_TEST_SIGNATURE;
1015             fail_key = EVP_PKEY_EC;     
1016         } else if (!strcmp(argv[1], "rsa")) {
1017             fail_id = FIPS_TEST_SIGNATURE;
1018             fail_key = EVP_PKEY_RSA;    
1019         } else if (!strcmp(argv[1], "rsakey")) {
1020             printf("RSA key generation and signature validation with corrupted key...\n");
1021             bad_rsa = 1;
1022             no_exit = 1;
1023         } else if (!strcmp(argv[1], "rsakeygen")) {
1024             fail_id = FIPS_TEST_PAIRWISE;
1025             fail_key = EVP_PKEY_RSA;
1026             no_exit = 1;
1027         } else if (!strcmp(argv[1], "dsakey")) {
1028             printf("DSA key generation and signature validation with corrupted key...\n");
1029             bad_dsa = 1;
1030             no_exit = 1;
1031         } else if (!strcmp(argv[1], "dsakeygen")) {
1032             fail_id = FIPS_TEST_PAIRWISE;
1033             fail_key = EVP_PKEY_DSA;
1034             no_exit = 1;
1035         } else if (!strcmp(argv[1], "sha1")) {
1036             fail_id = FIPS_TEST_DIGEST;
1037         } else if (!strcmp(argv[1], "hmac")) {
1038             fail_id = FIPS_TEST_HMAC;
1039         } else if (!strcmp(argv[1], "cmac")) {
1040             fail_id = FIPS_TEST_CMAC;
1041         } else if (!strcmp(argv[1], "drbg")) {
1042             fail_id = FIPS_TEST_DRBG;
1043         } else if (!strcmp(argv[1], "rng")) {
1044             fail_id = FIPS_TEST_X931;
1045         } else if (!strcmp(argv[1], "nodh")) {
1046             no_dh = 1;
1047             no_exit = 1;
1048         } else if (!strcmp(argv[1], "post")) {
1049             fail_id = -1;
1050         } else if (!strcmp(argv[1], "rngstick")) {
1051             do_rng_stick = 1;
1052             no_exit = 1;
1053             printf("RNG test with stuck continuous test...\n");
1054         } else if (!strcmp(argv[1], "drbgentstick")) {
1055                 do_entropy_stick();
1056         } else if (!strcmp(argv[1], "drbgstick")) {
1057             do_drbg_stick = 1;
1058             no_exit = 1;
1059             printf("DRBG test with stuck continuous test...\n");
1060         } else {
1061             printf("Bad argument \"%s\"\n", argv[1]);
1062             exit(1);
1063         }
1064         if (!no_exit) {
1065                 fips_algtest_init_nofips();
1066                 if (!FIPS_module_mode_set(1)) {
1067                     printf("Power-up self test failed\n");
1068                     exit(1);
1069                 }
1070                 printf("Power-up self test successful\n");
1071                 exit(0);
1072         }
1073     }
1074
1075     fips_algtest_init_nofips();
1076
1077     /* Non-Approved cryptographic operation
1078     */
1079     printf("1. Non-Approved cryptographic operation test...\n");
1080     if (no_dh)
1081         printf("\t D-H test skipped\n");
1082     else
1083         test_msg("\ta. Included algorithm (D-H)...", dh_test());
1084
1085     /* Power-up self test
1086     */
1087     ERR_clear_error();
1088     test_msg("2. Automatic power-up self test", FIPS_module_mode_set(1));
1089     if (!FIPS_module_mode())
1090         exit(1);
1091     if (do_drbg_stick)
1092             FIPS_drbg_stick();
1093     if (do_rng_stick)
1094             FIPS_x931_stick();
1095
1096     /* AES encryption/decryption
1097     */
1098     test_msg("3a. AES encryption/decryption", FIPS_aes_test());
1099     /* AES GCM encryption/decryption
1100     */
1101     test_msg("3b. AES-GCM encryption/decryption", FIPS_aes_gcm_test());
1102
1103     /* RSA key generation and encryption/decryption
1104     */
1105     test_msg("4. RSA key generation and encryption/decryption",
1106                                                 FIPS_rsa_test(bad_rsa));
1107
1108     /* DES-CBC encryption/decryption
1109     */
1110     test_msg("5. DES-ECB encryption/decryption", FIPS_des3_test());
1111
1112     /* DSA key generation and signature validation
1113     */
1114     test_msg("6. DSA key generation and signature validation",
1115                                                 FIPS_dsa_test(bad_dsa));
1116
1117     /* SHA-1 hash
1118     */
1119     test_msg("7a. SHA-1 hash", FIPS_sha1_test());
1120
1121     /* SHA-256 hash
1122     */
1123     test_msg("7b. SHA-256 hash", FIPS_sha256_test());
1124
1125     /* SHA-512 hash
1126     */
1127     test_msg("7c. SHA-512 hash", FIPS_sha512_test());
1128
1129     /* HMAC-SHA-1 hash
1130     */
1131     test_msg("7d. HMAC-SHA-1 hash", FIPS_hmac_sha1_test());
1132
1133     /* HMAC-SHA-224 hash
1134     */
1135     test_msg("7e. HMAC-SHA-224 hash", FIPS_hmac_sha224_test());
1136
1137     /* HMAC-SHA-256 hash
1138     */
1139     test_msg("7f. HMAC-SHA-256 hash", FIPS_hmac_sha256_test());
1140
1141     /* HMAC-SHA-384 hash
1142     */
1143     test_msg("7g. HMAC-SHA-384 hash", FIPS_hmac_sha384_test());
1144
1145     /* HMAC-SHA-512 hash
1146     */
1147     test_msg("7h. HMAC-SHA-512 hash", FIPS_hmac_sha512_test());
1148
1149     /* CMAC-AES-128 hash
1150     */
1151     test_msg("8a. CMAC-AES-128 hash", FIPS_cmac_aes128_test());
1152
1153     /* CMAC-AES-192 hash
1154     */
1155     test_msg("8b. CMAC-AES-192 hash", FIPS_cmac_aes192_test());
1156
1157     /* CMAC-AES-256 hash
1158     */
1159     test_msg("8c. CMAC-AES-256 hash", FIPS_cmac_aes256_test());
1160
1161 # if 0                          /* Not a FIPS algorithm */
1162     /* CMAC-TDEA-2 hash
1163     */
1164     test_msg("8d. CMAC-TDEA-2 hash", FIPS_cmac_tdea2_test());
1165 #endif
1166
1167     /* CMAC-TDEA-3 hash
1168     */
1169     test_msg("8e. CMAC-TDEA-3 hash", FIPS_cmac_tdea3_test());
1170
1171     /* Non-Approved cryptographic operation
1172     */
1173     printf("9. Non-Approved cryptographic operation test...\n");
1174     printf("\ta. Included algorithm (D-H)...%s\n",
1175                 no_dh ? "skipped" :
1176                 dh_test() ? "successful as expected"
1177                                                 : Fail("failed INCORRECTLY!") );
1178
1179     /* Zeroization
1180     */
1181     printf("10. Zero-ization...\n\t%s\n",
1182                 Zeroize() ? "successful as expected"
1183                                         : Fail("failed INCORRECTLY!") );
1184
1185     printf("11. Complete DRBG health check...\n");
1186     printf("\t%s\n", FIPS_selftest_drbg_all() ? "successful as expected"
1187                                         : Fail("failed INCORRECTLY!") );
1188
1189     printf("12. DRBG generation check...\n");
1190     printf("\t%s\n", do_drbg_all() ? "successful as expected"
1191                                         : Fail("failed INCORRECTLY!") );
1192
1193     printf("\nAll tests completed with %d errors\n", Error);
1194     return Error ? 1 : 0;
1195     }
1196
1197 #endif