CR_1831:crypto:starfive: Add fallback algo for crypto drivers
authorjiajie.ho <jiajie.ho@starfivetech.com>
Tue, 23 Aug 2022 02:48:11 +0000 (10:48 +0800)
committerjiajie.ho <jiajie.ho@starfivetech.com>
Wed, 24 Aug 2022 08:34:17 +0000 (16:34 +0800)
Add software fallback for RSA driver to support key sizes > 2Kb.
Add software fallback for Hash driver for smaller input data
blocksize to improve overall hash module efficiency.

Signed-off-by: jiajie.ho <jiajie.ho@starfivetech.com>
drivers/crypto/starfive/jh7110/jh7110-pka.c
drivers/crypto/starfive/jh7110/jh7110-sha.c
drivers/crypto/starfive/jh7110/jh7110-str.h

index 7c4b3eb..1831c30 100644 (file)
@@ -24,8 +24,8 @@
 #include "jh7110-str.h"
 
 #define JH7110_RSA_KEYSZ_LEN                   (2048 >> 2)
-#define JH7110_RSA_KEY_SIZE                            (JH7110_RSA_KEYSZ_LEN * 3)
-
+#define JH7110_RSA_KEY_SIZE                    (JH7110_RSA_KEYSZ_LEN * 3)
+#define JH7110_RSA_MAX_KEYSZ                   256
 #define swap32(val) (                                          \
                     (((u32)(val) << 24) & (u32)0xFF000000) |   \
                     (((u32)(val) <<  8) & (u32)0x00FF0000) |   \
@@ -107,7 +107,6 @@ static int jh7110_rsa_domain_transfer(struct jh7110_sec_ctx *ctx, u32 *result, u
                rctx->csr.pka_csr.ie = 1;
                rctx->csr.pka_csr.start = 0x1;
                rctx->csr.pka_csr.not_r2 = 0x1;
-               //rctx->csr.pka_csr.bigendian = 1;
                jh7110_sec_write(sdev, JH7110_CRYPTO_CACR_OFFSET, rctx->csr.pka_csr.v);
 
                jh7110_pka_wait_done(sdev);
@@ -387,6 +386,13 @@ static int jh7110_rsa_enc(struct akcipher_request *req)
        struct jh7110_sec_request_ctx *rctx = akcipher_request_ctx(req);
        int ret = 0;
 
+       if (key->key_sz > JH7110_RSA_MAX_KEYSZ) {
+               akcipher_request_set_tfm(req, ctx->soft_tfm);
+               ret = crypto_akcipher_encrypt(req);
+               akcipher_request_set_tfm(req, tfm);
+               return ret;
+       }
+
        if (unlikely(!key->n || !key->e))
                return -EINVAL;
 
@@ -420,6 +426,13 @@ static int jh7110_rsa_dec(struct akcipher_request *req)
        struct jh7110_sec_request_ctx *rctx = akcipher_request_ctx(req);
        int ret = 0;
 
+       if (key->key_sz > JH7110_RSA_MAX_KEYSZ) {
+               akcipher_request_set_tfm(req, ctx->soft_tfm);
+               ret = crypto_akcipher_decrypt(req);
+               akcipher_request_set_tfm(req, tfm);
+               return ret;
+       }
+
        if (unlikely(!key->n || !key->d))
                return -EINVAL;
 
@@ -452,10 +465,10 @@ static unsigned long jh7110_rsa_enc_fn_id(unsigned int len)
        if (bitslen & 0x1f)
                return -EINVAL;
 
-       if (bitslen < 32 || bitslen > 2048)
-               return -EINVAL;
+       if (bitslen > 2048)
+               return false;
 
-       return 0;
+       return true;
 }
 
 static int jh7110_rsa_set_n(struct jh7110_rsa_key *rsa_key, const char *value,
@@ -471,15 +484,15 @@ static int jh7110_rsa_set_n(struct jh7110_rsa_key *rsa_key, const char *value,
        rsa_key->key_sz = vlen;
        ret = -EINVAL;
        /* invalid key size provided */
-       if (jh7110_rsa_enc_fn_id(rsa_key->key_sz))
-               goto err;
+       if (!jh7110_rsa_enc_fn_id(rsa_key->key_sz))
+               return 0;
 
        ret = -ENOMEM;
        rsa_key->n = kmemdup(ptr, rsa_key->key_sz, GFP_KERNEL);
        if (!rsa_key->n)
                goto err;
 
-       return 0;
+       return 1;
  err:
        rsa_key->key_sz = 0;
        rsa_key->n = NULL;
@@ -578,8 +591,9 @@ static int jh7110_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
                goto err;
 
        ret = jh7110_rsa_set_n(rsa_key, raw_key.n, raw_key.n_sz);
-       if (ret < 0)
-               goto err;
+       if (ret <= 0)
+               return ret;
+
        ret = jh7110_rsa_set_e(rsa_key, raw_key.e, raw_key.e_sz);
        if (ret < 0)
                goto err;
@@ -610,12 +624,26 @@ static int jh7110_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
 static int jh7110_rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
                               unsigned int keylen)
 {
+       struct jh7110_sec_ctx *ctx = akcipher_tfm_ctx(tfm);
+       int ret;
+
+       ret = crypto_akcipher_set_pub_key(ctx->soft_tfm, key, keylen);
+       if (ret)
+               return ret;
+
        return jh7110_rsa_setkey(tfm, key, keylen, false);
 }
 
 static int jh7110_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
                                unsigned int keylen)
 {
+       struct jh7110_sec_ctx *ctx = akcipher_tfm_ctx(tfm);
+       int ret;
+
+       ret = crypto_akcipher_set_priv_key(ctx->soft_tfm, key, keylen);
+       if (ret)
+               return ret;
+
        return jh7110_rsa_setkey(tfm, key, keylen, true);
 }
 
