Add pairwise consistency test to EC.
[openssl.git] / fips / fips.c
1 /* ====================================================================
2  * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer. 
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in
13  *    the documentation and/or other materials provided with the
14  *    distribution.
15  *
16  * 3. All advertising materials mentioning features or use of this
17  *    software must display the following acknowledgment:
18  *    "This product includes software developed by the OpenSSL Project
19  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20  *
21  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22  *    endorse or promote products derived from this software without
23  *    prior written permission. For written permission, please contact
24  *    openssl-core@openssl.org.
25  *
26  * 5. Products derived from this software may not be called "OpenSSL"
27  *    nor may "OpenSSL" appear in their names without prior written
28  *    permission of the OpenSSL Project.
29  *
30  * 6. Redistributions of any form whatsoever must retain the following
31  *    acknowledgment:
32  *    "This product includes software developed by the OpenSSL Project
33  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46  * OF THE POSSIBILITY OF SUCH DAMAGE.
47  *
48  */
49
50 #define OPENSSL_FIPSAPI
51
52 #include <openssl/rand.h>
53 #include <openssl/fips_rand.h>
54 #include <openssl/err.h>
55 #include <openssl/bio.h>
56 #include <openssl/hmac.h>
57 #include <openssl/rsa.h>
58 #include <openssl/dsa.h>
59 #include <openssl/ecdsa.h>
60 #include <string.h>
61 #include <limits.h>
62 #include "fips_locl.h"
63
64 #ifdef OPENSSL_FIPS
65
66 #include <openssl/fips.h>
67
68 #ifndef PATH_MAX
69 #define PATH_MAX 1024
70 #endif
71
72 static int fips_selftest_fail;
73 static int fips_mode;
74 static int fips_started = 0;
75 static const void *fips_rand_check;
76
77 static int fips_is_owning_thread(void);
78 static int fips_set_owning_thread(void);
79 static int fips_clear_owning_thread(void);
80 static unsigned char *fips_signature_witness(void);
81
82 static void fips_w_lock(void)   { CRYPTO_w_lock(CRYPTO_LOCK_FIPS); }
83 static void fips_w_unlock(void) { CRYPTO_w_unlock(CRYPTO_LOCK_FIPS); }
84 static void fips_r_lock(void)   { CRYPTO_r_lock(CRYPTO_LOCK_FIPS); }
85 static void fips_r_unlock(void) { CRYPTO_r_unlock(CRYPTO_LOCK_FIPS); }
86
87 static void fips_set_mode(int onoff)
88         {
89         int owning_thread = fips_is_owning_thread();
90
91         if (fips_started)
92                 {
93                 if (!owning_thread) fips_w_lock();
94                 fips_mode = onoff;
95                 if (!owning_thread) fips_w_unlock();
96                 }
97         }
98
99 static void fips_set_rand_check(const void *rand_check)
100         {
101         int owning_thread = fips_is_owning_thread();
102
103         if (fips_started)
104                 {
105                 if (!owning_thread) fips_w_lock();
106                 fips_rand_check = rand_check;
107                 if (!owning_thread) fips_w_unlock();
108                 }
109         }
110
111 int FIPS_mode(void)
112         {
113         int ret = 0;
114         int owning_thread = fips_is_owning_thread();
115
116         if (fips_started)
117                 {
118                 if (!owning_thread) fips_r_lock();
119                 ret = fips_mode;
120                 if (!owning_thread) fips_r_unlock();
121                 }
122         return ret;
123         }
124
125 const void *FIPS_rand_check(void)
126         {
127         const void *ret = 0;
128         int owning_thread = fips_is_owning_thread();
129
130         if (fips_started)
131                 {
132                 if (!owning_thread) fips_r_lock();
133                 ret = fips_rand_check;
134                 if (!owning_thread) fips_r_unlock();
135                 }
136         return ret;
137         }
138
139 int FIPS_selftest_failed(void)
140     {
141     int ret = 0;
142     if (fips_started)
143         {
144         int owning_thread = fips_is_owning_thread();
145
146         if (!owning_thread) fips_r_lock();
147         ret = fips_selftest_fail;
148         if (!owning_thread) fips_r_unlock();
149         }
150     return ret;
151     }
152
153 /* Selftest failure fatal exit routine. This will be called
154  * during *any* cryptographic operation. It has the minimum
155  * overhead possible to avoid too big a performance hit.
156  */
157
158 void FIPS_selftest_check(void)
159     {
160     if (fips_selftest_fail)
161         {
162         OpenSSLDie(__FILE__,__LINE__, "FATAL FIPS SELFTEST FAILURE");
163         }
164     }
165
166 void fips_set_selftest_fail(void)
167     {
168     fips_selftest_fail = 1;
169     }
170
171 int FIPS_selftest(void)
172     {
173
174     return FIPS_selftest_sha1()
175         && FIPS_selftest_hmac()
176         && FIPS_selftest_aes()
177         && FIPS_selftest_des()
178         && FIPS_selftest_rsa()
179         && FIPS_selftest_dsa();
180     }
181
182 extern const void         *FIPS_text_start(),  *FIPS_text_end();
183 extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[];
184 unsigned char              FIPS_signature [20] = { 0 };
185 static const char          FIPS_hmac_key[]="etaonrishdlcupfm";
186
187 unsigned int FIPS_incore_fingerprint(unsigned char *sig,unsigned int len)
188     {
189     const unsigned char *p1 = FIPS_text_start();
190     const unsigned char *p2 = FIPS_text_end();
191     const unsigned char *p3 = FIPS_rodata_start;
192     const unsigned char *p4 = FIPS_rodata_end;
193     HMAC_CTX c;
194
195     HMAC_CTX_init(&c);
196     HMAC_Init(&c,FIPS_hmac_key,strlen(FIPS_hmac_key),EVP_sha1());
197
198     /* detect overlapping regions */
199     if (p1<=p3 && p2>=p3)
200         p3=p1, p4=p2>p4?p2:p4, p1=NULL, p2=NULL;
201     else if (p3<=p1 && p4>=p1)
202         p3=p3, p4=p2>p4?p2:p4, p1=NULL, p2=NULL;
203
204     if (p1)
205         HMAC_Update(&c,p1,(size_t)p2-(size_t)p1);
206
207     if (FIPS_signature>=p3 && FIPS_signature<p4)
208         {
209         /* "punch" hole */
210         HMAC_Update(&c,p3,(size_t)FIPS_signature-(size_t)p3);
211         p3 = FIPS_signature+sizeof(FIPS_signature);
212         if (p3<p4)
213             HMAC_Update(&c,p3,(size_t)p4-(size_t)p3);
214         }
215     else
216         HMAC_Update(&c,p3,(size_t)p4-(size_t)p3);
217
218     HMAC_Final(&c,sig,&len);
219     HMAC_CTX_cleanup(&c);
220
221     return len;
222     }
223
224 int FIPS_check_incore_fingerprint(void)
225     {
226     unsigned char sig[EVP_MAX_MD_SIZE];
227     unsigned int len;
228 #if defined(__sgi) && (defined(__mips) || defined(mips))
229     extern int __dso_displacement[];
230 #else
231     extern int OPENSSL_NONPIC_relocated;
232 #endif
233
234     if (FIPS_text_start()==NULL)
235         {
236         FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_UNSUPPORTED_PLATFORM);
237         return 0;
238         }
239
240     len=FIPS_incore_fingerprint (sig,sizeof(sig));
241
242     if (len!=sizeof(FIPS_signature) ||
243         memcmp(FIPS_signature,sig,sizeof(FIPS_signature)))
244         {
245         if (FIPS_signature>=FIPS_rodata_start && FIPS_signature<FIPS_rodata_end)
246             FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING);
247 #if defined(__sgi) && (defined(__mips) || defined(mips))
248         else if (__dso_displacement!=NULL)
249 #else
250         else if (OPENSSL_NONPIC_relocated)
251 #endif
252             FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED);
253         else
254             FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH);
255 #ifdef OPENSSL_FIPS_DEBUGGER
256         return 1;
257 #else
258         return 0;
259 #endif
260         }
261     return 1;
262     }
263
264 int FIPS_mode_set(int onoff)
265     {
266     int fips_set_owning_thread();
267     int fips_clear_owning_thread();
268     int ret = 0;
269
270     fips_w_lock();
271     fips_started = 1;
272     fips_set_owning_thread();
273
274     if(onoff)
275         {
276         unsigned char buf[48];
277
278         fips_selftest_fail = 0;
279
280         /* Don't go into FIPS mode twice, just so we can do automagic
281            seeding */
282         if(FIPS_mode())
283             {
284             FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_FIPS_MODE_ALREADY_SET);
285             fips_selftest_fail = 1;
286             ret = 0;
287             goto end;
288             }
289
290 #ifdef OPENSSL_IA32_SSE2
291         if ((OPENSSL_ia32cap & (1<<25|1<<26)) != (1<<25|1<<26))
292             {
293             FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_UNSUPPORTED_PLATFORM);
294             fips_selftest_fail = 1;
295             ret = 0;
296             goto end;
297             }
298 #endif
299
300         if(fips_signature_witness() != FIPS_signature)
301             {
302             FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_CONTRADICTING_EVIDENCE);
303             fips_selftest_fail = 1;
304             ret = 0;
305             goto end;
306             }
307
308         if(!FIPS_check_incore_fingerprint())
309             {
310             fips_selftest_fail = 1;
311             ret = 0;
312             goto end;
313             }
314
315         /* Perform RNG KAT before seeding */
316         if (!FIPS_selftest_rng())
317             {
318             fips_selftest_fail = 1;
319             ret = 0;
320             goto end;
321             }
322
323         /* automagically seed PRNG if not already seeded */
324         if(!FIPS_rand_status())
325             {
326             if(RAND_bytes(buf,sizeof buf) <= 0)
327                 {
328                 fips_selftest_fail = 1;
329                 ret = 0;
330                 goto end;
331                 }
332             FIPS_rand_set_key(buf,32);
333             FIPS_rand_seed(buf+32,16);
334             }
335
336         /* now switch into FIPS mode */
337         fips_set_rand_check(FIPS_rand_method());
338         RAND_set_rand_method(FIPS_rand_method());
339         if(FIPS_selftest())
340             fips_set_mode(1);
341         else
342             {
343             fips_selftest_fail = 1;
344             ret = 0;
345             goto end;
346             }
347         ret = 1;
348         goto end;
349         }
350     fips_set_mode(0);
351     fips_selftest_fail = 0;
352     ret = 1;
353 end:
354     fips_clear_owning_thread();
355     fips_w_unlock();
356     return ret;
357     }
358
359 static CRYPTO_THREADID fips_thread;
360 static int fips_thread_set = 0;
361
362 static int fips_is_owning_thread(void)
363         {
364         int ret = 0;
365
366         if (fips_started)
367                 {
368                 CRYPTO_r_lock(CRYPTO_LOCK_FIPS2);
369                 if (fips_thread_set)
370                         {
371                         CRYPTO_THREADID cur;
372                         CRYPTO_THREADID_current(&cur);
373                         if (!CRYPTO_THREADID_cmp(&cur, &fips_thread))
374                                 ret = 1;
375                         }
376                 CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2);
377                 }
378         return ret;
379         }
380
381 int fips_set_owning_thread(void)
382         {
383         int ret = 0;
384
385         if (fips_started)
386                 {
387                 CRYPTO_w_lock(CRYPTO_LOCK_FIPS2);
388                 if (!fips_thread_set)
389                         {
390                         CRYPTO_THREADID_current(&fips_thread);
391                         ret = 1;
392                         }
393                 CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
394                 }
395         return ret;
396         }
397
398 int fips_clear_owning_thread(void)
399         {
400         int ret = 0;
401
402         if (fips_started)
403                 {
404                 CRYPTO_w_lock(CRYPTO_LOCK_FIPS2);
405                 if (fips_thread_set)
406                         {
407                         CRYPTO_THREADID cur;
408                         CRYPTO_THREADID_current(&cur);
409                         if (!CRYPTO_THREADID_cmp(&cur, &fips_thread))
410                                 fips_thread_set = 0;
411                         }
412                 CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
413                 }
414         return ret;
415         }
416
417 unsigned char *fips_signature_witness(void)
418         {
419         extern unsigned char FIPS_signature[];
420         return FIPS_signature;
421         }
422
423 /* Generalized public key test routine. Signs and verifies the data
424  * supplied in tbs using mesage digest md and setting RSA padding mode
425  * pad_mode. If the 'kat' parameter is not NULL it will
426  * additionally check the signature matches it: a known answer test
427  * The string "fail_str" is used for identification purposes in case
428  * of failure.
429  */
430
431 int fips_pkey_signature_test(EVP_PKEY *pkey,
432                         const unsigned char *tbs, int tbslen,
433                         const unsigned char *kat, unsigned int katlen,
434                         const EVP_MD *digest, int pad_mode,
435                         const char *fail_str)
436         {       
437         int ret = 0;
438         unsigned char sigtmp[256], *sig = sigtmp;
439         unsigned int siglen;
440         DSA_SIG *dsig = NULL;
441         ECDSA_SIG *esig = NULL;
442         EVP_MD_CTX mctx;
443         FIPS_md_ctx_init(&mctx);
444
445         if ((pkey->type == EVP_PKEY_RSA)
446                 && ((size_t)RSA_size(pkey->pkey.rsa) > sizeof(sigtmp)))
447                 {
448                 sig = OPENSSL_malloc(RSA_size(pkey->pkey.rsa));
449                 if (!sig)
450                         {
451                         FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,ERR_R_MALLOC_FAILURE);
452                         return 0;
453                         }
454                 }
455
456         if (tbslen == -1)
457                 tbslen = strlen((char *)tbs);
458
459         if (digest == NULL)
460                 digest = EVP_sha256();
461
462         if (!FIPS_digestinit(&mctx, digest))
463                 goto error;
464         if (!FIPS_digestupdate(&mctx, tbs, tbslen))
465                 goto error;
466         if (pkey->type == EVP_PKEY_RSA)
467                 {
468                 if (!FIPS_rsa_sign_ctx(pkey->pkey.rsa, &mctx,
469                                         pad_mode, 0, NULL, sig, &siglen))
470                         goto error;
471                 }
472         else if (pkey->type == EVP_PKEY_DSA)
473                 {
474                 dsig = FIPS_dsa_sign_ctx(pkey->pkey.dsa, &mctx);
475                 if (!dsig)
476                         goto error;
477                 }
478         else if (pkey->type == EVP_PKEY_EC)
479                 {
480                 esig = FIPS_ecdsa_sign_ctx(pkey->pkey.ec, &mctx);
481                 if (!esig)
482                         goto error;
483                 }
484 #if 0
485         else if (!EVP_SignFinal(&mctx, sig, &siglen, pkey))
486                 goto error;
487 #endif
488
489         if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen)))
490                 goto error;
491
492         if (!FIPS_digestinit(&mctx, digest))
493                 goto error;
494         if (!FIPS_digestupdate(&mctx, tbs, tbslen))
495                 goto error;
496         if (pkey->type == EVP_PKEY_RSA)
497                 {
498                 ret = FIPS_rsa_verify_ctx(pkey->pkey.rsa, &mctx,
499                                                 pad_mode, 0, NULL, sig, siglen);
500                 }
501         else if (pkey->type == EVP_PKEY_DSA)
502                 {
503                 ret = FIPS_dsa_verify_ctx(pkey->pkey.dsa, &mctx, dsig);
504                 }
505         else if (pkey->type == EVP_PKEY_EC)
506                 {
507                 ret = FIPS_ecdsa_verify_ctx(pkey->pkey.ec, &mctx, esig);
508                 }
509 #if 0
510         else
511                 ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey);
512 #endif
513
514         error:
515         if (dsig != NULL)
516                 FIPS_dsa_sig_free(dsig);
517         if (esig != NULL)
518                 FIPS_ecdsa_sig_free(esig);
519         if (sig != sigtmp)
520                 OPENSSL_free(sig);
521         FIPS_md_ctx_cleanup(&mctx);
522         if (ret != 1)
523                 {
524                 FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE);
525                 if (fail_str)
526                         FIPS_add_error_data(2, "Type=", fail_str);
527                 return 0;
528                 }
529         return 1;
530         }
531
532 /* Generalized symmetric cipher test routine. Encrypt data, verify result
533  * against known answer, decrypt and compare with original plaintext.
534  */
535
536 int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
537                         const unsigned char *key,
538                         const unsigned char *iv,
539                         const unsigned char *plaintext,
540                         const unsigned char *ciphertext,
541                         int len)
542         {
543         unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE];
544         unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE];
545         OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE);
546         if (FIPS_cipherinit(ctx, cipher, key, iv, 1) <= 0)
547                 return 0;
548         FIPS_cipher(ctx, citmp, plaintext, len);
549         if (memcmp(citmp, ciphertext, len))
550                 return 0;
551         if (FIPS_cipherinit(ctx, cipher, key, iv, 0) <= 0)
552                 return 0;
553         FIPS_cipher(ctx, pltmp, citmp, len);
554         if (memcmp(pltmp, plaintext, len))
555                 return 0;
556         return 1;
557         }
558
559 #if 0
560 /* The purpose of this is to ensure the error code exists and the function
561  * name is to keep the error checking script quiet
562  */
563 void hash_final(void)
564         {
565         FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD);
566         }
567 #endif
568
569
570 #endif