Add OpenSSL 0.9.7e.
[dragonfly.git] / crypto / openssl-0.9.7e / test / fips_randtest.c
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  * 
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  * 
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  * 
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from 
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  * 
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  * 
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.]
56  */
57 /* ====================================================================
58  * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
59  *
60  * Redistribution and use in source and binary forms, with or without
61  * modification, are permitted provided that the following conditions
62  * are met:
63  *
64  * 1. Redistributions of source code must retain the above copyright
65  *    notice, this list of conditions and the following disclaimer. 
66  *
67  * 2. Redistributions in binary form must reproduce the above copyright
68  *    notice, this list of conditions and the following disclaimer in
69  *    the documentation and/or other materials provided with the
70  *    distribution.
71  *
72  * 3. All advertising materials mentioning features or use of this
73  *    software must display the following acknowledgment:
74  *    "This product includes software developed by the OpenSSL Project
75  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76  *
77  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78  *    endorse or promote products derived from this software without
79  *    prior written permission. For written permission, please contact
80  *    openssl-core@openssl.org.
81  *
82  * 5. Products derived from this software may not be called "OpenSSL"
83  *    nor may "OpenSSL" appear in their names without prior written
84  *    permission of the OpenSSL Project.
85  *
86  * 6. Redistributions of any form whatsoever must retain the following
87  *    acknowledgment:
88  *    "This product includes software developed by the OpenSSL Project
89  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90  *
91  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
95  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102  * OF THE POSSIBILITY OF SUCH DAMAGE.
103  *
104  */
105
106 #include <stdio.h>
107 #include <stdlib.h>
108 #include <openssl/rand.h>
109 #include <openssl/fips_rand.h>
110 #include <openssl/err.h>
111
112 #include "e_os.h"
113
114 #ifndef OPENSSL_FIPS
115 int main(int argc, char *argv[])
116 {
117     printf("No FIPS RAND support\n");
118     return(0);
119 }
120
121 #else
122
123 /* some FIPS 140-1 random number test */
124 /* some simple tests */
125
126 static DES_cblock prng_key1={0x21,0x58,0x47,0xb7,0xc2,0x97,0x5a,0x8e};
127 static DES_cblock prng_key2={0x61,0x23,0x05,0x96,0x18,0x91,0x86,0xac};
128 static unsigned char prng_seed[8]={0x6b,0xa3,0x4f,0x07,0xe4,0x2a,0xb0,0xc};
129
130 typedef struct
131     {
132     DES_cblock keys[2];
133     const unsigned char time[8];
134     const unsigned char seed[8];
135     const unsigned char block1[8];
136     const unsigned char block100[8];
137     } PRNGtest;
138
139 /* FIXME: these test vectors are made up! */
140 static PRNGtest t1=
141     {
142     { { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 },
143       { 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },
144     },
145     { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
146     { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
147     { 0x33,0xc3,0xdf,0xfe,0x60,0x60,0x49,0x9e },
148     { 0xcd,0x2b,0x41,0xaf,0x80,0x51,0x37,0xd8 }
149     };
150 static PRNGtest t2=
151     {
152     { { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },
153       { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff } },
154     { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },
155     { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },
156     { 0x65,0xf1,0xa4,0x07,0x42,0x38,0xd5,0x25 },
157     { 0xbb,0x75,0x84,0x20,0x7a,0x44,0xf0,0xa0 }
158     };
159
160 static void dump(const unsigned char *b,int n)
161     {
162     while(n-- > 0)
163         {
164         printf(" %02x",*b++);
165         }
166     }
167
168 static void compare(const unsigned char *result,const unsigned char *expected,
169                     int n)
170     {
171     int i;
172
173     for(i=0 ; i < n ; ++i)
174         if(result[i] != expected[i])
175             {
176             puts("Random test failed, got:");
177             dump(result,8);
178             puts("\n               expected:");
179             dump(expected,8);
180             putchar('\n');
181             exit(1);
182             }
183     }
184
185 static void run_test(const PRNGtest *t)
186     {
187     unsigned char buf[8];
188     int n;
189
190     FIPS_set_prng_key(t->keys[0],t->keys[1]);
191     FIPS_test_mode(1,t->time);
192     RAND_seed(t->seed,sizeof t->seed);
193
194     if(RAND_bytes(buf,8) <= 0)
195         {
196         ERR_print_errors_fp(stderr);
197         exit(2);
198         }
199     compare(buf,t->block1,8);
200     for(n=0 ; n < 99 ; ++n)
201         if(RAND_bytes(buf,8) <= 0)
202             {
203             ERR_print_errors_fp(stderr);
204             exit(2);
205             }
206     compare(buf,t->block100,8);
207     FIPS_test_mode(0,NULL);
208     }
209
210 int main()
211         {
212         unsigned char buf[2500];
213         int i,j,k,s,sign,nsign,err=0;
214         unsigned long n1;
215         unsigned long n2[16];
216         unsigned long runs[2][34];
217         /*double d; */
218         long d;
219
220         ERR_load_crypto_strings();
221         RAND_set_rand_method(FIPS_rand_method());
222
223         run_test(&t1);
224         run_test(&t2);
225
226         FIPS_set_prng_key(prng_key1,prng_key2);
227         RAND_seed(prng_seed,sizeof prng_seed);
228
229         i = RAND_pseudo_bytes(buf,2500);
230         if (i <= 0)
231                 {
232                 printf ("init failed, the rand method is not properly installed\n");
233                 err++;
234                 goto err;
235                 }
236
237         n1=0;
238         for (i=0; i<16; i++) n2[i]=0;
239         for (i=0; i<34; i++) runs[0][i]=runs[1][i]=0;
240
241         /* test 1 and 2 */
242         sign=0;
243         nsign=0;
244         for (i=0; i<2500; i++)
245                 {
246                 j=buf[i];
247
248                 n2[j&0x0f]++;
249                 n2[(j>>4)&0x0f]++;
250
251                 for (k=0; k<8; k++)
252                         {
253                         s=(j&0x01);
254                         if (s == sign)
255                                 nsign++;
256                         else
257                                 {
258                                 if (nsign > 34) nsign=34;
259                                 if (nsign != 0)
260                                         {
261                                         runs[sign][nsign-1]++;
262                                         if (nsign > 6)
263                                                 runs[sign][5]++;
264                                         }
265                                 sign=s;
266                                 nsign=1;
267                                 }
268
269                         if (s) n1++;
270                         j>>=1;
271                         }
272                 }
273                 if (nsign > 34) nsign=34;
274                 if (nsign != 0) runs[sign][nsign-1]++;
275
276         /* test 1 */
277         if (!((9654 < n1) && (n1 < 10346)))
278                 {
279                 printf("test 1 failed, X=%lu\n",n1);
280                 err++;
281                 }
282         printf("test 1 done\n");
283
284         /* test 2 */
285 #ifdef undef
286         d=0;
287         for (i=0; i<16; i++)
288                 d+=n2[i]*n2[i];
289         d=d*16.0/5000.0-5000.0;
290         if (!((1.03 < d) && (d < 57.4)))
291                 {
292                 printf("test 2 failed, X=%.2f\n",d);
293                 err++;
294                 }
295 #endif
296         d=0;
297         for (i=0; i<16; i++)
298                 d+=n2[i]*n2[i];
299         d=(d*8)/25-500000;
300         if (!((103 < d) && (d < 5740)))
301                 {
302                 printf("test 2 failed, X=%ld.%02ld\n",d/100L,d%100L);
303                 err++;
304                 }
305         printf("test 2 done\n");
306
307         /* test 3 */
308         for (i=0; i<2; i++)
309                 {
310                 if (!((2267 < runs[i][0]) && (runs[i][0] < 2733)))
311                         {
312                         printf("test 3 failed, bit=%d run=%d num=%lu\n",
313                                 i,1,runs[i][0]);
314                         err++;
315                         }
316                 if (!((1079 < runs[i][1]) && (runs[i][1] < 1421)))
317                         {
318                         printf("test 3 failed, bit=%d run=%d num=%lu\n",
319                                 i,2,runs[i][1]);
320                         err++;
321                         }
322                 if (!(( 502 < runs[i][2]) && (runs[i][2] <  748)))
323                         {
324                         printf("test 3 failed, bit=%d run=%d num=%lu\n",
325                                 i,3,runs[i][2]);
326                         err++;
327                         }
328                 if (!(( 223 < runs[i][3]) && (runs[i][3] <  402)))
329                         {
330                         printf("test 3 failed, bit=%d run=%d num=%lu\n",
331                                 i,4,runs[i][3]);
332                         err++;
333                         }
334                 if (!((  90 < runs[i][4]) && (runs[i][4] <  223)))
335                         {
336                         printf("test 3 failed, bit=%d run=%d num=%lu\n",
337                                 i,5,runs[i][4]);
338                         err++;
339                         }
340                 if (!((  90 < runs[i][5]) && (runs[i][5] <  223)))
341                         {
342                         printf("test 3 failed, bit=%d run=%d num=%lu\n",
343                                 i,6,runs[i][5]);
344                         err++;
345                         }
346                 }
347         printf("test 3 done\n");
348         
349         /* test 4 */
350         if (runs[0][33] != 0)
351                 {
352                 printf("test 4 failed, bit=%d run=%d num=%lu\n",
353                         0,34,runs[0][33]);
354                 err++;
355                 }
356         if (runs[1][33] != 0)
357                 {
358                 printf("test 4 failed, bit=%d run=%d num=%lu\n",
359                         1,34,runs[1][33]);
360                 err++;
361                 }
362         printf("test 4 done\n");
363  err:
364         err=((err)?1:0);
365         EXIT(err);
366         return(err);
367         }
368
369 #endif