@@ -623,6 +651,10 @@ static unsigned int jh7110_rsa_max_size(struct crypto_akcipher *tfm)
 {
        struct jh7110_sec_ctx *ctx = akcipher_tfm_ctx(tfm);
 
+       /* For key sizes > 2Kb, use software tfm */
+       if (ctx->rsa_key.key_sz > JH7110_RSA_MAX_KEYSZ)
+               return crypto_akcipher_maxsize(ctx->soft_tfm);
+
        return ctx->rsa_key.key_sz;
 }
 
@@ -631,9 +663,17 @@ static int jh7110_rsa_init_tfm(struct crypto_akcipher *tfm)
 {
        struct jh7110_sec_ctx *ctx = akcipher_tfm_ctx(tfm);
 
+       ctx->soft_tfm = crypto_alloc_akcipher("rsa-generic", 0, 0);
+       if (IS_ERR(ctx->soft_tfm)) {
+               pr_err("Can not alloc_akcipher!\n");
+               return PTR_ERR(ctx->soft_tfm);
+       }
+
        ctx->sdev = jh7110_sec_find_dev(ctx);
-       if (!ctx->sdev)
+       if (!ctx->sdev) {
+               crypto_free_akcipher(ctx->soft_tfm);
                return -ENODEV;
+       }
 
        akcipher_set_reqsize(tfm, sizeof(struct jh7110_sec_request_ctx));
 
@@ -646,6 +686,7 @@ static void jh7110_rsa_exit_tfm(struct crypto_akcipher *tfm)
        struct jh7110_sec_ctx *ctx = akcipher_tfm_ctx(tfm);
        struct jh7110_rsa_key *key = (struct jh7110_rsa_key *)&ctx->rsa_key;
 
+       crypto_free_akcipher(ctx->soft_tfm);
        jh7110_rsa_free_key(key);
 }
 
