Coverage Report

Created: 2026-09-12 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl41/crypto/sha/sha512.c
Line
Count
Source
1
/*
2
 * Copyright 2004-2026 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (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
/*
11
 * SHA512 low level APIs are deprecated for public use, but still ok for
12
 * internal use.
13
 */
14
#include "internal/deprecated.h"
15
16
#include <stdio.h>
17
#include <openssl/opensslconf.h>
18
#include <openssl/byteorder.h>
19
/*-
20
 * IMPLEMENTATION NOTES.
21
 *
22
 * As you might have noticed, 32-bit hash algorithms:
23
 *
24
 * - permit SHA_LONG to be wider than 32-bit
25
 * - optimized versions implement two transform functions: one operating
26
 *   on [aligned] data in host byte order, and one operating on data in input
27
 *   stream byte order;
28
 * - share common byte-order neutral collector and padding function
29
 *   implementations, crypto/md32_common.inc;
30
 *
31
 * Neither of the above applies to this SHA-512 implementation. Reasons
32
 * [in reverse order] are:
33
 *
34
 * - it's the only 64-bit hash algorithm for the moment of this writing,
35
 *   there is no need for common collector/padding implementation [yet];
36
 * - by supporting only one transform function [which operates on
37
 *   *aligned* data in input stream byte order, big-endian in this case]
38
 *   we minimize burden of maintenance in two ways: a) collector/padding
39
 *   function is simpler; b) only one transform function to stare at;
40
 * - SHA_LONG64 is required to be exactly 64-bit in order to be able to
41
 *   apply a number of optimizations to mitigate potential performance
42
 *   penalties caused by previous design decision;
43
 *
44
 * Caveat lector.
45
 *
46
 * Implementation relies on the fact that "long long" is 64-bit on
47
 * both 32- and 64-bit platforms. If some compiler vendor comes up
48
 * with 128-bit long long, adjustment to sha.h would be required.
49
 * As this implementation relies on 64-bit integer type, it's totally
50
 * inappropriate for platforms which don't support it, most notably
51
 * 16-bit platforms.
52
 */
53
#include <stdlib.h>
54
#include <string.h>
55
56
#include <openssl/crypto.h>
57
#include <openssl/sha.h>
58
#include <openssl/opensslv.h>
59
60
#include "internal/cryptlib.h"
61
#include "crypto/sha.h"
62
63
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(__s390__) || defined(__s390x__) || defined(__aarch64__) || defined(__e2k__) || defined(SHA512_ASM)
64
#define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
65
#endif
66
67
#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
68
#define U64(C) C##UI64
69
#elif defined(__arch64__)
70
#define U64(C) C##UL
71
#else
72
339M
#define U64(C) C##ULL
73
#endif
74
75
int SHA512_Update_thunk(void *cp, const unsigned char *data, size_t len);
76
77
int sha512_224_init(SHA512_CTX *c)
78
143k
{
79
143k
    c->h[0] = U64(0x8c3d37c819544da2);
80
143k
    c->h[1] = U64(0x73e1996689dcd4d6);
81
143k
    c->h[2] = U64(0x1dfab7ae32ff9c82);
82
143k
    c->h[3] = U64(0x679dd514582f9fcf);
83
143k
    c->h[4] = U64(0x0f6d2b697bd44da8);
84
143k
    c->h[5] = U64(0x77e36f7304c48942);
85
143k
    c->h[6] = U64(0x3f9d85a86a1d36c8);
86
143k
    c->h[7] = U64(0x1112e6ad91d692a1);
87
88
143k
    c->Nl = 0;
89
143k
    c->Nh = 0;
90
143k
    c->num = 0;
91
143k
    c->md_len = SHA224_DIGEST_LENGTH;
92
143k
    return 1;
93
143k
}
94
95
int sha512_256_init(SHA512_CTX *c)
96
155k
{
97
155k
    c->h[0] = U64(0x22312194fc2bf72c);
98
155k
    c->h[1] = U64(0x9f555fa3c84c64c2);
99
155k
    c->h[2] = U64(0x2393b86b6f53b151);
100
155k
    c->h[3] = U64(0x963877195940eabd);
101
155k
    c->h[4] = U64(0x96283ee2a88effe3);
102
155k
    c->h[5] = U64(0xbe5e1e2553863992);
103
155k
    c->h[6] = U64(0x2b0199fc2c85b8aa);
104
155k
    c->h[7] = U64(0x0eb72ddc81c52ca2);
105
106
155k
    c->Nl = 0;
107
155k
    c->Nh = 0;
108
155k
    c->num = 0;
109
155k
    c->md_len = SHA256_DIGEST_LENGTH;
110
155k
    return 1;
111
155k
}
112
113
int SHA384_Init(SHA512_CTX *c)
114
1.64M
{
115
1.64M
    c->h[0] = U64(0xcbbb9d5dc1059ed8);
116
1.64M
    c->h[1] = U64(0x629a292a367cd507);
117
1.64M
    c->h[2] = U64(0x9159015a3070dd17);
118
1.64M
    c->h[3] = U64(0x152fecd8f70e5939);
119
1.64M
    c->h[4] = U64(0x67332667ffc00b31);
120
1.64M
    c->h[5] = U64(0x8eb44a8768581511);
121
1.64M
    c->h[6] = U64(0xdb0c2e0d64f98fa7);
122
1.64M
    c->h[7] = U64(0x47b5481dbefa4fa4);
123
124
1.64M
    c->Nl = 0;
125
1.64M
    c->Nh = 0;
126
1.64M
    c->num = 0;
127
1.64M
    c->md_len = SHA384_DIGEST_LENGTH;
128
1.64M
    return 1;
129
1.64M
}
130
131
int SHA512_Init(SHA512_CTX *c)
132
30.4M
{
133
30.4M
    c->h[0] = U64(0x6a09e667f3bcc908);
134
30.4M
    c->h[1] = U64(0xbb67ae8584caa73b);
135
30.4M
    c->h[2] = U64(0x3c6ef372fe94f82b);
136
30.4M
    c->h[3] = U64(0xa54ff53a5f1d36f1);
137
30.4M
    c->h[4] = U64(0x510e527fade682d1);
138
30.4M
    c->h[5] = U64(0x9b05688c2b3e6c1f);
139
30.4M
    c->h[6] = U64(0x1f83d9abfb41bd6b);
140
30.4M
    c->h[7] = U64(0x5be0cd19137e2179);
141
142
30.4M
    c->Nl = 0;
143
30.4M
    c->Nh = 0;
144
30.4M
    c->num = 0;
145
30.4M
    c->md_len = SHA512_DIGEST_LENGTH;
146
30.4M
    return 1;
147
30.4M
}
148
149
#ifndef SHA512_ASM
150
static
151
#else
152
#ifdef INCLUDE_C_SHA512
153
void sha512_block_data_order_c(SHA512_CTX *ctx, const void *in, size_t num);
154
#endif
155
#endif
156
    void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num);
