0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <crypto/internal/hash.h>
0012 #include <linux/init.h>
0013 #include <linux/module.h>
0014 #include <linux/mm.h>
0015 #include <linux/types.h>
0016 #include <crypto/sha2.h>
0017 #include <crypto/sha256_base.h>
0018 #include <asm/byteorder.h>
0019 #include <asm/switch_to.h>
0020 #include <linux/hardirq.h>
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #define MAX_BYTES 1024
0033
0034 extern void ppc_spe_sha256_transform(u32 *state, const u8 *src, u32 blocks);
0035
0036 static void spe_begin(void)
0037 {
0038
0039 preempt_disable();
0040 enable_kernel_spe();
0041 }
0042
0043 static void spe_end(void)
0044 {
0045 disable_kernel_spe();
0046
0047 preempt_enable();
0048 }
0049
0050 static inline void ppc_sha256_clear_context(struct sha256_state *sctx)
0051 {
0052 int count = sizeof(struct sha256_state) >> 2;
0053 u32 *ptr = (u32 *)sctx;
0054
0055
0056 BUILD_BUG_ON(sizeof(struct sha256_state) % 4);
0057 do { *ptr++ = 0; } while (--count);
0058 }
0059
0060 static int ppc_spe_sha256_update(struct shash_desc *desc, const u8 *data,
0061 unsigned int len)
0062 {
0063 struct sha256_state *sctx = shash_desc_ctx(desc);
0064 const unsigned int offset = sctx->count & 0x3f;
0065 const unsigned int avail = 64 - offset;
0066 unsigned int bytes;
0067 const u8 *src = data;
0068
0069 if (avail > len) {
0070 sctx->count += len;
0071 memcpy((char *)sctx->buf + offset, src, len);
0072 return 0;
0073 }
0074
0075 sctx->count += len;
0076
0077 if (offset) {
0078 memcpy((char *)sctx->buf + offset, src, avail);
0079
0080 spe_begin();
0081 ppc_spe_sha256_transform(sctx->state, (const u8 *)sctx->buf, 1);
0082 spe_end();
0083
0084 len -= avail;
0085 src += avail;
0086 }
0087
0088 while (len > 63) {
0089
0090 bytes = (len > MAX_BYTES) ? MAX_BYTES : len;
0091 bytes = bytes & ~0x3f;
0092
0093 spe_begin();
0094 ppc_spe_sha256_transform(sctx->state, src, bytes >> 6);
0095 spe_end();
0096
0097 src += bytes;
0098 len -= bytes;
0099 }
0100
0101 memcpy((char *)sctx->buf, src, len);
0102 return 0;
0103 }
0104
0105 static int ppc_spe_sha256_final(struct shash_desc *desc, u8 *out)
0106 {
0107 struct sha256_state *sctx = shash_desc_ctx(desc);
0108 const unsigned int offset = sctx->count & 0x3f;
0109 char *p = (char *)sctx->buf + offset;
0110 int padlen;
0111 __be64 *pbits = (__be64 *)(((char *)&sctx->buf) + 56);
0112 __be32 *dst = (__be32 *)out;
0113
0114 padlen = 55 - offset;
0115 *p++ = 0x80;
0116
0117 spe_begin();
0118
0119 if (padlen < 0) {
0120 memset(p, 0x00, padlen + sizeof (u64));
0121 ppc_spe_sha256_transform(sctx->state, sctx->buf, 1);
0122 p = (char *)sctx->buf;
0123 padlen = 56;
0124 }
0125
0126 memset(p, 0, padlen);
0127 *pbits = cpu_to_be64(sctx->count << 3);
0128 ppc_spe_sha256_transform(sctx->state, sctx->buf, 1);
0129
0130 spe_end();
0131
0132 dst[0] = cpu_to_be32(sctx->state[0]);
0133 dst[1] = cpu_to_be32(sctx->state[1]);
0134 dst[2] = cpu_to_be32(sctx->state[2]);
0135 dst[3] = cpu_to_be32(sctx->state[3]);
0136 dst[4] = cpu_to_be32(sctx->state[4]);
0137 dst[5] = cpu_to_be32(sctx->state[5]);
0138 dst[6] = cpu_to_be32(sctx->state[6]);
0139 dst[7] = cpu_to_be32(sctx->state[7]);
0140
0141 ppc_sha256_clear_context(sctx);
0142 return 0;
0143 }
0144
0145 static int ppc_spe_sha224_final(struct shash_desc *desc, u8 *out)
0146 {
0147 __be32 D[SHA256_DIGEST_SIZE >> 2];
0148 __be32 *dst = (__be32 *)out;
0149
0150 ppc_spe_sha256_final(desc, (u8 *)D);
0151
0152
0153 dst[0] = D[0];
0154 dst[1] = D[1];
0155 dst[2] = D[2];
0156 dst[3] = D[3];
0157 dst[4] = D[4];
0158 dst[5] = D[5];
0159 dst[6] = D[6];
0160
0161
0162 memzero_explicit(D, SHA256_DIGEST_SIZE);
0163 return 0;
0164 }
0165
0166 static int ppc_spe_sha256_export(struct shash_desc *desc, void *out)
0167 {
0168 struct sha256_state *sctx = shash_desc_ctx(desc);
0169
0170 memcpy(out, sctx, sizeof(*sctx));
0171 return 0;
0172 }
0173
0174 static int ppc_spe_sha256_import(struct shash_desc *desc, const void *in)
0175 {
0176 struct sha256_state *sctx = shash_desc_ctx(desc);
0177
0178 memcpy(sctx, in, sizeof(*sctx));
0179 return 0;
0180 }
0181
0182 static struct shash_alg algs[2] = { {
0183 .digestsize = SHA256_DIGEST_SIZE,
0184 .init = sha256_base_init,
0185 .update = ppc_spe_sha256_update,
0186 .final = ppc_spe_sha256_final,
0187 .export = ppc_spe_sha256_export,
0188 .import = ppc_spe_sha256_import,
0189 .descsize = sizeof(struct sha256_state),
0190 .statesize = sizeof(struct sha256_state),
0191 .base = {
0192 .cra_name = "sha256",
0193 .cra_driver_name= "sha256-ppc-spe",
0194 .cra_priority = 300,
0195 .cra_blocksize = SHA256_BLOCK_SIZE,
0196 .cra_module = THIS_MODULE,
0197 }
0198 }, {
0199 .digestsize = SHA224_DIGEST_SIZE,
0200 .init = sha224_base_init,
0201 .update = ppc_spe_sha256_update,
0202 .final = ppc_spe_sha224_final,
0203 .export = ppc_spe_sha256_export,
0204 .import = ppc_spe_sha256_import,
0205 .descsize = sizeof(struct sha256_state),
0206 .statesize = sizeof(struct sha256_state),
0207 .base = {
0208 .cra_name = "sha224",
0209 .cra_driver_name= "sha224-ppc-spe",
0210 .cra_priority = 300,
0211 .cra_blocksize = SHA224_BLOCK_SIZE,
0212 .cra_module = THIS_MODULE,
0213 }
0214 } };
0215
0216 static int __init ppc_spe_sha256_mod_init(void)
0217 {
0218 return crypto_register_shashes(algs, ARRAY_SIZE(algs));
0219 }
0220
0221 static void __exit ppc_spe_sha256_mod_fini(void)
0222 {
0223 crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
0224 }
0225
0226 module_init(ppc_spe_sha256_mod_init);
0227 module_exit(ppc_spe_sha256_mod_fini);
0228
0229 MODULE_LICENSE("GPL");
0230 MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, SPE optimized");
0231
0232 MODULE_ALIAS_CRYPTO("sha224");
0233 MODULE_ALIAS_CRYPTO("sha224-ppc-spe");
0234 MODULE_ALIAS_CRYPTO("sha256");
0235 MODULE_ALIAS_CRYPTO("sha256-ppc-spe");