mirror of https://gitee.com/openkylin/linux.git
crypto: atmel-tdes - Map driver data flags to Mode Register
Simplifies the configuration of the TDES IP. Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
7d0979e2df
commit
848572f817
|
@ -40,20 +40,23 @@
|
||||||
#define ATMEL_TDES_PRIORITY 300
|
#define ATMEL_TDES_PRIORITY 300
|
||||||
|
|
||||||
/* TDES flags */
|
/* TDES flags */
|
||||||
#define TDES_FLAGS_MODE_MASK 0x00ff
|
/* Reserve bits [17:16], [13:12], [2:0] for AES Mode Register */
|
||||||
#define TDES_FLAGS_ENCRYPT BIT(0)
|
#define TDES_FLAGS_ENCRYPT TDES_MR_CYPHER_ENC
|
||||||
#define TDES_FLAGS_CBC BIT(1)
|
#define TDES_FLAGS_OPMODE_MASK (TDES_MR_OPMOD_MASK | TDES_MR_CFBS_MASK)
|
||||||
#define TDES_FLAGS_CFB BIT(2)
|
#define TDES_FLAGS_ECB TDES_MR_OPMOD_ECB
|
||||||
#define TDES_FLAGS_CFB8 BIT(3)
|
#define TDES_FLAGS_CBC TDES_MR_OPMOD_CBC
|
||||||
#define TDES_FLAGS_CFB16 BIT(4)
|
#define TDES_FLAGS_OFB TDES_MR_OPMOD_OFB
|
||||||
#define TDES_FLAGS_CFB32 BIT(5)
|
#define TDES_FLAGS_CFB64 (TDES_MR_OPMOD_CFB | TDES_MR_CFBS_64b)
|
||||||
#define TDES_FLAGS_CFB64 BIT(6)
|
#define TDES_FLAGS_CFB32 (TDES_MR_OPMOD_CFB | TDES_MR_CFBS_32b)
|
||||||
#define TDES_FLAGS_OFB BIT(7)
|
#define TDES_FLAGS_CFB16 (TDES_MR_OPMOD_CFB | TDES_MR_CFBS_16b)
|
||||||
|
#define TDES_FLAGS_CFB8 (TDES_MR_OPMOD_CFB | TDES_MR_CFBS_8b)
|
||||||
|
|
||||||
#define TDES_FLAGS_INIT BIT(16)
|
#define TDES_FLAGS_MODE_MASK (TDES_FLAGS_OPMODE_MASK | TDES_FLAGS_ENCRYPT)
|
||||||
#define TDES_FLAGS_FAST BIT(17)
|
|
||||||
#define TDES_FLAGS_BUSY BIT(18)
|
#define TDES_FLAGS_INIT BIT(3)
|
||||||
#define TDES_FLAGS_DMA BIT(19)
|
#define TDES_FLAGS_FAST BIT(4)
|
||||||
|
#define TDES_FLAGS_BUSY BIT(5)
|
||||||
|
#define TDES_FLAGS_DMA BIT(6)
|
||||||
|
|
||||||
#define ATMEL_TDES_QUEUE_LENGTH 50
|
#define ATMEL_TDES_QUEUE_LENGTH 50
|
||||||
|
|
||||||
|
@ -287,35 +290,15 @@ static int atmel_tdes_write_ctrl(struct atmel_tdes_dev *dd)
|
||||||
valmr |= TDES_MR_TDESMOD_DES;
|
valmr |= TDES_MR_TDESMOD_DES;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dd->flags & TDES_FLAGS_CBC) {
|
valmr |= dd->flags & TDES_FLAGS_MODE_MASK;
|
||||||
valmr |= TDES_MR_OPMOD_CBC;
|
|
||||||
} else if (dd->flags & TDES_FLAGS_CFB) {
|
|
||||||
valmr |= TDES_MR_OPMOD_CFB;
|
|
||||||
|
|
||||||
if (dd->flags & TDES_FLAGS_CFB8)
|
|
||||||
valmr |= TDES_MR_CFBS_8b;
|
|
||||||
else if (dd->flags & TDES_FLAGS_CFB16)
|
|
||||||
valmr |= TDES_MR_CFBS_16b;
|
|
||||||
else if (dd->flags & TDES_FLAGS_CFB32)
|
|
||||||
valmr |= TDES_MR_CFBS_32b;
|
|
||||||
else if (dd->flags & TDES_FLAGS_CFB64)
|
|
||||||
valmr |= TDES_MR_CFBS_64b;
|
|
||||||
} else if (dd->flags & TDES_FLAGS_OFB) {
|
|
||||||
valmr |= TDES_MR_OPMOD_OFB;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((dd->flags & TDES_FLAGS_ENCRYPT) || (dd->flags & TDES_FLAGS_OFB))
|
|
||||||
valmr |= TDES_MR_CYPHER_ENC;
|
|
||||||
|
|
||||||
atmel_tdes_write(dd, TDES_MR, valmr);
|
atmel_tdes_write(dd, TDES_MR, valmr);
|
||||||
|
|
||||||
atmel_tdes_write_n(dd, TDES_KEY1W1R, dd->ctx->key,
|
atmel_tdes_write_n(dd, TDES_KEY1W1R, dd->ctx->key,
|
||||||
dd->ctx->keylen >> 2);
|
dd->ctx->keylen >> 2);
|
||||||
|
|
||||||
if (((dd->flags & TDES_FLAGS_CBC) || (dd->flags & TDES_FLAGS_CFB) ||
|
if (dd->req->iv && (valmr & TDES_MR_OPMOD_MASK) != TDES_MR_OPMOD_ECB)
|
||||||
(dd->flags & TDES_FLAGS_OFB)) && dd->req->iv) {
|
|
||||||
atmel_tdes_write_n(dd, TDES_IV1R, (void *)dd->req->iv, 2);
|
atmel_tdes_write_n(dd, TDES_IV1R, (void *)dd->req->iv, 2);
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -406,6 +389,7 @@ static int atmel_tdes_crypt_pdc(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
|
||||||
{
|
{
|
||||||
struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
|
struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||||
struct atmel_tdes_dev *dd = ctx->dd;
|
struct atmel_tdes_dev *dd = ctx->dd;
|
||||||
|
struct atmel_tdes_reqctx *rctx = skcipher_request_ctx(dd->req);
|
||||||
int len32;
|
int len32;
|
||||||
|
|
||||||
dd->dma_size = length;
|
dd->dma_size = length;
|
||||||
|
@ -415,12 +399,19 @@ static int atmel_tdes_crypt_pdc(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dd->flags & TDES_FLAGS_CFB) && (dd->flags & TDES_FLAGS_CFB8))
|
switch (rctx->mode & TDES_FLAGS_OPMODE_MASK) {
|
||||||
|
case TDES_FLAGS_CFB8:
|
||||||
len32 = DIV_ROUND_UP(length, sizeof(u8));
|
len32 = DIV_ROUND_UP(length, sizeof(u8));
|
||||||
else if ((dd->flags & TDES_FLAGS_CFB) && (dd->flags & TDES_FLAGS_CFB16))
|
break;
|
||||||
|
|
||||||
|
case TDES_FLAGS_CFB16:
|
||||||
len32 = DIV_ROUND_UP(length, sizeof(u16));
|
len32 = DIV_ROUND_UP(length, sizeof(u16));
|
||||||
else
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
len32 = DIV_ROUND_UP(length, sizeof(u32));
|
len32 = DIV_ROUND_UP(length, sizeof(u32));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTDIS|TDES_PTCR_RXTDIS);
|
atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTDIS|TDES_PTCR_RXTDIS);
|
||||||
atmel_tdes_write(dd, TDES_TPR, dma_addr_in);
|
atmel_tdes_write(dd, TDES_TPR, dma_addr_in);
|
||||||
|
@ -442,8 +433,10 @@ static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
|
||||||
{
|
{
|
||||||
struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
|
struct atmel_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||||
struct atmel_tdes_dev *dd = ctx->dd;
|
struct atmel_tdes_dev *dd = ctx->dd;
|
||||||
|
struct atmel_tdes_reqctx *rctx = skcipher_request_ctx(dd->req);
|
||||||
struct scatterlist sg[2];
|
struct scatterlist sg[2];
|
||||||
struct dma_async_tx_descriptor *in_desc, *out_desc;
|
struct dma_async_tx_descriptor *in_desc, *out_desc;
|
||||||
|
enum dma_slave_buswidth addr_width;
|
||||||
|
|
||||||
dd->dma_size = length;
|
dd->dma_size = length;
|
||||||
|
|
||||||
|
@ -452,23 +445,23 @@ static int atmel_tdes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dd->flags & TDES_FLAGS_CFB8) {
|
switch (rctx->mode & TDES_FLAGS_OPMODE_MASK) {
|
||||||
dd->dma_lch_in.dma_conf.dst_addr_width =
|
case TDES_FLAGS_CFB8:
|
||||||
DMA_SLAVE_BUSWIDTH_1_BYTE;
|
addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
||||||
dd->dma_lch_out.dma_conf.src_addr_width =
|
break;
|
||||||
DMA_SLAVE_BUSWIDTH_1_BYTE;
|
|
||||||
} else if (dd->flags & TDES_FLAGS_CFB16) {
|
case TDES_FLAGS_CFB16:
|
||||||
dd->dma_lch_in.dma_conf.dst_addr_width =
|
addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||||
DMA_SLAVE_BUSWIDTH_2_BYTES;
|
break;
|
||||||
dd->dma_lch_out.dma_conf.src_addr_width =
|
|
||||||
DMA_SLAVE_BUSWIDTH_2_BYTES;
|
default:
|
||||||
} else {
|
addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||||
dd->dma_lch_in.dma_conf.dst_addr_width =
|
break;
|
||||||
DMA_SLAVE_BUSWIDTH_4_BYTES;
|
|
||||||
dd->dma_lch_out.dma_conf.src_addr_width =
|
|
||||||
DMA_SLAVE_BUSWIDTH_4_BYTES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dd->dma_lch_in.dma_conf.dst_addr_width = addr_width;
|
||||||
|
dd->dma_lch_out.dma_conf.src_addr_width = addr_width;
|
||||||
|
|
||||||
dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf);
|
dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf);
|
||||||
dmaengine_slave_config(dd->dma_lch_out.chan, &dd->dma_lch_out.dma_conf);
|
dmaengine_slave_config(dd->dma_lch_out.chan, &dd->dma_lch_out.dma_conf);
|
||||||
|
|
||||||
|
@ -703,30 +696,38 @@ static int atmel_tdes_crypt(struct skcipher_request *req, unsigned long mode)
|
||||||
struct atmel_tdes_ctx *ctx = crypto_skcipher_ctx(skcipher);
|
struct atmel_tdes_ctx *ctx = crypto_skcipher_ctx(skcipher);
|
||||||
struct atmel_tdes_reqctx *rctx = skcipher_request_ctx(req);
|
struct atmel_tdes_reqctx *rctx = skcipher_request_ctx(req);
|
||||||
|
|
||||||
if (mode & TDES_FLAGS_CFB8) {
|
switch (mode & TDES_FLAGS_OPMODE_MASK) {
|
||||||
|
case TDES_FLAGS_CFB8:
|
||||||
if (!IS_ALIGNED(req->cryptlen, CFB8_BLOCK_SIZE)) {
|
if (!IS_ALIGNED(req->cryptlen, CFB8_BLOCK_SIZE)) {
|
||||||
pr_err("request size is not exact amount of CFB8 blocks\n");
|
pr_err("request size is not exact amount of CFB8 blocks\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
ctx->block_size = CFB8_BLOCK_SIZE;
|
ctx->block_size = CFB8_BLOCK_SIZE;
|
||||||
} else if (mode & TDES_FLAGS_CFB16) {
|
break;
|
||||||
|
|
||||||
|
case TDES_FLAGS_CFB16:
|
||||||
if (!IS_ALIGNED(req->cryptlen, CFB16_BLOCK_SIZE)) {
|
if (!IS_ALIGNED(req->cryptlen, CFB16_BLOCK_SIZE)) {
|
||||||
pr_err("request size is not exact amount of CFB16 blocks\n");
|
pr_err("request size is not exact amount of CFB16 blocks\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
ctx->block_size = CFB16_BLOCK_SIZE;
|
ctx->block_size = CFB16_BLOCK_SIZE;
|
||||||
} else if (mode & TDES_FLAGS_CFB32) {
|
break;
|
||||||
|
|
||||||
|
case TDES_FLAGS_CFB32:
|
||||||
if (!IS_ALIGNED(req->cryptlen, CFB32_BLOCK_SIZE)) {
|
if (!IS_ALIGNED(req->cryptlen, CFB32_BLOCK_SIZE)) {
|
||||||
pr_err("request size is not exact amount of CFB32 blocks\n");
|
pr_err("request size is not exact amount of CFB32 blocks\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
ctx->block_size = CFB32_BLOCK_SIZE;
|
ctx->block_size = CFB32_BLOCK_SIZE;
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
if (!IS_ALIGNED(req->cryptlen, DES_BLOCK_SIZE)) {
|
if (!IS_ALIGNED(req->cryptlen, DES_BLOCK_SIZE)) {
|
||||||
pr_err("request size is not exact amount of DES blocks\n");
|
pr_err("request size is not exact amount of DES blocks\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
ctx->block_size = DES_BLOCK_SIZE;
|
ctx->block_size = DES_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rctx->mode = mode;
|
rctx->mode = mode;
|
||||||
|
@ -833,17 +834,17 @@ static int atmel_tdes_setkey(struct crypto_skcipher *tfm, const u8 *key,
|
||||||
|
|
||||||
static int atmel_tdes_ecb_encrypt(struct skcipher_request *req)
|
static int atmel_tdes_ecb_encrypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT);
|
return atmel_tdes_crypt(req, TDES_FLAGS_ECB | TDES_FLAGS_ENCRYPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_tdes_ecb_decrypt(struct skcipher_request *req)
|
static int atmel_tdes_ecb_decrypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
return atmel_tdes_crypt(req, 0);
|
return atmel_tdes_crypt(req, TDES_FLAGS_ECB);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_tdes_cbc_encrypt(struct skcipher_request *req)
|
static int atmel_tdes_cbc_encrypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CBC);
|
return atmel_tdes_crypt(req, TDES_FLAGS_CBC | TDES_FLAGS_ENCRYPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_tdes_cbc_decrypt(struct skcipher_request *req)
|
static int atmel_tdes_cbc_decrypt(struct skcipher_request *req)
|
||||||
|
@ -852,50 +853,47 @@ static int atmel_tdes_cbc_decrypt(struct skcipher_request *req)
|
||||||
}
|
}
|
||||||
static int atmel_tdes_cfb_encrypt(struct skcipher_request *req)
|
static int atmel_tdes_cfb_encrypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CFB);
|
return atmel_tdes_crypt(req, TDES_FLAGS_CFB64 | TDES_FLAGS_ENCRYPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_tdes_cfb_decrypt(struct skcipher_request *req)
|
static int atmel_tdes_cfb_decrypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
return atmel_tdes_crypt(req, TDES_FLAGS_CFB);
|
return atmel_tdes_crypt(req, TDES_FLAGS_CFB64);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_tdes_cfb8_encrypt(struct skcipher_request *req)
|
static int atmel_tdes_cfb8_encrypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CFB |
|
return atmel_tdes_crypt(req, TDES_FLAGS_CFB8 | TDES_FLAGS_ENCRYPT);
|
||||||
TDES_FLAGS_CFB8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_tdes_cfb8_decrypt(struct skcipher_request *req)
|
static int atmel_tdes_cfb8_decrypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
return atmel_tdes_crypt(req, TDES_FLAGS_CFB | TDES_FLAGS_CFB8);
|
return atmel_tdes_crypt(req, TDES_FLAGS_CFB8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_tdes_cfb16_encrypt(struct skcipher_request *req)
|
static int atmel_tdes_cfb16_encrypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CFB |
|
return atmel_tdes_crypt(req, TDES_FLAGS_CFB16 | TDES_FLAGS_ENCRYPT);
|
||||||
TDES_FLAGS_CFB16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_tdes_cfb16_decrypt(struct skcipher_request *req)
|
static int atmel_tdes_cfb16_decrypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
return atmel_tdes_crypt(req, TDES_FLAGS_CFB | TDES_FLAGS_CFB16);
|
return atmel_tdes_crypt(req, TDES_FLAGS_CFB16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_tdes_cfb32_encrypt(struct skcipher_request *req)
|
static int atmel_tdes_cfb32_encrypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_CFB |
|
return atmel_tdes_crypt(req, TDES_FLAGS_CFB32 | TDES_FLAGS_ENCRYPT);
|
||||||
TDES_FLAGS_CFB32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_tdes_cfb32_decrypt(struct skcipher_request *req)
|
static int atmel_tdes_cfb32_decrypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
return atmel_tdes_crypt(req, TDES_FLAGS_CFB | TDES_FLAGS_CFB32);
|
return atmel_tdes_crypt(req, TDES_FLAGS_CFB32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_tdes_ofb_encrypt(struct skcipher_request *req)
|
static int atmel_tdes_ofb_encrypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
return atmel_tdes_crypt(req, TDES_FLAGS_ENCRYPT | TDES_FLAGS_OFB);
|
return atmel_tdes_crypt(req, TDES_FLAGS_OFB | TDES_FLAGS_ENCRYPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atmel_tdes_ofb_decrypt(struct skcipher_request *req)
|
static int atmel_tdes_ofb_decrypt(struct skcipher_request *req)
|
||||||
|
|
Loading…
Reference in New Issue