Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/crypto/openssl/ossl_sha512.c
39536 views
1
/*
2
* Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved.
3
*
4
* Licensed under the OpenSSL license (the "License"). You may not use
5
* this file except in compliance with the License. You can obtain a copy
6
* in the file LICENSE in the source distribution or at
7
* https://www.openssl.org/source/license.html
8
*/
9
10
#include <sys/cdefs.h>
11
#include <sys/libkern.h>
12
#include <sys/malloc.h>
13
14
#include <opencrypto/cryptodev.h>
15
#include <opencrypto/xform_auth.h>
16
17
#include <crypto/openssl/ossl.h>
18
#include <crypto/openssl/ossl_sha.h>
19
20
/* sha512-x86_64.S */
21
void sha512_block_data_order(SHA512_CTX *c, const void *in, size_t num);
22
23
/* From crypto/sha/sha512.c */
24
25
#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
26
# define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
27
#endif
28
29
static void
30
ossl_sha384_init(void *c_)
31
{
32
SHA512_CTX *c = c_;
33
c->h[0] = U64(0xcbbb9d5dc1059ed8);
34
c->h[1] = U64(0x629a292a367cd507);
35
c->h[2] = U64(0x9159015a3070dd17);
36
c->h[3] = U64(0x152fecd8f70e5939);
37
c->h[4] = U64(0x67332667ffc00b31);
38
c->h[5] = U64(0x8eb44a8768581511);
39
c->h[6] = U64(0xdb0c2e0d64f98fa7);
40
c->h[7] = U64(0x47b5481dbefa4fa4);
41
42
c->Nl = 0;
43
c->Nh = 0;
44
c->num = 0;
45
c->md_len = SHA384_DIGEST_LENGTH;
46
}
47
48
static void
49
ossl_sha512_init(void *c_)
50
{
51
SHA512_CTX *c = c_;
52
c->h[0] = U64(0x6a09e667f3bcc908);
53
c->h[1] = U64(0xbb67ae8584caa73b);
54
c->h[2] = U64(0x3c6ef372fe94f82b);
55
c->h[3] = U64(0xa54ff53a5f1d36f1);
56
c->h[4] = U64(0x510e527fade682d1);
57
c->h[5] = U64(0x9b05688c2b3e6c1f);
58
c->h[6] = U64(0x1f83d9abfb41bd6b);
59
c->h[7] = U64(0x5be0cd19137e2179);
60
61
c->Nl = 0;
62
c->Nh = 0;
63
c->num = 0;
64
c->md_len = SHA512_DIGEST_LENGTH;
65
}
66
67
static void
68
ossl_sha512_final(uint8_t *md, void *c_)
69
{
70
SHA512_CTX *c = c_;
71
unsigned char *p = (unsigned char *)c->u.p;
72
size_t n = c->num;
73
74
p[n] = 0x80; /* There always is a room for one */
75
n++;
76
if (n > (sizeof(c->u) - 16)) {
77
memset(p + n, 0, sizeof(c->u) - n);
78
n = 0;
79
sha512_block_data_order(c, p, 1);
80
}
81
82
memset(p + n, 0, sizeof(c->u) - 16 - n);
83
#if _BYTE_ORDER == _BIG_ENDIAN
84
c->u.d[SHA_LBLOCK - 2] = c->Nh;
85
c->u.d[SHA_LBLOCK - 1] = c->Nl;
86
#else
87
p[sizeof(c->u) - 1] = (unsigned char)(c->Nl);
88
p[sizeof(c->u) - 2] = (unsigned char)(c->Nl >> 8);
89
p[sizeof(c->u) - 3] = (unsigned char)(c->Nl >> 16);
90
p[sizeof(c->u) - 4] = (unsigned char)(c->Nl >> 24);
91
p[sizeof(c->u) - 5] = (unsigned char)(c->Nl >> 32);
92
p[sizeof(c->u) - 6] = (unsigned char)(c->Nl >> 40);
93
p[sizeof(c->u) - 7] = (unsigned char)(c->Nl >> 48);
94
p[sizeof(c->u) - 8] = (unsigned char)(c->Nl >> 56);
95
p[sizeof(c->u) - 9] = (unsigned char)(c->Nh);
96
p[sizeof(c->u) - 10] = (unsigned char)(c->Nh >> 8);
97
p[sizeof(c->u) - 11] = (unsigned char)(c->Nh >> 16);
98
p[sizeof(c->u) - 12] = (unsigned char)(c->Nh >> 24);
99
p[sizeof(c->u) - 13] = (unsigned char)(c->Nh >> 32);
100
p[sizeof(c->u) - 14] = (unsigned char)(c->Nh >> 40);
101
p[sizeof(c->u) - 15] = (unsigned char)(c->Nh >> 48);
102
p[sizeof(c->u) - 16] = (unsigned char)(c->Nh >> 56);
103
#endif
104
105
sha512_block_data_order(c, p, 1);
106
107
switch (c->md_len) {
108
/* Let compiler decide if it's appropriate to unroll... */
109
case SHA224_DIGEST_LENGTH:
110
for (n = 0; n < SHA224_DIGEST_LENGTH / 8; n++) {
111
SHA_LONG64 t = c->h[n];
112
113
*(md++) = (unsigned char)(t >> 56);
114
*(md++) = (unsigned char)(t >> 48);
115
*(md++) = (unsigned char)(t >> 40);
116
*(md++) = (unsigned char)(t >> 32);
117
*(md++) = (unsigned char)(t >> 24);
118
*(md++) = (unsigned char)(t >> 16);
119
*(md++) = (unsigned char)(t >> 8);
120
*(md++) = (unsigned char)(t);
121
}
122
/*
123
* For 224 bits, there are four bytes left over that have to be
124
* processed separately.
125
*/
126
{
127
SHA_LONG64 t = c->h[SHA224_DIGEST_LENGTH / 8];
128
129
*(md++) = (unsigned char)(t >> 56);
130
*(md++) = (unsigned char)(t >> 48);
131
*(md++) = (unsigned char)(t >> 40);
132
*(md++) = (unsigned char)(t >> 32);
133
}
134
break;
135
case SHA256_DIGEST_LENGTH:
136
for (n = 0; n < SHA256_DIGEST_LENGTH / 8; n++) {
137
SHA_LONG64 t = c->h[n];
138
139
*(md++) = (unsigned char)(t >> 56);
140
*(md++) = (unsigned char)(t >> 48);
141
*(md++) = (unsigned char)(t >> 40);
142
*(md++) = (unsigned char)(t >> 32);
143
*(md++) = (unsigned char)(t >> 24);
144
*(md++) = (unsigned char)(t >> 16);
145
*(md++) = (unsigned char)(t >> 8);
146
*(md++) = (unsigned char)(t);
147
}
148
break;
149
case SHA384_DIGEST_LENGTH:
150
for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) {
151
SHA_LONG64 t = c->h[n];
152
153
*(md++) = (unsigned char)(t >> 56);
154
*(md++) = (unsigned char)(t >> 48);
155
*(md++) = (unsigned char)(t >> 40);
156
*(md++) = (unsigned char)(t >> 32);
157
*(md++) = (unsigned char)(t >> 24);
158
*(md++) = (unsigned char)(t >> 16);
159
*(md++) = (unsigned char)(t >> 8);
160
*(md++) = (unsigned char)(t);
161
}
162
break;
163
case SHA512_DIGEST_LENGTH:
164
for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) {
165
SHA_LONG64 t = c->h[n];
166
167
*(md++) = (unsigned char)(t >> 56);
168
*(md++) = (unsigned char)(t >> 48);
169
*(md++) = (unsigned char)(t >> 40);
170
*(md++) = (unsigned char)(t >> 32);
171
*(md++) = (unsigned char)(t >> 24);
172
*(md++) = (unsigned char)(t >> 16);
173
*(md++) = (unsigned char)(t >> 8);
174
*(md++) = (unsigned char)(t);
175
}
176
break;
177
/* ... as well as make sure md_len is not abused. */
178
default:
179
__assert_unreachable();
180
}
181
}
182
183
static int
184
ossl_sha512_update(void *c_, const void *_data, unsigned int len)
185
{
186
SHA512_CTX *c = c_;
187
SHA_LONG64 l;
188
unsigned char *p = c->u.p;
189
const unsigned char *data = (const unsigned char *)_data;
190
191
if (len == 0)
192
return 0;
193
194
l = (c->Nl + (((SHA_LONG64) len) << 3)) & U64(0xffffffffffffffff);
195
if (l < c->Nl)
196
c->Nh++;
197
if (sizeof(len) >= 8)
198
c->Nh += (((SHA_LONG64) len) >> 61);
199
c->Nl = l;
200
201
if (c->num != 0) {
202
size_t n = sizeof(c->u) - c->num;
203
204
if (len < n) {
205
memcpy(p + c->num, data, len), c->num += (unsigned int)len;
206
return 0;
207
} else {
208
memcpy(p + c->num, data, n), c->num = 0;
209
len -= n, data += n;
210
sha512_block_data_order(c, p, 1);
211
}
212
}
213
214
if (len >= sizeof(c->u)) {
215
#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
216
if ((size_t)data % sizeof(c->u.d[0]) != 0)
217
while (len >= sizeof(c->u))
218
memcpy(p, data, sizeof(c->u)),
219
sha512_block_data_order(c, p, 1),
220
len -= sizeof(c->u), data += sizeof(c->u);
221
else
222
#endif
223
sha512_block_data_order(c, data, len / sizeof(c->u)),
224
data += len, len %= sizeof(c->u), data -= len;
225
}
226
227
if (len != 0)
228
memcpy(p, data, len), c->num = (int)len;
229
230
return 0;
231
}
232
233
struct auth_hash ossl_hash_sha384 = {
234
.type = CRYPTO_SHA2_384,
235
.name = "OpenSSL-SHA2-384",
236
.hashsize = SHA2_384_HASH_LEN,
237
.ctxsize = sizeof(SHA512_CTX),
238
.blocksize = SHA2_384_BLOCK_LEN,
239
.Init = ossl_sha384_init,
240
.Update = ossl_sha512_update,
241
.Final = ossl_sha512_final,
242
};
243
244
struct auth_hash ossl_hash_sha512 = {
245
.type = CRYPTO_SHA2_512,
246
.name = "OpenSSL-SHA2-512",
247
.hashsize = SHA2_512_HASH_LEN,
248
.ctxsize = sizeof(SHA512_CTX),
249
.blocksize = SHA2_512_BLOCK_LEN,
250
.Init = ossl_sha512_init,
251
.Update = ossl_sha512_update,
252
.Final = ossl_sha512_final,
253
};
254
255
_Static_assert(sizeof(SHA512_CTX) <= sizeof(struct ossl_hash_context),
256
"ossl_hash_context too small");
257
258