]> Git Repo - J-linux.git/blob - arch/s390/crypto/sha_common.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / arch / s390 / crypto / sha_common.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Cryptographic API.
4  *
5  * s390 generic implementation of the SHA Secure Hash Algorithms.
6  *
7  * Copyright IBM Corp. 2007
8  * Author(s): Jan Glauber ([email protected])
9  */
10
11 #include <crypto/internal/hash.h>
12 #include <linux/module.h>
13 #include <asm/cpacf.h>
14 #include "sha.h"
15
16 int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
17 {
18         struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
19         unsigned int bsize = crypto_shash_blocksize(desc->tfm);
20         unsigned int index, n;
21         int fc;
22
23         /* how much is already in the buffer? */
24         index = ctx->count % bsize;
25         ctx->count += len;
26
27         if ((index + len) < bsize)
28                 goto store;
29
30         fc = ctx->func;
31         if (ctx->first_message_part)
32                 fc |= test_facility(86) ? CPACF_KIMD_NIP : 0;
33
34         /* process one stored block */
35         if (index) {
36                 memcpy(ctx->buf + index, data, bsize - index);
37                 cpacf_kimd(fc, ctx->state, ctx->buf, bsize);
38                 ctx->first_message_part = 0;
39                 fc &= ~CPACF_KIMD_NIP;
40                 data += bsize - index;
41                 len -= bsize - index;
42                 index = 0;
43         }
44
45         /* process as many blocks as possible */
46         if (len >= bsize) {
47                 n = (len / bsize) * bsize;
48                 cpacf_kimd(fc, ctx->state, data, n);
49                 ctx->first_message_part = 0;
50                 data += n;
51                 len -= n;
52         }
53 store:
54         if (len)
55                 memcpy(ctx->buf + index , data, len);
56
57         return 0;
58 }
59 EXPORT_SYMBOL_GPL(s390_sha_update);
60
61 static int s390_crypto_shash_parmsize(int func)
62 {
63         switch (func) {
64         case CPACF_KLMD_SHA_1:
65                 return 20;
66         case CPACF_KLMD_SHA_256:
67                 return 32;
68         case CPACF_KLMD_SHA_512:
69                 return 64;
70         case CPACF_KLMD_SHA3_224:
71         case CPACF_KLMD_SHA3_256:
72         case CPACF_KLMD_SHA3_384:
73         case CPACF_KLMD_SHA3_512:
74                 return 200;
75         default:
76                 return -EINVAL;
77         }
78 }
79
80 int s390_sha_final(struct shash_desc *desc, u8 *out)
81 {
82         struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
83         unsigned int bsize = crypto_shash_blocksize(desc->tfm);
84         u64 bits;
85         unsigned int n;
86         int mbl_offset, fc;
87
88         n = ctx->count % bsize;
89         bits = ctx->count * 8;
90         mbl_offset = s390_crypto_shash_parmsize(ctx->func);
91         if (mbl_offset < 0)
92                 return -EINVAL;
93
94         mbl_offset = mbl_offset / sizeof(u32);
95
96         /* set total msg bit length (mbl) in CPACF parmblock */
97         switch (ctx->func) {
98         case CPACF_KLMD_SHA_1:
99         case CPACF_KLMD_SHA_256:
100                 memcpy(ctx->state + mbl_offset, &bits, sizeof(bits));
101                 break;
102         case CPACF_KLMD_SHA_512:
103                 /*
104                  * the SHA512 parmblock has a 128-bit mbl field, clear
105                  * high-order u64 field, copy bits to low-order u64 field
106                  */
107                 memset(ctx->state + mbl_offset, 0x00, sizeof(bits));
108                 mbl_offset += sizeof(u64) / sizeof(u32);
109                 memcpy(ctx->state + mbl_offset, &bits, sizeof(bits));
110                 break;
111         case CPACF_KLMD_SHA3_224:
112         case CPACF_KLMD_SHA3_256:
113         case CPACF_KLMD_SHA3_384:
114         case CPACF_KLMD_SHA3_512:
115                 break;
116         default:
117                 return -EINVAL;
118         }
119
120         fc = ctx->func;
121         fc |= test_facility(86) ? CPACF_KLMD_DUFOP : 0;
122         if (ctx->first_message_part)
123                 fc |= CPACF_KLMD_NIP;
124         cpacf_klmd(fc, ctx->state, ctx->buf, n);
125
126         /* copy digest to out */
127         memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
128         /* wipe context */
129         memset(ctx, 0, sizeof *ctx);
130
131         return 0;
132 }
133 EXPORT_SYMBOL_GPL(s390_sha_final);
134
135 MODULE_LICENSE("GPL");
136 MODULE_DESCRIPTION("s390 SHA cipher common functions");
This page took 0.03438 seconds and 4 git commands to generate.