Skip to content

Commit e68410e

Browse files
Ard Biesheuvelherbertx
authored andcommitted
crypto: x86/sha512_ssse3 - move SHA-384/512 SSSE3 implementation to base layer
This removes all the boilerplate from the existing implementation, and replaces it with calls into the base layer. It also changes the prototypes of the core asm functions to be compatible with the base prototype void (sha512_block_fn)(struct sha256_state *sst, u8 const *src, int blocks) so that they can be passed to the base layer directly. Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 1631030 commit e68410e

File tree

4 files changed

+44
-176
lines changed

4 files changed

+44
-176
lines changed

arch/x86/crypto/sha512-avx-asm.S

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@
5454

5555
# Virtual Registers
5656
# ARG1
57-
msg = %rdi
57+
digest = %rdi
5858
# ARG2
59-
digest = %rsi
59+
msg = %rsi
6060
# ARG3
6161
msglen = %rdx
6262
T1 = %rcx
@@ -271,7 +271,7 @@ frame_size = frame_GPRSAVE + GPRSAVE_SIZE
271271
.endm
272272

273273
########################################################################
274-
# void sha512_transform_avx(const void* M, void* D, u64 L)
274+
# void sha512_transform_avx(void* D, const void* M, u64 L)
275275
# Purpose: Updates the SHA512 digest stored at D with the message stored in M.
276276
# The size of the message pointed to by M must be an integer multiple of SHA512
277277
# message blocks.

arch/x86/crypto/sha512-avx2-asm.S

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ XFER = YTMP0
7070
BYTE_FLIP_MASK = %ymm9
7171

7272
# 1st arg
73-
INP = %rdi
73+
CTX = %rdi
7474
# 2nd arg
75-
CTX = %rsi
75+
INP = %rsi
7676
# 3rd arg
7777
NUM_BLKS = %rdx
7878

@@ -562,7 +562,7 @@ frame_size = frame_GPRSAVE + GPRSAVE_SIZE
562562
.endm
563563

564564
########################################################################
565-
# void sha512_transform_rorx(const void* M, void* D, uint64_t L)#
565+
# void sha512_transform_rorx(void* D, const void* M, uint64_t L)#
566566
# Purpose: Updates the SHA512 digest stored at D with the message stored in M.
567567
# The size of the message pointed to by M must be an integer multiple of SHA512
568568
# message blocks.

arch/x86/crypto/sha512-ssse3-asm.S

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@
5353

5454
# Virtual Registers
5555
# ARG1
56-
msg = %rdi
56+
digest = %rdi
5757
# ARG2
58-
digest = %rsi
58+
msg = %rsi
5959
# ARG3
6060
msglen = %rdx
6161
T1 = %rcx
@@ -269,7 +269,7 @@ frame_size = frame_GPRSAVE + GPRSAVE_SIZE
269269
.endm
270270

271271
########################################################################
272-
# void sha512_transform_ssse3(const void* M, void* D, u64 L)#
272+
# void sha512_transform_ssse3(void* D, const void* M, u64 L)#
273273
# Purpose: Updates the SHA512 digest stored at D with the message stored in M.
274274
# The size of the message pointed to by M must be an integer multiple of SHA512
275275
# message blocks.

arch/x86/crypto/sha512_ssse3_glue.c

Lines changed: 35 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -34,205 +34,75 @@
3434
#include <linux/cryptohash.h>
3535
#include <linux/types.h>
3636
#include <crypto/sha.h>
37-
#include <asm/byteorder.h>
37+
#include <crypto/sha512_base.h>
3838
#include <asm/i387.h>
3939
#include <asm/xcr.h>
4040
#include <asm/xsave.h>
4141

4242
#include <linux/string.h>
4343

