summaryrefslogtreecommitdiffabout
path: root/pwmanager/libcrypt/crypt/module.c
Unidiff
Diffstat (limited to 'pwmanager/libcrypt/crypt/module.c') (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/libcrypt/crypt/module.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/pwmanager/libcrypt/crypt/module.c b/pwmanager/libcrypt/crypt/module.c
new file mode 100644
index 0000000..e98c36e
--- a/dev/null
+++ b/pwmanager/libcrypt/crypt/module.c
@@ -0,0 +1,200 @@
1/* module.c - Module management for libgcrypt.
2 * Copyright (C) 2003 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
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
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
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
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21#include <assert.h>
22#include <config.h>
23#include <errno.h>
24#include "g10lib.h"
25
26#define MODULE_ID_MIN 600
27
28/* Internal function. Generate a new, unique module ID for a module
29 that should be inserted into the module chain starting at
30 MODULES. */
31static gcry_err_code_t
32_gcry_module_id_new (gcry_module_t modules, unsigned int *id_new)
33{
34 /* FIXME, what should be the ID of the first module registered by
35 the user? */
36 unsigned int id_min = MODULE_ID_MIN, id_max = (unsigned int) -1, mod_id;
37 gcry_err_code_t err = GPG_ERR_NO_ERROR;
38 gcry_module_t module;
39
40 /* Search for unused ID. */
41 for (mod_id = id_min; mod_id < id_max; mod_id++)
42 {
43 /* Search for a module with the current ID. */
44 for (module = modules; module; module = module->next)
45 if (mod_id == module->mod_id)
46 break;
47
48 if (! module)
49 /* None found -> the ID is available for use. */
50 break;
51 }
52
53 if (mod_id < id_max)
54 /* Done. */
55 *id_new = mod_id;
56 else
57 /* No free ID found. */
58 err = GPG_ERR_INTERNAL;
59
60 return err;
61}
62
63/* Add a module specification to the list ENTRIES. The new module has
64 it's use-counter set to one. */
65gcry_err_code_t
66_gcry_module_add (gcry_module_t *entries, unsigned int mod_id,
67 void *spec, gcry_module_t *module)
68{
69 gcry_err_code_t err = 0;
70 gcry_module_t entry;
71
72 if (! mod_id)
73 err = _gcry_module_id_new (*entries, &mod_id);
74
75 if (! err)
76 {
77 entry = gcry_malloc (sizeof (struct gcry_module));
78 if (! entry)
79 err = gpg_err_code_from_errno (errno);
80 }
81
82 if (! err)
83 {
84 /* Fill new module entry. */
85 entry->flags = 0;
86 entry->counter = 1;
87 entry->spec = spec;
88 entry->mod_id = mod_id;
89
90 /* Link it into the list. */
91 entry->next = *entries;
92 entry->prevp = entries;
93 if (*entries)
94 (*entries)->prevp = &entry->next;
95 *entries = entry;
96
97 /* And give it to the caller. */
98 if (module)
99 *module = entry;
100 }
101 return err;
102}
103
104/* Internal function. Unlink CIPHER_ENTRY from the list of registered
105 ciphers and destroy it. */
106static void
107_gcry_module_drop (gcry_module_t entry)
108{
109 *entry->prevp = entry->next;
110 if (entry->next)
111 entry->next->prevp = entry->prevp;
112
113 gcry_free (entry);
114}
115
116/* Lookup a module specification by it's ID. After a successfull
117 lookup, the module has it's resource counter incremented. */
118gcry_module_t
119_gcry_module_lookup_id (gcry_module_t entries, unsigned int mod_id)
120{
121 gcry_module_t entry;
122
123 for (entry = entries; entry; entry = entry->next)
124 if (entry->mod_id == mod_id)
125 {
126 entry->counter++;
127 break;
128 }
129
130 return entry;
131}
132
133/* Lookup a module specification. After a successfull lookup, the
134 module has it's resource counter incremented. FUNC is a function
135 provided by the caller, which is responsible for identifying the
136 wanted module. */
137gcry_module_t
138_gcry_module_lookup (gcry_module_t entries, void *data,
139 gcry_module_lookup_t func)
140{
141 gcry_module_t entry;
142
143 for (entry = entries; entry; entry = entry->next)
144 if ((*func) (entry->spec, data))
145 {
146 entry->counter++;
147 break;
148 }
149
150 return entry;
151}
152
153/* Release a module. In case the use-counter reaches zero, destroy
154 the module. Passing MODULE as NULL is a dummy operation (similar
155 to free()). */
156void
157_gcry_module_release (gcry_module_t module)
158{
159 if (module && ! --module->counter)
160 _gcry_module_drop (module);
161}
162
163/* Add a reference to a module. */
164void
165_gcry_module_use (gcry_module_t module)
166{
167 ++module->counter;
168}
169
170/* If LIST is zero, write the number of modules identified by MODULES
171 to LIST_LENGTH and return. If LIST is non-zero, the first
172 *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
173 according size. In case there are less cipher modules than
174 *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
175gcry_err_code_t
176_gcry_module_list (gcry_module_t modules,
177 int *list, int *list_length)
178{
179 gcry_err_code_t err = GPG_ERR_NO_ERROR;
180 gcry_module_t module;
181 int length, i;
182
183 for (module = modules, length = 0; module; module = module->next, length++);
184
185 if (list)
186 {
187 if (length > *list_length)
188 length = *list_length;
189
190 for (module = modules, i = 0; i < length; module = module->next, i++)
191 list[i] = module->mod_id;
192
193 if (length < *list_length)
194 *list_length = length;
195 }
196 else
197 *list_length = length;
198
199 return err;
200}