Redirect FIPS memory allocation to FIPS_malloc() routine, remove
[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 #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/bn.h>
67
68 #include <openssl/x509v3.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 "fips_utl.h"
81
82 static int hmac_test(const EVP_MD *md, FILE *out, FILE *in);
83 static int print_hmac(const EVP_MD *md, FILE *out,
84                 unsigned char *Key, int Klen,
85                 unsigned char *Msg, int Msglen, int Tlen);
86
87 int main(int argc, char **argv)
88         {
89         FILE *in = NULL, *out = NULL;
90
91         int ret = 1;
92         fips_set_error_print();
93         if(!FIPS_mode_set(1))
94                 goto end;
95
96         if (argc == 1)
97                 in = stdin;
98         else
99                 in = fopen(argv[1], "r");
100
101         if (argc < 2)
102                 out = stdout;
103         else
104                 out = fopen(argv[2], "w");
105
106         if (!in)
107                 {
108                 fprintf(stderr, "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(EVP_sha1(), 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 (in && (in != stdin))
129                 fclose(in);
130         if (out && (out != stdout))
131                 fclose(out);
132
133         return ret;
134
135         }
136
137 #define HMAC_TEST_MAXLINELEN    1024
138
139 int hmac_test(const EVP_MD *md, FILE *out, FILE *in)
140         {
141         char *linebuf, *olinebuf, *p, *q;
142         char *keyword, *value;
143         unsigned char *Key = NULL, *Msg = NULL;
144         int Count, Klen, Tlen;
145         long Keylen, Msglen;
146         int ret = 0;
147         int lnum = 0;
148
149         olinebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
150         linebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
151
152         if (!linebuf || !olinebuf)
153                 goto error;
154
155         Count = -1;
156         Klen = -1;
157         Tlen = -1;
158
159         while (fgets(olinebuf, HMAC_TEST_MAXLINELEN, in))
160                 {
161                 lnum++;
162                 strcpy(linebuf, olinebuf);
163                 keyword = linebuf;
164                 /* Skip leading space */
165                 while (isspace((unsigned char)*keyword))
166                         keyword++;
167
168                 /* Look for = sign */
169                 p = strchr(linebuf, '=');
170
171                 /* If no = or starts with [ (for [L=20] line) just copy */
172                 if (!p)
173                         {
174                         if (fputs(olinebuf, out) < 0)
175                                 goto error;
176                         continue;
177                         }
178
179                 q = p - 1;
180
181                 /* Remove trailing space */
182                 while (isspace((unsigned char)*q))
183                         *q-- = 0;
184
185                 *p = 0;
186                 value = p + 1;
187
188                 /* Remove leading space from value */
189                 while (isspace((unsigned char)*value))
190                         value++;
191
192                 /* Remove trailing space from value */
193                 p = value + strlen(value) - 1;
194
195                 while (*p == '\n' || isspace((unsigned char)*p))
196                         *p-- = 0;
197
198                 if (!strcmp(keyword,"[L") && *p==']')
199                         {
200                         switch (atoi(value))
201                                 {
202                                 case 20: md=EVP_sha1();   break;
203                                 case 28: md=EVP_sha224(); break;
204                                 case 32: md=EVP_sha256(); break;
205                                 case 48: md=EVP_sha384(); break;
206                                 case 64: md=EVP_sha512(); break;
207                                 default: goto parse_error;
208                                 }
209                         }
210                 else if (!strcmp(keyword, "Count"))
211                         {
212                         if (Count != -1)
213                                 goto parse_error;
214                         Count = atoi(value);
215                         if (Count < 0)
216                                 goto parse_error;
217                         }
218                 else if (!strcmp(keyword, "Klen"))
219                         {
220                         if (Klen != -1)
221                                 goto parse_error;
222                         Klen = atoi(value);
223                         if (Klen < 0)
224                                 goto parse_error;
225                         }
226                 else if (!strcmp(keyword, "Tlen"))
227                         {
228                         if (Tlen != -1)
229                                 goto parse_error;
230                         Tlen = atoi(value);
231                         if (Tlen < 0)
232                                 goto parse_error;
233                         }
234                 else if (!strcmp(keyword, "Msg"))
235                         {
236                         if (Msg)
237                                 goto parse_error;
238                         Msg = hex2bin_m(value, &Msglen);
239                         if (!Msg)
240                                 goto parse_error;
241                         }
242                 else if (!strcmp(keyword, "Key"))
243                         {
244                         if (Key)
245                                 goto parse_error;
246                         Key = hex2bin_m(value, &Keylen);
247                         if (!Key)
248                                 goto parse_error;
249                         }
250                 else if (!strcmp(keyword, "Mac"))
251                         continue;
252                 else
253                         goto parse_error;
254
255                 fputs(olinebuf, out);
256
257                 if (Key && Msg && (Tlen > 0) && (Klen > 0))
258                         {
259                         if (!print_hmac(md, out, Key, Klen, Msg, Msglen, Tlen))
260                                 goto error;
261                         OPENSSL_free(Key);
262                         Key = NULL;
263                         OPENSSL_free(Msg);
264                         Msg = NULL;
265                         Klen = -1;
266                         Tlen = -1;
267                         Count = -1;
268                         }
269
270                 }
271
272
273         ret = 1;
274
275
276         error:
277
278         if (olinebuf)
279                 OPENSSL_free(olinebuf);
280         if (linebuf)
281                 OPENSSL_free(linebuf);
282         if (Key)
283                 OPENSSL_free(Key);
284         if (Msg)
285                 OPENSSL_free(Msg);
286
287         return ret;
288
289         parse_error:
290
291         fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
292
293         goto error;
294
295         }
296
297 static int print_hmac(const EVP_MD *emd, FILE *out,
298                 unsigned char *Key, int Klen,
299                 unsigned char *Msg, int Msglen, int Tlen)
300         {
301         int i, mdlen;
302         unsigned char md[EVP_MAX_MD_SIZE];
303         if (!HMAC(emd, Key, Klen, Msg, Msglen, md,
304                                                 (unsigned int *)&mdlen))
305                 {
306                 fputs("Error calculating HMAC\n", stderr);
307                 return 0;
308                 }
309         if (Tlen > mdlen)
310                 {
311                 fputs("Parameter error, Tlen > HMAC length\n", stderr);
312                 return 0;
313                 }
314         fputs("Mac = ", out);
315         for (i = 0; i < Tlen; i++)
316                 fprintf(out, "%02x", md[i]);
317         fputs("\n", out);
318         return 1;
319         }
320
321 #endif