From 560b1a82ee87288c18aca31ee3053272c3737fe5 Mon Sep 17 00:00:00 2001 From: Kamil Konieczny Date: Thu, 17 Aug 2017 12:11:36 +0200 Subject: crypto: doc - clarify return values for async hash methods * fix documentation of return values for crypto_ahash_init(), crypto_ahash_finup(), crypto_ahash_final(), crypto_ahash_digest() and crypto_ahash_update() Also while at it: * add notes for device driver developers in struct ahash_alg description * fix description of @final method in struct ahash_alg * fix typo in crypto_ahash_finup() description Signed-off-by: Kamil Konieczny Signed-off-by: Herbert Xu --- include/crypto/hash.h | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/crypto/hash.h b/include/crypto/hash.h index b5727bcd2336..0ed31fd80242 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -75,6 +75,7 @@ struct ahash_request { * state of the HASH transformation at the beginning. This shall fill in * the internal structures used during the entire duration of the whole * transformation. No data processing happens at this point. + * Note: mandatory. * @update: Push a chunk of data into the driver for transformation. This * function actually pushes blocks of data from upper layers into the * driver, which then passes those to the hardware as seen fit. This @@ -84,16 +85,20 @@ struct ahash_request { * context, as this function may be called in parallel with the same * transformation object. Data processing can happen synchronously * [SHASH] or asynchronously [AHASH] at this point. + * Note: mandatory. * @final: Retrieve result from the driver. This function finalizes the * transformation and retrieves the resulting hash from the driver and * pushes it back to upper layers. No data processing happens at this - * point. + * point unless hardware requires it to finish the transformation + * (then the data buffered by the device driver is processed). + * Note: mandatory. * @finup: Combination of @update and @final. This function is effectively a * combination of @update and @final calls issued in sequence. As some * hardware cannot do @update and @final separately, this callback was * added to allow such hardware to be used at least by IPsec. Data * processing can happen synchronously [SHASH] or asynchronously [AHASH] * at this point. + * Note: optional. * @digest: Combination of @init and @update and @final. This function * effectively behaves as the entire chain of operations, @init, * @update and @final issued in sequence. Just like @finup, this was @@ -416,11 +421,10 @@ static inline bool crypto_ahash_has_setkey(struct crypto_ahash *tfm) * needed to perform the cipher operation * * This function is a "short-hand" for the function calls of - * crypto_ahash_update and crypto_shash_final. The parameters have the same + * crypto_ahash_update and crypto_ahash_final. The parameters have the same * meaning as discussed for those separate functions. * - * Return: 0 if the message digest creation was successful; < 0 if an error - * occurred + * Return: see crypto_ahash_final() */ int crypto_ahash_finup(struct ahash_request *req); @@ -433,8 +437,11 @@ int crypto_ahash_finup(struct ahash_request *req); * based on all data added to the cipher handle. The message digest is placed * into the output buffer registered with the ahash_request handle. * - * Return: 0 if the message digest creation was successful; < 0 if an error - * occurred + * Return: + * 0 if the message digest was successfully calculated; + * -EINPROGRESS if data is feeded into hardware (DMA) or queued for later; + * -EBUSY if queue is full and request should be resubmitted later; + * other < 0 if an error occurred */ int crypto_ahash_final(struct ahash_request *req); @@ -447,8 +454,7 @@ int crypto_ahash_final(struct ahash_request *req); * crypto_ahash_update and crypto_ahash_final. The parameters have the same * meaning as discussed for those separate three functions. * - * Return: 0 if the message digest creation was successful; < 0 if an error - * occurred + * Return: see crypto_ahash_final() */ int crypto_ahash_digest(struct ahash_request *req); @@ -493,8 +499,7 @@ static inline int crypto_ahash_import(struct ahash_request *req, const void *in) * handle. Any potentially existing state created by previous operations is * discarded. * - * Return: 0 if the message digest initialization was successful; < 0 if an - * error occurred + * Return: see crypto_ahash_final() */ static inline int crypto_ahash_init(struct ahash_request *req) { @@ -510,8 +515,7 @@ static inline int crypto_ahash_init(struct ahash_request *req) * is pointed to by the scatter/gather list registered in the &ahash_request * handle * - * Return: 0 if the message digest update was successful; < 0 if an error - * occurred + * Return: see crypto_ahash_final() */ static inline int crypto_ahash_update(struct ahash_request *req) { -- cgit v1.2.3 From 4f0fc1600edbdb3612b931aa5076ca984f7ee8fe Mon Sep 17 00:00:00 2001 From: Gilad Ben-Yossef Date: Mon, 21 Aug 2017 13:51:28 +0300 Subject: crypto: sm3 - add OSCCA SM3 secure hash Add OSCCA SM3 secure hash (OSCCA GM/T 0004-2012 SM3) generic hash transformation. Signed-off-by: Gilad Ben-Yossef Signed-off-by: Herbert Xu --- include/crypto/sm3.h | 40 ++++++++++++++++ include/crypto/sm3_base.h | 117 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 include/crypto/sm3.h create mode 100644 include/crypto/sm3_base.h (limited to 'include') diff --git a/include/crypto/sm3.h b/include/crypto/sm3.h new file mode 100644 index 000000000000..1438942dc773 --- /dev/null +++ b/include/crypto/sm3.h @@ -0,0 +1,40 @@ +/* + * Common values for SM3 algorithm + */ + +#ifndef _CRYPTO_SM3_H +#define _CRYPTO_SM3_H + +#include + +#define SM3_DIGEST_SIZE 32 +#define SM3_BLOCK_SIZE 64 + +#define SM3_T1 0x79CC4519 +#define SM3_T2 0x7A879D8A + +#define SM3_IVA 0x7380166f +#define SM3_IVB 0x4914b2b9 +#define SM3_IVC 0x172442d7 +#define SM3_IVD 0xda8a0600 +#define SM3_IVE 0xa96f30bc +#define SM3_IVF 0x163138aa +#define SM3_IVG 0xe38dee4d +#define SM3_IVH 0xb0fb0e4e + +extern const u8 sm3_zero_message_hash[SM3_DIGEST_SIZE]; + +struct sm3_state { + u32 state[SM3_DIGEST_SIZE / 4]; + u64 count; + u8 buffer[SM3_BLOCK_SIZE]; +}; + +struct shash_desc; + +extern int crypto_sm3_update(struct shash_desc *desc, const u8 *data, + unsigned int len); + +extern int crypto_sm3_finup(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *hash); +#endif diff --git a/include/crypto/sm3_base.h b/include/crypto/sm3_base.h new file mode 100644 index 000000000000..256948e39296 --- /dev/null +++ b/include/crypto/sm3_base.h @@ -0,0 +1,117 @@ +/* + * sm3_base.h - core logic for SM3 implementations + * + * Copyright (C) 2017 ARM Limited or its affiliates. + * Written by Gilad Ben-Yossef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include + +typedef void (sm3_block_fn)(struct sm3_state *sst, u8 const *src, int blocks); + +static inline int sm3_base_init(struct shash_desc *desc) +{ + struct sm3_state *sctx = shash_desc_ctx(desc); + + sctx->state[0] = SM3_IVA; + sctx->state[1] = SM3_IVB; + sctx->state[2] = SM3_IVC; + sctx->state[3] = SM3_IVD; + sctx->state[4] = SM3_IVE; + sctx->state[5] = SM3_IVF; + sctx->state[6] = SM3_IVG; + sctx->state[7] = SM3_IVH; + sctx->count = 0; + + return 0; +} + +static inline int sm3_base_do_update(struct shash_desc *desc, + const u8 *data, + unsigned int len, + sm3_block_fn *block_fn) +{ + struct sm3_state *sctx = shash_desc_ctx(desc); + unsigned int partial = sctx->count % SM3_BLOCK_SIZE; + + sctx->count += len; + + if (unlikely((partial + len) >= SM3_BLOCK_SIZE)) { + int blocks; + + if (partial) { + int p = SM3_BLOCK_SIZE - partial; + + memcpy(sctx->buffer + partial, data, p); + data += p; + len -= p; + + block_fn(sctx, sctx->buffer, 1); + } + + blocks = len / SM3_BLOCK_SIZE; + len %= SM3_BLOCK_SIZE; + + if (blocks) { + block_fn(sctx, data, blocks); + data += blocks * SM3_BLOCK_SIZE; + } + partial = 0; + } + if (len) + memcpy(sctx->buffer + partial, data, len); + + return 0; +} + +static inline int sm3_base_do_finalize(struct shash_desc *desc, + sm3_block_fn *block_fn) +{ + const int bit_offset = SM3_BLOCK_SIZE - sizeof(__be64); + struct sm3_state *sctx = shash_desc_ctx(desc); + __be64 *bits = (__be64 *)(sctx->buffer + bit_offset); + unsigned int partial = sctx->count % SM3_BLOCK_SIZE; + + sctx->buffer[partial++] = 0x80; + if (partial > bit_offset) { + memset(sctx->buffer + partial, 0x0, SM3_BLOCK_SIZE - partial); + partial = 0; + + block_fn(sctx, sctx->buffer, 1); + } + + memset(sctx->buffer + partial, 0x0, bit_offset - partial); + *bits = cpu_to_be64(sctx->count << 3); + block_fn(sctx, sctx->buffer, 1); + + return 0; +} + +static inline int sm3_base_finish(struct shash_desc *desc, u8 *out) +{ + struct sm3_state *sctx = shash_desc_ctx(desc); + __be32 *digest = (__be32 *)out; + int i; + + for (i = 0; i < SM3_DIGEST_SIZE / sizeof(__be32); i++) + put_unaligned_be32(sctx->state[i], digest++); + + *sctx = (struct sm3_state){}; + return 0; +} -- cgit v1.2.3 From ef780324592dd639e4bfbc5b9bf8934b234b7c99 Mon Sep 17 00:00:00 2001 From: Corentin LABBE Date: Tue, 22 Aug 2017 10:08:08 +0200 Subject: crypto: gcm - add GCM IV size constant Many GCM users use directly GCM IV size instead of using some constant. This patch add all IV size constant used by GCM. Signed-off-by: Corentin Labbe Signed-off-by: Herbert Xu --- include/crypto/gcm.h | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 include/crypto/gcm.h (limited to 'include') diff --git a/include/crypto/gcm.h b/include/crypto/gcm.h new file mode 100644 index 000000000000..c50e057ea17e --- /dev/null +++ b/include/crypto/gcm.h @@ -0,0 +1,8 @@ +#ifndef _CRYPTO_GCM_H +#define _CRYPTO_GCM_H + +#define GCM_AES_IV_SIZE 12 +#define GCM_RFC4106_IV_SIZE 8 +#define GCM_RFC4543_IV_SIZE 8 + +#endif -- cgit v1.2.3 From cf5868c8a22dc2854b96e9569064bb92365549ca Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Fri, 8 Sep 2017 20:57:10 +0200 Subject: padata: ensure the reorder timer callback runs on the correct CPU The reorder timer function runs on the CPU where the timer interrupt was handled which is not necessarily one of the CPUs of the 'pcpu' CPU mask set. Ensure the padata_reorder() callback runs on the correct CPU, which is one in the 'pcpu' CPU mask set and, preferrably, the next expected one. Do so by comparing the current CPU with the expected target CPU. If they match, call padata_reorder() right away. If they differ, schedule a work item on the target CPU that does the padata_reorder() call for us. Signed-off-by: Mathias Krause Signed-off-by: Herbert Xu --- include/linux/padata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/padata.h b/include/linux/padata.h index 2f9c1f93b1ce..5c0175bbc179 100644 --- a/include/linux/padata.h +++ b/include/linux/padata.h @@ -85,6 +85,7 @@ struct padata_serial_queue { * @swork: work struct for serialization. * @pd: Backpointer to the internal control structure. * @work: work struct for parallelization. + * @reorder_work: work struct for reordering. * @num_obj: Number of objects that are processed by this cpu. * @cpu_index: Index of the cpu. */ @@ -93,6 +94,7 @@ struct padata_parallel_queue { struct padata_list reorder; struct parallel_data *pd; struct work_struct work; + struct work_struct reorder_work; atomic_t num_obj; int cpu_index; }; -- cgit v1.2.3 From 350ef88e7e922354f82a931897ad4a4ce6c686ff Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Fri, 8 Sep 2017 20:57:11 +0200 Subject: padata: ensure padata_do_serial() runs on the correct CPU If the algorithm we're parallelizing is asynchronous we might change CPUs between padata_do_parallel() and padata_do_serial(). However, we don't expect this to happen as we need to enqueue the padata object into the per-cpu reorder queue we took it from, i.e. the same-cpu's parallel queue. Ensure we're not switching CPUs for a given padata object by tracking the CPU within the padata object. If the serial callback gets called on the wrong CPU, defer invoking padata_reorder() via a kernel worker on the CPU we're expected to run on. Signed-off-by: Mathias Krause Signed-off-by: Herbert Xu --- include/linux/padata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/padata.h b/include/linux/padata.h index 5c0175bbc179..5d13d25da2c8 100644 --- a/include/linux/padata.h +++ b/include/linux/padata.h @@ -37,6 +37,7 @@ * @list: List entry, to attach to the padata lists. * @pd: Pointer to the internal control structure. * @cb_cpu: Callback cpu for serializatioon. + * @cpu: Cpu for parallelization. * @seq_nr: Sequence number of the parallelized data object. * @info: Used to pass information from the parallel to the serial function. * @parallel: Parallel execution function. @@ -46,6 +47,7 @@ struct padata_priv { struct list_head list; struct parallel_data *pd; int cb_cpu; + int cpu; int info; void (*parallel)(struct padata_priv *padata); void (*serial)(struct padata_priv *padata); -- cgit v1.2.3 From 6e97e08d4311d2413df0e891a10301bf4258fe3e Mon Sep 17 00:00:00 2001 From: Tudor-Dan Ambarus Date: Fri, 29 Sep 2017 12:13:08 +0300 Subject: crypto: ecdh - return unsigned value for crypto_ecdh_key_len() ECDH_KPP_SECRET_MIN_SIZE and params->key_size are both returning unsigned values. Signed-off-by: Tudor Ambarus Signed-off-by: Herbert Xu --- include/crypto/ecdh.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/crypto/ecdh.h b/include/crypto/ecdh.h index 1aff2a8a3a68..d696317c43a8 100644 --- a/include/crypto/ecdh.h +++ b/include/crypto/ecdh.h @@ -54,7 +54,7 @@ struct ecdh { * * Return: size of the key in bytes */ -int crypto_ecdh_key_len(const struct ecdh *params); +unsigned int crypto_ecdh_key_len(const struct ecdh *params); /** * crypto_ecdh_encode_key() - encode the private key -- cgit v1.2.3 From 5b3f3a8bede7d3af2dc9ea20b0ad971d4e5e83cc Mon Sep 17 00:00:00 2001 From: Tudor-Dan Ambarus Date: Fri, 29 Sep 2017 12:21:05 +0300 Subject: crypto: dh - return unsigned value for crypto_dh_key_len() DH_KPP_SECRET_MIN_SIZE and dh_data_size() are both returning unsigned values. Signed-off-by: Tudor Ambarus Signed-off-by: Herbert Xu --- include/crypto/dh.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/crypto/dh.h b/include/crypto/dh.h index f638998fb6d0..71e1bb24d79f 100644 --- a/include/crypto/dh.h +++ b/include/crypto/dh.h @@ -53,7 +53,7 @@ struct dh { * * Return: size of the key in bytes */ -int crypto_dh_key_len(const struct dh *params); +unsigned int crypto_dh_key_len(const struct dh *params); /** * crypto_dh_encode_key() - encode the private key -- cgit v1.2.3 From acfc587810bea08fdd62c9d5ed7cefe8be874a4f Mon Sep 17 00:00:00 2001 From: Harsh Jain Date: Sun, 8 Oct 2017 13:37:20 +0530 Subject: crypto: gf128mul - The x8_ble multiplication functions It multiply GF(2^128) elements in the ble format. It will be used by chelsio driver to speed up gf multiplication. Signed-off-by: Harsh Jain Signed-off-by: Herbert Xu --- include/crypto/gf128mul.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/crypto/gf128mul.h b/include/crypto/gf128mul.h index 0977fb18ff68..fa0a63d298dc 100644 --- a/include/crypto/gf128mul.h +++ b/include/crypto/gf128mul.h @@ -227,7 +227,7 @@ struct gf128mul_4k *gf128mul_init_4k_lle(const be128 *g); struct gf128mul_4k *gf128mul_init_4k_bbe(const be128 *g); void gf128mul_4k_lle(be128 *a, const struct gf128mul_4k *t); void gf128mul_4k_bbe(be128 *a, const struct gf128mul_4k *t); - +void gf128mul_x8_ble(le128 *r, const le128 *x); static inline void gf128mul_free_4k(struct gf128mul_4k *t) { kzfree(t); -- cgit v1.2.3 From ada69a1639eca54ff74d839a6513c43db8d57d70 Mon Sep 17 00:00:00 2001 From: Gilad Ben-Yossef Date: Wed, 18 Oct 2017 08:00:38 +0100 Subject: crypto: introduce crypto wait for async op Invoking a possibly async. crypto op and waiting for completion while correctly handling backlog processing is a common task in the crypto API implementation and outside users of it. This patch adds a generic implementation for doing so in preparation for using it across the board instead of hand rolled versions. Signed-off-by: Gilad Ben-Yossef CC: Eric Biggers CC: Jonathan Cameron Signed-off-by: Herbert Xu --- include/linux/crypto.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'include') diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 84da9978e951..78508ca4b108 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -24,6 +24,7 @@ #include #include #include +#include /* * Autoloaded crypto modules should only use a prefixed name to avoid allowing @@ -467,6 +468,45 @@ struct crypto_alg { struct module *cra_module; } CRYPTO_MINALIGN_ATTR; +/* + * A helper struct for waiting for completion of async crypto ops + */ +struct crypto_wait { + struct completion completion; + int err; +}; + +/* + * Macro for declaring a crypto op async wait object on stack + */ +#define DECLARE_CRYPTO_WAIT(_wait) \ + struct crypto_wait _wait = { \ + COMPLETION_INITIALIZER_ONSTACK((_wait).completion), 0 } + +/* + * Async ops completion helper functioons + */ +void crypto_req_done(struct crypto_async_request *req, int err); + +static inline int crypto_wait_req(int err, struct crypto_wait *wait) +{ + switch (err) { + case -EINPROGRESS: + case -EBUSY: + wait_for_completion(&wait->completion); + reinit_completion(&wait->completion); + err = wait->err; + break; + }; + + return err; +} + +static inline void crypto_init_wait(struct crypto_wait *wait) +{ + init_completion(&wait->completion); +} + /* * Algorithm registration interface. */ -- cgit v1.2.3 From 2c3f8b162106a7d12097d02eb22459f57fab8247 Mon Sep 17 00:00:00 2001 From: Gilad Ben-Yossef Date: Wed, 18 Oct 2017 08:00:39 +0100 Subject: crypto: algif - move to generic async completion algif starts several async crypto ops and waits for their completion. Move it over to generic code doing the same. Signed-off-by: Gilad Ben-Yossef Signed-off-by: Herbert Xu --- include/crypto/if_alg.h | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'include') diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h index 75ec9c662268..6abf0a3604dc 100644 --- a/include/crypto/if_alg.h +++ b/include/crypto/if_alg.h @@ -40,11 +40,6 @@ struct alg_sock { void *private; }; -struct af_alg_completion { - struct completion completion; - int err; -}; - struct af_alg_control { struct af_alg_iv *iv; int op; @@ -152,7 +147,7 @@ struct af_alg_ctx { void *iv; size_t aead_assoclen; - struct af_alg_completion completion; + struct crypto_wait wait; size_t used; size_t rcvused; @@ -177,19 +172,11 @@ void af_alg_link_sg(struct af_alg_sgl *sgl_prev, struct af_alg_sgl *sgl_new); int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con); -int af_alg_wait_for_completion(int err, struct af_alg_completion *completion); -void af_alg_complete(struct crypto_async_request *req, int err); - static inline struct alg_sock *alg_sk(struct sock *sk) { return (struct alg_sock *)sk; } -static inline void af_alg_init_completion(struct af_alg_completion *completion) -{ - init_completion(&completion->completion); -} - /** * Size of available buffer for sending data from user space to kernel. * -- cgit v1.2.3 From 85a2dea4bdbfa7565818ca094d08e838cf62da77 Mon Sep 17 00:00:00 2001 From: Gilad Ben-Yossef Date: Wed, 18 Oct 2017 08:00:41 +0100 Subject: crypto: drbg - move to generic async completion DRBG is starting an async. crypto op and waiting for it complete. Move it over to generic code doing the same. The code now also passes CRYPTO_TFM_REQ_MAY_SLEEP flag indicating crypto request memory allocation may use GFP_KERNEL which should be perfectly fine as the code is obviously sleeping for the completion of the request any way. Signed-off-by: Gilad Ben-Yossef Signed-off-by: Herbert Xu --- include/crypto/drbg.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h index 22f884c97387..8f941102af36 100644 --- a/include/crypto/drbg.h +++ b/include/crypto/drbg.h @@ -126,8 +126,7 @@ struct drbg_state { __u8 *ctr_null_value; /* CTR mode aligned zero buf */ __u8 *outscratchpadbuf; /* CTR mode output scratchpad */ __u8 *outscratchpad; /* CTR mode aligned outbuf */ - struct completion ctr_completion; /* CTR mode async handler */ - int ctr_async_err; /* CTR mode async error */ + struct crypto_wait ctr_wait; /* CTR mode async wait obj */ bool seeded; /* DRBG fully seeded? */ bool pr; /* Prediction resistance enabled? */ -- cgit v1.2.3