aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/md.c')
-rw-r--r--[-rwxr-xr-x]linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/md.c2508
1 files changed, 1254 insertions, 1254 deletions
diff --git a/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/md.c b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/md.c
index a2878cc..59466df 100755..100644
--- a/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/md.c
+++ b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/md.c
@@ -1,1254 +1,1254 @@
1/* md.c - message digest dispatcher 1/* md.c - message digest dispatcher
2 * Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc. 2 * Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
3 * 3 *
4 * This file is part of Libgcrypt. 4 * This file is part of Libgcrypt.
5 * 5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify 6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser general Public License as 7 * it under the terms of the GNU Lesser general Public License as
8 * published by the Free Software Foundation; either version 2.1 of 8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version. 9 * the License, or (at your option) any later version.
10 * 10 *
11 * Libgcrypt is distributed in the hope that it will be useful, 11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details. 14 * GNU Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software 17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */ 19 */
20 20
21#include <config.h> 21#include <config.h>
22#include <stdio.h> 22#include <stdio.h>
23#include <stdlib.h> 23#include <stdlib.h>
24#include <string.h> 24#include <string.h>
25#include <errno.h> 25#include <errno.h>
26#include <assert.h> 26#include <assert.h>
27 27
28#include "g10lib.h" 28#include "g10lib.h"
29#include "cipher.h" 29#include "cipher.h"
30#include "ath.h" 30#include "ath.h"
31 31
32#include "rmd.h" 32#include "rmd.h"
33 33
34static struct digest_table_entry 34static struct digest_table_entry
35{ 35{
36 gcry_md_spec_t *digest; 36 gcry_md_spec_t *digest;
37 unsigned int algorithm; 37 unsigned int algorithm;
38} digest_table[] = 38} digest_table[] =
39 { 39 {
40#if USE_CRC 40#if USE_CRC
41 { &_gcry_digest_spec_crc32, GCRY_MD_CRC32 }, 41 { &_gcry_digest_spec_crc32, GCRY_MD_CRC32 },
42 { &_gcry_digest_spec_crc32_rfc1510, GCRY_MD_CRC32_RFC1510 }, 42 { &_gcry_digest_spec_crc32_rfc1510, GCRY_MD_CRC32_RFC1510 },
43 { &_gcry_digest_spec_crc24_rfc2440, GCRY_MD_CRC24_RFC2440 }, 43 { &_gcry_digest_spec_crc24_rfc2440, GCRY_MD_CRC24_RFC2440 },
44#endif 44#endif
45#if USE_MD4 45#if USE_MD4
46 { &_gcry_digest_spec_md4, GCRY_MD_MD4 }, 46 { &_gcry_digest_spec_md4, GCRY_MD_MD4 },
47#endif 47#endif
48#if USE_MD5 48#if USE_MD5
49 { &_gcry_digest_spec_md5, GCRY_MD_MD5 }, 49 { &_gcry_digest_spec_md5, GCRY_MD_MD5 },
50#endif 50#endif
51#if USE_RMD160 51#if USE_RMD160
52 { &_gcry_digest_spec_rmd160, GCRY_MD_RMD160 }, 52 { &_gcry_digest_spec_rmd160, GCRY_MD_RMD160 },
53#endif 53#endif
54#if USE_SHA1 54#if USE_SHA1
55 { &_gcry_digest_spec_sha1, GCRY_MD_SHA1 }, 55 { &_gcry_digest_spec_sha1, GCRY_MD_SHA1 },
56#endif 56#endif
57#if USE_SHA256 57#if USE_SHA256
58 { &_gcry_digest_spec_sha256, GCRY_MD_SHA256 }, 58 { &_gcry_digest_spec_sha256, GCRY_MD_SHA256 },
59#endif 59#endif
60#if USE_SHA512 60#if USE_SHA512
61 { &_gcry_digest_spec_sha512, GCRY_MD_SHA512 }, 61 { &_gcry_digest_spec_sha512, GCRY_MD_SHA512 },
62 { &_gcry_digest_spec_sha384, GCRY_MD_SHA384 }, 62 { &_gcry_digest_spec_sha384, GCRY_MD_SHA384 },
63#endif 63#endif
64#if USE_TIGER 64#if USE_TIGER
65 { &_gcry_digest_spec_tiger, GCRY_MD_TIGER }, 65 { &_gcry_digest_spec_tiger, GCRY_MD_TIGER },
66#endif 66#endif
67 { NULL }, 67 { NULL },
68 }; 68 };
69 69
70/* List of registered digests. */ 70/* List of registered digests. */
71static gcry_module_t digests_registered; 71static gcry_module_t digests_registered;
72 72
73/* This is the lock protecting DIGESTS_REGISTERED. */ 73/* This is the lock protecting DIGESTS_REGISTERED. */
74static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER; 74static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER;
75 75
76/* Flag to check wether the default ciphers have already been 76/* Flag to check wether the default ciphers have already been
77 registered. */ 77 registered. */
78static int default_digests_registered; 78static int default_digests_registered;
79 79
80typedef struct gcry_md_list 80typedef struct gcry_md_list
81{ 81{
82 gcry_md_spec_t *digest; 82 gcry_md_spec_t *digest;
83 gcry_module_t module; 83 gcry_module_t module;
84 struct gcry_md_list *next; 84 struct gcry_md_list *next;
85 size_t actual_struct_size; /* Allocated size of this structure. */ 85 size_t actual_struct_size; /* Allocated size of this structure. */
86 PROPERLY_ALIGNED_TYPE context; 86 PROPERLY_ALIGNED_TYPE context;
87} GcryDigestEntry; 87} GcryDigestEntry;
88 88
89/* this structure is put right after the gcry_md_hd_t buffer, so that 89/* this structure is put right after the gcry_md_hd_t buffer, so that
90 * only one memory block is needed. */ 90 * only one memory block is needed. */
91struct gcry_md_context 91struct gcry_md_context
92{ 92{
93 int magic; 93 int magic;
94 size_t actual_handle_size; /* Allocated size of this handle. */ 94 size_t actual_handle_size; /* Allocated size of this handle. */
95 int secure; 95 int secure;
96 FILE *debug; 96 FILE *debug;
97 int finalized; 97 int finalized;
98 GcryDigestEntry *list; 98 GcryDigestEntry *list;
99 byte *macpads; 99 byte *macpads;
100}; 100};
101 101
102 102
103#define CTX_MAGIC_NORMAL 0x11071961 103#define CTX_MAGIC_NORMAL 0x11071961
104#define CTX_MAGIC_SECURE 0x16917011 104#define CTX_MAGIC_SECURE 0x16917011
105 105
106/* Convenient macro for registering the default digests. */ 106/* Convenient macro for registering the default digests. */
107#define REGISTER_DEFAULT_DIGESTS \ 107#define REGISTER_DEFAULT_DIGESTS \
108 do \ 108 do \
109 { \ 109 { \
110 ath_mutex_lock (&digests_registered_lock); \ 110 ath_mutex_lock (&digests_registered_lock); \
111 if (! default_digests_registered) \ 111 if (! default_digests_registered) \
112 { \ 112 { \
113 gcry_md_register_default (); \ 113 gcry_md_register_default (); \
114 default_digests_registered = 1; \ 114 default_digests_registered = 1; \
115 } \ 115 } \
116 ath_mutex_unlock (&digests_registered_lock); \ 116 ath_mutex_unlock (&digests_registered_lock); \
117 } \ 117 } \
118 while (0) 118 while (0)
119 119
120 120
121static const char * digest_algo_to_string( int algo ); 121static const char * digest_algo_to_string( int algo );
122static gcry_err_code_t check_digest_algo (int algo); 122static gcry_err_code_t check_digest_algo (int algo);
123static gcry_err_code_t md_open (gcry_md_hd_t *h, int algo, 123static gcry_err_code_t md_open (gcry_md_hd_t *h, int algo,
124 int secure, int hmac); 124 int secure, int hmac);
125static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo); 125static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
126static gcry_err_code_t md_copy (gcry_md_hd_t a, gcry_md_hd_t *b); 126static gcry_err_code_t md_copy (gcry_md_hd_t a, gcry_md_hd_t *b);
127static void md_close (gcry_md_hd_t a); 127static void md_close (gcry_md_hd_t a);
128static void md_write (gcry_md_hd_t a, byte *inbuf, size_t inlen); 128static void md_write (gcry_md_hd_t a, byte *inbuf, size_t inlen);
129static void md_final(gcry_md_hd_t a); 129static void md_final(gcry_md_hd_t a);
130static byte *md_read( gcry_md_hd_t a, int algo ); 130static byte *md_read( gcry_md_hd_t a, int algo );
131static int md_get_algo( gcry_md_hd_t a ); 131static int md_get_algo( gcry_md_hd_t a );
132static int md_digest_length( int algo ); 132static int md_digest_length( int algo );
133static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen ); 133static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen );
134static void md_start_debug( gcry_md_hd_t a, char *suffix ); 134static void md_start_debug( gcry_md_hd_t a, char *suffix );
135static void md_stop_debug( gcry_md_hd_t a ); 135static void md_stop_debug( gcry_md_hd_t a );
136 136
137 137
138 138
139 139
140/* Internal function. Register all the ciphers included in 140/* Internal function. Register all the ciphers included in
141 CIPHER_TABLE. Returns zero on success or an error code. */ 141 CIPHER_TABLE. Returns zero on success or an error code. */
142static void 142static void
143gcry_md_register_default (void) 143gcry_md_register_default (void)
144{ 144{
145 gcry_err_code_t err = 0; 145 gcry_err_code_t err = 0;
146 int i; 146 int i;
147 147
148 for (i = 0; (! err) && digest_table[i].digest; i++) 148 for (i = 0; (! err) && digest_table[i].digest; i++)
149 err = _gcry_module_add (&digests_registered, 149 err = _gcry_module_add (&digests_registered,
150 digest_table[i].algorithm, 150 digest_table[i].algorithm,
151 (void *) digest_table[i].digest, 151 (void *) digest_table[i].digest,
152 NULL); 152 NULL);
153 153
154 if (err) 154 if (err)
155 BUG (); 155 BUG ();
156} 156}
157 157
158/* Internal callback function. */ 158/* Internal callback function. */
159static int 159static int
160gcry_md_lookup_func_name (void *spec, void *data) 160gcry_md_lookup_func_name (void *spec, void *data)
161{ 161{
162 gcry_md_spec_t *digest = (gcry_md_spec_t *) spec; 162 gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
163 char *name = (char *) data; 163 char *name = (char *) data;
164 164
165 return (! stricmp (digest->name, name)); 165 return (! stricmp (digest->name, name));
166} 166}
167 167
168/* Internal callback function. Used via _gcry_module_lookup. */ 168/* Internal callback function. Used via _gcry_module_lookup. */
169static int 169static int
170gcry_md_lookup_func_oid (void *spec, void *data) 170gcry_md_lookup_func_oid (void *spec, void *data)
171{ 171{
172 gcry_md_spec_t *digest = (gcry_md_spec_t *) spec; 172 gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
173 char *oid = (char *) data; 173 char *oid = (char *) data;
174 gcry_md_oid_spec_t *oid_specs = digest->oids; 174 gcry_md_oid_spec_t *oid_specs = digest->oids;
175 int ret = 0, i; 175 int ret = 0, i;
176 176
177 if (oid_specs) 177 if (oid_specs)
178 { 178 {
179 for (i = 0; oid_specs[i].oidstring && (! ret); i++) 179 for (i = 0; oid_specs[i].oidstring && (! ret); i++)
180 if (! stricmp (oid, oid_specs[i].oidstring)) 180 if (! stricmp (oid, oid_specs[i].oidstring))
181 ret = 1; 181 ret = 1;
182 } 182 }
183 183
184 return ret; 184 return ret;
185} 185}
186 186
187/* Internal function. Lookup a digest entry by it's name. */ 187/* Internal function. Lookup a digest entry by it's name. */
188static gcry_module_t 188static gcry_module_t
189gcry_md_lookup_name (const char *name) 189gcry_md_lookup_name (const char *name)
190{ 190{
191 gcry_module_t digest; 191 gcry_module_t digest;
192 192
193 digest = _gcry_module_lookup (digests_registered, (void *) name, 193 digest = _gcry_module_lookup (digests_registered, (void *) name,
194 gcry_md_lookup_func_name); 194 gcry_md_lookup_func_name);
195 195
196 return digest; 196 return digest;
197} 197}
198 198
199/* Internal function. Lookup a cipher entry by it's oid. */ 199/* Internal function. Lookup a cipher entry by it's oid. */
200static gcry_module_t 200static gcry_module_t
201gcry_md_lookup_oid (const char *oid) 201gcry_md_lookup_oid (const char *oid)
202{ 202{
203 gcry_module_t digest; 203 gcry_module_t digest;
204 204
205 digest = _gcry_module_lookup (digests_registered, (void *) oid, 205 digest = _gcry_module_lookup (digests_registered, (void *) oid,
206 gcry_md_lookup_func_oid); 206 gcry_md_lookup_func_oid);
207 207
208 return digest; 208 return digest;
209} 209}
210 210
211/* Register a new digest module whose specification can be found in 211/* Register a new digest module whose specification can be found in
212 DIGEST. On success, a new algorithm ID is stored in ALGORITHM_ID 212 DIGEST. On success, a new algorithm ID is stored in ALGORITHM_ID
213 and a pointer representhing this module is stored in MODULE. */ 213 and a pointer representhing this module is stored in MODULE. */
214gcry_error_t 214gcry_error_t
215gcry_md_register (gcry_md_spec_t *digest, 215gcry_md_register (gcry_md_spec_t *digest,
216 unsigned int *algorithm_id, 216 unsigned int *algorithm_id,
217 gcry_module_t *module) 217 gcry_module_t *module)
218{ 218{
219 gcry_err_code_t err = 0; 219 gcry_err_code_t err = 0;
220 gcry_module_t mod; 220 gcry_module_t mod;
221 221
222 ath_mutex_lock (&digests_registered_lock); 222 ath_mutex_lock (&digests_registered_lock);
223 err = _gcry_module_add (&digests_registered, 0, 223 err = _gcry_module_add (&digests_registered, 0,
224 (void *) digest, &mod); 224 (void *) digest, &mod);
225 ath_mutex_unlock (&digests_registered_lock); 225 ath_mutex_unlock (&digests_registered_lock);
226 226
227 if (! err) 227 if (! err)
228 { 228 {
229 *module = mod; 229 *module = mod;
230 *algorithm_id = mod->mod_id; 230 *algorithm_id = mod->mod_id;
231 } 231 }
232 232
233 return gcry_error (err); 233 return gcry_error (err);
234} 234}
235 235
236/* Unregister the digest identified by ID, which must have been 236/* Unregister the digest identified by ID, which must have been
237 registered with gcry_digest_register. */ 237 registered with gcry_digest_register. */
238void 238void
239gcry_md_unregister (gcry_module_t module) 239gcry_md_unregister (gcry_module_t module)
240{ 240{
241 ath_mutex_lock (&digests_registered_lock); 241 ath_mutex_lock (&digests_registered_lock);
242 _gcry_module_release (module); 242 _gcry_module_release (module);
243 ath_mutex_unlock (&digests_registered_lock); 243 ath_mutex_unlock (&digests_registered_lock);
244} 244}
245 245
246 246
247static int 247static int
248search_oid (const char *oid, int *algorithm, gcry_md_oid_spec_t *oid_spec) 248search_oid (const char *oid, int *algorithm, gcry_md_oid_spec_t *oid_spec)
249{ 249{
250 gcry_module_t module; 250 gcry_module_t module;
251 int ret = 0; 251 int ret = 0;
252 252
253 if (oid && ((! strncmp (oid, "oid.", 4)) 253 if (oid && ((! strncmp (oid, "oid.", 4))
254 || (! strncmp (oid, "OID.", 4)))) 254 || (! strncmp (oid, "OID.", 4))))
255 oid += 4; 255 oid += 4;
256 256
257 module = gcry_md_lookup_oid (oid); 257 module = gcry_md_lookup_oid (oid);
258 if (module) 258 if (module)
259 { 259 {
260 gcry_md_spec_t *digest = module->spec; 260 gcry_md_spec_t *digest = module->spec;
261 int i; 261 int i;
262 262
263 for (i = 0; digest->oids[i].oidstring && !ret; i++) 263 for (i = 0; digest->oids[i].oidstring && !ret; i++)
264 if (! stricmp (oid, digest->oids[i].oidstring)) 264 if (! stricmp (oid, digest->oids[i].oidstring))
265 { 265 {
266 if (algorithm) 266 if (algorithm)
267 *algorithm = module->mod_id; 267 *algorithm = module->mod_id;
268 if (oid_spec) 268 if (oid_spec)
269 *oid_spec = digest->oids[i]; 269 *oid_spec = digest->oids[i];
270 ret = 1; 270 ret = 1;
271 } 271 }
272 _gcry_module_release (module); 272 _gcry_module_release (module);
273 } 273 }
274 274
275 return ret; 275 return ret;
276} 276}
277 277
278/**************** 278/****************
279 * Map a string to the digest algo 279 * Map a string to the digest algo
280 */ 280 */
281int 281int
282gcry_md_map_name (const char *string) 282gcry_md_map_name (const char *string)
283{ 283{
284 gcry_module_t digest; 284 gcry_module_t digest;
285 int ret, algorithm = 0; 285 int ret, algorithm = 0;
286 286
287 if (! string) 287 if (! string)
288 return 0; 288 return 0;
289 289
290 REGISTER_DEFAULT_DIGESTS; 290 REGISTER_DEFAULT_DIGESTS;
291 291
292 /* If the string starts with a digit (optionally prefixed with 292 /* If the string starts with a digit (optionally prefixed with
293 either "OID." or "oid."), we first look into our table of ASN.1 293 either "OID." or "oid."), we first look into our table of ASN.1
294 object identifiers to figure out the algorithm */ 294 object identifiers to figure out the algorithm */
295 295
296 ath_mutex_lock (&digests_registered_lock); 296 ath_mutex_lock (&digests_registered_lock);
297 297
298 ret = search_oid (string, &algorithm, NULL); 298 ret = search_oid (string, &algorithm, NULL);
299 if (! ret) 299 if (! ret)
300 { 300 {
301 /* Not found, search for an acording diget name. */ 301 /* Not found, search for an acording diget name. */
302 digest = gcry_md_lookup_name (string); 302 digest = gcry_md_lookup_name (string);
303 if (digest) 303 if (digest)
304 { 304 {
305 algorithm = digest->mod_id; 305 algorithm = digest->mod_id;
306 _gcry_module_release (digest); 306 _gcry_module_release (digest);
307 } 307 }
308 } 308 }
309 ath_mutex_unlock (&digests_registered_lock); 309 ath_mutex_unlock (&digests_registered_lock);
310 310
311 return algorithm; 311 return algorithm;
312} 312}
313 313
314 314
315/**************** 315/****************
316 * Map a digest algo to a string 316 * Map a digest algo to a string
317 */ 317 */
318static const char * 318static const char *
319digest_algo_to_string (int algorithm) 319digest_algo_to_string (int algorithm)
320{ 320{
321 const char *name = NULL; 321 const char *name = NULL;
322 gcry_module_t digest; 322 gcry_module_t digest;
323 323
324 REGISTER_DEFAULT_DIGESTS; 324 REGISTER_DEFAULT_DIGESTS;
325 325
326 ath_mutex_lock (&digests_registered_lock); 326 ath_mutex_lock (&digests_registered_lock);
327 digest = _gcry_module_lookup_id (digests_registered, algorithm); 327 digest = _gcry_module_lookup_id (digests_registered, algorithm);
328 if (digest) 328 if (digest)
329 { 329 {
330 name = ((gcry_md_spec_t *) digest->spec)->name; 330 name = ((gcry_md_spec_t *) digest->spec)->name;
331 _gcry_module_release (digest); 331 _gcry_module_release (digest);
332 } 332 }
333 ath_mutex_unlock (&digests_registered_lock); 333 ath_mutex_unlock (&digests_registered_lock);
334 334
335 return name; 335 return name;
336} 336}
337 337
338/**************** 338/****************
339 * This function simply returns the name of the algorithm or some constant 339 * This function simply returns the name of the algorithm or some constant
340 * string when there is no algo. It will never return NULL. 340 * string when there is no algo. It will never return NULL.
341 * Use the macro gcry_md_test_algo() to check whether the algorithm 341 * Use the macro gcry_md_test_algo() to check whether the algorithm
342 * is valid. 342 * is valid.
343 */ 343 */
344const char * 344const char *
345gcry_md_algo_name (int algorithm) 345gcry_md_algo_name (int algorithm)
346{ 346{
347 const char *s = digest_algo_to_string (algorithm); 347 const char *s = digest_algo_to_string (algorithm);
348 return s ? s : "?"; 348 return s ? s : "?";
349} 349}
350 350
351 351
352static gcry_err_code_t 352static gcry_err_code_t
353check_digest_algo (int algorithm) 353check_digest_algo (int algorithm)
354{ 354{
355 gcry_err_code_t rc = 0; 355 gcry_err_code_t rc = 0;
356 gcry_module_t digest; 356 gcry_module_t digest;
357 357
358 REGISTER_DEFAULT_DIGESTS; 358 REGISTER_DEFAULT_DIGESTS;
359 359
360 ath_mutex_lock (&digests_registered_lock); 360 ath_mutex_lock (&digests_registered_lock);
361 digest = _gcry_module_lookup_id (digests_registered, algorithm); 361 digest = _gcry_module_lookup_id (digests_registered, algorithm);
362 if (digest) 362 if (digest)
363 _gcry_module_release (digest); 363 _gcry_module_release (digest);
364 else 364 else
365 rc = GPG_ERR_DIGEST_ALGO; 365 rc = GPG_ERR_DIGEST_ALGO;
366 ath_mutex_unlock (&digests_registered_lock); 366 ath_mutex_unlock (&digests_registered_lock);
367 367
368 return rc; 368 return rc;
369} 369}
370 370
371 371
372 372
373/**************** 373/****************
374 * Open a message digest handle for use with algorithm ALGO. 374 * Open a message digest handle for use with algorithm ALGO.
375 * More algorithms may be added by md_enable(). The initial algorithm 375 * More algorithms may be added by md_enable(). The initial algorithm
376 * may be 0. 376 * may be 0.
377 */ 377 */
378static gcry_err_code_t 378static gcry_err_code_t
379md_open (gcry_md_hd_t *h, int algo, int secure, int hmac) 379md_open (gcry_md_hd_t *h, int algo, int secure, int hmac)
380{ 380{
381 gcry_err_code_t err = GPG_ERR_NO_ERROR; 381 gcry_err_code_t err = GPG_ERR_NO_ERROR;
382 int bufsize = secure ? 512 : 1024; 382 int bufsize = secure ? 512 : 1024;
383 struct gcry_md_context *ctx; 383 struct gcry_md_context *ctx;
384 gcry_md_hd_t hd; 384 gcry_md_hd_t hd;
385 size_t n; 385 size_t n;
386 386
387 /* Allocate a memory area to hold the caller visible buffer with it's 387 /* Allocate a memory area to hold the caller visible buffer with it's
388 * control information and the data required by this module. Set the 388 * control information and the data required by this module. Set the
389 * context pointer at the beginning to this area. 389 * context pointer at the beginning to this area.
390 * We have to use this strange scheme because we want to hide the 390 * We have to use this strange scheme because we want to hide the
391 * internal data but have a variable sized buffer. 391 * internal data but have a variable sized buffer.
392 * 392 *
393 * +---+------+---........------+-------------+ 393 * +---+------+---........------+-------------+
394 * !ctx! bctl ! buffer ! private ! 394 * !ctx! bctl ! buffer ! private !
395 * +---+------+---........------+-------------+ 395 * +---+------+---........------+-------------+
396 * ! ^ 396 * ! ^
397 * !---------------------------! 397 * !---------------------------!
398 * 398 *
399 * We have to make sure that private is well aligned. 399 * We have to make sure that private is well aligned.
400 */ 400 */
401 n = sizeof (struct gcry_md_handle) + bufsize; 401 n = sizeof (struct gcry_md_handle) + bufsize;
402 n = ((n + sizeof (PROPERLY_ALIGNED_TYPE) - 1) 402 n = ((n + sizeof (PROPERLY_ALIGNED_TYPE) - 1)
403 / sizeof (PROPERLY_ALIGNED_TYPE)) * sizeof (PROPERLY_ALIGNED_TYPE); 403 / sizeof (PROPERLY_ALIGNED_TYPE)) * sizeof (PROPERLY_ALIGNED_TYPE);
404 404
405 /* Allocate and set the Context pointer to the private data */ 405 /* Allocate and set the Context pointer to the private data */
406 if (secure) 406 if (secure)
407 hd = gcry_malloc_secure (n + sizeof (struct gcry_md_context)); 407 hd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
408 else 408 else
409 hd = gcry_malloc (n + sizeof (struct gcry_md_context)); 409 hd = gcry_malloc (n + sizeof (struct gcry_md_context));
410 410
411 if (! hd) 411 if (! hd)
412 err = gpg_err_code_from_errno (errno); 412 err = gpg_err_code_from_errno (errno);
413 413
414 if (! err) 414 if (! err)
415 { 415 {
416 hd->ctx = ctx = (struct gcry_md_context *) ((char *) hd + n); 416 hd->ctx = ctx = (struct gcry_md_context *) ((char *) hd + n);
417 /* Setup the globally visible data (bctl in the diagram).*/ 417 /* Setup the globally visible data (bctl in the diagram).*/
418 hd->bufsize = n - sizeof (struct gcry_md_handle) + 1; 418 hd->bufsize = n - sizeof (struct gcry_md_handle) + 1;
419 hd->bufpos = 0; 419 hd->bufpos = 0;
420 420
421 /* Initialize the private data. */ 421 /* Initialize the private data. */
422 memset (hd->ctx, 0, sizeof *hd->ctx); 422 memset (hd->ctx, 0, sizeof *hd->ctx);
423 ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL; 423 ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
424 ctx->actual_handle_size = n + sizeof (struct gcry_md_context); 424 ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
425 ctx->secure = secure; 425 ctx->secure = secure;
426 426
427 if (hmac) 427 if (hmac)
428 { 428 {
429 ctx->macpads = gcry_malloc_secure (128); 429 ctx->macpads = gcry_malloc_secure (128);
430 if (! ctx->macpads) 430 if (! ctx->macpads)
431 { 431 {
432 md_close (hd); 432 md_close (hd);
433 err = gpg_err_code_from_errno (errno); 433 err = gpg_err_code_from_errno (errno);
434 } 434 }
435 } 435 }
436 } 436 }
437 437
438 if (! err) 438 if (! err)
439 { 439 {
440 /* FIXME: should we really do that? - yes [-wk] */ 440 /* FIXME: should we really do that? - yes [-wk] */
441 _gcry_fast_random_poll (); 441 _gcry_fast_random_poll ();
442 442
443 if (algo) 443 if (algo)
444 { 444 {
445 err = md_enable (hd, algo); 445 err = md_enable (hd, algo);
446 if (err) 446 if (err)
447 md_close (hd); 447 md_close (hd);
448 } 448 }
449 } 449 }
450 450
451 if (! err) 451 if (! err)
452 *h = hd; 452 *h = hd;
453 453
454 return err; 454 return err;
455} 455}
456 456
457/* Create a message digest object for algorithm ALGO. FLAGS may be 457/* Create a message digest object for algorithm ALGO. FLAGS may be
458 given as an bitwise OR of the gcry_md_flags values. ALGO may be 458 given as an bitwise OR of the gcry_md_flags values. ALGO may be
459 given as 0 if the algorithms to be used are later set using 459 given as 0 if the algorithms to be used are later set using
460 gcry_md_enable. H is guaranteed to be a valid handle or NULL on 460 gcry_md_enable. H is guaranteed to be a valid handle or NULL on
461 error. */ 461 error. */
462gcry_error_t 462gcry_error_t
463gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags) 463gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
464{ 464{
465 gcry_err_code_t err = GPG_ERR_NO_ERROR; 465 gcry_err_code_t err = GPG_ERR_NO_ERROR;
466 gcry_md_hd_t hd; 466 gcry_md_hd_t hd;
467 467
468 if ((flags & ~(GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC))) 468 if ((flags & ~(GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC)))
469 err = GPG_ERR_INV_ARG; 469 err = GPG_ERR_INV_ARG;
470 else 470 else
471 { 471 {
472 err = md_open (&hd, algo, (flags & GCRY_MD_FLAG_SECURE), 472 err = md_open (&hd, algo, (flags & GCRY_MD_FLAG_SECURE),
473 (flags & GCRY_MD_FLAG_HMAC)); 473 (flags & GCRY_MD_FLAG_HMAC));
474 } 474 }
475 475
476 *h = err? NULL : hd; 476 *h = err? NULL : hd;
477 return gcry_error (err); 477 return gcry_error (err);
478} 478}
479 479
480 480
481 481
482static gcry_err_code_t 482static gcry_err_code_t
483md_enable (gcry_md_hd_t hd, int algorithm) 483md_enable (gcry_md_hd_t hd, int algorithm)
484{ 484{
485 struct gcry_md_context *h = hd->ctx; 485 struct gcry_md_context *h = hd->ctx;
486 gcry_md_spec_t *digest = NULL; 486 gcry_md_spec_t *digest = NULL;
487 GcryDigestEntry *entry; 487 GcryDigestEntry *entry;
488 gcry_module_t module; 488 gcry_module_t module;
489 gcry_err_code_t err = 0; 489 gcry_err_code_t err = 0;
490 490
491 for (entry = h->list; entry; entry = entry->next) 491 for (entry = h->list; entry; entry = entry->next)
492 if (entry->module->mod_id == algorithm) 492 if (entry->module->mod_id == algorithm)
493 return err; /* already enabled */ 493 return err; /* already enabled */
494 494
495 REGISTER_DEFAULT_DIGESTS; 495 REGISTER_DEFAULT_DIGESTS;
496 496
497 ath_mutex_lock (&digests_registered_lock); 497 ath_mutex_lock (&digests_registered_lock);
498 module = _gcry_module_lookup_id (digests_registered, algorithm); 498 module = _gcry_module_lookup_id (digests_registered, algorithm);
499 ath_mutex_unlock (&digests_registered_lock); 499 ath_mutex_unlock (&digests_registered_lock);
500 if (! module) 500 if (! module)
501 { 501 {
502 log_debug ("md_enable: algorithm %d not available\n", algorithm); 502 log_debug ("md_enable: algorithm %d not available\n", algorithm);
503 err = GPG_ERR_DIGEST_ALGO; 503 err = GPG_ERR_DIGEST_ALGO;
504 } 504 }
505 else 505 else
506 digest = (gcry_md_spec_t *) module->spec; 506 digest = (gcry_md_spec_t *) module->spec;
507 507
508 if (! err) 508 if (! err)
509 { 509 {
510 size_t size = (sizeof (*entry) 510 size_t size = (sizeof (*entry)
511 + digest->contextsize 511 + digest->contextsize
512 - sizeof (entry->context)); 512 - sizeof (entry->context));
513 513
514 /* And allocate a new list entry. */ 514 /* And allocate a new list entry. */
515 if (h->secure) 515 if (h->secure)
516 entry = gcry_malloc_secure (size); 516 entry = gcry_malloc_secure (size);
517 else 517 else
518 entry = gcry_malloc (size); 518 entry = gcry_malloc (size);
519 519
520 if (! entry) 520 if (! entry)
521 err = gpg_err_code_from_errno (errno); 521 err = gpg_err_code_from_errno (errno);
522 else 522 else
523 { 523 {
524 entry->digest = digest; 524 entry->digest = digest;
525 entry->module = module; 525 entry->module = module;
526 entry->next = h->list; 526 entry->next = h->list;
527 entry->actual_struct_size = size; 527 entry->actual_struct_size = size;
528 h->list = entry; 528 h->list = entry;
529 529
530 /* And init this instance. */ 530 /* And init this instance. */
531 entry->digest->init (&entry->context.c); 531 entry->digest->init (&entry->context.c);
532 } 532 }
533 } 533 }
534 534
535 if (err) 535 if (err)
536 { 536 {
537 if (module) 537 if (module)
538 { 538 {
539 ath_mutex_lock (&digests_registered_lock); 539 ath_mutex_lock (&digests_registered_lock);
540 _gcry_module_release (module); 540 _gcry_module_release (module);
541 ath_mutex_unlock (&digests_registered_lock); 541 ath_mutex_unlock (&digests_registered_lock);
542 } 542 }
543 } 543 }
544 544
545 return err; 545 return err;
546} 546}
547 547
548 548
549gcry_error_t 549gcry_error_t
550gcry_md_enable (gcry_md_hd_t hd, int algorithm) 550gcry_md_enable (gcry_md_hd_t hd, int algorithm)
551{ 551{
552 gcry_err_code_t err = md_enable (hd, algorithm); 552 gcry_err_code_t err = md_enable (hd, algorithm);
553 return gcry_error (err); 553 return gcry_error (err);
554} 554}
555 555
556static gcry_err_code_t 556static gcry_err_code_t
557md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd) 557md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
558{ 558{
559 gcry_err_code_t err = GPG_ERR_NO_ERROR; 559 gcry_err_code_t err = GPG_ERR_NO_ERROR;
560 struct gcry_md_context *a = ahd->ctx; 560 struct gcry_md_context *a = ahd->ctx;
561 struct gcry_md_context *b; 561 struct gcry_md_context *b;
562 GcryDigestEntry *ar, *br; 562 GcryDigestEntry *ar, *br;
563 gcry_md_hd_t bhd; 563 gcry_md_hd_t bhd;
564 size_t n; 564 size_t n;
565 565
566 if (ahd->bufpos) 566 if (ahd->bufpos)
567 md_write (ahd, NULL, 0); 567 md_write (ahd, NULL, 0);
568 568
569 n = (char *) ahd->ctx - (char *) ahd; 569 n = (char *) ahd->ctx - (char *) ahd;
570 if (a->secure) 570 if (a->secure)
571 bhd = gcry_malloc_secure (n + sizeof (struct gcry_md_context)); 571 bhd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
572 else 572 else
573 bhd = gcry_malloc (n + sizeof (struct gcry_md_context)); 573 bhd = gcry_malloc (n + sizeof (struct gcry_md_context));
574 574
575 if (! bhd) 575 if (! bhd)
576 err = gpg_err_code_from_errno (errno); 576 err = gpg_err_code_from_errno (errno);
577 577
578 if (! err) 578 if (! err)
579 { 579 {
580 bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n); 580 bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n);
581 /* No need to copy the buffer due to the write above. */ 581 /* No need to copy the buffer due to the write above. */
582 assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1)); 582 assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
583 bhd->bufsize = ahd->bufsize; 583 bhd->bufsize = ahd->bufsize;
584 bhd->bufpos = 0; 584 bhd->bufpos = 0;
585 assert (! ahd->bufpos); 585 assert (! ahd->bufpos);
586 memcpy (b, a, sizeof *a); 586 memcpy (b, a, sizeof *a);
587 b->list = NULL; 587 b->list = NULL;
588 b->debug = NULL; 588 b->debug = NULL;
589 if (a->macpads) 589 if (a->macpads)
590 { 590 {
591 b->macpads = gcry_malloc_secure (128); 591 b->macpads = gcry_malloc_secure (128);
592 if (! b->macpads) 592 if (! b->macpads)
593 { 593 {
594 md_close (bhd); 594 md_close (bhd);
595 err = gpg_err_code_from_errno (errno); 595 err = gpg_err_code_from_errno (errno);
596 } 596 }
597 else 597 else
598 memcpy (b->macpads, a->macpads, 128); 598 memcpy (b->macpads, a->macpads, 128);
599 } 599 }
600 } 600 }
601 601
602 /* Copy the complete list of algorithms. The copied list is 602 /* Copy the complete list of algorithms. The copied list is
603 reversed, but that doesn't matter. */ 603 reversed, but that doesn't matter. */
604 if (! err) 604 if (! err)
605 for (ar = a->list; ar; ar = ar->next) 605 for (ar = a->list; ar; ar = ar->next)
606 { 606 {
607 if (a->secure) 607 if (a->secure)
608 br = gcry_xmalloc_secure (sizeof *br 608 br = gcry_xmalloc_secure (sizeof *br
609 + ar->digest->contextsize 609 + ar->digest->contextsize
610 - sizeof(ar->context)); 610 - sizeof(ar->context));
611 else 611 else
612 br = gcry_xmalloc (sizeof *br 612 br = gcry_xmalloc (sizeof *br
613 + ar->digest->contextsize 613 + ar->digest->contextsize
614 - sizeof (ar->context)); 614 - sizeof (ar->context));
615 memcpy (br, ar, 615 memcpy (br, ar,
616 sizeof (*br) + ar->digest->contextsize - sizeof (ar->context)); 616 sizeof (*br) + ar->digest->contextsize - sizeof (ar->context));
617 br->next = b->list; 617 br->next = b->list;
618 b->list = br; 618 b->list = br;
619 619
620 /* Add a reference to the module. */ 620 /* Add a reference to the module. */
621 ath_mutex_lock (&digests_registered_lock); 621 ath_mutex_lock (&digests_registered_lock);
622 _gcry_module_use (br->module); 622 _gcry_module_use (br->module);
623 ath_mutex_unlock (&digests_registered_lock); 623 ath_mutex_unlock (&digests_registered_lock);
624 } 624 }
625 625
626 if (a->debug) 626 if (a->debug)
627 md_start_debug (bhd, "unknown"); 627 md_start_debug (bhd, "unknown");
628 628
629 if (! err) 629 if (! err)
630 *b_hd = bhd; 630 *b_hd = bhd;
631 631
632 return err; 632 return err;
633} 633}
634 634
635gcry_error_t 635gcry_error_t
636gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd) 636gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
637{ 637{
638 gcry_err_code_t err = md_copy (hd, handle); 638 gcry_err_code_t err = md_copy (hd, handle);
639 if (err) 639 if (err)
640 *handle = NULL; 640 *handle = NULL;
641 return gcry_error (err); 641 return gcry_error (err);
642} 642}
643 643
644/* 644/*
645 * Reset all contexts and discard any buffered stuff. This may be used 645 * Reset all contexts and discard any buffered stuff. This may be used
646 * instead of a md_close(); md_open(). 646 * instead of a md_close(); md_open().
647 */ 647 */
648void 648void
649gcry_md_reset (gcry_md_hd_t a) 649gcry_md_reset (gcry_md_hd_t a)
650{ 650{
651 GcryDigestEntry *r; 651 GcryDigestEntry *r;
652 652
653 a->bufpos = a->ctx->finalized = 0; 653 a->bufpos = a->ctx->finalized = 0;
654 654
655 for (r = a->ctx->list; r; r = r->next) 655 for (r = a->ctx->list; r; r = r->next)
656 { 656 {
657 memset (r->context.c, 0, r->digest->contextsize); 657 memset (r->context.c, 0, r->digest->contextsize);
658 (*r->digest->init) (&r->context.c); 658 (*r->digest->init) (&r->context.c);
659 } 659 }
660 if (a->ctx->macpads) 660 if (a->ctx->macpads)
661 md_write (a, a->ctx->macpads, 64); /* inner pad */ 661 md_write (a, a->ctx->macpads, 64); /* inner pad */
662} 662}
663 663
664static void 664static void
665md_close (gcry_md_hd_t a) 665md_close (gcry_md_hd_t a)
666{ 666{
667 GcryDigestEntry *r, *r2; 667 GcryDigestEntry *r, *r2;
668 668
669 if (! a) 669 if (! a)
670 return; 670 return;
671 if (a->ctx->debug) 671 if (a->ctx->debug)
672 md_stop_debug (a); 672 md_stop_debug (a);
673 for (r = a->ctx->list; r; r = r2) 673 for (r = a->ctx->list; r; r = r2)
674 { 674 {
675 r2 = r->next; 675 r2 = r->next;
676 ath_mutex_lock (&digests_registered_lock); 676 ath_mutex_lock (&digests_registered_lock);
677 _gcry_module_release (r->module); 677 _gcry_module_release (r->module);
678 ath_mutex_unlock (&digests_registered_lock); 678 ath_mutex_unlock (&digests_registered_lock);
679 wipememory (r, r->actual_struct_size); 679 wipememory (r, r->actual_struct_size);
680 gcry_free (r); 680 gcry_free (r);
681 } 681 }
682 682
683 if (a->ctx->macpads) 683 if (a->ctx->macpads)
684 { 684 {
685 wipememory (a->ctx->macpads, 128); 685 wipememory (a->ctx->macpads, 128);
686 gcry_free(a->ctx->macpads); 686 gcry_free(a->ctx->macpads);
687 } 687 }
688 688
689 wipememory (a, a->ctx->actual_handle_size); 689 wipememory (a, a->ctx->actual_handle_size);
690 gcry_free(a); 690 gcry_free(a);
691} 691}
692 692
693void 693void
694gcry_md_close (gcry_md_hd_t hd) 694gcry_md_close (gcry_md_hd_t hd)
695{ 695{
696 md_close (hd); 696 md_close (hd);
697} 697}
698 698
699static void 699static void
700md_write (gcry_md_hd_t a, byte *inbuf, size_t inlen) 700md_write (gcry_md_hd_t a, byte *inbuf, size_t inlen)
701{ 701{
702 GcryDigestEntry *r; 702 GcryDigestEntry *r;
703 703
704 if (a->ctx->debug) 704 if (a->ctx->debug)
705 { 705 {
706 if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1) 706 if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1)
707 BUG(); 707 BUG();
708 if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1) 708 if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1)
709 BUG(); 709 BUG();
710 } 710 }
711 711
712 for (r = a->ctx->list; r; r = r->next) 712 for (r = a->ctx->list; r; r = r->next)
713 { 713 {
714 if (a->bufpos) 714 if (a->bufpos)
715 (*r->digest->write) (&r->context.c, a->buf, a->bufpos); 715 (*r->digest->write) (&r->context.c, a->buf, a->bufpos);
716 (*r->digest->write) (&r->context.c, inbuf, inlen); 716 (*r->digest->write) (&r->context.c, inbuf, inlen);
717 } 717 }
718 a->bufpos = 0; 718 a->bufpos = 0;
719} 719}
720 720
721void 721void
722gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen) 722gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
723{ 723{
724 md_write (hd, (unsigned char *) inbuf, inlen); 724 md_write (hd, (unsigned char *) inbuf, inlen);
725} 725}
726 726
727static void 727static void
728md_final (gcry_md_hd_t a) 728md_final (gcry_md_hd_t a)
729{ 729{
730 GcryDigestEntry *r; 730 GcryDigestEntry *r;
731 731
732 if (a->ctx->finalized) 732 if (a->ctx->finalized)
733 return; 733 return;
734 734
735 if (a->bufpos) 735 if (a->bufpos)
736 md_write (a, NULL, 0); 736 md_write (a, NULL, 0);
737 737
738 for (r = a->ctx->list; r; r = r->next) 738 for (r = a->ctx->list; r; r = r->next)
739 (*r->digest->final) (&r->context.c); 739 (*r->digest->final) (&r->context.c);
740 740
741 a->ctx->finalized = 1; 741 a->ctx->finalized = 1;
742 742
743 if (a->ctx->macpads) 743 if (a->ctx->macpads)
744 { 744 {
745 /* Finish the hmac. */ 745 /* Finish the hmac. */
746 int algo = md_get_algo (a); 746 int algo = md_get_algo (a);
747 byte *p = md_read (a, algo); 747 byte *p = md_read (a, algo);
748 size_t dlen = md_digest_length (algo); 748 size_t dlen = md_digest_length (algo);
749 gcry_md_hd_t om; 749 gcry_md_hd_t om;
750 gcry_err_code_t err = md_open (&om, algo, a->ctx->secure, 0); 750 gcry_err_code_t err = md_open (&om, algo, a->ctx->secure, 0);
751 751
752 if (err) 752 if (err)
753 _gcry_fatal_error (err, NULL); 753 _gcry_fatal_error (err, NULL);
754 md_write (om, a->ctx->macpads+64, 64); 754 md_write (om, a->ctx->macpads+64, 64);
755 md_write (om, p, dlen); 755 md_write (om, p, dlen);
756 md_final (om); 756 md_final (om);
757 /* Replace our digest with the mac (they have the same size). */ 757 /* Replace our digest with the mac (they have the same size). */
758 memcpy (p, md_read (om, algo), dlen); 758 memcpy (p, md_read (om, algo), dlen);
759 md_close (om); 759 md_close (om);
760 } 760 }
761} 761}
762 762
763static gcry_err_code_t 763static gcry_err_code_t
764prepare_macpads( gcry_md_hd_t hd, const byte *key, size_t keylen) 764prepare_macpads( gcry_md_hd_t hd, const byte *key, size_t keylen)
765{ 765{
766 int i; 766 int i;
767 int algo = md_get_algo( hd ); 767 int algo = md_get_algo( hd );
768 byte *helpkey = NULL; 768 byte *helpkey = NULL;
769 byte *ipad, *opad; 769 byte *ipad, *opad;
770 770
771 if ( !algo ) 771 if ( !algo )
772 return GPG_ERR_DIGEST_ALGO; /* i.e. no algo enabled */ 772 return GPG_ERR_DIGEST_ALGO; /* i.e. no algo enabled */
773 773
774 if ( keylen > 64 ) 774 if ( keylen > 64 )
775 { 775 {
776 helpkey = gcry_malloc_secure ( md_digest_length( algo ) ); 776 helpkey = gcry_malloc_secure ( md_digest_length( algo ) );
777 if ( !helpkey ) 777 if ( !helpkey )
778 return gpg_err_code_from_errno (errno); 778 return gpg_err_code_from_errno (errno);
779 gcry_md_hash_buffer ( algo, helpkey, key, keylen ); 779 gcry_md_hash_buffer ( algo, helpkey, key, keylen );
780 key = helpkey; 780 key = helpkey;
781 keylen = md_digest_length( algo ); 781 keylen = md_digest_length( algo );
782 assert ( keylen <= 64 ); 782 assert ( keylen <= 64 );
783 } 783 }
784 784
785 memset ( hd->ctx->macpads, 0, 128 ); 785 memset ( hd->ctx->macpads, 0, 128 );
786 ipad = hd->ctx->macpads; 786 ipad = hd->ctx->macpads;
787 opad = hd->ctx->macpads+64; 787 opad = hd->ctx->macpads+64;
788 memcpy ( ipad, key, keylen ); 788 memcpy ( ipad, key, keylen );
789 memcpy ( opad, key, keylen ); 789 memcpy ( opad, key, keylen );
790 for (i=0; i < 64; i++ ) 790 for (i=0; i < 64; i++ )
791 { 791 {
792 ipad[i] ^= 0x36; 792 ipad[i] ^= 0x36;
793 opad[i] ^= 0x5c; 793 opad[i] ^= 0x5c;
794 } 794 }
795 gcry_free( helpkey ); 795 gcry_free( helpkey );
796 796
797 return GPG_ERR_NO_ERROR; 797 return GPG_ERR_NO_ERROR;
798} 798}
799 799
800gcry_error_t 800gcry_error_t
801gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen) 801gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
802{ 802{
803 unsigned char *buf = (unsigned char *)buffer; 803 unsigned char *buf = (unsigned char *)buffer;
804 gcry_err_code_t rc = 0; 804 gcry_err_code_t rc = 0;
805 805
806 switch (cmd) 806 switch (cmd)
807 { 807 {
808 case GCRYCTL_FINALIZE: 808 case GCRYCTL_FINALIZE:
809 md_final (hd); 809 md_final (hd);
810 break; 810 break;
811 case GCRYCTL_SET_KEY: 811 case GCRYCTL_SET_KEY:
812 rc = gcry_err_code (gcry_md_setkey (hd, buf, buflen)); 812 rc = gcry_err_code (gcry_md_setkey (hd, buf, buflen));
813 break; 813 break;
814 case GCRYCTL_START_DUMP: 814 case GCRYCTL_START_DUMP:
815 md_start_debug (hd, (char*)buf); 815 md_start_debug (hd, (char*)buf);
816 break; 816 break;
817 case GCRYCTL_STOP_DUMP: 817 case GCRYCTL_STOP_DUMP:
818 md_stop_debug( hd ); 818 md_stop_debug( hd );
819 break; 819 break;
820 default: 820 default:
821 rc = GPG_ERR_INV_OP; 821 rc = GPG_ERR_INV_OP;
822 } 822 }
823 return gcry_error (rc); 823 return gcry_error (rc);
824} 824}
825 825
826gcry_error_t 826gcry_error_t
827gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen) 827gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
828{ 828{
829 gcry_err_code_t rc = GPG_ERR_NO_ERROR; 829 gcry_err_code_t rc = GPG_ERR_NO_ERROR;
830 830
831 if (! hd->ctx->macpads) 831 if (! hd->ctx->macpads)
832 rc = GPG_ERR_CONFLICT; 832 rc = GPG_ERR_CONFLICT;
833 else 833 else
834 { 834 {
835 rc = prepare_macpads (hd, key, keylen); 835 rc = prepare_macpads (hd, key, keylen);
836 if (! rc) 836 if (! rc)
837 gcry_md_reset (hd); 837 gcry_md_reset (hd);
838 } 838 }
839 839
840 return gcry_error (rc); 840 return gcry_error (rc);
841} 841}
842 842
843 843
844/**************** 844/****************
845 * if ALGO is null get the digest for the used algo (which should be only one) 845 * if ALGO is null get the digest for the used algo (which should be only one)
846 */ 846 */
847static byte * 847static byte *
848md_read( gcry_md_hd_t a, int algo ) 848md_read( gcry_md_hd_t a, int algo )
849{ 849{
850 GcryDigestEntry *r = a->ctx->list; 850 GcryDigestEntry *r = a->ctx->list;
851 851
852 if (! algo) 852 if (! algo)
853 { 853 {
854 /* return the first algorithm */ 854 /* return the first algorithm */
855 if (r && r->next) 855 if (r && r->next)
856 log_debug("more than algorithm in md_read(0)\n"); 856 log_debug("more than algorithm in md_read(0)\n");
857 return r->digest->read( &r->context.c ); 857 return r->digest->read( &r->context.c );
858 } 858 }
859 else 859 else
860 { 860 {
861 for (r = a->ctx->list; r; r = r->next) 861 for (r = a->ctx->list; r; r = r->next)
862 if (r->module->mod_id == algo) 862 if (r->module->mod_id == algo)
863 return r->digest->read (&r->context.c); 863 return r->digest->read (&r->context.c);
864 } 864 }
865 BUG(); 865 BUG();
866 return NULL; 866 return NULL;
867} 867}
868 868
869/* 869/*
870 * Read out the complete digest, this function implictly finalizes 870 * Read out the complete digest, this function implictly finalizes
871 * the hash. 871 * the hash.
872 */ 872 */
873byte * 873byte *
874gcry_md_read (gcry_md_hd_t hd, int algo) 874gcry_md_read (gcry_md_hd_t hd, int algo)
875{ 875{
876 gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0); 876 gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
877 return md_read (hd, algo); 877 return md_read (hd, algo);
878} 878}
879 879
880/**************** 880/****************
881 * This function combines md_final and md_read but keeps the context 881 * This function combines md_final and md_read but keeps the context
882 * intact. This function can be used to calculate intermediate 882 * intact. This function can be used to calculate intermediate
883 * digests. The digest is copied into buffer and the digestlength is 883 * digests. The digest is copied into buffer and the digestlength is
884 * returned. If buffer is NULL only the needed size for buffer is returned. 884 * returned. If buffer is NULL only the needed size for buffer is returned.
885 * buflen gives the max size of buffer. If the buffer is too shourt to 885 * buflen gives the max size of buffer. If the buffer is too shourt to
886 * hold the complete digest, the buffer is filled with as many bytes are 886 * hold the complete digest, the buffer is filled with as many bytes are
887 * possible and this value is returned. 887 * possible and this value is returned.
888 */ 888 */
889#if 0 889#if 0
890static int 890static int
891md_digest( gcry_md_hd_t a, int algo, byte *buffer, int buflen ) 891md_digest( gcry_md_hd_t a, int algo, byte *buffer, int buflen )
892{ 892{
893 struct md_digest_list_s *r = NULL; 893 struct md_digest_list_s *r = NULL;
894 char *context; 894 char *context;
895 char *digest; 895 char *digest;
896 896
897 if( a->bufpos ) 897 if( a->bufpos )
898 md_write( a, NULL, 0 ); 898 md_write( a, NULL, 0 );
899 899
900 if( !algo ) { /* return digest for the first algorithm */ 900 if( !algo ) { /* return digest for the first algorithm */
901 if( (r=a->ctx->list) && r->next ) 901 if( (r=a->ctx->list) && r->next )
902 log_debug("more than algorithm in md_digest(0)\n"); 902 log_debug("more than algorithm in md_digest(0)\n");
903 } 903 }
904 else { 904 else {
905 for(r=a->ctx->list; r; r = r->next ) 905 for(r=a->ctx->list; r; r = r->next )
906 if( r->algo == algo ) 906 if( r->algo == algo )
907 break; 907 break;
908 } 908 }
909 if( !r ) 909 if( !r )
910 BUG(); 910 BUG();
911 911
912 if( !buffer ) 912 if( !buffer )
913 return r->mdlen; 913 return r->mdlen;
914 914
915 /* I don't want to change the interface, so I simply work on a copy 915 /* I don't want to change the interface, so I simply work on a copy
916 * of the context (extra overhead - should be fixed)*/ 916 * of the context (extra overhead - should be fixed)*/
917 context = a->ctx->secure ? gcry_xmalloc_secure( r->contextsize ) 917 context = a->ctx->secure ? gcry_xmalloc_secure( r->contextsize )
918 : gcry_xmalloc( r->contextsize ); 918 : gcry_xmalloc( r->contextsize );
919 memcpy( context, r->context.c, r->contextsize ); 919 memcpy( context, r->context.c, r->contextsize );
920 (*r->digest->final)( context ); 920 (*r->digest->final)( context );
921 digest = (*r->digest->read)( context ); 921 digest = (*r->digest->read)( context );
922 922
923 if( buflen > r->mdlen ) 923 if( buflen > r->mdlen )
924 buflen = r->mdlen; 924 buflen = r->mdlen;
925 memcpy( buffer, digest, buflen ); 925 memcpy( buffer, digest, buflen );
926 926
927 gcry_free(context); 927 gcry_free(context);
928 return buflen; 928 return buflen;
929} 929}
930#endif 930#endif
931 931
932/* 932/*
933 * Read out an intermediate digest. Not yet fucntional. 933 * Read out an intermediate digest. Not yet fucntional.
934 */ 934 */
935gcry_err_code_t 935gcry_err_code_t
936gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen) 936gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
937{ 937{
938 /*md_digest ... */ 938 /*md_digest ... */
939 return GPG_ERR_INTERNAL; 939 return GPG_ERR_INTERNAL;
940} 940}
941 941
942 942
943/* 943/*
944 * Shortcut function to hash a buffer with a given algo. The only 944 * Shortcut function to hash a buffer with a given algo. The only
945 * guaranteed supported algorithms are RIPE-MD160 and SHA-1. The 945 * guaranteed supported algorithms are RIPE-MD160 and SHA-1. The
946 * supplied digest buffer must be large enough to store the resulting 946 * supplied digest buffer must be large enough to store the resulting
947 * hash. No error is returned, the function will abort on an invalid 947 * hash. No error is returned, the function will abort on an invalid
948 * algo. DISABLED_ALGOS are ignored here. */ 948 * algo. DISABLED_ALGOS are ignored here. */
949void 949void
950gcry_md_hash_buffer (int algo, void *digest, 950gcry_md_hash_buffer (int algo, void *digest,
951 const void *buffer, size_t length) 951 const void *buffer, size_t length)
952{ 952{
953 if (algo == GCRY_MD_SHA1) 953 if (algo == GCRY_MD_SHA1)
954 _gcry_sha1_hash_buffer (digest, buffer, length); 954 _gcry_sha1_hash_buffer (digest, buffer, length);
955 else if (algo == GCRY_MD_RMD160) 955 else if (algo == GCRY_MD_RMD160)
956 _gcry_rmd160_hash_buffer (digest, buffer, length); 956 _gcry_rmd160_hash_buffer (digest, buffer, length);
957 else 957 else
958 { 958 {
959 /* For the others we do not have a fast function, so we use the 959 /* For the others we do not have a fast function, so we use the
960 normal functions. */ 960 normal functions. */
961 gcry_md_hd_t h; 961 gcry_md_hd_t h;
962 gpg_err_code_t err = md_open (&h, algo, 0, 0); 962 gpg_err_code_t err = md_open (&h, algo, 0, 0);
963 if (err) 963 if (err)
964 log_bug ("gcry_md_open failed for algo %d: %s", 964 log_bug ("gcry_md_open failed for algo %d: %s",
965 algo, gpg_strerror (gcry_error(err))); 965 algo, gpg_strerror (gcry_error(err)));
966 md_write (h, (byte *) buffer, length); 966 md_write (h, (byte *) buffer, length);
967 md_final (h); 967 md_final (h);
968 memcpy (digest, md_read (h, algo), md_digest_length (algo)); 968 memcpy (digest, md_read (h, algo), md_digest_length (algo));
969 md_close (h); 969 md_close (h);
970 } 970 }
971} 971}
972 972
973static int 973static int
974md_get_algo (gcry_md_hd_t a) 974md_get_algo (gcry_md_hd_t a)
975{ 975{
976 GcryDigestEntry *r = a->ctx->list; 976 GcryDigestEntry *r = a->ctx->list;
977 977
978 if (r && r->next) 978 if (r && r->next)
979 log_error("WARNING: more than algorithm in md_get_algo()\n"); 979 log_error("WARNING: more than algorithm in md_get_algo()\n");
980 return r ? r->module->mod_id : 0; 980 return r ? r->module->mod_id : 0;
981} 981}
982 982
983int 983int
984gcry_md_get_algo (gcry_md_hd_t hd) 984gcry_md_get_algo (gcry_md_hd_t hd)
985{ 985{
986 return md_get_algo (hd); 986 return md_get_algo (hd);
987} 987}
988 988
989 989
990/**************** 990/****************
991 * Return the length of the digest 991 * Return the length of the digest
992 */ 992 */
993static int 993static int
994md_digest_length (int algorithm) 994md_digest_length (int algorithm)
995{ 995{
996 gcry_module_t digest; 996 gcry_module_t digest;
997 int mdlen = 0; 997 int mdlen = 0;
998 998
999 REGISTER_DEFAULT_DIGESTS; 999 REGISTER_DEFAULT_DIGESTS;
1000 1000
1001 ath_mutex_lock (&digests_registered_lock); 1001 ath_mutex_lock (&digests_registered_lock);
1002 digest = _gcry_module_lookup_id (digests_registered, algorithm); 1002 digest = _gcry_module_lookup_id (digests_registered, algorithm);
1003 if (digest) 1003 if (digest)
1004 { 1004 {
1005 mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen; 1005 mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
1006 _gcry_module_release (digest); 1006 _gcry_module_release (digest);
1007 } 1007 }
1008 ath_mutex_unlock (&digests_registered_lock); 1008 ath_mutex_unlock (&digests_registered_lock);
1009 1009
1010 return mdlen; 1010 return mdlen;
1011} 1011}
1012 1012
1013/**************** 1013/****************
1014 * Return the length of the digest in bytes. 1014 * Return the length of the digest in bytes.
1015 * This function will return 0 in case of errors. 1015 * This function will return 0 in case of errors.
1016 */ 1016 */
1017unsigned int 1017unsigned int
1018gcry_md_get_algo_dlen (int algorithm) 1018gcry_md_get_algo_dlen (int algorithm)
1019{ 1019{
1020 return md_digest_length (algorithm); 1020 return md_digest_length (algorithm);
1021} 1021}
1022 1022
1023 1023
1024/* Hmmm: add a mode to enumerate the OIDs 1024/* Hmmm: add a mode to enumerate the OIDs
1025 * to make g10/sig-check.c more portable */ 1025 * to make g10/sig-check.c more portable */
1026static const byte * 1026static const byte *
1027md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen) 1027md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
1028{ 1028{
1029 const byte *asnoid = NULL; 1029 const byte *asnoid = NULL;
1030 gcry_module_t digest; 1030 gcry_module_t digest;
1031 1031
1032 REGISTER_DEFAULT_DIGESTS; 1032 REGISTER_DEFAULT_DIGESTS;
1033 1033
1034 ath_mutex_lock (&digests_registered_lock); 1034 ath_mutex_lock (&digests_registered_lock);
1035 digest = _gcry_module_lookup_id (digests_registered, algorithm); 1035 digest = _gcry_module_lookup_id (digests_registered, algorithm);
1036 if (digest) 1036 if (digest)
1037 { 1037 {
1038 if (asnlen) 1038 if (asnlen)
1039 *asnlen = ((gcry_md_spec_t *) digest->spec)->asnlen; 1039 *asnlen = ((gcry_md_spec_t *) digest->spec)->asnlen;
1040 if (mdlen) 1040 if (mdlen)
1041 *mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen; 1041 *mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
1042 asnoid = ((gcry_md_spec_t *) digest->spec)->asnoid; 1042 asnoid = ((gcry_md_spec_t *) digest->spec)->asnoid;
1043 _gcry_module_release (digest); 1043 _gcry_module_release (digest);
1044 } 1044 }
1045 else 1045 else
1046 log_bug ("no ASN.1 OID for md algo %d\n", algorithm); 1046 log_bug ("no ASN.1 OID for md algo %d\n", algorithm);
1047 ath_mutex_unlock (&digests_registered_lock); 1047 ath_mutex_unlock (&digests_registered_lock);
1048 1048
1049 return asnoid; 1049 return asnoid;
1050} 1050}
1051 1051
1052 1052
1053 1053
1054/**************** 1054/****************
1055 * Return information about the given cipher algorithm 1055 * Return information about the given cipher algorithm
1056 * WHAT select the kind of information returned: 1056 * WHAT select the kind of information returned:
1057 * GCRYCTL_TEST_ALGO: 1057 * GCRYCTL_TEST_ALGO:
1058 * Returns 0 when the specified algorithm is available for use. 1058 * Returns 0 when the specified algorithm is available for use.
1059 * buffer and nbytes must be zero. 1059 * buffer and nbytes must be zero.
1060 * GCRYCTL_GET_ASNOID: 1060 * GCRYCTL_GET_ASNOID:
1061 * Return the ASNOID of the algorithm in buffer. if buffer is NULL, only 1061 * Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
1062 * the required length is returned. 1062 * the required length is returned.
1063 * 1063 *
1064 * Note: Because this function is in most cases used to return an 1064 * Note: Because this function is in most cases used to return an
1065 * integer value, we can make it easier for the caller to just look at 1065 * integer value, we can make it easier for the caller to just look at
1066 * the return value. The caller will in all cases consult the value 1066 * the return value. The caller will in all cases consult the value
1067 * and thereby detecting whether a error occured or not (i.e. while checking 1067 * and thereby detecting whether a error occured or not (i.e. while checking
1068 * the block size) 1068 * the block size)
1069 */ 1069 */
1070gcry_error_t 1070gcry_error_t
1071gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes) 1071gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
1072{ 1072{
1073 gcry_err_code_t err = GPG_ERR_NO_ERROR; 1073 gcry_err_code_t err = GPG_ERR_NO_ERROR;
1074 1074
1075 switch (what) 1075 switch (what)
1076 { 1076 {
1077 case GCRYCTL_TEST_ALGO: 1077 case GCRYCTL_TEST_ALGO:
1078 if (buffer || nbytes) 1078 if (buffer || nbytes)
1079 err = GPG_ERR_INV_ARG; 1079 err = GPG_ERR_INV_ARG;
1080 else 1080 else
1081 err = check_digest_algo (algo); 1081 err = check_digest_algo (algo);
1082 break; 1082 break;
1083 1083
1084 case GCRYCTL_GET_ASNOID: 1084 case GCRYCTL_GET_ASNOID:
1085 { 1085 {
1086 const char unsigned *asn; 1086 const char unsigned *asn;
1087 size_t asnlen; 1087 size_t asnlen;
1088 1088
1089 asn = md_asn_oid (algo, &asnlen, NULL); 1089 asn = md_asn_oid (algo, &asnlen, NULL);
1090 if (buffer && (*nbytes >= asnlen)) 1090 if (buffer && (*nbytes >= asnlen))
1091 { 1091 {
1092 memcpy (buffer, asn, asnlen); 1092 memcpy (buffer, asn, asnlen);
1093 *nbytes = asnlen; 1093 *nbytes = asnlen;
1094 } 1094 }
1095 else if ((! buffer) && nbytes) 1095 else if ((! buffer) && nbytes)
1096 *nbytes = asnlen; 1096 *nbytes = asnlen;
1097 else 1097 else
1098 { 1098 {
1099 if (buffer) 1099 if (buffer)
1100 err = GPG_ERR_TOO_SHORT; 1100 err = GPG_ERR_TOO_SHORT;
1101 else 1101 else
1102 err = GPG_ERR_INV_ARG; 1102 err = GPG_ERR_INV_ARG;
1103 } 1103 }
1104 break; 1104 break;
1105 } 1105 }
1106 1106
1107 default: 1107 default:
1108 err = GPG_ERR_INV_OP; 1108 err = GPG_ERR_INV_OP;
1109 } 1109 }
1110 1110
1111 return gcry_error (err); 1111 return gcry_error (err);
1112} 1112}
1113 1113
1114 1114
1115static void 1115static void
1116md_start_debug( gcry_md_hd_t md, char *suffix ) 1116md_start_debug( gcry_md_hd_t md, char *suffix )
1117{ 1117{
1118 static int idx=0; 1118 static int idx=0;
1119 char buf[50]; 1119 char buf[50];
1120 1120
1121 if( md->ctx->debug ) { 1121 if( md->ctx->debug ) {
1122 log_debug("Oops: md debug already started\n"); 1122 log_debug("Oops: md debug already started\n");
1123 return; 1123 return;
1124 } 1124 }
1125 idx++; 1125 idx++;
1126 sprintf(buf, "dbgmd-%05d.%.10s", idx, suffix ); 1126 sprintf(buf, "dbgmd-%05d.%.10s", idx, suffix );
1127 md->ctx->debug = fopen(buf, "w"); 1127 md->ctx->debug = fopen(buf, "w");
1128 if( !md->ctx->debug ) 1128 if( !md->ctx->debug )
1129 log_debug("md debug: can't open %s\n", buf ); 1129 log_debug("md debug: can't open %s\n", buf );
1130} 1130}
1131 1131
1132static void 1132static void
1133md_stop_debug( gcry_md_hd_t md ) 1133md_stop_debug( gcry_md_hd_t md )
1134{ 1134{
1135 if( md->ctx->debug ) { 1135 if( md->ctx->debug ) {
1136 if( md->bufpos ) 1136 if( md->bufpos )
1137 md_write( md, NULL, 0 ); 1137 md_write( md, NULL, 0 );
1138 fclose(md->ctx->debug); 1138 fclose(md->ctx->debug);
1139 md->ctx->debug = NULL; 1139 md->ctx->debug = NULL;
1140 } 1140 }
1141#ifdef HAVE_U64_TYPEDEF 1141#ifdef HAVE_U64_TYPEDEF
1142 { /* a kludge to pull in the __muldi3 for Solaris */ 1142 { /* a kludge to pull in the __muldi3 for Solaris */
1143 volatile u32 a = (u32)(ulong)md; 1143 volatile u32 a = (u32)(ulong)md;
1144 volatile u64 b = 42; 1144 volatile u64 b = 42;
1145 volatile u64 c; 1145 volatile u64 c;
1146 c = a * b; 1146 c = a * b;
1147 } 1147 }
1148#endif 1148#endif
1149} 1149}
1150 1150
1151 1151
1152 1152
1153/* 1153/*
1154 * Return information about the digest handle. 1154 * Return information about the digest handle.
1155 * GCRYCTL_IS_SECURE: 1155 * GCRYCTL_IS_SECURE:
1156 * Returns 1 when the handle works on secured memory 1156 * Returns 1 when the handle works on secured memory
1157 * otherwise 0 is returned. There is no error return. 1157 * otherwise 0 is returned. There is no error return.
1158 * GCRYCTL_IS_ALGO_ENABLED: 1158 * GCRYCTL_IS_ALGO_ENABLED:
1159 * Returns 1 if the algo is enanled for that handle. 1159 * Returns 1 if the algo is enanled for that handle.
1160 * The algo must be passed as the address of an int. 1160 * The algo must be passed as the address of an int.
1161 */ 1161 */
1162gcry_error_t 1162gcry_error_t
1163gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes) 1163gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
1164{ 1164{
1165 gcry_err_code_t err = GPG_ERR_NO_ERROR; 1165 gcry_err_code_t err = GPG_ERR_NO_ERROR;
1166 1166
1167 switch (cmd) 1167 switch (cmd)
1168 { 1168 {
1169 case GCRYCTL_IS_SECURE: 1169 case GCRYCTL_IS_SECURE:
1170 *nbytes = h->ctx->secure; 1170 *nbytes = h->ctx->secure;
1171 break; 1171 break;
1172 1172
1173 case GCRYCTL_IS_ALGO_ENABLED: 1173 case GCRYCTL_IS_ALGO_ENABLED:
1174 { 1174 {
1175 GcryDigestEntry *r; 1175 GcryDigestEntry *r;
1176 int algo; 1176 int algo;
1177 1177
1178 if ( !buffer || (nbytes && (*nbytes != sizeof (int)))) 1178 if ( !buffer || (nbytes && (*nbytes != sizeof (int))))
1179 err = GPG_ERR_INV_ARG; 1179 err = GPG_ERR_INV_ARG;
1180 else 1180 else
1181 { 1181 {
1182 algo = *(int*)buffer; 1182 algo = *(int*)buffer;
1183 1183
1184 *nbytes = 0; 1184 *nbytes = 0;
1185 for(r=h->ctx->list; r; r = r->next ) { 1185 for(r=h->ctx->list; r; r = r->next ) {
1186 if (r->module->mod_id == algo) 1186 if (r->module->mod_id == algo)
1187 { 1187 {
1188 *nbytes = 1; 1188 *nbytes = 1;
1189 break; 1189 break;
1190 } 1190 }
1191 } 1191 }
1192 } 1192 }
1193 break; 1193 break;
1194 } 1194 }
1195 1195
1196 default: 1196 default:
1197 err = GPG_ERR_INV_OP; 1197 err = GPG_ERR_INV_OP;
1198 } 1198 }
1199 1199
1200 return gcry_error (err); 1200 return gcry_error (err);
1201} 1201}
1202 1202
1203gcry_err_code_t 1203gcry_err_code_t
1204_gcry_md_init (void) 1204_gcry_md_init (void)
1205{ 1205{
1206 gcry_err_code_t err = GPG_ERR_NO_ERROR; 1206 gcry_err_code_t err = GPG_ERR_NO_ERROR;
1207 1207
1208 REGISTER_DEFAULT_DIGESTS; 1208 REGISTER_DEFAULT_DIGESTS;
1209 1209
1210 return err; 1210 return err;
1211} 1211}
1212 1212
1213 1213
1214int 1214int
1215gcry_md_is_secure (gcry_md_hd_t a) 1215gcry_md_is_secure (gcry_md_hd_t a)
1216{ 1216{
1217 size_t value; 1217 size_t value;
1218 1218
1219 if (gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value)) 1219 if (gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value))
1220 value = 1; /* It seems to be better to assume secure memory on 1220 value = 1; /* It seems to be better to assume secure memory on
1221 error. */ 1221 error. */
1222 return value; 1222 return value;
1223} 1223}
1224 1224
1225 1225
1226int 1226int
1227gcry_md_is_enabled (gcry_md_hd_t a, int algo) 1227gcry_md_is_enabled (gcry_md_hd_t a, int algo)
1228{ 1228{
1229 size_t value; 1229 size_t value;
1230 1230
1231 value = sizeof algo; 1231 value = sizeof algo;
1232 if (gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value)) 1232 if (gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
1233 value = 0; 1233 value = 0;
1234 return value; 1234 return value;
1235} 1235}
1236 1236
1237/* Get a list consisting of the IDs of the loaded message digest 1237/* Get a list consisting of the IDs of the loaded message digest
1238 modules. If LIST is zero, write the number of loaded message 1238 modules. If LIST is zero, write the number of loaded message
1239 digest modules to LIST_LENGTH and return. If LIST is non-zero, the 1239 digest modules to LIST_LENGTH and return. If LIST is non-zero, the
1240 first *LIST_LENGTH algorithm IDs are stored in LIST, which must be 1240 first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
1241 of according size. In case there are less message digest modules 1241 of according size. In case there are less message digest modules
1242 than *LIST_LENGTH, *LIST_LENGTH is updated to the correct 1242 than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
1243 number. */ 1243 number. */
1244gcry_error_t 1244gcry_error_t
1245gcry_md_list (int *list, int *list_length) 1245gcry_md_list (int *list, int *list_length)
1246{ 1246{
1247 gcry_err_code_t err = GPG_ERR_NO_ERROR; 1247 gcry_err_code_t err = GPG_ERR_NO_ERROR;
1248 1248
1249 ath_mutex_lock (&digests_registered_lock); 1249 ath_mutex_lock (&digests_registered_lock);
1250 err = _gcry_module_list (digests_registered, list, list_length); 1250 err = _gcry_module_list (digests_registered, list, list_length);
1251 ath_mutex_unlock (&digests_registered_lock); 1251 ath_mutex_unlock (&digests_registered_lock);
1252 1252
1253 return err; 1253 return err;
1254} 1254}