Coverage Report

Created: 2026-06-07 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cryptofuzz/crypto.cpp
Line
Count
Source
1
#include <cryptofuzz/crypto.h>
2
#include <stdint.h>
3
#include <stdlib.h>
4
#include <string.h>
5
#include <climits>
6
7
namespace cryptofuzz {
8
namespace crypto {
9
namespace impl {
10
11
#if defined(__clang__)
12
335k
#define rotate_right_32 __builtin_rotateright32
13
0
#define rotate_left_32 __builtin_rotateleft32
14
#else
15
static uint32_t rotate_right_32(uint32_t value, unsigned int count) {
16
    const unsigned int mask = (CHAR_BIT * sizeof(value)) - 1;
17
    count &= mask;
18
    return (value >> count) | (value << ((-count) & mask));
19
}
20
static uint32_t rotate_left_32(uint32_t value, unsigned int count) {
21
    const unsigned int mask = (CHAR_BIT * sizeof(value)) - 1;
22
    count &= mask;
23
    return (value << count) | (value >> ((-count) & mask));
24
}
25
#endif
26
27
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
28
/* SPDX-License-Identifier: Unlicense */
29
30
335k
#define ROR(x,n) rotate_right_32(x,n)
31
0
#define ROL(x,n) rotate_left_32(x,n)
32
0
#define ROLc(x,n) ROL(x,n)
33
335k
#define RORc(x,n) ROR(x,n)
34
35
12.6k
#define XMEMCPY memcpy
36
37
#define LTC_ARGCHK(...)
38
39
261
#define MIN(x, y) ( ((x)<(y))?(x):(y) )
40
41
2.75k
#define STORE32H(x, y)                          \
42
2.75k
do { ulong32 ttt = __builtin_bswap32 ((x));     \
43
2.75k
      XMEMCPY ((y), &ttt, 4); } while(0)
44
45
9.31k
#define LOAD32H(x, y)                           \
46
9.31k
do { XMEMCPY (&(x), (y), 4);                    \
47
9.31k
      (x) = __builtin_bswap32 ((x)); } while(0)
48
49
344
#define STORE64H(x, y)                          \
50
344
do { ulong64 ttt = __builtin_bswap64 ((x));     \
51
344
      XMEMCPY ((y), &ttt, 8); } while(0)
52
53
#define LOAD64H(x, y)                           \
54
do { XMEMCPY (&(x), (y), 8);                    \
55
      (x) = __builtin_bswap64 ((x)); } while(0)
56
57
typedef uint64_t ulong64;
58
typedef uint32_t ulong32;
59
60
/* error codes [will be expanded in future releases] */
61
enum {
62
   CRYPT_OK=0,             /* Result OK */
63
   CRYPT_ERROR,            /* Generic Error */
64
   CRYPT_NOP,              /* Not a failure but no operation was performed */
65
66
   CRYPT_INVALID_KEYSIZE,  /* Invalid key size given */
67
   CRYPT_INVALID_ROUNDS,   /* Invalid number of rounds */
68
   CRYPT_FAIL_TESTVECTOR,  /* Algorithm failed test vectors */
69
70
   CRYPT_BUFFER_OVERFLOW,  /* Not enough space for output */
71
   CRYPT_INVALID_PACKET,   /* Invalid input packet given */
72
73
   CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */
74
   CRYPT_ERROR_READPRNG,   /* Could not read enough from PRNG */
75
76
   CRYPT_INVALID_CIPHER,   /* Invalid cipher specified */
77
   CRYPT_INVALID_HASH,     /* Invalid hash specified */
78
   CRYPT_INVALID_PRNG,     /* Invalid PRNG specified */
79
80
   CRYPT_MEM,              /* Out of memory */
81
82
   CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */
83
   CRYPT_PK_NOT_PRIVATE,   /* Requires a private PK key */
84
85
   CRYPT_INVALID_ARG,      /* Generic invalid argument */
86
   CRYPT_FILE_NOTFOUND,    /* File Not Found */
87
88
   CRYPT_PK_INVALID_TYPE,  /* Invalid type of PK key */
89
90
   CRYPT_OVERFLOW,         /* An overflow of a value was detected/prevented */
91
92
   CRYPT_PK_ASN1_ERROR,    /* An error occurred while en- or decoding ASN.1 data */
93
94
   CRYPT_INPUT_TOO_LONG,   /* The input was longer than expected. */
95
96
   CRYPT_PK_INVALID_SIZE,  /* Invalid size input for PK parameters */
97
98
   CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */
99
   CRYPT_PK_INVALID_PADDING, /* Invalid padding on input */
100
101
   CRYPT_HASH_OVERFLOW      /* Hash applied to too many bits */
102
};
103
104
#define HASH_PROCESS(func_name, compress_name, state_var, block_size)                       \
105
344
int func_name (hash_state * md, const unsigned char *in, unsigned long inlen)               \
106
344
{                                                                                           \
107
344
    unsigned long n;                                                                        \
108
344
    int           err;                                                                      \
109
344
    LTC_ARGCHK(md != NULL);                                                                 \
110
344
    LTC_ARGCHK(in != NULL);                                                                 \
111
344
    if (md-> state_var .curlen > sizeof(md-> state_var .buf)) {                             \
112
0
       return CRYPT_INVALID_ARG;                                                            \
113
0
    }                                                                                       \
114
344
    if ((md-> state_var .length + inlen * 8) < md-> state_var .length) {                        \
115
0
      return CRYPT_HASH_OVERFLOW;                                                           \
116
0
    }                                                                                       \
117
800
    while (inlen > 0) {                                                                     \
118
456
        if (md-> state_var .curlen == 0 && inlen >= block_size) {                           \
119
195
           if ((err = compress_name (md, in)) != CRYPT_OK) {                                \
120
0
              return err;                                                                   \
121
0
           }                                                                                \
122
195
           md-> state_var .length += block_size * 8;                                        \
123
195
           in             += block_size;                                                    \
124
195
           inlen          -= block_size;                                                    \
125
261
        } else {                                                                            \
126
261
           n = MIN(inlen, (block_size - md-> state_var .curlen));                           \
127
261
           XMEMCPY(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n);             \
128
261
           md-> state_var .curlen += n;                                                     \
129
261
           in             += n;                                                             \
130
261
           inlen          -= n;                                                             \
131
261
           if (md-> state_var .curlen == block_size) {                                      \
132
0
              if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) {            \
133
0
                 return err;                                                                \
134
0
              }                                                                             \
135
0
              md-> state_var .length += 8*block_size;                                       \
136
0
              md-> state_var .curlen = 0;                                                   \
137
0
           }                                                                                \
138
261
       }                                                                                    \
139
456
    }                                                                                       \
140
344
    return CRYPT_OK;                                                                        \
141
344
}
Unexecuted instantiation: cryptofuzz::crypto::impl::sha1_process(cryptofuzz::crypto::impl::Hash_state*, unsigned char const*, unsigned long)
cryptofuzz::crypto::impl::sha256_process(cryptofuzz::crypto::impl::Hash_state*, unsigned char const*, unsigned long)
Line
Count
Source
105
344
int func_name (hash_state * md, const unsigned char *in, unsigned long inlen)               \
106
344
{                                                                                           \
107
344
    unsigned long n;                                                                        \
108
344
    int           err;                                                                      \
109
344
    LTC_ARGCHK(md != NULL);                                                                 \
110
344
    LTC_ARGCHK(in != NULL);                                                                 \
111
344
    if (md-> state_var .curlen > sizeof(md-> state_var .buf)) {                             \
112
0
       return CRYPT_INVALID_ARG;                                                            \
113
0
    }                                                                                       \
114
344
    if ((md-> state_var .length + inlen * 8) < md-> state_var .length) {                        \
115
0
      return CRYPT_HASH_OVERFLOW;                                                           \
116
0
    }                                                                                       \
117
800
    while (inlen > 0) {                                                                     \
118
456
        if (md-> state_var .curlen == 0 && inlen >= block_size) {                           \
119
195
           if ((err = compress_name (md, in)) != CRYPT_OK) {                                \
120
0
              return err;                                                                   \
121
0
           }                                                                                \
122
195
           md-> state_var .length += block_size * 8;                                        \
123
195
           in             += block_size;                                                    \
124
195
           inlen          -= block_size;                                                    \
125
261
        } else {                                                                            \
126
261
           n = MIN(inlen, (block_size - md-> state_var .curlen));                           \
127
261
           XMEMCPY(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n);             \
128
261
           md-> state_var .curlen += n;                                                     \
129
261
           in             += n;                                                             \
130
261
           inlen          -= n;                                                             \
131
261
           if (md-> state_var .curlen == block_size) {                                      \
132
0
              if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) {            \
133
0
                 return err;                                                                \
134
0
              }                                                                             \
135
0
              md-> state_var .length += 8*block_size;                                       \
136
0
              md-> state_var .curlen = 0;                                                   \
137
0
           }                                                                                \
138
261
       }                                                                                    \
139
456
    }                                                                                       \
140
344
    return CRYPT_OK;                                                                        \
141
344
}
142
143
struct sha1_state {
144
    ulong64 length;
145
    ulong32 state[5], curlen;
146
    unsigned char buf[64];
147
};
148
149
struct sha256_state {
150
    ulong64 length;
151
    ulong32 state[8], curlen;
152
    unsigned char buf[64];
153
};
154
155
typedef union Hash_state {
156
    char dummy[1];
157
    struct sha1_state   sha1;
158
    struct sha256_state sha256;
159
    void *data;
160
} hash_state;
161
162
/**
163
  @file sha1.c
164
  LTC_SHA1 code by Tom St Denis
165
*/
166
167
168
0
#define F0(x,y,z)  (z ^ (x & (y ^ z)))
169
0
#define F1(x,y,z)  (x ^ y ^ z)
170
0
#define F2(x,y,z)  ((x & y) | (z & (x | y)))
171
0
#define F3(x,y,z)  (x ^ y ^ z)
172
173
#ifdef LTC_CLEAN_STACK
174
static int ss_sha1_compress(hash_state *md, const unsigned char *buf)
175
#else
176
static int  s_sha1_compress(hash_state *md, const unsigned char *buf)
177
#endif
178
0
{
179
0
    ulong32 a,b,c,d,e,W[80],i;
180
#ifdef LTC_SMALL_CODE
181
    ulong32 t;
182
#endif
183
184
    /* copy the state into 512-bits into W[0..15] */
185
0
    for (i = 0; i < 16; i++) {
186
0
        LOAD32H(W[i], buf + (4*i));
187
0
    }
188
189
    /* copy state */
190
0
    a = md->sha1.state[0];
191
0
    b = md->sha1.state[1];
192
0
    c = md->sha1.state[2];
193
0
    d = md->sha1.state[3];
194
0
    e = md->sha1.state[4];
195
196
    /* expand it */
197
0
    for (i = 16; i < 80; i++) {
198
0
        W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
199
0
    }
200
201
    /* compress */
202
    /* round one */
203
0
    #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
204
0
    #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
205
0
    #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
206
0
    #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
207
208
#ifdef LTC_SMALL_CODE
209
210
    for (i = 0; i < 20; ) {
211
       FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
212
    }
213
214
    for (; i < 40; ) {
215
       FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
216
    }
217
218
    for (; i < 60; ) {
219
       FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
220
    }
221
222
    for (; i < 80; ) {
223
       FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
224
    }
225
226
#else
227
228
0
    for (i = 0; i < 20; ) {
229
0
       FF0(a,b,c,d,e,i++);
230
0
       FF0(e,a,b,c,d,i++);
231
0
       FF0(d,e,a,b,c,i++);
232
0
       FF0(c,d,e,a,b,i++);
233
0
       FF0(b,c,d,e,a,i++);
234
0
    }
235
236
    /* round two */
237
0
    for (; i < 40; )  {
238
0
       FF1(a,b,c,d,e,i++);
239
0
       FF1(e,a,b,c,d,i++);
240
0
       FF1(d,e,a,b,c,i++);
241
0
       FF1(c,d,e,a,b,i++);
242
0
       FF1(b,c,d,e,a,i++);
243
0
    }
244
245
    /* round three */
246
0
    for (; i < 60; )  {
247
0
       FF2(a,b,c,d,e,i++);
248
0
       FF2(e,a,b,c,d,i++);
249
0
       FF2(d,e,a,b,c,i++);
250
0
       FF2(c,d,e,a,b,i++);
251
0
       FF2(b,c,d,e,a,i++);
252
0
    }
253
254
    /* round four */
255
0
    for (; i < 80; )  {
256
0
       FF3(a,b,c,d,e,i++);
257
0
       FF3(e,a,b,c,d,i++);
258
0
       FF3(d,e,a,b,c,i++);
259
0
       FF3(c,d,e,a,b,i++);
260
0
       FF3(b,c,d,e,a,i++);
261
0
    }
262
0
#endif
263
264
0
    #undef FF0
265
0
    #undef FF1
266
0
    #undef FF2
267
0
    #undef FF3
268
269
    /* store */
270
0
    md->sha1.state[0] = md->sha1.state[0] + a;
271
0
    md->sha1.state[1] = md->sha1.state[1] + b;
272
0
    md->sha1.state[2] = md->sha1.state[2] + c;
273
0
    md->sha1.state[3] = md->sha1.state[3] + d;
274
0
    md->sha1.state[4] = md->sha1.state[4] + e;
275
276
0
    return CRYPT_OK;
277
0
}
278
279
#ifdef LTC_CLEAN_STACK
280
static int s_sha1_compress(hash_state *md, const unsigned char *buf)
281
{
282
   int err;
283
   err = ss_sha1_compress(md, buf);
284
   burn_stack(sizeof(ulong32) * 87);
285
   return err;
286
}
287
#endif
288
289
/**
290
   Initialize the hash state
291
   @param md   The hash state you wish to initialize
292
   @return CRYPT_OK if successful
293
*/
294
int sha1_init(hash_state * md)
295
0
{
296
0
   LTC_ARGCHK(md != NULL);
297
0
   md->sha1.state[0] = 0x67452301UL;
298
0
   md->sha1.state[1] = 0xefcdab89UL;
299
0
   md->sha1.state[2] = 0x98badcfeUL;
300
0
   md->sha1.state[3] = 0x10325476UL;
301
0
   md->sha1.state[4] = 0xc3d2e1f0UL;
302
0
   md->sha1.curlen = 0;
303
0
   md->sha1.length = 0;
304
0
   return CRYPT_OK;
305
0
}
306
307
/**
308
   Process a block of memory though the hash
309
   @param md     The hash state
310
   @param in     The data to hash
311
   @param inlen  The length of the data (octets)
312
   @return CRYPT_OK if successful
313
*/
314
HASH_PROCESS(sha1_process, s_sha1_compress, sha1, 64)
315
316
/**
317
   Terminate the hash to get the digest
318
   @param md  The hash state
319
   @param out [out] The destination of the hash (20 bytes)
320
   @return CRYPT_OK if successful
321
*/
322
int sha1_done(hash_state * md, unsigned char *out)
323
0
{
324
0
    int i;
325
326
0
    LTC_ARGCHK(md  != NULL);
327
0
    LTC_ARGCHK(out != NULL);
328
329
0
    if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
330
0
       return CRYPT_INVALID_ARG;
331
0
    }
332
333
    /* increase the length of the message */
334
0
    md->sha1.length += md->sha1.curlen * 8;
335
336
    /* append the '1' bit */
337
0
    md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
338
339
    /* if the length is currently above 56 bytes we append zeros
340
     * then compress.  Then we can fall back to padding zeros and length
341
     * encoding like normal.
342
     */
343
0
    if (md->sha1.curlen > 56) {
344
0
        while (md->sha1.curlen < 64) {
345
0
            md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
346
0
        }
347
0
        s_sha1_compress(md, md->sha1.buf);
348
0
        md->sha1.curlen = 0;
349
0
    }
350
351
    /* pad upto 56 bytes of zeroes */
352
0
    while (md->sha1.curlen < 56) {
353
0
        md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
354
0
    }
355
356
    /* store length */
357
0
    STORE64H(md->sha1.length, md->sha1.buf+56);
358
0
    s_sha1_compress(md, md->sha1.buf);
359
360
    /* copy output */
361
0
    for (i = 0; i < 5; i++) {
362
0
        STORE32H(md->sha1.state[i], out+(4*i));
363
0
    }
364
#ifdef LTC_CLEAN_STACK
365
    zeromem(md, sizeof(hash_state));
366
#endif
367
0
    return CRYPT_OK;
368
0
}
369
370
#ifdef LTC_SMALL_CODE
371
/* the K array */
372
static const ulong32 K[64] = {
373
    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
374
    0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
375
    0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
376
    0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
377
    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
378
    0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
379
    0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
380
    0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
381
    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
382
    0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
383
    0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
384
    0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
385
    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
386
};
387
#endif
388
389
/* Various logical functions */
390
37.2k
#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
391
37.2k
#define Maj(x,y,z)      (((x | y) & z) | (x & y))
392
335k
#define S(x, n)         RORc((x),(n))
393
55.8k
#define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
394
37.2k
#define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
395
37.2k
#define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
396
27.9k
#define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
397
27.9k
#define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
398
399
/* compress 512-bits */
400
#ifdef LTC_CLEAN_STACK
401
static int ss_sha256_compress(hash_state * md, const unsigned char *buf)
402
#else
403
static int s_sha256_compress(hash_state * md, const unsigned char *buf)
404
#endif
405
582
{
406
582
    ulong32 S[8], W[64], t0, t1;
407
#ifdef LTC_SMALL_CODE
408
    ulong32 t;
409
#endif
410
582
    int i;
411
412
    /* copy state into S */
413
5.23k
    for (i = 0; i < 8; i++) {
414
4.65k
        S[i] = md->sha256.state[i];
415
4.65k
    }
416
417
    /* copy the state into 512-bits into W[0..15] */
418
9.89k
    for (i = 0; i < 16; i++) {
419
9.31k
        LOAD32H(W[i], buf + (4*i));
420
9.31k
    }
421
422
    /* fill W[16..63] */
423
28.5k
    for (i = 16; i < 64; i++) {
424
27.9k
        W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
425
27.9k
    }
426
427
    /* Compress */
428
#ifdef LTC_SMALL_CODE
429
#define RND(a,b,c,d,e,f,g,h,i)                         \
430
     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];   \