157
158
#define OUTPUT_RESULT(md, len)      \
159
93.0M
    for (n = 0; n < (len / 8); n++) \
160
73.7M
    md = OPENSSL_store_u64_be(md, (uint64_t)c->h[n])
161
162
int SHA512_Final(unsigned char *out, SHA512_CTX *c)
163
19.2M
{
164
19.2M
    unsigned char *p = (unsigned char *)c->u.p;
165
19.2M
    size_t n = c->num;
166
167
19.2M
    p[n] = 0x80; /* There always is a room for one */
168
19.2M
    n++;
169
19.2M
    if (n > (sizeof(c->u) - 16)) {
170
73.4k
        memset(p + n, 0, sizeof(c->u) - n);
171
73.4k
        n = 0;
172
73.4k
        sha512_block_data_order(c, p, 1);
173
73.4k
    }
174
175
19.2M
    memset(p + n, 0, sizeof(c->u) - 16 - n);
176
#ifdef B_ENDIAN
177
    c->u.d[SHA_LBLOCK - 2] = c->Nh;
178
    c->u.d[SHA_LBLOCK - 1] = c->Nl;
179
#else
180
19.2M
    uint8_t *cu = p + sizeof(c->u) - 16;
181
182
19.2M
    cu = OPENSSL_store_u64_be(cu, (uint64_t)c->Nh);
183
19.2M
    cu = OPENSSL_store_u64_be(cu, (uint64_t)c->Nl);
184
19.2M
#endif
185
186
19.2M
    sha512_block_data_order(c, p, 1);
187
188
19.2M
    if (out == NULL)
189
0
        return 0;
190
191
    /* Let compiler decide if it's appropriate to unroll... */
192
19.2M
    switch (c->md_len) {
193
5.38M
    case SHA256_192_DIGEST_LENGTH:
194
5.38M
        OUTPUT_RESULT(out, SHA256_192_DIGEST_LENGTH);
195
5.38M
        break;
196
10.8M
    case SHA256_DIGEST_LENGTH:
197
10.8M
        OUTPUT_RESULT(out, SHA256_DIGEST_LENGTH);
198
10.8M
        break;
199
1.21M
    case SHA384_DIGEST_LENGTH:
200
1.21M
        OUTPUT_RESULT(out, SHA384_DIGEST_LENGTH);
201
1.21M
        break;
202
298k
    case SHA512_DIGEST_LENGTH:
203
298k
        OUTPUT_RESULT(out, SHA512_DIGEST_LENGTH);
204
298k
        break;
205
1.55M
    case SHA224_DIGEST_LENGTH: {
206
1.55M
        OUTPUT_RESULT(out, SHA224_DIGEST_LENGTH);
207
        /*
208
         * For 224 bits, there are four bytes left over that have to be
209
         * processed separately.
210
         */
211
1.55M
        {
212
1.55M
            SHA_LONG64 t = c->h[SHA224_DIGEST_LENGTH / 8];
213
214
1.55M
            *(out++) = (unsigned char)(t >> 56);
215
1.55M
            *(out++) = (unsigned char)(t >> 48);
216
1.55M
            *(out++) = (unsigned char)(t >> 40);
217
1.55M
            *(out++) = (unsigned char)(t >> 32);
218
1.55M
        }
219
1.55M
        break;
220
0
    }
221
    /* ... as well as make sure md_len is not abused. */
222
0
    default:
223
0
        return 0;
224
19.2M
    }
225
226
19.2M
    return 1;
227
19.2M
}
228
229
int SHA384_Final(unsigned char *md, SHA512_CTX *c)
230
2.35M
{
231
2.35M
    return SHA512_Final(md, c);
232
2.35M
}
233
234
int SHA512_Update_thunk(void *cp, const unsigned char *data, size_t len)
235
80.5M
{
236
80.5M
    SHA512_CTX *c = (SHA512_CTX *)cp;
237
80.5M
    SHA_LONG64 l;
238
80.5M
    unsigned char *p = c->u.p;
239
240
80.5M
    if (len == 0)
241
0
        return 1;
242
243
80.5M
    l = (c->Nl + (((SHA_LONG64)len) << 3)) & U64(0xffffffffffffffff);
244
80.5M
    if (l < c->Nl)
245
0
        c->Nh++;
246
80.5M
    if (sizeof(len) >= 8)
247
80.5M
        c->Nh += (((SHA_LONG64)len) >> 61);
248
80.5M
    c->Nl = l;
249
250
80.5M
    if (c->num != 0) {
251
45.8M
        size_t n = sizeof(c->u) - c->num;
252
253
45.8M
        if (len < n) {
254
30.4M
            memcpy(p + c->num, data, len), c->num += (unsigned int)len;
255
30.4M
            return 1;
256
30.4M
        } else {
257
15.3M
            memcpy(p + c->num, data, n), c->num = 0;
258
15.3M
            len -= n, data += n;
259
15.3M
            sha512_block_data_order(c, p, 1);
260
15.3M
        }
261
45.8M
    }
262
263
50.1M
    if (len >= sizeof(c->u)) {
264
#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
265
        if ((size_t)data % sizeof(c->u.d[0]) != 0)
266
            while (len >= sizeof(c->u))
267
                memcpy(p, data, sizeof(c->u)),
268
                    sha512_block_data_order(c, p, 1),
269
                    len -= sizeof(c->u), data += sizeof(c->u);
270
        else
271
#endif
272
721k
            sha512_block_data_order(c, data, len / sizeof(c->u)),
273
721k
                data += len, len %= sizeof(c->u), data -= len;
274
721k
    }
275
276
50.1M
    if (len != 0)
277
34.6M
        memcpy(p, data, len), c->num = (int)len;
278
279
50.1M
    return 1;
280
80.5M
}
281
282
int SHA512_Update(SHA512_CTX *c, const void *_data, size_t len)
283
74.7M
{
284
74.7M
    return SHA512_Update_thunk((void *)c, (const unsigned char *)_data, len);
285
74.7M
}
286
287
int SHA384_Update(SHA512_CTX *c, const void *data, size_t len)
288
2.25M
{
289
2.25M
    return SHA512_Update_thunk((void *)c, (const unsigned char *)data, len);
290
2.25M
}
291
292
void SHA512_Transform(SHA512_CTX *c, const unsigned char *data)
293
89.3k
{
294
#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
295
    if ((size_t)data % sizeof(c->u.d[0]) != 0)
296
        memcpy(c->u.p, data, sizeof(c->u.p)), data = c->u.p;
297
#endif
298
89.3k
    sha512_block_data_order(c, data, 1);
299
89.3k
}
300
301
#if !defined(SHA512_ASM) || defined(INCLUDE_C_SHA512)
302
static const SHA_LONG64 K512[80] = {
303
    U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd),
