2 * GCRYPT crypto backend implementation
4 * Copyright (C) 2010-2012, Red Hat, Inc. All rights reserved.
5 * Copyright (C) 2010-2014, 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 int crypto_backend_whirlpool_bug = -1;
32 static char version[64];
47 * Test for wrong Whirlpool variant,
48 * Ref: http://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html
50 static void crypt_hash_test_whirlpool_bug(void)
53 char buf[2] = "\0\0", hash_out1[64], hash_out2[64];
56 if (crypto_backend_whirlpool_bug >= 0)
59 crypto_backend_whirlpool_bug = 0;
60 if (crypt_hash_init(&h, "whirlpool"))
64 if ((r = crypt_hash_write(h, &buf[0], 2)) ||
65 (r = crypt_hash_final(h, hash_out1, 64))) {
66 crypt_hash_destroy(h);
70 /* Split buf (crypt_hash_final resets hash state) */
71 if ((r = crypt_hash_write(h, &buf[0], 1)) ||
72 (r = crypt_hash_write(h, &buf[1], 1)) ||
73 (r = crypt_hash_final(h, hash_out2, 64))) {
74 crypt_hash_destroy(h);
78 crypt_hash_destroy(h);
80 if (memcmp(hash_out1, hash_out2, 64))
81 crypto_backend_whirlpool_bug = 1;
84 int crypt_backend_init(struct crypt_device *ctx)
86 if (crypto_backend_initialised)
89 if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
90 if (!gcry_check_version (GCRYPT_REQ_VERSION)) {
94 /* FIXME: If gcrypt compiled to support POSIX 1003.1e capabilities,
95 * it drops all privileges during secure memory initialisation.
96 * For now, the only workaround is to disable secure memory in gcrypt.
97 * cryptsetup always need at least cap_sys_admin privilege for dm-ioctl
98 * and it locks its memory space anyway.
101 gcry_control (GCRYCTL_DISABLE_SECMEM);
102 crypto_backend_secmem = 0;
105 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
106 gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
107 gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
109 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
112 crypto_backend_initialised = 1;
113 crypt_hash_test_whirlpool_bug();
115 snprintf(version, 64, "gcrypt %s%s%s",
116 gcry_check_version(NULL),
117 crypto_backend_secmem ? "" : ", secmem disabled",
118 crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : ""
124 const char *crypt_backend_version(void)
126 return crypto_backend_initialised ? version : "";
129 uint32_t crypt_backend_flags(void)
134 static const char *crypt_hash_compat_name(const char *name, unsigned int *flags)
136 const char *hash_name = name;
138 /* "whirlpool_gcryptbug" is out shortcut to flawed whirlpool
139 * in libgcrypt < 1.6.0 */
140 if (name && !strcasecmp(name, "whirlpool_gcryptbug")) {
141 #if GCRYPT_VERSION_NUMBER >= 0x010601
143 *flags |= GCRY_MD_FLAG_BUGEMU1;
145 hash_name = "whirlpool";
152 int crypt_hash_size(const char *name)
156 assert(crypto_backend_initialised);
158 hash_id = gcry_md_map_name(crypt_hash_compat_name(name, NULL));
162 return gcry_md_get_algo_dlen(hash_id);
165 int crypt_hash_init(struct crypt_hash **ctx, const char *name)
167 struct crypt_hash *h;
168 unsigned int flags = 0;
170 assert(crypto_backend_initialised);
172 h = malloc(sizeof(*h));
176 h->hash_id = gcry_md_map_name(crypt_hash_compat_name(name, &flags));
182 if (gcry_md_open(&h->hd, h->hash_id, flags)) {
187 h->hash_len = gcry_md_get_algo_dlen(h->hash_id);
192 static void crypt_hash_restart(struct crypt_hash *ctx)
194 gcry_md_reset(ctx->hd);
197 int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
199 gcry_md_write(ctx->hd, buffer, length);
203 int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
207 if (length > (size_t)ctx->hash_len)
210 hash = gcry_md_read(ctx->hd, ctx->hash_id);
214 memcpy(buffer, hash, length);
215 crypt_hash_restart(ctx);
220 int crypt_hash_destroy(struct crypt_hash *ctx)
222 gcry_md_close(ctx->hd);
223 memset(ctx, 0, sizeof(*ctx));
229 int crypt_hmac_size(const char *name)
231 return crypt_hash_size(name);
234 int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
235 const void *buffer, size_t length)
237 struct crypt_hmac *h;
238 unsigned int flags = GCRY_MD_FLAG_HMAC;
240 assert(crypto_backend_initialised);
242 h = malloc(sizeof(*h));
246 h->hash_id = gcry_md_map_name(crypt_hash_compat_name(name, &flags));
252 if (gcry_md_open(&h->hd, h->hash_id, flags)) {
257 if (gcry_md_setkey(h->hd, buffer, length)) {
258 gcry_md_close(h->hd);
263 h->hash_len = gcry_md_get_algo_dlen(h->hash_id);
268 static void crypt_hmac_restart(struct crypt_hmac *ctx)
270 gcry_md_reset(ctx->hd);
273 int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
275 gcry_md_write(ctx->hd, buffer, length);
279 int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
283 if (length > (size_t)ctx->hash_len)
286 hash = gcry_md_read(ctx->hd, ctx->hash_id);
290 memcpy(buffer, hash, length);
291 crypt_hmac_restart(ctx);
296 int crypt_hmac_destroy(struct crypt_hmac *ctx)
298 gcry_md_close(ctx->hd);
299 memset(ctx, 0, sizeof(*ctx));
305 int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
308 case CRYPT_RND_NORMAL:
309 gcry_randomize(buffer, length, GCRY_STRONG_RANDOM);
314 gcry_randomize(buffer, length, GCRY_VERY_STRONG_RANDOM);
321 int crypt_pbkdf(const char *kdf, const char *hash,
322 const char *password, size_t password_length,
323 const char *salt, size_t salt_length,
324 char *key, size_t key_length,
325 unsigned int iterations)
327 const char *hash_name = crypt_hash_compat_name(hash, NULL);
329 #if USE_INTERNAL_PBKDF2
330 if (!kdf || strncmp(kdf, "pbkdf2", 6))
333 return pkcs5_pbkdf2(hash_name, password, password_length, salt, salt_length,
334 iterations, key_length, key, 0);
336 #else /* USE_INTERNAL_PBKDF2 */
337 int hash_id = gcry_md_map_name(hash_name);
343 if (kdf && !strncmp(kdf, "pbkdf2", 6))
344 kdf_id = GCRY_KDF_PBKDF2;
348 if (gcry_kdf_derive(password, password_length, kdf_id, hash_id,
349 salt, salt_length, iterations, key_length, key))
353 #endif /* USE_INTERNAL_PBKDF2 */