crypto: ccp - Fix XTS-AES-128 support on v5 CCPs
Version 5 CCPs have some new requirements for XTS-AES: the type field must be specified, and the key requires 512 bits, with each part occupying 256 bits and padded with zeroes. cc: <stable@vger.kernel.org> # 4.9.x+ Signed-off-by: Gary R Hook <ghook@amd.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support
|
* AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 Advanced Micro Devices, Inc.
|
* Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
|
||||||
*
|
*
|
||||||
|
* Author: Gary R Hook <gary.hook@amd.com>
|
||||||
* Author: Tom Lendacky <thomas.lendacky@amd.com>
|
* Author: Tom Lendacky <thomas.lendacky@amd.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@@ -164,6 +165,7 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
|
|||||||
memset(&rctx->cmd, 0, sizeof(rctx->cmd));
|
memset(&rctx->cmd, 0, sizeof(rctx->cmd));
|
||||||
INIT_LIST_HEAD(&rctx->cmd.entry);
|
INIT_LIST_HEAD(&rctx->cmd.entry);
|
||||||
rctx->cmd.engine = CCP_ENGINE_XTS_AES_128;
|
rctx->cmd.engine = CCP_ENGINE_XTS_AES_128;
|
||||||
|
rctx->cmd.u.xts.type = CCP_AES_TYPE_128;
|
||||||
rctx->cmd.u.xts.action = (encrypt) ? CCP_AES_ACTION_ENCRYPT
|
rctx->cmd.u.xts.action = (encrypt) ? CCP_AES_ACTION_ENCRYPT
|
||||||
: CCP_AES_ACTION_DECRYPT;
|
: CCP_AES_ACTION_DECRYPT;
|
||||||
rctx->cmd.u.xts.unit_size = unit_size;
|
rctx->cmd.u.xts.unit_size = unit_size;
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ union ccp_function {
|
|||||||
#define CCP_AES_MODE(p) ((p)->aes.mode)
|
#define CCP_AES_MODE(p) ((p)->aes.mode)
|
||||||
#define CCP_AES_TYPE(p) ((p)->aes.type)
|
#define CCP_AES_TYPE(p) ((p)->aes.type)
|
||||||
#define CCP_XTS_SIZE(p) ((p)->aes_xts.size)
|
#define CCP_XTS_SIZE(p) ((p)->aes_xts.size)
|
||||||
|
#define CCP_XTS_TYPE(p) ((p)->aes_xts.type)
|
||||||
#define CCP_XTS_ENCRYPT(p) ((p)->aes_xts.encrypt)
|
#define CCP_XTS_ENCRYPT(p) ((p)->aes_xts.encrypt)
|
||||||
#define CCP_DES3_SIZE(p) ((p)->des3.size)
|
#define CCP_DES3_SIZE(p) ((p)->des3.size)
|
||||||
#define CCP_DES3_ENCRYPT(p) ((p)->des3.encrypt)
|
#define CCP_DES3_ENCRYPT(p) ((p)->des3.encrypt)
|
||||||
@@ -344,6 +345,7 @@ static int ccp5_perform_xts_aes(struct ccp_op *op)
|
|||||||
CCP5_CMD_PROT(&desc) = 0;
|
CCP5_CMD_PROT(&desc) = 0;
|
||||||
|
|
||||||
function.raw = 0;
|
function.raw = 0;
|
||||||
|
CCP_XTS_TYPE(&function) = op->u.xts.type;
|
||||||
CCP_XTS_ENCRYPT(&function) = op->u.xts.action;
|
CCP_XTS_ENCRYPT(&function) = op->u.xts.action;
|
||||||
CCP_XTS_SIZE(&function) = op->u.xts.unit_size;
|
CCP_XTS_SIZE(&function) = op->u.xts.unit_size;
|
||||||
CCP5_CMD_FUNCTION(&desc) = function.raw;
|
CCP5_CMD_FUNCTION(&desc) = function.raw;
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
#define CCP_AES_CTX_SB_COUNT 1
|
#define CCP_AES_CTX_SB_COUNT 1
|
||||||
|
|
||||||
#define CCP_XTS_AES_KEY_SB_COUNT 1
|
#define CCP_XTS_AES_KEY_SB_COUNT 1
|
||||||
|
#define CCP5_XTS_AES_KEY_SB_COUNT 2
|
||||||
#define CCP_XTS_AES_CTX_SB_COUNT 1
|
#define CCP_XTS_AES_CTX_SB_COUNT 1
|
||||||
|
|
||||||
#define CCP_DES3_KEY_SB_COUNT 1
|
#define CCP_DES3_KEY_SB_COUNT 1
|
||||||
@@ -498,6 +499,7 @@ struct ccp_aes_op {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ccp_xts_aes_op {
|
struct ccp_xts_aes_op {
|
||||||
|
enum ccp_aes_type type;
|
||||||
enum ccp_aes_action action;
|
enum ccp_aes_action action;
|
||||||
enum ccp_xts_aes_unit_size unit_size;
|
enum ccp_xts_aes_unit_size unit_size;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1038,6 +1038,8 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q,
|
|||||||
struct ccp_op op;
|
struct ccp_op op;
|
||||||
unsigned int unit_size, dm_offset;
|
unsigned int unit_size, dm_offset;
|
||||||
bool in_place = false;
|
bool in_place = false;
|
||||||
|
unsigned int sb_count;
|
||||||
|
enum ccp_aes_type aestype;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch (xts->unit_size) {
|
switch (xts->unit_size) {
|
||||||
@@ -1061,7 +1063,9 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xts->key_len != AES_KEYSIZE_128)
|
if (xts->key_len == AES_KEYSIZE_128)
|
||||||
|
aestype = CCP_AES_TYPE_128;
|
||||||
|
else
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!xts->final && (xts->src_len & (AES_BLOCK_SIZE - 1)))
|
if (!xts->final && (xts->src_len & (AES_BLOCK_SIZE - 1)))
|
||||||
@@ -1083,23 +1087,44 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q,
|
|||||||
op.sb_key = cmd_q->sb_key;
|
op.sb_key = cmd_q->sb_key;
|
||||||
op.sb_ctx = cmd_q->sb_ctx;
|
op.sb_ctx = cmd_q->sb_ctx;
|
||||||
op.init = 1;
|
op.init = 1;
|
||||||
|
op.u.xts.type = aestype;
|
||||||
op.u.xts.action = xts->action;
|
op.u.xts.action = xts->action;
|
||||||
op.u.xts.unit_size = xts->unit_size;
|
op.u.xts.unit_size = xts->unit_size;
|
||||||
|
|
||||||
/* All supported key sizes fit in a single (32-byte) SB entry
|
/* A version 3 device only supports 128-bit keys, which fits into a
|
||||||
* and must be in little endian format. Use the 256-bit byte
|
* single SB entry. A version 5 device uses a 512-bit vector, so two
|
||||||
* swap passthru option to convert from big endian to little
|
* SB entries.
|
||||||
* endian.
|
|
||||||
*/
|
*/
|
||||||
|
if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0))
|
||||||
|
sb_count = CCP_XTS_AES_KEY_SB_COUNT;
|
||||||
|
else
|
||||||
|
sb_count = CCP5_XTS_AES_KEY_SB_COUNT;
|
||||||
ret = ccp_init_dm_workarea(&key, cmd_q,
|
ret = ccp_init_dm_workarea(&key, cmd_q,
|
||||||
CCP_XTS_AES_KEY_SB_COUNT * CCP_SB_BYTES,
|
sb_count * CCP_SB_BYTES,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
dm_offset = CCP_SB_BYTES - AES_KEYSIZE_128;
|
if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0)) {
|
||||||
ccp_set_dm_area(&key, dm_offset, xts->key, 0, xts->key_len);
|
/* All supported key sizes must be in little endian format.
|
||||||
ccp_set_dm_area(&key, 0, xts->key, dm_offset, xts->key_len);
|
* Use the 256-bit byte swap passthru option to convert from
|
||||||
|
* big endian to little endian.
|
||||||
|
*/
|
||||||
|
dm_offset = CCP_SB_BYTES - AES_KEYSIZE_128;
|
||||||
|
ccp_set_dm_area(&key, dm_offset, xts->key, 0, xts->key_len);
|
||||||
|
ccp_set_dm_area(&key, 0, xts->key, xts->key_len, xts->key_len);
|
||||||
|
} else {
|
||||||
|
/* Version 5 CCPs use a 512-bit space for the key: each portion
|
||||||
|
* occupies 256 bits, or one entire slot, and is zero-padded.
|
||||||
|
*/
|
||||||
|
unsigned int pad;
|
||||||
|
|
||||||
|
dm_offset = CCP_SB_BYTES;
|
||||||
|
pad = dm_offset - xts->key_len;
|
||||||
|
ccp_set_dm_area(&key, pad, xts->key, 0, xts->key_len);
|
||||||
|
ccp_set_dm_area(&key, dm_offset + pad, xts->key, xts->key_len,
|
||||||
|
xts->key_len);
|
||||||
|
}
|
||||||
ret = ccp_copy_to_sb(cmd_q, &key, op.jobid, op.sb_key,
|
ret = ccp_copy_to_sb(cmd_q, &key, op.jobid, op.sb_key,
|
||||||
CCP_PASSTHRU_BYTESWAP_256BIT);
|
CCP_PASSTHRU_BYTESWAP_256BIT);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* AMD Cryptographic Coprocessor (CCP) driver
|
* AMD Cryptographic Coprocessor (CCP) driver
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
|
* Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
|
||||||
*
|
*
|
||||||
* Author: Tom Lendacky <thomas.lendacky@amd.com>
|
* Author: Tom Lendacky <thomas.lendacky@amd.com>
|
||||||
* Author: Gary R Hook <gary.hook@amd.com>
|
* Author: Gary R Hook <gary.hook@amd.com>
|
||||||
@@ -229,6 +229,7 @@ enum ccp_xts_aes_unit_size {
|
|||||||
* AES operation the new IV overwrites the old IV.
|
* AES operation the new IV overwrites the old IV.
|
||||||
*/
|
*/
|
||||||
struct ccp_xts_aes_engine {
|
struct ccp_xts_aes_engine {
|
||||||
|
enum ccp_aes_type type;
|
||||||
enum ccp_aes_action action;
|
enum ccp_aes_action action;
|
||||||
enum ccp_xts_aes_unit_size unit_size;
|
enum ccp_xts_aes_unit_size unit_size;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user