304
    U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc),
305
    U64(0x3956c25bf348b538), U64(0x59f111f1b605d019),
306
    U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118),
307
    U64(0xd807aa98a3030242), U64(0x12835b0145706fbe),
308
    U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2),
309
    U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1),
310
    U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694),
311
    U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3),
312
    U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65),
313
    U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483),
314
    U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5),
315
    U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210),
316
    U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4),
317
    U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725),
318
    U64(0x06ca6351e003826f), U64(0x142929670a0e6e70),
319
    U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926),
320
    U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df),
321
    U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8),
322
    U64(0x81c2c92e47edaee6), U64(0x92722c851482353b),
323
    U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001),
324
    U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30),
325
    U64(0xd192e819d6ef5218), U64(0xd69906245565a910),
326
    U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8),
327
    U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53),
328
    U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8),
329
    U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb),
330
    U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3),
331
    U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60),
332
    U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec),
333
    U64(0x90befffa23631e28), U64(0xa4506cebde82bde9),
334
    U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b),
335
    U64(0xca273eceea26619c), U64(0xd186b8c721c0c207),
336
    U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178),
337
    U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6),
338
    U64(0x113f9804bef90dae), U64(0x1b710b35131c471b),
339
    U64(0x28db77f523047d84), U64(0x32caab7b40c72493),
