Fix mk1mf.pl and avoid warning in VC++.
[oweals/openssl.git] / fips / 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/x509v3.h>
67
68 static int hmac_test(BIO *err, BIO *out, BIO *in);
69 static int print_hmac(BIO *err, BIO *out,
70                 unsigned char *Key, int Klen,
71                 unsigned char *Msg, int Msglen, int Tlen);
72
73 int main(int argc, char **argv)
74         {
75         BIO *in = NULL, *out = NULL, *err = NULL;
76
77         int ret = 1;
78         ERR_load_crypto_strings();
79
80         err = BIO_new_fp(stderr, BIO_NOCLOSE);
81
82         if (!err)
83                 {
84                 fprintf(stderr, "FATAL stderr initialization error\n");
85                 goto end;
86                 }
87
88 #ifdef OPENSSL_FIPS
89         if(!FIPS_mode_set(1,argv[0]))
90                 {
91                 ERR_print_errors(err);
92                 goto end;
93                 }
94 #endif
95
96         if (argc == 1)
97                 in = BIO_new_fp(stdin, BIO_NOCLOSE);
98         else
99                 in = BIO_new_file(argv[1], "r");
100
101         if (argc < 2)
102                 out = BIO_new_fp(stdout, BIO_NOCLOSE);
103         else
104                 out = BIO_new_file(argv[2], "w");
105
106         if (!in)
107                 {
108                 BIO_printf(err, "FATAL input initialization error\n");
109                 goto end;
110                 }
111
112         if (!out)
113                 {
114                 fprintf(stderr, "FATAL output initialization error\n");
115                 goto end;
116                 }
117
118         if (!hmac_test(err, out, in))
119                 {
120                 fprintf(stderr, "FATAL hmac file processing error\n");
121                 goto end;
122                 }
123         else
124                 ret = 0;
125
126         end:
127
128         if (ret && err)
129                 ERR_print_errors(err);
130
131         if (in)
132                 BIO_free(in);
133         if (out)
134                 BIO_free(out);
135         if (err)
136                 BIO_free(err);
137
138         return ret;
139
140         }
141
142 #define HMAC_TEST_MAXLINELEN    1024
143
144 int hmac_test(BIO *err, BIO *out, BIO *in)
145         {
146         char *linebuf, *olinebuf, *p, *q;
147         char *keyword, *value;
148         unsigned char *Key = NULL, *Msg = NULL;
149         int Count, Klen, Tlen, have_key, have_mesg;
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         have_key = 0;
164         have_mesg = 0;
165
166         while (BIO_gets(in, olinebuf, HMAC_TEST_MAXLINELEN) > 0)
167                 {
168                 lnum++;
169                 strcpy(linebuf, olinebuf);
170                 keyword = linebuf;
171                 /* Skip leading space */
172                 while (isspace((unsigned char)*keyword))
173                         keyword++;
174
175                 /* Look for = sign */
176                 p = strchr(linebuf, '=');
177
178                 /* If no = or starts with [ (for [L=20] line) just copy */
179                 if (!p || *keyword=='[')
180                         {
181                         if (!BIO_puts(out, olinebuf))
182                                 goto error;
183                         continue;
184                         }
185
186                 q = p - 1;
187
188                 /* Remove trailing space */
189                 while (isspace((unsigned char)*q))
190                         *q-- = 0;
191
192
193                 value = p + 1;
194
195                 /* Remove leading space from value */
196                 while (isspace((unsigned char)*value))
197                         value++;
198
199                 /* Remove trailing space from value */
200                 p = value + strlen(value) - 1;
201
202                 while (*p == '\n' || isspace((unsigned char)*p))
203                         *p-- = 0;
204
205                 if (!strcmp(keyword, "Count"))
206                         {
207                         if (Count != -1)
208                                 goto parse_error;
209                         Count = atoi(value);
210                         if (Count < 0)
211                                 goto parse_error;
212                         }
213                 else if (!strcmp(keyword, "Klen"))
214                         {
215                         if (Klen != -1)
216                                 goto parse_error;
217                         Klen = atoi(value);
218                         if (Klen < 0)
219                                 goto parse_error;
220                         }
221                 else if (!strcmp(keyword, "Tlen"))
222                         {
223                         if (Tlen != -1)
224                                 goto parse_error;
225                         Tlen = atoi(value);
226                         if (Tlen < 0)
227                                 goto parse_error;
228                         }
229                 else if (!strcmp(keyword, "Msg"))
230                         {
231                         if (Msg)
232                                 goto parse_error;
233                         Msg = string_to_hex(value, &Msglen);
234                         }
235                 else if (!strcmp(keyword, "Key"))
236                         {
237                         if (Key)
238                                 goto parse_error;
239                         Key = string_to_hex(value, &Keylen);
240                         }
241                 else if (!strcmp(keyword, "Mac"))
242                         continue;
243                 else
244                         goto parse_error;
245
246                 BIO_puts(out, olinebuf);
247
248                 if (Key && Msg && (Tlen > 0) && (Klen > 0))
249                         {
250                         if (!print_hmac(err, out, Key, Klen, Msg, Msglen, Tlen))
251                                 goto error;
252                         OPENSSL_free(Key);
253                         Key = NULL;
254                         OPENSSL_free(Msg);
255                         Msg = NULL;
256                         Klen = -1;
257                         Tlen = -1;
258                         Count = -1;
259                         }
260
261                 }
262
263
264         ret = 1;
265
266
267         error:
268
269         if (olinebuf)
270                 OPENSSL_free(olinebuf);
271         if (linebuf)
272                 OPENSSL_free(linebuf);
273         if (Key)
274                 OPENSSL_free(Key);
275         if (Msg)
276                 OPENSSL_free(Msg);
277
278         return ret;
279
280         parse_error:
281
282         BIO_printf(err, "FATAL parse error processing line %d\n", lnum);
283
284         goto error;
285
286         }
287
288 static int print_hmac(BIO *err, BIO *out,
289                 unsigned char *Key, int Klen,
290                 unsigned char *Msg, int Msglen, int Tlen)
291         {
292         int i, mdlen;
293         unsigned char md[EVP_MAX_MD_SIZE];
294         if (!HMAC(EVP_sha1(), Key, Klen, Msg, Msglen, md,
295                                                 (unsigned int *)&mdlen))
296                 {
297                 BIO_puts(err, "Error calculating HMAC\n");
298                 return 0;
299                 }
300         if (Tlen > mdlen)
301                 {
302                 BIO_puts(err, "Parameter error, Tlen > HMAC length\n");
303                 return 0;
304                 }
305         BIO_puts(out, "Mac = ");
306         for (i = 0; i < Tlen; i++)
307                 BIO_printf(out, "%02x", md[i]);
308         BIO_puts(out, "\n");
309         return 1;
310         }
311
312