2 * GCRYPT crypto backend implementation
4 * Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
5 * Copyright (C) 2010-2012, Milan Broz
7 * This file is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This file is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this file; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "crypto_backend.h"
29 static int crypto_backend_initialised = 0;
30 static int crypto_backend_secmem = 1;
31 static char version[64];
45 int crypt_backend_init(struct crypt_device *ctx)
47 if (crypto_backend_initialised)
50 if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
51 if (!gcry_check_version (GCRYPT_REQ_VERSION)) {
55 /* FIXME: If gcrypt compiled to support POSIX 1003.1e capabilities,
56 * it drops all privileges during secure memory initialisation.
57 * For now, the only workaround is to disable secure memory in gcrypt.
58 * cryptsetup always need at least cap_sys_admin privilege for dm-ioctl
59 * and it locks its memory space anyway.
62 gcry_control (GCRYCTL_DISABLE_SECMEM);
63 crypto_backend_secmem = 0;
66 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
67 gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
68 gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
70 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
73 snprintf(version, 64, "gcrypt %s%s",
74 gcry_check_version(NULL),
75 crypto_backend_secmem ? "" : ", secmem disabled");
76 crypto_backend_initialised = 1;
80 const char *crypt_backend_version(void)
82 return crypto_backend_initialised ? version : "";
85 uint32_t crypt_backend_flags(void)
91 int crypt_hash_size(const char *name)
95 assert(crypto_backend_initialised);
97 hash_id = gcry_md_map_name(name);
101 return gcry_md_get_algo_dlen(hash_id);
104 int crypt_hash_init(struct crypt_hash **ctx, const char *name)
106 struct crypt_hash *h;
108 assert(crypto_backend_initialised);
110 h = malloc(sizeof(*h));
114 h->hash_id = gcry_md_map_name(name);
120 if (gcry_md_open(&h->hd, h->hash_id, 0)) {
125 h->hash_len = gcry_md_get_algo_dlen(h->hash_id);
130 static void crypt_hash_restart(struct crypt_hash *ctx)
132 gcry_md_reset(ctx->hd);
135 int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
137 gcry_md_write(ctx->hd, buffer, length);
141 int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
145 if (length > (size_t)ctx->hash_len)
148 hash = gcry_md_read(ctx->hd, ctx->hash_id);
152 memcpy(buffer, hash, length);
153 crypt_hash_restart(ctx);
158 int crypt_hash_destroy(struct crypt_hash *ctx)
160 gcry_md_close(ctx->hd);
161 memset(ctx, 0, sizeof(*ctx));
167 int crypt_hmac_size(const char *name)
169 return crypt_hash_size(name);
172 int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
173 const void *buffer, size_t length)
175 struct crypt_hmac *h;
177 assert(crypto_backend_initialised);
179 h = malloc(sizeof(*h));
183 h->hash_id = gcry_md_map_name(name);
189 if (gcry_md_open(&h->hd, h->hash_id, GCRY_MD_FLAG_HMAC)) {
194 if (gcry_md_setkey(h->hd, buffer, length)) {
195 gcry_md_close(h->hd);
200 h->hash_len = gcry_md_get_algo_dlen(h->hash_id);
205 static void crypt_hmac_restart(struct crypt_hmac *ctx)
207 gcry_md_reset(ctx->hd);
210 int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
212 gcry_md_write(ctx->hd, buffer, length);
216 int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
220 if (length > (size_t)ctx->hash_len)
223 hash = gcry_md_read(ctx->hd, ctx->hash_id);
227 memcpy(buffer, hash, length);
228 crypt_hmac_restart(ctx);
233 int crypt_hmac_destroy(struct crypt_hmac *ctx)
235 gcry_md_close(ctx->hd);
236 memset(ctx, 0, sizeof(*ctx));
242 int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
245 case CRYPT_RND_NORMAL:
246 gcry_randomize(buffer, length, GCRY_STRONG_RANDOM);
251 gcry_randomize(buffer, length, GCRY_VERY_STRONG_RANDOM);
258 int crypt_pbkdf(const char *kdf, const char *hash,
259 const char *password, size_t password_length,
260 const char *salt, size_t salt_length,
261 char *key, size_t key_length,
262 unsigned int iterations)
264 #if USE_INTERNAL_PBKDF2
265 if (!kdf || strncmp(kdf, "pbkdf2", 6))
268 return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length,
269 iterations, key_length, key);
271 #else /* USE_INTERNAL_PBKDF2 */
272 int hash_id = gcry_md_map_name(hash);
278 if (kdf && !strncmp(kdf, "pbkdf2", 6))
279 kdf_id = GCRY_KDF_PBKDF2;
283 if (gcry_kdf_derive(password, password_length, kdf_id, hash_id,
284 salt, salt_length, iterations, key_length, key))
288 #endif /* USE_INTERNAL_PBKDF2 */