Coverage Report

Created: 2025-08-29 06:39

/src/dropbear/libtomcrypt/src/hashes/sha2/sha512.c
Line
Count
Source (jump to first uncovered line)
1
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2
 *
3
 * LibTomCrypt is a library that provides various cryptographic
4
 * algorithms in a highly modular and flexible manner.
5
 *
6
 * The library is free for all purposes without any express
7
 * guarantee it works.
8
 */
9
#include "tomcrypt.h"
10
11
/**
12
   @param sha512.c
13
   LTC_SHA512 by Tom St Denis
14
*/
15
16
#ifdef LTC_SHA512
17
18
const struct ltc_hash_descriptor sha512_desc =
19
{
20
    "sha512",
21
    5,
22
    64,
23
    128,
24
25
    /* OID */
26
   { 2, 16, 840, 1, 101, 3, 4, 2, 3,  },
27
   9,
28
29
    &sha512_init,
30
    &sha512_process,
31
    &sha512_done,
32
    &sha512_test,
33
    NULL
34
};
35
36
/* the K array */
37
static const ulong64 K[80] = {
38
CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
39
CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
40
CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
41
CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
42
CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
43
CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
44
CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
45
CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
46
CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
47
CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
48
CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
49
CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
50
CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
51
CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
52
CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
53
CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
54
CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
55
CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
56
CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
57
CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
58
CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
59
CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
60
CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
61
CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
62
CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
63
CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
64
CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
65
CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
66
CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
67
CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
68
CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
69
CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
70
CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
71
CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
72
CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
73
CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
74
CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
75
CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
76
CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
77
CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
78
};
79
80
/* Various logical functions */
81
13.4M
#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
82
13.4M
#define Maj(x,y,z)      (((x | y) & z) | (x & y))
83
123M
#define S(x, n)         ROR64c(x, n)
84
21.5M
#define R(x, n)         (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
85
13.4M
#define Sigma0(x)       (S(x, 28) ^ S(x, 34) ^ S(x, 39))
86
13.4M
#define Sigma1(x)       (S(x, 14) ^ S(x, 18) ^ S(x, 41))
87
10.7M
#define Gamma0(x)       (S(x, 1) ^ S(x, 8) ^ R(x, 7))
88
10.7M
#define Gamma1(x)       (S(x, 19) ^ S(x, 61) ^ R(x, 6))
89
90
/* compress 1024-bits */
91
#ifdef LTC_CLEAN_STACK
92
static int _sha512_compress(hash_state * md, unsigned char *buf)
93
#else
94
static int  sha512_compress(hash_state * md, unsigned char *buf)
95
#endif
96
168k
{
97
168k
    ulong64 S[8], W[80], t0, t1;
98
168k
    int i;
99
100
    /* copy state into S */
101
1.51M
    for (i = 0; i < 8; i++) {
102
1.34M
        S[i] = md->sha512.state[i];
103
1.34M
    }
104
105
    /* copy the state into 1024-bits into W[0..15] */
106
2.85M
    for (i = 0; i < 16; i++) {
107
2.69M
        LOAD64H(W[i], buf + (8*i));
108
2.69M
    }
109
110
    /* fill W[16..79] */
111
10.9M
    for (i = 16; i < 80; i++) {
112
10.7M
        W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
113
10.7M
    }
114
115
    /* Compress */
116
168k
#ifdef LTC_SMALL_CODE
117
13.6M
    for (i = 0; i < 80; i++) {
118
13.4M
        t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
119
13.4M
        t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
120
13.4M
        S[7] = S[6];
121
13.4M
        S[6] = S[5];
122
13.4M
        S[5] = S[4];
123
13.4M
        S[4] = S[3] + t0;
124
13.4M
        S[3] = S[2];
125
13.4M
        S[2] = S[1];
126
13.4M
        S[1] = S[0];
127
13.4M
        S[0] = t0 + t1;
128
13.4M
    }
129
#else
130
#define RND(a,b,c,d,e,f,g,h,i)                    \
131
     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];   \
132
     t1 = Sigma0(a) + Maj(a, b, c);                  \
133
     d += t0;                                        \
134
     h  = t0 + t1;
135
136
    for (i = 0; i < 80; i += 8) {
137
        RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
138
        RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
139
        RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
140
        RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
141
        RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
142
        RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
143
        RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
144
        RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
145
    }
146
#endif
147
148
149
    /* feedback */
150
1.51M
    for (i = 0; i < 8; i++) {
151
1.34M
        md->sha512.state[i] = md->sha512.state[i] + S[i];
152
1.34M
    }
153
154
168k
    return CRYPT_OK;