340
    U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c),
341
    U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a),
342
    U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817)
343
};
344
345
#ifndef PEDANTIC
346
#if defined(__GNUC__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
347
#if defined(__x86_64) || defined(__x86_64__)
348
#define ROTR(a, n) ({ SHA_LONG64 ret;             \
349
                                asm ("rorq %1,%0"       \
350
                                : "=r"(ret)             \
351
                                : "J"(n),"0"(a)         \
352
                                : "cc"); ret; })
353
#if !defined(B_ENDIAN)
354
#define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x)));  \
355
                                asm ("bswapq    %0"             \
356
                                : "=r"(ret)                     \
357
                                : "0"(ret)); ret; })
358
#endif
359
#elif (defined(__i386) || defined(__i386__)) && !defined(B_ENDIAN)
360
#if defined(I386_ONLY)
361
#define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
362
                          unsigned int hi=p[0],lo=p[1];          \
363
                                asm("xchgb %%ah,%%al;xchgb %%dh,%%dl;"\
364
                                    "roll $16,%%eax; roll $16,%%edx; "\
365
                                    "xchgb %%ah,%%al;xchgb %%dh,%%dl;"\
366
                                : "=a"(lo),"=d"(hi)             \
367
                                : "0"(lo),"1"(hi) : "cc");      \
368
                                ((SHA_LONG64)hi)<<32|lo; })
369
#else
370
#define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
371
                          unsigned int hi=p[0],lo=p[1];         \
372
                                asm ("bswapl %0; bswapl %1;"    \
373
                                : "=r"(lo),"=r"(hi)             \
374
                                : "0"(lo),"1"(hi));             \
375
                                ((SHA_LONG64)hi)<<32|lo; })
376
#endif
377
#elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
378
#define ROTR(a, n) ({ SHA_LONG64 ret;             \
379
                                asm ("rotrdi %0,%1,%2"  \
380
                                : "=r"(ret)             \
381
                                : "r"(a),"K"(n)); ret; })
382
#elif defined(__aarch64__)
383
#define ROTR(a, n) ({ SHA_LONG64 ret;             \
384
                                asm ("ror %0,%1,%2"     \
385
                                : "=r"(ret)             \
386
                                : "r"(a),"I"(n)); ret; })
387
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
388
#define PULL64(x) ({ SHA_LONG64 ret;                     \
389
                                asm ("rev       %0,%1"          \
390
                                : "=r"(ret)                     \
391
                                : "r"(*((const SHA_LONG64 *)(&(x))))); ret; })
392
#endif
393
#elif (defined(__riscv_zbkb) || defined(__riscv_zbb)) && __riscv_xlen == 32
394
#define PULL64(x) ({ SHA_LONG64 ret;                                        \
395
                        unsigned int *r = (unsigned int *)(&(ret));             \
396
                        const unsigned int *p = (const unsigned int *)(&(x));   \
397
                        asm ("rev8 %0, %1"                                      \
398
                        : "=r"(r[0])                                            \
399
                        : "r" (p[1]));                                          \
400
                        asm ("rev8 %0, %1"                                      \
401
                        : "=r"(r[1])                                            \
402
                        : "r" (p[0])); ret; })
403
#elif (defined(__riscv_zbkb) || defined(__riscv_zbb)) && __riscv_xlen == 64
404
#define PULL64(x) ({ SHA_LONG64 ret;    \
405
                        asm ("rev8 %0, %1"  \
406
                        : "=r"(ret)         \
407
                        : "r"(x)); ret; })
408
#elif defined(__e2k__)
409
#include <x86gprintrin.h>
410
#define PULL64(x) __builtin_bswap64(x)
411
#define ROTR(x, s) ((s) > 48 ? __rolq((x), 64 - (s)) \
412
                             : __rorq((x), (s)))
413
#endif
414
#if defined(__riscv_zknh) && __riscv_xlen == 32
415
#define Sigma0(x) ({ SHA_LONG64 ret; unsigned int *r = (unsigned int *)(&(ret));    \
416
                        const unsigned int *p = (const unsigned int *)(&(x));           \
417
                        asm ("sha512sum0r %0, %1, %2"                                   \
418
                        : "=r"(r[0])                                                    \
419
                        : "r" (p[0]), "r" (p[1]));                                      \
420
                        asm ("sha512sum0r %0, %2, %1"                                   \
421
                        : "=r"(r[1])                                                    \
422
                        : "r" (p[0]), "r" (p[1])); ret; })
