sched: Add cpuset_t for FreeBSD compat
[dragonfly.git] / contrib / cryptsetup / lib / gcrypt.c
blobcfbcdc7bf9e31c792bbed0a4f4e0a7028147bdb4
1 #include <stdlib.h>
2 #include <string.h>
3 #include <ctype.h>
4 #include <errno.h>
5 #include <gcrypt.h>
7 #include "libcryptsetup.h"
8 #include "internal.h"
10 #define MAX_DIGESTS 64
11 #define GCRYPT_REQ_VERSION "1.1.42"
13 int init_crypto(void)
15 if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
16 if (!gcry_check_version (GCRYPT_REQ_VERSION))
17 return -ENOSYS;
19 /* FIXME: If gcrypt compiled to support POSIX 1003.1e capabilities,
20 * it drops all privileges during secure memory initialisation.
21 * For now, the only workaround is to disable secure memory in gcrypt.
22 * cryptsetup always need at least cap_sys_admin privilege for dm-ioctl
23 * and it locks its memory space anyway.
25 #if 0
26 log_dbg("Initializing crypto backend (secure memory disabled).");
27 gcry_control (GCRYCTL_DISABLE_SECMEM);
28 #else
29 log_dbg("Initializing crypto backend (using secure memory).");
30 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
31 gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
32 gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
33 #endif
34 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
37 return 0;
40 static int gcrypt_hash(void *data, int size, char *key,
41 int sizep, const char *passphrase)
43 gcry_md_hd_t md;
44 int algo = *((int *)data);
45 int len = gcry_md_get_algo_dlen(algo);
46 int round, i;
48 if (gcry_md_open(&md, algo, 0))
49 return -1;
51 for(round = 0; size; round++) {
52 /* hack from hashalot to avoid null bytes in key */
53 for(i = 0; i < round; i++)
54 gcry_md_write(md, "A", 1);
56 gcry_md_write(md, passphrase, sizep);
58 if (len > size)
59 len = size;
60 memcpy(key, gcry_md_read(md, algo), len);
62 key += len;
63 size -= len;
64 if (size)
65 gcry_md_reset(md);
68 gcry_md_close(md);
69 return 0;
72 static struct hash_type *gcrypt_get_hashes(void)
74 struct hash_type *hashes;
75 int size = MAX_DIGESTS;
76 int *list;
77 int i;
78 gcry_error_t r;
80 if (!gcry_check_version(GCRYPT_REQ_VERSION))
81 return NULL;
83 list = (int *)malloc(sizeof(*list) * size);
84 if (!list)
85 return NULL;
87 r = gcry_md_list(list, &size);
88 if (r || !size) {
89 free(list);
90 return NULL;
93 hashes = malloc(sizeof(*hashes) * (size + 1));
94 if (!hashes) {
95 free(list);
96 return NULL;
99 for(i = 0; i < size; i++) {
100 hashes[i].name = NULL;
101 hashes[i].private = NULL;
104 for(i = 0; i < size; i++) {
105 char *p;
107 hashes[i].name = strdup(gcry_md_algo_name(list[i]));
108 if(!hashes[i].name)
109 goto err;
110 for(p = (char *)hashes[i].name; *p; p++)
111 *p = tolower(*p);
112 hashes[i].private = malloc(sizeof(int));
113 if(!hashes[i].private)
114 goto err;
115 *((int *)hashes[i].private) = list[i];
116 hashes[i].fn = gcrypt_hash;
118 hashes[i].name = NULL;
119 hashes[i].private = NULL;
120 hashes[i].fn = NULL;
122 free(list);
124 return hashes;
126 err:
127 free(list);
128 for(i = 0; i < size; i++) {
129 free(hashes[i].name);
130 free(hashes[i].private);
132 free(hashes);
133 return NULL;
136 static void gcrypt_free_hashes(struct hash_type *hashes)
138 struct hash_type *hash;
140 for(hash = hashes; hash->name; hash++) {
141 free(hash->name);
142 free(hash->private);
145 free(hashes);
148 struct hash_backend hash_gcrypt_backend = {
149 .name = "libgcrypt",
150 .get_hashes = gcrypt_get_hashes,
151 .free_hashes = gcrypt_free_hashes