diff options
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.c | 2508 |
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 | ||
34 | static struct digest_table_entry | 34 | static 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. */ |
71 | static gcry_module_t digests_registered; | 71 | static gcry_module_t digests_registered; |
72 | 72 | ||
73 | /* This is the lock protecting DIGESTS_REGISTERED. */ | 73 | /* This is the lock protecting DIGESTS_REGISTERED. */ |
74 | static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER; | 74 | static 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. */ |
78 | static int default_digests_registered; | 78 | static int default_digests_registered; |
79 | 79 | ||
80 | typedef struct gcry_md_list | 80 | typedef 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. */ |
91 | struct gcry_md_context | 91 | struct 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 | ||
121 | static const char * digest_algo_to_string( int algo ); | 121 | static const char * digest_algo_to_string( int algo ); |
122 | static gcry_err_code_t check_digest_algo (int algo); | 122 | static gcry_err_code_t check_digest_algo (int algo); |
123 | static gcry_err_code_t md_open (gcry_md_hd_t *h, int algo, | 123 | static gcry_err_code_t md_open (gcry_md_hd_t *h, int algo, |
124 | int secure, int hmac); | 124 | int secure, int hmac); |
125 | static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo); | 125 | static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo); |
126 | static gcry_err_code_t md_copy (gcry_md_hd_t a, gcry_md_hd_t *b); | 126 | static gcry_err_code_t md_copy (gcry_md_hd_t a, gcry_md_hd_t *b); |
127 | static void md_close (gcry_md_hd_t a); | 127 | static void md_close (gcry_md_hd_t a); |
128 | static void md_write (gcry_md_hd_t a, byte *inbuf, size_t inlen); | 128 | static void md_write (gcry_md_hd_t a, byte *inbuf, size_t inlen); |
129 | static void md_final(gcry_md_hd_t a); | 129 | static void md_final(gcry_md_hd_t a); |
130 | static byte *md_read( gcry_md_hd_t a, int algo ); | 130 | static byte *md_read( gcry_md_hd_t a, int algo ); |
131 | static int md_get_algo( gcry_md_hd_t a ); | 131 | static int md_get_algo( gcry_md_hd_t a ); |
132 | static int md_digest_length( int algo ); | 132 | static int md_digest_length( int algo ); |
133 | static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen ); | 133 | static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen ); |
134 | static void md_start_debug( gcry_md_hd_t a, char *suffix ); | 134 | static void md_start_debug( gcry_md_hd_t a, char *suffix ); |
135 | static void md_stop_debug( gcry_md_hd_t a ); | 135 | static 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. */ |
142 | static void | 142 | static void |
143 | gcry_md_register_default (void) | 143 | gcry_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. */ |
159 | static int | 159 | static int |
160 | gcry_md_lookup_func_name (void *spec, void *data) | 160 | gcry_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. */ |
169 | static int | 169 | static int |
170 | gcry_md_lookup_func_oid (void *spec, void *data) | 170 | gcry_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. */ |
188 | static gcry_module_t | 188 | static gcry_module_t |
189 | gcry_md_lookup_name (const char *name) | 189 | gcry_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. */ |
200 | static gcry_module_t | 200 | static gcry_module_t |
201 | gcry_md_lookup_oid (const char *oid) | 201 | gcry_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. */ |
214 | gcry_error_t | 214 | gcry_error_t |
215 | gcry_md_register (gcry_md_spec_t *digest, | 215 | gcry_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. */ |
238 | void | 238 | void |
239 | gcry_md_unregister (gcry_module_t module) | 239 | gcry_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 | ||
247 | static int | 247 | static int |
248 | search_oid (const char *oid, int *algorithm, gcry_md_oid_spec_t *oid_spec) | 248 | search_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 | */ |
281 | int | 281 | int |
282 | gcry_md_map_name (const char *string) | 282 | gcry_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 | */ |
318 | static const char * | 318 | static const char * |
319 | digest_algo_to_string (int algorithm) | 319 | digest_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 | */ |
344 | const char * | 344 | const char * |
345 | gcry_md_algo_name (int algorithm) | 345 | gcry_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 | ||
352 | static gcry_err_code_t | 352 | static gcry_err_code_t |
353 | check_digest_algo (int algorithm) | 353 | check_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 | */ |
378 | static gcry_err_code_t | 378 | static gcry_err_code_t |
379 | md_open (gcry_md_hd_t *h, int algo, int secure, int hmac) | 379 | md_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. */ |
462 | gcry_error_t | 462 | gcry_error_t |
463 | gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags) | 463 | gcry_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 | ||
482 | static gcry_err_code_t | 482 | static gcry_err_code_t |
483 | md_enable (gcry_md_hd_t hd, int algorithm) | 483 | md_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 | ||
549 | gcry_error_t | 549 | gcry_error_t |
550 | gcry_md_enable (gcry_md_hd_t hd, int algorithm) | 550 | gcry_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 | ||
556 | static gcry_err_code_t | 556 | static gcry_err_code_t |
557 | md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd) | 557 | md_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 | ||
635 | gcry_error_t | 635 | gcry_error_t |
636 | gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd) | 636 | gcry_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 | */ |
648 | void | 648 | void |
649 | gcry_md_reset (gcry_md_hd_t a) | 649 | gcry_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 | ||
664 | static void | 664 | static void |
665 | md_close (gcry_md_hd_t a) | 665 | md_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 | ||
693 | void | 693 | void |
694 | gcry_md_close (gcry_md_hd_t hd) | 694 | gcry_md_close (gcry_md_hd_t hd) |
695 | { | 695 | { |
696 | md_close (hd); | 696 | md_close (hd); |
697 | } | 697 | } |
698 | 698 | ||
699 | static void | 699 | static void |
700 | md_write (gcry_md_hd_t a, byte *inbuf, size_t inlen) | 700 | md_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 | ||
721 | void | 721 | void |
722 | gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen) | 722 | gcry_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 | ||
727 | static void | 727 | static void |
728 | md_final (gcry_md_hd_t a) | 728 | md_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 | ||
763 | static gcry_err_code_t | 763 | static gcry_err_code_t |
764 | prepare_macpads( gcry_md_hd_t hd, const byte *key, size_t keylen) | 764 | prepare_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 | ||
800 | gcry_error_t | 800 | gcry_error_t |
801 | gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen) | 801 | gcry_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 | ||
826 | gcry_error_t | 826 | gcry_error_t |
827 | gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen) | 827 | gcry_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 | */ |
847 | static byte * | 847 | static byte * |
848 | md_read( gcry_md_hd_t a, int algo ) | 848 | md_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 | */ |
873 | byte * | 873 | byte * |
874 | gcry_md_read (gcry_md_hd_t hd, int algo) | 874 | gcry_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 |
890 | static int | 890 | static int |
891 | md_digest( gcry_md_hd_t a, int algo, byte *buffer, int buflen ) | 891 | md_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 | */ |
935 | gcry_err_code_t | 935 | gcry_err_code_t |
936 | gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen) | 936 | gcry_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. */ |
949 | void | 949 | void |
950 | gcry_md_hash_buffer (int algo, void *digest, | 950 | gcry_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 | ||
973 | static int | 973 | static int |
974 | md_get_algo (gcry_md_hd_t a) | 974 | md_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 | ||
983 | int | 983 | int |
984 | gcry_md_get_algo (gcry_md_hd_t hd) | 984 | gcry_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 | */ |
993 | static int | 993 | static int |
994 | md_digest_length (int algorithm) | 994 | md_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 | */ |
1017 | unsigned int | 1017 | unsigned int |
1018 | gcry_md_get_algo_dlen (int algorithm) | 1018 | gcry_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 */ |
1026 | static const byte * | 1026 | static const byte * |
1027 | md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen) | 1027 | md_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 | */ |
1070 | gcry_error_t | 1070 | gcry_error_t |
1071 | gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes) | 1071 | gcry_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 | ||
1115 | static void | 1115 | static void |
1116 | md_start_debug( gcry_md_hd_t md, char *suffix ) | 1116 | md_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 | ||
1132 | static void | 1132 | static void |
1133 | md_stop_debug( gcry_md_hd_t md ) | 1133 | md_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 | */ |
1162 | gcry_error_t | 1162 | gcry_error_t |
1163 | gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes) | 1163 | gcry_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 | ||
1203 | gcry_err_code_t | 1203 | gcry_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 | ||
1214 | int | 1214 | int |
1215 | gcry_md_is_secure (gcry_md_hd_t a) | 1215 | gcry_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 | ||
1226 | int | 1226 | int |
1227 | gcry_md_is_enabled (gcry_md_hd_t a, int algo) | 1227 | gcry_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. */ |
1244 | gcry_error_t | 1244 | gcry_error_t |
1245 | gcry_md_list (int *list, int *list_length) | 1245 | gcry_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 | } |