1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * SHA-512 and SHA-384 using the RISC-V vector crypto extensions
5 * Copyright (C) 2023 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/sha512_base.h>
17 #include <linux/linkage.h>
18 #include <linux/module.h>
21 * Note: the asm function only uses the 'state' field of struct sha512_state.
22 * It is assumed to be the first field.
24 asmlinkage
void sha512_transform_zvknhb_zvkb(
25 struct sha512_state
*state
, const u8
*data
, int num_blocks
);
27 static int riscv64_sha512_update(struct shash_desc
*desc
, const u8
*data
,
31 * Ensure struct sha512_state begins directly with the SHA-512
32 * 512-bit internal state, as this is what the asm function expects.
34 BUILD_BUG_ON(offsetof(struct sha512_state
, state
) != 0);
36 if (crypto_simd_usable()) {
37 kernel_vector_begin();
38 sha512_base_do_update(desc
, data
, len
,
39 sha512_transform_zvknhb_zvkb
);
42 crypto_sha512_update(desc
, data
, len
);
47 static int riscv64_sha512_finup(struct shash_desc
*desc
, const u8
*data
,
48 unsigned int len
, u8
*out
)
50 if (crypto_simd_usable()) {
51 kernel_vector_begin();
53 sha512_base_do_update(desc
, data
, len
,
54 sha512_transform_zvknhb_zvkb
);
55 sha512_base_do_finalize(desc
, sha512_transform_zvknhb_zvkb
);
58 return sha512_base_finish(desc
, out
);
61 return crypto_sha512_finup(desc
, data
, len
, out
);
64 static int riscv64_sha512_final(struct shash_desc
*desc
, u8
*out
)
66 return riscv64_sha512_finup(desc
, NULL
, 0, out
);
69 static int riscv64_sha512_digest(struct shash_desc
*desc
, const u8
*data
,
70 unsigned int len
, u8
*out
)
72 return sha512_base_init(desc
) ?:
73 riscv64_sha512_finup(desc
, data
, len
, out
);
76 static struct shash_alg riscv64_sha512_algs
[] = {
78 .init
= sha512_base_init
,
79 .update
= riscv64_sha512_update
,
80 .final
= riscv64_sha512_final
,
81 .finup
= riscv64_sha512_finup
,
82 .digest
= riscv64_sha512_digest
,
83 .descsize
= sizeof(struct sha512_state
),
84 .digestsize
= SHA512_DIGEST_SIZE
,
86 .cra_blocksize
= SHA512_BLOCK_SIZE
,
89 .cra_driver_name
= "sha512-riscv64-zvknhb-zvkb",
90 .cra_module
= THIS_MODULE
,
93 .init
= sha384_base_init
,
94 .update
= riscv64_sha512_update
,
95 .final
= riscv64_sha512_final
,
96 .finup
= riscv64_sha512_finup
,
97 .descsize
= sizeof(struct sha512_state
),
98 .digestsize
= SHA384_DIGEST_SIZE
,
100 .cra_blocksize
= SHA384_BLOCK_SIZE
,
102 .cra_name
= "sha384",
103 .cra_driver_name
= "sha384-riscv64-zvknhb-zvkb",
104 .cra_module
= THIS_MODULE
,
109 static int __init
riscv64_sha512_mod_init(void)
111 if (riscv_isa_extension_available(NULL
, ZVKNHB
) &&
112 riscv_isa_extension_available(NULL
, ZVKB
) &&
113 riscv_vector_vlen() >= 128)
114 return crypto_register_shashes(riscv64_sha512_algs
,
115 ARRAY_SIZE(riscv64_sha512_algs
));
120 static void __exit
riscv64_sha512_mod_exit(void)
122 crypto_unregister_shashes(riscv64_sha512_algs
,
123 ARRAY_SIZE(riscv64_sha512_algs
));
126 module_init(riscv64_sha512_mod_init
);
127 module_exit(riscv64_sha512_mod_exit
);
129 MODULE_DESCRIPTION("SHA-512 (RISC-V accelerated)");
130 MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@vrull.eu>");
131 MODULE_LICENSE("GPL");
132 MODULE_ALIAS_CRYPTO("sha512");
133 MODULE_ALIAS_CRYPTO("sha384");