]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/openssl/fips/sha/fips_shatest.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / crypto / openssl / fips / sha / fips_shatest.c
1 /* fips_shatest.c */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 2005.
4  */
5 /* ====================================================================
6  * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer. 
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58
59 #include <stdio.h>
60 #include <ctype.h>
61 #include <string.h>
62 #include <openssl/bio.h>
63 #include <openssl/evp.h>
64 #include <openssl/err.h>
65 #include <openssl/bn.h>
66 #include <openssl/x509v3.h>
67
68 #ifndef OPENSSL_FIPS
69
70 int main(int argc, char *argv[])
71 {
72     printf("No FIPS SHAXXX support\n");
73     return(0);
74 }
75
76 #else
77
78 #include "fips_utl.h"
79
80 static int dgst_test(FILE *out, FILE *in);
81 static int print_dgst(const EVP_MD *md, FILE *out,
82                 unsigned char *Msg, int Msglen);
83 static int print_monte(const EVP_MD *md, FILE *out,
84                 unsigned char *Seed, int SeedLen);
85
86 int main(int argc, char **argv)
87         {
88         FILE *in = NULL, *out = NULL;
89
90         int ret = 1;
91
92         if(!FIPS_mode_set(1))
93                 {
94                 do_print_errors();
95                 goto end;
96                 }
97
98         if (argc == 1)
99                 in = stdin;
100         else
101                 in = fopen(argv[1], "r");
102
103         if (argc < 2)
104                 out = stdout;
105         else
106                 out = fopen(argv[2], "w");
107
108         if (!in)
109                 {
110                 fprintf(stderr, "FATAL input initialization error\n");
111                 goto end;
112                 }
113
114         if (!out)
115                 {
116                 fprintf(stderr, "FATAL output initialization error\n");
117                 goto end;
118                 }
119
120         if (!dgst_test(out, in))
121                 {
122                 fprintf(stderr, "FATAL digest file processing error\n");
123                 goto end;
124                 }
125         else
126                 ret = 0;
127
128         end:
129
130         if (ret)
131                 do_print_errors();
132
133         if (in && (in != stdin))
134                 fclose(in);
135         if (out && (out != stdout))
136                 fclose(out);
137
138         return ret;
139
140         }
141
142 #define SHA_TEST_MAX_BITS       102400
143 #define SHA_TEST_MAXLINELEN     (((SHA_TEST_MAX_BITS >> 3) * 2) + 100)
144
145 int dgst_test(FILE *out, FILE *in)
146         {
147         const EVP_MD *md = NULL;
148         char *linebuf, *olinebuf, *p, *q;
149         char *keyword, *value;
150         unsigned char *Msg = NULL, *Seed = NULL;
151         long MsgLen = -1, Len = -1, SeedLen = -1;
152         int ret = 0;
153         int lnum = 0;
154
155         olinebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN);
156         linebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN);
157
158         if (!linebuf || !olinebuf)
159                 goto error;
160
161
162         while (fgets(olinebuf, SHA_TEST_MAXLINELEN, in))
163                 {
164                 lnum++;
165                 strcpy(linebuf, olinebuf);
166                 keyword = linebuf;
167                 /* Skip leading space */
168                 while (isspace((unsigned char)*keyword))
169                         keyword++;
170
171                 /* Look for = sign */
172                 p = strchr(linebuf, '=');
173
174                 /* If no = or starts with [ (for [L=20] line) just copy */
175                 if (!p)
176                         {
177                         fputs(olinebuf, out);
178                         continue;
179                         }
180
181                 q = p - 1;
182
183                 /* Remove trailing space */
184                 while (isspace((unsigned char)*q))
185                         *q-- = 0;
186
187                 *p = 0;
188                 value = p + 1;
189
190                 /* Remove leading space from value */
191                 while (isspace((unsigned char)*value))
192                         value++;
193
194                 /* Remove trailing space from value */
195                 p = value + strlen(value) - 1;
196                 while (*p == '\n' || isspace((unsigned char)*p))
197                         *p-- = 0;
198
199                 if (!strcmp(keyword,"[L") && *p==']')
200                         {
201                         switch (atoi(value))
202                                 {
203                                 case 20: md=EVP_sha1();   break;
204                                 case 28: md=EVP_sha224(); break;
205                                 case 32: md=EVP_sha256(); break;
206                                 case 48: md=EVP_sha384(); break;
207                                 case 64: md=EVP_sha512(); break;
208                                 default: goto parse_error;
209                                 }
210                         }
211                 else if (!strcmp(keyword, "Len"))
212                         {
213                         if (Len != -1)
214                                 goto parse_error;
215                         Len = atoi(value);
216                         if (Len < 0)
217                                 goto parse_error;
218                         /* Only handle multiples of 8 bits */
219                         if (Len & 0x7)
220                                 goto parse_error;
221                         if (Len > SHA_TEST_MAX_BITS)
222                                 goto parse_error;
223                         MsgLen = Len >> 3;
224                         }
225
226                 else if (!strcmp(keyword, "Msg"))
227                         {
228                         long tmplen;
229                         if (strlen(value) & 1)
230                                 *(--value) = '0';
231                         if (Msg)
232                                 goto parse_error;
233                         Msg = hex2bin_m(value, &tmplen);
234                         if (!Msg)
235                                 goto parse_error;
236                         }
237                 else if (!strcmp(keyword, "Seed"))
238                         {
239                         if (strlen(value) & 1)
240                                 *(--value) = '0';
241                         if (Seed)
242                                 goto parse_error;
243                         Seed = hex2bin_m(value, &SeedLen);
244                         if (!Seed)
245                                 goto parse_error;
246                         }
247                 else if (!strcmp(keyword, "MD"))
248                         continue;
249                 else
250                         goto parse_error;
251
252                 fputs(olinebuf, out);
253
254                 if (md && Msg && (MsgLen >= 0))
255                         {
256                         if (!print_dgst(md, out, Msg, MsgLen))
257                                 goto error;
258                         OPENSSL_free(Msg);
259                         Msg = NULL;
260                         MsgLen = -1;
261                         Len = -1;
262                         }
263                 else if (md && Seed && (SeedLen > 0))
264                         {
265                         if (!print_monte(md, out, Seed, SeedLen))
266                                 goto error;
267                         OPENSSL_free(Seed);
268                         Seed = NULL;
269                         SeedLen = -1;
270                         }
271         
272
273                 }
274
275
276         ret = 1;
277
278
279         error:
280
281         if (olinebuf)
282                 OPENSSL_free(olinebuf);
283         if (linebuf)
284                 OPENSSL_free(linebuf);
285         if (Msg)
286                 OPENSSL_free(Msg);
287         if (Seed)
288                 OPENSSL_free(Seed);
289
290         return ret;
291
292         parse_error:
293
294         fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
295
296         goto error;
297
298         }
299
300 static int print_dgst(const EVP_MD *emd, FILE *out,
301                 unsigned char *Msg, int Msglen)
302         {
303         int i, mdlen;
304         unsigned char md[EVP_MAX_MD_SIZE];
305         if (!EVP_Digest(Msg, Msglen, md, (unsigned int *)&mdlen, emd, NULL))
306                 {
307                 fputs("Error calculating HASH\n", stderr);
308                 return 0;
309                 }
310         fputs("MD = ", out);
311         for (i = 0; i < mdlen; i++)
312                 fprintf(out, "%02x", md[i]);
313         fputs("\n", out);
314         return 1;
315         }
316
317 static int print_monte(const EVP_MD *md, FILE *out,
318                 unsigned char *Seed, int SeedLen)
319         {
320         unsigned int i, j, k;
321         int ret = 0;
322         EVP_MD_CTX ctx;
323         unsigned char *m1, *m2, *m3, *p;
324         unsigned int mlen, m1len, m2len, m3len;
325
326         EVP_MD_CTX_init(&ctx);
327
328         if (SeedLen > EVP_MAX_MD_SIZE)
329                 mlen = SeedLen;
330         else
331                 mlen = EVP_MAX_MD_SIZE;
332
333         m1 = OPENSSL_malloc(mlen);
334         m2 = OPENSSL_malloc(mlen);
335         m3 = OPENSSL_malloc(mlen);
336
337         if (!m1 || !m2 || !m3)
338                 goto mc_error;
339
340         m1len = m2len = m3len = SeedLen;
341         memcpy(m1, Seed, SeedLen);
342         memcpy(m2, Seed, SeedLen);
343         memcpy(m3, Seed, SeedLen);
344
345         fputs("\n", out);
346
347         for (j = 0; j < 100; j++)
348                 {
349                 for (i = 0; i < 1000; i++)
350                         {
351                         EVP_DigestInit_ex(&ctx, md, NULL);
352                         EVP_DigestUpdate(&ctx, m1, m1len);
353                         EVP_DigestUpdate(&ctx, m2, m2len);
354                         EVP_DigestUpdate(&ctx, m3, m3len);
355                         p = m1;
356                         m1 = m2;
357                         m1len = m2len;
358                         m2 = m3;
359                         m2len = m3len;
360                         m3 = p;
361                         EVP_DigestFinal_ex(&ctx, m3, &m3len);
362                         }
363                 fprintf(out, "COUNT = %d\n", j);
364                 fputs("MD = ", out);
365                 for (k = 0; k < m3len; k++)
366                         fprintf(out, "%02x", m3[k]);
367                 fputs("\n\n", out);
368                 memcpy(m1, m3, m3len);
369                 memcpy(m2, m3, m3len);
370                 m1len = m2len = m3len;
371                 }
372
373         ret = 1;
374
375         mc_error:
376         if (m1)
377                 OPENSSL_free(m1);
378         if (m2)
379                 OPENSSL_free(m2);
380         if (m3)
381                 OPENSSL_free(m3);
382
383         EVP_MD_CTX_cleanup(&ctx);
384
385         return ret;
386         }
387
388 #endif