Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/s390/crypto/sha_common.c
10817 views
1
/*
2
* Cryptographic API.
3
*
4
* s390 generic implementation of the SHA Secure Hash Algorithms.
5
*
6
* Copyright IBM Corp. 2007
7
* Author(s): Jan Glauber ([email protected])
8
*
9
* This program is free software; you can redistribute it and/or modify it
10
* under the terms of the GNU General Public License as published by the Free
11
* Software Foundation; either version 2 of the License, or (at your option)
12
* any later version.
13
*
14
*/
15
16
#include <crypto/internal/hash.h>
17
#include "sha.h"
18
#include "crypt_s390.h"
19
20
int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
21
{
22
struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
23
unsigned int bsize = crypto_shash_blocksize(desc->tfm);
24
unsigned int index;
25
int ret;
26
27
/* how much is already in the buffer? */
28
index = ctx->count & (bsize - 1);
29
ctx->count += len;
30
31
if ((index + len) < bsize)
32
goto store;
33
34
/* process one stored block */
35
if (index) {
36
memcpy(ctx->buf + index, data, bsize - index);
37
ret = crypt_s390_kimd(ctx->func, ctx->state, ctx->buf, bsize);
38
BUG_ON(ret != bsize);
39
data += bsize - index;
40
len -= bsize - index;
41
index = 0;
42
}
43
44
/* process as many blocks as possible */
45
if (len >= bsize) {
46
ret = crypt_s390_kimd(ctx->func, ctx->state, data,
47
len & ~(bsize - 1));
48
BUG_ON(ret != (len & ~(bsize - 1)));
49
data += ret;
50
len -= ret;
51
}
52
store:
53
if (len)
54
memcpy(ctx->buf + index , data, len);
55
56
return 0;
57
}
58
EXPORT_SYMBOL_GPL(s390_sha_update);
59
60
int s390_sha_final(struct shash_desc *desc, u8 *out)
61
{
62
struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
63
unsigned int bsize = crypto_shash_blocksize(desc->tfm);
64
u64 bits;
65
unsigned int index, end, plen;
66
int ret;
67
68
/* SHA-512 uses 128 bit padding length */
69
plen = (bsize > SHA256_BLOCK_SIZE) ? 16 : 8;
70
71
/* must perform manual padding */
72
index = ctx->count & (bsize - 1);
73
end = (index < bsize - plen) ? bsize : (2 * bsize);
74
75
/* start pad with 1 */
76
ctx->buf[index] = 0x80;
77
index++;
78
79
/* pad with zeros */
80
memset(ctx->buf + index, 0x00, end - index - 8);
81
82
/*
83
* Append message length. Well, SHA-512 wants a 128 bit length value,
84
* nevertheless we use u64, should be enough for now...
85
*/
86
bits = ctx->count * 8;
87
memcpy(ctx->buf + end - 8, &bits, sizeof(bits));
88
89
ret = crypt_s390_kimd(ctx->func, ctx->state, ctx->buf, end);
90
BUG_ON(ret != end);
91
92
/* copy digest to out */
93
memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
94
/* wipe context */
95
memset(ctx, 0, sizeof *ctx);
96
97
return 0;
98
}
99
EXPORT_SYMBOL_GPL(s390_sha_final);
100
101
MODULE_LICENSE("GPL");
102
MODULE_DESCRIPTION("s390 SHA cipher common functions");
103
104