x509v3.h header file not needed in fips algorithm test utilities.
[openssl.git] / fips / hmac / fips_hmactest.c
1 /* fips_hmactest.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 #define OPENSSL_FIPSAPI
60
61 #include <stdio.h>
62 #include <ctype.h>
63 #include <string.h>
64 #include <openssl/bio.h>
65 #include <openssl/evp.h>
66 #include <openssl/hmac.h>
67 #include <openssl/err.h>
68 #include <openssl/bn.h>
69
70 #ifndef OPENSSL_FIPS
71
72 int main(int argc, char *argv[])
73 {
74     printf("No FIPS HMAC support\n");
75     return(0);
76 }
77
78 #else
79
80 #include <openssl/fips.h>
81 #include "fips_utl.h"
82
83 static int hmac_test(const EVP_MD *md, FILE *out, FILE *in);
84 static int print_hmac(const EVP_MD *md, FILE *out,
85                 unsigned char *Key, int Klen,
86                 unsigned char *Msg, int Msglen, int Tlen);
87
88 int main(int argc, char **argv)
89         {
90         FILE *in = NULL, *out = NULL;
91
92         int ret = 1;
93         fips_set_error_print();
94         if(!FIPS_mode_set(1))
95                 goto end;
96
97         if (argc == 1)
98                 in = stdin;
99         else
100                 in = fopen(argv[1], "r");
101
102         if (argc < 2)
103                 out = stdout;
104         else
105                 out = fopen(argv[2], "w");
106
107         if (!in)
108                 {
109                 fprintf(stderr, "FATAL input initialization error\n");
110                 goto end;
111                 }
112
113         if (!out)
114                 {
115                 fprintf(stderr, "FATAL output initialization error\n");
116                 goto end;
117                 }
118
119         if (!hmac_test(EVP_sha1(), out, in))
120                 {
121                 fprintf(stderr, "FATAL hmac file processing error\n");
122                 goto end;
123                 }
124         else
125                 ret = 0;
126
127         end:
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 HMAC_TEST_MAXLINELEN    1024
139
140 int hmac_test(const EVP_MD *md, FILE *out, FILE *in)
141         {
142         char *linebuf, *olinebuf, *p, *q;
143         char *keyword, *value;
144         unsigned char *Key = NULL, *Msg = NULL;
145         int Count, Klen, Tlen;
146         long Keylen, Msglen;
147         int ret = 0;
148         int lnum = 0;
149
150         olinebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
151         linebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
152
153         if (!linebuf || !olinebuf)
154                 goto error;
155
156         Count = -1;
157         Klen = -1;
158         Tlen = -1;
159
160         while (fgets(olinebuf, HMAC_TEST_MAXLINELEN, in))
161                 {
162                 lnum++;
163                 strcpy(linebuf, olinebuf);
164                 keyword = linebuf;
165                 /* Skip leading space */
166                 while (isspace((unsigned char)*keyword))
167                         keyword++;
168
169                 /* Look for = sign */
170                 p = strchr(linebuf, '=');
171
172                 /* If no = or starts with [ (for [L=20] line) just copy */
173                 if (!p)
174                         {
175                         if (fputs(olinebuf, out) < 0)
176                                 goto error;
177                         continue;
178                         }
179
180                 q = p - 1;
181
182                 /* Remove trailing space */
183                 while (isspace((unsigned char)*q))
184                         *q-- = 0;
185
186                 *p = 0;
187                 value = p + 1;
188
189                 /* Remove leading space from value */
190                 while (isspace((unsigned char)*value))
191                         value++;
192
193                 /* Remove trailing space from value */
194                 p = value + strlen(value) - 1;
195
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, "Count"))
212                         {
213                         if (Count != -1)
214                                 goto parse_error;
215                         Count = atoi(value);
216                         if (Count < 0)
217                                 goto parse_error;
218                         }
219                 else if (!strcmp(keyword, "Klen"))
220                         {
221                         if (Klen != -1)
222                                 goto parse_error;
223                         Klen = atoi(value);
224                         if (Klen < 0)
225                                 goto parse_error;
226                         }
227                 else if (!strcmp(keyword, "Tlen"))
228                         {
229                         if (Tlen != -1)
230                                 goto parse_error;
231                         Tlen = atoi(value);
232                         if (Tlen < 0)
233                                 goto parse_error;
234                         }
235                 else if (!strcmp(keyword, "Msg"))
236                         {
237                         if (Msg)
238                                 goto parse_error;
239                         Msg = hex2bin_m(value, &Msglen);
240                         if (!Msg)
241                                 goto parse_error;
242                         }
243                 else if (!strcmp(keyword, "Key"))
244                         {
245                         if (Key)
246                                 goto parse_error;
247                         Key = hex2bin_m(value, &Keylen);
248                         if (!Key)
249                                 goto parse_error;
250                         }
251                 else if (!strcmp(keyword, "Mac"))
252                         continue;
253                 else
254                         goto parse_error;
255
256                 fputs(olinebuf, out);
257
258                 if (Key && Msg && (Tlen > 0) && (Klen > 0))
259                         {
260                         if (!print_hmac(md, out, Key, Klen, Msg, Msglen, Tlen))
261                                 goto error;
262                         OPENSSL_free(Key);
263                         Key = NULL;
264                         OPENSSL_free(Msg);
265                         Msg = NULL;
266                         Klen = -1;
267                         Tlen = -1;
268                         Count = -1;
269                         }
270
271                 }
272
273
274         ret = 1;
275
276
277         error:
278
279         if (olinebuf)
280                 OPENSSL_free(olinebuf);
281         if (linebuf)
282                 OPENSSL_free(linebuf);
283         if (Key)
284                 OPENSSL_free(Key);
285         if (Msg)
286                 OPENSSL_free(Msg);
287
288         return ret;
289
290         parse_error:
291
292         fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
293
294         goto error;
295
296         }
297
298 static int print_hmac(const EVP_MD *emd, FILE *out,
299                 unsigned char *Key, int Klen,
300                 unsigned char *Msg, int Msglen, int Tlen)
301         {
302         int i, mdlen;
303         unsigned char md[EVP_MAX_MD_SIZE];
304         if (!HMAC(emd, Key, Klen, Msg, Msglen, md,
305                                                 (unsigned int *)&mdlen))
306                 {
307                 fputs("Error calculating HMAC\n", stderr);
308                 return 0;
309                 }
310         if (Tlen > mdlen)
311                 {
312                 fputs("Parameter error, Tlen > HMAC length\n", stderr);
313                 return 0;
314                 }
315         fputs("Mac = ", out);
316         for (i = 0; i < Tlen; i++)
317                 fprintf(out, "%02x", md[i]);
318         fputs("\n", out);
319         return 1;
320         }
321
322 #endif