44-
asmlinkage void sha512_transform_ssse3(const char *data, u64 *digest,
45-
u64 rounds);
44+
asmlinkage void sha512_transform_ssse3(u64 *digest, const char *data,
45+
u64 rounds);
4646
#ifdef CONFIG_AS_AVX
47-
asmlinkage void sha512_transform_avx(const char *data, u64 *digest,
47+
asmlinkage void sha512_transform_avx(u64 *digest, const char *data,
4848
u64 rounds);
4949
#endif
5050
#ifdef CONFIG_AS_AVX2
51-
asmlinkage void sha512_transform_rorx(const char *data, u64 *digest,
52-
u64 rounds);
51+
asmlinkage void sha512_transform_rorx(u64 *digest, const char *data,
52+
u64 rounds);
5353
#endif
5454

55-
static asmlinkage void (*sha512_transform_asm)(const char *, u64 *, u64);
56-
57-
58-
static int sha512_ssse3_init(struct shash_desc *desc)
59-
{
60-
struct sha512_state *sctx = shash_desc_ctx(desc);
61-
62-
sctx->state[0] = SHA512_H0;
63-
sctx->state[1] = SHA512_H1;
64-
sctx->state[2] = SHA512_H2;
65-
sctx->state[3] = SHA512_H3;
66-
sctx->state[4] = SHA512_H4;
67-
sctx->state[5] = SHA512_H5;
68-
sctx->state[6] = SHA512_H6;
69-
sctx->state[7] = SHA512_H7;
70-
sctx->count[0] = sctx->count[1] = 0;
71-
72-
return 0;
73-
}
55+
static void (*sha512_transform_asm)(u64 *, const char *, u64);
7456

75-
static int __sha512_ssse3_update(struct shash_desc *desc, const u8 *data,
76-
unsigned int len, unsigned int partial)
57+
static int sha512_ssse3_update(struct shash_desc *desc, const u8 *data,
58+
unsigned int len)
7759
{
7860
struct sha512_state *sctx = shash_desc_ctx(desc);
79-
unsigned int done = 0;
80-
81-
sctx->count[0] += len;
82-
if (sctx->count[0] < len)
83-
sctx->count[1]++;
8461

85-
if (partial) {
86-
done = SHA512_BLOCK_SIZE - partial;
87-
memcpy(sctx->buf + partial, data, done);
88-
sha512_transform_asm(sctx->buf, sctx->state, 1);
89-
}
90-
91-
if (len - done >= SHA512_BLOCK_SIZE) {
92-
const unsigned int rounds = (len - done) / SHA512_BLOCK_SIZE;
62+
if (!irq_fpu_usable() ||
63+
(sctx->count[0] % SHA512_BLOCK_SIZE) + len < SHA512_BLOCK_SIZE)
64+
return crypto_sha512_update(desc, data, len);
9365

94-
sha512_transform_asm(data + done, sctx->state, (u64) rounds);
95-
96-
done += rounds * SHA512_BLOCK_SIZE;
97-
}
66+
/* make sure casting to sha512_block_fn() is safe */
67+
BUILD_BUG_ON(offsetof(struct sha512_state, state) != 0);
9868

99-
memcpy(sctx->buf, data + done, len - done);
69+
kernel_fpu_begin();
70+
sha512_base_do_update(desc, data, len,
71+
(sha512_block_fn *)sha512_transform_asm);
72+
kernel_fpu_end();
10073

10174
return 0;
10275
}
10376

104-
static int sha512_ssse3_update(struct shash_desc *desc, const u8 *data,
105-
unsigned int len)
77+
static int sha512_ssse3_finup(struct shash_desc *desc, const u8 *data,
78+
unsigned int len, u8 *out)
10679
{
107-
struct sha512_state *sctx = shash_desc_ctx(desc);
108-
unsigned int partial = sctx->count[0] % SHA512_BLOCK_SIZE;
109-
int res;
110-
111-
/* Handle the fast case right here */
112-
if (partial + len < SHA512_BLOCK_SIZE) {
113-
sctx->count[0] += len;
114-
if (sctx->count[0] < len)
115-
sctx->count[1]++;
116-
memcpy(sctx->buf + partial, data, len);
117-
118-
return 0;
119-
}
80+
if (!irq_fpu_usable())
81+
return crypto_sha512_finup(desc, data, len, out);
12082

121-
if (!irq_fpu_usable()) {
122-
res = crypto_sha512_update(desc, data, len);
123-
} else {
124-
kernel_fpu_begin();
125-
res = __sha512_ssse3_update(desc, data, len, partial);
126-
kernel_fpu_end();
127-
}
83+
kernel_fpu_begin();
84+
if (len)
85+
sha512_base_do_update(desc, data, len,
86+
(sha512_block_fn *)sha512_transform_asm);
87+
sha512_base_do_finalize(desc, (sha512_block_fn *)sha512_transform_asm);
88+
kernel_fpu_end();
12889

129-
return res;
90+
return sha512_base_finish(desc, out);
13091
}
13192

132-
13393
/* Add padding and return the message digest. */
13494
static int sha512_ssse3_final(struct shash_desc *desc, u8 *out)
13595
{
136-
struct sha512_state *sctx = shash_desc_ctx(desc);
137-
unsigned int i, index, padlen;
138-
__be64 *dst = (__be64 *)out;
139-
__be64 bits[2];
140-
static const u8 padding[SHA512_BLOCK_SIZE] = { 0x80, };
141-
142-
/* save number of bits */
143-
bits[1] = cpu_to_be64(sctx->count[0] << 3);
144-
bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61);
145-
146-
/* Pad out to 112 mod 128 and append length */
147-
index = sctx->count[0] & 0x7f;
148-
padlen = (index < 112) ? (112 - index) : ((128+112) - index);
149-
150-
if (!irq_fpu_usable()) {
151-
crypto_sha512_update(desc, padding, padlen);
152-
crypto_sha512_update(desc, (const u8 *)&bits, sizeof(bits));
153-
} else {
154-
kernel_fpu_begin();
155-
/* We need to fill a whole block for __sha512_ssse3_update() */
156-
if (padlen <= 112) {
157-
sctx->count[0] += padlen;
158-
if (sctx->count[0] < padlen)
159-
sctx->count[1]++;
160-
memcpy(sctx->buf + index, padding, padlen);
161-
} else {
162-
__sha512_ssse3_update(desc, padding, padlen, index);
163-
}
164-
__sha512_ssse3_update(desc, (const u8 *)&bits,
165-
sizeof(bits), 112);
166-
kernel_fpu_end();
167-
}
168-
169-
/* Store state in digest */
170-
for (i = 0; i < 8; i++)
171-
dst[i] = cpu_to_be64(sctx->state[i]);
172-
173-
/* Wipe context */
174-
memset(sctx, 0, sizeof(*sctx));
175-
176-
return 0;
177-
}
178-
179-
static int sha512_ssse3_export(struct shash_desc *desc, void *out)
180-
{
181-
struct sha512_state *sctx = shash_desc_ctx(desc);
182-
183-
memcpy(out, sctx, sizeof(*sctx));
184-
185-
return 0;
186-
}
187-
188-
static int sha512_ssse3_import(struct shash_desc *desc, const void *in)
189-
{
190-
struct sha512_state *sctx = shash_desc_ctx(desc);
191-
192-
memcpy(sctx, in, sizeof(*sctx));
193-
194-
return 0;
195-
}
196-
197-
static int sha384_ssse3_init(struct shash_desc *desc)
198-
{
199-
struct sha512_state *sctx = shash_desc_ctx(desc);
200-
201-
sctx->state[0] = SHA384_H0;
202-
sctx->state[1] = SHA384_H1;
203-
sctx->state[2] = SHA384_H2;
204-
sctx->state[3] = SHA384_H3;
205-
sctx->state[4] = SHA384_H4;
206-
sctx->state[5] = SHA384_H5;
207-
sctx->state[6] = SHA384_H6;
208-
sctx->state[7] = SHA384_H7;
209-
210-
sctx->count[0] = sctx->count[1] = 0;
211-
212-
return 0;
213-
}
214-
215-
static int sha384_ssse3_final(struct shash_desc *desc, u8 *hash)
216-
{
217-
u8 D[SHA512_DIGEST_SIZE];
218-
219-
sha512_ssse3_final(desc, D);
220-
221-
memcpy(hash, D, SHA384_DIGEST_SIZE);
222-
memzero_explicit(D, SHA512_DIGEST_SIZE);
223-
224-
return 0;
96+
return sha512_ssse3_finup(desc, NULL, 0, out);
22597
}
22698

