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.1.1.1 2000/06/27 11:36:55 priikone
24 * Importet from internal CVS/Added Log headers.
29 #include "silcincludes.h"
34 /* List of all hash functions in SILC. You can dynamically add new hash
35 functions into the list. At the initialization of SILC this list is
36 filled with the configured hash functions. */
37 struct SilcHashListStruct {
39 struct SilcHashListStruct *next;
42 /* List of dynamically registered hash functions. */
43 struct SilcHashListStruct *silc_hash_list = NULL;
45 /* Statically declared list of hash functions. */
46 SilcHashObject silc_hash_builtin_list[] =
48 { "md5", 16, 64, silc_md5_init, silc_md5_update, silc_md5_final,
49 silc_md5_transform, silc_md5_context_len },
50 { "sha1", 20, 64, silc_sha1_init, silc_sha1_update, silc_sha1_final,
51 silc_sha1_transform, silc_sha1_context_len },
53 { NULL, 0, 0, NULL, NULL, NULL, NULL, NULL }
56 /* Registers a ned hash function into the SILC. This function is used at
57 the initialization of the SILC. */
59 int silc_hash_register(SilcHashObject *hash)
61 struct SilcHashListStruct *new, *h;
63 SILC_LOG_DEBUG(("Registering new hash function"));
65 new = silc_calloc(1, sizeof(*new));
67 SILC_LOG_ERROR(("Could not allocate new hash list object"));
71 new->hash = silc_calloc(1, sizeof(*new->hash));
73 SILC_LOG_ERROR(("Could not allocate new hash object"));
77 /* Set the pointers */
78 new->hash->name = silc_calloc(1, strlen(hash->name));
79 memcpy(new->hash->name, hash->name, strlen(hash->name));
80 new->hash->hash_len = hash->hash_len;
81 new->hash->block_len = hash->block_len;
82 new->hash->init = hash->init;
83 new->hash->update = hash->update;
84 new->hash->final = hash->final;
85 new->hash->context_len = hash->context_len;
88 /* Add the new hash function to the list */
89 if (!silc_hash_list) {
106 /* Unregister a hash function from the SILC. */
108 int silc_hash_unregister(SilcHashObject *hash)
110 struct SilcHashListStruct *h, *tmp;
112 SILC_LOG_DEBUG(("Unregistering hash function"));
116 /* Unregister all hash functions */
117 if (hash == SILC_ALL_HASH_FUNCTIONS) {
118 /* Unregister all ciphers */
121 silc_free(h->hash->name);
129 /* Unregister the hash function */
130 if (h->hash == hash) {
132 silc_free(h->hash->name);
134 silc_hash_list = tmp;
140 if (h->next->hash == hash) {
142 silc_free(h->hash->name);
154 /* Allocates a new SilcHash object. New object is returned into new_hash
157 int silc_hash_alloc(const unsigned char *name, SilcHash *new_hash)
159 struct SilcHashListStruct *h;
162 SILC_LOG_DEBUG(("Allocating new hash object"));
164 /* Allocate the new object */
165 *new_hash = silc_calloc(1, sizeof(**new_hash));
166 if (*new_hash == NULL) {
167 SILC_LOG_ERROR(("Could not allocate new hash object"));
171 if (silc_hash_list) {
174 if (!strcmp(h->hash->name, name))
182 /* Set the pointers */
183 (*new_hash)->hash = h->hash;
184 (*new_hash)->context = silc_calloc(1, h->hash->context_len());
185 (*new_hash)->make_hash = silc_hash_make;
191 for (i = 0; silc_hash_builtin_list[i].name; i++)
192 if (!strcmp(silc_hash_builtin_list[i].name, name))
195 if (silc_hash_builtin_list[i].name == NULL) {
196 silc_free(*new_hash);
200 /* Set the pointers */
201 (*new_hash)->hash = &silc_hash_builtin_list[i];
202 (*new_hash)->context = silc_calloc(1, (*new_hash)->hash->context_len());
203 (*new_hash)->make_hash = silc_hash_make;
208 /* Free's the SilcHash object */
210 void silc_hash_free(SilcHash hash)
213 silc_free(hash->context);
218 /* Returns TRUE if hash algorithm `name' is supported. */
220 int silc_hash_is_supported(const unsigned char *name)
222 struct SilcHashListStruct *h;
225 if (silc_hash_list) {
229 if (!strcmp(h->hash->name, name))
235 for (i = 0; silc_hash_builtin_list[i].name; i++)
236 if (!strcmp(silc_hash_builtin_list[i].name, name))
242 /* Returns comma separated list of supported hash functions. */
244 char *silc_hash_get_supported()
248 struct SilcHashListStruct *h;
251 if (silc_hash_list) {
255 len += strlen(h->hash->name);
256 list = silc_realloc(list, len + 1);
258 memcpy(list + (len - strlen(h->hash->name)),
259 h->hash->name, strlen(h->hash->name));
260 memcpy(list + len, ",", 1);
267 for (i = 0; silc_hash_builtin_list[i].name; i++) {
268 len += strlen(silc_hash_builtin_list[i].name);
269 list = silc_realloc(list, len + 1);
271 memcpy(list + (len - strlen(silc_hash_builtin_list[i].name)),
272 silc_hash_builtin_list[i].name,
273 strlen(silc_hash_builtin_list[i].name));
274 memcpy(list + len, ",", 1);
283 /* Creates the hash value and returns it to the return_hash argument. */
285 void silc_hash_make(SilcHash hash, const unsigned char *data,
286 unsigned int len, unsigned char *return_hash)
288 hash->hash->init(hash->context);
289 hash->hash->update(hash->context, (unsigned char *)data, len);
290 hash->hash->final(hash->context, return_hash);