a606d31fbdfe39f41433a98759dff2fd176bc5b8
[openssl.git] / fips / rand / fips_rand_lib.c
1 /* ====================================================================
2  * Copyright (c) 2011 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/crypto.h>
53 #include <openssl/rand.h>
54 #include <openssl/err.h>
55 #include <openssl/fips.h>
56 #include <openssl/fips_rand.h>
57 #include "e_os.h"
58
59 /* FIPS API for PRNG use. Similar to RAND functionality but without
60  * ENGINE and additional checking for non-FIPS rand methods.
61  */
62
63 static const RAND_METHOD *fips_rand_meth = NULL;
64 static int fips_approved_rand_meth = 0;
65 static int fips_rand_bits = 0;
66
67 /* Allows application to override number of bits and uses non-FIPS methods */
68 void FIPS_rand_set_bits(int nbits)
69         {
70         fips_rand_bits = nbits;
71         }
72
73 int FIPS_rand_set_method(const RAND_METHOD *meth)
74         {
75         if (!fips_rand_bits)
76                 {
77                 if (meth == FIPS_drbg_method())
78                         fips_approved_rand_meth = 1;
79                 else if (meth == FIPS_x931_method())
80                         fips_approved_rand_meth = 2;
81                 else
82                         {
83                         fips_approved_rand_meth = 0;
84                         if (FIPS_module_mode())
85                                 {
86                                 FIPSerr(FIPS_F_FIPS_RAND_SET_METHOD,
87                                                 FIPS_R_NON_FIPS_METHOD);
88                                 return 0;
89                                 }
90                         }
91                 }
92         fips_rand_meth = meth;
93         return 1;
94         }
95
96 const RAND_METHOD *FIPS_rand_get_method(void)
97         {
98         return fips_rand_meth;
99         }
100
101 void FIPS_rand_seed(const void *buf, int num)
102         {
103         if (!fips_approved_rand_meth && FIPS_module_mode())
104                 {
105                 FIPSerr(FIPS_F_FIPS_RAND_SEED, FIPS_R_NON_FIPS_METHOD);
106                 return;
107                 }
108         if (fips_rand_meth && fips_rand_meth->seed)
109                 fips_rand_meth->seed(buf,num);
110         }
111
112 void FIPS_rand_add(const void *buf, int num, double entropy)
113         {
114         if (!fips_approved_rand_meth && FIPS_module_mode())
115                 {
116                 FIPSerr(FIPS_F_FIPS_RAND_ADD, FIPS_R_NON_FIPS_METHOD);
117                 return;
118                 }
119         if (fips_rand_meth && fips_rand_meth->add)
120                 fips_rand_meth->add(buf,num,entropy);
121         }
122
123 int FIPS_rand_bytes(unsigned char *buf, int num)
124         {
125         if (!fips_approved_rand_meth && FIPS_module_mode())
126                 {
127                 FIPSerr(FIPS_F_FIPS_RAND_BYTES, FIPS_R_NON_FIPS_METHOD);
128                 return 0;
129                 }
130         if (fips_rand_meth && fips_rand_meth->bytes)
131                 return fips_rand_meth->bytes(buf,num);
132         return 0;
133         }
134
135 int FIPS_rand_pseudo_bytes(unsigned char *buf, int num)
136         {
137         if (!fips_approved_rand_meth && FIPS_module_mode())
138                 {
139                 FIPSerr(FIPS_F_FIPS_RAND_PSEUDO_BYTES, FIPS_R_NON_FIPS_METHOD);
140                 return 0;
141                 }
142         if (fips_rand_meth && fips_rand_meth->pseudorand)
143                 return fips_rand_meth->pseudorand(buf,num);
144         return -1;
145         }
146
147 int FIPS_rand_status(void)
148         {
149         if (!fips_approved_rand_meth && FIPS_module_mode())
150                 {
151                 FIPSerr(FIPS_F_FIPS_RAND_STATUS, FIPS_R_NON_FIPS_METHOD);
152                 return 0;
153                 }
154         if (fips_rand_meth && fips_rand_meth->status)
155                 return fips_rand_meth->status();
156         return 0;
157         }
158
159 /* Return instantiated strength of PRNG. For DRBG this is an internal
160  * parameter. For X9.31 PRNG it is 80 bits (from SP800-131). Any other
161  * type of PRNG is not approved and returns 0 in FIPS mode and maximum
162  * 256 outside FIPS mode.
163  */
164
165 int FIPS_rand_strength(void)
166         {
167         if (fips_rand_bits)
168                 return fips_rand_bits;
169         if (fips_approved_rand_meth == 1)
170                 return FIPS_drbg_get_strength(FIPS_get_default_drbg());
171         else if (fips_approved_rand_meth == 2)
172                 return 80;
173         else if (fips_approved_rand_meth == 0)
174                 {
175                 if (FIPS_module_mode())
176                         return 0;
177                 else
178                         return 256;
179                 }
180         return 0;
181         }