@@ -664,7 +705,8 @@ static struct akcipher_alg jh7110_rsa = {
                .cra_name = "rsa",
                .cra_driver_name = "rsa-jh7110",
                .cra_flags = CRYPTO_ALG_TYPE_AKCIPHER |
-                                               CRYPTO_ALG_ASYNC,
+                            CRYPTO_ALG_ASYNC |
+                            CRYPTO_ALG_NEED_FALLBACK,
                .cra_priority = 3000,
                .cra_module = THIS_MODULE,
                .cra_ctxsize = sizeof(struct jh7110_sec_ctx),
index bbdaba2..0be29a6 100644 (file)
@@ -41,6 +41,7 @@
 #define JH7110_MAX_ALIGN_SIZE  SHA512_BLOCK_SIZE
 
 #define JH7110_HASH_BUFLEN             8192
+#define JH7110_HASH_THRES              2048
 
 static inline int jh7110_hash_wait_hmac_done(struct jh7110_sec_ctx *ctx)
 {
@@ -329,7 +330,6 @@ static int jh7110_hash_xmit(struct jh7110_sec_ctx *ctx, int flags)
        if (!rctx->csr.sha_csr.hmac) {
                rctx->csr.sha_csr.start = 1;
                rctx->csr.sha_csr.firstb = 1;
-               ctx->sec_init = 0;
                jh7110_sec_write(sdev, JH7110_SHA_SHACSR, rctx->csr.sha_csr.v);
        }
 
@@ -379,7 +379,7 @@ static int jh7110_hash_update_req(struct jh7110_sec_ctx *ctx)
 
        if (final) {
                err = jh7110_hash_xmit(ctx,
-                                       (rctx->flags & HASH_FLAGS_FINUP));
+                               (rctx->flags & HASH_FLAGS_FINUP));
                rctx->bufcnt = 0;
        }
 
@@ -567,9 +567,19 @@ static int jh7110_hash_update(struct ahash_request *req)
 static int jh7110_hash_final(struct ahash_request *req)
 {
        struct jh7110_sec_request_ctx *rctx = ahash_request_ctx(req);
+       struct jh7110_sec_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
 
        rctx->flags |= HASH_FLAGS_FINUP;
 
+       if (ctx->fallback_available && (rctx->bufcnt < JH7110_HASH_THRES)) {
+               if (ctx->sha_mode & JH7110_SHA_HMAC_FLAGS)
+                       crypto_shash_setkey(ctx->fallback, ctx->key,
+                                       ctx->keylen);
+
+               return crypto_shash_tfm_digest(ctx->fallback, ctx->buffer,
+                               rctx->bufcnt, req->result);
+       }
+
        return jh7110_hash_enqueue(req, HASH_OP_FINAL);
 }
 
@@ -625,16 +635,25 @@ static int jh7110_hash_cra_init_algs(struct crypto_tfm *tfm,
                                        unsigned int mode)
 {
        struct jh7110_sec_ctx *ctx = crypto_tfm_ctx(tfm);
+       const char *alg_name = crypto_tfm_alg_name(tfm);
 
        ctx->sdev = jh7110_sec_find_dev(ctx);
+       ctx->fallback_available = true;
 
        if (!ctx->sdev)
                return -ENODEV;
 
+       ctx->fallback = crypto_alloc_shash(alg_name, 0,
+                       CRYPTO_ALG_NEED_FALLBACK);
+       
+       if (IS_ERR(ctx->fallback)) {
+               pr_err("fallback unavailable for '%s'\n", alg_name);
+               ctx->fallback_available = false;
+       }
+
        crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
-                               sizeof(struct jh7110_sec_request_ctx));
+                       sizeof(struct jh7110_sec_request_ctx));
 
-       ctx->sec_init = 1;
        ctx->keylen   = 0;
        ctx->sha_mode = mode;
        ctx->sha_len_total = 0;
