Redirect FIPS memory allocation to FIPS_malloc() routine, remove
[openssl.git] / fips / fips_utl.h
1 /* ====================================================================
2  * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer. 
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in
13  *    the documentation and/or other materials provided with the
14  *    distribution.
15  *
16  * 3. All advertising materials mentioning features or use of this
17  *    software must display the following acknowledgment:
18  *    "This product includes software developed by the OpenSSL Project
19  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20  *
21  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22  *    endorse or promote products derived from this software without
23  *    prior written permission. For written permission, please contact
24  *    openssl-core@openssl.org.
25  *
26  * 5. Products derived from this software may not be called "OpenSSL"
27  *    nor may "OpenSSL" appear in their names without prior written
28  *    permission of the OpenSSL Project.
29  *
30  * 6. Redistributions of any form whatsoever must retain the following
31  *    acknowledgment:
32  *    "This product includes software developed by the OpenSSL Project
33  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46  * OF THE POSSIBILITY OF SUCH DAMAGE.
47  *
48  */
49
50 #define OPENSSL_FIPSAPI
51 #include <openssl/fips.h>
52
53 int hex2bin(const char *in, unsigned char *out);
54 unsigned char *hex2bin_m(const char *in, long *plen);
55 int do_hex2bn(BIGNUM **pr, const char *in);
56 int do_bn_print(FILE *out, BIGNUM *bn);
57 int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn);
58 int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf);
59 BIGNUM *hex2bn(const char *in);
60 int bin2hex(const unsigned char *in,int len,char *out);
61 void pv(const char *tag,const unsigned char *val,int len);
62 int tidy_line(char *linebuf, char *olinebuf);
63 int bint2bin(const char *in, int len, unsigned char *out);
64 int bin2bint(const unsigned char *in,int len,char *out);
65 void PrintValue(char *tag, unsigned char *val, int len);
66 void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode);
67
68 static int no_err;
69
70 static void put_err_cb(int lib, int func,int reason,const char *file,int line)
71         {
72                 if (no_err)
73                         return;
74                 fprintf(stderr, "ERROR:lib=%d,func=%d,reason=%d"
75                                 ":file=%s:line=%d\n",
76                         lib, func, reason, file, line);
77         }
78
79 static void add_err_cb(int num, va_list args)
80         {
81         int i;
82         char *str;
83         if (no_err)
84                 return;
85         fputs("\t", stderr);
86         for (i = 0; i < num; i++)
87                 {
88                 str = va_arg(args, char *);
89                 if (str)
90                         fputs(str, stderr);
91                 }
92         fputs("\n", stderr);
93         }
94
95 static void fips_set_error_print(void)
96         {
97         FIPS_set_error_callbacks(put_err_cb, add_err_cb);
98         }
99
100 int hex2bin(const char *in, unsigned char *out)
101     {
102     int n1, n2;
103     unsigned char ch;
104
105     for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; )
106         { /* first byte */
107         if ((in[n1] >= '0') && (in[n1] <= '9'))
108             ch = in[n1++] - '0';
109         else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
110             ch = in[n1++] - 'A' + 10;
111         else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
112             ch = in[n1++] - 'a' + 10;
113         else
114             return -1;
115         if(!in[n1])
116             {
117             out[n2++]=ch;
118             break;
119             }
120         out[n2] = ch << 4;
121         /* second byte */
122         if ((in[n1] >= '0') && (in[n1] <= '9'))
123             ch = in[n1++] - '0';
124         else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
125             ch = in[n1++] - 'A' + 10;
126         else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
127             ch = in[n1++] - 'a' + 10;
128         else
129             return -1;
130         out[n2++] |= ch;
131         }
132     return n2;
133     }
134
135 unsigned char *hex2bin_m(const char *in, long *plen)
136         {
137         unsigned char *p;
138         p = OPENSSL_malloc((strlen(in) + 1)/2);
139         *plen = hex2bin(in, p);
140         return p;
141         }
142
143 int do_hex2bn(BIGNUM **pr, const char *in)
144         {
145         unsigned char *p;
146         long plen;
147         int r = 0;
148         p = hex2bin_m(in, &plen);
149         if (!p)
150                 return 0;
151         if (!*pr)
152                 *pr = BN_new();
153         if (!*pr)
154                 return 0;
155         if (BN_bin2bn(p, plen, *pr))
156                 r = 1;
157         OPENSSL_free(p);
158         return r;
159         }
160
161 int do_bn_print(FILE *out, BIGNUM *bn)
162         {
163         int len, i;
164         unsigned char *tmp;
165         len = BN_num_bytes(bn);
166         if (len == 0)
167                 {
168                 fputs("00", out);
169                 return 1;
170                 }
171
172         tmp = OPENSSL_malloc(len);
173         if (!tmp)
174                 {
175                 fprintf(stderr, "Memory allocation error\n");
176                 return 0;
177                 }
178         BN_bn2bin(bn, tmp);
179         for (i = 0; i < len; i++)
180                 fprintf(out, "%02x", tmp[i]);
181         OPENSSL_free(tmp);
182         return 1;
183         }
184
185 int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn)
186         {
187         int r;
188         fprintf(out, "%s = ", name);
189         r = do_bn_print(out, bn);
190         if (!r)
191                 return 0;
192         fputs("\n", out);
193         return 1;
194         }
195
196 int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf)
197         {
198         char *keyword, *value, *p, *q;
199         strcpy(linebuf, olinebuf);
200         keyword = linebuf;
201         /* Skip leading space */
202         while (isspace((unsigned char)*keyword))
203                 keyword++;
204
205         /* Look for = sign */
206         p = strchr(linebuf, '=');
207
208         /* If no '=' exit */
209         if (!p)
210                 return 0;
211
212         q = p - 1;
213
214         /* Remove trailing space */
215         while (isspace((unsigned char)*q))
216                 *q-- = 0;
217
218         *p = 0;
219         value = p + 1;
220
221         /* Remove leading space from value */
222         while (isspace((unsigned char)*value))
223                 value++;
224
225         /* Remove trailing space from value */
226         p = value + strlen(value) - 1;
227
228         while (*p == '\n' || isspace((unsigned char)*p))
229                 *p-- = 0;
230
231         *pkw = keyword;
232         *pval = value;
233         return 1;
234         }
235
236 BIGNUM *hex2bn(const char *in)
237     {
238     BIGNUM *p=NULL;
239
240     if (!do_hex2bn(&p, in))
241         return NULL;
242
243     return p;
244     }
245
246 int bin2hex(const unsigned char *in,int len,char *out)
247     {
248     int n1, n2;
249     unsigned char ch;
250
251     for (n1=0,n2=0 ; n1 < len ; ++n1)
252         {
253         ch=in[n1] >> 4;
254         if (ch <= 0x09)
255             out[n2++]=ch+'0';
256         else
257             out[n2++]=ch-10+'a';
258         ch=in[n1] & 0x0f;
259         if(ch <= 0x09)
260             out[n2++]=ch+'0';
261         else
262             out[n2++]=ch-10+'a';
263         }
264     out[n2]='\0';
265     return n2;
266     }
267
268 void pv(const char *tag,const unsigned char *val,int len)
269     {
270     char obuf[2048];
271
272     bin2hex(val,len,obuf);
273     printf("%s = %s\n",tag,obuf);
274     }
275
276 /* To avoid extensive changes to test program at this stage just convert
277  * the input line into an acceptable form. Keyword lines converted to form
278  * "keyword = value\n" no matter what white space present, all other lines
279  * just have leading and trailing space removed.
280  */
281
282 int tidy_line(char *linebuf, char *olinebuf)
283         {
284         char *keyword, *value, *p, *q;
285         strcpy(linebuf, olinebuf);
286         keyword = linebuf;
287         /* Skip leading space */
288         while (isspace((unsigned char)*keyword))
289                 keyword++;
290         /* Look for = sign */
291         p = strchr(linebuf, '=');
292
293         /* If no '=' just chop leading, trailing ws */
294         if (!p)
295                 {
296                 p = keyword + strlen(keyword) - 1;
297                 while (*p == '\n' || isspace((unsigned char)*p))
298                         *p-- = 0;
299                 strcpy(olinebuf, keyword);
300                 strcat(olinebuf, "\n");
301                 return 1;
302                 }
303
304         q = p - 1;
305
306         /* Remove trailing space */
307         while (isspace((unsigned char)*q))
308                 *q-- = 0;
309
310         *p = 0;
311         value = p + 1;
312
313         /* Remove leading space from value */
314         while (isspace((unsigned char)*value))
315                 value++;
316
317         /* Remove trailing space from value */
318         p = value + strlen(value) - 1;
319
320         while (*p == '\n' || isspace((unsigned char)*p))
321                 *p-- = 0;
322
323         strcpy(olinebuf, keyword);
324         strcat(olinebuf, " = ");
325         strcat(olinebuf, value);
326         strcat(olinebuf, "\n");
327
328         return 1;
329         }
330
331 /* NB: this return the number of _bits_ read */
332 int bint2bin(const char *in, int len, unsigned char *out)
333     {
334     int n;
335
336     memset(out,0,len);
337     for(n=0 ; n < len ; ++n)
338         if(in[n] == '1')
339             out[n/8]|=(0x80 >> (n%8));
340     return len;
341     }
342
343 int bin2bint(const unsigned char *in,int len,char *out)
344     {
345     int n;
346
347     for(n=0 ; n < len ; ++n)
348         out[n]=(in[n/8]&(0x80 >> (n%8))) ? '1' : '0';
349     return n;
350     }
351
352 /*-----------------------------------------------*/
353
354 void PrintValue(char *tag, unsigned char *val, int len)
355 {
356 #if VERBOSE
357   char obuf[2048];
358   int olen;
359   olen = bin2hex(val, len, obuf);
360   printf("%s = %.*s\n", tag, olen, obuf);
361 #endif
362 }
363
364 void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode)
365     {
366     char obuf[2048];
367     int olen;
368
369     if(bitmode)
370         olen=bin2bint(val,len,obuf);
371     else
372         olen=bin2hex(val,len,obuf);
373
374     fprintf(rfp, "%s = %.*s\n", tag, olen, obuf);
375 #if VERBOSE
376     printf("%s = %.*s\n", tag, olen, obuf);
377 #endif
378     }
379