2005-10-08 Simon Josefsson <jas@extundo.com>
[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 #include "md5.h"
41 #include "hmac.h"
42
43 int
44 gc_init (void)
45 {
46   return 0;
47 }
48
49 void
50 gc_done (void)
51 {
52   return;
53 }
54
55 /* Randomness. */
56
57 static int
58 randomize (int level, char *data, size_t datalen)
59 {
60   int fd;
61   const char *device;
62   size_t len = 0;
63   int rc;
64
65   switch (level)
66     {
67     case 0:
68       device = NAME_OF_NONCE_DEVICE;
69       break;
70
71     case 1:
72       device = NAME_OF_PSEUDO_RANDOM_DEVICE;
73       break;
74
75     default:
76       device = NAME_OF_RANDOM_DEVICE;
77       break;
78     }
79
80   fd = open (device, O_RDONLY);
81   if (fd < 0)
82     return GC_RANDOM_ERROR;
83
84   do
85     {
86       ssize_t tmp;
87
88       tmp = read (fd, data, datalen);
89
90       if (tmp < 0)
91         {
92           int save_errno = errno;
93           close (fd);
94           errno = save_errno;
95           return GC_RANDOM_ERROR;
96         }
97
98       len += tmp;
99     }
100   while (len < datalen);
101
102   rc = close (fd);
103   if (rc < 0)
104     return GC_RANDOM_ERROR;
105
106   return GC_OK;
107 }
108
109 int
110 gc_nonce (char *data, size_t datalen)
111 {
112   return randomize (0, data, datalen);
113 }
114
115 int
116 gc_pseudo_random (char *data, size_t datalen)
117 {
118   return randomize (1, data, datalen);
119 }
120
121 int
122 gc_random (char *data, size_t datalen)
123 {
124   return randomize (2, data, datalen);
125 }
126
127 /* Memory allocation. */
128
129 void
130 gc_set_allocators (gc_malloc_t func_malloc,
131                    gc_malloc_t secure_malloc,
132                    gc_secure_check_t secure_check,
133                    gc_realloc_t func_realloc, gc_free_t func_free)
134 {
135   return;
136 }
137
138 /* Hashes. */
139
140 int
141 gc_hash_buffer (int hash, const void *in, size_t inlen, char *resbuf)
142 {
143   switch (hash)
144     {
145     case GC_MD5:
146       md5_buffer (in, inlen, resbuf);
147       break;
148
149     default:
150       return GC_INVALID_HASH;
151     }
152
153   return GC_OK;
154 }
155
156 int
157 gc_md5 (const void *in, size_t inlen, void *resbuf)
158 {
159   md5_buffer (in, inlen, resbuf);
160   return 0;
161 }
162
163 int
164 gc_hmac_md5 (const void *key, size_t keylen,
165              const void *in, size_t inlen, char *resbuf)
166 {
167   hmac_md5 (key, keylen, in, inlen, resbuf);
168   return 0;
169 }