Cope with new DSA2 file format where some p/q only tests are made.
[openssl.git] / fips / dsa / fips_dsatest.c
1 /* crypto/dsa/dsatest.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  * 
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  * 
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  * 
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from 
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  * 
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * 
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58
59 #define OPENSSL_FIPSAPI
60
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <string.h>
64 #include <ctype.h>
65 #include <sys/types.h>
66 #include <sys/stat.h>
67
68 #include "e_os.h"
69
70 #include <openssl/crypto.h>
71 #include <openssl/rand.h>
72 #include <openssl/bio.h>
73 #include <openssl/err.h>
74 #include <openssl/bn.h>
75 #ifndef OPENSSL_NO_ENGINE
76 #include <openssl/engine.h>
77 #endif
78
79
80 #if defined(OPENSSL_NO_DSA) || !defined(OPENSSL_FIPS)
81 int main(int argc, char *argv[])
82 {
83     printf("No FIPS DSA support\n");
84     return(0);
85 }
86 #else
87 #include <openssl/dsa.h>
88 #include <openssl/fips.h>
89 #include <openssl/fips_rand.h>
90 #include <openssl/dsa.h>
91
92 #ifdef OPENSSL_SYS_WIN16
93 #define MS_CALLBACK     _far _loadds
94 #else
95 #define MS_CALLBACK
96 #endif
97
98 #include "fips_utl.h"
99
100 static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb);
101
102 /* seed, out_p, out_q, out_g are taken from the earlier validation test
103  * vectors.
104  */
105
106 static unsigned char seed[20] = {
107         0x1c, 0xfb, 0xa9, 0x6c, 0xf7, 0x95, 0xb3, 0x2e, 0x01, 0x01, 0x3c, 0x8d,
108         0x7f, 0x6e, 0xf4, 0x59, 0xcc, 0x2f, 0x19, 0x59
109         };
110
111 static unsigned char out_p[] = {
112         0xc2, 0x3c, 0x48, 0x31, 0x7e, 0x3b, 0x4e, 0x5d, 0x3c, 0x93, 0x78, 0x60,
113         0x5c, 0xf2, 0x60, 0xbb, 0x5a, 0xfa, 0x7f, 0x17, 0xf9, 0x26, 0x69, 0x46,
114         0xe7, 0x07, 0xbb, 0x3b, 0x2e, 0xc4, 0xb5, 0x66, 0xf7, 0x4d, 0xae, 0x9b,
115         0x8f, 0xf0, 0x42, 0xea, 0xb3, 0xa0, 0x7e, 0x81, 0x85, 0x89, 0xe6, 0xb0,
116         0x29, 0x03, 0x6b, 0xcc, 0xfb, 0x8e, 0x46, 0x15, 0x4d, 0xc1, 0x69, 0xd8,
117         0x2f, 0xef, 0x5c, 0x8b, 0x29, 0x32, 0x41, 0xbd, 0x13, 0x72, 0x3d, 0xac,
118         0x81, 0xcc, 0x86, 0x6c, 0x06, 0x5d, 0x51, 0xa1, 0xa5, 0x07, 0x0c, 0x3e,
119         0xbe, 0xdd, 0xf4, 0x6e, 0xa8, 0xed, 0xb4, 0x2f, 0xbd, 0x3e, 0x64, 0xea,
120         0xee, 0x92, 0xec, 0x51, 0xe1, 0x0d, 0xab, 0x25, 0x45, 0xae, 0x55, 0x21,
121         0x4d, 0xd6, 0x96, 0x6f, 0xe6, 0xaa, 0xd3, 0xca, 0x87, 0x92, 0xb1, 0x1c,
122         0x3c, 0xaf, 0x29, 0x09, 0x8b, 0xc6, 0xed, 0xe1
123         };
124
125 static unsigned char out_q[] = {
126         0xae, 0x0a, 0x8c, 0xfb, 0x80, 0xe1, 0xc6, 0xd1, 0x09, 0x0f, 0x26, 0xde,
127         0x91, 0x53, 0xc2, 0x8b, 0x2b, 0x0f, 0xde, 0x7f
128         };
129
130 static unsigned char out_g[] = {
131         0x0d, 0x7d, 0x92, 0x74, 0x10, 0xf6, 0xa4, 0x43, 0x86, 0x9a, 0xd1, 0xd9,
132         0x56, 0x00, 0xbc, 0x18, 0x97, 0x99, 0x4e, 0x9a, 0x93, 0xfb, 0x00, 0x3d,
133         0x6c, 0xa0, 0x1b, 0x95, 0x6b, 0xbd, 0xf7, 0x7a, 0xbc, 0x36, 0x3f, 0x3d,
134         0xb9, 0xbf, 0xf9, 0x91, 0x37, 0x68, 0xd1, 0xb9, 0x1e, 0xfe, 0x7f, 0x10,
135         0xc0, 0x6a, 0xcd, 0x5f, 0xc1, 0x65, 0x1a, 0xb8, 0xe7, 0xab, 0xb5, 0xc6,
136         0x8d, 0xb7, 0x86, 0xad, 0x3a, 0xbf, 0x6b, 0x7b, 0x0a, 0x66, 0xbe, 0xd5,
137         0x58, 0x23, 0x16, 0x48, 0x83, 0x29, 0xb6, 0xa7, 0x64, 0xc7, 0x08, 0xbe,
138         0x55, 0x4c, 0x6f, 0xcb, 0x34, 0xc1, 0x73, 0xb0, 0x39, 0x68, 0x52, 0xdf,
139         0x27, 0x7f, 0x32, 0xbc, 0x2b, 0x0d, 0x63, 0xed, 0x75, 0x3e, 0xb5, 0x54,
140         0xac, 0xc8, 0x20, 0x2a, 0x73, 0xe8, 0x29, 0x51, 0x03, 0x77, 0xe8, 0xc9,
141         0x61, 0x32, 0x25, 0xaf, 0x21, 0x5b, 0x6e, 0xda
142         };
143
144
145 static const unsigned char str1[]="12345678901234567890";
146
147 static const char rnd_seed[] = "string to make the random number generator think it has entropy";
148
149 int main(int argc, char **argv)
150         {
151         DSA *dsa=NULL;
152         DSA_SIG *sig = NULL;
153         int counter,ret=0,i,j;
154         unsigned char buf[256];
155         unsigned long h;
156         BN_GENCB cb;
157         EVP_MD_CTX mctx;
158         BN_GENCB_set(&cb, dsa_cb, stderr);
159         EVP_MD_CTX_init(&mctx);
160
161         fips_set_error_print();
162         if(!FIPS_mode_set(1))
163             EXIT(1);
164
165         fprintf(stderr,"test generation of DSA parameters\n");
166
167         dsa = FIPS_dsa_new();
168         DSA_generate_parameters_ex(dsa, 1024,seed,20,&counter,&h,&cb);
169
170         fprintf(stderr,"seed\n");
171         for (i=0; i<20; i+=4)
172                 {
173                 fprintf(stderr,"%02X%02X%02X%02X ",
174                         seed[i],seed[i+1],seed[i+2],seed[i+3]);
175                 }
176         fprintf(stderr,"\ncounter=%d h=%ld\n",counter,h);
177
178         if (dsa == NULL) goto end;
179         if (counter != 16) 
180                 {
181                 fprintf(stderr,"counter should be 105\n");
182                 goto end;
183                 }
184         if (h != 2)
185                 {
186                 fprintf(stderr,"h should be 2\n");
187                 goto end;
188                 }
189
190         i=BN_bn2bin(dsa->q,buf);
191         j=sizeof(out_q);
192         if ((i != j) || (memcmp(buf,out_q,i) != 0))
193                 {
194                 fprintf(stderr,"q value is wrong\n");
195                 goto end;
196                 }
197
198         i=BN_bn2bin(dsa->p,buf);
199         j=sizeof(out_p);
200         if ((i != j) || (memcmp(buf,out_p,i) != 0))
201                 {
202                 fprintf(stderr,"p value is wrong\n");
203                 goto end;
204                 }
205
206         i=BN_bn2bin(dsa->g,buf);
207         j=sizeof(out_g);
208         if ((i != j) || (memcmp(buf,out_g,i) != 0))
209                 {
210                 fprintf(stderr,"g value is wrong\n");
211                 goto end;
212                 }
213         DSA_generate_key(dsa);
214
215         if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL))
216                 goto end;
217         if (!EVP_DigestUpdate(&mctx, str1, 20))
218                 goto end;
219         sig = FIPS_dsa_sign_ctx(dsa, &mctx);
220         if (!sig)
221                 goto end;
222
223         if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL))
224                 goto end;
225         if (!EVP_DigestUpdate(&mctx, str1, 20))
226                 goto end;
227         if (FIPS_dsa_verify_ctx(dsa, &mctx, sig) != 1)
228                 goto end;
229
230         ret = 1;
231
232 end:
233         if (sig)
234                 DSA_SIG_free(sig);
235         if (dsa != NULL) FIPS_dsa_free(dsa);
236         EVP_MD_CTX_cleanup(&mctx);
237 #if 0
238         CRYPTO_mem_leaks(bio_err);
239 #endif
240         EXIT(!ret);
241         return(!ret);
242         }
243
244 static int cb_exit(int ec)
245         {
246         EXIT(ec);
247         return(0);              /* To keep some compilers quiet */
248         }
249
250 static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb)
251         {
252         char c='*';
253         static int ok=0,num=0;
254
255         if (p == 0) { c='.'; num++; };
256         if (p == 1) c='+';
257         if (p == 2) { c='*'; ok++; }
258         if (p == 3) c='\n';
259         fwrite(&c,1, 1, cb->arg);
260         fflush(cb->arg);
261
262         if (!ok && (p == 0) && (num > 1))
263                 {
264                 fprintf(cb->arg,"error in dsatest\n");
265                 cb_exit(1);
266                 }
267         return 1;
268         }
269 #endif