crypto: ccree - add SM4 support
authorGilad Ben-Yossef <gilad@benyossef.com>
Mon, 29 Oct 2018 09:50:14 +0000 (09:50 +0000)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 9 Nov 2018 09:36:49 +0000 (17:36 +0800)
Add support for SM4 cipher in CryptoCell 713.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/Kconfig
drivers/crypto/ccree/cc_cipher.c
drivers/crypto/ccree/cc_hw_queue_defs.h

index 75d401c32a16a10cd0ce86fb003c970d69e375b0..1de998d5bdb56898035cdb48ecbe40753501d6da 100644 (file)
@@ -762,6 +762,7 @@ config CRYPTO_DEV_CCREE
        select CRYPTO_ECB
        select CRYPTO_CTR
        select CRYPTO_XTS
+       select CRYPTO_SM4
        help
          Say 'Y' to enable a driver for the REE interface of the Arm
          TrustZone CryptoCell family of processors. Currently the
index 7623b29911af443ed62491acad2916f078e58a01..989e70f43bd96075399ba6ce14959a726d7588ed 100644 (file)
@@ -7,6 +7,7 @@
 #include <crypto/internal/skcipher.h>
 #include <crypto/des.h>
 #include <crypto/xts.h>
+#include <crypto/sm4.h>
 #include <crypto/scatterwalk.h>
 
 #include "cc_driver.h"
@@ -83,6 +84,9 @@ static int validate_keys_sizes(struct cc_cipher_ctx *ctx_p, u32 size)
                if (size == DES3_EDE_KEY_SIZE || size == DES_KEY_SIZE)
                        return 0;
                break;
+       case S_DIN_to_SM4:
+               if (size == SM4_KEY_SIZE)
+                       return 0;
        default:
                break;
        }
@@ -122,6 +126,17 @@ static int validate_data_size(struct cc_cipher_ctx *ctx_p,
                if (IS_ALIGNED(size, DES_BLOCK_SIZE))
                        return 0;
                break;
+       case S_DIN_to_SM4:
+               switch (ctx_p->cipher_mode) {
+               case DRV_CIPHER_CTR:
+                       return 0;
+               case DRV_CIPHER_ECB:
+               case DRV_CIPHER_CBC:
+                       if (IS_ALIGNED(size, SM4_BLOCK_SIZE))
+                               return 0;
+               default:
+                       break;
+               }
        default:
                break;
        }
@@ -522,6 +537,9 @@ static void cc_setup_cipher_data(struct crypto_tfm *tfm,
        case S_DIN_to_DES:
                flow_mode = DIN_DES_DOUT;
                break;
+       case S_DIN_to_SM4:
+               flow_mode = DIN_SM4_DOUT;
+               break;
        default:
                dev_err(dev, "invalid flow mode, flow_mode = %d\n", flow_mode);
                return;
@@ -1324,6 +1342,54 @@ static const struct cc_alg_template skcipher_algs[] = {
                .flow_mode = S_DIN_to_DES,
                .min_hw_rev = CC_HW_REV_630,
        },
+       {
+               .name = "cbc(sm4)",
+               .driver_name = "cbc-sm4-ccree",
+               .blocksize = SM4_BLOCK_SIZE,
+               .template_skcipher = {
+                       .setkey = cc_cipher_setkey,
+                       .encrypt = cc_cipher_encrypt,
+                       .decrypt = cc_cipher_decrypt,
+                       .min_keysize = SM4_KEY_SIZE,
+                       .max_keysize = SM4_KEY_SIZE,
+                       .ivsize = SM4_BLOCK_SIZE,
+                       },
+               .cipher_mode = DRV_CIPHER_CBC,
+               .flow_mode = S_DIN_to_SM4,
+               .min_hw_rev = CC_HW_REV_713,
+       },
+       {
+               .name = "ecb(sm4)",
+               .driver_name = "ecb-sm4-ccree",
+               .blocksize = SM4_BLOCK_SIZE,
+               .template_skcipher = {
+                       .setkey = cc_cipher_setkey,
+                       .encrypt = cc_cipher_encrypt,
+                       .decrypt = cc_cipher_decrypt,
+                       .min_keysize = SM4_KEY_SIZE,
+                       .max_keysize = SM4_KEY_SIZE,
+                       .ivsize = 0,
+                       },
+               .cipher_mode = DRV_CIPHER_ECB,
+               .flow_mode = S_DIN_to_SM4,
+               .min_hw_rev = CC_HW_REV_713,
+       },
+       {
+               .name = "ctr(sm4)",
+               .driver_name = "ctr-sm4-ccree",
+               .blocksize = SM4_BLOCK_SIZE,
+               .template_skcipher = {
+                       .setkey = cc_cipher_setkey,
+                       .encrypt = cc_cipher_encrypt,
+                       .decrypt = cc_cipher_decrypt,
+                       .min_keysize = SM4_KEY_SIZE,
+                       .max_keysize = SM4_KEY_SIZE,
+                       .ivsize = SM4_BLOCK_SIZE,
+                       },
+               .cipher_mode = DRV_CIPHER_CTR,
+               .flow_mode = S_DIN_to_SM4,
+               .min_hw_rev = CC_HW_REV_713,
+       },
 };
 
 static struct cc_crypto_alg *cc_create_alg(const struct cc_alg_template *tmpl,
index 45985b955d2c899c1478ce43d2d279c6590d9e0a..f719ff9c0277de6ad23b8b245bc6a9091b30fc0c 100644 (file)
@@ -107,6 +107,7 @@ enum cc_flow_mode {
        AES_to_AES_to_HASH_and_DOUT     = 13,
        AES_to_AES_to_HASH      = 14,
        AES_to_HASH_and_AES     = 15,
+       DIN_SM4_DOUT            = 16,
        DIN_AES_AESMAC          = 17,
        HASH_to_DOUT            = 18,
        /* setup flows */
@@ -114,9 +115,11 @@ enum cc_flow_mode {
        S_DIN_to_AES2           = 33,
        S_DIN_to_DES            = 34,
        S_DIN_to_RC4            = 35,
+       S_DIN_to_SM4            = 36,
        S_DIN_to_HASH           = 37,
        S_AES_to_DOUT           = 38,
        S_AES2_to_DOUT          = 39,
+       S_SM4_to_DOUT           = 40,
        S_RC4_to_DOUT           = 41,
        S_DES_to_DOUT           = 42,
        S_HASH_to_DOUT          = 43,