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