Fix self-tests, ban some things in FIPS mode, fix copyrights.
[oweals/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 #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
28 #ifndef OPENSSL_FIPS
29 int main(int argc, char *argv[])
30     {
31     printf("No FIPS support\n");
32     return(0);
33     }
34 #else
35
36 /* AES: encrypt and decrypt known plaintext, verify result matches original plaintext
37 */
38 static int FIPS_aes_test()
39     {
40     unsigned char userkey[16] = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xf0, 0x0d };
41     unsigned char plaintext[16] = "etaonrishdlcu";
42     unsigned char ciphertext[16];
43     unsigned char buf[16];
44     AES_KEY key;
45     AES_KEY dkey;
46
47     ERR_clear_error();
48     if (AES_set_encrypt_key( userkey, 128, &key ))
49         return 0;
50     AES_encrypt( plaintext, ciphertext, &key);
51     if (AES_set_decrypt_key( userkey, 128, &dkey ))
52         return 0;
53     AES_decrypt( ciphertext, buf, &dkey);
54     if (memcmp(buf, plaintext, sizeof(buf)))
55         return 0;
56     return 1;
57     }
58
59 /* DES: encrypt and decrypt known plaintext, verify result matches original plaintext
60 */
61 static int FIPS_des_test()
62     {
63     DES_cblock userkey = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xf0, 0x0d };
64     DES_cblock plaintext = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' };
65
66     DES_key_schedule key;
67     DES_cblock ciphertext;
68     DES_cblock buf;
69
70     ERR_clear_error();
71     if (DES_set_key(&userkey, &key) < 0)
72         return 0;
73     DES_ecb_encrypt( &plaintext, &ciphertext, &key, 1);
74     DES_ecb_encrypt( &ciphertext, &buf, &key, 0);
75     if (memcmp(buf, plaintext, sizeof(buf)))
76         return 0;
77     return 1;
78     }
79
80 /* DSA: generate key and sign a known digest, then verify the signature
81  * against the digest
82 */
83 static int FIPS_dsa_test()
84     {
85     DSA *dsa = NULL;
86     unsigned char dgst[] = "etaonrishdlc";
87     unsigned char sig[256];
88     unsigned int siglen;
89
90     ERR_clear_error();
91     dsa = DSA_generate_parameters(512,NULL,0,NULL,NULL,NULL,NULL);
92     if (!dsa)
93         return 0;
94     if (!DSA_generate_key(dsa))
95         return 0;
96     if ( DSA_sign(0,dgst,strlen(dgst),sig,&siglen,dsa) != 1 )
97         return 0;
98     if ( DSA_verify(0,dgst,strlen(dgst),sig,siglen,dsa) != 1 )
99         return 0;
100     DSA_free(dsa);
101     return 1;
102     }
103
104 /* RSA: generate keys and encrypt and decrypt known plaintext, verify result
105  * matches the original plaintext
106 */
107 static int FIPS_rsa_test()
108     {
109     RSA *key;
110     unsigned char input_ptext[] = "etaonrishdlc";
111     unsigned char ctext[256];
112     unsigned char ptext[256];
113     int n;
114
115     ERR_clear_error();
116     key = RSA_generate_key(1024,65537,NULL,NULL);
117     if (!key)
118         return 0;
119     n = RSA_size(key);
120     n = RSA_public_encrypt(strlen(input_ptext),input_ptext,ctext,key,RSA_PKCS1_PADDING);
121     if (n < 0)
122         return 0;
123     n = RSA_private_decrypt(n,ctext,ptext,key,RSA_PKCS1_PADDING);
124     if (n < 0)
125         return 0;
126     RSA_free(key);
127     if (memcmp(input_ptext,ptext,strlen(input_ptext)))
128         return 0;
129     return 1;
130     }
131
132 /* SHA1: generate hash of known digest value and compare to known
133    precomputed correct hash
134 */
135 static int FIPS_sha1_test()
136     {
137     unsigned char digest[SHA_DIGEST_LENGTH] =
138         { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a, 0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 };
139     char str[] = "etaonrishd";
140
141     unsigned char md[SHA_DIGEST_LENGTH];
142
143     ERR_clear_error();
144     if (!SHA1(str,strlen(str),md)) return 0;
145     if (memcmp(md,digest,sizeof(md)))
146         return 0;
147     return 1;
148     }
149
150 /* MD5: generate hash of known digest value and compare to known
151    precomputed correct hash
152 */
153 static int md5_test()
154     {
155     unsigned char digest[MD5_DIGEST_LENGTH] =
156         { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 };
157     char str[] = "etaonrishd";
158
159     unsigned char md[MD5_DIGEST_LENGTH];
160
161     ERR_clear_error();
162     if (!MD5(str,strlen(str),md))
163         return 0;
164     if (memcmp(md,digest,sizeof(md)))
165         return 0;
166     return 1;
167     }
168
169 /* DH: generate shared parameters
170 */
171 static int dh_test()
172     {
173     DH *dh;
174
175     ERR_clear_error();
176     dh = DH_generate_parameters(256, 2, NULL, NULL);
177     if (dh)
178         return 1;
179     return 0;
180     }
181
182 static int Error;
183 const char * Fail(const char *msg)
184     {
185     Error++;
186     return msg; 
187     }
188
189 int main(int argc,char **argv)
190     {
191
192     printf("\tFIPS-mode test application\n\n");
193
194     if (argv[1]) {
195         /* Corrupted KAT tests */
196         if (!strcmp(argv[1], "aes")) {
197             FIPS_corrupt_aes();
198             printf("3. AES encryption/decryption with corrupted KAT...\n");
199         } else if (!strcmp(argv[1], "des")) {
200             FIPS_corrupt_des();
201             printf("5. DES-ECB encryption/decryption with corrupted KAT...\n");
202         } else if (!strcmp(argv[1], "dsa")) {
203             FIPS_corrupt_dsa();
204             printf("6. DSA key generation and signature validation with corrupted KAT...\n");
205         } else if (!strcmp(argv[1], "rsa")) {
206             FIPS_corrupt_rsa();
207             printf("4. RSA key generation and encryption/decryption with corrupted KAT...\n");
208         } else if (!strcmp(argv[1], "sha1")) {
209             FIPS_corrupt_sha1();
210             printf("7. SHA-1 hash with corrupted KAT...\n");
211         } else {
212             printf("Bad argument \"%s\"\n", argv[1]);
213             exit(1);
214         }
215         if (!FIPS_mode_set(1,argv[0]))
216             {
217             ERR_load_crypto_strings();
218             ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
219             printf("Power-up self test failed\n");
220             exit(1);
221         }
222         printf("Power-up self test successful\n");
223         exit(0);
224     }
225
226     /* Non-Approved cryptographic operation
227     */
228     printf("0. Non-Approved cryptographic operation test...\n");
229     printf("\ta. MD5...");
230     printf( md5_test() ? "successful\n" :  Fail("FAILED!\n") );
231     printf("\tb. D-H...");
232     printf( dh_test() ? "successful\n" :  Fail("FAILED!\n") );
233
234     /* Power-up self test failure
235     */
236     printf("1. Automatic power-up self test...");
237     printf( FIPS_mode_set(1,"/dev/null") ? Fail("passed INCORRECTLY!\n") : "failed as expected\n" );
238
239     /* Algorithm call when uninitialized failure
240     */
241     printf("\ta. AES API failure on failed power-up self test...");
242     printf( FIPS_aes_test() ? Fail("passed INCORRECTLY!\n") :"failed as expected\n" );
243     printf("\tb. RSA API failure on failed power-up self test...");
244     printf( FIPS_rsa_test() ? Fail("passed INCORRECTLY!\n") :  "failed as expected\n" );
245     printf("\tc. DES API failure on failed power-up self test...");
246     printf( FIPS_des_test() ? Fail("passed INCORRECTLY!\n") : "failed as expected\n" );
247     printf("\td. DSA API failure on failed power-up self test...");
248     printf( FIPS_dsa_test() ? Fail("passed INCORRECTLY!\n") :  "failed as expected\n" );
249     printf("\te. SHA1 API failure on failed power-up self test...");
250     printf( FIPS_sha1_test() ? Fail("passed INCORRECTLY!\n") : "failed as expected\n" );
251
252     /* Power-up self test retry
253     */
254     ERR_clear_error();
255     printf("2. Automatic power-up self test retry...");
256     if (!FIPS_mode_set(1,argv[0]))
257         {
258         ERR_load_crypto_strings();
259         ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
260         printf(Fail("FAILED!\n"));
261         exit(1);
262         }
263     printf("successful\n");
264
265     /* AES encryption/decryption
266     */
267     printf("3. AES encryption/decryption...");
268     printf( FIPS_aes_test() ? "successful\n" :  Fail("FAILED!\n") );
269
270     /* RSA key generation and encryption/decryption
271     */
272     printf("4. RSA key generation and encryption/decryption...");
273     printf( FIPS_rsa_test() ? "successful\n" :  Fail("FAILED!\n") );
274
275     /* DES-CBC encryption/decryption
276     */
277     printf("5. DES-ECB encryption/decryption...");
278     printf( FIPS_des_test() ? "successful\n" :  Fail("FAILED!\n") );
279
280     /* DSA key generation and signature validation
281     */
282     printf("6. DSA key generation and signature validation...");
283     printf( FIPS_dsa_test() ? "successful\n" :  Fail("FAILED!\n") );
284
285     /* SHA-1 hash
286     */
287     printf("7. SHA-1 hash...");
288     printf( FIPS_sha1_test() ? "successful\n" :  Fail("FAILED!\n") );
289
290     /* Non-Approved cryptographic operation
291     */
292     printf("8. Non-Approved cryptographic operation test...\n");
293     printf("\ta. MD5...");
294     printf( md5_test() ? Fail("passed INCORRECTLY!\n")
295             : "failed as expected\n" );
296     printf("\tb. D-H...");
297     printf( dh_test() ? Fail("passed INCORRECTLY!\n")
298             : "failed as expected\n" );
299
300     printf("\nAll tests completed with %d errors\n", Error);
301     return 0;
302     }
303 #endif