7 #include "libcryptsetup.h"
10 #define MAX_DIGESTS 64
11 #define GCRYPT_REQ_VERSION "1.1.42"
13 int init_crypto(struct crypt_device *ctx)
17 if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
18 if (!gcry_check_version (GCRYPT_REQ_VERSION)) {
23 /* FIXME: If gcrypt compiled to support POSIX 1003.1e capabilities,
24 * it drops all privileges during secure memory initialisation.
25 * For now, the only workaround is to disable secure memory in gcrypt.
26 * cryptsetup always need at least cap_sys_admin privilege for dm-ioctl
27 * and it locks its memory space anyway.
30 log_dbg("Initializing crypto backend (secure memory disabled).");
31 gcry_control (GCRYCTL_DISABLE_SECMEM);
33 log_dbg("Initializing crypto backend (using secure memory).");
34 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
35 gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
36 gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
38 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
43 log_err(ctx, _("Cannot initialize crypto backend.\n"));
47 static int gcrypt_hash(void *data, int size, char *key,
48 int sizep, const char *passphrase)
51 int algo = *((int *)data);
52 int len = gcry_md_get_algo_dlen(algo);
55 if (gcry_md_open(&md, algo, 0))
58 for(round = 0; size; round++) {
59 /* hack from hashalot to avoid null bytes in key */
60 for(i = 0; i < round; i++)
61 gcry_md_write(md, "A", 1);
63 gcry_md_write(md, passphrase, sizep);
67 memcpy(key, gcry_md_read(md, algo), len);
79 static struct hash_type *gcrypt_get_hashes(void)
81 struct hash_type *hashes;
82 int size = MAX_DIGESTS;
87 if (!gcry_check_version(GCRYPT_REQ_VERSION))
90 list = (int *)malloc(sizeof(*list) * size);
94 r = gcry_md_list(list, &size);
100 hashes = malloc(sizeof(*hashes) * (size + 1));
106 for(i = 0; i < size; i++) {
107 hashes[i].name = NULL;
108 hashes[i].private = NULL;
111 for(i = 0; i < size; i++) {
114 hashes[i].name = strdup(gcry_md_algo_name(list[i]));
117 for(p = (char *)hashes[i].name; *p; p++)
119 hashes[i].private = malloc(sizeof(int));
120 if(!hashes[i].private)
122 *((int *)hashes[i].private) = list[i];
123 hashes[i].fn = gcrypt_hash;
125 hashes[i].name = NULL;
126 hashes[i].private = NULL;
135 for(i = 0; i < size; i++) {
136 free(hashes[i].name);
137 free(hashes[i].private);
143 static void gcrypt_free_hashes(struct hash_type *hashes)
145 struct hash_type *hash;
147 for(hash = hashes; hash->name; hash++) {
155 struct hash_backend hash_gcrypt_backend = {
157 .get_hashes = gcrypt_get_hashes,
158 .free_hashes = gcrypt_free_hashes