155
168k
}
156
157
/* compress 1024-bits */
158
#ifdef LTC_CLEAN_STACK
159
static int sha512_compress(hash_state * md, unsigned char *buf)
160
{
161
    int err;
162
    err = _sha512_compress(md, buf);
163
    burn_stack(sizeof(ulong64) * 90 + sizeof(int));
164
    return err;
165
}
166
#endif
167
168
/**
169
   Initialize the hash state
170
   @param md   The hash state you wish to initialize
171
   @return CRYPT_OK if successful
172
*/
173
int sha512_init(hash_state * md)
174
15.8k
{
175
15.8k
    LTC_ARGCHK(md != NULL);
176
15.8k
    md->sha512.curlen = 0;
177
15.8k
    md->sha512.length = 0;
178
15.8k
    md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
179
15.8k
    md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
180
15.8k
    md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
181
15.8k
    md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
182
15.8k
    md->sha512.state[4] = CONST64(0x510e527fade682d1);
183
15.8k
    md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
184
15.8k
    md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
185
15.8k
    md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
186
15.8k
    return CRYPT_OK;
187
15.8k
}
188
189
/**
190
   Process a block of memory though the hash
191
   @param md     The hash state
192
   @param in     The data to hash
193
   @param inlen  The length of the data (octets)
194
   @return CRYPT_OK if successful
195
*/
196
HASH_PROCESS(sha512_process, sha512_compress, sha512, 128)
197
198
/**
199
   Terminate the hash to get the digest
200
   @param md  The hash state
201
   @param out [out] The destination of the hash (64 bytes)
202
   @return CRYPT_OK if successful
203
*/
204
int sha512_done(hash_state * md, unsigned char *out)
205
58.3k
{
206
58.3k
    int i;
207
208
58.3k
    LTC_ARGCHK(md  != NULL);
209
58.3k
    LTC_ARGCHK(out != NULL);
210
211
58.3k
    if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
212
0
       return CRYPT_INVALID_ARG;
213
0
    }
214
215
    /* increase the length of the message */
216
58.3k
    md->sha512.length += md->sha512.curlen * CONST64(8);
217
218
    /* append the '1' bit */
219
58.3k
    md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
220
221
    /* if the length is currently above 112 bytes we append zeros
222
     * then compress.  Then we can fall back to padding zeros and length
223
     * encoding like normal.
224
     */
225
58.3k
    if (md->sha512.curlen > 112) {
226
34.4k
        while (md->sha512.curlen < 128) {
227
29.3k
            md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
228
29.3k
        }
229
5.03k
        sha512_compress(md, md->sha512.buf);
230
5.03k
        md->sha512.curlen = 0;
231
5.03k
    }
232
233
    /* pad upto 120 bytes of zeroes
234
     * note: that from 112 to 120 is the 64 MSB of the length.  We assume that you won't hash
235
     * > 2^64 bits of data... :-)
236
     */
237
3.30M
    while (md->sha512.curlen < 120) {
238
3.24M
        md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
239
3.24M
    }
240
241
    /* store length */
242
58.3k
    STORE64H(md->sha512.length, md->sha512.buf+120);
243
58.3k
    sha512_compress(md, md->sha512.buf);
244
245
    /* copy output */
246
524k
    for (i = 0; i < 8; i++) {
247
466k
        STORE64H(md->sha512.state[i], out+(8*i));
248
466k
    }
249
#ifdef LTC_CLEAN_STACK
250
    zeromem(md, sizeof(hash_state));
251
#endif
252
58.3k
    return CRYPT_OK;
253
58.3k
}
254
255
/**
256
  Self-test the hash
257
  @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
258
*/
259
int  sha512_test(void)
260
0
{
261
0
 #ifndef LTC_TEST
262
0
    return CRYPT_NOP;
263
 #else
264
  static const struct {
265
      const char *msg;
266
      unsigned char hash[64];
267
  } tests[] = {
268
    { "abc",
269
     { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
270
       0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
271
       0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
272
       0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
273
       0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
274
       0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
275
       0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
276
       0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
277
    },
278
    { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
279
     { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
280
       0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
281
       0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
282
       0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
283
       0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
284
       0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
285
       0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
286
       0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
287
    },
288
  };
289
290
  int i;
291
  unsigned char tmp[64];
292
  hash_state md;
293
294
  for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
295
      sha512_init(&md);
296
      sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
297
      sha512_done(&md, tmp);
298
      if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA512", i)) {
299
         return CRYPT_FAIL_TESTVECTOR;
300
      }
301
  }
302
  return CRYPT_OK;
303
  #endif
304
0
}
305
306
#endif
307
308
309
310
311
/* ref:         $Format:%D$ */
312
/* git commit:  $Format:%H$ */
313
/* commit time: $Format:%ai$ */