1 | // SPDX-License-Identifier: GPL-2.0 |
2 | |
3 | /* |
4 | * SM4 Cipher Algorithm. |
5 | * |
6 | * Copyright (C) 2018 ARM Limited or its affiliates. |
7 | * All rights reserved. |
8 | */ |
9 | |
10 | #include <crypto/algapi.h> |
11 | #include <crypto/sm4.h> |
12 | #include <linux/module.h> |
13 | #include <linux/init.h> |
14 | #include <linux/types.h> |
15 | #include <linux/errno.h> |
16 | #include <asm/byteorder.h> |
17 | #include <asm/unaligned.h> |
18 | |
19 | /** |
20 | * sm4_setkey - Set the SM4 key. |
21 | * @tfm: The %crypto_tfm that is used in the context. |
22 | * @in_key: The input key. |
23 | * @key_len: The size of the key. |
24 | * |
25 | * This function uses sm4_expandkey() to expand the key. |
26 | * &sm4_ctx _must_ be the private data embedded in @tfm which is |
27 | * retrieved with crypto_tfm_ctx(). |
28 | * |
29 | * Return: 0 on success; -EINVAL on failure (only happens for bad key lengths) |
30 | */ |
31 | static int sm4_setkey(struct crypto_tfm *tfm, const u8 *in_key, |
32 | unsigned int key_len) |
33 | { |
34 | struct sm4_ctx *ctx = crypto_tfm_ctx(tfm); |
35 | |
36 | return sm4_expandkey(ctx, in_key, key_len); |
37 | } |
38 | |
39 | /* encrypt a block of text */ |
40 | |
41 | static void sm4_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) |
42 | { |
43 | const struct sm4_ctx *ctx = crypto_tfm_ctx(tfm); |
44 | |
45 | sm4_crypt_block(rk: ctx->rkey_enc, out, in); |
46 | } |
47 | |
48 | /* decrypt a block of text */ |
49 | |
50 | static void sm4_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) |
51 | { |
52 | const struct sm4_ctx *ctx = crypto_tfm_ctx(tfm); |
53 | |
54 | sm4_crypt_block(rk: ctx->rkey_dec, out, in); |
55 | } |
56 | |
57 | static struct crypto_alg sm4_alg = { |
58 | .cra_name = "sm4" , |
59 | .cra_driver_name = "sm4-generic" , |
60 | .cra_priority = 100, |
61 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, |
62 | .cra_blocksize = SM4_BLOCK_SIZE, |
63 | .cra_ctxsize = sizeof(struct sm4_ctx), |
64 | .cra_module = THIS_MODULE, |
65 | .cra_u = { |
66 | .cipher = { |
67 | .cia_min_keysize = SM4_KEY_SIZE, |
68 | .cia_max_keysize = SM4_KEY_SIZE, |
69 | .cia_setkey = sm4_setkey, |
70 | .cia_encrypt = sm4_encrypt, |
71 | .cia_decrypt = sm4_decrypt |
72 | } |
73 | } |
74 | }; |
75 | |
76 | static int __init sm4_init(void) |
77 | { |
78 | return crypto_register_alg(alg: &sm4_alg); |
79 | } |
80 | |
81 | static void __exit sm4_fini(void) |
82 | { |
83 | crypto_unregister_alg(alg: &sm4_alg); |
84 | } |
85 | |
86 | subsys_initcall(sm4_init); |
87 | module_exit(sm4_fini); |
88 | |
89 | MODULE_DESCRIPTION("SM4 Cipher Algorithm" ); |
90 | MODULE_LICENSE("GPL v2" ); |
91 | MODULE_ALIAS_CRYPTO("sm4" ); |
92 | MODULE_ALIAS_CRYPTO("sm4-generic" ); |
93 | |