0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <crypto/internal/hash.h>
0012 #include <linux/module.h>
0013 #include <asm/cpacf.h>
0014 #include "sha.h"
0015
0016 int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
0017 {
0018 struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
0019 unsigned int bsize = crypto_shash_blocksize(desc->tfm);
0020 unsigned int index, n;
0021
0022
0023 index = ctx->count % bsize;
0024 ctx->count += len;
0025
0026 if ((index + len) < bsize)
0027 goto store;
0028
0029
0030 if (index) {
0031 memcpy(ctx->buf + index, data, bsize - index);
0032 cpacf_kimd(ctx->func, ctx->state, ctx->buf, bsize);
0033 data += bsize - index;
0034 len -= bsize - index;
0035 index = 0;
0036 }
0037
0038
0039 if (len >= bsize) {
0040 n = (len / bsize) * bsize;
0041 cpacf_kimd(ctx->func, ctx->state, data, n);
0042 data += n;
0043 len -= n;
0044 }
0045 store:
0046 if (len)
0047 memcpy(ctx->buf + index , data, len);
0048
0049 return 0;
0050 }
0051 EXPORT_SYMBOL_GPL(s390_sha_update);
0052
0053 static int s390_crypto_shash_parmsize(int func)
0054 {
0055 switch (func) {
0056 case CPACF_KLMD_SHA_1:
0057 return 20;
0058 case CPACF_KLMD_SHA_256:
0059 return 32;
0060 case CPACF_KLMD_SHA_512:
0061 return 64;
0062 case CPACF_KLMD_SHA3_224:
0063 case CPACF_KLMD_SHA3_256:
0064 case CPACF_KLMD_SHA3_384:
0065 case CPACF_KLMD_SHA3_512:
0066 return 200;
0067 default:
0068 return -EINVAL;
0069 }
0070 }
0071
0072 int s390_sha_final(struct shash_desc *desc, u8 *out)
0073 {
0074 struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
0075 unsigned int bsize = crypto_shash_blocksize(desc->tfm);
0076 u64 bits;
0077 unsigned int n;
0078 int mbl_offset;
0079
0080 n = ctx->count % bsize;
0081 bits = ctx->count * 8;
0082 mbl_offset = s390_crypto_shash_parmsize(ctx->func);
0083 if (mbl_offset < 0)
0084 return -EINVAL;
0085
0086 mbl_offset = mbl_offset / sizeof(u32);
0087
0088
0089 switch (ctx->func) {
0090 case CPACF_KLMD_SHA_1:
0091 case CPACF_KLMD_SHA_256:
0092 memcpy(ctx->state + mbl_offset, &bits, sizeof(bits));
0093 break;
0094 case CPACF_KLMD_SHA_512:
0095
0096
0097
0098
0099 memset(ctx->state + mbl_offset, 0x00, sizeof(bits));
0100 mbl_offset += sizeof(u64) / sizeof(u32);
0101 memcpy(ctx->state + mbl_offset, &bits, sizeof(bits));
0102 break;
0103 case CPACF_KLMD_SHA3_224:
0104 case CPACF_KLMD_SHA3_256:
0105 case CPACF_KLMD_SHA3_384:
0106 case CPACF_KLMD_SHA3_512:
0107 break;
0108 default:
0109 return -EINVAL;
0110 }
0111
0112 cpacf_klmd(ctx->func, ctx->state, ctx->buf, n);
0113
0114
0115 memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
0116
0117 memset(ctx, 0, sizeof *ctx);
0118
0119 return 0;
0120 }
0121 EXPORT_SYMBOL_GPL(s390_sha_final);
0122
0123 MODULE_LICENSE("GPL");
0124 MODULE_DESCRIPTION("s390 SHA cipher common functions");