1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Cryptographic API. 4 * 5 * powerpc implementation of the SHA1 Secure Hash Algorithm. 6 * 7 * Derived from cryptoapi implementation, adapted for in-place 8 * scatterlist interface. 9 * 10 * Derived from "crypto/sha1.c" 11 * Copyright (c) Alan Smithee. 12 * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk> 13 * Copyright (c) Jean-Francois Dive <jef@linuxbe.org> 14 */ 15 #include <crypto/internal/hash.h> 16 #include <linux/init.h> 17 #include <linux/module.h> 18 #include <linux/mm.h> 19 #include <linux/cryptohash.h> 20 #include <linux/types.h> 21 #include <crypto/sha.h> 22 #include <asm/byteorder.h> 23 24 extern void powerpc_sha_transform(u32 *state, const u8 *src, u32 *temp); 25 26 static int sha1_init(struct shash_desc *desc) 27 { 28 struct sha1_state *sctx = shash_desc_ctx(desc); 29 30 *sctx = (struct sha1_state){ 31 .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 }, 32 }; 33 34 return 0; 35 } 36 37 static int sha1_update(struct shash_desc *desc, const u8 *data, 38 unsigned int len) 39 { 40 struct sha1_state *sctx = shash_desc_ctx(desc); 41 unsigned int partial, done; 42 const u8 *src; 43 44 partial = sctx->count & 0x3f; 45 sctx->count += len; 46 done = 0; 47 src = data; 48 49 if ((partial + len) > 63) { 50 u32 temp[SHA_WORKSPACE_WORDS]; 51 52 if (partial) { 53 done = -partial; 54 memcpy(sctx->buffer + partial, data, done + 64); 55 src = sctx->buffer; 56 } 57 58 do { 59 powerpc_sha_transform(sctx->state, src, temp); 60 done += 64; 61 src = data + done; 62 } while (done + 63 < len); 63 64 memzero_explicit(temp, sizeof(temp)); 65 partial = 0; 66 } 67 memcpy(sctx->buffer + partial, src, len - done); 68 69 return 0; 70 } 71 72 73 /* Add padding and return the message digest. */ 74 static int sha1_final(struct shash_desc *desc, u8 *out) 75 { 76 struct sha1_state *sctx = shash_desc_ctx(desc); 77 __be32 *dst = (__be32 *)out; 78 u32 i, index, padlen; 79 __be64 bits; 80 static const u8 padding[64] = { 0x80, }; 81 82 bits = cpu_to_be64(sctx->count << 3); 83 84 /* Pad out to 56 mod 64 */ 85 index = sctx->count & 0x3f; 86 padlen = (index < 56) ? (56 - index) : ((64+56) - index); 87 sha1_update(desc, padding, padlen); 88 89 /* Append length */ 90 sha1_update(desc, (const u8 *)&bits, sizeof(bits)); 91 92 /* Store state in digest */ 93 for (i = 0; i < 5; i++) 94 dst[i] = cpu_to_be32(sctx->state[i]); 95 96 /* Wipe context */ 97 memset(sctx, 0, sizeof *sctx); 98 99 return 0; 100 } 101 102 static int sha1_export(struct shash_desc *desc, void *out) 103 { 104 struct sha1_state *sctx = shash_desc_ctx(desc); 105 106 memcpy(out, sctx, sizeof(*sctx)); 107 return 0; 108 } 109 110 static int sha1_import(struct shash_desc *desc, const void *in) 111 { 112 struct sha1_state *sctx = shash_desc_ctx(desc); 113 114 memcpy(sctx, in, sizeof(*sctx)); 115 return 0; 116 } 117 118 static struct shash_alg alg = { 119 .digestsize = SHA1_DIGEST_SIZE, 120 .init = sha1_init, 121 .update = sha1_update, 122 .final = sha1_final, 123 .export = sha1_export, 124 .import = sha1_import, 125 .descsize = sizeof(struct sha1_state), 126 .statesize = sizeof(struct sha1_state), 127 .base = { 128 .cra_name = "sha1", 129 .cra_driver_name= "sha1-powerpc", 130 .cra_blocksize = SHA1_BLOCK_SIZE, 131 .cra_module = THIS_MODULE, 132 } 133 }; 134 135 static int __init sha1_powerpc_mod_init(void) 136 { 137 return crypto_register_shash(&alg); 138 } 139 140 static void __exit sha1_powerpc_mod_fini(void) 141 { 142 crypto_unregister_shash(&alg); 143 } 144 145 module_init(sha1_powerpc_mod_init); 146 module_exit(sha1_powerpc_mod_fini); 147 148 MODULE_LICENSE("GPL"); 149 MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm"); 150 151 MODULE_ALIAS_CRYPTO("sha1"); 152 MODULE_ALIAS_CRYPTO("sha1-powerpc"); 153