2 * Linux kernel userspace API 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 <sys/socket.h>
28 #include <sys/utsname.h>
29 #include <linux/if_alg.h>
30 #include "crypto_backend.h"
32 /* FIXME: remove later */
40 static int crypto_backend_initialised = 0;
41 static char version[64];
45 const char *kernel_name;
47 unsigned int block_length;
50 static struct hash_alg hash_algs[] = {
51 { "sha1", "sha1", 20, 64 },
52 { "sha256", "sha256", 32, 64 },
53 { "sha512", "sha512", 64, 128 },
54 { "ripemd160", "rmd160", 20, 64 },
55 { "whirlpool", "wp512", 64, 64 },
71 /* Defined in crypt_kernel_ciphers.c */
72 extern int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *opfd);
74 int crypt_backend_init(struct crypt_device *ctx)
77 struct sockaddr_alg sa = {
78 .salg_family = AF_ALG,
82 int tfmfd = -1, opfd = -1;
84 if (crypto_backend_initialised)
87 if (uname(&uts) == -1 || strcmp(uts.sysname, "Linux"))
90 if (crypt_kernel_socket_init(&sa, &tfmfd, &opfd) < 0)
96 snprintf(version, sizeof(version), "%s %s kernel cryptoAPI",
97 uts.sysname, uts.release);
99 crypto_backend_initialised = 1;
103 uint32_t crypt_backend_flags(void)
105 return CRYPT_BACKEND_KERNEL;
108 const char *crypt_backend_version(void)
110 return crypto_backend_initialised ? version : "";
113 static struct hash_alg *_get_alg(const char *name)
117 while (name && hash_algs[i].name) {
118 if (!strcmp(name, hash_algs[i].name))
119 return &hash_algs[i];
126 int crypt_hash_size(const char *name)
128 struct hash_alg *ha = _get_alg(name);
130 return ha ? ha->length : -EINVAL;
133 int crypt_hash_init(struct crypt_hash **ctx, const char *name)
135 struct crypt_hash *h;
137 struct sockaddr_alg sa = {
138 .salg_family = AF_ALG,
142 h = malloc(sizeof(*h));
151 h->hash_len = ha->length;
153 strncpy((char *)sa.salg_name, ha->kernel_name, sizeof(sa.salg_name));
155 if (crypt_kernel_socket_init(&sa, &h->tfmfd, &h->opfd) < 0) {
164 int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
168 r = send(ctx->opfd, buffer, length, MSG_MORE);
169 if (r < 0 || (size_t)r < length)
175 int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
179 if (length > (size_t)ctx->hash_len)
182 r = read(ctx->opfd, buffer, length);
189 int crypt_hash_destroy(struct crypt_hash *ctx)
191 if (ctx->tfmfd != -1)
195 memset(ctx, 0, sizeof(*ctx));
201 int crypt_hmac_size(const char *name)
203 return crypt_hash_size(name);
206 int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
207 const void *buffer, size_t length)
209 struct crypt_hmac *h;
211 struct sockaddr_alg sa = {
212 .salg_family = AF_ALG,
216 h = malloc(sizeof(*h));
225 h->hash_len = ha->length;
227 snprintf((char *)sa.salg_name, sizeof(sa.salg_name),
228 "hmac(%s)", ha->kernel_name);
230 if (crypt_kernel_socket_init(&sa, &h->tfmfd, &h->opfd) < 0) {
235 if (setsockopt(h->tfmfd, SOL_ALG, ALG_SET_KEY, buffer, length) == -1) {
236 crypt_hmac_destroy(h);
244 int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
248 r = send(ctx->opfd, buffer, length, MSG_MORE);
249 if (r < 0 || (size_t)r < length)
255 int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
259 if (length > (size_t)ctx->hash_len)
262 r = read(ctx->opfd, buffer, length);
269 int crypt_hmac_destroy(struct crypt_hmac *ctx)
271 if (ctx->tfmfd != -1)
275 memset(ctx, 0, sizeof(*ctx));
281 int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
287 int crypt_pbkdf(const char *kdf, const char *hash,
288 const char *password, size_t password_length,
289 const char *salt, size_t salt_length,
290 char *key, size_t key_length,
291 unsigned int iterations)
293 struct hash_alg *ha = _get_alg(hash);
295 if (!ha || !kdf || strncmp(kdf, "pbkdf2", 6))
298 return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length,
299 iterations, key_length, key, ha->block_length);