1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * SHA-256 and SHA-224 using the RISC-V vector crypto extensions
5 * Copyright (C) 2022 VRULL GmbH
6 * Author: Heiko Stuebner <heiko.stuebner@vrull.eu>
8 * Copyright (C) 2023 SiFive, Inc.
9 * Author: Jerry Shih <jerry.shih@sifive.com>
13 #include <asm/vector.h>
14 #include <crypto/internal/hash.h>
15 #include <crypto/internal/simd.h>
16 #include <crypto/sha256_base.h>
17 #include <linux/linkage.h>
18 #include <linux/module.h>
21 * Note: the asm function only uses the 'state' field of struct sha256_state.
22 * It is assumed to be the first field.
24 asmlinkage
void sha256_transform_zvknha_or_zvknhb_zvkb(
25 struct sha256_state
*state
, const u8
*data
, int num_blocks
);
27 static int riscv64_sha256_update(struct shash_desc
*desc
, const u8
*data
,
31 * Ensure struct sha256_state begins directly with the SHA-256
32 * 256-bit internal state, as this is what the asm function expects.
34 BUILD_BUG_ON(offsetof(struct sha256_state
, state
) != 0);
36 if (crypto_simd_usable()) {
37 kernel_vector_begin();
38 sha256_base_do_update(desc
, data
, len
,
39 sha256_transform_zvknha_or_zvknhb_zvkb
);
42 crypto_sha256_update(desc
, data
, len
);
47 static int riscv64_sha256_finup(struct shash_desc
*desc
, const u8
*data
,
48 unsigned int len
, u8
*out
)
50 if (crypto_simd_usable()) {
51 kernel_vector_begin();
53 sha256_base_do_update(
55 sha256_transform_zvknha_or_zvknhb_zvkb
);
56 sha256_base_do_finalize(
57 desc
, sha256_transform_zvknha_or_zvknhb_zvkb
);
60 return sha256_base_finish(desc
, out
);
63 return crypto_sha256_finup(desc
, data
, len
, out
);
66 static int riscv64_sha256_final(struct shash_desc
*desc
, u8
*out
)
68 return riscv64_sha256_finup(desc
, NULL
, 0, out
);
71 static int riscv64_sha256_digest(struct shash_desc
*desc
, const u8
*data
,
72 unsigned int len
, u8
*out
)
74 return sha256_base_init(desc
) ?:
75 riscv64_sha256_finup(desc
, data
, len
, out
);
78 static struct shash_alg riscv64_sha256_algs
[] = {
80 .init
= sha256_base_init
,
81 .update
= riscv64_sha256_update
,
82 .final
= riscv64_sha256_final
,
83 .finup
= riscv64_sha256_finup
,
84 .digest
= riscv64_sha256_digest
,
85 .descsize
= sizeof(struct sha256_state
),
86 .digestsize
= SHA256_DIGEST_SIZE
,
88 .cra_blocksize
= SHA256_BLOCK_SIZE
,
91 .cra_driver_name
= "sha256-riscv64-zvknha_or_zvknhb-zvkb",
92 .cra_module
= THIS_MODULE
,
95 .init
= sha224_base_init
,
96 .update
= riscv64_sha256_update
,
97 .final
= riscv64_sha256_final
,
98 .finup
= riscv64_sha256_finup
,
99 .descsize
= sizeof(struct sha256_state
),
100 .digestsize
= SHA224_DIGEST_SIZE
,
102 .cra_blocksize
= SHA224_BLOCK_SIZE
,
104 .cra_name
= "sha224",
105 .cra_driver_name
= "sha224-riscv64-zvknha_or_zvknhb-zvkb",
106 .cra_module
= THIS_MODULE
,
111 static int __init
riscv64_sha256_mod_init(void)
113 /* Both zvknha and zvknhb provide the SHA-256 instructions. */
114 if ((riscv_isa_extension_available(NULL
, ZVKNHA
) ||
115 riscv_isa_extension_available(NULL
, ZVKNHB
)) &&
116 riscv_isa_extension_available(NULL
, ZVKB
) &&
117 riscv_vector_vlen() >= 128)
118 return crypto_register_shashes(riscv64_sha256_algs
,
119 ARRAY_SIZE(riscv64_sha256_algs
));
124 static void __exit
riscv64_sha256_mod_exit(void)
126 crypto_unregister_shashes(riscv64_sha256_algs
,
127 ARRAY_SIZE(riscv64_sha256_algs
));
130 module_init(riscv64_sha256_mod_init
);
131 module_exit(riscv64_sha256_mod_exit
);
133 MODULE_DESCRIPTION("SHA-256 (RISC-V accelerated)");
134 MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@vrull.eu>");
135 MODULE_LICENSE("GPL");
136 MODULE_ALIAS_CRYPTO("sha256");
137 MODULE_ALIAS_CRYPTO("sha224");