423
#define Sigma1(x) ({ SHA_LONG64 ret; unsigned int *r = (unsigned int *)(&(ret));    \
424
                        const unsigned int *p = (const unsigned int *)(&(x));           \
425
                        asm ("sha512sum1r %0, %1, %2"                                   \
426
                        : "=r"(r[0])                                                    \
427
                        : "r" (p[0]), "r" (p[1]));                                      \
428
                        asm ("sha512sum1r %0, %2, %1"                                   \
429
                        : "=r"(r[1])                                                    \
430
                        : "r" (p[0]), "r" (p[1])); ret; })
431
#define sigma0(x) ({ SHA_LONG64 ret; unsigned int *r = (unsigned int *)(&(ret));    \
432
                        const unsigned int *p = (const unsigned int *)(&(x));           \
433
                        asm ("sha512sig0l %0, %1, %2"                                   \
434
                        : "=r"(r[0])                                                    \
435
                        : "r" (p[0]), "r" (p[1]));                                      \
436
                        asm ("sha512sig0h %0, %2, %1"                                   \
437
                        : "=r"(r[1])                                                    \
438
                        : "r" (p[0]), "r" (p[1])); ret; })
439
#define sigma1(x) ({ SHA_LONG64 ret; unsigned int *r = (unsigned int *)(&(ret));    \
440
                        const unsigned int *p = (const unsigned int *)(&(x));           \
441
                        asm ("sha512sig1l %0, %1, %2"                                   \
442
                        : "=r"(r[0])                                                    \
443
                        : "r" (p[0]), "r" (p[1]));                                      \
444
                        asm ("sha512sig1h %0, %2, %1"                                   \
445
                        : "=r"(r[1])                                                    \
446
                        : "r" (p[0]), "r" (p[1])); ret; })
447
#elif defined(__riscv_zknh) && __riscv_xlen == 64
448
#define Sigma0(x) ({ SHA_LONG64 ret;            \
449
                        asm ("sha512sum0 %0, %1"    \
450
                        : "=r"(ret)                 \
451
                        : "r"(x)); ret; })
452
#define Sigma1(x) ({ SHA_LONG64 ret;            \
453
                        asm ("sha512sum1 %0, %1"    \
454
                        : "=r"(ret)                 \
455
                        : "r"(x)); ret; })
456
#define sigma0(x) ({ SHA_LONG64 ret;            \
457
                        asm ("sha512sig0 %0, %1"    \
458
                        : "=r"(ret)                 \
459
                        : "r"(x)); ret; })
460
#define sigma1(x) ({ SHA_LONG64 ret;            \
461
                        asm ("sha512sig1 %0, %1"    \
462
                        : "=r"(ret)                 \
463
                        : "r"(x)); ret; })
464
#endif
465
#if (defined(__riscv_zbt) || defined(__riscv_zpn)) && __riscv_xlen == 32
466
#define Ch(x, y, z) ({  SHA_LONG64 ret; unsigned int *r = (unsigned int *)(&(ret));   \
467
                        const unsigned int *xp = (const unsigned int *)(&(x));          \
468
                        const unsigned int *yp = (const unsigned int *)(&(y));          \
469
                        const unsigned int *zp = (const unsigned int *)(&(z));          \
470
                        asm (".insn r4 0x33, 1, 0x3, %0, %2, %1, %3\n\t"                \
471
                        : "=r"(r[0])                                                    \
472
                        : "r"(xp[0]), "r"(yp[0]), "r"(zp[0]));                          \
473
                        asm (".insn r4 0x33, 1, 0x3, %0, %2, %1, %3\n\t"                \
474
                        : "=r"(r[1])                                                    \
475
                        : "r"(xp[1]), "r"(yp[1]), "r"(zp[1])); ret; })
476
#define Maj(x, y, z) ({ SHA_LONG64 ret; unsigned int *r = (unsigned int *)(&(ret));   \
477
                        const unsigned int *xp = (const unsigned int *)(&(x));          \
478
                        const unsigned int *yp = (const unsigned int *)(&(y));          \
479
                        const unsigned int *zp = (const unsigned int *)(&(z));          \
480
                        asm (".insn r4 0x33, 1, 0x3, %0, %2, %1, %3\n\t"                \
481
                        : "=r"(r[0])                                                    \
482
                        : "r"(xp[0]^zp[0]), "r"(yp[0]), "r"(zp[0]));                    \
483
                        asm (".insn r4 0x33, 1, 0x3, %0, %2, %1, %3\n\t"                \
484
                        : "=r"(r[1])                                                    \
485
                        : "r"(xp[1]^zp[1]), "r"(yp[1]), "r"(zp[1])); ret; })
486
#elif (defined(__riscv_zbt) || defined(__riscv_zpn)) && __riscv_xlen == 64
487
#define Ch(x, y, z) ({  SHA_LONG64 ret;                           \
488
                        asm (".insn r4 0x33, 1, 0x3, %0, %2, %1, %3"\
489
                        : "=r"(ret)                                 \
490
                        : "r"(x), "r"(y), "r"(z)); ret; })
