Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Cryptographic API.
0004  *
0005  * powerpc implementation of the SHA1 Secure Hash Algorithm.
0006  *
0007  * Derived from cryptoapi implementation, adapted for in-place
0008  * scatterlist interface.
0009  *
0010  * Derived from "crypto/sha1.c"
0011  * Copyright (c) Alan Smithee.
0012  * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
0013  * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
0014  */
0015 #include <crypto/internal/hash.h>
0016 #include <linux/init.h>
0017 #include <linux/module.h>
0018 #include <linux/mm.h>
0019 #include <linux/types.h>
0020 #include <crypto/sha1.h>
0021 #include <crypto/sha1_base.h>
0022 #include <asm/byteorder.h>
0023 
0024 void powerpc_sha_transform(u32 *state, const u8 *src);
0025 
0026 static int powerpc_sha1_update(struct shash_desc *desc, const u8 *data,
0027                    unsigned int len)
0028 {
0029     struct sha1_state *sctx = shash_desc_ctx(desc);
0030     unsigned int partial, done;
0031     const u8 *src;
0032 
0033     partial = sctx->count & 0x3f;
0034     sctx->count += len;
0035     done = 0;
0036     src = data;
0037 
0038     if ((partial + len) > 63) {
0039 
0040         if (partial) {
0041             done = -partial;
0042             memcpy(sctx->buffer + partial, data, done + 64);
0043             src = sctx->buffer;
0044         }
0045 
0046         do {
0047             powerpc_sha_transform(sctx->state, src);
0048             done += 64;
0049             src = data + done;
0050         } while (done + 63 < len);
0051 
0052         partial = 0;
0053     }
0054     memcpy(sctx->buffer + partial, src, len - done);
0055 
0056     return 0;
0057 }
0058 
0059 
0060 /* Add padding and return the message digest. */
0061 static int powerpc_sha1_final(struct shash_desc *desc, u8 *out)
0062 {
0063     struct sha1_state *sctx = shash_desc_ctx(desc);
0064     __be32 *dst = (__be32 *)out;
0065     u32 i, index, padlen;
0066     __be64 bits;
0067     static const u8 padding[64] = { 0x80, };
0068 
0069     bits = cpu_to_be64(sctx->count << 3);
0070 
0071     /* Pad out to 56 mod 64 */
0072     index = sctx->count & 0x3f;
0073     padlen = (index < 56) ? (56 - index) : ((64+56) - index);
0074     powerpc_sha1_update(desc, padding, padlen);
0075 
0076     /* Append length */
0077     powerpc_sha1_update(desc, (const u8 *)&bits, sizeof(bits));
0078 
0079     /* Store state in digest */
0080     for (i = 0; i < 5; i++)
0081         dst[i] = cpu_to_be32(sctx->state[i]);
0082 
0083     /* Wipe context */
0084     memset(sctx, 0, sizeof *sctx);
0085 
0086     return 0;
0087 }
0088 
0089 static int powerpc_sha1_export(struct shash_desc *desc, void *out)
0090 {
0091     struct sha1_state *sctx = shash_desc_ctx(desc);
0092 
0093     memcpy(out, sctx, sizeof(*sctx));
0094     return 0;
0095 }
0096 
0097 static int powerpc_sha1_import(struct shash_desc *desc, const void *in)
0098 {
0099     struct sha1_state *sctx = shash_desc_ctx(desc);
0100 
0101     memcpy(sctx, in, sizeof(*sctx));
0102     return 0;
0103 }
0104 
0105 static struct shash_alg alg = {
0106     .digestsize =   SHA1_DIGEST_SIZE,
0107     .init       =   sha1_base_init,
0108     .update     =   powerpc_sha1_update,
0109     .final      =   powerpc_sha1_final,
0110     .export     =   powerpc_sha1_export,
0111     .import     =   powerpc_sha1_import,
0112     .descsize   =   sizeof(struct sha1_state),
0113     .statesize  =   sizeof(struct sha1_state),
0114     .base       =   {
0115         .cra_name   =   "sha1",
0116         .cra_driver_name=   "sha1-powerpc",
0117         .cra_blocksize  =   SHA1_BLOCK_SIZE,
0118         .cra_module =   THIS_MODULE,
0119     }
0120 };
0121 
0122 static int __init sha1_powerpc_mod_init(void)
0123 {
0124     return crypto_register_shash(&alg);
0125 }
0126 
0127 static void __exit sha1_powerpc_mod_fini(void)
0128 {
0129     crypto_unregister_shash(&alg);
0130 }
0131 
0132 module_init(sha1_powerpc_mod_init);
0133 module_exit(sha1_powerpc_mod_fini);
0134 
0135 MODULE_LICENSE("GPL");
0136 MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");
0137 
0138 MODULE_ALIAS_CRYPTO("sha1");
0139 MODULE_ALIAS_CRYPTO("sha1-powerpc");