Re: [cryptodev:master 79/79] (.text+0x330de0): multiple definition of `ecdh_shared_secret'
On Fri, Jun 24, 2016 at 07:36:44AM +0100, Salvatore Benedetto wrote: > > > The patch was based on the current tree. I just pulled. > There is not point in moving to lib because bluetooth is > about to be converted to kpp. > That patch I believe will go up the bluetooth tree, so > my suggestion is to simply accept that I fail to properly > name that symbol. > > Renaming the symbol in net/bluetooth/ecc which I think will conflict > with the patch where I remove it completely which, again, I believe > will go up the BT tree. OK I will have no option but to revert your patches then. Cheers, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [cryptodev:master 79/79] (.text+0x330de0): multiple definition of `ecdh_shared_secret'
On Fri, Jun 24, 2016 at 07:23:16AM +0100, Herbert Xu wrote: > On Fri, Jun 24, 2016 at 02:10:12PM +0800, Herbert Xu wrote: > > On Fri, Jun 24, 2016 at 07:06:49AM +0100, Salvatore Benedetto wrote: > > > > > > can you squash the following patch? > > > > No, please prune anything that we don't use from ecc.c. > > I take that back. I see it's actually coming from bluetooth. > > How about moving ecc.c to lib so that it's shared between the > two? The patch was based on the current tree. I just pulled. There is not point in moving to lib because bluetooth is about to be converted to kpp. That patch I believe will go up the bluetooth tree, so my suggestion is to simply accept that I fail to properly name that symbol. Renaming the symbol in net/bluetooth/ecc which I think will conflict with the patch where I remove it completely which, again, I believe will go up the BT tree. Thanks, Salvatore > Thanks, > -- > Email: Herbert Xu > Home Page: http://gondor.apana.org.au/~herbert/ > PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [cryptodev:master 79/79] (.text+0x330de0): multiple definition of `ecdh_shared_secret'
On Fri, Jun 24, 2016 at 07:23:42AM +0100, Salvatore Benedetto wrote: > > We do use the symbol in question, and I'm pretty sure we use > all of crypto/ecc.c. I was going to send a patch where > I remove the net/bluetooth/ecc.c I see. In that case either rename the symbols in net/bluetooth/ecc.c since it's going away or just do the bluetooth conversion. Please send any new patches based on the current tree. Thanks, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [cryptodev:master 79/79] (.text+0x330de0): multiple definition of `ecdh_shared_secret'
On Fri, Jun 24, 2016 at 02:10:12PM +0800, Herbert Xu wrote: > On Fri, Jun 24, 2016 at 07:06:49AM +0100, Salvatore Benedetto wrote: > > > > can you squash the following patch? > > No, please prune anything that we don't use from ecc.c. We do use the symbol in question, and I'm pretty sure we use all of crypto/ecc.c. I was going to send a patch where I remove the net/bluetooth/ecc.c How do you want me to proceed with this build failure? Do you want me to send a new patch so that you can revert 3c4b23901a0c766879dff680cd6bdab47bcdbbd2 ? Thanks, Salvatore > Thanks, > -- > Email: Herbert Xu > Home Page: http://gondor.apana.org.au/~herbert/ > PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt > -- > To unsubscribe from this list: send the line "unsubscribe linux-crypto" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [cryptodev:master 79/79] (.text+0x330de0): multiple definition of `ecdh_shared_secret'
On Fri, Jun 24, 2016 at 02:10:12PM +0800, Herbert Xu wrote: > On Fri, Jun 24, 2016 at 07:06:49AM +0100, Salvatore Benedetto wrote: > > > > can you squash the following patch? > > No, please prune anything that we don't use from ecc.c. I take that back. I see it's actually coming from bluetooth. How about moving ecc.c to lib so that it's shared between the two? Thanks, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [cryptodev:master 79/79] (.text+0x330de0): multiple definition of `ecdh_shared_secret'
On Fri, Jun 24, 2016 at 07:06:49AM +0100, Salvatore Benedetto wrote: > > can you squash the following patch? No, please prune anything that we don't use from ecc.c. Thanks, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v8 0/6] crypto: algif - add akcipher
Am Donnerstag, 23. Juni 2016, 15:55:26 schrieb Tadeusz Struk: Hi Tadeusz, > First four patches are a resend algif_akcipher from > Stephan Mueller, with minor changes after rebase on top of 4.7-rc1. The first four patches: Acked-by: Stephan Mueller Ciao Stephan -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [cryptodev:master 79/79] (.text+0x330de0): multiple definition of `ecdh_shared_secret'
On Fri, Jun 24, 2016 at 03:47:04AM +0800, kbuild test robot wrote: > tree: > https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git > master > head: 3c4b23901a0c766879dff680cd6bdab47bcdbbd2 > commit: 3c4b23901a0c766879dff680cd6bdab47bcdbbd2 [79/79] crypto: ecdh - Add > ECDH software support > config: i386-allyesconfig (attached as .config) > compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430 > reproduce: > git checkout 3c4b23901a0c766879dff680cd6bdab47bcdbbd2 > # save the attached .config to linux build tree > make ARCH=i386 > > All errors (new ones prefixed by >>): > >net/built-in.o: In function `ecdh_shared_secret': > >> (.text+0x330de0): multiple definition of `ecdh_shared_secret' >crypto/built-in.o:(.text+0xb1b0): first defined here > > --- > 0-DAY kernel test infrastructureOpen Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation Hi Herbert, can you squash the following patch? Thanks, Salvatore ---8<--- Rename ecdh_shared_secret Signed-off-by: Salvatore Benedetto --- crypto/ecc.c | 8 crypto/ecc.h | 12 ++-- crypto/ecdh.c | 8 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/crypto/ecc.c b/crypto/ecc.c index 9aedec6..1ba2436 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -966,10 +966,10 @@ out: return ret; } -int ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, - const u8 *private_key, unsigned int private_key_len, - const u8 *public_key, unsigned int public_key_len, - u8 *secret, unsigned int secret_len) +int ecdh_compute_ss(unsigned int curve_id, unsigned int ndigits, + const u8 *private_key, unsigned int private_key_len, + const u8 *public_key, unsigned int public_key_len, + u8 *secret, unsigned int secret_len) { int ret = 0; struct ecc_point *product, *pk; diff --git a/crypto/ecc.h b/crypto/ecc.h index b5db4b9..a856175 100644 --- a/crypto/ecc.h +++ b/crypto/ecc.h @@ -60,7 +60,7 @@ int ecdh_make_pub_key(const unsigned int curve_id, unsigned int ndigits, u8 *public_key, unsigned int public_key_len); /** - * ecdh_shared_secret() - Compute a shared secret + * ecdh_compute_ss() - Compute a shared secret * * @curve_id: id representing the curve to use * @private_key: private key of part A @@ -70,14 +70,14 @@ int ecdh_make_pub_key(const unsigned int curve_id, unsigned int ndigits, * @secret:buffer for storing the calculated shared secret * @secret_len:length of the secret buffer * - * Note: It is recommended that you hash the result of ecdh_shared_secret + * Note: It is recommended that you hash the result of ecdh_compute_ss * before using it for symmetric encryption or HMAC. * * Returns 0 if the shared secret was generated successfully, a negative value * if an error occurred. */ -int ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, - const u8 *private_key, unsigned int private_key_len, - const u8 *public_key, unsigned int public_key_len, - u8 *secret, unsigned int secret_len); +int ecdh_compute_ss(unsigned int curve_id, unsigned int ndigits, + const u8 *private_key, unsigned int private_key_len, + const u8 *public_key, unsigned int public_key_len, + u8 *secret, unsigned int secret_len); #endif diff --git a/crypto/ecdh.c b/crypto/ecdh.c index d3a9eec..7e12a34 100644 --- a/crypto/ecdh.c +++ b/crypto/ecdh.c @@ -79,10 +79,10 @@ static int ecdh_compute_value(struct kpp_request *req) if (copied != 2 * nbytes) return -EINVAL; - ret = ecdh_shared_secret(ctx->curve_id, ctx->ndigits, -(const u8 *)ctx->private_key, nbytes, -(const u8 *)ctx->public_key, 2 * nbytes, -(u8 *)ctx->shared_secret, nbytes); + ret = ecdh_compute_ss(ctx->curve_id, ctx->ndigits, + (const u8 *)ctx->private_key, nbytes, + (const u8 *)ctx->public_key, 2 * nbytes, + (u8 *)ctx->shared_secret, nbytes); buf = ctx->shared_secret; } else { -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/7] crypto: sha256-mb - Enable multibuffer support
Add the config CRYPTO_SHA256_MB which will enable the computation using the SHA256 multi-buffer algorithm. Signed-off-by: Megha Dey Reviewed-by: Fenghua Yu Reviewed-by: Tim Chen --- crypto/Kconfig | 16 1 file changed, 16 insertions(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index 5baaa9d..d8cc0f0 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -704,6 +704,22 @@ config CRYPTO_SHA1_MB lanes remain unfilled, a flush operation will be initiated to process the crypto jobs, adding a slight latency. +config CRYPTO_SHA256_MB + tristate "SHA256 digest algorithm (x86_64 Multi-Buffer, Experimental)" + depends on X86 && 64BIT + select CRYPTO_SHA256 + select CRYPTO_HASH + select CRYPTO_MCRYPTD + help + SHA-256 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented + using multi-buffer technique. This algorithm computes on + multiple data lanes concurrently with SIMD instructions for + better throughput. It should not be enabled by default but + used when there is significant amount of work to keep the keep + the data lanes filled to get performance benefit. If the data + lanes remain unfilled, a flush operation will be initiated to + process the crypto jobs, adding a slight latency. + config CRYPTO_SHA256 tristate "SHA224 and SHA256 digest algorithm" select CRYPTO_HASH -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/7] crypto: sha256-mb - SHA256 multibuffer job manager and glue code
This patch introduces the multi-buffer job manager which is responsible for submitting scatter-gather buffers from several SHA256 jobs to the multi-buffer algorithm. It also contains the flush routine to that's called by the crypto daemon to complete the job when no new jobs arrive before the deadline of maximum latency of a SHA256 crypto job. The SHA256 multi-buffer crypto algorithm is defined and initialized in this patch. Signed-off-by: Megha Dey Reviewed-by: Fenghua Yu Reviewed-by: Tim Chen --- arch/x86/crypto/Makefile |1 + arch/x86/crypto/sha256-mb/Makefile| 11 + arch/x86/crypto/sha256-mb/sha256_mb.c | 1027 + 3 files changed, 1039 insertions(+) create mode 100644 arch/x86/crypto/sha256-mb/Makefile create mode 100644 arch/x86/crypto/sha256-mb/sha256_mb.c diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index b9b912a..aafff22 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile @@ -50,6 +50,7 @@ ifeq ($(avx2_supported),yes) obj-$(CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64) += camellia-aesni-avx2.o obj-$(CONFIG_CRYPTO_SERPENT_AVX2_X86_64) += serpent-avx2.o obj-$(CONFIG_CRYPTO_SHA1_MB) += sha-mb/ + obj-$(CONFIG_CRYPTO_SHA256_MB) += sha256-mb/ endif aes-i586-y := aes-i586-asm_32.o aes_glue.o diff --git a/arch/x86/crypto/sha256-mb/Makefile b/arch/x86/crypto/sha256-mb/Makefile new file mode 100644 index 000..41089e7 --- /dev/null +++ b/arch/x86/crypto/sha256-mb/Makefile @@ -0,0 +1,11 @@ +# +# Arch-specific CryptoAPI modules. +# + +avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\ +$(comma)4)$(comma)%ymm2,yes,no) +ifeq ($(avx2_supported),yes) + obj-$(CONFIG_CRYPTO_SHA256_MB) += sha256-mb.o + sha256-mb-y := sha256_mb.o sha256_mb_mgr_flush_avx2.o \ +sha256_mb_mgr_init_avx2.o sha256_mb_mgr_submit_avx2.o sha256_x8_avx2.o +endif diff --git a/arch/x86/crypto/sha256-mb/sha256_mb.c b/arch/x86/crypto/sha256-mb/sha256_mb.c new file mode 100644 index 000..d1c1045 --- /dev/null +++ b/arch/x86/crypto/sha256-mb/sha256_mb.c @@ -0,0 +1,1027 @@ +/* + * Multi buffer SHA256 algorithm Glue Code + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2016 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Contact Information: + * Megha Dey + * + * BSD LICENSE + * + * Copyright(c) 2016 Intel Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + ** 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. + ** Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define pr_fmt(fmt)KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sha256_mb_ctx.h" + +#define FLUSH_INTERVAL 1000 /* in usec */ + +static struct mcryptd_alg_state sha256_mb_alg_state; + +struct sha256_mb_ctx { + struct mcryptd_ahash *mcrypt
[PATCH 4/7] crypto: sha256-mb - Algorithm data structures
This patch introduces the data structures and prototypes of functions needed for computing SHA256 hash using multi-buffer. Included are the structures of the multi-buffer SHA256 job, job scheduler in C and x86 assembly. Signed-off-by: Megha Dey Reviewed-by: Fenghua Yu Reviewed-by: Tim Chen --- arch/x86/crypto/sha256-mb/sha256_mb_ctx.h | 136 + arch/x86/crypto/sha256-mb/sha256_mb_mgr.h | 108 .../crypto/sha256-mb/sha256_mb_mgr_datastruct.S| 304 + 3 files changed, 548 insertions(+) create mode 100644 arch/x86/crypto/sha256-mb/sha256_mb_ctx.h create mode 100644 arch/x86/crypto/sha256-mb/sha256_mb_mgr.h create mode 100644 arch/x86/crypto/sha256-mb/sha256_mb_mgr_datastruct.S diff --git a/arch/x86/crypto/sha256-mb/sha256_mb_ctx.h b/arch/x86/crypto/sha256-mb/sha256_mb_ctx.h new file mode 100644 index 000..edd252b --- /dev/null +++ b/arch/x86/crypto/sha256-mb/sha256_mb_ctx.h @@ -0,0 +1,136 @@ +/* + * Header file for multi buffer SHA256 context + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2016 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Contact Information: + * Megha Dey + * + * BSD LICENSE + * + * Copyright(c) 2016 Intel Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + ** 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. + ** Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SHA_MB_CTX_INTERNAL_H +#define _SHA_MB_CTX_INTERNAL_H + +#include "sha256_mb_mgr.h" + +#define HASH_UPDATE 0x00 +#define HASH_FIRST 0x01 +#define HASH_LAST0x02 +#define HASH_ENTIRE 0x03 +#define HASH_DONE 0x04 +#define HASH_FINAL 0x08 + +#define HASH_CTX_STS_IDLE 0x00 +#define HASH_CTX_STS_PROCESSING 0x01 +#define HASH_CTX_STS_LAST 0x02 +#define HASH_CTX_STS_COMPLETE 0x04 + +enum hash_ctx_error { + HASH_CTX_ERROR_NONE = 0, + HASH_CTX_ERROR_INVALID_FLAGS = -1, + HASH_CTX_ERROR_ALREADY_PROCESSING = -2, + HASH_CTX_ERROR_ALREADY_COMPLETED = -3, + +#ifdef HASH_CTX_DEBUG + HASH_CTX_ERROR_DEBUG_DIGEST_MISMATCH = -4, +#endif +}; + + +#define hash_ctx_user_data(ctx) ((ctx)->user_data) +#define hash_ctx_digest(ctx) ((ctx)->job.result_digest) +#define hash_ctx_processing(ctx) ((ctx)->status & HASH_CTX_STS_PROCESSING) +#define hash_ctx_complete(ctx) ((ctx)->status == HASH_CTX_STS_COMPLETE) +#define hash_ctx_status(ctx) ((ctx)->status) +#define hash_ctx_error(ctx) ((ctx)->error) +#define hash_ctx_init(ctx) \ + do { \ + (ctx)->error = HASH_CTX_ERROR_NONE; \ + (ctx)->status = HASH_CTX_STS_COMPLETE; \ + } while (0) + + +/* Hash Constants and Typedefs */ +#define SHA256_DIGEST_LENGTH8 +#define SHA256_LOG2_BLOCK_SIZE6 + +#define SHA256_PADLENGTHFIELD_SIZE8 + +#ifdef SHA_MB_DEBUG +#define assert(expr) \ +do { \ + if (unlikely(!(expr))) { \ + printk(KERN_ERR "Assertion fa
[PATCH 7/7] crypto: sha1-mb - rename sha-mb to sha1-mb
From: Megha Dey Until now, there was only support for the SHA1 multibuffer algorithm. Hence, there was just one sha-mb folder. Now, with the introduction of the SHA256 multi-buffer algorithm , it is logical to name the existing folder as sha1-mb. Signed-off-by: Megha Dey Reviewed-by: Fenghua Yu Reviewed-by: Tim Chen --- arch/x86/crypto/Makefile | 2 +- arch/x86/crypto/{sha-mb => sha1-mb}/Makefile | 0 arch/x86/crypto/{sha-mb => sha1-mb}/sha1_mb.c | 2 +- arch/x86/crypto/{sha-mb/sha_mb_ctx.h => sha1-mb/sha1_mb_ctx.h} | 2 +- arch/x86/crypto/{sha-mb/sha_mb_mgr.h => sha1-mb/sha1_mb_mgr.h} | 0 arch/x86/crypto/{sha-mb => sha1-mb}/sha1_mb_mgr_datastruct.S | 0 arch/x86/crypto/{sha-mb => sha1-mb}/sha1_mb_mgr_flush_avx2.S | 0 arch/x86/crypto/{sha-mb => sha1-mb}/sha1_mb_mgr_init_avx2.c| 2 +- arch/x86/crypto/{sha-mb => sha1-mb}/sha1_mb_mgr_submit_avx2.S | 0 arch/x86/crypto/{sha-mb => sha1-mb}/sha1_x8_avx2.S | 0 10 files changed, 4 insertions(+), 4 deletions(-) rename arch/x86/crypto/{sha-mb => sha1-mb}/Makefile (100%) rename arch/x86/crypto/{sha-mb => sha1-mb}/sha1_mb.c (99%) rename arch/x86/crypto/{sha-mb/sha_mb_ctx.h => sha1-mb/sha1_mb_ctx.h} (99%) rename arch/x86/crypto/{sha-mb/sha_mb_mgr.h => sha1-mb/sha1_mb_mgr.h} (100%) rename arch/x86/crypto/{sha-mb => sha1-mb}/sha1_mb_mgr_datastruct.S (100%) rename arch/x86/crypto/{sha-mb => sha1-mb}/sha1_mb_mgr_flush_avx2.S (100%) rename arch/x86/crypto/{sha-mb => sha1-mb}/sha1_mb_mgr_init_avx2.c (99%) rename arch/x86/crypto/{sha-mb => sha1-mb}/sha1_mb_mgr_submit_avx2.S (100%) rename arch/x86/crypto/{sha-mb => sha1-mb}/sha1_x8_avx2.S (100%) diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index aafff22..52c8685 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile @@ -49,7 +49,7 @@ endif ifeq ($(avx2_supported),yes) obj-$(CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64) += camellia-aesni-avx2.o obj-$(CONFIG_CRYPTO_SERPENT_AVX2_X86_64) += serpent-avx2.o - obj-$(CONFIG_CRYPTO_SHA1_MB) += sha-mb/ + obj-$(CONFIG_CRYPTO_SHA1_MB) += sha1-mb/ obj-$(CONFIG_CRYPTO_SHA256_MB) += sha256-mb/ endif diff --git a/arch/x86/crypto/sha-mb/Makefile b/arch/x86/crypto/sha1-mb/Makefile similarity index 100% rename from arch/x86/crypto/sha-mb/Makefile rename to arch/x86/crypto/sha1-mb/Makefile diff --git a/arch/x86/crypto/sha-mb/sha1_mb.c b/arch/x86/crypto/sha1-mb/sha1_mb.c similarity index 99% rename from arch/x86/crypto/sha-mb/sha1_mb.c rename to arch/x86/crypto/sha1-mb/sha1_mb.c index 669cc37..561b286 100644 --- a/arch/x86/crypto/sha-mb/sha1_mb.c +++ b/arch/x86/crypto/sha1-mb/sha1_mb.c @@ -67,7 +67,7 @@ #include #include #include -#include "sha_mb_ctx.h" +#include "sha1_mb_ctx.h" #define FLUSH_INTERVAL 1000 /* in usec */ diff --git a/arch/x86/crypto/sha-mb/sha_mb_ctx.h b/arch/x86/crypto/sha1-mb/sha1_mb_ctx.h similarity index 99% rename from arch/x86/crypto/sha-mb/sha_mb_ctx.h rename to arch/x86/crypto/sha1-mb/sha1_mb_ctx.h index e36069d..98a35bc 100644 --- a/arch/x86/crypto/sha-mb/sha_mb_ctx.h +++ b/arch/x86/crypto/sha1-mb/sha1_mb_ctx.h @@ -54,7 +54,7 @@ #ifndef _SHA_MB_CTX_INTERNAL_H #define _SHA_MB_CTX_INTERNAL_H -#include "sha_mb_mgr.h" +#include "sha1_mb_mgr.h" #define HASH_UPDATE 0x00 #define HASH_FIRST 0x01 diff --git a/arch/x86/crypto/sha-mb/sha_mb_mgr.h b/arch/x86/crypto/sha1-mb/sha1_mb_mgr.h similarity index 100% rename from arch/x86/crypto/sha-mb/sha_mb_mgr.h rename to arch/x86/crypto/sha1-mb/sha1_mb_mgr.h diff --git a/arch/x86/crypto/sha-mb/sha1_mb_mgr_datastruct.S b/arch/x86/crypto/sha1-mb/sha1_mb_mgr_datastruct.S similarity index 100% rename from arch/x86/crypto/sha-mb/sha1_mb_mgr_datastruct.S rename to arch/x86/crypto/sha1-mb/sha1_mb_mgr_datastruct.S diff --git a/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S b/arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.S similarity index 100% rename from arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S rename to arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.S diff --git a/arch/x86/crypto/sha-mb/sha1_mb_mgr_init_avx2.c b/arch/x86/crypto/sha1-mb/sha1_mb_mgr_init_avx2.c similarity index 99% rename from arch/x86/crypto/sha-mb/sha1_mb_mgr_init_avx2.c rename to arch/x86/crypto/sha1-mb/sha1_mb_mgr_init_avx2.c index 822acb5..d2add0d 100644 --- a/arch/x86/crypto/sha-mb/sha1_mb_mgr_init_avx2.c +++ b/arch/x86/crypto/sha1-mb/sha1_mb_mgr_init_avx2.c @@ -51,7 +51,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "sha_mb_mgr.h" +#include "sha1_mb_mgr.h" void sha1_mb_mgr_init_avx2(struct sha1_mb_mgr *state) { diff --git a/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S b/arch/x86/crypto/sha1-mb/sha1_mb_mgr_submit_avx2.S similarity index 100% rename from arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S rename to arch/x86/crypto/sha1-mb/sha1_mb_mgr_submit_avx2.S diff --git a/arch/x86/cryp
[PATCH 6/7] crypto: tcrypt - Add speed tests for SHA multibuffer algorithms
From: Megha Dey The existing test suite to calculate the speed of the SHA algorithms assumes serial (single buffer)) computation of data. With the SHA multibuffer algorithms, we work on 8 lanes of data in parallel. Hence, the need to introduce a new test suite to calculate the speed for these algorithms. Signed-off-by: Megha Dey --- crypto/tcrypt.c | 118 1 file changed, 118 insertions(+) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 4675459..6ef7815 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -578,6 +578,117 @@ static inline int do_one_ahash_op(struct ahash_request *req, int ret) return ret; } +char ptext[4096]; +struct scatterlist sg[8][8]; +char result[8][64]; +struct ahash_request *req[8]; +struct tcrypt_result tresult[8]; +char *xbuf[8][XBUFSIZE]; +cycles_t start[8], end[8], mid; + +static void test_mb_ahash_speed(const char *algo, unsigned int sec, + struct hash_speed *speed) +{ + unsigned int i, j, k; + void *hash_buff; + int ret = -ENOMEM; + struct crypto_ahash *tfm; + + tfm = crypto_alloc_ahash(algo, 0, 0); + if (IS_ERR(tfm)) { + pr_err("failed to load transform for %s: %ld\n", + algo, PTR_ERR(tfm)); + return; + } + for (i = 0; i < 8; ++i) { + if (testmgr_alloc_buf(xbuf[i])) + goto out_nobuf; + + init_completion(&tresult[i].completion); + + req[i] = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req[i]) { + printk(KERN_ERR "alg: hash: Failed to allocate " + "request for %s\n", algo); + goto out_noreq; + } + ahash_request_set_callback(req[i], CRYPTO_TFM_REQ_MAY_BACKLOG, + tcrypt_complete, &tresult[i]); + + hash_buff = xbuf[i][0]; + memcpy(hash_buff, ptext, 4096); + } + + j = 0; + + printk(KERN_INFO "\ntesting speed of %s (%s)\n", algo, + get_driver_name(crypto_ahash, tfm)); + + for (i = 0; speed[i].blen != 0; i++) { + if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) { + printk(KERN_ERR + "template (%u) too big for tvmem (%lu)\n", + speed[i].blen, TVMEMSIZE * PAGE_SIZE); + goto out; + } + + if (speed[i].klen) + crypto_ahash_setkey(tfm, tvmem[0], speed[i].klen); + + for (k = 0; k < 8; ++k) { + sg_init_one(&sg[k][0], (void *) xbuf[k][0], + speed[i].blen); + ahash_request_set_crypt(req[k], sg[k], + result[k], speed[i].blen); + } + + printk(KERN_INFO "test%3u " + "(%5u byte blocks,%5u bytes per update,%4u updates): ", + i, speed[i].blen, speed[i].plen, + speed[i].blen / speed[i].plen); + + for (k = 0; k < 8; ++k) { + start[k] = get_cycles(); + ret = crypto_ahash_digest(req[k]); + if (ret == -EBUSY || ret == -EINPROGRESS) + continue; + if (ret) { + printk(KERN_ERR + "alg (%s) something wrong, ret = %d ...\n", + algo, ret); + goto out; + } + } + mid = get_cycles(); + + for (k = 0; k < 8; ++k) { + struct tcrypt_result *tr = &tresult[k]; + + ret = wait_for_completion_interruptible + (&tr->completion); + if (ret) + printk(KERN_ERR + "alg(%s): hash: digest failed\n", algo); + end[k] = get_cycles(); + } + + printk("\nBlock: %lld cycles (%lld cycles/byte), %d bytes\n", + (s64) (end[7]-start[0])/1, + (s64) (end[7]-start[0])/(8*speed[i].blen), + 8*speed[i].blen); + } + ret = 0; + +out: + for (k = 0; k < 8; ++k) + ahash_request_free(req[k]); +out_noreq: + for (k = 0; k < 8; ++k) + testmgr_free_buf(xbuf[k]); +out_nobuf: + return; +} + static int test_ahash_jiffies_digest(struct ahash_request *req, int blen, char *out, int secs) { @@ -1820,6 +1931,13 @@ static int do_test(const char *alg, u3
[PATCH 3/7] crypto: sha256-mb - submit/flush routines for AVX2
This patch introduces the routines used to submit and flush buffers belonging to SHA256 crypto jobs to the SHA256 multibuffer algorithm. It is implemented mostly in assembly optimized with AVX2 instructions. Signed-off-by: Megha Dey Reviewed-by: Fenghua Yu Reviewed-by: Tim Chen --- .../crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S| 304 + .../x86/crypto/sha256-mb/sha256_mb_mgr_init_avx2.c | 65 + .../crypto/sha256-mb/sha256_mb_mgr_submit_avx2.S | 215 +++ 3 files changed, 584 insertions(+) create mode 100644 arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S create mode 100644 arch/x86/crypto/sha256-mb/sha256_mb_mgr_init_avx2.c create mode 100644 arch/x86/crypto/sha256-mb/sha256_mb_mgr_submit_avx2.S diff --git a/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S b/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S new file mode 100644 index 000..b691da9 --- /dev/null +++ b/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S @@ -0,0 +1,304 @@ +/* + * Flush routine for SHA256 multibuffer + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2016 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Contact Information: + * Megha Dey + * + * BSD LICENSE + * + * Copyright(c) 2016 Intel Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + ** 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. + ** Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "sha256_mb_mgr_datastruct.S" + +.extern sha256_x8_avx2 + +#LINUX register definitions +#define arg1 %rdi +#define arg2 %rsi + +# Common register definitions +#define state arg1 +#define jobarg2 +#define len2 arg2 + +# idx must be a register not clobberred by sha1_mult +#define idx%r8 +#define DWORD_idx %r8d + +#define unused_lanes %rbx +#define lane_data %rbx +#define tmp2 %rbx +#define tmp2_w %ebx + +#define job_rax%rax +#define tmp1 %rax +#define size_offset%rax +#define tmp%rax +#define start_offset %rax + +#define tmp3 %arg1 + +#define extra_blocks %arg2 +#define p %arg2 + +.macro LABEL prefix n +\prefix\n\(): +.endm + +.macro JNE_SKIP i +jne skip_\i +.endm + +.altmacro +.macro SET_OFFSET _offset +offset = \_offset +.endm +.noaltmacro + +# JOB_SHA256* sha256_mb_mgr_flush_avx2(MB_MGR *state) +# arg 1 : rcx : state +ENTRY(sha256_mb_mgr_flush_avx2) + FRAME_BEGIN +push%rbx + + # If bit (32+3) is set, then all lanes are empty + mov _unused_lanes(state), unused_lanes + bt $32+3, unused_lanes + jc return_null + + # find a lane with a non-null job + xor idx, idx + offset = (_ldata + 1 * _LANE_DATA_size + _job_in_lane) + cmpq$0, offset(state) + cmovne one(%rip), idx + offset = (_ldata + 2 * _LANE_DATA_size + _job_in_lane) + cmpq$0, offset(state) + cmovne two(%rip), idx +
[PATCH 5/7] crypto: sha256-mb - Crypto computation (x8 AVX2)
This patch introduces the assembly routines to do SHA256 computation on buffers belonging to several jobs at once. The assembly routines are optimized with AVX2 instructions that have 8 data lanes and using AVX2 registers. Signed-off-by: Megha Dey Reviewed-by: Fenghua Yu Reviewed-by: Tim Chen --- arch/x86/crypto/sha256-mb/sha256_x8_avx2.S | 593 + 1 file changed, 593 insertions(+) create mode 100644 arch/x86/crypto/sha256-mb/sha256_x8_avx2.S diff --git a/arch/x86/crypto/sha256-mb/sha256_x8_avx2.S b/arch/x86/crypto/sha256-mb/sha256_x8_avx2.S new file mode 100644 index 000..aa21aea --- /dev/null +++ b/arch/x86/crypto/sha256-mb/sha256_x8_avx2.S @@ -0,0 +1,593 @@ +/* + * Multi-buffer SHA256 algorithm hash compute routine + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2016 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Contact Information: + * Megha Dey + * + * BSD LICENSE + * + * Copyright(c) 2016 Intel Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + ** 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. + ** Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS 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 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "sha256_mb_mgr_datastruct.S" + +## code to compute oct SHA256 using SSE-256 +## outer calling routine takes care of save and restore of XMM registers +## Logic designed/laid out by JDG + +## Function clobbers: rax, rcx, rdx, rbx, rsi, rdi, r9-r15; %ymm0-15 +## Linux clobbers:rax rbx rcx rdx rsir9 r10 r11 r12 r13 r14 r15 +## Linux preserves: rdi rbp r8 +## +## clobbers %ymm0-15 + +arg1 = %rdi +arg2 = %rsi +reg3 = %rcx +reg4 = %rdx + +# Common definitions +STATE = arg1 +INP_SIZE = arg2 + +IDX = %rax +ROUND = %rbx +TBL = reg3 + +inp0 = %r9 +inp1 = %r10 +inp2 = %r11 +inp3 = %r12 +inp4 = %r13 +inp5 = %r14 +inp6 = %r15 +inp7 = reg4 + +a = %ymm0 +b = %ymm1 +c = %ymm2 +d = %ymm3 +e = %ymm4 +f = %ymm5 +g = %ymm6 +h = %ymm7 + +T1 = %ymm8 + +a0 = %ymm12 +a1 = %ymm13 +a2 = %ymm14 +TMP = %ymm15 +TMP0 = %ymm6 +TMP1 = %ymm7 + +TT0 = %ymm8 +TT1 = %ymm9 +TT2 = %ymm10 +TT3 = %ymm11 +TT4 = %ymm12 +TT5 = %ymm13 +TT6 = %ymm14 +TT7 = %ymm15 + +# Define stack usage + +# Assume stack aligned to 32 bytes before call +# Therefore FRAMESZ mod 32 must be 32-8 = 24 + +#define FRAMESZ0x388 + +#define VMOVPS vmovups + +# TRANSPOSE8 r0, r1, r2, r3, r4, r5, r6, r7, t0, t1 +# "transpose" data in {r0...r7} using temps {t0...t1} +# Input looks like: {r0 r1 r2 r3 r4 r5 r6 r7} +# r0 = {a7 a6 a5 a4 a3 a2 a1 a0} +# r1 = {b7 b6 b5 b4 b3 b2 b1 b0} +# r2 = {c7 c6 c5 c4 c3 c2 c1 c0} +# r3 = {d7 d6 d5 d4 d3 d2 d1 d0} +# r4 = {e7 e6 e5 e4 e3 e2 e1 e0} +# r5 = {f7 f6 f5 f4 f3 f2 f1 f0} +# r6 = {g7 g6 g5 g4 g3 g2 g1 g0} +# r7 = {h7 h6 h5 h4 h3 h2 h1 h0} +# +# Output looks like: {r0 r1 r2 r3 r4 r5 r6 r7} +# r0 = {h0 g0 f0 e0 d0 c0 b0 a0} +# r1 = {h1 g1 f1 e1 d1 c1 b1 a1} +# r2 = {h2 g2 f2 e2 d2 c2 b2 a2} +# r3 = {h3 g3 f3 e3 d3 c3 b3 a3} +# r4 = {h4 g4 f4 e4 d4 c4 b4 a4} +# r5 = {h5
[PATCH 0/7] crypto: SHA256 multibuffer implementation
From: Megha Dey In this patch series, we introduce the multi-buffer crypto algorithm on x86_64 and apply it to SHA256 hash computation. The multi-buffer technique takes advantage of the 8 data lanes in the AVX2 registers and allows computation to be performed on data from multiple jobs in parallel. This allows us to parallelize computations when data inter-dependency in a single crypto job prevents us to fully parallelize our computations. The algorithm can be extended to other hashing and encryption schemes in the future. On multi-buffer SHA256 computation with AVX2, we see throughput increase up to 2.2x over the existing x86_64 single buffer AVX2 algorithm. The multi-buffer crypto algorithm is described in the following paper: Processing Multiple Buffers in Parallel to Increase Performance on Intel® Architecture Processors http://www.intel.com/content/www/us/en/communications/communications-ia-multi-buffer-paper.html The outline of the algorithm is sketched below: Any driver requesting the crypto service will place an async crypto request on the workqueue. The multi-buffer crypto daemon will pull request from work queue and put each request in an empty data lane for multi-buffer crypto computation. When all the empty lanes are filled, computation will commence on the jobs in parallel and the job with the shortest remaining buffer will get completed and be returned. To prevent prolonged stall when there is no new jobs arriving, we will flush a crypto job if it has not been completed after a maximum allowable delay. To accommodate the fragmented nature of scatter-gather, we will keep submitting the next scatter-buffer fragment for a job for multi-buffer computation until a job is completed and no more buffer fragments remain. At that time we will pull a new job to fill the now empty data slot. We call a get_completed_job function to check whether there are other jobs that have been completed when we job when we have no new job arrival to prevent extraneous delay in returning any completed jobs. The multi-buffer algorithm should be used for cases where crypto jobs submissions are at a reasonable high rate. For low crypto job submission rate, this algorithm will not be beneficial. The reason is at low rate, we do not fill out the data lanes before the maximum allowable latency, we will be flushing the jobs instead of processing them with all the data lanes full. We will miss the benefit of parallel computation, and adding delay to the processing of the crypto job at the same time. Some tuning of the maximum latency parameter may be needed to get the best performance. Note that the tcrypt SHA256 speed test, we wait for a previous job to be completed before submitting a new job. Hence this is not a valid test for multi-buffer algorithm as it requires multiple outstanding jobs submitted to fill the all data lanes to be effective (i.e. 8 outstanding jobs for the AVX2 case). An updated version of the tcrypt test is also included which would contain a more appropriate test for this scenario. As this is the first algorithm in the kernel's crypto library that we have tried to use multi-buffer optimizations, feedbacks and testings will be much appreciated. Megha Dey (7): crypto: sha256-mb - SHA256 multibuffer job manager and glue code crypto: sha256-mb - Enable multibuffer support crypto: sha256-mb - submit/flush routines for AVX2 crypto: sha256-mb - Algorithm data structures crypto: sha256-mb - Crypto computation (x8 AVX2) crypto: tcrypt - Add speed tests for SHA multibuffer algorithms crypto: sha1-mb - rename sha-mb to sha1-mb arch/x86/crypto/Makefile |3 +- arch/x86/crypto/{sha-mb => sha1-mb}/Makefile |0 arch/x86/crypto/{sha-mb => sha1-mb}/sha1_mb.c |2 +- .../{sha-mb/sha_mb_ctx.h => sha1-mb/sha1_mb_ctx.h} |2 +- .../{sha-mb/sha_mb_mgr.h => sha1-mb/sha1_mb_mgr.h} |0 .../{sha-mb => sha1-mb}/sha1_mb_mgr_datastruct.S |0 .../{sha-mb => sha1-mb}/sha1_mb_mgr_flush_avx2.S |0 .../{sha-mb => sha1-mb}/sha1_mb_mgr_init_avx2.c|2 +- .../{sha-mb => sha1-mb}/sha1_mb_mgr_submit_avx2.S |0 arch/x86/crypto/{sha-mb => sha1-mb}/sha1_x8_avx2.S |0 arch/x86/crypto/sha256-mb/Makefile | 11 + arch/x86/crypto/sha256-mb/sha256_mb.c | 1027 arch/x86/crypto/sha256-mb/sha256_mb_ctx.h | 136 +++ arch/x86/crypto/sha256-mb/sha256_mb_mgr.h | 108 ++ .../crypto/sha256-mb/sha256_mb_mgr_datastruct.S| 304 ++ .../crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S| 304 ++ .../x86/crypto/sha256-mb/sha256_mb_mgr_init_avx2.c | 65 ++ .../crypto/sha256-mb/sha256_mb_mgr_submit_avx2.S | 215 arch/x86/crypto/sha256-mb/sha256_x8_avx2.S | 593 +++ crypto/Kconfig | 16 + crypto/tcrypt.c| 118 +++ 21 files changed, 2902 insertions(+), 4 deletions(-) rename
Re: [PATCH v8 6/6] crypto: AF_ALG - add support for key_id
Hi, [auto build test ERROR on cryptodev/master] [also build test ERROR on v4.7-rc4 next-20160623] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Tadeusz-Struk/crypto-algif-add-akcipher/20160624-065803 base: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master config: x86_64-allmodconfig (attached as .config) compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All error/warnings (new ones prefixed by >>): crypto/algif_akcipher.c: In function 'asym_key_encrypt': >> crypto/algif_akcipher.c:326:9: error: variable 'params' has initializer but >> incomplete type struct kernel_pkey_params params = {0}; ^~ >> crypto/algif_akcipher.c:326:38: warning: excess elements in struct >> initializer struct kernel_pkey_params params = {0}; ^ crypto/algif_akcipher.c:326:38: note: (near initialization for 'params') >> crypto/algif_akcipher.c:326:28: error: storage size of 'params' isn't known struct kernel_pkey_params params = {0}; ^~ >> crypto/algif_akcipher.c:352:8: error: implicit declaration of function >> 'encrypt_blob' [-Werror=implicit-function-declaration] ret = encrypt_blob(¶ms, in, out); ^~~~ >> crypto/algif_akcipher.c:326:28: warning: unused variable 'params' >> [-Wunused-variable] struct kernel_pkey_params params = {0}; ^~ crypto/algif_akcipher.c: In function 'asym_key_decrypt': crypto/algif_akcipher.c:366:9: error: variable 'params' has initializer but incomplete type struct kernel_pkey_params params = {0}; ^~ crypto/algif_akcipher.c:366:38: warning: excess elements in struct initializer struct kernel_pkey_params params = {0}; ^ crypto/algif_akcipher.c:366:38: note: (near initialization for 'params') crypto/algif_akcipher.c:366:28: error: storage size of 'params' isn't known struct kernel_pkey_params params = {0}; ^~ >> crypto/algif_akcipher.c:392:8: error: implicit declaration of function >> 'decrypt_blob' [-Werror=implicit-function-declaration] ret = decrypt_blob(¶ms, in, out); ^~~~ crypto/algif_akcipher.c:366:28: warning: unused variable 'params' [-Wunused-variable] struct kernel_pkey_params params = {0}; ^~ crypto/algif_akcipher.c: In function 'asym_key_sign': crypto/algif_akcipher.c:406:9: error: variable 'params' has initializer but incomplete type struct kernel_pkey_params params = {0}; ^~ crypto/algif_akcipher.c:406:38: warning: excess elements in struct initializer struct kernel_pkey_params params = {0}; ^ crypto/algif_akcipher.c:406:38: note: (near initialization for 'params') crypto/algif_akcipher.c:406:28: error: storage size of 'params' isn't known struct kernel_pkey_params params = {0}; ^~ >> crypto/algif_akcipher.c:432:8: error: implicit declaration of function >> 'create_signature' [-Werror=implicit-function-declaration] ret = create_signature(¶ms, in, out); ^~~~ crypto/algif_akcipher.c:406:28: warning: unused variable 'params' [-Wunused-variable] struct kernel_pkey_params params = {0}; ^~ crypto/algif_akcipher.c: In function 'asym_key_verify': >> crypto/algif_akcipher.c:460:5: error: 'struct public_key_signature' has no >> member named 'encoding' sig.encoding = "pkcs1"; ^ cc1: some warnings being treated as errors vim +/params +326 crypto/algif_akcipher.c 320 321 return err ? err : size; 322 } 323 324 static int asym_key_encrypt(const struct key *key, struct akcipher_request *req) 325 { > 326 struct kernel_pkey_params params = {0}; 327 char *src = NULL, *dst = NULL, *in, *out; 328 int ret; 329 330 if (!sg_is_last(req->src)) { 331 src = kmalloc(req->src_len, GFP_KERNEL); 332 if (!src) 333 return -ENOMEM; 334 scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0); 335 in = src; 336 } else { 337
Re: [PATCH] crypto: user - re-add size check for CRYPTO_MSG_GETALG
On Thu, Jun 23, 2016 at 04:46:26PM +0200, Stephan Mueller wrote: > > Please revert my patch eed1e1afd8d542d9644534c1b712599b5d680007 as requested > by Matthias. It's already done. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 5/6] crypto: algif_akcipher - add ops_nokey
Similar to algif_skcipher and algif_hash, algif_akcipher needs to prevent user space from using the interface in an improper way. This patch adds nokey ops handlers, which do just that. Signed-off-by: Tadeusz Struk --- crypto/algif_akcipher.c | 159 +-- 1 file changed, 152 insertions(+), 7 deletions(-) diff --git a/crypto/algif_akcipher.c b/crypto/algif_akcipher.c index 8dd6354..2b8d37e 100644 --- a/crypto/algif_akcipher.c +++ b/crypto/algif_akcipher.c @@ -27,6 +27,11 @@ struct akcipher_sg_list { struct scatterlist sg[ALG_MAX_PAGES]; }; +struct akcipher_tfm { + struct crypto_akcipher *akcipher; + bool has_key; +}; + struct akcipher_ctx { struct akcipher_sg_list tsgl; struct af_alg_sgl rsgl[ALG_MAX_PAGES]; @@ -439,25 +444,151 @@ static struct proto_ops algif_akcipher_ops = { .poll = akcipher_poll, }; +static int akcipher_check_key(struct socket *sock) +{ + int err = 0; + struct sock *psk; + struct alg_sock *pask; + struct akcipher_tfm *tfm; + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + + lock_sock(sk); + if (ask->refcnt) + goto unlock_child; + + psk = ask->parent; + pask = alg_sk(ask->parent); + tfm = pask->private; + + err = -ENOKEY; + lock_sock_nested(psk, SINGLE_DEPTH_NESTING); + if (!tfm->has_key) + goto unlock; + + if (!pask->refcnt++) + sock_hold(psk); + + ask->refcnt = 1; + sock_put(psk); + + err = 0; + +unlock: + release_sock(psk); +unlock_child: + release_sock(sk); + + return err; +} + +static int akcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg, + size_t size) +{ + int err; + + err = akcipher_check_key(sock); + if (err) + return err; + + return akcipher_sendmsg(sock, msg, size); +} + +static ssize_t akcipher_sendpage_nokey(struct socket *sock, struct page *page, + int offset, size_t size, int flags) +{ + int err; + + err = akcipher_check_key(sock); + if (err) + return err; + + return akcipher_sendpage(sock, page, offset, size, flags); +} + +static int akcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg, + size_t ignored, int flags) +{ + int err; + + err = akcipher_check_key(sock); + if (err) + return err; + + return akcipher_recvmsg(sock, msg, ignored, flags); +} + +static struct proto_ops algif_akcipher_ops_nokey = { + .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, + + .release= af_alg_release, + .sendmsg= akcipher_sendmsg_nokey, + .sendpage = akcipher_sendpage_nokey, + .recvmsg= akcipher_recvmsg_nokey, + .poll = akcipher_poll, +}; + static void *akcipher_bind(const char *name, u32 type, u32 mask) { - return crypto_alloc_akcipher(name, type, mask); + struct akcipher_tfm *tfm; + struct crypto_akcipher *akcipher; + + tfm = kzalloc(sizeof(*tfm), GFP_KERNEL); + if (!tfm) + return ERR_PTR(-ENOMEM); + + akcipher = crypto_alloc_akcipher(name, type, mask); + if (IS_ERR(akcipher)) { + kfree(tfm); + return ERR_CAST(akcipher); + } + + tfm->akcipher = akcipher; + return tfm; } static void akcipher_release(void *private) { - crypto_free_akcipher(private); + struct akcipher_tfm *tfm = private; + struct crypto_akcipher *akcipher = tfm->akcipher; + + crypto_free_akcipher(akcipher); + kfree(tfm); } static int akcipher_setprivkey(void *private, const u8 *key, unsigned int keylen) { - return crypto_akcipher_set_priv_key(private, key, keylen); + struct akcipher_tfm *tfm = private; + struct crypto_akcipher *akcipher = tfm->akcipher; + int err; + + err = crypto_akcipher_set_priv_key(akcipher, key, keylen); + tfm->has_key = !err; + return err; } static int akcipher_setpubkey(void *private, const u8 *key, unsigned int keylen) { - return crypto_akcipher_set_pub_key(private, key, keylen); + struct akcipher_tfm *tfm = private; + s
[PATCH v8 3/6] crypto: AF_ALG -- add asymmetric cipher interface
From: Stephan Mueller This patch adds the user space interface for asymmetric ciphers. The interface allows the use of sendmsg as well as vmsplice to provide data. This version has been rebased on top of 4.7 and a few chackpatch issues have been fixed. This version also removes the constrain on the output buffer size. Signed-off-by: Stephan Mueller Signed-off-by: Tadeusz Struk --- crypto/algif_akcipher.c | 531 +++ 1 file changed, 531 insertions(+) create mode 100644 crypto/algif_akcipher.c diff --git a/crypto/algif_akcipher.c b/crypto/algif_akcipher.c new file mode 100644 index 000..8dd6354 --- /dev/null +++ b/crypto/algif_akcipher.c @@ -0,0 +1,531 @@ +/* + * algif_akcipher: User-space interface for asymmetric cipher algorithms + * + * Copyright (C) 2015, Stephan Mueller + * + * This file provides the user-space API for asymmetric ciphers. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct akcipher_sg_list { + unsigned int cur; + struct scatterlist sg[ALG_MAX_PAGES]; +}; + +struct akcipher_ctx { + struct akcipher_sg_list tsgl; + struct af_alg_sgl rsgl[ALG_MAX_PAGES]; + + struct af_alg_completion completion; + + unsigned long used; + + unsigned int len; + bool more; + bool merge; + int op; + + struct akcipher_request req; +}; + +static inline int akcipher_sndbuf(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct akcipher_ctx *ctx = ask->private; + + return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) - + ctx->used, 0); +} + +static inline bool akcipher_writable(struct sock *sk) +{ + return akcipher_sndbuf(sk) >= PAGE_SIZE; +} + +static void akcipher_put_sgl(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct akcipher_ctx *ctx = ask->private; + struct akcipher_sg_list *sgl = &ctx->tsgl; + struct scatterlist *sg = sgl->sg; + unsigned int i; + + for (i = 0; i < sgl->cur; i++) { + if (!sg_page(sg + i)) + continue; + + put_page(sg_page(sg + i)); + sg_assign_page(sg + i, NULL); + } + sg_init_table(sg, ALG_MAX_PAGES); + sgl->cur = 0; + ctx->used = 0; + ctx->more = 0; + ctx->merge = 0; +} + +static void akcipher_wmem_wakeup(struct sock *sk) +{ + struct socket_wq *wq; + + if (!akcipher_writable(sk)) + return; + + rcu_read_lock(); + wq = rcu_dereference(sk->sk_wq); + if (wq_has_sleeper(&wq->wait)) + wake_up_interruptible_sync_poll(&wq->wait, POLLIN | + POLLRDNORM | + POLLRDBAND); + sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); + rcu_read_unlock(); +} + +static int akcipher_wait_for_data(struct sock *sk, unsigned int flags) +{ + struct alg_sock *ask = alg_sk(sk); + struct akcipher_ctx *ctx = ask->private; + long timeout; + DEFINE_WAIT(wait); + int err = -ERESTARTSYS; + + if (flags & MSG_DONTWAIT) + return -EAGAIN; + + set_bit(SOCKWQ_ASYNC_WAITDATA, &sk->sk_socket->flags); + + for (;;) { + if (signal_pending(current)) + break; + prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); + timeout = MAX_SCHEDULE_TIMEOUT; + if (sk_wait_event(sk, &timeout, !ctx->more)) { + err = 0; + break; + } + } + finish_wait(sk_sleep(sk), &wait); + + clear_bit(SOCKWQ_ASYNC_WAITDATA, &sk->sk_socket->flags); + + return err; +} + +static void akcipher_data_wakeup(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct akcipher_ctx *ctx = ask->private; + struct socket_wq *wq; + + if (ctx->more) + return; + if (!ctx->used) + return; + + rcu_read_lock(); + wq = rcu_dereference(sk->sk_wq); + if (wq_has_sleeper(&wq->wait)) + wake_up_interruptible_sync_poll(&wq->wait, POLLOUT | + POLLRDNORM | + POLLRDBAND); + sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); + rcu_read_unlock(); +} + +static int akcipher_sendmsg(struct socket *sock, struct msghdr *msg, + size_t size) +{ + struct sock *sk = sock->sk; + struct alg_soc
[PATCH v8 2/6] crypto: AF_ALG -- add setpubkey setsockopt call
From: Stephan Mueller For supporting asymmetric ciphers, user space must be able to set the public key. The patch adds a new setsockopt call for setting the public key. Signed-off-by: Stephan Mueller Signed-off-by: Tadeusz Struk --- crypto/af_alg.c | 18 +- include/crypto/if_alg.h |1 + 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index f5e18c2..24dc082 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -202,13 +202,17 @@ unlock: } static int alg_setkey(struct sock *sk, char __user *ukey, - unsigned int keylen) + unsigned int keylen, + int (*setkey)(void *private, const u8 *key, + unsigned int keylen)) { struct alg_sock *ask = alg_sk(sk); - const struct af_alg_type *type = ask->type; u8 *key; int err; + if (!setkey) + return -ENOPROTOOPT; + key = sock_kmalloc(sk, keylen, GFP_KERNEL); if (!key) return -ENOMEM; @@ -217,7 +221,7 @@ static int alg_setkey(struct sock *sk, char __user *ukey, if (copy_from_user(key, ukey, keylen)) goto out; - err = type->setkey(ask->private, key, keylen); + err = setkey(ask->private, key, keylen); out: sock_kzfree_s(sk, key, keylen); @@ -247,10 +251,14 @@ static int alg_setsockopt(struct socket *sock, int level, int optname, case ALG_SET_KEY: if (sock->state == SS_CONNECTED) goto unlock; - if (!type->setkey) + + err = alg_setkey(sk, optval, optlen, type->setkey); + break; + case ALG_SET_PUBKEY: + if (sock->state == SS_CONNECTED) goto unlock; - err = alg_setkey(sk, optval, optlen); + err = alg_setkey(sk, optval, optlen, type->setpubkey); break; case ALG_SET_AEAD_AUTHSIZE: if (sock->state == SS_CONNECTED) diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h index a2bfd78..6c3e6e7 100644 --- a/include/crypto/if_alg.h +++ b/include/crypto/if_alg.h @@ -52,6 +52,7 @@ struct af_alg_type { void *(*bind)(const char *name, u32 type, u32 mask); void (*release)(void *private); int (*setkey)(void *private, const u8 *key, unsigned int keylen); + int (*setpubkey)(void *private, const u8 *key, unsigned int keylen); int (*accept)(void *private, struct sock *sk); int (*accept_nokey)(void *private, struct sock *sk); int (*setauthsize)(void *private, unsigned int authsize); -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 6/6] crypto: AF_ALG - add support for key_id
This patch adds support for asymmetric key type to AF_ALG. It will work as follows: A new PF_ALG socket options are added on top of existing ALG_SET_KEY and ALG_SET_PUBKEY, namely ALG_SET_KEY_ID and ALG_SET_PUBKEY_ID for setting public and private keys respectively. When these new options will be used the user, instead of providing the key material, will provide a key id and the key itself will be obtained from kernel keyring subsystem. The user will use the standard tools (keyctl tool or the keyctl syscall) for key instantiation and to obtain the key id. The key id can also be obtained by reading the /proc/keys file. When a key corresponding to the given keyid is found, it is stored in the socket context and subsequent crypto operation invoked by the user will use the new asymmetric accessor functions instead of akcipher api. The asymmetric subtype can internally use akcipher api or invoke operations defined by a given subtype, depending on the key type. Signed-off-by: Tadeusz Struk --- crypto/af_alg.c | 10 ++ crypto/algif_akcipher.c | 212 ++- include/crypto/if_alg.h |1 include/uapi/linux/if_alg.h |2 4 files changed, 220 insertions(+), 5 deletions(-) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 24dc082..59c8244 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -260,6 +260,16 @@ static int alg_setsockopt(struct socket *sock, int level, int optname, err = alg_setkey(sk, optval, optlen, type->setpubkey); break; + + case ALG_SET_KEY_ID: + case ALG_SET_PUBKEY_ID: + /* ALG_SET_KEY_ID is only for akcipher */ + if (!strcmp(type->name, "akcipher") || + sock->state == SS_CONNECTED) + goto unlock; + + err = alg_setkey(sk, optval, optlen, type->setkeyid); + break; case ALG_SET_AEAD_AUTHSIZE: if (sock->state == SS_CONNECTED) goto unlock; diff --git a/crypto/algif_akcipher.c b/crypto/algif_akcipher.c index 2b8d37e..106f715 100644 --- a/crypto/algif_akcipher.c +++ b/crypto/algif_akcipher.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include #include @@ -29,6 +31,7 @@ struct akcipher_sg_list { struct akcipher_tfm { struct crypto_akcipher *akcipher; + char keyid[12]; bool has_key; }; @@ -37,6 +40,7 @@ struct akcipher_ctx { struct af_alg_sgl rsgl[ALG_MAX_PAGES]; struct af_alg_completion completion; + struct key *key; unsigned long used; @@ -317,6 +321,158 @@ unlock: return err ? err : size; } +static int asym_key_encrypt(const struct key *key, struct akcipher_request *req) +{ + struct kernel_pkey_params params = {0}; + char *src = NULL, *dst = NULL, *in, *out; + int ret; + + if (!sg_is_last(req->src)) { + src = kmalloc(req->src_len, GFP_KERNEL); + if (!src) + return -ENOMEM; + scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0); + in = src; + } else { + in = sg_virt(req->src); + } + if (!sg_is_last(req->dst)) { + dst = kmalloc(req->dst_len, GFP_KERNEL); + if (!dst) { + kfree(src); + return -ENOMEM; + } + out = dst; + } else { + out = sg_virt(req->dst); + } + params.key = (struct key *)key; + params.in_len = req->src_len; + params.out_len = req->dst_len; + ret = encrypt_blob(¶ms, in, out); + if (ret) + goto free; + + if (dst) + scatterwalk_map_and_copy(dst, req->dst, 0, req->dst_len, 1); +free: + kfree(src); + kfree(dst); + return ret; +} + +static int asym_key_decrypt(const struct key *key, struct akcipher_request *req) +{ + struct kernel_pkey_params params = {0}; + char *src = NULL, *dst = NULL, *in, *out; + int ret; + + if (!sg_is_last(req->src)) { + src = kmalloc(req->src_len, GFP_KERNEL); + if (!src) + return -ENOMEM; + scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0); + in = src; + } else { + in = sg_virt(req->src); + } + if (!sg_is_last(req->dst)) { + dst = kmalloc(req->dst_len, GFP_KERNEL); + if (!dst) { + kfree(src); + return -ENOMEM; + } + out = dst; + } else { + out = sg_virt(req->dst); + } + params.key = (struct key *)key; + params.in_len = req->src_len; + params.out_len = req->dst_len; + ret = decrypt_blob(¶ms, in, out); + if (ret) + goto free; + + if (d
[PATCH v8 4/6] crypto: algif_akcipher - enable compilation
From: Stephan Mueller Add the Makefile and Kconfig updates to allow algif_akcipher to be compiled. Signed-off-by: Stephan Mueller Signed-off-by: Tadeusz Struk --- crypto/Kconfig |9 + crypto/Makefile |1 + 2 files changed, 10 insertions(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index 1d33beb..3c6113e 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -1627,6 +1627,15 @@ config CRYPTO_USER_API_AEAD This option enables the user-spaces interface for AEAD cipher algorithms. +config CRYPTO_USER_API_AKCIPHER + tristate "User-space interface for asymmetric key cipher algorithms" + depends on NET + select CRYPTO_AKCIPHER2 + select CRYPTO_USER_API + help + This option enables the user-spaces interface for asymmetric + key cipher algorithms. + config CRYPTO_HASH_INFO bool diff --git a/crypto/Makefile b/crypto/Makefile index 4f4ef7e..c51ac16 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -121,6 +121,7 @@ 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 obj-$(CONFIG_CRYPTO_USER_API_AEAD) += algif_aead.o +obj-$(CONFIG_CRYPTO_USER_API_AKCIPHER) += algif_akcipher.o # # generic algorithms and the async_tx api -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 1/6] crypto: AF_ALG -- add sign/verify API
From: Stephan Mueller Add the flags for handling signature generation and signature verification. Also, the patch adds the interface for setting a public key. Signed-off-by: Stephan Mueller Signed-off-by: Tadeusz Struk --- include/uapi/linux/if_alg.h |3 +++ 1 file changed, 3 insertions(+) diff --git a/include/uapi/linux/if_alg.h b/include/uapi/linux/if_alg.h index f2acd2f..02e6162 100644 --- a/include/uapi/linux/if_alg.h +++ b/include/uapi/linux/if_alg.h @@ -34,9 +34,12 @@ struct af_alg_iv { #define ALG_SET_OP 3 #define ALG_SET_AEAD_ASSOCLEN 4 #define ALG_SET_AEAD_AUTHSIZE 5 +#define ALG_SET_PUBKEY 6 /* Operations */ #define ALG_OP_DECRYPT 0 #define ALG_OP_ENCRYPT 1 +#define ALG_OP_SIGN2 +#define ALG_OP_VERIFY 3 #endif /* _LINUX_IF_ALG_H */ -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 0/6] crypto: algif - add akcipher
First four patches are a resend algif_akcipher from Stephan Mueller, with minor changes after rebase on top of 4.7-rc1. The next three patches add support for keys stored in system keyring subsystem. First patch adds algif_akcipher nokey hadlers. Second patch adds generic sign, verify, encrypt, decrypt accessors functions to the asymmetric key type. These will be defined by asymmetric subtypes, similarly to how public_key currently defines the verify_signature function. Third patch adds support for ALG_SET_KEY_ID and ALG_SET_PUBKEY_ID commands to AF_ALG and setkeyid operation to the af_alg_type struct. If the keyid is used then the afalg layer acquires the key for the keyring subsystem and uses the new asymmetric accessor functions instead of akcipher api. The asymmetric subtypes can use akcipher api internally. Patches are generate against: http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-next v8 hanges: - copy the result to user for verify after the signature_verify operation. Before only the return code was checked, but not the actual data. Reported by Mat Martineau - remove the constrain on the output buffer size as requested by Mat Martineau - ifx uninitialize variable issue, reported by Mat Martineau v7 changes: - update to reflect changes in kernel_pkey_params struct v6 changes: - rabased on top of http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-asym-keyctl v5 changes: - drop public key changes and use new version provided by David v4 changes: - don't use internal public_key struct in af_alg. - add generic accessor functions to asymmetric key type, which take the generic struct key type and resolve the specific subtype internally v3 changes: - include Stephan's patches (rebased on 4.6-rc1) - add algif_akcipher nokey hadlers - add public_key info struct to public_key and helper query functions - add a check if a key is a software accessible key on af_alg, and return -ENOKEY if it isn't v2 changes: - pass the original skcipher request in ablkcipher.base.data instead of casting it back from the ablkcipher request. - rename _req to base_req - dropped 3/3 --- Stephan Mueller (4): crypto: AF_ALG -- add sign/verify API crypto: AF_ALG -- add setpubkey setsockopt call crypto: AF_ALG -- add asymmetric cipher interface crypto: algif_akcipher - enable compilation Tadeusz Struk (2): crypto: algif_akcipher - add ops_nokey crypto: AF_ALG - add support for key_id crypto/Kconfig |9 crypto/Makefile |1 crypto/af_alg.c | 28 + crypto/algif_akcipher.c | 878 +++ include/crypto/if_alg.h |2 include/uapi/linux/if_alg.h |5 6 files changed, 918 insertions(+), 5 deletions(-) create mode 100644 crypto/algif_akcipher.c -- TS -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Doing crypto in small stack buffers (bluetooth vs vmalloc-stack crash, etc)
On Wed, Jun 22, 2016 at 11:41 PM, Herbert Xu wrote: > On Thu, Jun 23, 2016 at 11:48:25AM +0800, Herbert Xu wrote: >> >> No we never had such an API in the kernel. However, I see that >> rxkad does some pretty silly things and we should be able to avoid >> using the stack in pretty much all cases. Let me try to come up with >> something. > > Here it is: > > ---8<--- > Subject: rxrpc: Avoid using stack memory in SG lists in rxkad Looks reasonable to me. Unless anyone tells me otherwise, my plan is to queue it in my virtually-mapped stack series and to ask Ingo to apply it via -tip. If it went in via the networking tree, that would work as well, but it would introduce a bisectability problem. Thanks! --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[cryptodev:master 79/79] (.text+0x330de0): multiple definition of `ecdh_shared_secret'
tree: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master head: 3c4b23901a0c766879dff680cd6bdab47bcdbbd2 commit: 3c4b23901a0c766879dff680cd6bdab47bcdbbd2 [79/79] crypto: ecdh - Add ECDH software support config: i386-allyesconfig (attached as .config) compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430 reproduce: git checkout 3c4b23901a0c766879dff680cd6bdab47bcdbbd2 # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): net/built-in.o: In function `ecdh_shared_secret': >> (.text+0x330de0): multiple definition of `ecdh_shared_secret' crypto/built-in.o:(.text+0xb1b0): first defined here --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: Binary data
Re: [PATCH 5/8] KEYS: Provide software public key query function [ver #2]
David, On Thu, 23 Jun 2016, David Howells wrote: Provide a query function for the software public key implementation. This permits information about such a key to be obtained using query_asymmetric_key() or KEYCTL_PKEY_QUERY. Signed-off-by: David Howells --- crypto/asymmetric_keys/public_key.c | 96 ++- 1 file changed, 82 insertions(+), 14 deletions(-) diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index fd76b5fc3b3a..a48a47a1dff0 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -57,6 +57,81 @@ static void public_key_destroy(void *payload0, void *payload3) public_key_signature_free(payload3); } +/* + * Determine the crypto algorithm name. + */ +static +int software_key_determine_akcipher(const char *encoding, + const char *hash_algo, + const struct public_key *pkey, + char alg_name[CRYPTO_MAX_ALG_NAME]) +{ + int n; + + if (strcmp(encoding, "pkcs1") == 0) { + /* The data wangled by the RSA algorithm is typically padded +* and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447 +* sec 8.2]. +*/ + if (!hash_algo) + n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, +"pkcs1pad(%s)", +pkey->pkey_algo); Did you see Herbert's patch that strips out non-hash pkcs1pad capabilities (and the ensuing discussion)? http://www.spinics.net/lists/linux-crypto/index.html#20432 I'm making use of pkcs1pad(rsa) with a TLS implementation, so it's good to see it supported here. + else + n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, +"pkcs1pad(%s,%s)", +pkey->pkey_algo, hash_algo); + return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0; + } + + if (strcmp(encoding, "raw") == 0) { + strcpy(alg_name, pkey->pkey_algo); + return 0; + } + + return -ENOPKG; +} Regards, -- Mat Martineau Intel OTC -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: crypto: rsa - Do not gratuitously drop leading zeroes
Hi Herbert, On 06/22/2016 03:14 AM, Herbert Xu wrote: > This was prompted by the caam RSA submission where a lot of work > was done just to strip the RSA output of leading zeroes. This is > in fact completely pointless because the only user of RSA in the > kernel then promptly puts them back. > > This patch series resolves this madness by simply leaving any > leading zeroes in place. The reason why mpi_write_to_sgl() strips the leading zeros is only because we said that it needs to work in the same way as the mpi_read_buffer(), which does remove it for whatever reason. So should we now change the mpi_read_buffer() as well? The mpi_read_buffer() is called from mpi_get_buffer(), which is used only by lib/digsig.c We also need to change the qat rsa implementation because it does remove zeros as well, but it will be very easy to do. Thanks, -- TS -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface
Hi Stephan, >> This brings me to another proposal for read buffer sizing: AF_ALG akcipher can guarantee that partial reads (where the read buffer is shorter than the output of the crypto op) will work using the same semantics as SOCK_DGRAM/SOCK_SEQPACKET. With those sockets, as much data as will fit is copied in to the read buffer and the remainder is discarded. I realize there's a performance and memory tradeoff, since the crypto algorithm needs a sufficiently large output buffer that would have to be created by AF_ALG akcipher. The user could manage that tradeoff by providing a larger buffer (typically key_size?) if it wants to avoid allocating and copying intermediate buffers inside the kernel. How shall the user know that something got truncated or that the kernel created memory? To the former point, recall the signature of recv: ssize_t recv(int sockfd, void *buf, size_t len, int flags); Traditionally, userspace apps can know that the buffer provided to recv was too small in two ways: The return value from recv / recvmsg was >= len. In the case of recvmsg, the MSG_TRUNC flag is set. To quote man recv: "All three calls return the length of the message on successful comple‐ tion. If a message is too long to fit in the supplied buffer, excess bytes may be discarded depending on the type of socket the message is received from." and "MSG_TRUNC (since Linux 2.2) For raw (AF_PACKET), Internet datagram (sinceLinux 2.4.27/2.6.8), netlink (since Linux 2.6.22), and UNIX datagram (since Linux 3.4) sockets: return the real length of the packet or datagram, even when it was longer than the passed buffer. " Regards, -Denis -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto: user - re-add size check for CRYPTO_MSG_GETALG
Am Donnerstag, 23. Juni 2016, 18:43:57 schrieb Herbert Xu: Hi Herbert, > On Wed, Jun 22, 2016 at 08:29:37PM +0200, Mathias Krause wrote: > > Commit 9aa867e46565 ("crypto: user - Add CRYPTO_MSG_DELRNG") > > accidentally removed the minimum size check for CRYPTO_MSG_GETALG > > netlink messages. This allows userland to send a truncated > > CRYPTO_MSG_GETALG message as short as a netlink header only making > > crypto_report() operate on uninitialized memory by accessing data > > beyond the end of the netlink message. > > > > Fix this be re-adding the minimum required size of CRYPTO_MSG_GETALG > > messages to the crypto_msg_min[] array. > > > > Fixes: 9aa867e46565 ("crypto: user - Add CRYPTO_MSG_DELRNG") > > Cc: sta...@vger.kernel.org # v4.2 > > Signed-off-by: Mathias Krause > > Cc: Steffen Klassert > > --- > > This should go on top of crypto-2.6/master. > > Patch applied to crypto. Thanks! Please revert my patch eed1e1afd8d542d9644534c1b712599b5d680007 as requested by Matthias. Ciao Stephan -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/8] KEYS: Provide software public key query function [ver #2]
Provide a query function for the software public key implementation. This permits information about such a key to be obtained using query_asymmetric_key() or KEYCTL_PKEY_QUERY. Signed-off-by: David Howells --- crypto/asymmetric_keys/public_key.c | 96 ++- 1 file changed, 82 insertions(+), 14 deletions(-) diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index fd76b5fc3b3a..a48a47a1dff0 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -57,6 +57,81 @@ static void public_key_destroy(void *payload0, void *payload3) public_key_signature_free(payload3); } +/* + * Determine the crypto algorithm name. + */ +static +int software_key_determine_akcipher(const char *encoding, + const char *hash_algo, + const struct public_key *pkey, + char alg_name[CRYPTO_MAX_ALG_NAME]) +{ + int n; + + if (strcmp(encoding, "pkcs1") == 0) { + /* The data wangled by the RSA algorithm is typically padded +* and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447 +* sec 8.2]. +*/ + if (!hash_algo) + n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, +"pkcs1pad(%s)", +pkey->pkey_algo); + else + n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, +"pkcs1pad(%s,%s)", +pkey->pkey_algo, hash_algo); + return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0; + } + + if (strcmp(encoding, "raw") == 0) { + strcpy(alg_name, pkey->pkey_algo); + return 0; + } + + return -ENOPKG; +} + +/* + * Query information about a key. + */ +static int software_key_query(const struct kernel_pkey_params *params, + struct kernel_pkey_query *info) +{ + struct crypto_akcipher *tfm; + struct public_key *pkey = params->key->payload.data[asym_crypto]; + char alg_name[CRYPTO_MAX_ALG_NAME]; + int ret, len; + + ret = software_key_determine_akcipher(params->encoding, + params->hash_algo, + pkey, alg_name); + if (ret < 0) + return ret; + + tfm = crypto_alloc_akcipher(alg_name, 0, 0); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + + ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen); + if (ret < 0) + goto error_free_tfm; + + len = crypto_akcipher_maxsize(tfm); + info->key_size = len * 8; + info->max_data_size = len; + info->max_sig_size = len; + info->max_enc_size = len; + info->max_dec_size = len; + info->supported_ops = KEYCTL_SUPPORTS_VERIFY; + ret = 0; + +error_free_tfm: + crypto_free_akcipher(tfm); + pr_devel("<==%s() = %d\n", __func__, ret); + return ret; +} + struct public_key_completion { struct completion completion; int err; @@ -83,8 +158,7 @@ int public_key_verify_signature(const struct public_key *pkey, struct crypto_akcipher *tfm; struct akcipher_request *req; struct scatterlist sig_sg, digest_sg; - const char *alg_name; - char alg_name_buf[CRYPTO_MAX_ALG_NAME]; + char alg_name[CRYPTO_MAX_ALG_NAME]; void *output; unsigned int outlen; int ret = -ENOMEM; @@ -96,18 +170,11 @@ int public_key_verify_signature(const struct public_key *pkey, BUG_ON(!sig->digest); BUG_ON(!sig->s); - alg_name = sig->pkey_algo; - if (strcmp(sig->pkey_algo, "rsa") == 0) { - /* The data wangled by the RSA algorithm is typically padded -* and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447 -* sec 8.2]. -*/ - if (snprintf(alg_name_buf, CRYPTO_MAX_ALG_NAME, -"pkcs1pad(rsa,%s)", sig->hash_algo -) >= CRYPTO_MAX_ALG_NAME) - return -EINVAL; - alg_name = alg_name_buf; - } + ret = software_key_determine_akcipher(sig->encoding, + sig->hash_algo, + pkey, alg_name); + if (ret < 0) + return ret; tfm = crypto_alloc_akcipher(alg_name, 0, 0); if (IS_ERR(tfm)) @@ -179,6 +246,7 @@ struct asymmetric_key_subtype public_key_subtype = { .name_len = sizeof("public_key") - 1, .describe = public_key_describe, .destroy= public_key_destroy, + .query = software_
[PATCH 4/8] KEYS: Make the X.509 and PKCS7 parsers supply the sig encoding type [ver #2]
Make the X.509 and PKCS7 parsers fill in the signature encoding type field recently added to the public_key_signature struct. Signed-off-by: David Howells --- crypto/asymmetric_keys/pkcs7_parser.c |1 + crypto/asymmetric_keys/x509_cert_parser.c | 21 + 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index af4cd8649117..5f0c6755a55b 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c @@ -261,6 +261,7 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen, switch (ctx->last_oid) { case OID_rsaEncryption: ctx->sinfo->sig->pkey_algo = "rsa"; + ctx->sinfo->sig->encoding = "pkcs1"; break; default: printk("Unsupported pkey algo: %u\n", ctx->last_oid); diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c index 865f46ea724f..1f1899d5ab43 100644 --- a/crypto/asymmetric_keys/x509_cert_parser.c +++ b/crypto/asymmetric_keys/x509_cert_parser.c @@ -199,35 +199,32 @@ int x509_note_pkey_algo(void *context, size_t hdrlen, case OID_md4WithRSAEncryption: ctx->cert->sig->hash_algo = "md4"; - ctx->cert->sig->pkey_algo = "rsa"; - break; + goto rsa_pkcs1; case OID_sha1WithRSAEncryption: ctx->cert->sig->hash_algo = "sha1"; - ctx->cert->sig->pkey_algo = "rsa"; - break; + goto rsa_pkcs1; case OID_sha256WithRSAEncryption: ctx->cert->sig->hash_algo = "sha256"; - ctx->cert->sig->pkey_algo = "rsa"; - break; + goto rsa_pkcs1; case OID_sha384WithRSAEncryption: ctx->cert->sig->hash_algo = "sha384"; - ctx->cert->sig->pkey_algo = "rsa"; - break; + goto rsa_pkcs1; case OID_sha512WithRSAEncryption: ctx->cert->sig->hash_algo = "sha512"; - ctx->cert->sig->pkey_algo = "rsa"; - break; + goto rsa_pkcs1; case OID_sha224WithRSAEncryption: ctx->cert->sig->hash_algo = "sha224"; - ctx->cert->sig->pkey_algo = "rsa"; - break; + goto rsa_pkcs1; } +rsa_pkcs1: + ctx->cert->sig->pkey_algo = "rsa"; + ctx->cert->sig->encoding = "pkcs1"; ctx->algo_oid = ctx->last_oid; return 0; } -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/8] KEYS: keyctl operations for asymmetric keys [ver #2]
Here's a set of patches that provides keyctl access for asymmetric keys, including a query function, and functions to do encryption, decryption, signature creation and signature verification. I've added a PKCS#8 asymmetric key parser so that you can load an RSA private key into the kernel. Currently only DER-encoded and unencrypted PKCS#8 is supported. Encryption and verification can use a public key from an X.509 cert, but signing and decryption require a private key, though encryption and verification can use that too. Example usage: j=`openssl pkcs8 -in private_key.pem -topk8 -nocrypt -outform DER | \ keyctl padd asymmetric foo @s` echo -n abcdefghijklmnopqrst >/tmp/data keyctl pkey_encrypt $j /tmp/data enc=pkcs1 >/tmp/enc keyctl pkey_decrypt $j /tmp/enc enc=pkcs1 >/tmp/dec cmp /tmp/data /tmp/dec keyctl pkey_sign $j /tmp/data enc=pkcs1 hash=sha1 >/tmp/sig keyctl pkey_verify $j /tmp/data /tmp/sig enc=pkcs1 hash=sha1 Changes: (*) I've taken out the password parameters for the moment as there isn't yet a subtype that uses them. I have, however, left space in the keyctl UAPI to add them back later. The kernel patches can be found here also: http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-asym-keyctl The keyutils changes needed can be found here: http://git.kernel.org/cgit/linux/kernel/git/dhowells/keyutils.git/log/?h=pkey David --- David Howells (8): KEYS: Provide key type operations for asymmetric key ops KEYS: Provide keyctls to drive the new key type ops for asymmetric keys KEYS: Provide missing asymmetric key subops for new key type ops KEYS: Make the X.509 and PKCS7 parsers supply the sig encoding type KEYS: Provide software public key query function KEYS: Allow the public_key struct to hold a private key KEYS: Implement encrypt, decrypt and sign for software asymmetric key KEYS: Implement PKCS#8 RSA Private Key parser Documentation/crypto/asymmetric-keys.txt | 26 ++ Documentation/security/keys.txt | 217 +++ crypto/asymmetric_keys/Kconfig| 10 + crypto/asymmetric_keys/Makefile | 13 + crypto/asymmetric_keys/asymmetric_keys.h |3 crypto/asymmetric_keys/asymmetric_type.c | 59 + crypto/asymmetric_keys/pkcs7_parser.c |1 crypto/asymmetric_keys/pkcs8.asn1 | 24 ++ crypto/asymmetric_keys/pkcs8_parser.c | 184 + crypto/asymmetric_keys/public_key.c | 195 -- crypto/asymmetric_keys/signature.c| 95 + crypto/asymmetric_keys/x509_cert_parser.c | 21 +- include/crypto/public_key.h | 14 + include/keys/asymmetric-subtype.h |9 + include/linux/key-type.h | 11 + include/linux/keyctl.h| 46 include/uapi/linux/keyctl.h | 30 +++ security/keys/Makefile|1 security/keys/compat.c| 18 ++ security/keys/internal.h | 39 security/keys/keyctl.c| 24 ++ security/keys/keyctl_pkey.c | 323 + 22 files changed, 1319 insertions(+), 44 deletions(-) create mode 100644 crypto/asymmetric_keys/pkcs8.asn1 create mode 100644 crypto/asymmetric_keys/pkcs8_parser.c create mode 100644 include/linux/keyctl.h create mode 100644 security/keys/keyctl_pkey.c -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/8] KEYS: Provide keyctls to drive the new key type ops for asymmetric keys [ver #2]
Provide five keyctl functions that permit userspace to make use of the new key type ops for accessing and driving asymmetric keys. (*) Query an asymmetric key. long keyctl(KEYCTL_PKEY_QUERY, key_serial_t key, unsigned long reserved, struct keyctl_pkey_query *info); Get information about an asymmetric key. The information is returned in the keyctl_pkey_query struct: __u32 supported_ops; A bit mask of flags indicating which ops are supported. This is constructed from a bitwise-OR of: KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY} __u32 key_size; The size in bits of the key. __u16 max_data_size; __u16 max_sig_size; __u16 max_enc_size; __u16 max_dec_size; The maximum sizes in bytes of a blob of data to be signed, a signature blob, a blob to be encrypted and a blob to be decrypted. reserved must be set to 0. This is intended for future use to hand over one or more passphrases needed unlock a key. If successful, 0 is returned. If the key is not an asymmetric key, EOPNOTSUPP is returned. (*) Encrypt, decrypt, sign or verify a blob using an asymmetric key. long keyctl(KEYCTL_PKEY_ENCRYPT, const struct keyctl_pkey_params *params, const char *info, const void *in, void *out); long keyctl(KEYCTL_PKEY_DECRYPT, const struct keyctl_pkey_params *params, const char *info, const void *in, void *out); long keyctl(KEYCTL_PKEY_SIGN, const struct keyctl_pkey_params *params, const char *info, const void *in, void *out); long keyctl(KEYCTL_PKEY_VERIFY, const struct keyctl_pkey_params *params, const char *info, const void *in, const void *in2); Use an asymmetric key to perform a public-key cryptographic operation a blob of data. The parameter block pointed to by params contains a number of integer values: __s32 key_id; __u32 in_len; __u32 out_len; __u32 in2_len; For a given operation, the in and out buffers are used as follows: Operation IDin,in_len out,out_len in2,in2_len === === === === KEYCTL_PKEY_ENCRYPT Raw dataEncrypted data - KEYCTL_PKEY_DECRYPT Encrypted data Raw data- KEYCTL_PKEY_SIGNRaw dataSignature - KEYCTL_PKEY_VERIFY Raw data- Signature info is a string of key=value pairs that supply supplementary information. The __spare space in the parameter block must be set to 0. This is intended, amongst other things, to allow the passing of passphrases required to unlock a key. If successful, encrypt, decrypt and sign all return the amount of data written into the output buffer. Verification returns 0 on success. Signed-off-by: David Howells --- Documentation/security/keys.txt | 111 + include/uapi/linux/keyctl.h | 25 +++ security/keys/Makefile |1 security/keys/compat.c | 18 ++ security/keys/internal.h| 39 + security/keys/keyctl.c | 24 +++ security/keys/keyctl_pkey.c | 323 +++ 7 files changed, 541 insertions(+) create mode 100644 security/keys/keyctl_pkey.c diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt index 286b4cab7e68..6844dcbba1ba 100644 --- a/Documentation/security/keys.txt +++ b/Documentation/security/keys.txt @@ -857,6 +857,117 @@ The keyctl syscall functions are: supported, error ENOKEY if the key could not be found, or error EACCES if the key is not readable by the caller. + + (*) Query an asymmetric key. + + long keyctl(KEYCTL_PKEY_QUERY, + key_serial_t key_id, unsigned long reserved, + struct keyctl_pkey_query *info); + + Get information about an asymmetric key. The information is returned in + the keyctl_pkey_query struct: + + __u32 supported_ops; + + A bit mask of flags indicating which ops are supported. This is + constructed from a bitwise-OR of: + + KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY} + + __u32 key_size; + + The size in bits of the key. + + __u16 max_data_size; + __u16 max_sig_size; + __u16 max_enc_size; + __u16 max_dec_size; + + The maximum sizes in bytes of a blob of data to be signed, a signature + blob, a blob to be encrypted and a blob to
[PATCH 3/8] KEYS: Provide missing asymmetric key subops for new key type ops [ver #2]
Provide the missing asymmetric key subops for new key type ops. This include query, encrypt, decrypt and create signature. Verify signature already exists. Also provided are accessor functions for this: int query_asymmetric_key(const struct key *key, struct kernel_pkey_query *info); int encrypt_blob(struct kernel_pkey_params *params, const void *data, void *enc); int decrypt_blob(struct kernel_pkey_params *params, const void *enc, void *data); int create_signature(struct kernel_pkey_params *params, const void *data, void *enc); The public_key_signature struct gains an encoding field to carry the encoding for verify_signature(). Signed-off-by: David Howells --- Documentation/crypto/asymmetric-keys.txt | 24 ++-- crypto/asymmetric_keys/asymmetric_keys.h |3 + crypto/asymmetric_keys/asymmetric_type.c | 59 --- crypto/asymmetric_keys/signature.c | 95 ++ include/crypto/public_key.h | 13 +++- include/keys/asymmetric-subtype.h|9 +++ 6 files changed, 188 insertions(+), 15 deletions(-) diff --git a/Documentation/crypto/asymmetric-keys.txt b/Documentation/crypto/asymmetric-keys.txt index 8c07e0ea6bc0..cdf2aca41b2c 100644 --- a/Documentation/crypto/asymmetric-keys.txt +++ b/Documentation/crypto/asymmetric-keys.txt @@ -182,6 +182,10 @@ and looks like the following: void (*describe)(const struct key *key, struct seq_file *m); void (*destroy)(void *payload); + int (*query)(const struct kernel_pkey_params *params, +struct kernel_pkey_query *info); + int (*eds_op)(struct kernel_pkey_params *params, + const void *in, void *out); int (*verify_signature)(const struct key *key, const struct public_key_signature *sig); }; @@ -206,12 +210,22 @@ There are a number of operations defined by the subtype: asymmetric key will look after freeing the fingerprint and releasing the reference on the subtype module. - (3) verify_signature(). + (3) query(). - Optional. These are the entry points for the key usage operations. - Currently there is only the one defined. If not set, the caller will be - given -ENOTSUPP. The subtype may do anything it likes to implement an - operation, including offloading to hardware. + Mandatory. This is a function for querying the capabilities of a key. + + (4) eds_op(). + + Optional. This is the entry point for the encryption, decryption and + signature creation operations (which are distinguished by the operation ID + in the parameter struct). The subtype may do anything it likes to + implement an operation, including offloading to hardware. + + (5) verify_signature(). + + Optional. This is the entry point for signature verification. The + subtype may do anything it likes to implement an operation, including + offloading to hardware. == diff --git a/crypto/asymmetric_keys/asymmetric_keys.h b/crypto/asymmetric_keys/asymmetric_keys.h index ca8e9ac34ce6..7be1ccf4fa9f 100644 --- a/crypto/asymmetric_keys/asymmetric_keys.h +++ b/crypto/asymmetric_keys/asymmetric_keys.h @@ -16,3 +16,6 @@ extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id); extern int __asymmetric_key_hex_to_key_id(const char *id, struct asymmetric_key_id *match_id, size_t hexlen); + +extern int asymmetric_key_eds_op(struct kernel_pkey_params *params, +const void *in, void *out); diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c index 6600181d5d01..77aa44abd7a6 100644 --- a/crypto/asymmetric_keys/asymmetric_type.c +++ b/crypto/asymmetric_keys/asymmetric_type.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "asymmetric_keys.h" MODULE_LICENSE("GPL"); @@ -451,15 +452,57 @@ static void asymmetric_key_destroy(struct key *key) asymmetric_key_free_kids(kids); } +int asymmetric_key_eds_op(struct kernel_pkey_params *params, + const void *in, void *out) +{ + const struct asymmetric_key_subtype *subtype; + struct key *key = params->key; + int ret; + + pr_devel("==>%s()\n", __func__); + + if (key->type != &key_type_asymmetric) + return -EINVAL; + subtype = asymmetric_key_subtype(key); + if (!subtype || + !key->payload.data[0]) + return -EINVAL; + if (!subtype->eds_op) + return -ENOTSUPP; + + ret = subtype->eds_op(params, in, out); + + pr_devel("<==%s() = %d\n", __func__, ret);
[PATCH 6/8] KEYS: Allow the public_key struct to hold a private key [ver #2]
Put a flag in the public_key struct to indicate if the structure is holding a private key. The private key must be held ASN.1 encoded in the format specified in RFC 3447 A.1.2. This is the form required by crypto/rsa.c. The software encryption subtype's verification and query functions then need to select the appropriate crypto function to set the key. Signed-off-by: David Howells --- crypto/asymmetric_keys/public_key.c | 14 -- include/crypto/public_key.h |1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index a48a47a1dff0..a29ca01a41a0 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -113,7 +113,12 @@ static int software_key_query(const struct kernel_pkey_params *params, if (IS_ERR(tfm)) return PTR_ERR(tfm); - ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen); + if (pkey->key_is_private) + ret = crypto_akcipher_set_priv_key(tfm, + pkey->key, pkey->keylen); + else + ret = crypto_akcipher_set_pub_key(tfm, + pkey->key, pkey->keylen); if (ret < 0) goto error_free_tfm; @@ -184,7 +189,12 @@ int public_key_verify_signature(const struct public_key *pkey, if (!req) goto error_free_tfm; - ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen); + if (pkey->key_is_private) + ret = crypto_akcipher_set_priv_key(tfm, + pkey->key, pkey->keylen); + else + ret = crypto_akcipher_set_pub_key(tfm, + pkey->key, pkey->keylen); if (ret) goto error_free_req; diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h index c46140d3729c..c5e569b2a73e 100644 --- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h @@ -25,6 +25,7 @@ struct public_key { void *key; u32 keylen; + bool key_is_private; const char *id_type; const char *pkey_algo; }; -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 8/8] KEYS: Implement PKCS#8 RSA Private Key parser [ver #2]
Implement PKCS#8 RSA Private Key format [RFC 5208] parser for the asymmetric key type. For the moment, this will only support unencrypted DER blobs. PEM and decryption can be added later. PKCS#8 keys can be loaded like this: openssl pkcs8 -in private_key.pem -topk8 -nocrypt -outform DER | \ keyctl padd asymmetric foo @s Signed-off-by: David Howells --- Documentation/crypto/asymmetric-keys.txt |2 crypto/asymmetric_keys/Kconfig | 10 ++ crypto/asymmetric_keys/Makefile | 13 ++ crypto/asymmetric_keys/pkcs8.asn1| 24 crypto/asymmetric_keys/pkcs8_parser.c| 184 ++ 5 files changed, 233 insertions(+) create mode 100644 crypto/asymmetric_keys/pkcs8.asn1 create mode 100644 crypto/asymmetric_keys/pkcs8_parser.c diff --git a/Documentation/crypto/asymmetric-keys.txt b/Documentation/crypto/asymmetric-keys.txt index cdf2aca41b2c..80d45b5776b0 100644 --- a/Documentation/crypto/asymmetric-keys.txt +++ b/Documentation/crypto/asymmetric-keys.txt @@ -247,6 +247,8 @@ Examples of blob formats for which parsers could be implemented include: - X.509 ASN.1 stream. - Pointer to TPM key. - Pointer to UEFI key. + - PKCS#8 private key [RFC 5208]. + - PKCS#5 encrypted private key [RFC 2898]. During key instantiation each parser in the list is tried until one doesn't return -EBADMSG. diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig index 331f6baf2df8..338fbed30a32 100644 --- a/crypto/asymmetric_keys/Kconfig +++ b/crypto/asymmetric_keys/Kconfig @@ -30,6 +30,16 @@ config X509_CERTIFICATE_PARSER data and provides the ability to instantiate a crypto key from a public key packet found inside the certificate. +config PKCS8_PRIVATE_KEY_PARSER + tristate "PKCS#8 private key parser" + depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE + select ASN1 + select OID_REGISTRY + help + This option provides support for parsing PKCS#8 format blobs for + private key data and provides the ability to instantiate a crypto key + from that data. + config PKCS7_MESSAGE_PARSER tristate "PKCS#7 message parser" depends on X509_CERTIFICATE_PARSER diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile index 6516855bec18..ac877577d677 100644 --- a/crypto/asymmetric_keys/Makefile +++ b/crypto/asymmetric_keys/Makefile @@ -32,6 +32,19 @@ clean-files += x509-asn1.c x509-asn1.h clean-files+= x509_akid-asn1.c x509_akid-asn1.h # +# PKCS#8 private key handling +# +obj-$(CONFIG_PKCS8_PRIVATE_KEY_PARSER) += pkcs8_key_parser.o +pkcs8_key_parser-y := \ + pkcs8-asn1.o \ + pkcs8_parser.o + +$(obj)/pkcs8_parser.o: $(obj)/pkcs8-asn1.h +$(obj)/pkcs8-asn1.o: $(obj)/pkcs8-asn1.c $(obj)/pkcs8-asn1.h + +clean-files+= pkcs8-asn1.c pkcs8-asn1.h + +# # PKCS#7 message handling # obj-$(CONFIG_PKCS7_MESSAGE_PARSER) += pkcs7_message.o diff --git a/crypto/asymmetric_keys/pkcs8.asn1 b/crypto/asymmetric_keys/pkcs8.asn1 new file mode 100644 index ..702c41a3c713 --- /dev/null +++ b/crypto/asymmetric_keys/pkcs8.asn1 @@ -0,0 +1,24 @@ +-- +-- This is the unencrypted variant +-- +PrivateKeyInfo ::= SEQUENCE { + version Version, + privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + privateKey PrivateKey, + attributes [0] IMPLICIT Attributes OPTIONAL +} + +Version ::= INTEGER ({ pkcs8_note_version }) + +PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier ({ pkcs8_note_algo }) + +PrivateKey ::= OCTET STRING ({ pkcs8_note_key }) + +Attributes ::= SET OF Attribute + +Attribute ::= ANY + +AlgorithmIdentifier ::= SEQUENCE { + algorithm OBJECT IDENTIFIER ({ pkcs8_note_OID }), + parameters ANY OPTIONAL +} diff --git a/crypto/asymmetric_keys/pkcs8_parser.c b/crypto/asymmetric_keys/pkcs8_parser.c new file mode 100644 index ..26a73c0b7eef --- /dev/null +++ b/crypto/asymmetric_keys/pkcs8_parser.c @@ -0,0 +1,184 @@ +/* PKCS#8 Private Key parser [RFC 5208]. + * + * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowe...@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "PKCS8: "fmt +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pkcs8-asn1.h" + +struct pkcs8_parse_context { + struct public_key *pub; + unsigned long data; /* Start of data */ + enum OIDlast_oid; /* Last OID encountered */ + enum OIDalgo_oid; /* Algorithm OID */ + u32 key_size; + const void *key; +}; + +/* +
[PATCH 7/8] KEYS: Implement encrypt, decrypt and sign for software asymmetric key [ver #2]
Implement the encrypt, decrypt and sign operations for the software asymmetric key subtype. This mostly involves offloading the call to the crypto layer. Note that the decrypt and sign operations require a private key to be supplied. Encrypt (and also verify) will work with either a public or a private key. A public key can be supplied with an X.509 certificate and a private key can be supplied using a PKCS#8 blob: # j=`openssl pkcs8 -in ~/pkcs7/firmwarekey2.priv -topk8 -nocrypt -outform DER | keyctl padd asymmetric foo @s` # keyctl pkey_query $j - enc=pkcs1 key_size=4096 max_data_size=512 max_sig_size=512 max_enc_size=512 max_dec_size=512 encrypt=y decrypt=y sign=y verify=y # keyctl pkey_encrypt $j 0 data enc=pkcs1 >/tmp/enc # keyctl pkey_decrypt $j 0 /tmp/enc enc=pkcs1 >/tmp/dec # cmp data /tmp/dec # keyctl pkey_sign $j 0 data enc=pkcs1 hash=sha1 >/tmp/sig # keyctl pkey_verify $j 0 data /tmp/sig enc=pkcs1 hash=sha1 # Signed-off-by: David Howells --- crypto/asymmetric_keys/public_key.c | 89 ++- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index a29ca01a41a0..8be2586028b6 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -128,7 +128,11 @@ static int software_key_query(const struct kernel_pkey_params *params, info->max_sig_size = len; info->max_enc_size = len; info->max_dec_size = len; - info->supported_ops = KEYCTL_SUPPORTS_VERIFY; + info->supported_ops = (KEYCTL_SUPPORTS_ENCRYPT | + KEYCTL_SUPPORTS_VERIFY); + if (pkey->key_is_private) + info->supported_ops |= (KEYCTL_SUPPORTS_DECRYPT | + KEYCTL_SUPPORTS_SIGN); ret = 0; error_free_tfm: @@ -142,7 +146,7 @@ struct public_key_completion { int err; }; -static void public_key_verify_done(struct crypto_async_request *req, int err) +static void public_key_crypto_done(struct crypto_async_request *req, int err) { struct public_key_completion *compl = req->data; @@ -154,6 +158,84 @@ static void public_key_verify_done(struct crypto_async_request *req, int err) } /* + * Do encryption, decryption and signing ops. + */ +static int software_key_eds_op(struct kernel_pkey_params *params, + const void *in, void *out) +{ + struct public_key_completion compl; + const struct public_key *pkey = params->key->payload.data[asym_crypto]; + struct akcipher_request *req; + struct crypto_akcipher *tfm; + struct scatterlist in_sg, out_sg; + char alg_name[CRYPTO_MAX_ALG_NAME]; + int ret; + + pr_devel("==>%s()\n", __func__); + + ret = software_key_determine_akcipher(params->encoding, + params->hash_algo, + pkey, alg_name); + if (ret < 0) + return ret; + + tfm = crypto_alloc_akcipher(alg_name, 0, 0); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + + req = akcipher_request_alloc(tfm, GFP_KERNEL); + if (!req) + goto error_free_tfm; + + if (pkey->key_is_private) + ret = crypto_akcipher_set_priv_key(tfm, + pkey->key, pkey->keylen); + else + ret = crypto_akcipher_set_pub_key(tfm, + pkey->key, pkey->keylen); + if (ret) + goto error_free_req; + + sg_init_one(&in_sg, in, params->in_len); + sg_init_one(&out_sg, out, params->out_len); + akcipher_request_set_crypt(req, &in_sg, &out_sg, params->in_len, + params->out_len); + init_completion(&compl.completion); + akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP, + public_key_crypto_done, &compl); + + /* Perform the encryption calculation. */ + switch (params->op) { + case kernel_pkey_encrypt: + ret = crypto_akcipher_encrypt(req); + break; + case kernel_pkey_decrypt: + ret = crypto_akcipher_decrypt(req); + break; + case kernel_pkey_sign: + ret = crypto_akcipher_sign(req); + break; + default: + BUG(); + } + if (ret == -EINPROGRESS) { + wait_for_completion(&compl.completion); + ret = compl.err; + } + + if (ret == 0) + ret = req->dst_len; + +error_free_req: + akcipher_request_free(req); +error_free_tfm: + crypto_fre
[PATCH 1/8] KEYS: Provide key type operations for asymmetric key ops [ver #2]
Provide five new operations in the key_type struct that can be used to provide access to asymmetric key operations. These will be implemented for the asymmetric key type in a later patch and may refer to a key retained in RAM by the kernel or a key retained in crypto hardware. int (*asym_query)(const struct kernel_pkey_params *params, struct kernel_pkey_query *info); int (*asym_eds_op)(struct kernel_pkey_params *params, const void *in, void *out); int (*asym_verify_signature)(struct kernel_pkey_params *params, const void *in, const void *in2); Since encrypt, decrypt and sign are identical in their interfaces, they're rolled together in the asym_eds_op() operation and there's an operation ID in the params argument to distinguish them. Verify is different in that we supply the data and the signature instead and get an error value (or 0) as the only result on the expectation that this may well be how a hardware crypto device may work. Signed-off-by: David Howells --- Documentation/security/keys.txt | 106 +++ include/linux/key-type.h| 11 include/linux/keyctl.h | 46 + include/uapi/linux/keyctl.h |5 ++ 4 files changed, 168 insertions(+) create mode 100644 include/linux/keyctl.h diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt index 3849814bfe6d..286b4cab7e68 100644 --- a/Documentation/security/keys.txt +++ b/Documentation/security/keys.txt @@ -1432,6 +1432,112 @@ The structure has a number of fields, some of which are mandatory: The authorisation key. + (*) int (*asym_eds_op)(struct kernel_pkey_params *params, + const void *in, void *out); + int (*asym_verify_signature)(struct kernel_pkey_params *params, + const void *in, const void *in2); + + These methods are optional. If provided the first allows a key to be + used to encrypt, decrypt or sign a blob of data, and the second allows a + key to verify a signature. + + In all cases, the following information is provided in the params block: + + struct kernel_pkey_params { + struct key *key; + const char *encoding; + const char *hash_algo; + char*info; + __u32 in_len; + union { + __u32 out_len; + __u32 in2_len; + }; + enum kernel_pkey_operation op : 8; + }; + + This includes the key to be used; an optional string indicating the + encoding to use (for instance, "pkcs1" may be used with an RSA key to + indicate RSASSA-PKCS1-v1.5 or RSAES-PKCS1-v1.5 encoding); the name of the + hash algorithm used to generate the data for a signature (if appropriate); + the sizes of the input and output (or second input) buffers; and the ID of + the operation to be performed. + + For a given operation ID, the input and output buffers are used as + follows: + + Operation IDin,in_len out,out_len in2,in2_len + === === === === + kernel_pkey_encrypt Raw dataEncrypted data - + kernel_pkey_decrypt Encrypted data Raw data- + kernel_pkey_signRaw dataSignature - + kernel_pkey_verify Raw data- Signature + + asym_eds_op() deals with encryption, decryption and signature creation as + specified by params->op. Note that params->op is also set for + asym_verify_signature(). + + Encrypting and signature creation both take raw data in the input buffer + and return the encrypted result in the output buffer. Padding may have + been added if an encoding was set. In the case of signature creation, + depending on the encoding, the padding created may need to indicate the + digest algorithm - the name of which should be supplied in hash_algo. + + Decryption takes encrypted data in the input buffer and returns the raw + data in the output buffer. Padding will get checked and stripped off if + an encoding was set. + + Verification takes raw data in the input buffer and the signature in the + second input buffer and checks that the one matches the other. Padding + will be validated. Depending on the encoding, the digest algorithm used + to generate the raw data may need to be indicated in hash_algo. + + If successful, asym_eds_op() should return the number of bytes written + into the output buffer. asym_verify_signature() should return 0. + + A variety of errors may be returned, including EOPNOTSUPP if the operation + is not supported; EKEYREJECTED if verification fails; ENOPKG if the + require
[PATCH 0/8] KEYS: keyctl operations for asymmetric keys
Here's a set of patches that provides keyctl access for asymmetric keys, including a query function, and functions to do encryption, decryption, signature creation and signature verification. I've added a PKCS#8 asymmetric key parser so that you can load an RSA private key into the kernel. Currently only DER-encoded and unencrypted PKCS#8 is supported. Encryption and verification can use a public key from an X.509 cert, but signing and decryption require a private key, though encryption and verification can use that too. Example usage: j=`openssl pkcs8 -in private_key.pem -topk8 -nocrypt -outform DER | \ keyctl padd asymmetric foo @s` echo -n abcdefghijklmnopqrst >/tmp/data keyctl pkey_encrypt $j /tmp/data enc=pkcs1 >/tmp/enc keyctl pkey_decrypt $j /tmp/enc enc=pkcs1 >/tmp/dec cmp /tmp/data /tmp/dec keyctl pkey_sign $j /tmp/data enc=pkcs1 hash=sha1 >/tmp/sig keyctl pkey_verify $j /tmp/data /tmp/sig enc=pkcs1 hash=sha1 Changes: (*) I've taken out the password parameters for the moment as there isn't yet a subtype that uses them. I have, however, left space in the keyctl UAPI to add them back later. The kernel patches can be found here also: http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-asym-keyctl The keyutils changes needed can be found here: http://git.kernel.org/cgit/linux/kernel/git/dhowells/keyutils.git/log/?h=pkey David --- David Howells (8): KEYS: Provide key type operations for asymmetric key ops KEYS: Provide keyctls to drive the new key type ops for asymmetric keys KEYS: Provide missing asymmetric key subops for new key type ops KEYS: Make the X.509 and PKCS7 parsers supply the sig encoding type KEYS: Provide software public key query function KEYS: Allow the public_key struct to hold a private key KEYS: Implement encrypt, decrypt and sign for software asymmetric key KEYS: Implement PKCS#8 RSA Private Key parser Documentation/crypto/asymmetric-keys.txt | 26 ++ Documentation/security/keys.txt | 217 +++ crypto/asymmetric_keys/Kconfig| 10 + crypto/asymmetric_keys/Makefile | 13 + crypto/asymmetric_keys/asymmetric_keys.h |3 crypto/asymmetric_keys/asymmetric_type.c | 59 + crypto/asymmetric_keys/pkcs7_parser.c |1 crypto/asymmetric_keys/pkcs8.asn1 | 24 ++ crypto/asymmetric_keys/pkcs8_parser.c | 184 + crypto/asymmetric_keys/public_key.c | 195 -- crypto/asymmetric_keys/signature.c| 95 + crypto/asymmetric_keys/x509_cert_parser.c | 21 +- include/crypto/public_key.h | 14 + include/keys/asymmetric-subtype.h |9 + include/linux/key-type.h | 11 + include/linux/keyctl.h| 46 include/uapi/linux/keyctl.h | 30 +++ security/keys/Makefile|1 security/keys/compat.c| 18 ++ security/keys/internal.h | 39 security/keys/keyctl.c| 24 ++ security/keys/keyctl_pkey.c | 323 + 22 files changed, 1319 insertions(+), 44 deletions(-) create mode 100644 crypto/asymmetric_keys/pkcs8.asn1 create mode 100644 crypto/asymmetric_keys/pkcs8_parser.c create mode 100644 include/linux/keyctl.h create mode 100644 security/keys/keyctl_pkey.c -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 2/8] crypto: add driver-side scomp interface
On Wed, Jun 22, 2016 at 04:53:50PM +0100, Giovanni Cabiddu wrote: > On Mon, Jun 13, 2016 at 04:56:12PM +0800, Herbert Xu wrote: > > The backup path is also very unlikely to work because we'll be > > hitting this with 64K sizes and this just won't work with a 4K > > page size. > Is scatterwalk_map_and_copy broken? No that's not the problem. The problem is that you can't kmalloc 64K of memory. kmalloc requires physically contiguous memory and you cannot rely on having 64K of contiguous memory. > > This totally breaks down once you go to DMA, where an SG list is > > required. > scomp backends should be used only for software implementations. > A driver backend which needs DMA should plug into acomp. What I'm saying is that the current strategy of using vmalloc memory as input/output buffers cannot possibly work with acomp since you cannot do DMA over vmalloc memory. Cheers, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto : async implementation for sha1-mb
On Tue, Jun 21, 2016 at 06:21:46PM -0700, Megha Dey wrote: > From: Megha Dey > > Herbert wants the sha1-mb algorithm to have an async implementation: > https://lkml.org/lkml/2016/4/5/286. > Currently, sha1-mb uses an async interface for the outer algorithm > and a sync interface for the inner algorithm. This patch introduces > a async interface for even the inner algorithm. > > Signed-off-by: Megha Dey > Signed-off-by: Tim Chen Patch applied. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 02/10] crypto: marvell: Check engine is not already running when enabling a req
On Wed, Jun 22, 2016 at 01:23:39PM +0200, Romain Perier wrote: > Hello, > > Le 22/06/2016 12:33, Herbert Xu a écrit : > >Romain Perier wrote: > >>Add a BUG_ON() call when the driver tries to launch a crypto request > >>while the engine is still processing the previous one. This replaces > >>a silent system hang by a verbose kernel panic with the associated > >>backtrace to let the user know that something went wrong in the CESA > >>driver. > > > >Hmm, so how can this happen? > If it is triggerable then we better > >try to recover from it more gracefully. If it is not triggerable > >then why bother? > > > > Well, It does not happen with the current driver (in mainline). This > is bug I had when I added support to chain requests. Take a look at > the patch 008/010, it changes the way the requests are "prepared". > If you really enable a request while the engine is running, that's > very hard to debug. This is more useful to have a backtrace to let > the user know that something is wrong instead of having a silent > system hang. That's easier to debug and you can detect regressions. OK. All applied. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v11 0/3] Key-agreement Protocol Primitives (KPP) API
On Wed, Jun 22, 2016 at 05:49:12PM +0100, Salvatore Benedetto wrote: > Hi Herb, > > the following patchset introduces a new API for abstracting key-agreement > protocols such as DH and ECDH. It provides the primitives required for > implementing > the protocol, thus the name KPP (Key-agreement Protocol Primitives). > > Regards, > Salvatore > > Changes from v10: > * Remove all DH/ECDH code from testmgr. Secret is now encoded both > in little and big endian in the testvector All applied. Thanks! -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] crypto: user - re-add size check for CRYPTO_MSG_GETALG
On Wed, Jun 22, 2016 at 08:29:37PM +0200, Mathias Krause wrote: > Commit 9aa867e46565 ("crypto: user - Add CRYPTO_MSG_DELRNG") > accidentally removed the minimum size check for CRYPTO_MSG_GETALG > netlink messages. This allows userland to send a truncated > CRYPTO_MSG_GETALG message as short as a netlink header only making > crypto_report() operate on uninitialized memory by accessing data > beyond the end of the netlink message. > > Fix this be re-adding the minimum required size of CRYPTO_MSG_GETALG > messages to the crypto_msg_min[] array. > > Fixes: 9aa867e46565 ("crypto: user - Add CRYPTO_MSG_DELRNG") > Cc: sta...@vger.kernel.org# v4.2 > Signed-off-by: Mathias Krause > Cc: Steffen Klassert > --- > This should go on top of crypto-2.6/master. Patch applied to crypto. Thanks! -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html