0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/mm.h>
0017 #include <crypto/sha2.h>
0018 #include <crypto/sha512_base.h>
0019 #include <linux/init.h>
0020 #include <linux/types.h>
0021 #include <linux/module.h>
0022 #include <asm/byteorder.h>
0023 #include <asm/octeon/octeon.h>
0024 #include <crypto/internal/hash.h>
0025
0026 #include "octeon-crypto.h"
0027
0028
0029
0030
0031
0032 static void octeon_sha512_store_hash(struct sha512_state *sctx)
0033 {
0034 write_octeon_64bit_hash_sha512(sctx->state[0], 0);
0035 write_octeon_64bit_hash_sha512(sctx->state[1], 1);
0036 write_octeon_64bit_hash_sha512(sctx->state[2], 2);
0037 write_octeon_64bit_hash_sha512(sctx->state[3], 3);
0038 write_octeon_64bit_hash_sha512(sctx->state[4], 4);
0039 write_octeon_64bit_hash_sha512(sctx->state[5], 5);
0040 write_octeon_64bit_hash_sha512(sctx->state[6], 6);
0041 write_octeon_64bit_hash_sha512(sctx->state[7], 7);
0042 }
0043
0044 static void octeon_sha512_read_hash(struct sha512_state *sctx)
0045 {
0046 sctx->state[0] = read_octeon_64bit_hash_sha512(0);
0047 sctx->state[1] = read_octeon_64bit_hash_sha512(1);
0048 sctx->state[2] = read_octeon_64bit_hash_sha512(2);
0049 sctx->state[3] = read_octeon_64bit_hash_sha512(3);
0050 sctx->state[4] = read_octeon_64bit_hash_sha512(4);
0051 sctx->state[5] = read_octeon_64bit_hash_sha512(5);
0052 sctx->state[6] = read_octeon_64bit_hash_sha512(6);
0053 sctx->state[7] = read_octeon_64bit_hash_sha512(7);
0054 }
0055
0056 static void octeon_sha512_transform(const void *_block)
0057 {
0058 const u64 *block = _block;
0059
0060 write_octeon_64bit_block_sha512(block[0], 0);
0061 write_octeon_64bit_block_sha512(block[1], 1);
0062 write_octeon_64bit_block_sha512(block[2], 2);
0063 write_octeon_64bit_block_sha512(block[3], 3);
0064 write_octeon_64bit_block_sha512(block[4], 4);
0065 write_octeon_64bit_block_sha512(block[5], 5);
0066 write_octeon_64bit_block_sha512(block[6], 6);
0067 write_octeon_64bit_block_sha512(block[7], 7);
0068 write_octeon_64bit_block_sha512(block[8], 8);
0069 write_octeon_64bit_block_sha512(block[9], 9);
0070 write_octeon_64bit_block_sha512(block[10], 10);
0071 write_octeon_64bit_block_sha512(block[11], 11);
0072 write_octeon_64bit_block_sha512(block[12], 12);
0073 write_octeon_64bit_block_sha512(block[13], 13);
0074 write_octeon_64bit_block_sha512(block[14], 14);
0075 octeon_sha512_start(block[15]);
0076 }
0077
0078 static void __octeon_sha512_update(struct sha512_state *sctx, const u8 *data,
0079 unsigned int len)
0080 {
0081 unsigned int part_len;
0082 unsigned int index;
0083 unsigned int i;
0084
0085
0086 index = sctx->count[0] % SHA512_BLOCK_SIZE;
0087
0088
0089 if ((sctx->count[0] += len) < len)
0090 sctx->count[1]++;
0091
0092 part_len = SHA512_BLOCK_SIZE - index;
0093
0094
0095 if (len >= part_len) {
0096 memcpy(&sctx->buf[index], data, part_len);
0097 octeon_sha512_transform(sctx->buf);
0098
0099 for (i = part_len; i + SHA512_BLOCK_SIZE <= len;
0100 i += SHA512_BLOCK_SIZE)
0101 octeon_sha512_transform(&data[i]);
0102
0103 index = 0;
0104 } else {
0105 i = 0;
0106 }
0107
0108
0109 memcpy(&sctx->buf[index], &data[i], len - i);
0110 }
0111
0112 static int octeon_sha512_update(struct shash_desc *desc, const u8 *data,
0113 unsigned int len)
0114 {
0115 struct sha512_state *sctx = shash_desc_ctx(desc);
0116 struct octeon_cop2_state state;
0117 unsigned long flags;
0118
0119
0120
0121
0122
0123
0124 if ((sctx->count[0] % SHA512_BLOCK_SIZE) + len < SHA512_BLOCK_SIZE)
0125 return crypto_sha512_update(desc, data, len);
0126
0127 flags = octeon_crypto_enable(&state);
0128 octeon_sha512_store_hash(sctx);
0129
0130 __octeon_sha512_update(sctx, data, len);
0131
0132 octeon_sha512_read_hash(sctx);
0133 octeon_crypto_disable(&state, flags);
0134
0135 return 0;
0136 }
0137
0138 static int octeon_sha512_final(struct shash_desc *desc, u8 *hash)
0139 {
0140 struct sha512_state *sctx = shash_desc_ctx(desc);
0141 static u8 padding[128] = { 0x80, };
0142 struct octeon_cop2_state state;
0143 __be64 *dst = (__be64 *)hash;
0144 unsigned int pad_len;
0145 unsigned long flags;
0146 unsigned int index;
0147 __be64 bits[2];
0148 int i;
0149
0150
0151 bits[1] = cpu_to_be64(sctx->count[0] << 3);
0152 bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61);
0153
0154
0155 index = sctx->count[0] & 0x7f;
0156 pad_len = (index < 112) ? (112 - index) : ((128+112) - index);
0157
0158 flags = octeon_crypto_enable(&state);
0159 octeon_sha512_store_hash(sctx);
0160
0161 __octeon_sha512_update(sctx, padding, pad_len);
0162
0163
0164 __octeon_sha512_update(sctx, (const u8 *)bits, sizeof(bits));
0165
0166 octeon_sha512_read_hash(sctx);
0167 octeon_crypto_disable(&state, flags);
0168
0169
0170 for (i = 0; i < 8; i++)
0171 dst[i] = cpu_to_be64(sctx->state[i]);
0172
0173
0174 memset(sctx, 0, sizeof(struct sha512_state));
0175
0176 return 0;
0177 }
0178
0179 static int octeon_sha384_final(struct shash_desc *desc, u8 *hash)
0180 {
0181 u8 D[64];
0182
0183 octeon_sha512_final(desc, D);
0184
0185 memcpy(hash, D, 48);
0186 memzero_explicit(D, 64);
0187
0188 return 0;
0189 }
0190
0191 static struct shash_alg octeon_sha512_algs[2] = { {
0192 .digestsize = SHA512_DIGEST_SIZE,
0193 .init = sha512_base_init,
0194 .update = octeon_sha512_update,
0195 .final = octeon_sha512_final,
0196 .descsize = sizeof(struct sha512_state),
0197 .base = {
0198 .cra_name = "sha512",
0199 .cra_driver_name= "octeon-sha512",
0200 .cra_priority = OCTEON_CR_OPCODE_PRIORITY,
0201 .cra_blocksize = SHA512_BLOCK_SIZE,
0202 .cra_module = THIS_MODULE,
0203 }
0204 }, {
0205 .digestsize = SHA384_DIGEST_SIZE,
0206 .init = sha384_base_init,
0207 .update = octeon_sha512_update,
0208 .final = octeon_sha384_final,
0209 .descsize = sizeof(struct sha512_state),
0210 .base = {
0211 .cra_name = "sha384",
0212 .cra_driver_name= "octeon-sha384",
0213 .cra_priority = OCTEON_CR_OPCODE_PRIORITY,
0214 .cra_blocksize = SHA384_BLOCK_SIZE,
0215 .cra_module = THIS_MODULE,
0216 }
0217 } };
0218
0219 static int __init octeon_sha512_mod_init(void)
0220 {
0221 if (!octeon_has_crypto())
0222 return -ENOTSUPP;
0223 return crypto_register_shashes(octeon_sha512_algs,
0224 ARRAY_SIZE(octeon_sha512_algs));
0225 }
0226
0227 static void __exit octeon_sha512_mod_fini(void)
0228 {
0229 crypto_unregister_shashes(octeon_sha512_algs,
0230 ARRAY_SIZE(octeon_sha512_algs));
0231 }
0232
0233 module_init(octeon_sha512_mod_init);
0234 module_exit(octeon_sha512_mod_fini);
0235
0236 MODULE_LICENSE("GPL");
0237 MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms (OCTEON)");
0238 MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>");