22799
static struct shash_alg algs[] = { {
228100
.digestsize = SHA512_DIGEST_SIZE,
229-
.init = sha512_ssse3_init,
101+
.init = sha512_base_init,
230102
.update = sha512_ssse3_update,
231103
.final = sha512_ssse3_final,
232-
.export = sha512_ssse3_export,
233-
.import = sha512_ssse3_import,
104+
.finup = sha512_ssse3_finup,
234105
.descsize = sizeof(struct sha512_state),
235-
.statesize = sizeof(struct sha512_state),
236106
.base = {
237107
.cra_name = "sha512",
238108
.cra_driver_name = "sha512-ssse3",
@@ -243,13 +113,11 @@ static struct shash_alg algs[] = { {
243113
}
244114
}, {
245115
.digestsize = SHA384_DIGEST_SIZE,
246-
.init = sha384_ssse3_init,
116+
.init = sha384_base_init,
247117
.update = sha512_ssse3_update,
248-
.final = sha384_ssse3_final,
249-
.export = sha512_ssse3_export,
250-
.import = sha512_ssse3_import,
118+
.final = sha512_ssse3_final,
119+
.finup = sha512_ssse3_finup,
251120
.descsize = sizeof(struct sha512_state),
252-
.statesize = sizeof(struct sha512_state),
253121
.base = {
254122
.cra_name = "sha384",
255123
.cra_driver_name = "sha384-ssse3",

0 commit comments

Comments
 (0)