162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci/* 462306a36Sopenharmony_ci * SM4 Cipher Algorithm. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 2018 ARM Limited or its affiliates. 762306a36Sopenharmony_ci * All rights reserved. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <crypto/algapi.h> 1162306a36Sopenharmony_ci#include <crypto/sm4.h> 1262306a36Sopenharmony_ci#include <linux/module.h> 1362306a36Sopenharmony_ci#include <linux/init.h> 1462306a36Sopenharmony_ci#include <linux/types.h> 1562306a36Sopenharmony_ci#include <linux/errno.h> 1662306a36Sopenharmony_ci#include <asm/byteorder.h> 1762306a36Sopenharmony_ci#include <asm/unaligned.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/** 2062306a36Sopenharmony_ci * sm4_setkey - Set the SM4 key. 2162306a36Sopenharmony_ci * @tfm: The %crypto_tfm that is used in the context. 2262306a36Sopenharmony_ci * @in_key: The input key. 2362306a36Sopenharmony_ci * @key_len: The size of the key. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * This function uses sm4_expandkey() to expand the key. 2662306a36Sopenharmony_ci * &sm4_ctx _must_ be the private data embedded in @tfm which is 2762306a36Sopenharmony_ci * retrieved with crypto_tfm_ctx(). 2862306a36Sopenharmony_ci * 2962306a36Sopenharmony_ci * Return: 0 on success; -EINVAL on failure (only happens for bad key lengths) 3062306a36Sopenharmony_ci */ 3162306a36Sopenharmony_cistatic int sm4_setkey(struct crypto_tfm *tfm, const u8 *in_key, 3262306a36Sopenharmony_ci unsigned int key_len) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci struct sm4_ctx *ctx = crypto_tfm_ctx(tfm); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci return sm4_expandkey(ctx, in_key, key_len); 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* encrypt a block of text */ 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic void sm4_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci const struct sm4_ctx *ctx = crypto_tfm_ctx(tfm); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci sm4_crypt_block(ctx->rkey_enc, out, in); 4662306a36Sopenharmony_ci} 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/* decrypt a block of text */ 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistatic void sm4_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci const struct sm4_ctx *ctx = crypto_tfm_ctx(tfm); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci sm4_crypt_block(ctx->rkey_dec, out, in); 5562306a36Sopenharmony_ci} 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_cistatic struct crypto_alg sm4_alg = { 5862306a36Sopenharmony_ci .cra_name = "sm4", 5962306a36Sopenharmony_ci .cra_driver_name = "sm4-generic", 6062306a36Sopenharmony_ci .cra_priority = 100, 6162306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 6262306a36Sopenharmony_ci .cra_blocksize = SM4_BLOCK_SIZE, 6362306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct sm4_ctx), 6462306a36Sopenharmony_ci .cra_module = THIS_MODULE, 6562306a36Sopenharmony_ci .cra_u = { 6662306a36Sopenharmony_ci .cipher = { 6762306a36Sopenharmony_ci .cia_min_keysize = SM4_KEY_SIZE, 6862306a36Sopenharmony_ci .cia_max_keysize = SM4_KEY_SIZE, 6962306a36Sopenharmony_ci .cia_setkey = sm4_setkey, 7062306a36Sopenharmony_ci .cia_encrypt = sm4_encrypt, 7162306a36Sopenharmony_ci .cia_decrypt = sm4_decrypt 7262306a36Sopenharmony_ci } 7362306a36Sopenharmony_ci } 7462306a36Sopenharmony_ci}; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistatic int __init sm4_init(void) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci return crypto_register_alg(&sm4_alg); 7962306a36Sopenharmony_ci} 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistatic void __exit sm4_fini(void) 8262306a36Sopenharmony_ci{ 8362306a36Sopenharmony_ci crypto_unregister_alg(&sm4_alg); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cisubsys_initcall(sm4_init); 8762306a36Sopenharmony_cimodule_exit(sm4_fini); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ciMODULE_DESCRIPTION("SM4 Cipher Algorithm"); 9062306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 9162306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("sm4"); 9262306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("sm4-generic"); 93