crypto: cavium/nitrox - Fix cbc ciphers self test failures
Self test failures are due to wrong output IV. This patch fixes this issue by copying back output IV into skcipher request. Signed-off-by: Nagadheeraj Rottela <rnagadheeraj@marvell.com> Reviewed-by: Srikanth Jampala <jsrikanth@marvell.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
3fed9baad5
commit
ced0a170fd
@ -10,6 +10,8 @@
|
|||||||
#define PENDING_SIG 0xFFFFFFFFFFFFFFFFUL
|
#define PENDING_SIG 0xFFFFFFFFFFFFFFFFUL
|
||||||
#define PRIO 4001
|
#define PRIO 4001
|
||||||
|
|
||||||
|
typedef void (*sereq_completion_t)(void *req, int err);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct gphdr - General purpose Header
|
* struct gphdr - General purpose Header
|
||||||
* @param0: first parameter.
|
* @param0: first parameter.
|
||||||
@ -203,12 +205,14 @@ struct nitrox_crypto_ctx {
|
|||||||
struct flexi_crypto_context *fctx;
|
struct flexi_crypto_context *fctx;
|
||||||
} u;
|
} u;
|
||||||
struct crypto_ctx_hdr *chdr;
|
struct crypto_ctx_hdr *chdr;
|
||||||
|
sereq_completion_t callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nitrox_kcrypt_request {
|
struct nitrox_kcrypt_request {
|
||||||
struct se_crypto_request creq;
|
struct se_crypto_request creq;
|
||||||
u8 *src;
|
u8 *src;
|
||||||
u8 *dst;
|
u8 *dst;
|
||||||
|
u8 *iv_out;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <crypto/aes.h>
|
#include <crypto/aes.h>
|
||||||
#include <crypto/skcipher.h>
|
#include <crypto/skcipher.h>
|
||||||
|
#include <crypto/scatterwalk.h>
|
||||||
#include <crypto/ctr.h>
|
#include <crypto/ctr.h>
|
||||||
#include <crypto/internal/des.h>
|
#include <crypto/internal/des.h>
|
||||||
#include <crypto/xts.h>
|
#include <crypto/xts.h>
|
||||||
@ -47,6 +48,63 @@ static enum flexi_cipher flexi_cipher_type(const char *name)
|
|||||||
return cipher->value;
|
return cipher->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void free_src_sglist(struct skcipher_request *skreq)
|
||||||
|
{
|
||||||
|
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
|
||||||
|
|
||||||
|
kfree(nkreq->src);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_dst_sglist(struct skcipher_request *skreq)
|
||||||
|
{
|
||||||
|
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
|
||||||
|
|
||||||
|
kfree(nkreq->dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nitrox_skcipher_callback(void *arg, int err)
|
||||||
|
{
|
||||||
|
struct skcipher_request *skreq = arg;
|
||||||
|
|
||||||
|
free_src_sglist(skreq);
|
||||||
|
free_dst_sglist(skreq);
|
||||||
|
if (err) {
|
||||||
|
pr_err_ratelimited("request failed status 0x%0x\n", err);
|
||||||
|
err = -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
skcipher_request_complete(skreq, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nitrox_cbc_cipher_callback(void *arg, int err)
|
||||||
|
{
|
||||||
|
struct skcipher_request *skreq = arg;
|
||||||
|
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
|
||||||
|
struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(skreq);
|
||||||
|
int ivsize = crypto_skcipher_ivsize(cipher);
|
||||||
|
unsigned int start = skreq->cryptlen - ivsize;
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
nitrox_skcipher_callback(arg, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nkreq->creq.ctrl.s.arg == ENCRYPT) {
|
||||||
|
scatterwalk_map_and_copy(skreq->iv, skreq->dst, start, ivsize,
|
||||||
|
0);
|
||||||
|
} else {
|
||||||
|
if (skreq->src != skreq->dst) {
|
||||||
|
scatterwalk_map_and_copy(skreq->iv, skreq->src, start,
|
||||||
|
ivsize, 0);
|
||||||
|
} else {
|
||||||
|
memcpy(skreq->iv, nkreq->iv_out, ivsize);
|
||||||
|
kfree(nkreq->iv_out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nitrox_skcipher_callback(arg, err);
|
||||||
|
}
|
||||||
|
|
||||||
static int nitrox_skcipher_init(struct crypto_skcipher *tfm)
|
static int nitrox_skcipher_init(struct crypto_skcipher *tfm)
|
||||||
{
|
{
|
||||||
struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm);
|
struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm);
|
||||||
@ -63,6 +121,8 @@ static int nitrox_skcipher_init(struct crypto_skcipher *tfm)
|
|||||||
nitrox_put_device(nctx->ndev);
|
nitrox_put_device(nctx->ndev);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nctx->callback = nitrox_skcipher_callback;
|
||||||
nctx->chdr = chdr;
|
nctx->chdr = chdr;
|
||||||
nctx->u.ctx_handle = (uintptr_t)((u8 *)chdr->vaddr +
|
nctx->u.ctx_handle = (uintptr_t)((u8 *)chdr->vaddr +
|
||||||
sizeof(struct ctx_hdr));
|
sizeof(struct ctx_hdr));
|
||||||
@ -71,6 +131,19 @@ static int nitrox_skcipher_init(struct crypto_skcipher *tfm)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nitrox_cbc_init(struct crypto_skcipher *tfm)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm);
|
||||||
|
|
||||||
|
err = nitrox_skcipher_init(tfm);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
nctx->callback = nitrox_cbc_cipher_callback;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void nitrox_skcipher_exit(struct crypto_skcipher *tfm)
|
static void nitrox_skcipher_exit(struct crypto_skcipher *tfm)
|
||||||
{
|
{
|
||||||
struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm);
|
struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm);
|
||||||
@ -173,34 +246,6 @@ static int alloc_dst_sglist(struct skcipher_request *skreq, int ivsize)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_src_sglist(struct skcipher_request *skreq)
|
|
||||||
{
|
|
||||||
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
|
|
||||||
|
|
||||||
kfree(nkreq->src);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free_dst_sglist(struct skcipher_request *skreq)
|
|
||||||
{
|
|
||||||
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
|
|
||||||
|
|
||||||
kfree(nkreq->dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nitrox_skcipher_callback(void *arg, int err)
|
|
||||||
{
|
|
||||||
struct skcipher_request *skreq = arg;
|
|
||||||
|
|
||||||
free_src_sglist(skreq);
|
|
||||||
free_dst_sglist(skreq);
|
|
||||||
if (err) {
|
|
||||||
pr_err_ratelimited("request failed status 0x%0x\n", err);
|
|
||||||
err = -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
skcipher_request_complete(skreq, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nitrox_skcipher_crypt(struct skcipher_request *skreq, bool enc)
|
static int nitrox_skcipher_crypt(struct skcipher_request *skreq, bool enc)
|
||||||
{
|
{
|
||||||
struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(skreq);
|
struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(skreq);
|
||||||
@ -240,8 +285,28 @@ static int nitrox_skcipher_crypt(struct skcipher_request *skreq, bool enc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* send the crypto request */
|
/* send the crypto request */
|
||||||
return nitrox_process_se_request(nctx->ndev, creq,
|
return nitrox_process_se_request(nctx->ndev, creq, nctx->callback,
|
||||||
nitrox_skcipher_callback, skreq);
|
skreq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nitrox_cbc_decrypt(struct skcipher_request *skreq)
|
||||||
|
{
|
||||||
|
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
|
||||||
|
struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(skreq);
|
||||||
|
int ivsize = crypto_skcipher_ivsize(cipher);
|
||||||
|
gfp_t flags = (skreq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
|
||||||
|
GFP_KERNEL : GFP_ATOMIC;
|
||||||
|
unsigned int start = skreq->cryptlen - ivsize;
|
||||||
|
|
||||||
|
if (skreq->src != skreq->dst)
|
||||||
|
return nitrox_skcipher_crypt(skreq, false);
|
||||||
|
|
||||||
|
nkreq->iv_out = kmalloc(ivsize, flags);
|
||||||
|
if (!nkreq->iv_out)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
scatterwalk_map_and_copy(nkreq->iv_out, skreq->src, start, ivsize, 0);
|
||||||
|
return nitrox_skcipher_crypt(skreq, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nitrox_aes_encrypt(struct skcipher_request *skreq)
|
static int nitrox_aes_encrypt(struct skcipher_request *skreq)
|
||||||
@ -340,8 +405,8 @@ static struct skcipher_alg nitrox_skciphers[] = { {
|
|||||||
.ivsize = AES_BLOCK_SIZE,
|
.ivsize = AES_BLOCK_SIZE,
|
||||||
.setkey = nitrox_aes_setkey,
|
.setkey = nitrox_aes_setkey,
|
||||||
.encrypt = nitrox_aes_encrypt,
|
.encrypt = nitrox_aes_encrypt,
|
||||||
.decrypt = nitrox_aes_decrypt,
|
.decrypt = nitrox_cbc_decrypt,
|
||||||
.init = nitrox_skcipher_init,
|
.init = nitrox_cbc_init,
|
||||||
.exit = nitrox_skcipher_exit,
|
.exit = nitrox_skcipher_exit,
|
||||||
}, {
|
}, {
|
||||||
.base = {
|
.base = {
|
||||||
@ -455,8 +520,8 @@ static struct skcipher_alg nitrox_skciphers[] = { {
|
|||||||
.ivsize = DES3_EDE_BLOCK_SIZE,
|
.ivsize = DES3_EDE_BLOCK_SIZE,
|
||||||
.setkey = nitrox_3des_setkey,
|
.setkey = nitrox_3des_setkey,
|
||||||
.encrypt = nitrox_3des_encrypt,
|
.encrypt = nitrox_3des_encrypt,
|
||||||
.decrypt = nitrox_3des_decrypt,
|
.decrypt = nitrox_cbc_decrypt,
|
||||||
.init = nitrox_skcipher_init,
|
.init = nitrox_cbc_init,
|
||||||
.exit = nitrox_skcipher_exit,
|
.exit = nitrox_skcipher_exit,
|
||||||
}, {
|
}, {
|
||||||
.base = {
|
.base = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user