mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu: "This push fixes a number of crashes triggered by a previous crypto self-test update. It also fixes a build problem in the caam driver, as well as a concurrency issue in s390. Finally there is a pair of fixes to bugs in the crypto scatterwalk code and authenc that may lead to crashes" * git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: crypto: testmgr - fix sglen in test_aead for case 'dst != src' crypto: talitos - fix aead sglen for case 'dst != src' crypto: caam - fix aead sglen for case 'dst != src' crypto: ccm - Fix handling of zero plaintext when computing mac crypto: s390 - Fix aes-xts parameter corruption crypto: talitos - corrrectly handle zero-length assoc data crypto: scatterwalk - Set the chain pointer indication bit crypto: authenc - Find proper IV address in ablkcipher callback crypto: caam - Add missing Job Ring include
This commit is contained in:
commit
d644c026e6
9 changed files with 109 additions and 83 deletions
|
@ -55,8 +55,7 @@ struct pcc_param {
|
||||||
|
|
||||||
struct s390_xts_ctx {
|
struct s390_xts_ctx {
|
||||||
u8 key[32];
|
u8 key[32];
|
||||||
u8 xts_param[16];
|
u8 pcc_key[32];
|
||||||
struct pcc_param pcc;
|
|
||||||
long enc;
|
long enc;
|
||||||
long dec;
|
long dec;
|
||||||
int key_len;
|
int key_len;
|
||||||
|
@ -591,7 +590,7 @@ static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||||
xts_ctx->enc = KM_XTS_128_ENCRYPT;
|
xts_ctx->enc = KM_XTS_128_ENCRYPT;
|
||||||
xts_ctx->dec = KM_XTS_128_DECRYPT;
|
xts_ctx->dec = KM_XTS_128_DECRYPT;
|
||||||
memcpy(xts_ctx->key + 16, in_key, 16);
|
memcpy(xts_ctx->key + 16, in_key, 16);
|
||||||
memcpy(xts_ctx->pcc.key + 16, in_key + 16, 16);
|
memcpy(xts_ctx->pcc_key + 16, in_key + 16, 16);
|
||||||
break;
|
break;
|
||||||
case 48:
|
case 48:
|
||||||
xts_ctx->enc = 0;
|
xts_ctx->enc = 0;
|
||||||
|
@ -602,7 +601,7 @@ static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||||
xts_ctx->enc = KM_XTS_256_ENCRYPT;
|
xts_ctx->enc = KM_XTS_256_ENCRYPT;
|
||||||
xts_ctx->dec = KM_XTS_256_DECRYPT;
|
xts_ctx->dec = KM_XTS_256_DECRYPT;
|
||||||
memcpy(xts_ctx->key, in_key, 32);
|
memcpy(xts_ctx->key, in_key, 32);
|
||||||
memcpy(xts_ctx->pcc.key, in_key + 32, 32);
|
memcpy(xts_ctx->pcc_key, in_key + 32, 32);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
|
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
|
||||||
|
@ -621,29 +620,33 @@ static int xts_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||||
unsigned int nbytes = walk->nbytes;
|
unsigned int nbytes = walk->nbytes;
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
u8 *in, *out;
|
u8 *in, *out;
|
||||||
void *param;
|
struct pcc_param pcc_param;
|
||||||
|
struct {
|
||||||
|
u8 key[32];
|
||||||
|
u8 init[16];
|
||||||
|
} xts_param;
|
||||||
|
|
||||||
if (!nbytes)
|
if (!nbytes)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
memset(xts_ctx->pcc.block, 0, sizeof(xts_ctx->pcc.block));
|
memset(pcc_param.block, 0, sizeof(pcc_param.block));
|
||||||
memset(xts_ctx->pcc.bit, 0, sizeof(xts_ctx->pcc.bit));
|
memset(pcc_param.bit, 0, sizeof(pcc_param.bit));
|
||||||
memset(xts_ctx->pcc.xts, 0, sizeof(xts_ctx->pcc.xts));
|
memset(pcc_param.xts, 0, sizeof(pcc_param.xts));
|
||||||
memcpy(xts_ctx->pcc.tweak, walk->iv, sizeof(xts_ctx->pcc.tweak));
|
memcpy(pcc_param.tweak, walk->iv, sizeof(pcc_param.tweak));
|
||||||
param = xts_ctx->pcc.key + offset;
|
memcpy(pcc_param.key, xts_ctx->pcc_key, 32);
|
||||||
ret = crypt_s390_pcc(func, param);
|
ret = crypt_s390_pcc(func, &pcc_param.key[offset]);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
memcpy(xts_ctx->xts_param, xts_ctx->pcc.xts, 16);
|
memcpy(xts_param.key, xts_ctx->key, 32);
|
||||||
param = xts_ctx->key + offset;
|
memcpy(xts_param.init, pcc_param.xts, 16);
|
||||||
do {
|
do {
|
||||||
/* only use complete blocks */
|
/* only use complete blocks */
|
||||||
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||||
out = walk->dst.virt.addr;
|
out = walk->dst.virt.addr;
|
||||||
in = walk->src.virt.addr;
|
in = walk->src.virt.addr;
|
||||||
|
|
||||||
ret = crypt_s390_km(func, param, out, in, n);
|
ret = crypt_s390_km(func, &xts_param.key[offset], out, in, n);
|
||||||
if (ret < 0 || ret != n)
|
if (ret < 0 || ret != n)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
|
|
|
@ -380,9 +380,10 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
|
||||||
if (!err) {
|
if (!err) {
|
||||||
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
|
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
|
||||||
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
|
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
|
||||||
struct ablkcipher_request *abreq = aead_request_ctx(areq);
|
struct authenc_request_ctx *areq_ctx = aead_request_ctx(areq);
|
||||||
u8 *iv = (u8 *)(abreq + 1) +
|
struct ablkcipher_request *abreq = (void *)(areq_ctx->tail
|
||||||
crypto_ablkcipher_reqsize(ctx->enc);
|
+ ctx->reqoff);
|
||||||
|
u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(ctx->enc);
|
||||||
|
|
||||||
err = crypto_authenc_genicv(areq, iv, 0);
|
err = crypto_authenc_genicv(areq, iv, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,7 +271,8 @@ static int crypto_ccm_auth(struct aead_request *req, struct scatterlist *plain,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compute plaintext into mac */
|
/* compute plaintext into mac */
|
||||||
get_data_to_compute(cipher, pctx, plain, cryptlen);
|
if (cryptlen)
|
||||||
|
get_data_to_compute(cipher, pctx, plain, cryptlen);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -1242,6 +1242,10 @@ static int do_test(int m)
|
||||||
ret += tcrypt_test("cmac(des3_ede)");
|
ret += tcrypt_test("cmac(des3_ede)");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 155:
|
||||||
|
ret += tcrypt_test("authenc(hmac(sha1),cbc(aes))");
|
||||||
|
break;
|
||||||
|
|
||||||
case 200:
|
case 200:
|
||||||
test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
|
test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
|
||||||
speed_template_16_24_32);
|
speed_template_16_24_32);
|
||||||
|
|
|
@ -503,16 +503,16 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sg_init_one(&sg[0], input,
|
|
||||||
template[i].ilen + (enc ? authsize : 0));
|
|
||||||
|
|
||||||
if (diff_dst) {
|
if (diff_dst) {
|
||||||
output = xoutbuf[0];
|
output = xoutbuf[0];
|
||||||
output += align_offset;
|
output += align_offset;
|
||||||
|
sg_init_one(&sg[0], input, template[i].ilen);
|
||||||
sg_init_one(&sgout[0], output,
|
sg_init_one(&sgout[0], output,
|
||||||
|
template[i].rlen);
|
||||||
|
} else {
|
||||||
|
sg_init_one(&sg[0], input,
|
||||||
template[i].ilen +
|
template[i].ilen +
|
||||||
(enc ? authsize : 0));
|
(enc ? authsize : 0));
|
||||||
} else {
|
|
||||||
output = input;
|
output = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,12 +612,6 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
|
||||||
memcpy(q, template[i].input + temp,
|
memcpy(q, template[i].input + temp,
|
||||||
template[i].tap[k]);
|
template[i].tap[k]);
|
||||||
|
|
||||||
n = template[i].tap[k];
|
|
||||||
if (k == template[i].np - 1 && enc)
|
|
||||||
n += authsize;
|
|
||||||
if (offset_in_page(q) + n < PAGE_SIZE)
|
|
||||||
q[n] = 0;
|
|
||||||
|
|
||||||
sg_set_buf(&sg[k], q, template[i].tap[k]);
|
sg_set_buf(&sg[k], q, template[i].tap[k]);
|
||||||
|
|
||||||
if (diff_dst) {
|
if (diff_dst) {
|
||||||
|
@ -625,13 +619,17 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
|
||||||
offset_in_page(IDX[k]);
|
offset_in_page(IDX[k]);
|
||||||
|
|
||||||
memset(q, 0, template[i].tap[k]);
|
memset(q, 0, template[i].tap[k]);
|
||||||
if (offset_in_page(q) + n < PAGE_SIZE)
|
|
||||||
q[n] = 0;
|
|
||||||
|
|
||||||
sg_set_buf(&sgout[k], q,
|
sg_set_buf(&sgout[k], q,
|
||||||
template[i].tap[k]);
|
template[i].tap[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n = template[i].tap[k];
|
||||||
|
if (k == template[i].np - 1 && enc)
|
||||||
|
n += authsize;
|
||||||
|
if (offset_in_page(q) + n < PAGE_SIZE)
|
||||||
|
q[n] = 0;
|
||||||
|
|
||||||
temp += template[i].tap[k];
|
temp += template[i].tap[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,10 +648,10 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sg[k - 1].length += authsize;
|
|
||||||
|
|
||||||
if (diff_dst)
|
if (diff_dst)
|
||||||
sgout[k - 1].length += authsize;
|
sgout[k - 1].length += authsize;
|
||||||
|
else
|
||||||
|
sg[k - 1].length += authsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
sg_init_table(asg, template[i].anp);
|
sg_init_table(asg, template[i].anp);
|
||||||
|
|
|
@ -818,7 +818,7 @@ static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
|
||||||
ivsize, 1);
|
ivsize, 1);
|
||||||
print_hex_dump(KERN_ERR, "dst @"__stringify(__LINE__)": ",
|
print_hex_dump(KERN_ERR, "dst @"__stringify(__LINE__)": ",
|
||||||
DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->dst),
|
DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->dst),
|
||||||
req->cryptlen, 1);
|
req->cryptlen - ctx->authsize, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -972,12 +972,9 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr,
|
||||||
(edesc->src_nents ? : 1);
|
(edesc->src_nents ? : 1);
|
||||||
in_options = LDST_SGF;
|
in_options = LDST_SGF;
|
||||||
}
|
}
|
||||||
if (encrypt)
|
|
||||||
append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize +
|
append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + req->cryptlen,
|
||||||
req->cryptlen - authsize, in_options);
|
in_options);
|
||||||
else
|
|
||||||
append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize +
|
|
||||||
req->cryptlen, in_options);
|
|
||||||
|
|
||||||
if (likely(req->src == req->dst)) {
|
if (likely(req->src == req->dst)) {
|
||||||
if (all_contig) {
|
if (all_contig) {
|
||||||
|
@ -998,7 +995,8 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (encrypt)
|
if (encrypt)
|
||||||
append_seq_out_ptr(desc, dst_dma, req->cryptlen, out_options);
|
append_seq_out_ptr(desc, dst_dma, req->cryptlen + authsize,
|
||||||
|
out_options);
|
||||||
else
|
else
|
||||||
append_seq_out_ptr(desc, dst_dma, req->cryptlen - authsize,
|
append_seq_out_ptr(desc, dst_dma, req->cryptlen - authsize,
|
||||||
out_options);
|
out_options);
|
||||||
|
@ -1048,8 +1046,8 @@ static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr,
|
||||||
sec4_sg_index += edesc->assoc_nents + 1 + edesc->src_nents;
|
sec4_sg_index += edesc->assoc_nents + 1 + edesc->src_nents;
|
||||||
in_options = LDST_SGF;
|
in_options = LDST_SGF;
|
||||||
}
|
}
|
||||||
append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize +
|
append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + req->cryptlen,
|
||||||
req->cryptlen - authsize, in_options);
|
in_options);
|
||||||
|
|
||||||
if (contig & GIV_DST_CONTIG) {
|
if (contig & GIV_DST_CONTIG) {
|
||||||
dst_dma = edesc->iv_dma;
|
dst_dma = edesc->iv_dma;
|
||||||
|
@ -1066,7 +1064,8 @@ static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
append_seq_out_ptr(desc, dst_dma, ivsize + req->cryptlen, out_options);
|
append_seq_out_ptr(desc, dst_dma, ivsize + req->cryptlen + authsize,
|
||||||
|
out_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1130,7 +1129,8 @@ static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr,
|
||||||
* allocate and map the aead extended descriptor
|
* allocate and map the aead extended descriptor
|
||||||
*/
|
*/
|
||||||
static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
|
static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
|
||||||
int desc_bytes, bool *all_contig_ptr)
|
int desc_bytes, bool *all_contig_ptr,
|
||||||
|
bool encrypt)
|
||||||
{
|
{
|
||||||
struct crypto_aead *aead = crypto_aead_reqtfm(req);
|
struct crypto_aead *aead = crypto_aead_reqtfm(req);
|
||||||
struct caam_ctx *ctx = crypto_aead_ctx(aead);
|
struct caam_ctx *ctx = crypto_aead_ctx(aead);
|
||||||
|
@ -1145,12 +1145,22 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
|
||||||
bool assoc_chained = false, src_chained = false, dst_chained = false;
|
bool assoc_chained = false, src_chained = false, dst_chained = false;
|
||||||
int ivsize = crypto_aead_ivsize(aead);
|
int ivsize = crypto_aead_ivsize(aead);
|
||||||
int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
|
int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
|
||||||
|
unsigned int authsize = ctx->authsize;
|
||||||
|
|
||||||
assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained);
|
assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained);
|
||||||
src_nents = sg_count(req->src, req->cryptlen, &src_chained);
|
|
||||||
|
|
||||||
if (unlikely(req->dst != req->src))
|
if (unlikely(req->dst != req->src)) {
|
||||||
dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained);
|
src_nents = sg_count(req->src, req->cryptlen, &src_chained);
|
||||||
|
dst_nents = sg_count(req->dst,
|
||||||
|
req->cryptlen +
|
||||||
|
(encrypt ? authsize : (-authsize)),
|
||||||
|
&dst_chained);
|
||||||
|
} else {
|
||||||
|
src_nents = sg_count(req->src,
|
||||||
|
req->cryptlen +
|
||||||
|
(encrypt ? authsize : 0),
|
||||||
|
&src_chained);
|
||||||
|
}
|
||||||
|
|
||||||
sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
|
sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
|
||||||
DMA_TO_DEVICE, assoc_chained);
|
DMA_TO_DEVICE, assoc_chained);
|
||||||
|
@ -1234,11 +1244,9 @@ static int aead_encrypt(struct aead_request *req)
|
||||||
u32 *desc;
|
u32 *desc;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
req->cryptlen += ctx->authsize;
|
|
||||||
|
|
||||||
/* allocate extended descriptor */
|
/* allocate extended descriptor */
|
||||||
edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN *
|
edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN *
|
||||||
CAAM_CMD_SZ, &all_contig);
|
CAAM_CMD_SZ, &all_contig, true);
|
||||||
if (IS_ERR(edesc))
|
if (IS_ERR(edesc))
|
||||||
return PTR_ERR(edesc);
|
return PTR_ERR(edesc);
|
||||||
|
|
||||||
|
@ -1275,7 +1283,7 @@ static int aead_decrypt(struct aead_request *req)
|
||||||
|
|
||||||
/* allocate extended descriptor */
|
/* allocate extended descriptor */
|
||||||
edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN *
|
edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN *
|
||||||
CAAM_CMD_SZ, &all_contig);
|
CAAM_CMD_SZ, &all_contig, false);
|
||||||
if (IS_ERR(edesc))
|
if (IS_ERR(edesc))
|
||||||
return PTR_ERR(edesc);
|
return PTR_ERR(edesc);
|
||||||
|
|
||||||
|
@ -1332,7 +1340,8 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
|
||||||
src_nents = sg_count(req->src, req->cryptlen, &src_chained);
|
src_nents = sg_count(req->src, req->cryptlen, &src_chained);
|
||||||
|
|
||||||
if (unlikely(req->dst != req->src))
|
if (unlikely(req->dst != req->src))
|
||||||
dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained);
|
dst_nents = sg_count(req->dst, req->cryptlen + ctx->authsize,
|
||||||
|
&dst_chained);
|
||||||
|
|
||||||
sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
|
sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
|
||||||
DMA_TO_DEVICE, assoc_chained);
|
DMA_TO_DEVICE, assoc_chained);
|
||||||
|
@ -1426,8 +1435,6 @@ static int aead_givencrypt(struct aead_givcrypt_request *areq)
|
||||||
u32 *desc;
|
u32 *desc;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
req->cryptlen += ctx->authsize;
|
|
||||||
|
|
||||||
/* allocate extended descriptor */
|
/* allocate extended descriptor */
|
||||||
edesc = aead_giv_edesc_alloc(areq, DESC_JOB_IO_LEN *
|
edesc = aead_giv_edesc_alloc(areq, DESC_JOB_IO_LEN *
|
||||||
CAAM_CMD_SZ, &contig);
|
CAAM_CMD_SZ, &contig);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "regs.h"
|
#include "regs.h"
|
||||||
|
|
|
@ -790,7 +790,7 @@ static void ipsec_esp_unmap(struct device *dev,
|
||||||
|
|
||||||
if (edesc->assoc_chained)
|
if (edesc->assoc_chained)
|
||||||
talitos_unmap_sg_chain(dev, areq->assoc, DMA_TO_DEVICE);
|
talitos_unmap_sg_chain(dev, areq->assoc, DMA_TO_DEVICE);
|
||||||
else
|
else if (areq->assoclen)
|
||||||
/* assoc_nents counts also for IV in non-contiguous cases */
|
/* assoc_nents counts also for IV in non-contiguous cases */
|
||||||
dma_unmap_sg(dev, areq->assoc,
|
dma_unmap_sg(dev, areq->assoc,
|
||||||
edesc->assoc_nents ? edesc->assoc_nents - 1 : 1,
|
edesc->assoc_nents ? edesc->assoc_nents - 1 : 1,
|
||||||
|
@ -973,7 +973,11 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
|
||||||
dma_sync_single_for_device(dev, edesc->dma_link_tbl,
|
dma_sync_single_for_device(dev, edesc->dma_link_tbl,
|
||||||
edesc->dma_len, DMA_BIDIRECTIONAL);
|
edesc->dma_len, DMA_BIDIRECTIONAL);
|
||||||
} else {
|
} else {
|
||||||
to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->assoc));
|
if (areq->assoclen)
|
||||||
|
to_talitos_ptr(&desc->ptr[1],
|
||||||
|
sg_dma_address(areq->assoc));
|
||||||
|
else
|
||||||
|
to_talitos_ptr(&desc->ptr[1], edesc->iv_dma);
|
||||||
desc->ptr[1].j_extent = 0;
|
desc->ptr[1].j_extent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1108,7 +1112,8 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
|
||||||
unsigned int authsize,
|
unsigned int authsize,
|
||||||
unsigned int ivsize,
|
unsigned int ivsize,
|
||||||
int icv_stashing,
|
int icv_stashing,
|
||||||
u32 cryptoflags)
|
u32 cryptoflags,
|
||||||
|
bool encrypt)
|
||||||
{
|
{
|
||||||
struct talitos_edesc *edesc;
|
struct talitos_edesc *edesc;
|
||||||
int assoc_nents = 0, src_nents, dst_nents, alloc_len, dma_len;
|
int assoc_nents = 0, src_nents, dst_nents, alloc_len, dma_len;
|
||||||
|
@ -1122,10 +1127,10 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iv)
|
if (ivsize)
|
||||||
iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
|
iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
|
||||||
|
|
||||||
if (assoc) {
|
if (assoclen) {
|
||||||
/*
|
/*
|
||||||
* Currently it is assumed that iv is provided whenever assoc
|
* Currently it is assumed that iv is provided whenever assoc
|
||||||
* is.
|
* is.
|
||||||
|
@ -1141,19 +1146,17 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
|
||||||
assoc_nents = assoc_nents ? assoc_nents + 1 : 2;
|
assoc_nents = assoc_nents ? assoc_nents + 1 : 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
src_nents = sg_count(src, cryptlen + authsize, &src_chained);
|
if (!dst || dst == src) {
|
||||||
src_nents = (src_nents == 1) ? 0 : src_nents;
|
src_nents = sg_count(src, cryptlen + authsize, &src_chained);
|
||||||
|
src_nents = (src_nents == 1) ? 0 : src_nents;
|
||||||
if (!dst) {
|
dst_nents = dst ? src_nents : 0;
|
||||||
dst_nents = 0;
|
} else { /* dst && dst != src*/
|
||||||
} else {
|
src_nents = sg_count(src, cryptlen + (encrypt ? 0 : authsize),
|
||||||
if (dst == src) {
|
&src_chained);
|
||||||
dst_nents = src_nents;
|
src_nents = (src_nents == 1) ? 0 : src_nents;
|
||||||
} else {
|
dst_nents = sg_count(dst, cryptlen + (encrypt ? authsize : 0),
|
||||||
dst_nents = sg_count(dst, cryptlen + authsize,
|
&dst_chained);
|
||||||
&dst_chained);
|
dst_nents = (dst_nents == 1) ? 0 : dst_nents;
|
||||||
dst_nents = (dst_nents == 1) ? 0 : dst_nents;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1173,9 +1176,16 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
|
||||||
|
|
||||||
edesc = kmalloc(alloc_len, GFP_DMA | flags);
|
edesc = kmalloc(alloc_len, GFP_DMA | flags);
|
||||||
if (!edesc) {
|
if (!edesc) {
|
||||||
talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE);
|
if (assoc_chained)
|
||||||
|
talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE);
|
||||||
|
else if (assoclen)
|
||||||
|
dma_unmap_sg(dev, assoc,
|
||||||
|
assoc_nents ? assoc_nents - 1 : 1,
|
||||||
|
DMA_TO_DEVICE);
|
||||||
|
|
||||||
if (iv_dma)
|
if (iv_dma)
|
||||||
dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
|
dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
|
||||||
|
|
||||||
dev_err(dev, "could not allocate edescriptor\n");
|
dev_err(dev, "could not allocate edescriptor\n");
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
|
@ -1197,7 +1207,7 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
|
static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
|
||||||
int icv_stashing)
|
int icv_stashing, bool encrypt)
|
||||||
{
|
{
|
||||||
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
|
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
|
||||||
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
|
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
|
||||||
|
@ -1206,7 +1216,7 @@ static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
|
||||||
return talitos_edesc_alloc(ctx->dev, areq->assoc, areq->src, areq->dst,
|
return talitos_edesc_alloc(ctx->dev, areq->assoc, areq->src, areq->dst,
|
||||||
iv, areq->assoclen, areq->cryptlen,
|
iv, areq->assoclen, areq->cryptlen,
|
||||||
ctx->authsize, ivsize, icv_stashing,
|
ctx->authsize, ivsize, icv_stashing,
|
||||||
areq->base.flags);
|
areq->base.flags, encrypt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aead_encrypt(struct aead_request *req)
|
static int aead_encrypt(struct aead_request *req)
|
||||||
|
@ -1216,7 +1226,7 @@ static int aead_encrypt(struct aead_request *req)
|
||||||
struct talitos_edesc *edesc;
|
struct talitos_edesc *edesc;
|
||||||
|
|
||||||
/* allocate extended descriptor */
|
/* allocate extended descriptor */
|
||||||
edesc = aead_edesc_alloc(req, req->iv, 0);
|
edesc = aead_edesc_alloc(req, req->iv, 0, true);
|
||||||
if (IS_ERR(edesc))
|
if (IS_ERR(edesc))
|
||||||
return PTR_ERR(edesc);
|
return PTR_ERR(edesc);
|
||||||
|
|
||||||
|
@ -1239,7 +1249,7 @@ static int aead_decrypt(struct aead_request *req)
|
||||||
req->cryptlen -= authsize;
|
req->cryptlen -= authsize;
|
||||||
|
|
||||||
/* allocate extended descriptor */
|
/* allocate extended descriptor */
|
||||||
edesc = aead_edesc_alloc(req, req->iv, 1);
|
edesc = aead_edesc_alloc(req, req->iv, 1, false);
|
||||||
if (IS_ERR(edesc))
|
if (IS_ERR(edesc))
|
||||||
return PTR_ERR(edesc);
|
return PTR_ERR(edesc);
|
||||||
|
|
||||||
|
@ -1285,7 +1295,7 @@ static int aead_givencrypt(struct aead_givcrypt_request *req)
|
||||||
struct talitos_edesc *edesc;
|
struct talitos_edesc *edesc;
|
||||||
|
|
||||||
/* allocate extended descriptor */
|
/* allocate extended descriptor */
|
||||||
edesc = aead_edesc_alloc(areq, req->giv, 0);
|
edesc = aead_edesc_alloc(areq, req->giv, 0, true);
|
||||||
if (IS_ERR(edesc))
|
if (IS_ERR(edesc))
|
||||||
return PTR_ERR(edesc);
|
return PTR_ERR(edesc);
|
||||||
|
|
||||||
|
@ -1441,7 +1451,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
|
static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
|
||||||
areq)
|
areq, bool encrypt)
|
||||||
{
|
{
|
||||||
struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
|
struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
|
||||||
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
|
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
|
||||||
|
@ -1449,7 +1459,7 @@ static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
|
||||||
|
|
||||||
return talitos_edesc_alloc(ctx->dev, NULL, areq->src, areq->dst,
|
return talitos_edesc_alloc(ctx->dev, NULL, areq->src, areq->dst,
|
||||||
areq->info, 0, areq->nbytes, 0, ivsize, 0,
|
areq->info, 0, areq->nbytes, 0, ivsize, 0,
|
||||||
areq->base.flags);
|
areq->base.flags, encrypt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ablkcipher_encrypt(struct ablkcipher_request *areq)
|
static int ablkcipher_encrypt(struct ablkcipher_request *areq)
|
||||||
|
@ -1459,7 +1469,7 @@ static int ablkcipher_encrypt(struct ablkcipher_request *areq)
|
||||||
struct talitos_edesc *edesc;
|
struct talitos_edesc *edesc;
|
||||||
|
|
||||||
/* allocate extended descriptor */
|
/* allocate extended descriptor */
|
||||||
edesc = ablkcipher_edesc_alloc(areq);
|
edesc = ablkcipher_edesc_alloc(areq, true);
|
||||||
if (IS_ERR(edesc))
|
if (IS_ERR(edesc))
|
||||||
return PTR_ERR(edesc);
|
return PTR_ERR(edesc);
|
||||||
|
|
||||||
|
@ -1476,7 +1486,7 @@ static int ablkcipher_decrypt(struct ablkcipher_request *areq)
|
||||||
struct talitos_edesc *edesc;
|
struct talitos_edesc *edesc;
|
||||||
|
|
||||||
/* allocate extended descriptor */
|
/* allocate extended descriptor */
|
||||||
edesc = ablkcipher_edesc_alloc(areq);
|
edesc = ablkcipher_edesc_alloc(areq, false);
|
||||||
if (IS_ERR(edesc))
|
if (IS_ERR(edesc))
|
||||||
return PTR_ERR(edesc);
|
return PTR_ERR(edesc);
|
||||||
|
|
||||||
|
@ -1628,7 +1638,7 @@ static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
|
||||||
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
|
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
|
||||||
|
|
||||||
return talitos_edesc_alloc(ctx->dev, NULL, req_ctx->psrc, NULL, NULL, 0,
|
return talitos_edesc_alloc(ctx->dev, NULL, req_ctx->psrc, NULL, NULL, 0,
|
||||||
nbytes, 0, 0, 0, areq->base.flags);
|
nbytes, 0, 0, 0, areq->base.flags, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ahash_init(struct ahash_request *areq)
|
static int ahash_init(struct ahash_request *areq)
|
||||||
|
|
|
@ -36,6 +36,7 @@ static inline void scatterwalk_sg_chain(struct scatterlist *sg1, int num,
|
||||||
{
|
{
|
||||||
sg_set_page(&sg1[num - 1], (void *)sg2, 0, 0);
|
sg_set_page(&sg1[num - 1], (void *)sg2, 0, 0);
|
||||||
sg1[num - 1].page_link &= ~0x02;
|
sg1[num - 1].page_link &= ~0x02;
|
||||||
|
sg1[num - 1].page_link |= 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
|
static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
|
||||||
|
|
Loading…
Add table
Reference in a new issue