1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * SM4 using the RISC-V vector crypto extensions 4 * 5 * Copyright (C) 2023 VRULL GmbH 6 * Author: Heiko Stuebner <heiko.stuebner@vrull.eu> 7 * 8 * Copyright (C) 2023 SiFive, Inc. 9 * Author: Jerry Shih <jerry.shih@sifive.com> 10 */ 11 12 #include <asm/simd.h> 13 #include <asm/vector.h> 14 #include <crypto/internal/cipher.h> 15 #include <crypto/internal/simd.h> 16 #include <crypto/sm4.h> 17 #include <linux/linkage.h> 18 #include <linux/module.h> 19 20 asmlinkage void sm4_expandkey_zvksed_zvkb(const u8 user_key[SM4_KEY_SIZE], 21 u32 rkey_enc[SM4_RKEY_WORDS], 22 u32 rkey_dec[SM4_RKEY_WORDS]); 23 asmlinkage void sm4_crypt_zvksed_zvkb(const u32 rkey[SM4_RKEY_WORDS], 24 const u8 in[SM4_BLOCK_SIZE], 25 u8 out[SM4_BLOCK_SIZE]); 26 27 static int riscv64_sm4_setkey(struct crypto_tfm *tfm, const u8 *key, 28 unsigned int keylen) 29 { 30 struct sm4_ctx *ctx = crypto_tfm_ctx(tfm); 31 32 if (crypto_simd_usable()) { 33 if (keylen != SM4_KEY_SIZE) 34 return -EINVAL; 35 kernel_vector_begin(); 36 sm4_expandkey_zvksed_zvkb(key, ctx->rkey_enc, ctx->rkey_dec); 37 kernel_vector_end(); 38 return 0; 39 } 40 return sm4_expandkey(ctx, key, keylen); 41 } 42 43 static void riscv64_sm4_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 44 { 45 const struct sm4_ctx *ctx = crypto_tfm_ctx(tfm); 46 47 if (crypto_simd_usable()) { 48 kernel_vector_begin(); 49 sm4_crypt_zvksed_zvkb(ctx->rkey_enc, src, dst); 50 kernel_vector_end(); 51 } else { 52 sm4_crypt_block(ctx->rkey_enc, dst, src); 53 } 54 } 55 56 static void riscv64_sm4_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 57 { 58 const struct sm4_ctx *ctx = crypto_tfm_ctx(tfm); 59 60 if (crypto_simd_usable()) { 61 kernel_vector_begin(); 62 sm4_crypt_zvksed_zvkb(ctx->rkey_dec, src, dst); 63 kernel_vector_end(); 64 } else { 65 sm4_crypt_block(ctx->rkey_dec, dst, src); 66 } 67 } 68 69 static struct crypto_alg riscv64_sm4_alg = { 70 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 71 .cra_blocksize = SM4_BLOCK_SIZE, 72 .cra_ctxsize = sizeof(struct sm4_ctx), 73 .cra_priority = 300, 74 .cra_name = "sm4", 75 .cra_driver_name = "sm4-riscv64-zvksed-zvkb", 76 .cra_cipher = { 77 .cia_min_keysize = SM4_KEY_SIZE, 78 .cia_max_keysize = SM4_KEY_SIZE, 79 .cia_setkey = riscv64_sm4_setkey, 80 .cia_encrypt = riscv64_sm4_encrypt, 81 .cia_decrypt = riscv64_sm4_decrypt, 82 }, 83 .cra_module = THIS_MODULE, 84 }; 85 86 static int __init riscv64_sm4_mod_init(void) 87 { 88 if (riscv_isa_extension_available(NULL, ZVKSED) && 89 riscv_isa_extension_available(NULL, ZVKB) && 90 riscv_vector_vlen() >= 128) 91 return crypto_register_alg(&riscv64_sm4_alg); 92 93 return -ENODEV; 94 } 95 96 static void __exit riscv64_sm4_mod_exit(void) 97 { 98 crypto_unregister_alg(&riscv64_sm4_alg); 99 } 100 101 module_init(riscv64_sm4_mod_init); 102 module_exit(riscv64_sm4_mod_exit); 103 104 MODULE_DESCRIPTION("SM4 (RISC-V accelerated)"); 105 MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@vrull.eu>"); 106 MODULE_LICENSE("GPL"); 107 MODULE_ALIAS_CRYPTO("sm4"); 108