Split parts of the gc module into gc-md5 and gc-hmac-md5 modules.
[gnulib.git] / lib / gc-gnulib.c
1 /* gc-gl-common.c --- Common gnulib internal crypto interface functions
2  * Copyright (C) 2002, 2003, 2004, 2005  Simon Josefsson
3  *
4  * This file is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2, or (at your
7  * option) any later version.
8  *
9  * This file is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this file; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  */
20
21 /* Note: This file is only built if GC uses internal functions. */
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 /* Get prototype. */
28 #include <gc.h>
29
30 #include <stdlib.h>
31 #include <string.h>
32
33 /* For randomize. */
34 #include <unistd.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <errno.h>
39
40 #ifdef GC_USE_MD5
41 # include "md5.h"
42 #endif
43 #ifdef GC_USE_HMAC_MD5
44 # include "hmac.h"
45 #endif
46
47 int
48 gc_init (void)
49 {
50   return 0;
51 }
52
53 void
54 gc_done (void)
55 {
56   return;
57 }
58
59 /* Randomness. */
60
61 static int
62 randomize (int level, char *data, size_t datalen)
63 {
64   int fd;
65   const char *device;
66   size_t len = 0;
67   int rc;
68
69   switch (level)
70     {
71     case 0:
72       device = NAME_OF_NONCE_DEVICE;
73       break;
74
75     case 1:
76       device = NAME_OF_PSEUDO_RANDOM_DEVICE;
77       break;
78
79     default:
80       device = NAME_OF_RANDOM_DEVICE;
81       break;
82     }
83
84   fd = open (device, O_RDONLY);
85   if (fd < 0)
86     return GC_RANDOM_ERROR;
87
88   do
89     {
90       ssize_t tmp;
91
92       tmp = read (fd, data, datalen);
93
94       if (tmp < 0)
95         {
96           int save_errno = errno;
97           close (fd);
98           errno = save_errno;
99           return GC_RANDOM_ERROR;
100         }
101
102       len += tmp;
103     }
104   while (len < datalen);
105
106   rc = close (fd);
107   if (rc < 0)
108     return GC_RANDOM_ERROR;
109
110   return GC_OK;
111 }
112
113 int
114 gc_nonce (char *data, size_t datalen)
115 {
116   return randomize (0, data, datalen);
117 }
118
119 int
120 gc_pseudo_random (char *data, size_t datalen)
121 {
122   return randomize (1, data, datalen);
123 }
124
125 int
126 gc_random (char *data, size_t datalen)
127 {
128   return randomize (2, data, datalen);
129 }
130
131 /* Memory allocation. */
132
133 void
134 gc_set_allocators (gc_malloc_t func_malloc,
135                    gc_malloc_t secure_malloc,
136                    gc_secure_check_t secure_check,
137                    gc_realloc_t func_realloc, gc_free_t func_free)
138 {
139   return;
140 }
141
142 /* Hashes. */
143
144 int
145 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
146 {
147   switch (hash)
148     {
149 #ifdef GC_USE_MD5
150     case GC_MD5:
151       md5_buffer (in, inlen, resbuf);
152       break;
153 #endif
154
155     default:
156       return GC_INVALID_HASH;
157     }
158
159   return GC_OK;
160 }
161
162 #ifdef GC_USE_MD5
163 int
164 gc_md5 (const void *in, size_t inlen, void *resbuf)
165 {
166   md5_buffer (in, inlen, resbuf);
167   return 0;
168 }
169 #endif
170
171 #ifdef GC_USE_HMAC_MD5
172 int
173 gc_hmac_md5 (const void *key, size_t keylen,
174              const void *in, size_t inlen, char *resbuf)
175 {
176   hmac_md5 (key, keylen, in, inlen, resbuf);
177   return 0;
178 }
179 #endif