@@ -654,6 +673,9 @@ static void jh7110_hash_cra_exit(struct crypto_tfm *tfm)
 {
        struct jh7110_sec_ctx *ctx = crypto_tfm_ctx(tfm);
 
+       crypto_free_shash(ctx->fallback);
+
+       ctx->fallback = NULL;
        ctx->enginectx.op.do_one_request = NULL;
        ctx->enginectx.op.prepare_request = NULL;
        ctx->enginectx.op.unprepare_request = NULL;
@@ -890,193 +912,199 @@ static int jh7110_hash_cra_hmac_sm3_init(struct crypto_tfm *tfm)
 }
 
 static struct ahash_alg algs_sha0_sha512_sm3[] = {
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SHA1_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "sha1",
-                               .cra_driver_name        = "jh7110-sha1",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA1_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_sha1_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SHA1_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "sha1",
+                       .cra_driver_name        = "jh7110-sha1",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA1_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_sha1_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .setkey   = jh7110_hash1_setkey,
-               .halg = {
-                       .digestsize = SHA1_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "hmac(sha1)",
-                               .cra_driver_name        = "jh7110-hmac-sha1",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA1_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_hmac_sha1_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .setkey   = jh7110_hash1_setkey,
+       .halg = {
+               .digestsize = SHA1_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "hmac(sha1)",
+                       .cra_driver_name        = "jh7110-hmac-sha1",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA1_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_hmac_sha1_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SHA224_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "sha224",
-                               .cra_driver_name        = "jh7110-sha224",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA224_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_sha224_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SHA224_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "sha224",
+                       .cra_driver_name        = "jh7110-sha224",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA224_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_sha224_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .setkey   = jh7110_hash224_setkey,
-               .halg = {
-                       .digestsize = SHA224_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "hmac(sha224)",
-                               .cra_driver_name        = "jh7110-hmac-sha224",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA224_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_hmac_sha224_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .setkey   = jh7110_hash224_setkey,
+       .halg = {
+               .digestsize = SHA224_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "hmac(sha224)",
+                       .cra_driver_name        = "jh7110-hmac-sha224",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA224_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_hmac_sha224_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SHA256_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "sha256",
-                               .cra_driver_name        = "jh7110-sha256",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA256_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_sha256_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SHA256_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "sha256",
+                       .cra_driver_name        = "jh7110-sha256",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA256_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_sha256_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .setkey   = jh7110_hash256_setkey,
-               .halg = {
-                       .digestsize = SHA256_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "hmac(sha256)",
-                               .cra_driver_name        = "jh7110-hmac-sha256",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA256_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_hmac_sha256_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .setkey   = jh7110_hash256_setkey,
+       .halg = {
+               .digestsize = SHA256_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "hmac(sha256)",
+                       .cra_driver_name        = "jh7110-hmac-sha256",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA256_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_hmac_sha256_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SHA384_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "sha384",
-                               .cra_driver_name        = "jh7110-sha384",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA384_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_sha384_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SHA384_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "sha384",
+                       .cra_driver_name        = "jh7110-sha384",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA384_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_sha384_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
+       }
+},
+{
                .init     = jh7110_hash_init,
                .update   = jh7110_hash_update,
                .final    = jh7110_hash_final,
@@ -1092,123 +1120,127 @@ static struct ahash_alg algs_sha0_sha512_sm3[] = {
                                .cra_name                       = "hmac(sha384)",
                                .cra_driver_name        = "jh7110-hmac-sha384",
                                .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
+                               .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                         CRYPTO_ALG_TYPE_AHASH |
+                                                         CRYPTO_ALG_NEED_FALLBACK,
                                .cra_blocksize          = SHA384_BLOCK_SIZE,
                                .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
                                .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_hmac_sha384_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
+                               .cra_init               = jh7110_hash_cra_hmac_sha384_init,
+                               .cra_exit               = jh7110_hash_cra_exit,
+                               .cra_module             = THIS_MODULE,
                        }
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SHA512_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "sha512",
-                               .cra_driver_name        = "jh7110-sha512",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA512_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_sha512_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SHA512_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name                       = "sha512",
+                       .cra_driver_name        = "jh7110-sha512",
+                       .cra_priority           = 200,
+                       .cra_flags                      = CRYPTO_ALG_ASYNC |
+                               CRYPTO_ALG_TYPE_AHASH,
+                       .cra_blocksize          = SHA512_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init                       = jh7110_hash_cra_sha512_init,
+                       .cra_exit                       = jh7110_hash_cra_exit,
+                       .cra_module                     = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .setkey   = jh7110_hash512_setkey,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SHA512_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "hmac(sha512)",
-                               .cra_driver_name        = "jh7110-hmac-sha512",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SHA512_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_hmac_sha512_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .setkey   = jh7110_hash512_setkey,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SHA512_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "hmac(sha512)",
+                       .cra_driver_name        = "jh7110-hmac-sha512",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SHA512_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_hmac_sha512_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init     = jh7110_hash_init,
-               .update   = jh7110_hash_update,
-               .final    = jh7110_hash_final,
-               .finup    = jh7110_hash_finup,
-               .digest   = jh7110_hash_digest,
-               .export   = jh7110_hash_export,
-               .import   = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SM3_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "sm3",
-                               .cra_driver_name        = "jh7110-sm3",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SM3_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_sm3_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init     = jh7110_hash_init,
+       .update   = jh7110_hash_update,
+       .final    = jh7110_hash_final,
+       .finup    = jh7110_hash_finup,
+       .digest   = jh7110_hash_digest,
+       .export   = jh7110_hash_export,
+       .import   = jh7110_hash_import,
+       .halg = {
+               .digestsize = SM3_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "sm3",
+                       .cra_driver_name        = "jh7110-sm3",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SM3_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_sm3_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
-       {
-               .init           = jh7110_hash_init,
-               .update         = jh7110_hash_update,
-               .final          = jh7110_hash_final,
-               .finup          = jh7110_hash_finup,
-               .digest         = jh7110_hash_digest,
-               .setkey         = jh7110_sm3_setkey,
-               .export         = jh7110_hash_export,
-               .import         = jh7110_hash_import,
-               .halg = {
-                       .digestsize = SM3_DIGEST_SIZE,
-                       .statesize  = sizeof(struct jh7110_sec_request_ctx),
-                       .base = {
-                               .cra_name                       = "hmac(sm3)",
-                               .cra_driver_name        = "jh7110-hmac-sm3",
-                               .cra_priority           = 200,
-                               .cra_flags                      = CRYPTO_ALG_ASYNC |
-                                                                               CRYPTO_ALG_TYPE_AHASH,
-                               .cra_blocksize          = SM3_BLOCK_SIZE,
-                               .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
-                               .cra_alignmask          = 3,
-                               .cra_init                       = jh7110_hash_cra_hmac_sm3_init,
-                               .cra_exit                       = jh7110_hash_cra_exit,
-                               .cra_module                     = THIS_MODULE,
-                       }
+       }
+},
+{
+       .init           = jh7110_hash_init,
+       .update         = jh7110_hash_update,
+       .final          = jh7110_hash_final,
+       .finup          = jh7110_hash_finup,
+       .digest         = jh7110_hash_digest,
+       .setkey         = jh7110_sm3_setkey,
+       .export         = jh7110_hash_export,
+       .import         = jh7110_hash_import,
+       .halg = {
+               .digestsize = SM3_DIGEST_SIZE,
+               .statesize  = sizeof(struct jh7110_sec_request_ctx),
+               .base = {
+                       .cra_name               = "hmac(sm3)",
+                       .cra_driver_name        = "jh7110-hmac-sm3",
+                       .cra_priority           = 200,
+                       .cra_flags              = CRYPTO_ALG_ASYNC |
+                                                 CRYPTO_ALG_TYPE_AHASH |
+                                                 CRYPTO_ALG_NEED_FALLBACK,
+                       .cra_blocksize          = SM3_BLOCK_SIZE,
+                       .cra_ctxsize            = sizeof(struct jh7110_sec_ctx),
+                       .cra_alignmask          = 3,
+                       .cra_init               = jh7110_hash_cra_hmac_sm3_init,
+                       .cra_exit               = jh7110_hash_cra_exit,
+                       .cra_module             = THIS_MODULE,
                }
-       },
+       }
+},
 };
 
 int jh7110_hash_register_algs(void)
index 085fa2e..5e7d896 100644 (file)
@@ -60,6 +60,9 @@ struct jh7110_sec_ctx {
        struct jh7110_rsa_key                   rsa_key;
        size_t                                  sha_len_total;
        u8                                      *buffer;
+       struct crypto_akcipher                  *soft_tfm;
+       struct crypto_shash                     *fallback;
+       bool                                    fallback_available;
 };
 
 struct jh7110_sec_dev {