431
     t1 = Sigma0(a) + Maj(a, b, c);                    \
432
     d += t0;                                          \
433
     h  = t0 + t1;
434
435
     for (i = 0; i < 64; ++i) {
436
         RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
437
         t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
438
         S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
439
     }
440
#else
441
582
#define RND(a,b,c,d,e,f,g,h,i,ki)                    \
442
37.2k
     t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i];   \
443
37.2k
     t1 = Sigma0(a) + Maj(a, b, c);                  \
444
37.2k
     d += t0;                                        \
445
37.2k
     h  = t0 + t1;
446
447
582
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
448
582
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
449
582
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
450
582
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
451
582
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
452
582
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
453
582
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
454
582
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
455
582
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
456
582
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
457
582
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
458
582
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
459
582
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
460
582
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
461
582
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
462
582
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
463
582
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
464
582
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
465
582
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
466
582
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
467
582
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
468
582
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
469
582
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
470
582
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
471
582
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
472
582
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
473
582
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
474
582
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
475
582
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
476
582
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
477
582
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
478
582
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
479
582
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
480
582
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
481
582
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
482
582
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
483
582
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
484
582
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
485
582
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
486
582
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
487
582
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
488
582
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
489
582
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
490
582
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
491
582
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
492
582
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
493
582
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
494
582
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
495
582
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
496
582
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
497
582
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
498
582
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
499
582
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
500
582
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
501
582
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
502
582
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
503
582
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
504
582
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
505
582
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
506
582
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
507
582
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
508
582
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
509
582
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
510
582
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
511
582
#endif
512
582
#undef RND
513
514
    /* feedback */
