Install fipscanister.o and friends. Disable warning halt in VC++ build.
[oweals/openssl.git] / fips-1.0 / hmac / fips_hmactest.c
1 /* fips_hmactest.c */
2 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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/hmac.h>
65 #include <openssl/err.h>
66 #include <openssl/fips.h>
67 #include <openssl/x509v3.h>
68
69 #ifndef OPENSSL_FIPS
70
71 int main(int argc, char *argv[])
72 {
73     printf("No FIPS HMAC support\n");
74     return(0);
75 }
76
77 #else
78
79 #include "fips_utl.h"
80
81 static int hmac_test(const EVP_MD *md, FILE *out, FILE *in);
82 static int print_hmac(const EVP_MD *md, FILE *out,
83                 unsigned char *Key, int Klen,
84                 unsigned char *Msg, int Msglen, int Tlen);
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 (!hmac_test(EVP_sha1(), out, in))
121                 {
122                 fprintf(stderr, "FATAL hmac 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 HMAC_TEST_MAXLINELEN    1024
143
144 int hmac_test(const EVP_MD *md, FILE *out, FILE *in)
145         {
146         char *linebuf, *olinebuf, *p, *q;
147         char *keyword, *value;
148         unsigned char *Key = NULL, *Msg = NULL;
149         int Count, Klen, Tlen;
150         long Keylen, Msglen;
151         int ret = 0;
152         int lnum = 0;
153
154         olinebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
155         linebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
156
157         if (!linebuf || !olinebuf)
158                 goto error;
159
160         Count = -1;
161         Klen = -1;
162         Tlen = -1;
163
164         while (fgets(olinebuf, HMAC_TEST_MAXLINELEN, in))
165                 {
166                 lnum++;
167                 strcpy(linebuf, olinebuf);
168                 keyword = linebuf;
169                 /* Skip leading space */
170                 while (isspace((unsigned char)*keyword))
171                         keyword++;
172
173                 /* Look for = sign */
174                 p = strchr(linebuf, '=');
175
176                 /* If no = or starts with [ (for [L=20] line) just copy */
177                 if (!p)
178                         {
179                         if (fputs(olinebuf, out) < 0)
180                                 goto error;
181                         continue;
182                         }
183
184                 q = p - 1;
185
186                 /* Remove trailing space */
187                 while (isspace((unsigned char)*q))
188                         *q-- = 0;
189
190                 *p = 0;
191                 value = p + 1;
192
193                 /* Remove leading space from value */
194                 while (isspace((unsigned char)*value))
195                         value++;
196
197                 /* Remove trailing space from value */
198                 p = value + strlen(value) - 1;
199
200                 while (*p == '\n' || isspace((unsigned char)*p))
201                         *p-- = 0;
202
203                 if (!strcmp(keyword,"[L") && *p==']')
204                         {
205                         switch (atoi(value))
206                                 {
207                                 case 20: md=EVP_sha1();   break;
208                                 case 28: md=EVP_sha224(); break;
209                                 case 32: md=EVP_sha256(); break;
210                                 case 48: md=EVP_sha384(); break;
211                                 case 64: md=EVP_sha512(); break;
212                                 default: goto parse_error;
213                                 }
214                         }
215                 else if (!strcmp(keyword, "Count"))
216                         {
217                         if (Count != -1)
218                                 goto parse_error;
219                         Count = atoi(value);
220                         if (Count < 0)
221                                 goto parse_error;
222                         }
223                 else if (!strcmp(keyword, "Klen"))
224                         {
225                         if (Klen != -1)
226                                 goto parse_error;
227                         Klen = atoi(value);
228                         if (Klen < 0)
229                                 goto parse_error;
230                         }
231                 else if (!strcmp(keyword, "Tlen"))
232                         {
233                         if (Tlen != -1)
234                                 goto parse_error;
235                         Tlen = atoi(value);
236                         if (Tlen < 0)
237                                 goto parse_error;
238                         }
239                 else if (!strcmp(keyword, "Msg"))
240                         {
241                         if (Msg)
242                                 goto parse_error;
243                         Msg = hex2bin_m(value, &Msglen);
244                         if (!Msg)
245                                 goto parse_error;
246                         }
247                 else if (!strcmp(keyword, "Key"))
248                         {
249                         if (Key)
250                                 goto parse_error;
251                         Key = hex2bin_m(value, &Keylen);
252                         if (!Key)
253                                 goto parse_error;
254                         }
255                 else if (!strcmp(keyword, "Mac"))
256                         continue;
257                 else
258                         goto parse_error;
259
260                 fputs(olinebuf, out);
261
262                 if (Key && Msg && (Tlen > 0) && (Klen > 0))
263                         {
264                         if (!print_hmac(md, out, Key, Klen, Msg, Msglen, Tlen))
265                                 goto error;
266                         OPENSSL_free(Key);
267                         Key = NULL;
268                         OPENSSL_free(Msg);
269                         Msg = NULL;
270                         Klen = -1;
271                         Tlen = -1;
272                         Count = -1;
273                         }
274
275                 }
276
277
278         ret = 1;
279
280
281         error:
282
283         if (olinebuf)
284                 OPENSSL_free(olinebuf);
285         if (linebuf)
286                 OPENSSL_free(linebuf);
287         if (Key)
288                 OPENSSL_free(Key);
289         if (Msg)
290                 OPENSSL_free(Msg);
291
292         return ret;
293
294         parse_error:
295
296         fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
297
298         goto error;
299
300         }
301
302 static int print_hmac(const EVP_MD *emd, FILE *out,
303                 unsigned char *Key, int Klen,
304                 unsigned char *Msg, int Msglen, int Tlen)
305         {
306         int i, mdlen;
307         unsigned char md[EVP_MAX_MD_SIZE];
308         if (!HMAC(emd, Key, Klen, Msg, Msglen, md,
309                                                 (unsigned int *)&mdlen))
310                 {
311                 fputs("Error calculating HMAC\n", stderr);
312                 return 0;
313                 }
314         if (Tlen > mdlen)
315                 {
316                 fputs("Parameter error, Tlen > HMAC length\n", stderr);
317                 return 0;
318                 }
319         fputs("Mac = ", out);
320         for (i = 0; i < Tlen; i++)
321                 fprintf(out, "%02x", md[i]);
322         fputs("\n", out);
323         return 1;
324         }
325
326 #endif