Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Cryptographic API.
0004  *
0005  * SHA-224 and SHA-256 Secure Hash Algorithm.
0006  *
0007  * Adapted for OCTEON by Aaro Koskinen <aaro.koskinen@iki.fi>.
0008  *
0009  * Based on crypto/sha256_generic.c, which is:
0010  *
0011  * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
0012  * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
0013  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
0014  * SHA224 Support Copyright 2007 Intel Corporation <jonathan.lynch@intel.com>
0015  */
0016 
0017 #include <linux/mm.h>
0018 #include <crypto/sha2.h>
0019 #include <crypto/sha256_base.h>
0020 #include <linux/init.h>
0021 #include <linux/types.h>
0022 #include <linux/module.h>
0023 #include <asm/byteorder.h>
0024 #include <asm/octeon/octeon.h>
0025 #include <crypto/internal/hash.h>
0026 
0027 #include "octeon-crypto.h"
0028 
0029 /*
0030  * We pass everything as 64-bit. OCTEON can handle misaligned data.
0031  */
0032 
0033 static void octeon_sha256_store_hash(struct sha256_state *sctx)
0034 {
0035     u64 *hash = (u64 *)sctx->state;
0036 
0037     write_octeon_64bit_hash_dword(hash[0], 0);
0038     write_octeon_64bit_hash_dword(hash[1], 1);
0039     write_octeon_64bit_hash_dword(hash[2], 2);
0040     write_octeon_64bit_hash_dword(hash[3], 3);
0041 }
0042 
0043 static void octeon_sha256_read_hash(struct sha256_state *sctx)
0044 {
0045     u64 *hash = (u64 *)sctx->state;
0046 
0047     hash[0] = read_octeon_64bit_hash_dword(0);
0048     hash[1] = read_octeon_64bit_hash_dword(1);
0049     hash[2] = read_octeon_64bit_hash_dword(2);
0050     hash[3] = read_octeon_64bit_hash_dword(3);
0051 }
0052 
0053 static void octeon_sha256_transform(const void *_block)
0054 {
0055     const u64 *block = _block;
0056 
0057     write_octeon_64bit_block_dword(block[0], 0);
0058     write_octeon_64bit_block_dword(block[1], 1);
0059     write_octeon_64bit_block_dword(block[2], 2);
0060     write_octeon_64bit_block_dword(block[3], 3);
0061     write_octeon_64bit_block_dword(block[4], 4);
0062     write_octeon_64bit_block_dword(block[5], 5);
0063     write_octeon_64bit_block_dword(block[6], 6);
0064     octeon_sha256_start(block[7]);
0065 }
0066 
0067 static void __octeon_sha256_update(struct sha256_state *sctx, const u8 *data,
0068                    unsigned int len)
0069 {
0070     unsigned int partial;
0071     unsigned int done;
0072     const u8 *src;
0073 
0074     partial = sctx->count % SHA256_BLOCK_SIZE;
0075     sctx->count += len;
0076     done = 0;
0077     src = data;
0078 
0079     if ((partial + len) >= SHA256_BLOCK_SIZE) {
0080         if (partial) {
0081             done = -partial;
0082             memcpy(sctx->buf + partial, data,
0083                    done + SHA256_BLOCK_SIZE);
0084             src = sctx->buf;
0085         }
0086 
0087         do {
0088             octeon_sha256_transform(src);
0089             done += SHA256_BLOCK_SIZE;
0090             src = data + done;
0091         } while (done + SHA256_BLOCK_SIZE <= len);
0092 
0093         partial = 0;
0094     }
0095     memcpy(sctx->buf + partial, src, len - done);
0096 }
0097 
0098 static int octeon_sha256_update(struct shash_desc *desc, const u8 *data,
0099                 unsigned int len)
0100 {
0101     struct sha256_state *sctx = shash_desc_ctx(desc);
0102     struct octeon_cop2_state state;
0103     unsigned long flags;
0104 
0105     /*
0106      * Small updates never reach the crypto engine, so the generic sha256 is
0107      * faster because of the heavyweight octeon_crypto_enable() /
0108      * octeon_crypto_disable().
0109      */
0110     if ((sctx->count % SHA256_BLOCK_SIZE) + len < SHA256_BLOCK_SIZE)
0111         return crypto_sha256_update(desc, data, len);
0112 
0113     flags = octeon_crypto_enable(&state);
0114     octeon_sha256_store_hash(sctx);
0115 
0116     __octeon_sha256_update(sctx, data, len);
0117 
0118     octeon_sha256_read_hash(sctx);
0119     octeon_crypto_disable(&state, flags);
0120 
0121     return 0;
0122 }
0123 
0124 static int octeon_sha256_final(struct shash_desc *desc, u8 *out)
0125 {
0126     struct sha256_state *sctx = shash_desc_ctx(desc);
0127     static const u8 padding[64] = { 0x80, };
0128     struct octeon_cop2_state state;
0129     __be32 *dst = (__be32 *)out;
0130     unsigned int pad_len;
0131     unsigned long flags;
0132     unsigned int index;
0133     __be64 bits;
0134     int i;
0135 
0136     /* Save number of bits. */
0137     bits = cpu_to_be64(sctx->count << 3);
0138 
0139     /* Pad out to 56 mod 64. */
0140     index = sctx->count & 0x3f;
0141     pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
0142 
0143     flags = octeon_crypto_enable(&state);
0144     octeon_sha256_store_hash(sctx);
0145 
0146     __octeon_sha256_update(sctx, padding, pad_len);
0147 
0148     /* Append length (before padding). */
0149     __octeon_sha256_update(sctx, (const u8 *)&bits, sizeof(bits));
0150 
0151     octeon_sha256_read_hash(sctx);
0152     octeon_crypto_disable(&state, flags);
0153 
0154     /* Store state in digest */
0155     for (i = 0; i < 8; i++)
0156         dst[i] = cpu_to_be32(sctx->state[i]);
0157 
0158     /* Zeroize sensitive information. */
0159     memset(sctx, 0, sizeof(*sctx));
0160 
0161     return 0;
0162 }
0163 
0164 static int octeon_sha224_final(struct shash_desc *desc, u8 *hash)
0165 {
0166     u8 D[SHA256_DIGEST_SIZE];
0167 
0168     octeon_sha256_final(desc, D);
0169 
0170     memcpy(hash, D, SHA224_DIGEST_SIZE);
0171     memzero_explicit(D, SHA256_DIGEST_SIZE);
0172 
0173     return 0;
0174 }
0175 
0176 static int octeon_sha256_export(struct shash_desc *desc, void *out)
0177 {
0178     struct sha256_state *sctx = shash_desc_ctx(desc);
0179 
0180     memcpy(out, sctx, sizeof(*sctx));
0181     return 0;
0182 }
0183 
0184 static int octeon_sha256_import(struct shash_desc *desc, const void *in)
0185 {
0186     struct sha256_state *sctx = shash_desc_ctx(desc);
0187 
0188     memcpy(sctx, in, sizeof(*sctx));
0189     return 0;
0190 }
0191 
0192 static struct shash_alg octeon_sha256_algs[2] = { {
0193     .digestsize =   SHA256_DIGEST_SIZE,
0194     .init       =   sha256_base_init,
0195     .update     =   octeon_sha256_update,
0196     .final      =   octeon_sha256_final,
0197     .export     =   octeon_sha256_export,
0198     .import     =   octeon_sha256_import,
0199     .descsize   =   sizeof(struct sha256_state),
0200     .statesize  =   sizeof(struct sha256_state),
0201     .base       =   {
0202         .cra_name   =   "sha256",
0203         .cra_driver_name=   "octeon-sha256",
0204         .cra_priority   =   OCTEON_CR_OPCODE_PRIORITY,
0205         .cra_blocksize  =   SHA256_BLOCK_SIZE,
0206         .cra_module =   THIS_MODULE,
0207     }
0208 }, {
0209     .digestsize =   SHA224_DIGEST_SIZE,
0210     .init       =   sha224_base_init,
0211     .update     =   octeon_sha256_update,
0212     .final      =   octeon_sha224_final,
0213     .descsize   =   sizeof(struct sha256_state),
0214     .base       =   {
0215         .cra_name   =   "sha224",
0216         .cra_driver_name=   "octeon-sha224",
0217         .cra_blocksize  =   SHA224_BLOCK_SIZE,
0218         .cra_module =   THIS_MODULE,
0219     }
0220 } };
0221 
0222 static int __init octeon_sha256_mod_init(void)
0223 {
0224     if (!octeon_has_crypto())
0225         return -ENOTSUPP;
0226     return crypto_register_shashes(octeon_sha256_algs,
0227                        ARRAY_SIZE(octeon_sha256_algs));
0228 }
0229 
0230 static void __exit octeon_sha256_mod_fini(void)
0231 {
0232     crypto_unregister_shashes(octeon_sha256_algs,
0233                   ARRAY_SIZE(octeon_sha256_algs));
0234 }
0235 
0236 module_init(octeon_sha256_mod_init);
0237 module_exit(octeon_sha256_mod_fini);
0238 
0239 MODULE_LICENSE("GPL");
0240 MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm (OCTEON)");
0241 MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>");