util/mkdef.pl: o_time.h doesn't exist any more
[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 #ifdef FIPS_ALGVS
89 int fips_hmactest_main(int argc, char **argv)
90 #else
91 int main(int argc, char **argv)
92 #endif
93         {
94         FILE *in = NULL, *out = NULL;
95
96         int ret = 1;
97         fips_algtest_init();
98
99         if (argc == 1)
100                 in = stdin;
101         else
102                 in = fopen(argv[1], "r");
103
104         if (argc < 2)
105                 out = stdout;
106         else
107                 out = fopen(argv[2], "w");
108
109         if (!in)
110                 {
111                 fprintf(stderr, "FATAL input initialization error\n");
112                 goto end;
113                 }
114
115         if (!out)
116                 {
117                 fprintf(stderr, "FATAL output initialization error\n");
118                 goto end;
119                 }
120
121         if (!hmac_test(EVP_sha1(), out, in))
122                 {
123                 fprintf(stderr, "FATAL hmac file processing error\n");
124                 goto end;
125                 }
126         else
127                 ret = 0;
128
129         end:
130
131         if (in && (in != stdin))
132                 fclose(in);
133         if (out && (out != stdout))
134                 fclose(out);
135
136         return ret;
137
138         }
139
140 #define HMAC_TEST_MAXLINELEN    1024
141
142 int hmac_test(const EVP_MD *md, FILE *out, FILE *in)
143         {
144         char *linebuf, *olinebuf, *p, *q;
145         char *keyword, *value;
146         unsigned char *Key = NULL, *Msg = NULL;
147         int Count, Klen, Tlen;
148         long Keylen, Msglen;
149         int ret = 0;
150         int lnum = 0;
151
152         olinebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
153         linebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
154
155         if (!linebuf || !olinebuf)
156                 goto error;
157
158         Count = -1;
159         Klen = -1;
160         Tlen = -1;
161
162         while (fgets(olinebuf, HMAC_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                         if (fputs(olinebuf, out) < 0)
178                                 goto error;
179                         continue;
180                         }
181
182                 q = p - 1;
183
184                 /* Remove trailing space */
185                 while (isspace((unsigned char)*q))
186                         *q-- = 0;
187
188                 *p = 0;
189                 value = p + 1;
190
191                 /* Remove leading space from value */
192                 while (isspace((unsigned char)*value))
193                         value++;
194
195                 /* Remove trailing space from value */
196                 p = value + strlen(value) - 1;
197
198                 while (*p == '\n' || isspace((unsigned char)*p))
199                         *p-- = 0;
200
201                 if (!strcmp(keyword,"[L") && *p==']')
202                         {
203                         switch (atoi(value))
204                                 {
205                                 case 20: md=EVP_sha1();   break;
206                                 case 28: md=EVP_sha224(); break;
207                                 case 32: md=EVP_sha256(); break;
208                                 case 48: md=EVP_sha384(); break;
209                                 case 64: md=EVP_sha512(); break;
210                                 default: goto parse_error;
211                                 }
212                         }
213                 else if (!strcmp(keyword, "Count"))
214                         {
215                         if (Count != -1)
216                                 goto parse_error;
217                         Count = atoi(value);
218                         if (Count < 0)
219                                 goto parse_error;
220                         }
221                 else if (!strcmp(keyword, "Klen"))
222                         {
223                         if (Klen != -1)
224                                 goto parse_error;
225                         Klen = atoi(value);
226                         if (Klen < 0)
227                                 goto parse_error;
228                         }
229                 else if (!strcmp(keyword, "Tlen"))
230                         {
231                         if (Tlen != -1)
232                                 goto parse_error;
233                         Tlen = atoi(value);
234                         if (Tlen < 0)
235                                 goto parse_error;
236                         }
237                 else if (!strcmp(keyword, "Msg"))
238                         {
239                         if (Msg)
240                                 goto parse_error;
241                         Msg = hex2bin_m(value, &Msglen);
242                         if (!Msg)
243                                 goto parse_error;
244                         }
245                 else if (!strcmp(keyword, "Key"))
246                         {
247                         if (Key)
248                                 goto parse_error;
249                         Key = hex2bin_m(value, &Keylen);
250                         if (!Key)
251                                 goto parse_error;
252                         }
253                 else if (!strcmp(keyword, "Mac"))
254                         continue;
255                 else
256                         goto parse_error;
257
258                 fputs(olinebuf, out);
259
260                 if (Key && Msg && (Tlen > 0) && (Klen > 0))
261                         {
262                         if (!print_hmac(md, out, Key, Klen, Msg, Msglen, Tlen))
263                                 goto error;
264                         OPENSSL_free(Key);
265                         Key = NULL;
266                         OPENSSL_free(Msg);
267                         Msg = NULL;
268                         Klen = -1;
269                         Tlen = -1;
270                         Count = -1;
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 (Key)
286                 OPENSSL_free(Key);
287         if (Msg)
288                 OPENSSL_free(Msg);
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_hmac(const EVP_MD *emd, FILE *out,
301                 unsigned char *Key, int Klen,
302                 unsigned char *Msg, int Msglen, int Tlen)
303         {
304         int i, mdlen;
305         unsigned char md[EVP_MAX_MD_SIZE];
306         if (!HMAC(emd, Key, Klen, Msg, Msglen, md,
307                                                 (unsigned int *)&mdlen))
308                 {
309                 fputs("Error calculating HMAC\n", stderr);
310                 return 0;
311                 }
312         if (Tlen > mdlen)
313                 {
314                 fputs("Parameter error, Tlen > HMAC length\n", stderr);
315                 return 0;
316                 }
317         fputs("Mac = ", out);
318         for (i = 0; i < Tlen; i++)
319                 fprintf(out, "%02x", md[i]);
320         fputs(RESP_EOL, out);
321         return 1;
322         }
323
324 #endif