Enable hashing and ciphers for v5 CCP
v2 cover Enable hashing and ciphers for v5 CCP
The following series implements new function for a version 5 CCP: Support for SHA-2, wiring of RSA using the updated framework, additional RSA features for new devices, AES GCM mode, and Triple-DES in ECB and CBC mode.
---
Gary R Hook (9):
crypto: ccp - Fix handling of RSA exponent on a v5 device
crypto: ccp - Update the command queue on errors
crypto: ccp - Simplify some buffer management routines
crypto: ccp - Add SHA-2 support
crypto: Move RSA+MPI constructs into an #include file
crypto: ccp - Add support for RSA on the CCP
crypto: ccp - Enhance RSA support for a v5 CCP
crypto: ccp - Enable support for AES GCM on v5 CCPs
crypto: ccp - Enable 3DES function on v5 CCPs
crypto/rsa.c | 16 - drivers/crypto/ccp/Makefile | 3 drivers/crypto/ccp/ccp-crypto-aes-galois.c | 257 ++++++++++ drivers/crypto/ccp/ccp-crypto-des3.c | 254 ++++++++++ drivers/crypto/ccp/ccp-crypto-main.c | 41 ++ drivers/crypto/ccp/ccp-crypto-rsa.c | 297 +++++++++++ drivers/crypto/ccp/ccp-crypto-sha.c | 22 + drivers/crypto/ccp/ccp-crypto.h | 75 +++ drivers/crypto/ccp/ccp-dev-v3.c | 2 drivers/crypto/ccp/ccp-dev-v5.c | 67 ++- drivers/crypto/ccp/ccp-dev.h | 17 + drivers/crypto/ccp/ccp-ops.c | 740 ++++++++++++++++++++++++---- include/crypto/internal/rsa.h | 17 + include/linux/ccp.h | 69 +++ 14 files changed, 1736 insertions(+), 141 deletions(-) create mode 100644 drivers/crypto/ccp/ccp-crypto-aes-galois.c create mode 100644 drivers/crypto/ccp/ccp-crypto-des3.c create mode 100644 drivers/crypto/ccp/ccp-crypto-rsa.c
--
This is my day job.
Follow me on FB/IG/Twitter: @grhphotographer and @grhookphoto
PATCH v2 1/9 crypto: ccp - Fix handling of RSA exponent on a v5 device
The exponent size in the ccp_op structure is in bits. A v5 CCP requires the exponent size to be in bytes, so convert the size from bits to bytes when populating the descriptor.
The current code references the exponent in memory, but these fields have not been set since the exponent is actually store in the LSB. Populate the descriptor with the LSB location (address).
--- drivers/crypto/ccp/ccp-dev-v5.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/crypto/ccp/ccp-dev-v5.c +5 -5
@@ -403,7 +403,7 @@ static int ccp5_perform_rsa(struct ccp_op *op)CCP5_CMD_PROT (&desc) =0 ; function.raw =0 ; -CCP_RSA_SIZE (&function) = op->u.rsa.mod_size; +CCP_RSA_SIZE (&function) = op->u.rsa.mod_size >>3 ;CCP5_CMD_FUNCTION (&desc) = function.raw;CCP5_CMD_LEN (&desc) = op->u.rsa.input_len;
@@ -418,10 +418,10 @@ static int ccp5_perform_rsa(struct ccp_op *op)CCP5_CMD_DST_HI (&desc) =ccp_addr_hi (&op->dst.u.dma);CCP5_CMD_DST_MEM (&desc) =CCP_MEMTYPE_SYSTEM ; -/* Key (Exponent) is in external memory */ -CCP5_CMD_KEY_LO (&desc) =ccp_addr_lo (&op->exp.u.dma); -CCP5_CMD_KEY_HI (&desc) =ccp_addr_hi (&op->exp.u.dma); -CCP5_CMD_KEY_MEM (&desc) =CCP_MEMTYPE_SYSTEM ; +/* Exponent is in LSB memory */ +CCP5_CMD_KEY_LO (&desc) = op->sb_key *LSB_ITEM_SIZE ; +CCP5_CMD_KEY_HI (&desc) =0 ; +CCP5_CMD_KEY_MEM (&desc) =CCP_MEMTYPE_SB ;return ccp5_do_cmd (&desc, op->cmd_q); }
PATCH v2 2/9 crypto: ccp - Update the command queue on errors
In reply to Gary R HookMove the command queue tail pointer when an error is detected. Always return the error.
--- drivers/crypto/ccp/ccp-dev-v5.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/crypto/ccp/ccp-dev-v5.c +5 -2
@@ -250,17 +250,20 @@ static int ccp5_do_cmd(struct ccp5_desc *desc, ret =wait_event_interruptible (cmd_q->int_queue, cmd_q->int_rcvd);if (ret || cmd_q->cmd_error) { +/* Log the error and flush the queue by +* moving the head pointer +*/ if (cmd_q->cmd_error)ccp_log_error (cmd_q->ccp, cmd_q->cmd_error); -/* A version 5 device doesn't use Job IDs... */ +iowrite32 (tail, cmd_q->reg_head_lo);if (!ret) ret = -EIO ; } cmd_q->int_rcvd =0 ; } -return 0 ; +return ret; }static int ccp5_perform_aes (struct ccp_op *op)
PATCH v2 3/9 crypto: ccp - Simplify some buffer management routines
In reply to Gary R HookThe reverse-get/set functions can be simplified by eliminating unused code.
--- drivers/crypto/ccp/ccp-ops.c | 142 +++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 86 deletions(-)
drivers/crypto/ccp/ccp-ops.c +56 -86
@@ -184,62 +184,46 @@ static void ccp_get_dm_area(struct ccp_dm_workarea *wa, unsigned int wa_offset, }static int ccp_reverse_set_dm_area (struct ccp_dm_workarea *wa, +unsigned int wa_offset,struct scatterlist *sg, -unsigned int len,unsigned int se_len, -bool sign_extend) +unsigned int sg_offset, +unsigned int len) { -unsigned int nbytes, sg_offset, dm_offset, sb_len, i; -u8 buffer[CCP_REVERSE_BUF_SIZE ]; - -if (WARN_ON (se_len >sizeof (buffer))) -return -EINVAL ; - - sg_offset = len; - dm_offset =0 ; - nbytes = len; -while (nbytes) { - sb_len = min_t(unsigned int, nbytes, se_len); - sg_offset -= sb_len; - -scatterwalk_map_and_copy (buffer, sg, sg_offset, sb_len,0 ); -for (i =0 ; i < sb_len; i++) - wa->address[dm_offset + i] = buffer[sb_len - i -1 ]; - - dm_offset += sb_len; - nbytes -= sb_len; - -if ((sb_len != se_len) && sign_extend) { -/* Must sign-extend to nearest sign-extend length */ -if (wa->address[dm_offset -1 ] &0x80 ) -memset (wa->address + dm_offset,0xff , - se_len - sb_len); - } +u8 *p, *q; + +ccp_set_dm_area (wa, wa_offset, sg, sg_offset, len); + + p = wa->address + wa_offset; + q = p + len -1 ; +while (p < q) { + *p = *p ^ *q; + *q = *p ^ *q; + *p = *p ^ *q; + p++; + q--; } -return 0 ; }static void ccp_reverse_get_dm_area (struct ccp_dm_workarea *wa, +unsigned int wa_offset,struct scatterlist *sg, +unsigned int sg_offset,unsigned int len) { -unsigned int nbytes, sg_offset, dm_offset, sb_len, i; -u8 buffer[CCP_REVERSE_BUF_SIZE ]; - - sg_offset =0 ; - dm_offset = len; - nbytes = len; -while (nbytes) { - sb_len = min_t(unsigned int, nbytes, sizeof(buffer)); - dm_offset -= sb_len; - -for (i =0 ; i < sb_len; i++) - buffer[sb_len - i -1 ] = wa->address[dm_offset + i]; -scatterwalk_map_and_copy (buffer, sg, sg_offset, sb_len,1 ); - - sg_offset += sb_len; - nbytes -= sb_len; +u8 *p, *q; + + p = wa->address + wa_offset; + q = p + len -1 ; +while (p < q) { + *p = *p ^ *q; + *q = *p ^ *q; + *p = *p ^ *q; + p++; + q--; } + +ccp_get_dm_area (wa, wa_offset, sg, sg_offset, len); }static void ccp_free_data (struct ccp_data *data,struct ccp_cmd_queue *cmd_q)
@@ -1261,8 +1245,7 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)if (ret) goto e_sb; - ret =ccp_reverse_set_dm_area (&exp, rsa->exp, rsa->exp_len, -CCP_SB_BYTES , false); + ret =ccp_reverse_set_dm_area (&exp,0 , rsa->exp,0 , rsa->exp_len);if (ret) goto e_exp; ret = ccp_copy_to_sb(cmd_q, &exp, op.jobid, op.sb_key,
@@ -1280,16 +1263,12 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)if (ret) goto e_exp; - ret =ccp_reverse_set_dm_area (&src, rsa->mod, rsa->mod_len, -CCP_SB_BYTES , false); + ret =ccp_reverse_set_dm_area (&src,0 , rsa->mod,0 , rsa->mod_len);if (ret) goto e_src; - src.address += o_len;/* Adjust the address for the copy operation */ - ret =ccp_reverse_set_dm_area (&src, rsa->src, rsa->src_len, -CCP_SB_BYTES , false); + ret =ccp_reverse_set_dm_area (&src, o_len, rsa->src,0 , rsa->src_len);if (ret) goto e_src; - src.address -= o_len;/* Reset the address to original value */ /* Prepare the output area for the operation */ ret = ccp_init_data(&dst, cmd_q, rsa->dst, rsa->mod_len,
@@ -1314,7 +1293,7 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) goto e_dst; } -ccp_reverse_get_dm_area (&dst.dm_wa, rsa->dst, rsa->mod_len); +ccp_reverse_get_dm_area (&dst.dm_wa,0 , rsa->dst,0 , rsa->mod_len); e_dst:ccp_free_data (&dst, cmd_q);
@@ -1566,25 +1545,22 @@ static int ccp_run_ecc_mm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) save = src.address;/* Copy the ECC modulus */ - ret =ccp_reverse_set_dm_area (&src, ecc->mod, ecc->mod_len, -CCP_ECC_OPERAND_SIZE , false); + ret =ccp_reverse_set_dm_area (&src,0 , ecc->mod,0 , ecc->mod_len);if (ret) goto e_src; src.address +=CCP_ECC_OPERAND_SIZE ;/* Copy the first operand */ - ret =ccp_reverse_set_dm_area (&src, ecc->u.mm.operand_1, - ecc->u.mm.operand_1_len, -CCP_ECC_OPERAND_SIZE , false); + ret =ccp_reverse_set_dm_area (&src,0 , ecc->u.mm.operand_1,0 , + ecc->u.mm.operand_1_len);if (ret) goto e_src; src.address +=CCP_ECC_OPERAND_SIZE ;if (ecc->function !=CCP_ECC_FUNCTION_MINV_384BIT ) {/* Copy the second operand */ - ret =ccp_reverse_set_dm_area (&src, ecc->u.mm.operand_2, - ecc->u.mm.operand_2_len, -CCP_ECC_OPERAND_SIZE , false); + ret =ccp_reverse_set_dm_area (&src,0 , ecc->u.mm.operand_2,0 , + ecc->u.mm.operand_2_len);if (ret) goto e_src; src.address +=CCP_ECC_OPERAND_SIZE ;
@@ -1623,7 +1599,8 @@ static int ccp_run_ecc_mm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) }/* Save the ECC result */ -ccp_reverse_get_dm_area (&dst, ecc->u.mm.result,CCP_ECC_MODULUS_BYTES ); +ccp_reverse_get_dm_area (&dst,0 , ecc->u.mm.result,0 , +CCP_ECC_MODULUS_BYTES ); e_dst:ccp_dm_free (&dst);
@@ -1691,22 +1668,19 @@ static int ccp_run_ecc_pm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) save = src.address;/* Copy the ECC modulus */ - ret =ccp_reverse_set_dm_area (&src, ecc->mod, ecc->mod_len, -CCP_ECC_OPERAND_SIZE , false); + ret =ccp_reverse_set_dm_area (&src,0 , ecc->mod,0 , ecc->mod_len);if (ret) goto e_src; src.address +=CCP_ECC_OPERAND_SIZE ;/* Copy the first point X and Y coordinate */ - ret =ccp_reverse_set_dm_area (&src, ecc->u.pm.point_1.x, - ecc->u.pm.point_1.x_len, -CCP_ECC_OPERAND_SIZE , false); + ret =ccp_reverse_set_dm_area (&src,0 , ecc->u.pm.point_1.x,0 , + ecc->u.pm.point_1.x_len);if (ret) goto e_src; src.address +=CCP_ECC_OPERAND_SIZE ; - ret =ccp_reverse_set_dm_area (&src, ecc->u.pm.point_1.y, - ecc->u.pm.point_1.y_len, -CCP_ECC_OPERAND_SIZE , false); + ret =ccp_reverse_set_dm_area (&src,0 , ecc->u.pm.point_1.y,0 , + ecc->u.pm.point_1.y_len);if (ret) goto e_src; src.address +=CCP_ECC_OPERAND_SIZE ;
@@ -1717,15 +1691,13 @@ static int ccp_run_ecc_pm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)if (ecc->function ==CCP_ECC_FUNCTION_PADD_384BIT ) {/* Copy the second point X and Y coordinate */ - ret =ccp_reverse_set_dm_area (&src, ecc->u.pm.point_2.x, - ecc->u.pm.point_2.x_len, -CCP_ECC_OPERAND_SIZE , false); + ret =ccp_reverse_set_dm_area (&src,0 , ecc->u.pm.point_2.x,0 , + ecc->u.pm.point_2.x_len);if (ret) goto e_src; src.address +=CCP_ECC_OPERAND_SIZE ; - ret =ccp_reverse_set_dm_area (&src, ecc->u.pm.point_2.y, - ecc->u.pm.point_2.y_len, -CCP_ECC_OPERAND_SIZE , false); + ret =ccp_reverse_set_dm_area (&src,0 , ecc->u.pm.point_2.y,0 , + ecc->u.pm.point_2.y_len);if (ret) goto e_src; src.address +=CCP_ECC_OPERAND_SIZE ;
@@ -1735,19 +1707,17 @@ static int ccp_run_ecc_pm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) src.address +=CCP_ECC_OPERAND_SIZE ; }else {/* Copy the Domain "a" parameter */ - ret =ccp_reverse_set_dm_area (&src, ecc->u.pm.domain_a, - ecc->u.pm.domain_a_len, -CCP_ECC_OPERAND_SIZE , false); + ret =ccp_reverse_set_dm_area (&src,0 , ecc->u.pm.domain_a,0 , + ecc->u.pm.domain_a_len);if (ret) goto e_src; src.address +=CCP_ECC_OPERAND_SIZE ;if (ecc->function ==CCP_ECC_FUNCTION_PMUL_384BIT ) {/* Copy the scalar value */ - ret =ccp_reverse_set_dm_area (&src, ecc->u.pm.scalar, - ecc->u.pm.scalar_len, -CCP_ECC_OPERAND_SIZE , - false); + ret =ccp_reverse_set_dm_area (&src,0 , + ecc->u.pm.scalar,0 , + ecc->u.pm.scalar_len);if (ret) goto e_src; src.address +=CCP_ECC_OPERAND_SIZE ;
@@ -1792,10 +1762,10 @@ static int ccp_run_ecc_pm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) save = dst.address;/* Save the ECC result X and Y coordinates */ -ccp_reverse_get_dm_area (&dst, ecc->u.pm.result.x, +ccp_reverse_get_dm_area (&dst,0 , ecc->u.pm.result.x,0 ,CCP_ECC_MODULUS_BYTES ); dst.address +=CCP_ECC_OUTPUT_SIZE ; -ccp_reverse_get_dm_area (&dst, ecc->u.pm.result.y, +ccp_reverse_get_dm_area (&dst,0 , ecc->u.pm.result.y,0 ,CCP_ECC_MODULUS_BYTES ); dst.address +=CCP_ECC_OUTPUT_SIZE ;
PATCH v2 4/9 crypto: ccp - Add SHA-2 support
In reply to Gary R HookIncorporate 384-bit and 512-bit hashing for a version 5 CCP device
--- drivers/crypto/ccp/ccp-crypto-sha.c | 22 +++++++++++ drivers/crypto/ccp/ccp-crypto.h | 8 ++-- drivers/crypto/ccp/ccp-ops.c | 72 +++++++++++++++++++++++++++++++++++ include/linux/ccp.h | 2 + 4 files changed, 101 insertions(+), 3 deletions(-)
drivers/crypto/ccp/ccp-crypto-sha.c +22 -0
@@ -146,6 +146,12 @@ static int ccp_do_sha_update(struct ahash_request *req, unsigned int nbytes,case CCP_SHA_TYPE_256 : rctx->cmd.u.sha.ctx_len =SHA256_DIGEST_SIZE ;break ; +case CCP_SHA_TYPE_384 : + rctx->cmd.u.sha.ctx_len =SHA384_DIGEST_SIZE ; +break ; +case CCP_SHA_TYPE_512 : + rctx->cmd.u.sha.ctx_len =SHA512_DIGEST_SIZE ; +break ;default :/* Should never get here */ break ;
@@ -393,6 +399,22 @@ struct ccp_sha_def { .digest_size = SHA256_DIGEST_SIZE, .block_size = SHA256_BLOCK_SIZE, }, + { + .version = CCP_VERSION(5, 0), + .name = "sha384", + .drv_name = "sha384-ccp", + .type = CCP_SHA_TYPE_384, + .digest_size = SHA384_DIGEST_SIZE, + .block_size = SHA384_BLOCK_SIZE, + }, + { + .version = CCP_VERSION(5, 0), + .name = "sha512", + .drv_name = "sha512-ccp", + .type = CCP_SHA_TYPE_512, + .digest_size = SHA512_DIGEST_SIZE, + .block_size = SHA512_BLOCK_SIZE, + }, }; static int ccp_register_hmac_alg(struct list_head *head,
drivers/crypto/ccp/ccp-crypto.h +5 -3
@@ -137,9 +137,11 @@ struct ccp_aes_cmac_exp_ctx {u8 buf[AES_BLOCK_SIZE ]; }; -/***** SHA related defines *****/ -#define MAX_SHA_CONTEXT_SIZE SHA256_DIGEST_SIZE -#define MAX_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE +/* SHA-related defines +* These values must be large enough to accommodate any variant +*/ +#define MAX_SHA_CONTEXT_SIZE SHA512_DIGEST_SIZE +#define MAX_SHA_BLOCK_SIZE SHA512_BLOCK_SIZEstruct ccp_sha_ctx {struct scatterlist opad_sg;
drivers/crypto/ccp/ccp-ops.c +72 -0
114 lines not on this page · raw message
include/linux/ccp.h +2 -0
@@ -249,6 +249,8 @@ enum ccp_sha_type {CCP_SHA_TYPE_1 =1 ,CCP_SHA_TYPE_224 ,CCP_SHA_TYPE_256 , +CCP_SHA_TYPE_384 , +CCP_SHA_TYPE_512 , CCP_SHA_TYPE__LAST, };
PATCH v2 5/9 crypto: Move RSA+MPI constructs into an #include file
In reply to Gary R HookRSA support of general use, but dependent upon MPI, should go into internal/rsa.h
--- crypto/rsa.c | 16 ---------------- include/crypto/internal/rsa.h | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 16 deletions(-)
crypto/rsa.c +0 -16
@@ -16,12 +16,6 @@#include <crypto/akcipher.h> #include <crypto/algapi.h> -struct rsa_mpi_key { -MPI n; -MPI e; -MPI d; -}; -/* * RSAEP function [RFC3447 sec 5.1.1] * c = m^e mod n;
@@ -240,16 +234,6 @@ static int rsa_verify(struct akcipher_request *req)return ret; } -static void rsa_free_mpi_key (struct rsa_mpi_key *key) -{ -mpi_free (key->d); -mpi_free (key->e); -mpi_free (key->n); - key->d =NULL ; - key->e =NULL ; - key->n =NULL ; -} -static int rsa_check_key_length (unsigned int len) {switch (len) {
include/crypto/internal/rsa.h +17 -0
@@ -13,6 +13,7 @@#ifndef _RSA_HELPER_#define _RSA_HELPER_#include <linux/types.h> +#include <linux/mpi.h> /** * rsa_key - RSA key structure
@@ -52,6 +53,22 @@ struct rsa_key {size_t qinv_sz; }; +struct rsa_mpi_key { +MPI n; +MPI e; +MPI d; +}; + +static inline void rsa_free_mpi_key (struct rsa_mpi_key *key) +{ +mpi_free (key->d); +mpi_free (key->e); +mpi_free (key->n); + key->d =NULL ; + key->e =NULL ; + key->n =NULL ; +} +int rsa_parse_pub_key (struct rsa_key *rsa_key,const void *key,unsigned int key_len);
PATCH v2 6/9 crypto: ccp - Add support for RSA on the CCP
In reply to Gary R HookWire up the CCP as an RSA cipher provider.
--- drivers/crypto/ccp/Makefile | 1 drivers/crypto/ccp/ccp-crypto-main.c | 19 ++ drivers/crypto/ccp/ccp-crypto-rsa.c | 294 ++++++++++++++++++++++++++++++++++ drivers/crypto/ccp/ccp-crypto.h | 32 ++++ include/linux/ccp.h | 1 5 files changed, 346 insertions(+), 1 deletion(-) create mode 100644 drivers/crypto/ccp/ccp-crypto-rsa.c
drivers/crypto/ccp/Makefile +1 -0
@@ -12,4 +12,5 @@ ccp-crypto-objs := ccp-crypto-main.o \ ccp-crypto-aes.o \ ccp-crypto-aes-cmac.o \ ccp-crypto-aes-xts.o \ + ccp-crypto-rsa.o \ ccp-crypto-sha.o
drivers/crypto/ccp/ccp-crypto-main.c +19 -0
@@ -17,6 +17,7 @@#include <linux/ccp.h> #include <linux/scatterlist.h> #include <crypto/internal/hash.h> +#include <crypto/internal/akcipher.h> #include "ccp-crypto.h"
@@ -33,9 +34,14 @@module_param (sha_disable, uint,0444 );MODULE_PARM_DESC (sha_disable,"Disable use of SHA - any non-zero value" ); +static unsigned int rsa_disable; +module_param (rsa_disable, uint,0444 ); +MODULE_PARM_DESC (rsa_disable,"Disable use of RSA - any non-zero value" ); +/* List heads for the supported algorithms */ static LIST_HEAD (hash_algs);static LIST_HEAD (cipher_algs); +static LIST_HEAD (akcipher_algs);/* For any tfm, requests for that tfm must be returned on the order * received. With multiple queues available, the CCP can process more
@@ -343,6 +349,12 @@ static int ccp_register_algs(void)return ret; } +if (!rsa_disable) { + ret =ccp_register_rsa_algs (&akcipher_algs); +if (ret) +return ret; + } +return 0 ; }
@@ -350,6 +362,7 @@ static void ccp_unregister_algs(void) {struct ccp_crypto_ahash_alg *ahash_alg, *ahash_tmp;struct ccp_crypto_ablkcipher_alg *ablk_alg, *ablk_tmp; +struct ccp_crypto_akcipher_alg *ak_alg, *ak_tmp;list_for_each_entry_safe (ahash_alg, ahash_tmp, &hash_algs, entry) {crypto_unregister_ahash (&ahash_alg->alg);
@@ -362,6 +375,12 @@ static void ccp_unregister_algs(void)list_del (&ablk_alg->entry);kfree (ablk_alg); } + +list_for_each_entry_safe (ak_alg, ak_tmp, &akcipher_algs, entry) { +crypto_unregister_akcipher (&ak_alg->alg); +list_del (&ak_alg->entry); +kfree (ak_alg); + } }static int ccp_crypto_init (void )
drivers/crypto/ccp/ccp-crypto-rsa.c new file +294 -0
294 lines not on this page · raw message
drivers/crypto/ccp/ccp-crypto.h +32 -0
@@ -22,6 +22,8 @@#include <crypto/ctr.h> #include <crypto/hash.h> #include <crypto/sha.h> +#include <crypto/akcipher.h> +#include <crypto/internal/rsa.h> #define CCP_CRA_PRIORITY 300
@@ -46,6 +48,12 @@ struct ccp_crypto_ahash_alg {struct ahash_alg alg; }; +struct ccp_crypto_akcipher_alg { +struct list_head entry; + +struct akcipher_alg alg; +}; +static inline struct ccp_crypto_ablkcipher_alg *ccp_crypto_ablkcipher_alg (struct crypto_tfm *tfm) {
@@ -194,12 +202,35 @@ struct ccp_sha_exp_ctx {u8 buf[MAX_SHA_BLOCK_SIZE ]; }; +/***** RSA related defines *****/ + +struct ccp_rsa_ctx { +unsigned int key_len;/* in bits */ +struct rsa_mpi_key pkey; +struct scatterlist e_sg; +u8 *e_buf; +unsigned int e_len; +struct scatterlist n_sg; +u8 *n_buf; +unsigned int n_len; +struct scatterlist d_sg; +u8 *d_buf; +unsigned int d_len; +}; + +struct ccp_rsa_req_ctx { +struct ccp_cmd cmd; +}; + +#define CCP_RSA_MAXMOD (4 * 1024 / 8) +/***** Common Context Structure *****/ struct ccp_ctx {int (*complete)(struct crypto_async_request *req,int ret);union {struct ccp_aes_ctx aes; +struct ccp_rsa_ctx rsa;struct ccp_sha_ctx sha; } u; };
@@ -213,5 +244,6 @@ struct scatterlist *ccp_crypto_sg_table_add(struct sg_table *table,int ccp_register_aes_cmac_algs (struct list_head *head);int ccp_register_aes_xts_algs (struct list_head *head);int ccp_register_sha_algs (struct list_head *head); +int ccp_register_rsa_algs (struct list_head *head);#endif
include/linux/ccp.h +0 -1
@@ -20,7 +20,6 @@#include <crypto/aes.h> #include <crypto/sha.h> -struct ccp_device ;struct ccp_cmd ;
Herbert Xu
maintainerRe: [PATCH V2 6/9] crypto: ccp - Add support for RSA on the CCP
drivers/crypto/ccp/ccp-crypto-rsa.c line 142
Quoted 6 lines · Gary R Hook
drivers/crypto/ccp/ccp-crypto-rsa.c new file +5
-0+ ctx->u.rsa.pkey.e =mpi_read_raw_data (raw_key.e, raw_key.e_sz); +if (!ctx->u.rsa.pkey.e) + goto e_ret; + ctx->u.rsa.e_buf =mpi_get_buffer (ctx->u.rsa.pkey.e, + &ctx->u.rsa.e_len,NULL );
You're converting a raw integer into an MPI and then back again. Why?
In general drivers shouldn't touch the MPI stuff at all since the hardware generally deals with raw integers.
Cheers,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH V2 6/9] crypto: ccp - Add support for RSA on the CCP
Quoted 11 lines · Herbert Xu
drivers/crypto/ccp/ccp-crypto-rsa.c line 142
Quoted 6 lines · Gary R Hook
drivers/crypto/ccp/ccp-crypto-rsa.c new file +5
-0+ ctx->u.rsa.pkey.e =mpi_read_raw_data (raw_key.e, raw_key.e_sz); +if (!ctx->u.rsa.pkey.e) + goto e_ret; + ctx->u.rsa.e_buf =mpi_get_buffer (ctx->u.rsa.pkey.e, + &ctx->u.rsa.e_len,NULL );You're converting a raw integer into an MPI and then back again. Why?
Quoted 2 lines
In general drivers shouldn't touch the MPI stuff at all since the hardware generally deals with raw integers.
D'oh! Yes, I see now what I missed before.
I will send out another patch set.
Signature · 3 lines
This is my day job. Follow me at: IG/Twitter/Facebook: @grhookphoto IG/Twitter/Facebook: @grhphotographer
PATCH v2 7/9 crypto: ccp - Enhance RSA support for a v5 CCP
In reply to Gary R HookTake advantage of the increased RSA key size support in the v5 CCP.
--- drivers/crypto/ccp/ccp-crypto-rsa.c | 5 ++ drivers/crypto/ccp/ccp-crypto.h | 1 drivers/crypto/ccp/ccp-dev-v3.c | 1 drivers/crypto/ccp/ccp-dev-v5.c | 10 +++-- drivers/crypto/ccp/ccp-dev.h | 2 + drivers/crypto/ccp/ccp-ops.c | 76 ++++++++++++++++++++++------------- 6 files changed, 61 insertions(+), 34 deletions(-)
drivers/crypto/ccp/ccp-crypto-rsa.c +4 -1
@@ -45,7 +45,10 @@ static int ccp_rsa_complete(struct crypto_async_request *async_req, int ret)static int ccp_rsa_maxsize (struct crypto_akcipher *tfm) { -return CCP_RSA_MAXMOD ; +if (ccp_version () >CCP_VERSION (3 ,0 )) +return CCP5_RSA_MAXMOD ; +else +return CCP_RSA_MAXMOD ; }static int ccp_rsa_crypt (struct akcipher_request *req,bool encrypt)
drivers/crypto/ccp/ccp-crypto.h +1 -0
@@ -223,6 +223,7 @@ struct ccp_rsa_req_ctx { };#define CCP_RSA_MAXMOD (4 * 1024 / 8) +#define CCP5_RSA_MAXMOD (16 * 1024 / 8)/***** Common Context Structure *****/ struct ccp_ctx {
drivers/crypto/ccp/ccp-dev-v3.c +1 -0
@@ -571,4 +571,5 @@ static irqreturn_t ccp_irq_handler(int irq, void *data) .perform = &ccp3_actions, .bar = 2, .offset = 0x20000, + .rsamax = CCP_RSA_MAX_WIDTH, };
drivers/crypto/ccp/ccp-dev-v5.c +6 -4
@@ -421,10 +421,10 @@ static int ccp5_perform_rsa(struct ccp_op *op)CCP5_CMD_DST_HI (&desc) =ccp_addr_hi (&op->dst.u.dma);CCP5_CMD_DST_MEM (&desc) =CCP_MEMTYPE_SYSTEM ; -/* Exponent is in LSB memory */ -CCP5_CMD_KEY_LO (&desc) = op->sb_key *LSB_ITEM_SIZE ; -CCP5_CMD_KEY_HI (&desc) =0 ; -CCP5_CMD_KEY_MEM (&desc) =CCP_MEMTYPE_SB ; +/* Key (Exponent) is in external memory */ +CCP5_CMD_KEY_LO (&desc) =ccp_addr_lo (&op->exp.u.dma); +CCP5_CMD_KEY_HI (&desc) =ccp_addr_hi (&op->exp.u.dma); +CCP5_CMD_KEY_MEM (&desc) =CCP_MEMTYPE_SYSTEM ;return ccp5_do_cmd (&desc, op->cmd_q); }
@@ -1013,6 +1013,7 @@ static void ccp5other_config(struct ccp_device *ccp) .perform = &ccp5_actions, .bar = 2, .offset = 0x0, + .rsamax = CCP5_RSA_MAX_WIDTH, };const struct ccp_vdata ccpv5b = {
@@ -1021,4 +1022,5 @@ static void ccp5other_config(struct ccp_device *ccp) .perform = &ccp5_actions, .bar = 2, .offset = 0x0, + .rsamax = CCP5_RSA_MAX_WIDTH, };
drivers/crypto/ccp/ccp-dev.h +2 -0
@@ -193,6 +193,7 @@#define CCP_SHA_SB_COUNT 1#define CCP_RSA_MAX_WIDTH 4096 +#define CCP5_RSA_MAX_WIDTH 16384#define CCP_PASSTHRU_BLOCKSIZE 256#define CCP_PASSTHRU_MASKSIZE 32
@@ -638,6 +639,7 @@ struct ccp_vdata {const struct ccp_actions *perform;const unsigned int bar;const unsigned int offset; +const unsigned int rsamax; };extern const struct ccp_vdata ccpv3;
drivers/crypto/ccp/ccp-ops.c +47 -29
109 lines not on this page · raw message
PATCH v2 8/9 crypto: ccp - Enable support for AES GCM on v5 CCPs
In reply to Gary R HookA version 5 device provides the primitive commands required for AES GCM. This patch adds support for en/decryption.
--- drivers/crypto/ccp/Makefile | 1 drivers/crypto/ccp/ccp-crypto-aes-galois.c | 257 ++++++++++++++++++++++++++++ drivers/crypto/ccp/ccp-crypto-main.c | 12 + drivers/crypto/ccp/ccp-crypto.h | 14 ++ drivers/crypto/ccp/ccp-dev-v5.c | 2 drivers/crypto/ccp/ccp-dev.h | 1 drivers/crypto/ccp/ccp-ops.c | 252 +++++++++++++++++++++++++++ include/linux/ccp.h | 9 + 8 files changed, 548 insertions(+) create mode 100644 drivers/crypto/ccp/ccp-crypto-aes-galois.c
drivers/crypto/ccp/Makefile +1 -0
@@ -13,4 +13,5 @@ ccp-crypto-objs := ccp-crypto-main.o \ ccp-crypto-aes-cmac.o \ ccp-crypto-aes-xts.o \ ccp-crypto-rsa.o \ + ccp-crypto-aes-galois.o \ ccp-crypto-sha.o
drivers/crypto/ccp/ccp-crypto-aes-galois.c new file +257 -0
257 lines not on this page · raw message
drivers/crypto/ccp/ccp-crypto-main.c +12 -0
@@ -42,6 +42,7 @@static LIST_HEAD (hash_algs);static LIST_HEAD (cipher_algs);static LIST_HEAD (akcipher_algs); +static LIST_HEAD (aead_algs);/* For any tfm, requests for that tfm must be returned on the order * received. With multiple queues available, the CCP can process more
@@ -341,6 +342,10 @@ static int ccp_register_algs(void) ret =ccp_register_aes_xts_algs (&cipher_algs);if (ret)return ret; + + ret =ccp_register_aes_aeads (&aead_algs); +if (ret) +return ret; }if (!sha_disable) {
@@ -363,6 +368,7 @@ static void ccp_unregister_algs(void)struct ccp_crypto_ahash_alg *ahash_alg, *ahash_tmp;struct ccp_crypto_ablkcipher_alg *ablk_alg, *ablk_tmp;struct ccp_crypto_akcipher_alg *ak_alg, *ak_tmp; +struct ccp_crypto_aead *aead_alg, *aead_tmp;list_for_each_entry_safe (ahash_alg, ahash_tmp, &hash_algs, entry) {crypto_unregister_ahash (&ahash_alg->alg);
@@ -381,6 +387,12 @@ static void ccp_unregister_algs(void)list_del (&ak_alg->entry);kfree (ak_alg); } + +list_for_each_entry_safe (aead_alg, aead_tmp, &aead_algs, entry) { +crypto_unregister_aead (&aead_alg->alg); +list_del (&aead_alg->entry); +kfree (aead_alg); + } }static int ccp_crypto_init (void )
drivers/crypto/ccp/ccp-crypto.h +14 -0
@@ -19,6 +19,8 @@#include <linux/ccp.h> #include <crypto/algapi.h> #include <crypto/aes.h> +#include <crypto/internal/aead.h> +#include <crypto/aead.h> #include <crypto/ctr.h> #include <crypto/hash.h> #include <crypto/sha.h>
@@ -35,6 +37,14 @@ struct ccp_crypto_ablkcipher_alg {struct crypto_alg alg; }; +struct ccp_crypto_aead { +struct list_head entry; + +u32 mode; + +struct aead_alg alg; +}; +struct ccp_crypto_ahash_alg {struct list_head entry;
@@ -103,6 +113,9 @@ struct ccp_aes_req_ctx {struct scatterlist iv_sg;u8 iv[AES_BLOCK_SIZE ]; +struct scatterlist tag_sg; +u8 tag[AES_BLOCK_SIZE ]; +/* Fields used for RFC3686 requests */ u8 *rfc3686_info;u8 rfc3686_iv[AES_BLOCK_SIZE ];
@@ -244,6 +257,7 @@ struct scatterlist *ccp_crypto_sg_table_add(struct sg_table *table,int ccp_register_aes_algs (struct list_head *head);int ccp_register_aes_cmac_algs (struct list_head *head);int ccp_register_aes_xts_algs (struct list_head *head); +int ccp_register_aes_aeads (struct list_head *head);int ccp_register_sha_algs (struct list_head *head);int ccp_register_rsa_algs (struct list_head *head);
drivers/crypto/ccp/ccp-dev-v5.c +2 -0
@@ -289,6 +289,8 @@ static int ccp5_perform_aes(struct ccp_op *op)CCP_AES_TYPE (&function) = op->u.aes.type;if (op->u.aes.mode ==CCP_AES_MODE_CFB )CCP_AES_SIZE (&function) =0x7f ; +if ((op->u.aes.mode ==CCP_AES_MODE_GCTR ) && op->eom) +CCP_AES_SIZE (&function) = op->u.aes.size;CCP5_CMD_FUNCTION (&desc) = function.raw;
drivers/crypto/ccp/ccp-dev.h +1 -0
@@ -467,6 +467,7 @@ struct ccp_aes_op {enum ccp_aes_type type;enum ccp_aes_mode mode;enum ccp_aes_action action; +unsigned int size; };struct ccp_xts_aes_op {
drivers/crypto/ccp/ccp-ops.c +252 -0
264 lines not on this page · raw message
include/linux/ccp.h +9 -0
@@ -122,6 +122,10 @@ enum ccp_aes_mode {CCP_AES_MODE_CFB ,CCP_AES_MODE_CTR ,CCP_AES_MODE_CMAC , +CCP_AES_MODE_GHASH , +CCP_AES_MODE_GCTR , +CCP_AES_MODE_GCM , +CCP_AES_MODE_GMAC , CCP_AES_MODE__LAST, };
@@ -136,6 +140,9 @@ enum ccp_aes_action {CCP_AES_ACTION_ENCRYPT , CCP_AES_ACTION__LAST, }; +/* Overloaded field */ +#define CCP_AES_GHASHAAD CCP_AES_ACTION_DECRYPT +#define CCP_AES_GHASHFINAL CCP_AES_ACTION_ENCRYPT/** * struct ccp_aes_engine - CCP AES operation
@@ -180,6 +187,8 @@ struct ccp_aes_engine {struct scatterlist *cmac_key;/* K1/K2 cmac key required for * final cmac cmd */ u32 cmac_key_len;/* In bytes */ + +u32 aad_len;/* In bytes */ };/***** XTS-AES engine *****/
PATCH v2 9/9 crypto: ccp - Enable 3DES function on v5 CCPs
In reply to Gary R HookWire up support for Triple DES in ECB mode.
--- drivers/crypto/ccp/Makefile | 1 drivers/crypto/ccp/ccp-crypto-des3.c | 254 ++++++++++++++++++++++++++++++++++ drivers/crypto/ccp/ccp-crypto-main.c | 10 + drivers/crypto/ccp/ccp-crypto.h | 20 +++ drivers/crypto/ccp/ccp-dev-v3.c | 1 drivers/crypto/ccp/ccp-dev-v5.c | 54 +++++++ drivers/crypto/ccp/ccp-dev.h | 14 ++ drivers/crypto/ccp/ccp-ops.c | 198 +++++++++++++++++++++++++++ include/linux/ccp.h | 57 +++++++- 9 files changed, 606 insertions(+), 3 deletions(-) create mode 100644 drivers/crypto/ccp/ccp-crypto-des3.c
drivers/crypto/ccp/Makefile +1 -0
@@ -14,4 +14,5 @@ ccp-crypto-objs := ccp-crypto-main.o \ ccp-crypto-aes-xts.o \ ccp-crypto-rsa.o \ ccp-crypto-aes-galois.o \ + ccp-crypto-des3.o \ ccp-crypto-sha.o
drivers/crypto/ccp/ccp-crypto-des3.c new file +254 -0
254 lines not on this page · raw message
drivers/crypto/ccp/ccp-crypto-main.c +10 -0
@@ -38,6 +38,10 @@module_param (rsa_disable, uint,0444 );MODULE_PARM_DESC (rsa_disable,"Disable use of RSA - any non-zero value" ); +static unsigned int des3_disable; +module_param (des3_disable, uint,0444 ); +MODULE_PARM_DESC (des3_disable,"Disable use of 3DES - any non-zero value" ); +/* List heads for the supported algorithms */ static LIST_HEAD (hash_algs);static LIST_HEAD (cipher_algs);
@@ -348,6 +352,12 @@ static int ccp_register_algs(void)return ret; } +if (!des3_disable) { + ret =ccp_register_des3_algs (&cipher_algs); +if (ret) +return ret; + } +if (!sha_disable) { ret =ccp_register_sha_algs (&hash_algs);if (ret)
drivers/crypto/ccp/ccp-crypto.h +20 -0
@@ -158,6 +158,24 @@ struct ccp_aes_cmac_exp_ctx {u8 buf[AES_BLOCK_SIZE ]; }; +/***** 3DES related defines *****/ +struct ccp_des3_ctx { +enum ccp_engine engine; +enum ccp_des3_type type; +enum ccp_des3_mode mode; + +struct scatterlist key_sg; +unsigned int key_len; +u8 key[AES_MAX_KEY_SIZE ]; +}; + +struct ccp_des3_req_ctx { +struct scatterlist iv_sg; +u8 iv[AES_BLOCK_SIZE ]; + +struct ccp_cmd cmd; +}; +/* SHA-related defines * These values must be large enough to accommodate any variant */
@@ -246,6 +264,7 @@ struct ccp_ctx {struct ccp_aes_ctx aes;struct ccp_rsa_ctx rsa;struct ccp_sha_ctx sha; +struct ccp_des3_ctx des3; } u; };
@@ -260,5 +279,6 @@ struct scatterlist *ccp_crypto_sg_table_add(struct sg_table *table,int ccp_register_aes_aeads (struct list_head *head);int ccp_register_sha_algs (struct list_head *head);int ccp_register_rsa_algs (struct list_head *head); +int ccp_register_des3_algs (struct list_head *head);#endif
drivers/crypto/ccp/ccp-dev-v3.c +1 -0
@@ -553,6 +553,7 @@ static irqreturn_t ccp_irq_handler(int irq, void *data)static const struct ccp_actions ccp3_actions = { .aes = ccp_perform_aes, .xts_aes = ccp_perform_xts_aes, + .des3 =NULL , .sha = ccp_perform_sha, .rsa = ccp_perform_rsa, .passthru = ccp_perform_passthru,
drivers/crypto/ccp/ccp-dev-v5.c +54 -0
90 lines not on this page · raw message
drivers/crypto/ccp/ccp-dev.h +12 -2
@@ -190,6 +190,9 @@#define CCP_XTS_AES_KEY_SB_COUNT 1#define CCP_XTS_AES_CTX_SB_COUNT 1 +#define CCP_DES3_KEY_SB_COUNT 1 +#define CCP_DES3_CTX_SB_COUNT 1 +#define CCP_SHA_SB_COUNT 1#define CCP_RSA_MAX_WIDTH 4096
@@ -475,6 +478,12 @@ struct ccp_xts_aes_op {enum ccp_xts_aes_unit_size unit_size; }; +struct ccp_des3_op { +enum ccp_des3_type type; +enum ccp_des3_mode mode; +enum ccp_des3_action action; +}; +struct ccp_sha_op {enum ccp_sha_type type;u64 msg_bits;
@@ -512,6 +521,7 @@ struct ccp_op {union {struct ccp_aes_op aes;struct ccp_xts_aes_op xts; +struct ccp_des3_op des3;struct ccp_sha_op sha;struct ccp_rsa_op rsa;struct ccp_passthru_op passthru;
@@ -620,13 +630,13 @@ struct ccp5_desc {struct ccp_actions {int (*aes)(struct ccp_op *);int (*xts_aes)(struct ccp_op *); +int (*des3)(struct ccp_op *);int (*sha)(struct ccp_op *);int (*rsa)(struct ccp_op *);int (*passthru)(struct ccp_op *);int (*ecc)(struct ccp_op *);u32 (*sballoc)(struct ccp_cmd_queue *,unsigned int ); -void (*sbfree)(struct ccp_cmd_queue *,unsigned int , -unsigned int ); +void (*sbfree)(struct ccp_cmd_queue *,unsigned int ,unsigned int );unsigned int (*get_free_slots)(struct ccp_cmd_queue *);int (*init)(struct ccp_device *);void (*destroy)(struct ccp_device *);
drivers/crypto/ccp/ccp-ops.c +198 -0
216 lines not on this page · raw message
include/linux/ccp.h +56 -1
75 lines not on this page · raw message