1 // SPDX-License-Identifier: GPL-2.0 1 2 /* 3 * sha3-ce-glue.c - core SHA-3 transform using 4 * 5 * Copyright (C) 2018 Linaro Ltd <ard.biesheuv 6 * 7 * This program is free software; you can redi 8 * it under the terms of the GNU General Publi 9 * published by the Free Software Foundation. 10 */ 11 12 #include <asm/hwcap.h> 13 #include <asm/neon.h> 14 #include <asm/simd.h> 15 #include <linux/unaligned.h> 16 #include <crypto/internal/hash.h> 17 #include <crypto/internal/simd.h> 18 #include <crypto/sha3.h> 19 #include <linux/cpufeature.h> 20 #include <linux/crypto.h> 21 #include <linux/module.h> 22 23 MODULE_DESCRIPTION("SHA3 secure hash using ARM 24 MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@ 25 MODULE_LICENSE("GPL v2"); 26 MODULE_ALIAS_CRYPTO("sha3-224"); 27 MODULE_ALIAS_CRYPTO("sha3-256"); 28 MODULE_ALIAS_CRYPTO("sha3-384"); 29 MODULE_ALIAS_CRYPTO("sha3-512"); 30 31 asmlinkage int sha3_ce_transform(u64 *st, cons 32 int md_len); 33 34 static int sha3_update(struct shash_desc *desc 35 unsigned int len) 36 { 37 struct sha3_state *sctx = shash_desc_c 38 unsigned int digest_size = crypto_shas 39 40 if (!crypto_simd_usable()) 41 return crypto_sha3_update(desc 42 43 if ((sctx->partial + len) >= sctx->rsi 44 int blocks; 45 46 if (sctx->partial) { 47 int p = sctx->rsiz - s 48 49 memcpy(sctx->buf + sct 50 kernel_neon_begin(); 51 sha3_ce_transform(sctx 52 kernel_neon_end(); 53 54 data += p; 55 len -= p; 56 sctx->partial = 0; 57 } 58 59 blocks = len / sctx->rsiz; 60 len %= sctx->rsiz; 61 62 while (blocks) { 63 int rem; 64 65 kernel_neon_begin(); 66 rem = sha3_ce_transfor 67 68 kernel_neon_end(); 69 data += (blocks - rem) 70 blocks = rem; 71 } 72 } 73 74 if (len) { 75 memcpy(sctx->buf + sctx->parti 76 sctx->partial += len; 77 } 78 return 0; 79 } 80 81 static int sha3_final(struct shash_desc *desc, 82 { 83 struct sha3_state *sctx = shash_desc_c 84 unsigned int digest_size = crypto_shas 85 __le64 *digest = (__le64 *)out; 86 int i; 87 88 if (!crypto_simd_usable()) 89 return crypto_sha3_final(desc, 90 91 sctx->buf[sctx->partial++] = 0x06; 92 memset(sctx->buf + sctx->partial, 0, s 93 sctx->buf[sctx->rsiz - 1] |= 0x80; 94 95 kernel_neon_begin(); 96 sha3_ce_transform(sctx->st, sctx->buf, 97 kernel_neon_end(); 98 99 for (i = 0; i < digest_size / 8; i++) 100 put_unaligned_le64(sctx->st[i] 101 102 if (digest_size & 4) 103 put_unaligned_le32(sctx->st[i] 104 105 memzero_explicit(sctx, sizeof(*sctx)); 106 return 0; 107 } 108 109 static struct shash_alg algs[] = { { 110 .digestsize = SHA3_224_DIG 111 .init = crypto_sha3_ 112 .update = sha3_update, 113 .final = sha3_final, 114 .descsize = sizeof(struc 115 .base.cra_name = "sha3-224", 116 .base.cra_driver_name = "sha3-224-ce 117 .base.cra_blocksize = SHA3_224_BLO 118 .base.cra_module = THIS_MODULE, 119 .base.cra_priority = 200, 120 }, { 121 .digestsize = SHA3_256_DIG 122 .init = crypto_sha3_ 123 .update = sha3_update, 124 .final = sha3_final, 125 .descsize = sizeof(struc 126 .base.cra_name = "sha3-256", 127 .base.cra_driver_name = "sha3-256-ce 128 .base.cra_blocksize = SHA3_256_BLO 129 .base.cra_module = THIS_MODULE, 130 .base.cra_priority = 200, 131 }, { 132 .digestsize = SHA3_384_DIG 133 .init = crypto_sha3_ 134 .update = sha3_update, 135 .final = sha3_final, 136 .descsize = sizeof(struc 137 .base.cra_name = "sha3-384", 138 .base.cra_driver_name = "sha3-384-ce 139 .base.cra_blocksize = SHA3_384_BLO 140 .base.cra_module = THIS_MODULE, 141 .base.cra_priority = 200, 142 }, { 143 .digestsize = SHA3_512_DIG 144 .init = crypto_sha3_ 145 .update = sha3_update, 146 .final = sha3_final, 147 .descsize = sizeof(struc 148 .base.cra_name = "sha3-512", 149 .base.cra_driver_name = "sha3-512-ce 150 .base.cra_blocksize = SHA3_512_BLO 151 .base.cra_module = THIS_MODULE, 152 .base.cra_priority = 200, 153 } }; 154 155 static int __init sha3_neon_mod_init(void) 156 { 157 return crypto_register_shashes(algs, A 158 } 159 160 static void __exit sha3_neon_mod_fini(void) 161 { 162 crypto_unregister_shashes(algs, ARRAY_ 163 } 164 165 module_cpu_feature_match(SHA3, sha3_neon_mod_i 166 module_exit(sha3_neon_mod_fini); 167
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.