Commit ccebcf3f authored by Gary R Hook's avatar Gary R Hook Committed by Herbert Xu

crypto: ccp - Add SHA-2 384- and 512-bit support

Incorporate 384-bit and 512-bit hashing for a version 5 CCP
device
Signed-off-by: default avatarGary R Hook <gary.hook@amd.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 146c8688
...@@ -146,6 +146,12 @@ static int ccp_do_sha_update(struct ahash_request *req, unsigned int nbytes, ...@@ -146,6 +146,12 @@ static int ccp_do_sha_update(struct ahash_request *req, unsigned int nbytes,
case CCP_SHA_TYPE_256: case CCP_SHA_TYPE_256:
rctx->cmd.u.sha.ctx_len = SHA256_DIGEST_SIZE; rctx->cmd.u.sha.ctx_len = SHA256_DIGEST_SIZE;
break; 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: default:
/* Should never get here */ /* Should never get here */
break; break;
...@@ -393,6 +399,22 @@ static struct ccp_sha_def sha_algs[] = { ...@@ -393,6 +399,22 @@ static struct ccp_sha_def sha_algs[] = {
.digest_size = SHA256_DIGEST_SIZE, .digest_size = SHA256_DIGEST_SIZE,
.block_size = SHA256_BLOCK_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, static int ccp_register_hmac_alg(struct list_head *head,
......
...@@ -137,9 +137,11 @@ struct ccp_aes_cmac_exp_ctx { ...@@ -137,9 +137,11 @@ struct ccp_aes_cmac_exp_ctx {
u8 buf[AES_BLOCK_SIZE]; u8 buf[AES_BLOCK_SIZE];
}; };
/***** SHA related defines *****/ /* SHA-related defines
#define MAX_SHA_CONTEXT_SIZE SHA256_DIGEST_SIZE * These values must be large enough to accommodate any variant
#define MAX_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE */
#define MAX_SHA_CONTEXT_SIZE SHA512_DIGEST_SIZE
#define MAX_SHA_BLOCK_SIZE SHA512_BLOCK_SIZE
struct ccp_sha_ctx { struct ccp_sha_ctx {
struct scatterlist opad_sg; struct scatterlist opad_sg;
......
...@@ -41,6 +41,20 @@ static const __be32 ccp_sha256_init[SHA256_DIGEST_SIZE / sizeof(__be32)] = { ...@@ -41,6 +41,20 @@ static const __be32 ccp_sha256_init[SHA256_DIGEST_SIZE / sizeof(__be32)] = {
cpu_to_be32(SHA256_H6), cpu_to_be32(SHA256_H7), cpu_to_be32(SHA256_H6), cpu_to_be32(SHA256_H7),
}; };
static const __be64 ccp_sha384_init[SHA512_DIGEST_SIZE / sizeof(__be64)] = {
cpu_to_be64(SHA384_H0), cpu_to_be64(SHA384_H1),
cpu_to_be64(SHA384_H2), cpu_to_be64(SHA384_H3),
cpu_to_be64(SHA384_H4), cpu_to_be64(SHA384_H5),
cpu_to_be64(SHA384_H6), cpu_to_be64(SHA384_H7),
};
static const __be64 ccp_sha512_init[SHA512_DIGEST_SIZE / sizeof(__be64)] = {
cpu_to_be64(SHA512_H0), cpu_to_be64(SHA512_H1),
cpu_to_be64(SHA512_H2), cpu_to_be64(SHA512_H3),
cpu_to_be64(SHA512_H4), cpu_to_be64(SHA512_H5),
cpu_to_be64(SHA512_H6), cpu_to_be64(SHA512_H7),
};
#define CCP_NEW_JOBID(ccp) ((ccp->vdata->version == CCP_VERSION(3, 0)) ? \ #define CCP_NEW_JOBID(ccp) ((ccp->vdata->version == CCP_VERSION(3, 0)) ? \
ccp_gen_jobid(ccp) : 0) ccp_gen_jobid(ccp) : 0)
...@@ -955,6 +969,18 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) ...@@ -955,6 +969,18 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
return -EINVAL; return -EINVAL;
block_size = SHA256_BLOCK_SIZE; block_size = SHA256_BLOCK_SIZE;
break; break;
case CCP_SHA_TYPE_384:
if (cmd_q->ccp->vdata->version < CCP_VERSION(4, 0)
|| sha->ctx_len < SHA384_DIGEST_SIZE)
return -EINVAL;
block_size = SHA384_BLOCK_SIZE;
break;
case CCP_SHA_TYPE_512:
if (cmd_q->ccp->vdata->version < CCP_VERSION(4, 0)
|| sha->ctx_len < SHA512_DIGEST_SIZE)
return -EINVAL;
block_size = SHA512_BLOCK_SIZE;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -1042,6 +1068,21 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) ...@@ -1042,6 +1068,21 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
sb_count = 1; sb_count = 1;
ooffset = ioffset = 0; ooffset = ioffset = 0;
break; break;
case CCP_SHA_TYPE_384:
digest_size = SHA384_DIGEST_SIZE;
init = (void *) ccp_sha384_init;
ctx_size = SHA512_DIGEST_SIZE;
sb_count = 2;
ioffset = 0;
ooffset = 2 * CCP_SB_BYTES - SHA384_DIGEST_SIZE;
break;
case CCP_SHA_TYPE_512:
digest_size = SHA512_DIGEST_SIZE;
init = (void *) ccp_sha512_init;
ctx_size = SHA512_DIGEST_SIZE;
sb_count = 2;
ooffset = ioffset = 0;
break;
default: default:
ret = -EINVAL; ret = -EINVAL;
goto e_data; goto e_data;
...@@ -1060,6 +1101,11 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) ...@@ -1060,6 +1101,11 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
op.u.sha.type = sha->type; op.u.sha.type = sha->type;
op.u.sha.msg_bits = sha->msg_bits; op.u.sha.msg_bits = sha->msg_bits;
/* For SHA1/224/256 the context fits in a single (32-byte) SB entry;
* SHA384/512 require 2 adjacent SB slots, with the right half in the
* first slot, and the left half in the second. Each portion must then
* be in little endian format: use the 256-bit byte swap option.
*/
ret = ccp_init_dm_workarea(&ctx, cmd_q, sb_count * CCP_SB_BYTES, ret = ccp_init_dm_workarea(&ctx, cmd_q, sb_count * CCP_SB_BYTES,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
if (ret) if (ret)
...@@ -1071,6 +1117,13 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) ...@@ -1071,6 +1117,13 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
case CCP_SHA_TYPE_256: case CCP_SHA_TYPE_256:
memcpy(ctx.address + ioffset, init, ctx_size); memcpy(ctx.address + ioffset, init, ctx_size);
break; break;
case CCP_SHA_TYPE_384:
case CCP_SHA_TYPE_512:
memcpy(ctx.address + ctx_size / 2, init,
ctx_size / 2);
memcpy(ctx.address, init + ctx_size / 2,
ctx_size / 2);
break;
default: default:
ret = -EINVAL; ret = -EINVAL;
goto e_ctx; goto e_ctx;
...@@ -1137,6 +1190,15 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) ...@@ -1137,6 +1190,15 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
sha->ctx, 0, sha->ctx, 0,
digest_size); digest_size);
break; break;
case CCP_SHA_TYPE_384:
case CCP_SHA_TYPE_512:
ccp_get_dm_area(&ctx, 0,
sha->ctx, LSB_ITEM_SIZE - ooffset,
LSB_ITEM_SIZE);
ccp_get_dm_area(&ctx, LSB_ITEM_SIZE + ooffset,
sha->ctx, 0,
LSB_ITEM_SIZE - ooffset);
break;
default: default:
ret = -EINVAL; ret = -EINVAL;
goto e_ctx; goto e_ctx;
...@@ -1174,6 +1236,16 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) ...@@ -1174,6 +1236,16 @@ static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
ctx.address + ooffset, ctx.address + ooffset,
digest_size); digest_size);
break; break;
case CCP_SHA_TYPE_384:
case CCP_SHA_TYPE_512:
memcpy(hmac_buf + block_size,
ctx.address + LSB_ITEM_SIZE + ooffset,
LSB_ITEM_SIZE);
memcpy(hmac_buf + block_size +
(LSB_ITEM_SIZE - ooffset),
ctx.address,
LSB_ITEM_SIZE);
break;
default: default:
ret = -EINVAL; ret = -EINVAL;
goto e_ctx; goto e_ctx;
......
...@@ -249,6 +249,8 @@ enum ccp_sha_type { ...@@ -249,6 +249,8 @@ enum ccp_sha_type {
CCP_SHA_TYPE_1 = 1, CCP_SHA_TYPE_1 = 1,
CCP_SHA_TYPE_224, CCP_SHA_TYPE_224,
CCP_SHA_TYPE_256, CCP_SHA_TYPE_256,
CCP_SHA_TYPE_384,
CCP_SHA_TYPE_512,
CCP_SHA_TYPE__LAST, CCP_SHA_TYPE__LAST,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment