summaryrefslogtreecommitdiff
path: root/drivers/crypto/qce
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/crypto/qce')
-rw-r--r--drivers/crypto/qce/cipher.h3
-rw-r--r--drivers/crypto/qce/common.h2
-rw-r--r--drivers/crypto/qce/sha.c36
-rw-r--r--drivers/crypto/qce/skcipher.c43
4 files changed, 56 insertions, 28 deletions
diff --git a/drivers/crypto/qce/cipher.h b/drivers/crypto/qce/cipher.h
index 7770660bc853..cffa9fc628ff 100644
--- a/drivers/crypto/qce/cipher.h
+++ b/drivers/crypto/qce/cipher.h
@@ -14,7 +14,7 @@
struct qce_cipher_ctx {
u8 enc_key[QCE_MAX_KEY_SIZE];
unsigned int enc_keylen;
- struct crypto_sync_skcipher *fallback;
+ struct crypto_skcipher *fallback;
};
/**
@@ -43,6 +43,7 @@ struct qce_cipher_reqctx {
struct sg_table src_tbl;
struct scatterlist *src_sg;
unsigned int cryptlen;
+ struct skcipher_request fallback_req; // keep at the end
};
static inline struct qce_alg_template *to_cipher_tmpl(struct crypto_skcipher *tfm)
diff --git a/drivers/crypto/qce/common.h b/drivers/crypto/qce/common.h
index 9f989cba0f1b..85ba16418a04 100644
--- a/drivers/crypto/qce/common.h
+++ b/drivers/crypto/qce/common.h
@@ -87,6 +87,8 @@ struct qce_alg_template {
struct ahash_alg ahash;
} alg;
struct qce_device *qce;
+ const u8 *hash_zero;
+ const u32 digest_size;
};
void qce_cpu_to_be32p_array(__be32 *dst, const u8 *src, unsigned int len);
diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c
index 1ab62e7d5f3c..c230843e2ffb 100644
--- a/drivers/crypto/qce/sha.c
+++ b/drivers/crypto/qce/sha.c
@@ -203,10 +203,18 @@ static int qce_import_common(struct ahash_request *req, u64 in_count,
static int qce_ahash_import(struct ahash_request *req, const void *in)
{
- struct qce_sha_reqctx *rctx = ahash_request_ctx(req);
- unsigned long flags = rctx->flags;
- bool hmac = IS_SHA_HMAC(flags);
- int ret = -EINVAL;
+ struct qce_sha_reqctx *rctx;
+ unsigned long flags;
+ bool hmac;
+ int ret;
+
+ ret = qce_ahash_init(req);
+ if (ret)
+ return ret;
+
+ rctx = ahash_request_ctx(req);
+ flags = rctx->flags;
+ hmac = IS_SHA_HMAC(flags);
if (IS_SHA1(flags) || IS_SHA1_HMAC(flags)) {
const struct sha1_state *state = in;
@@ -284,8 +292,6 @@ static int qce_ahash_update(struct ahash_request *req)
if (!sg_last)
return -EINVAL;
- sg_mark_end(sg_last);
-
if (rctx->buflen) {
sg_init_table(rctx->sg, 2);
sg_set_buf(rctx->sg, rctx->tmpbuf, rctx->buflen);
@@ -305,8 +311,12 @@ static int qce_ahash_final(struct ahash_request *req)
struct qce_alg_template *tmpl = to_ahash_tmpl(req->base.tfm);
struct qce_device *qce = tmpl->qce;
- if (!rctx->buflen)
+ if (!rctx->buflen) {
+ if (tmpl->hash_zero)
+ memcpy(req->result, tmpl->hash_zero,
+ tmpl->alg.ahash.halg.digestsize);
return 0;
+ }
rctx->last_blk = true;
@@ -338,6 +348,13 @@ static int qce_ahash_digest(struct ahash_request *req)
rctx->first_blk = true;
rctx->last_blk = true;
+ if (!rctx->nbytes_orig) {
+ if (tmpl->hash_zero)
+ memcpy(req->result, tmpl->hash_zero,
+ tmpl->alg.ahash.halg.digestsize);
+ return 0;
+ }
+
return qce->async_req_enqueue(tmpl->qce, &req->base);
}
@@ -490,6 +507,11 @@ static int qce_ahash_register_one(const struct qce_ahash_def *def,
alg->halg.digestsize = def->digestsize;
alg->halg.statesize = def->statesize;
+ if (IS_SHA1(def->flags))
+ tmpl->hash_zero = sha1_zero_message_hash;
+ else if (IS_SHA256(def->flags))
+ tmpl->hash_zero = sha256_zero_message_hash;
+
base = &alg->halg.base;
base->cra_blocksize = def->blocksize;
base->cra_priority = 300;
diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
index 9412433f3b21..5630c5addd28 100644
--- a/drivers/crypto/qce/skcipher.c
+++ b/drivers/crypto/qce/skcipher.c
@@ -178,7 +178,7 @@ static int qce_skcipher_setkey(struct crypto_skcipher *ablk, const u8 *key,
break;
}
- ret = crypto_sync_skcipher_setkey(ctx->fallback, key, keylen);
+ ret = crypto_skcipher_setkey(ctx->fallback, key, keylen);
if (!ret)
ctx->enc_keylen = keylen;
return ret;
@@ -235,16 +235,15 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
req->cryptlen <= aes_sw_max_len) ||
(IS_XTS(rctx->flags) && req->cryptlen > QCE_SECTOR_SIZE &&
req->cryptlen % QCE_SECTOR_SIZE))) {
- SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, ctx->fallback);
-
- skcipher_request_set_sync_tfm(subreq, ctx->fallback);
- skcipher_request_set_callback(subreq, req->base.flags,
- NULL, NULL);
- skcipher_request_set_crypt(subreq, req->src, req->dst,
- req->cryptlen, req->iv);
- ret = encrypt ? crypto_skcipher_encrypt(subreq) :
- crypto_skcipher_decrypt(subreq);
- skcipher_request_zero(subreq);
+ skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback);
+ skcipher_request_set_callback(&rctx->fallback_req,
+ req->base.flags,
+ req->base.complete,
+ req->base.data);
+ skcipher_request_set_crypt(&rctx->fallback_req, req->src,
+ req->dst, req->cryptlen, req->iv);
+ ret = encrypt ? crypto_skcipher_encrypt(&rctx->fallback_req) :
+ crypto_skcipher_decrypt(&rctx->fallback_req);
return ret;
}
@@ -263,10 +262,9 @@ static int qce_skcipher_decrypt(struct skcipher_request *req)
static int qce_skcipher_init(struct crypto_skcipher *tfm)
{
- struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
-
- memset(ctx, 0, sizeof(*ctx));
- crypto_skcipher_set_reqsize(tfm, sizeof(struct qce_cipher_reqctx));
+ /* take the size without the fallback skcipher_request at the end */
+ crypto_skcipher_set_reqsize(tfm, offsetof(struct qce_cipher_reqctx,
+ fallback_req));
return 0;
}
@@ -274,17 +272,21 @@ static int qce_skcipher_init_fallback(struct crypto_skcipher *tfm)
{
struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
- qce_skcipher_init(tfm);
- ctx->fallback = crypto_alloc_sync_skcipher(crypto_tfm_alg_name(&tfm->base),
- 0, CRYPTO_ALG_NEED_FALLBACK);
- return PTR_ERR_OR_ZERO(ctx->fallback);
+ ctx->fallback = crypto_alloc_skcipher(crypto_tfm_alg_name(&tfm->base),
+ 0, CRYPTO_ALG_NEED_FALLBACK);
+ if (IS_ERR(ctx->fallback))
+ return PTR_ERR(ctx->fallback);
+
+ crypto_skcipher_set_reqsize(tfm, sizeof(struct qce_cipher_reqctx) +
+ crypto_skcipher_reqsize(ctx->fallback));
+ return 0;
}
static void qce_skcipher_exit(struct crypto_skcipher *tfm)
{
struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
- crypto_free_sync_skcipher(ctx->fallback);
+ crypto_free_skcipher(ctx->fallback);
}
struct qce_skcipher_def {
@@ -404,6 +406,7 @@ static int qce_skcipher_register_one(const struct qce_skcipher_def *def,
alg->base.cra_priority = 300;
alg->base.cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_ALLOCATES_MEMORY |
CRYPTO_ALG_KERN_DRIVER_ONLY;
alg->base.cra_ctxsize = sizeof(struct qce_cipher_ctx);
alg->base.cra_alignmask = 0;