5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
23 * Revision 1.2 2000/07/05 06:08:43 priikone
24 * Global cosmetic change.
26 * Revision 1.1.1.1 2000/06/27 11:36:55 priikone
27 * Imported from internal CVS/Added Log headers.
32 #include "silcincludes.h"
37 /* List of all hash functions in SILC. You can dynamically add new hash
38 functions into the list. At the initialization of SILC this list is
39 filled with the configured hash functions. */
40 struct SilcHashListStruct {
42 struct SilcHashListStruct *next;
45 /* List of dynamically registered hash functions. */
46 struct SilcHashListStruct *silc_hash_list = NULL;
48 /* Statically declared list of hash functions. */
49 SilcHashObject silc_hash_builtin_list[] =
51 { "md5", 16, 64, silc_md5_init, silc_md5_update, silc_md5_final,
52 silc_md5_transform, silc_md5_context_len },
53 { "sha1", 20, 64, silc_sha1_init, silc_sha1_update, silc_sha1_final,
54 silc_sha1_transform, silc_sha1_context_len },
56 { NULL, 0, 0, NULL, NULL, NULL, NULL, NULL }
59 /* Registers a ned hash function into the SILC. This function is used at
60 the initialization of the SILC. */
62 int silc_hash_register(SilcHashObject *hash)
64 struct SilcHashListStruct *new, *h;
66 SILC_LOG_DEBUG(("Registering new hash function"));
68 new = silc_calloc(1, sizeof(*new));
69 new->hash = silc_calloc(1, sizeof(*new->hash));
71 /* Set the pointers */
72 new->hash->name = silc_calloc(1, strlen(hash->name));
73 memcpy(new->hash->name, hash->name, strlen(hash->name));
74 new->hash->hash_len = hash->hash_len;
75 new->hash->block_len = hash->block_len;
76 new->hash->init = hash->init;
77 new->hash->update = hash->update;
78 new->hash->final = hash->final;
79 new->hash->context_len = hash->context_len;
82 /* Add the new hash function to the list */
83 if (!silc_hash_list) {
100 /* Unregister a hash function from the SILC. */
102 int silc_hash_unregister(SilcHashObject *hash)
104 struct SilcHashListStruct *h, *tmp;
106 SILC_LOG_DEBUG(("Unregistering hash function"));
110 /* Unregister all hash functions */
111 if (hash == SILC_ALL_HASH_FUNCTIONS) {
112 /* Unregister all ciphers */
115 silc_free(h->hash->name);
123 /* Unregister the hash function */
124 if (h->hash == hash) {
126 silc_free(h->hash->name);
128 silc_hash_list = tmp;
134 if (h->next->hash == hash) {
136 silc_free(h->hash->name);
148 /* Allocates a new SilcHash object. New object is returned into new_hash
151 int silc_hash_alloc(const unsigned char *name, SilcHash *new_hash)
153 struct SilcHashListStruct *h;
156 SILC_LOG_DEBUG(("Allocating new hash object"));
158 /* Allocate the new object */
159 *new_hash = silc_calloc(1, sizeof(**new_hash));
161 if (silc_hash_list) {
164 if (!strcmp(h->hash->name, name))
172 /* Set the pointers */
173 (*new_hash)->hash = h->hash;
174 (*new_hash)->context = silc_calloc(1, h->hash->context_len());
175 (*new_hash)->make_hash = silc_hash_make;
181 for (i = 0; silc_hash_builtin_list[i].name; i++)
182 if (!strcmp(silc_hash_builtin_list[i].name, name))
185 if (silc_hash_builtin_list[i].name == NULL) {
186 silc_free(*new_hash);
190 /* Set the pointers */
191 (*new_hash)->hash = &silc_hash_builtin_list[i];
192 (*new_hash)->context = silc_calloc(1, (*new_hash)->hash->context_len());
193 (*new_hash)->make_hash = silc_hash_make;
198 /* Free's the SilcHash object */
200 void silc_hash_free(SilcHash hash)
203 silc_free(hash->context);
208 /* Returns TRUE if hash algorithm `name' is supported. */
210 int silc_hash_is_supported(const unsigned char *name)
212 struct SilcHashListStruct *h;
215 if (silc_hash_list) {
219 if (!strcmp(h->hash->name, name))
225 for (i = 0; silc_hash_builtin_list[i].name; i++)
226 if (!strcmp(silc_hash_builtin_list[i].name, name))
232 /* Returns comma separated list of supported hash functions. */
234 char *silc_hash_get_supported()
238 struct SilcHashListStruct *h;
241 if (silc_hash_list) {
245 len += strlen(h->hash->name);
246 list = silc_realloc(list, len + 1);
248 memcpy(list + (len - strlen(h->hash->name)),
249 h->hash->name, strlen(h->hash->name));
250 memcpy(list + len, ",", 1);
257 for (i = 0; silc_hash_builtin_list[i].name; i++) {
258 len += strlen(silc_hash_builtin_list[i].name);
259 list = silc_realloc(list, len + 1);
261 memcpy(list + (len - strlen(silc_hash_builtin_list[i].name)),
262 silc_hash_builtin_list[i].name,
263 strlen(silc_hash_builtin_list[i].name));
264 memcpy(list + len, ",", 1);
273 /* Creates the hash value and returns it to the return_hash argument. */
275 void silc_hash_make(SilcHash hash, const unsigned char *data,
276 unsigned int len, unsigned char *return_hash)
278 hash->hash->init(hash->context);
279 hash->hash->update(hash->context, (unsigned char *)data, len);
280 hash->hash->final(hash->context, return_hash);