491
#define Maj(x, y, z) ({ SHA_LONG64 ret;                           \
492
                        asm (".insn r4 0x33, 1, 0x3, %0, %2, %1, %3"\
493
                        : "=r"(ret)                                 \
494
                        : "r"(x^z), "r"(y), "r"(x)); ret; })
495
#elif defined(__e2k__) && __iset__ >= 5
496
#define sigma0(x) (__builtin_e2k_plog(0x96, ROTR((x), 1), ROTR((x), 8), ((x) >> 7)))
497
#define sigma1(x) (__builtin_e2k_plog(0x96, ROTR((x), 19), ROTR((x), 61), ((x) >> 6)))
498
#endif
499
#elif defined(_MSC_VER)
500
#if defined(_WIN64) /* applies to both IA-64 and AMD64 */
501
#pragma intrinsic(_rotr64)
502
#define ROTR(a, n) _rotr64((a), n)
503
#endif
504
#if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
505
#if defined(I386_ONLY)
506
static SHA_LONG64 __fastcall __pull64be(const void *x)
507
{
508
    _asm mov edx, [ecx + 0] _asm mov eax, [ecx + 4] _asm xchg dh, dl _asm xchg ah, al _asm rol edx, 16 _asm rol eax, 16 _asm xchg dh, dl _asm xchg ah, al
509
}
510
#else
511
static SHA_LONG64 __fastcall __pull64be(const void *x) {
512
    _asm mov edx, [ecx + 0] _asm mov eax, [ecx + 4] _asm bswap edx _asm bswap eax
513
}
514
#endif
515
#define PULL64(x) __pull64be(&(x))
516
#endif
517
#endif
518
#endif
519
#ifndef PULL64
520
#define B(x, j) (((SHA_LONG64)(*(((const unsigned char *)(&x)) + j))) << ((7 - j) * 8))
521
#define PULL64(x) (B(x, 0) | B(x, 1) | B(x, 2) | B(x, 3) | B(x, 4) | B(x, 5) | B(x, 6) | B(x, 7))
522
#endif
523
#ifndef ROTR
524
#define ROTR(x, s) (((x) >> s) | (x) << (64 - s))
525
#endif
526
#ifndef Sigma0
527
#define Sigma0(x) (ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
528
#endif
529
#ifndef Sigma1
530
#define Sigma1(x) (ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
531
#endif
532
#ifndef sigma0
533
#define sigma0(x) (ROTR((x), 1) ^ ROTR((x), 8) ^ ((x) >> 7))
534
#endif
535
#ifndef sigma1
536
#define sigma1(x) (ROTR((x), 19) ^ ROTR((x), 61) ^ ((x) >> 6))
537
#endif
538
#ifndef Ch
539
#define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
540
#endif
541
#ifndef Maj
542
#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
543
#endif
544
545
#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
546
/*
547
 * This code should give better results on 32-bit CPU with less than
548
 * ~24 registers, both size and performance wise...
549
 */
550
551
static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
552
    size_t num)
553
{
554
    const SHA_LONG64 *W = in;
555
    SHA_LONG64 A, E, T;
556
    SHA_LONG64 X[9 + 80], *F;
557
    int i;
558
559
    while (num--) {
560
561
        F = X + 80;
562
        A = ctx->h[0];
563
        F[1] = ctx->h[1];
564
        F[2] = ctx->h[2];
565
        F[3] = ctx->h[3];
566
        E = ctx->h[4];
567
        F[5] = ctx->h[5];
568
        F[6] = ctx->h[6];
569
        F[7] = ctx->h[7];
570
571
        for (i = 0; i < 16; i++, F--) {
572
#ifdef B_ENDIAN
573
            T = W[i];
574
#else
575
            T = PULL64(W[i]);
576
#endif
577
            F[0] = A;
578
            F[4] = E;
579
            F[8] = T;
580
            T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i];
581
            E = F[3] + T;
582
            A = T + Sigma0(A) + Maj(A, F[1], F[2]);
583
        }
584
585
        for (; i < 80; i++, F--) {
586
            T = sigma0(F[8 + 16 - 1]);
587
            T += sigma1(F[8 + 16 - 14]);
588
            T += F[8 + 16] + F[8 + 16 - 9];
589
590
            F[0] = A;
591
            F[4] = E;
592
            F[8] = T;
593
            T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i];
594
            E = F[3] + T;
595
            A = T + Sigma0(A) + Maj(A, F[1], F[2]);
596
        }
597
598
        ctx->h[0] += A;
599
        ctx->h[1] += F[1];
600
        ctx->h[2] += F[2];
601
        ctx->h[3] += F[3];
602
        ctx->h[4] += E;
603
        ctx->h[5] += F[5];
604
        ctx->h[6] += F[6];
