From 923ce9a0091bdcc86fdab434de2f4506c1176524 Mon Sep 17 00:00:00 2001 From: "Joshua I. James" Date: Fri, 5 Dec 2014 14:06:16 +0900 Subject: crypto: ablkcipher - fixed style errors in ablkcipher.c Fixed style errors reported by checkpatch. WARNING: Missing a blank line after declarations + u8 *end_page = (u8 *)(((unsigned long)(start + len - 1)) & PAGE_MASK); + return max(start, end_page); WARNING: line over 80 characters + scatterwalk_start(&walk->out, scatterwalk_sg_next(walk->out.sg)); WARNING: Missing a blank line after declarations + int err = ablkcipher_copy_iv(walk, tfm, alignmask); + if (err) ERROR: do not use assignment in if condition + if ((err = crypto_register_instance(tmpl, inst))) { Signed-off-by: Joshua I. James Signed-off-by: Herbert Xu --- crypto/ablkcipher.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c index 40886c48..7bbc8b4e 100644 --- a/crypto/ablkcipher.c +++ b/crypto/ablkcipher.c @@ -69,6 +69,7 @@ static inline void ablkcipher_queue_write(struct ablkcipher_walk *walk, static inline u8 *ablkcipher_get_spot(u8 *start, unsigned int len) { u8 *end_page = (u8 *)(((unsigned long)(start + len - 1)) & PAGE_MASK); + return max(start, end_page); } @@ -86,7 +87,8 @@ static inline unsigned int ablkcipher_done_slow(struct ablkcipher_walk *walk, if (n == len_this_page) break; n -= len_this_page; - scatterwalk_start(&walk->out, scatterwalk_sg_next(walk->out.sg)); + scatterwalk_start(&walk->out, scatterwalk_sg_next( + walk->out.sg)); } return bsize; @@ -284,6 +286,7 @@ static int ablkcipher_walk_first(struct ablkcipher_request *req, walk->iv = req->info; if (unlikely(((unsigned long)walk->iv & alignmask))) { int err = ablkcipher_copy_iv(walk, tfm, alignmask); + if (err) return err; } @@ -589,7 +592,8 @@ static int crypto_givcipher_default(struct crypto_alg *alg, u32 type, u32 mask) if (IS_ERR(inst)) goto put_tmpl; - if ((err = crypto_register_instance(tmpl, inst))) { + err = crypto_register_instance(tmpl, inst); + if (err) { tmpl->free(inst); goto put_tmpl; } -- cgit v1.2.3 From e5d7afd024da27d19b1d966a87bc7ded4fc5f127 Mon Sep 17 00:00:00 2001 From: "Joshua I. James" Date: Fri, 5 Dec 2014 14:24:44 +0900 Subject: crypto: aead - fixed style error in aead.c Fixed style error identified by checkpatch. ERROR: do not use assignment in if condition + if ((err = crypto_register_instance(tmpl, inst))) { Signed-off-by: Joshua I. James Signed-off-by: Herbert Xu --- crypto/aead.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crypto/aead.c b/crypto/aead.c index 547491e3..22227107 100644 --- a/crypto/aead.c +++ b/crypto/aead.c @@ -448,7 +448,8 @@ static int crypto_nivaead_default(struct crypto_alg *alg, u32 type, u32 mask) if (IS_ERR(inst)) goto put_tmpl; - if ((err = crypto_register_instance(tmpl, inst))) { + err = crypto_register_instance(tmpl, inst); + if (err) { tmpl->free(inst); goto put_tmpl; } -- cgit v1.2.3 From 3cd5b0be5ef0c2ad595549465c7db7ce638b2a12 Mon Sep 17 00:00:00 2001 From: "Joshua I. James" Date: Fri, 5 Dec 2014 14:38:40 +0900 Subject: crypto: af_alg - fixed style error in af_alg.c Fixed style error identified by checkpatch. ERROR: space required before the open parenthesis '(' + switch(cmsg->cmsg_type) { Signed-off-by: Joshua I. James Signed-off-by: Herbert Xu --- crypto/af_alg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 4665b79c..8ffc174a 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -405,7 +405,7 @@ int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con) if (cmsg->cmsg_level != SOL_ALG) continue; - switch(cmsg->cmsg_type) { + switch (cmsg->cmsg_type) { case ALG_SET_IV: if (cmsg->cmsg_len < CMSG_LEN(sizeof(*con->iv))) return -EINVAL; -- cgit v1.2.3 From 509979eda037e8973364894dacccca3da9f162ed Mon Sep 17 00:00:00 2001 From: "Joshua I. James" Date: Fri, 5 Dec 2014 14:44:54 +0900 Subject: crypto: ahash - fixed style error in ahash.c Fixed style error identified by checkpatch. WARNING: Missing a blank line after declarations + unsigned int unaligned = alignmask + 1 - (offset & alignmask); + if (nbytes > unaligned) Signed-off-by: Joshua I. James Signed-off-by: Herbert Xu --- crypto/ahash.c | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto/ahash.c b/crypto/ahash.c index f6a36a52..dd289060 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -55,6 +55,7 @@ static int hash_walk_next(struct crypto_hash_walk *walk) if (offset & alignmask) { unsigned int unaligned = alignmask + 1 - (offset & alignmask); + if (nbytes > unaligned) nbytes = unaligned; } -- cgit v1.2.3 From 4cf5c4753707baf7b5a1c017cf03e12836547a30 Mon Sep 17 00:00:00 2001 From: "Joshua I. James" Date: Fri, 5 Dec 2014 15:00:10 +0900 Subject: crypto: api - fixed style erro in algapi.c Fixed style error identified by checkpatch. WARNING: Missing a blank line after declarations + int err = crypto_remove_alg(&inst->alg, &users); + BUG_ON(err); Signed-off-by: Joshua I. James Signed-off-by: Herbert Xu --- crypto/algapi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto/algapi.c b/crypto/algapi.c index 71a8143e..83b04e08 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -473,6 +473,7 @@ void crypto_unregister_template(struct crypto_template *tmpl) list = &tmpl->instances; hlist_for_each_entry(inst, list, list) { int err = crypto_remove_alg(&inst->alg, &users); + BUG_ON(err); } -- cgit v1.2.3 From 2718d3daac8bfa60bb7a9746c587499802c7c6a6 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Fri, 5 Dec 2014 22:40:21 +0100 Subject: crypto: drbg - panic on continuous self test error This patch adds a panic if the FIPS 140-2 self test error failed. Note, that entire code is only executed with fips_enabled (i.e. when the kernel is booted with fips=1. It is therefore not executed for 99.9% of all user base. As mathematically such failure cannot occur, this panic should never be triggered. But to comply with NISTs current requirements, an endless loop must be replaced with the panic. When the new version of FIPS 140 will be released, this entire continuous self test function will be ripped out as it will not be needed any more. This patch is functionally equivalent as implemented in ansi_cprng.c and drivers/char/random.c. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/drbg.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/crypto/drbg.c b/crypto/drbg.c index d748a1d0..96138396 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -223,15 +223,6 @@ static inline unsigned short drbg_sec_strength(drbg_flag_t flags) * function. Thus, the function implicitly knows the size of the * buffer. * - * The FIPS test can be called in an endless loop until it returns - * true. Although the code looks like a potential for a deadlock, it - * is not the case, because returning a false cannot mathematically - * occur (except once when a reseed took place and the updated state - * would is now set up such that the generation of new value returns - * an identical one -- this is most unlikely and would happen only once). - * Thus, if this function repeatedly returns false and thus would cause - * a deadlock, the integrity of the entire kernel is lost. - * * @drbg DRBG handle * @buf output buffer of random data to be checked * @@ -258,6 +249,8 @@ static bool drbg_fips_continuous_test(struct drbg_state *drbg, return false; } ret = memcmp(drbg->prev, buf, drbg_blocklen(drbg)); + if (!ret) + panic("DRBG continuous self test failed\n"); memcpy(drbg->prev, buf, drbg_blocklen(drbg)); /* the test shall pass when the two compared values are not equal */ return ret != 0; -- cgit v1.2.3 From 4c787567186b1e2df82b6f920d692ce67421ec75 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Sun, 7 Dec 2014 23:21:42 +0100 Subject: crypto: af_alg - add setsockopt for auth tag size Use setsockopt on the tfm FD to provide the authentication tag size for an AEAD cipher. This is achieved by adding a callback function which is intended to be used by the AEAD AF_ALG implementation. The optlen argument of the setsockopt specifies the authentication tag size to be used with the AEAD tfm. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/af_alg.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 8ffc174a..a8ff3c44 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -215,6 +215,13 @@ static int alg_setsockopt(struct socket *sock, int level, int optname, goto unlock; err = alg_setkey(sk, optval, optlen); + break; + case ALG_SET_AEAD_AUTHSIZE: + if (sock->state == SS_CONNECTED) + goto unlock; + if (!type->setauthsize) + goto unlock; + err = type->setauthsize(ask->private, optlen); } unlock: -- cgit v1.2.3 From a57d5b404077034de1c5a1c767387b3abb7d4d42 Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Mon, 8 Dec 2014 12:03:42 -0800 Subject: crypto: algif - Mark sgl end at the end of data algif_skcipher sends 127 sgl buffers for encryption regardless of how many buffers acctually have data to process, where the few first with valid len and the rest with zero len. This is not very eficient. This patch marks the last one with data as the last one to process. Signed-off-by: Tadeusz Struk Signed-off-by: Herbert Xu --- crypto/algif_skcipher.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index c12207c8..38a6757e 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -330,6 +330,7 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); sg = sgl->sg; + sg_unmark_end(sg + sgl->cur); do { i = sgl->cur; plen = min_t(int, len, PAGE_SIZE); @@ -355,6 +356,9 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, sgl->cur++; } while (len && sgl->cur < MAX_SGL_ENTS); + if (!size) + sg_mark_end(sg + sgl->cur - 1); + ctx->merge = plen & (PAGE_SIZE - 1); } @@ -401,6 +405,10 @@ static ssize_t skcipher_sendpage(struct socket *sock, struct page *page, ctx->merge = 0; sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); + if (sgl->cur) + sg_unmark_end(sgl->sg + sgl->cur - 1); + + sg_mark_end(sgl->sg + sgl->cur); get_page(page); sg_set_page(sgl->sg + sgl->cur, page, size, offset); sgl->cur++; -- cgit v1.2.3 From df5f79630807fb18202dc32648863ae32c0a0742 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 21 Dec 2014 22:54:02 +0200 Subject: crypto: octeon - enable OCTEON MD5 module selection Enable user to select OCTEON MD5 module. Signed-off-by: Aaro Koskinen Signed-off-by: Herbert Xu --- crypto/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index 87bbc9c1..1618468b 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -427,6 +427,15 @@ config CRYPTO_MD5 help MD5 message digest algorithm (RFC1321). +config CRYPTO_MD5_OCTEON + tristate "MD5 digest algorithm (OCTEON)" + depends on CPU_CAVIUM_OCTEON + select CRYPTO_MD5 + select CRYPTO_HASH + help + MD5 message digest algorithm (RFC1321) implemented + using OCTEON crypto instructions, when available. + config CRYPTO_MD5_SPARC64 tristate "MD5 digest algorithm (SPARC64)" depends on SPARC64 -- cgit v1.2.3 From 3ddb5ea2a13a74e9a28d686b3b52c81b919b9124 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Tue, 23 Dec 2014 09:34:03 +0100 Subject: crypto: af_alg - zeroize key data alg_setkey should zeroize the sensitive data after use. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/af_alg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index a8ff3c44..76d739d0 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -188,7 +188,7 @@ static int alg_setkey(struct sock *sk, char __user *ukey, err = type->setkey(ask->private, key, keylen); out: - sock_kfree_s(sk, key, keylen); + sock_kzfree_s(sk, key, keylen); return err; } -- cgit v1.2.3 From f9b1d33400b689d77c48b5bccd94e6cc264f4a31 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Thu, 25 Dec 2014 23:00:06 +0100 Subject: crypto: algif_rng - add random number generator support This patch adds the random number generator support for AF_ALG. A random number generator's purpose is to generate data without requiring the caller to provide any data. Therefore, the AF_ALG interface handler for RNGs only implements a callback handler for recvmsg. The following parameters provided with a recvmsg are processed by the RNG callback handler: * sock - to resolve the RNG context data structure accessing the RNG instance private to the socket * len - this parameter allows userspace callers to specify how many random bytes the RNG shall produce and return. As the kernel context for the RNG allocates a buffer of 128 bytes to store random numbers before copying them to userspace, the len parameter is checked that it is not larger than 128. If a caller wants more random numbers, a new request for recvmsg shall be made. The size of 128 bytes is chose because of the following considerations: * to increase the memory footprint of the kernel too much (note, that would be 128 bytes per open socket) * 128 is divisible by any typical cryptographic block size an RNG may have * A request for random numbers typically only shall supply small amount of data like for keys or IVs that should only require one invocation of the recvmsg function. Note, during instantiation of the RNG, the code checks whether the RNG implementation requires seeding. If so, the RNG is seeded with output from get_random_bytes. A fully working example using all aspects of the RNG interface is provided at http://www.chronox.de/libkcapi.html Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/algif_rng.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 crypto/algif_rng.c diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c new file mode 100644 index 00000000..91c06f56 --- /dev/null +++ b/crypto/algif_rng.c @@ -0,0 +1,192 @@ +/* + * algif_rng: User-space interface for random number generators + * + * This file provides the user-space API for random number generators. + * + * Copyright (C) 2014, Stephan Mueller + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU General Public License, in which case the provisions of the GPL2 + * are required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Stephan Mueller "); +MODULE_DESCRIPTION("User-space interface for random number generators"); + +struct rng_ctx { +#define MAXSIZE 128 + unsigned int len; + struct crypto_rng *drng; +}; + +static int rng_recvmsg(struct kiocb *unused, struct socket *sock, + struct msghdr *msg, size_t len, int flags) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct rng_ctx *ctx = ask->private; + int err = -EFAULT; + int genlen = 0; + u8 result[MAXSIZE]; + + if (len == 0) + return 0; + if (len > MAXSIZE) + len = MAXSIZE; + + /* + * although not strictly needed, this is a precaution against coding + * errors + */ + memset(result, 0, len); + + /* + * The enforcement of a proper seeding of an RNG is done within an + * RNG implementation. Some RNGs (DRBG, krng) do not need specific + * seeding as they automatically seed. The X9.31 DRNG will return + * an error if it was not seeded properly. + */ + genlen = crypto_rng_get_bytes(ctx->drng, result, len); + if (genlen < 0) + return genlen; + + err = memcpy_to_msg(msg, result, len); + memzero_explicit(result, genlen); + + return err ? err : len; +} + +static struct proto_ops algif_rng_ops = { + .family = PF_ALG, + + .connect = sock_no_connect, + .socketpair = sock_no_socketpair, + .getname = sock_no_getname, + .ioctl = sock_no_ioctl, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .getsockopt = sock_no_getsockopt, + .mmap = sock_no_mmap, + .bind = sock_no_bind, + .accept = sock_no_accept, + .setsockopt = sock_no_setsockopt, + .poll = sock_no_poll, + .sendmsg = sock_no_sendmsg, + .sendpage = sock_no_sendpage, + + .release = af_alg_release, + .recvmsg = rng_recvmsg, +}; + +static void *rng_bind(const char *name, u32 type, u32 mask) +{ + return crypto_alloc_rng(name, type, mask); +} + +static void rng_release(void *private) +{ + crypto_free_rng(private); +} + +static void rng_sock_destruct(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct rng_ctx *ctx = ask->private; + + sock_kfree_s(sk, ctx, ctx->len); + af_alg_release_parent(sk); +} + +static int rng_accept_parent(void *private, struct sock *sk) +{ + struct rng_ctx *ctx; + struct alg_sock *ask = alg_sk(sk); + unsigned int len = sizeof(*ctx); + + ctx = sock_kmalloc(sk, len, GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + ctx->len = len; + + /* + * No seeding done at that point -- if multiple accepts are + * done on one RNG instance, each resulting FD points to the same + * state of the RNG. + */ + + ctx->drng = private; + ask->private = ctx; + sk->sk_destruct = rng_sock_destruct; + + return 0; +} + +static int rng_setkey(void *private, const u8 *seed, unsigned int seedlen) +{ + /* + * Check whether seedlen is of sufficient size is done in RNG + * implementations. + */ + return crypto_rng_reset(private, (u8 *)seed, seedlen); +} + +static const struct af_alg_type algif_type_rng = { + .bind = rng_bind, + .release = rng_release, + .accept = rng_accept_parent, + .setkey = rng_setkey, + .ops = &algif_rng_ops, + .name = "rng", + .owner = THIS_MODULE +}; + +static int __init rng_init(void) +{ + return af_alg_register_type(&algif_type_rng); +} + +void __exit rng_exit(void) +{ + int err = af_alg_unregister_type(&algif_type_rng); + BUG_ON(err); +} + +module_init(rng_init); +module_exit(rng_exit); -- cgit v1.2.3 From c772d87b4c33db2f7341f91e32207a5ef03a3fde Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Thu, 25 Dec 2014 23:00:39 +0100 Subject: crypto: algif_rng - enable RNG interface compilation Enable compilation of the RNG AF_ALG support and provide a Kconfig option to compile the RNG AF_ALG support. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/Kconfig | 9 +++++++++ crypto/Makefile | 1 + 2 files changed, 10 insertions(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index 1618468b..50f4da44 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -1514,6 +1514,15 @@ config CRYPTO_USER_API_SKCIPHER This option enables the user-spaces interface for symmetric key cipher algorithms. +config CRYPTO_USER_API_RNG + tristate "User-space interface for random number generator algorithms" + depends on NET + select CRYPTO_RNG + select CRYPTO_USER_API + help + This option enables the user-spaces interface for random + number generator algorithms. + config CRYPTO_HASH_INFO bool diff --git a/crypto/Makefile b/crypto/Makefile index 1445b910..ba19465f 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -99,6 +99,7 @@ obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o +obj-$(CONFIG_CRYPTO_USER_API_RNG) += algif_rng.o # # generic algorithms and the async_tx api -- cgit v1.2.3 From 1fbedcb208372773cf2ddf4b929894adbdc05897 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 5 Jan 2015 10:44:09 +1100 Subject: Revert "crypto: drbg - use memzero_explicit() for clearing sensitive data" This reverts commit d04559b19f65b04ca6cf45c80c934c75e5030507. None of the data zeroed are on the stack so the compiler cannot optimise them away. Signed-off-by: Herbert Xu --- crypto/drbg.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/crypto/drbg.c b/crypto/drbg.c index 96138396..d8ff16e5 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -98,7 +98,6 @@ */ #include -#include /*************************************************************** * Backend cipher definitions available to DRBG @@ -491,9 +490,9 @@ static int drbg_ctr_df(struct drbg_state *drbg, ret = 0; out: - memzero_explicit(iv, drbg_blocklen(drbg)); - memzero_explicit(temp, drbg_statelen(drbg)); - memzero_explicit(pad, drbg_blocklen(drbg)); + memset(iv, 0, drbg_blocklen(drbg)); + memset(temp, 0, drbg_statelen(drbg)); + memset(pad, 0, drbg_blocklen(drbg)); return ret; } @@ -567,9 +566,9 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, ret = 0; out: - memzero_explicit(temp, drbg_statelen(drbg) + drbg_blocklen(drbg)); + memset(temp, 0, drbg_statelen(drbg) + drbg_blocklen(drbg)); if (2 != reseed) - memzero_explicit(df_data, drbg_statelen(drbg)); + memset(df_data, 0, drbg_statelen(drbg)); return ret; } @@ -627,7 +626,7 @@ static int drbg_ctr_generate(struct drbg_state *drbg, len = ret; out: - memzero_explicit(drbg->scratchpad, drbg_blocklen(drbg)); + memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); return len; } @@ -865,7 +864,7 @@ static int drbg_hash_df(struct drbg_state *drbg, } out: - memzero_explicit(tmp, drbg_blocklen(drbg)); + memset(tmp, 0, drbg_blocklen(drbg)); return ret; } @@ -909,7 +908,7 @@ static int drbg_hash_update(struct drbg_state *drbg, struct list_head *seed, ret = drbg_hash_df(drbg, drbg->C, drbg_statelen(drbg), &datalist2); out: - memzero_explicit(drbg->scratchpad, drbg_statelen(drbg)); + memset(drbg->scratchpad, 0, drbg_statelen(drbg)); return ret; } @@ -944,7 +943,7 @@ static int drbg_hash_process_addtl(struct drbg_state *drbg, drbg->scratchpad, drbg_blocklen(drbg)); out: - memzero_explicit(drbg->scratchpad, drbg_blocklen(drbg)); + memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); return ret; } @@ -991,7 +990,7 @@ static int drbg_hash_hashgen(struct drbg_state *drbg, } out: - memzero_explicit(drbg->scratchpad, + memset(drbg->scratchpad, 0, (drbg_statelen(drbg) + drbg_blocklen(drbg))); return len; } @@ -1040,7 +1039,7 @@ static int drbg_hash_generate(struct drbg_state *drbg, drbg_add_buf(drbg->V, drbg_statelen(drbg), u.req, 8); out: - memzero_explicit(drbg->scratchpad, drbg_blocklen(drbg)); + memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); return len; } -- cgit v1.2.3 From e61ef0139ced7fcecaa9113a51641f3504e86d28 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Fri, 9 Jan 2015 16:25:28 +0100 Subject: crypto: testmgr - don't use interruptible wait in tests tcrypt/testmgr uses wait_for_completion_interruptible() everywhere when it waits for a request to be completed. If it's interrupted, then the test is aborted and the request is freed. However, if any of these calls actually do get interrupted, the result will likely be a kernel crash, when the driver handles the now-freed request. Use wait_for_completion() instead. Signed-off-by: Rabin Vincent Signed-off-by: Herbert Xu --- crypto/tcrypt.c | 10 ++++------ crypto/testmgr.c | 50 ++++++++++++++++++++++---------------------------- 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 1d864e98..00434957 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -764,10 +764,9 @@ static inline int do_one_ahash_op(struct ahash_request *req, int ret) if (ret == -EINPROGRESS || ret == -EBUSY) { struct tcrypt_result *tr = req->base.data; - ret = wait_for_completion_interruptible(&tr->completion); - if (!ret) - ret = tr->err; + wait_for_completion(&tr->completion); reinit_completion(&tr->completion); + ret = tr->err; } return ret; } @@ -993,10 +992,9 @@ static inline int do_one_acipher_op(struct ablkcipher_request *req, int ret) if (ret == -EINPROGRESS || ret == -EBUSY) { struct tcrypt_result *tr = req->base.data; - ret = wait_for_completion_interruptible(&tr->completion); - if (!ret) - ret = tr->err; + wait_for_completion(&tr->completion); reinit_completion(&tr->completion); + ret = tr->err; } return ret; diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 037368d3..235b1fff 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -181,10 +181,9 @@ static void testmgr_free_buf(char *buf[XBUFSIZE]) static int wait_async_op(struct tcrypt_result *tr, int ret) { if (ret == -EINPROGRESS || ret == -EBUSY) { - ret = wait_for_completion_interruptible(&tr->completion); - if (!ret) - ret = tr->err; + wait_for_completion(&tr->completion); reinit_completion(&tr->completion); + ret = tr->err; } return ret; } @@ -353,12 +352,11 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, break; case -EINPROGRESS: case -EBUSY: - ret = wait_for_completion_interruptible( - &tresult.completion); - if (!ret && !(ret = tresult.err)) { - reinit_completion(&tresult.completion); + wait_for_completion(&tresult.completion); + reinit_completion(&tresult.completion); + ret = tresult.err; + if (!ret) break; - } /* fall through */ default: printk(KERN_ERR "alg: hash: digest failed " @@ -569,12 +567,11 @@ static int __test_aead(struct crypto_aead *tfm, int enc, break; case -EINPROGRESS: case -EBUSY: - ret = wait_for_completion_interruptible( - &result.completion); - if (!ret && !(ret = result.err)) { - reinit_completion(&result.completion); + wait_for_completion(&result.completion); + reinit_completion(&result.completion); + ret = result.err; + if (!ret) break; - } case -EBADMSG: if (template[i].novrfy) /* verification failure was expected */ @@ -720,12 +717,11 @@ static int __test_aead(struct crypto_aead *tfm, int enc, break; case -EINPROGRESS: case -EBUSY: - ret = wait_for_completion_interruptible( - &result.completion); - if (!ret && !(ret = result.err)) { - reinit_completion(&result.completion); + wait_for_completion(&result.completion); + reinit_completion(&result.completion); + ret = result.err; + if (!ret) break; - } case -EBADMSG: if (template[i].novrfy) /* verification failure was expected */ @@ -1002,12 +998,11 @@ static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc, break; case -EINPROGRESS: case -EBUSY: - ret = wait_for_completion_interruptible( - &result.completion); - if (!ret && !((ret = result.err))) { - reinit_completion(&result.completion); + wait_for_completion(&result.completion); + reinit_completion(&result.completion); + ret = result.err; + if (!ret) break; - } /* fall through */ default: pr_err("alg: skcipher%s: %s failed on test %d for %s: ret=%d\n", @@ -1097,12 +1092,11 @@ static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc, break; case -EINPROGRESS: case -EBUSY: - ret = wait_for_completion_interruptible( - &result.completion); - if (!ret && !((ret = result.err))) { - reinit_completion(&result.completion); + wait_for_completion(&result.completion); + reinit_completion(&result.completion); + ret = result.err; + if (!ret) break; - } /* fall through */ default: pr_err("alg: skcipher%s: %s failed on chunk test %d for %s: ret=%d\n", -- cgit v1.2.3 From bcd6093dabd102db9d49e3106102e70273850b70 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 14 Jan 2015 09:14:41 +0800 Subject: crypto: algif_rng - fix sparse non static symbol warning Fixes the following sparse warnings: crypto/algif_rng.c:185:13: warning: symbol 'rng_exit' was not declared. Should it be static? Signed-off-by: Wei Yongjun Acked-by: Stephan Mueller Acked-by: Neil Horman Signed-off-by: Herbert Xu --- crypto/algif_rng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c index 91c06f56..67f612cf 100644 --- a/crypto/algif_rng.c +++ b/crypto/algif_rng.c @@ -182,7 +182,7 @@ static int __init rng_init(void) return af_alg_register_type(&algif_type_rng); } -void __exit rng_exit(void) +static void __exit rng_exit(void) { int err = af_alg_unregister_type(&algif_type_rng); BUG_ON(err); -- cgit v1.2.3 From 05253b62d8bcd34511158c90ab84d3ed18a03954 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 16 Jan 2015 18:09:21 +1100 Subject: crypto: cts - Remove bogus use of seqiv The seqiv generator is completely inappropriate for cts as it's designed for IPsec algorithms. Since cts users do not actually use the IV generator we can just fall back to the default. Signed-off-by: Herbert Xu Acked-by: Maciej ?enczykowski --- crypto/cts.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/crypto/cts.c b/crypto/cts.c index bd940582..6a8089c4 100644 --- a/crypto/cts.c +++ b/crypto/cts.c @@ -307,8 +307,6 @@ static struct crypto_instance *crypto_cts_alloc(struct rtattr **tb) inst->alg.cra_blkcipher.min_keysize = alg->cra_blkcipher.min_keysize; inst->alg.cra_blkcipher.max_keysize = alg->cra_blkcipher.max_keysize; - inst->alg.cra_blkcipher.geniv = "seqiv"; - inst->alg.cra_ctxsize = sizeof(struct crypto_cts_ctx); inst->alg.cra_init = crypto_cts_init_tfm; -- cgit v1.2.3 From aa3e312a9b98552a28b22fa166597b0767952ba0 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 16 Jan 2015 19:38:17 +1100 Subject: crypto: cts - Weed out non-CBC algorithms The cts algorithm as currently implemented assumes the underlying is a CBC-mode algorithm. So this patch adds a check for that to eliminate bogus combinations of cts with non-CBC modes. Signed-off-by: Herbert Xu --- crypto/cts.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crypto/cts.c b/crypto/cts.c index 6a8089c4..e467ec0a 100644 --- a/crypto/cts.c +++ b/crypto/cts.c @@ -290,6 +290,9 @@ static struct crypto_instance *crypto_cts_alloc(struct rtattr **tb) if (!is_power_of_2(alg->cra_blocksize)) goto out_put_alg; + if (strncmp(alg->cra_name, "cbc(", 4)) + goto out_put_alg; + inst = crypto_alloc_instance("cts", alg); if (IS_ERR(inst)) goto out_put_alg; -- cgit v1.2.3 From 439e6c93e275bd72d51bed0fdca493ffa8eaaa4a Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 16 Jan 2015 19:51:20 +1100 Subject: crypto: seqiv - Ensure that IV size is at least 8 bytes Since seqiv is designed for IPsec we need to be able to accomodate the whole IPsec sequence number in order to ensure the uniqueness of the IV. This patch forbids any algorithm with an IV size of less than 8 from using it. This should have no impact on existing users since they all have an IV size of 8. Reported-by: Maciej ?enczykowski Signed-off-by: Herbert Xu Acked-by: Maciej ?enczykowski --- crypto/seqiv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crypto/seqiv.c b/crypto/seqiv.c index 9daa854c..b7bb9a2f 100644 --- a/crypto/seqiv.c +++ b/crypto/seqiv.c @@ -267,6 +267,12 @@ static struct crypto_instance *seqiv_ablkcipher_alloc(struct rtattr **tb) if (IS_ERR(inst)) goto out; + if (inst->alg.cra_ablkcipher.ivsize < sizeof(u64)) { + skcipher_geniv_free(inst); + inst = ERR_PTR(-EINVAL); + goto out; + } + inst->alg.cra_ablkcipher.givencrypt = seqiv_givencrypt_first; inst->alg.cra_init = seqiv_init; @@ -287,6 +293,12 @@ static struct crypto_instance *seqiv_aead_alloc(struct rtattr **tb) if (IS_ERR(inst)) goto out; + if (inst->alg.cra_aead.ivsize < sizeof(u64)) { + aead_geniv_free(inst); + inst = ERR_PTR(-EINVAL); + goto out; + } + inst->alg.cra_aead.givencrypt = seqiv_aead_givencrypt_first; inst->alg.cra_init = seqiv_aead_init; -- cgit v1.2.3 From 1206eddfc81bb6e7f67c2a9b3b93c6ccd5495f2b Mon Sep 17 00:00:00 2001 From: Cristian Stoica Date: Tue, 20 Jan 2015 10:06:16 +0200 Subject: crypto: replace scatterwalk_sg_next with sg_next Modify crypto drivers to use the generic SG helper since both of them are equivalent and the one from crypto is redundant. See also: e1831a52fbacad9aa2bcc90636f2a8e03584d90c reverted in cf51b44c8b86c241584aefaa1f612cbe8f75123f Signed-off-by: Cristian Stoica Signed-off-by: Herbert Xu --- crypto/ablkcipher.c | 3 +-- crypto/ahash.c | 2 +- crypto/scatterwalk.c | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c index 7bbc8b4e..db201bca 100644 --- a/crypto/ablkcipher.c +++ b/crypto/ablkcipher.c @@ -87,8 +87,7 @@ static inline unsigned int ablkcipher_done_slow(struct ablkcipher_walk *walk, if (n == len_this_page) break; n -= len_this_page; - scatterwalk_start(&walk->out, scatterwalk_sg_next( - walk->out.sg)); + scatterwalk_start(&walk->out, sg_next(walk->out.sg)); } return bsize; diff --git a/crypto/ahash.c b/crypto/ahash.c index dd289060..8acb8860 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -121,7 +121,7 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err) if (!walk->total) return 0; - walk->sg = scatterwalk_sg_next(walk->sg); + walk->sg = sg_next(walk->sg); return hash_walk_new_entry(walk); } diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c index 79ca2278..3bd749c7 100644 --- a/crypto/scatterwalk.c +++ b/crypto/scatterwalk.c @@ -62,7 +62,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out, walk->offset += PAGE_SIZE - 1; walk->offset &= PAGE_MASK; if (walk->offset >= walk->sg->offset + walk->sg->length) - scatterwalk_start(walk, scatterwalk_sg_next(walk->sg)); + scatterwalk_start(walk, sg_next(walk->sg)); } } @@ -116,7 +116,7 @@ void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg, break; offset += sg->length; - sg = scatterwalk_sg_next(sg); + sg = sg_next(sg); } scatterwalk_advance(&walk, start - offset); @@ -136,7 +136,7 @@ int scatterwalk_bytes_sglen(struct scatterlist *sg, int num_bytes) do { offset += sg->length; n++; - sg = scatterwalk_sg_next(sg); + sg = sg_next(sg); /* num_bytes is too large */ if (unlikely(!sg && (num_bytes < offset))) -- cgit v1.2.3 From 9367e7cdb1a269517d4ab4c2570617f8fbce498f Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Fri, 23 Jan 2015 12:42:15 -0500 Subject: crypto: testmgr - mark rfc4106(gcm(aes)) as fips_allowed This gcm variant is popular for ipsec use, and there are folks who would like to use it while in fips mode. Mark it with fips_allowed=1 to facilitate that. CC: LKML CC: Stephan Mueller Signed-off-by: Jarod Wilson Acked-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/testmgr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 235b1fff..758d0284 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -3293,6 +3293,7 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "rfc4106(gcm(aes))", .test = alg_test_aead, + .fips_allowed = 1, .suite = { .aead = { .enc = { -- cgit v1.2.3 From 9ac171c026475175c25ea3b0c0ac7d67100b2d8d Mon Sep 17 00:00:00 2001 From: Cristian Stoica Date: Tue, 27 Jan 2015 11:54:27 +0200 Subject: crypto: tcrypt - fix buflen reminder calculation - This fixes the intent of the code to limit the last scatterlist to either a full PAGE or a fraction of it, depending on the number of pages needed by buflen and the available space advertised by XBUFLEN. The original code always sets the last scatterlist to a fraction of a PAGE because the first 'if' is never executed. - Rearrange the second part of the code to remove the conditional from the loop Signed-off-by: Cristian Stoica Signed-off-by: Herbert Xu --- crypto/tcrypt.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 00434957..2b2486ad 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -250,19 +250,19 @@ static void sg_init_aead(struct scatterlist *sg, char *xbuf[XBUFSIZE], int np = (buflen + PAGE_SIZE - 1)/PAGE_SIZE; int k, rem; - np = (np > XBUFSIZE) ? XBUFSIZE : np; - rem = buflen % PAGE_SIZE; if (np > XBUFSIZE) { rem = PAGE_SIZE; np = XBUFSIZE; + } else { + rem = buflen % PAGE_SIZE; } + sg_init_table(sg, np); - for (k = 0; k < np; ++k) { - if (k == (np-1)) - sg_set_buf(&sg[k], xbuf[k], rem); - else - sg_set_buf(&sg[k], xbuf[k], PAGE_SIZE); - } + np--; + for (k = 0; k < np; k++) + sg_set_buf(&sg[k], xbuf[k], PAGE_SIZE); + + sg_set_buf(&sg[k], xbuf[k], rem); } static void test_aead_speed(const char *algo, int enc, unsigned int secs, -- cgit v1.2.3 From 2e037a4bc5daed2cd453599a3a8420ad2ef199c5 Mon Sep 17 00:00:00 2001 From: Cristian Stoica Date: Wed, 28 Jan 2015 11:03:05 +0200 Subject: crypto: testmgr - limit IV copy length in aead tests The working copy of IV is the same size as the transformation's IV. It is not necessary to copy more than that from the template since iv_len is usually less than MAX_IVLEN and the rest of the copied data is garbage. Signed-off-by: Cristian Stoica Signed-off-by: Herbert Xu --- crypto/testmgr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 758d0284..f4ed6d42 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -429,7 +429,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc, struct scatterlist *sgout; const char *e, *d; struct tcrypt_result result; - unsigned int authsize; + unsigned int authsize, iv_len; void *input; void *output; void *assoc; @@ -500,10 +500,11 @@ static int __test_aead(struct crypto_aead *tfm, int enc, memcpy(input, template[i].input, template[i].ilen); memcpy(assoc, template[i].assoc, template[i].alen); + iv_len = crypto_aead_ivsize(tfm); if (template[i].iv) - memcpy(iv, template[i].iv, MAX_IVLEN); + memcpy(iv, template[i].iv, iv_len); else - memset(iv, 0, MAX_IVLEN); + memset(iv, 0, iv_len); crypto_aead_clear_flags(tfm, ~0); if (template[i].wk) -- cgit v1.2.3 From ee331ed90ef034b75b98ebddbb1db8b3969d78f0 Mon Sep 17 00:00:00 2001 From: Cristian Stoica Date: Wed, 28 Jan 2015 13:07:32 +0200 Subject: crypto: tcrypt - do not allocate iv on stack for aead speed tests See also: b5f1234285bca12041a01cc3bc83d824c2f27ee5 Signed-off-by: Cristian Stoica Signed-off-by: Herbert Xu --- crypto/tcrypt.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 2b2486ad..4b9e23fa 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -280,16 +280,20 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, struct scatterlist *sgout; const char *e; void *assoc; - char iv[MAX_IVLEN]; + char *iv; char *xbuf[XBUFSIZE]; char *xoutbuf[XBUFSIZE]; char *axbuf[XBUFSIZE]; unsigned int *b_size; unsigned int iv_len; + iv = kzalloc(MAX_IVLEN, GFP_KERNEL); + if (!iv) + return; + if (aad_size >= PAGE_SIZE) { pr_err("associate data length (%u) too big\n", aad_size); - return; + goto out_noxbuf; } if (enc == ENCRYPT) @@ -355,7 +359,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, iv_len = crypto_aead_ivsize(tfm); if (iv_len) - memset(&iv, 0xff, iv_len); + memset(iv, 0xff, iv_len); crypto_aead_clear_flags(tfm, ~0); printk(KERN_INFO "test %u (%d bit key, %d byte blocks): ", @@ -408,6 +412,7 @@ out_nooutbuf: out_noaxbuf: testmgr_free_buf(xbuf); out_noxbuf: + kfree(iv); return; } -- cgit v1.2.3