515
5.23k
    for (i = 0; i < 8; i++) {
516
4.65k
        md->sha256.state[i] = md->sha256.state[i] + S[i];
517
4.65k
    }
518
582
    return CRYPT_OK;
519
582
}
520
521
#ifdef LTC_CLEAN_STACK
522
static int s_sha256_compress(hash_state * md, const unsigned char *buf)
523
{
524
    int err;
525
    err = ss_sha256_compress(md, buf);
526
    burn_stack(sizeof(ulong32) * 74);
527
    return err;
528
}
529
#endif
530
531
/**
532
   Initialize the hash state
533
   @param md   The hash state you wish to initialize
534
   @return CRYPT_OK if successful
535
*/
536
int sha256_init(hash_state * md)
537
344
{
538
344
    LTC_ARGCHK(md != NULL);
539
540
344
    md->sha256.curlen = 0;
541
344
    md->sha256.length = 0;
542
344
    md->sha256.state[0] = 0x6A09E667UL;
543
344
    md->sha256.state[1] = 0xBB67AE85UL;
544
344
    md->sha256.state[2] = 0x3C6EF372UL;
545
344
    md->sha256.state[3] = 0xA54FF53AUL;
546
344
    md->sha256.state[4] = 0x510E527FUL;
547
344
    md->sha256.state[5] = 0x9B05688CUL;
548
344
    md->sha256.state[6] = 0x1F83D9ABUL;
549
344
    md->sha256.state[7] = 0x5BE0CD19UL;
550
344
    return CRYPT_OK;
551
344
}
552
553
/**
554
   Process a block of memory though the hash
555
   @param md     The hash state
556
   @param in     The data to hash
557
   @param inlen  The length of the data (octets)
558
   @return CRYPT_OK if successful
559
*/
560
HASH_PROCESS(sha256_process,s_sha256_compress, sha256, 64)
561
562
/**
563
   Terminate the hash to get the digest
564
   @param md  The hash state
565
   @param out [out] The destination of the hash (32 bytes)
566
   @return CRYPT_OK if successful
567
*/
568
int sha256_done(hash_state * md, unsigned char *out)
569
344
{
570
344
    int i;
571
572
344
    LTC_ARGCHK(md  != NULL);
573
344
    LTC_ARGCHK(out != NULL);
574
575
344
    if (md->sha256.curlen >= sizeof(md->sha256.buf)) {
576
0
       return CRYPT_INVALID_ARG;
577
0
    }
578
579
580
    /* increase the length of the message */
581
344
    md->sha256.length += md->sha256.curlen * 8;
582
583
    /* append the '1' bit */
584
344
    md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80;
585
586
    /* if the length is currently above 56 bytes we append zeros
587
     * then compress.  Then we can fall back to padding zeros and length
588
     * encoding like normal.
589
     */
590
344
    if (md->sha256.curlen > 56) {
591
221
        while (md->sha256.curlen < 64) {
592
178
            md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
593
178
        }
594
43
        s_sha256_compress(md, md->sha256.buf);
595
43
        md->sha256.curlen = 0;
596
43
    }
597
598
    /* pad upto 56 bytes of zeroes */
599
15.5k
    while (md->sha256.curlen < 56) {
600
15.1k
        md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
601
15.1k
    }
602
603
    /* store length */
604
344
    STORE64H(md->sha256.length, md->sha256.buf+56);
605
344
    s_sha256_compress(md, md->sha256.buf);
606
607
    /* copy output */
608
3.09k
    for (i = 0; i < 8; i++) {
609
2.75k
        STORE32H(md->sha256.state[i], out+(4*i));
610
2.75k
    }
611
#ifdef LTC_CLEAN_STACK
612
    zeromem(md, sizeof(hash_state));
613
#endif
614
344
    return CRYPT_OK;
615
344
}
616
617
} /* namespace impl */
618
619
0
std::vector<uint8_t> sha1(const uint8_t* data, const size_t size) {
620
0
    uint8_t out[20];
621
622
0
    impl::hash_state md;
623
0
    impl::sha1_init(&md);
624
0
    impl::sha1_process(&md, data, size);
625
0
    impl::sha1_done(&md, out);
626
627
0
    return std::vector<uint8_t>(out, out + sizeof(out));
628
0
}
629
630
0
std::vector<uint8_t> sha1(const std::vector<uint8_t> data) {
631
0
    return sha1(data.data(), data.size());
632
0
}
633
634
344
std::vector<uint8_t> sha256(const uint8_t* data, const size_t size) {
635
344
    uint8_t out[32];
636
637
344
    impl::hash_state md;
638
344
    impl::sha256_init(&md);
639
344
    impl::sha256_process(&md, data, size);
640
344
    impl::sha256_done(&md, out);
641
642
344
    return std::vector<uint8_t>(out, out + sizeof(out));
643
344
}
644
645
344
std::vector<uint8_t> sha256(const std::vector<uint8_t> data) {
646
344
    return sha256(data.data(), data.size());
647
344
}
648
649
0
std::vector<uint8_t> hmac_sha256(const uint8_t* data, const size_t size, const uint8_t* key, const size_t key_size) {
650
0
    uint8_t _key[64];
651
0
    uint8_t out[32];
652
0
    impl::hash_state inner, outer;
653
654
0
    impl::sha256_init(&inner);
655
0
    impl::sha256_init(&outer);
656
657
0
    if ( key_size <= 64 ) {
658
0
        if ( key_size ) {
659
0
            memcpy(_key, key, key_size);
660
0
        }
661
0
        memset(_key + key_size, 0, 64 - key_size);
662
0
    } else {
663
0
        const auto key_hash = sha256(key, key_size);
664
0
        memcpy(_key, key_hash.data(), key_hash.size());
665
0
        memset(_key + 32, 0, 32);
666
0
    }
667
668
0
    for (size_t i = 0; i < 64; i++) {
669
0
        _key[i] ^= 0x5C;
670
0
    }
671
0
    impl::sha256_process(&outer, _key, 64);
672
673
0
    for (int i = 0; i < 64; i++) {
674
0
        _key[i] ^= 0x5C ^ 0x36;
675
0
    }
676
0
    impl::sha256_process(&inner, _key, 64);
677
678
0
    impl::sha256_process(&inner, data, size);
679
680
0
    impl::sha256_done(&inner, out);
681
0
    impl::sha256_process(&outer, out, 32);
682
0
    impl::sha256_done(&outer, out);
683
684
0
    return {out, out + 32};
685
0
}
686
687
0
std::vector<uint8_t> hmac_sha256(const std::vector<uint8_t> data, const std::vector<uint8_t> key) {
688
0
    return hmac_sha256(data.data(), data.size(), key.data(), key.size());
689
0
}
690
691
692
} /* namespace crypto */
693
} /* namespace cryptofuzz */