605
        ctx->h[7] += F[7];
606
607
        W += SHA_LBLOCK;
608
    }
609
}
610
611
#elif defined(OPENSSL_SMALL_FOOTPRINT)
612
613
static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
614
    size_t num)
615
{
616
    const SHA_LONG64 *W = in;
617
    SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1, T2;
618
    SHA_LONG64 X[16];
619
    int i;
620
621
    while (num--) {
622
623
        a = ctx->h[0];
624
        b = ctx->h[1];
625
        c = ctx->h[2];
626
        d = ctx->h[3];
627
        e = ctx->h[4];
628
        f = ctx->h[5];
629
        g = ctx->h[6];
630
        h = ctx->h[7];
631
632
        for (i = 0; i < 16; i++) {
633
#ifdef B_ENDIAN
634
            T1 = X[i] = W[i];
635
#else
636
            T1 = X[i] = PULL64(W[i]);
637
#endif
638
            T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i];
639
            T2 = Sigma0(a) + Maj(a, b, c);
640
            h = g;
641
            g = f;
642
            f = e;
643
            e = d + T1;
644
            d = c;
645
            c = b;
646
            b = a;
647
            a = T1 + T2;
648
        }
649
650
        for (; i < 80; i++) {
651
            s0 = X[(i + 1) & 0x0f];
652
            s0 = sigma0(s0);
653
            s1 = X[(i + 14) & 0x0f];
654
            s1 = sigma1(s1);
655
656
            T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf];
657
            T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i];
658
            T2 = Sigma0(a) + Maj(a, b, c);
659
            h = g;
660
            g = f;
661
            f = e;
662
            e = d + T1;
663
            d = c;
664
            c = b;
665
            b = a;
666
            a = T1 + T2;
667
        }
668
669
        ctx->h[0] += a;
670
        ctx->h[1] += b;
671
        ctx->h[2] += c;
672
        ctx->h[3] += d;
673
        ctx->h[4] += e;
674
        ctx->h[5] += f;
675
        ctx->h[6] += g;
676
        ctx->h[7] += h;
677
678
        W += SHA_LBLOCK;
679
    }
680
}
681
682
#else
683
#define ROUND_00_15(i, a, b, c, d, e, f, g, h)       \
684
    do {                                             \
685
        T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i]; \
686
        h = Sigma0(a) + Maj(a, b, c);                \
687
        d += T1;                                     \
688
        h += T1;                                     \
689
    } while (0)
690
691
#define ROUND_16_80(i, j, a, b, c, d, e, f, g, h, X)       \
692
    do {                                                   \
693
        s0 = X[(j + 1) & 0x0f];                            \
694
        s0 = sigma0(s0);                                   \
695
        s1 = X[(j + 14) & 0x0f];                           \
696
        s1 = sigma1(s1);                                   \
697
        T1 = X[(j) & 0x0f] += s0 + s1 + X[(j + 9) & 0x0f]; \
698
        ROUND_00_15(i + j, a, b, c, d, e, f, g, h);        \
699
    } while (0)
700
701
#ifdef INCLUDE_C_SHA512
702
void sha512_block_data_order_c(SHA512_CTX *ctx, const void *in, size_t num)
703
#else
704
static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
705
    size_t num)
706
#endif
707
{
708
    const SHA_LONG64 *W = in;
709
    SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1;
710
    SHA_LONG64 X[16];
711
    int i;
712
713
    while (num--) {
714
715
        a = ctx->h[0];
716
        b = ctx->h[1];
717
        c = ctx->h[2];
718
        d = ctx->h[3];
719
        e = ctx->h[4];
720
        f = ctx->h[5];
721
        g = ctx->h[6];
722
        h = ctx->h[7];
723
724
#ifdef B_ENDIAN
725
        T1 = X[0] = W[0];
726
        ROUND_00_15(0, a, b, c, d, e, f, g, h);
727
        T1 = X[1] = W[1];
728
        ROUND_00_15(1, h, a, b, c, d, e, f, g);
729
        T1 = X[2] = W[2];
730
        ROUND_00_15(2, g, h, a, b, c, d, e, f);
731
        T1 = X[3] = W[3];
732
        ROUND_00_15(3, f, g, h, a, b, c, d, e);
733
        T1 = X[4] = W[4];
734
        ROUND_00_15(4, e, f, g, h, a, b, c, d);
735
        T1 = X[5] = W[5];
736
        ROUND_00_15(5, d, e, f, g, h, a, b, c);
737
        T1 = X[6] = W[6];
738
        ROUND_00_15(6, c, d, e, f, g, h, a, b);
739
        T1 = X[7] = W[7];
740
        ROUND_00_15(7, b, c, d, e, f, g, h, a);
741
        T1 = X[8] = W[8];
742
        ROUND_00_15(8, a, b, c, d, e, f, g, h);
743
        T1 = X[9] = W[9];
744
        ROUND_00_15(9, h, a, b, c, d, e, f, g);
745
        T1 = X[10] = W[10];
746
        ROUND_00_15(10, g, h, a, b, c, d, e, f);
747
        T1 = X[11] = W[11];
748
        ROUND_00_15(11, f, g, h, a, b, c, d, e);
749
        T1 = X[12] = W[12];
750
        ROUND_00_15(12, e, f, g, h, a, b, c, d);
751
        T1 = X[13] = W[13];
752
        ROUND_00_15(13, d, e, f, g, h, a, b, c);
753
        T1 = X[14] = W[14];
754
        ROUND_00_15(14, c, d, e, f, g, h, a, b);
755
        T1 = X[15] = W[15];
756
        ROUND_00_15(15, b, c, d, e, f, g, h, a);
757
#else
758
        T1 = X[0] = PULL64(W[0]);
759
        ROUND_00_15(0, a, b, c, d, e, f, g, h);
760
        T1 = X[1] = PULL64(W[1]);
761
        ROUND_00_15(1, h, a, b, c, d, e, f, g);
762
        T1 = X[2] = PULL64(W[2]);
763
        ROUND_00_15(2, g, h, a, b, c, d, e, f);
764
        T1 = X[3] = PULL64(W[3]);
765
        ROUND_00_15(3, f, g, h, a, b, c, d, e);
766
        T1 = X[4] = PULL64(W[4]);
767
        ROUND_00_15(4, e, f, g, h, a, b, c, d);
768
        T1 = X[5] = PULL64(W[5]);
769
        ROUND_00_15(5, d, e, f, g, h, a, b, c);
770
        T1 = X[6] = PULL64(W[6]);
771
        ROUND_00_15(6, c, d, e, f, g, h, a, b);
772
        T1 = X[7] = PULL64(W[7]);
773
        ROUND_00_15(7, b, c, d, e, f, g, h, a);
774
        T1 = X[8] = PULL64(W[8]);
775
        ROUND_00_15(8, a, b, c, d, e, f, g, h);
776
        T1 = X[9] = PULL64(W[9]);
777
        ROUND_00_15(9, h, a, b, c, d, e, f, g);
778
        T1 = X[10] = PULL64(W[10]);
779
        ROUND_00_15(10, g, h, a, b, c, d, e, f);
780
        T1 = X[11] = PULL64(W[11]);
781
        ROUND_00_15(11, f, g, h, a, b, c, d, e);
782
        T1 = X[12] = PULL64(W[12]);
783
        ROUND_00_15(12, e, f, g, h, a, b, c, d);
784
        T1 = X[13] = PULL64(W[13]);
785
        ROUND_00_15(13, d, e, f, g, h, a, b, c);
786
        T1 = X[14] = PULL64(W[14]);
787
        ROUND_00_15(14, c, d, e, f, g, h, a, b);
788
        T1 = X[15] = PULL64(W[15]);
789
        ROUND_00_15(15, b, c, d, e, f, g, h, a);
790
#endif
791
792
        for (i = 16; i < 80; i += 16) {
793
            ROUND_16_80(i, 0, a, b, c, d, e, f, g, h, X);
794
            ROUND_16_80(i, 1, h, a, b, c, d, e, f, g, X);
795
            ROUND_16_80(i, 2, g, h, a, b, c, d, e, f, X);
796
            ROUND_16_80(i, 3, f, g, h, a, b, c, d, e, X);
797
            ROUND_16_80(i, 4, e, f, g, h, a, b, c, d, X);
798
            ROUND_16_80(i, 5, d, e, f, g, h, a, b, c, X);
799
            ROUND_16_80(i, 6, c, d, e, f, g, h, a, b, X);
800
            ROUND_16_80(i, 7, b, c, d, e, f, g, h, a, X);
801
            ROUND_16_80(i, 8, a, b, c, d, e, f, g, h, X);
802
            ROUND_16_80(i, 9, h, a, b, c, d, e, f, g, X);
803
            ROUND_16_80(i, 10, g, h, a, b, c, d, e, f, X);
804
            ROUND_16_80(i, 11, f, g, h, a, b, c, d, e, X);
805
            ROUND_16_80(i, 12, e, f, g, h, a, b, c, d, X);
806
            ROUND_16_80(i, 13, d, e, f, g, h, a, b, c, X);
807
            ROUND_16_80(i, 14, c, d, e, f, g, h, a, b, X);
808
            ROUND_16_80(i, 15, b, c, d, e, f, g, h, a, X);
809
        }
810
811
        ctx->h[0] += a;
812
        ctx->h[1] += b;
813
        ctx->h[2] += c;
814
        ctx->h[3] += d;
815
        ctx->h[4] += e;
816
        ctx->h[5] += f;
817
        ctx->h[6] += g;
818
        ctx->h[7] += h;
819
820
        W += SHA_LBLOCK;
821
    }
822
}
823
824
#endif
825
826
#endif /* SHA512_ASM */