Coverage Report

Created: 2025-11-16 06:36

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
305k
#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
305k
#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
305k
#define RORc(x,n) ROR(x,n)
34
35
11.3k
#define XMEMCPY memcpy
36
37
#define LTC_ARGCHK(...)
38
39
199
#define MIN(x, y) ( ((x)<(y))?(x):(y) )
40
41
2.34k
#define STORE32H(x, y)                          \
42
2.34k
do { ulong32 ttt = __builtin_bswap32 ((x));     \
43
2.34k
      XMEMCPY ((y), &ttt, 4); } while(0)
44
45
8.48k
#define LOAD32H(x, y)                           \
46
8.48k
do { XMEMCPY (&(x), (y), 4);                    \
47
8.48k
      (x) = __builtin_bswap32 ((x)); } while(0)
48
49
293
#define STORE64H(x, y)                          \
50
293
do { ulong64 ttt = __builtin_bswap64 ((x));     \
51
293
      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
293
int func_name (hash_state * md, const unsigned char *in, unsigned long inlen)               \
106
293
{                                                                                           \
107
293
    unsigned long n;                                                                        \
108
293
    int           err;                                                                      \
109
293
    LTC_ARGCHK(md != NULL);                                                                 \
110
293
    LTC_ARGCHK(in != NULL);                                                                 \
111
293
    if (md-> state_var .curlen > sizeof(md-> state_var .buf)) {                             \
112
0
       return CRYPT_INVALID_ARG;                                                            \
113
0
    }                                                                                       \
114
293
    if ((md-> state_var .length + inlen * 8) < md-> state_var .length) {                        \
115
0
      return CRYPT_HASH_OVERFLOW;                                                           \
116
0
    }                                                                                       \
117
705
    while (inlen > 0) {                                                                     \
118
412
        if (md-> state_var .curlen == 0 && inlen >= block_size) {                           \
119
213
           if ((err = compress_name (md, in)) != CRYPT_OK) {                                \
120
0
              return err;                                                                   \
121
0
           }                                                                                \
122
213
           md-> state_var .length += block_size * 8;                                        \
123
213
           in             += block_size;                                                    \
124
213
           inlen          -= block_size;                                                    \
125
213
        } else {                                                                            \
126
199
           n = MIN(inlen, (block_size - md-> state_var .curlen));                           \
127
199
           XMEMCPY(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n);             \
128
199
           md-> state_var .curlen += n;                                                     \
129
199
           in             += n;                                                             \
130
199
           inlen          -= n;                                                             \
131
199
           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
199
       }                                                                                    \
139
412
    }                                                                                       \
140
293
    return CRYPT_OK;                                                                        \
141
293
}
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
293
int func_name (hash_state * md, const unsigned char *in, unsigned long inlen)               \
106
293
{                                                                                           \
107
293
    unsigned long n;                                                                        \
108
293
    int           err;                                                                      \
109
293
    LTC_ARGCHK(md != NULL);                                                                 \
110
293
    LTC_ARGCHK(in != NULL);                                                                 \
111
293
    if (md-> state_var .curlen > sizeof(md-> state_var .buf)) {                             \
112
0
       return CRYPT_INVALID_ARG;                                                            \
113
0
    }                                                                                       \
114
293
    if ((md-> state_var .length + inlen * 8) < md-> state_var .length) {                        \
115
0
      return CRYPT_HASH_OVERFLOW;                                                           \
116
0
    }                                                                                       \
117
705
    while (inlen > 0) {                                                                     \
118
412
        if (md-> state_var .curlen == 0 && inlen >= block_size) {                           \
119
213
           if ((err = compress_name (md, in)) != CRYPT_OK) {                                \
120
0
              return err;                                                                   \
121
0
           }                                                                                \
122
213
           md-> state_var .length += block_size * 8;                                        \
123
213
           in             += block_size;                                                    \
124
213
           inlen          -= block_size;                                                    \
125
213
        } else {                                                                            \
126
199
           n = MIN(inlen, (block_size - md-> state_var .curlen));                           \
127
199
           XMEMCPY(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n);             \
128
199
           md-> state_var .curlen += n;                                                     \
129
199
           in             += n;                                                             \
130
199
           inlen          -= n;                                                             \
131
199
           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
199
       }                                                                                    \
139
412
    }                                                                                       \
140
293
    return CRYPT_OK;                                                                        \
141
293
}
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
33.9k
#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
391
33.9k
#define Maj(x,y,z)      (((x | y) & z) | (x & y))
392
305k
#define S(x, n)         RORc((x),(n))
393
50.8k
#define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
394
33.9k
#define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
395
33.9k
#define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
396
25.4k
#define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
397
25.4k
#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
530
{
406
530
    ulong32 S[8], W[64], t0, t1;
407
#ifdef LTC_SMALL_CODE
408
    ulong32 t;
409
#endif
410
530
    int i;
411
412
    /* copy state into S */
413
4.77k
    for (i = 0; i < 8; i++) {
414
4.24k
        S[i] = md->sha256.state[i];
415
4.24k
    }
416
417
    /* copy the state into 512-bits into W[0..15] */
418
9.01k
    for (i = 0; i < 16; i++) {
419
8.48k
        LOAD32H(W[i], buf + (4*i));
420
8.48k
    }
421
422
    /* fill W[16..63] */
423
25.9k
    for (i = 16; i < 64; i++) {
424
25.4k
        W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
425
25.4k
    }
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
530
#define RND(a,b,c,d,e,f,g,h,i,ki)                    \
442
33.9k
     t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i];   \
443
33.9k
     t1 = Sigma0(a) + Maj(a, b, c);                  \
444
33.9k
     d += t0;                                        \
445
33.9k
     h  = t0 + t1;
446
447
530
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
448
530
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
449
530
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
450
530
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
451
530
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
452
530
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
453
530
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
454
530
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
455
530
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
456
530
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
457
530
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
458
530
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
459
530
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
460
530
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
461
530
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
462
530
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
463
530
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
464
530
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
465
530
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
466
530
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
467
530
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
468
530
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
469
530
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
470
530
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
471
530
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
472
530
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
473
530
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
474
530
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
475
530
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
476
530
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
477
530
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
478
530
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
479
530
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
480
530
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
481
530
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
482
530
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
483
530
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
484
530
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
485
530
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
486
530
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
487
530
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
488
530
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
489
530
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
490
530
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
491
530
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
492
530
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
493
530
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
494
530
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
495
530
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
496
530
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
497
530
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
498
530
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
499
530
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
500
530
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
501
530
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
502
530
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
503
530
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
504
530
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
505
530
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
506
530
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
507
530
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
508
530
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
509
530
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
510
530
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
511
530
#endif
512
530
#undef RND
513
514
    /* feedback */
515
4.77k
    for (i = 0; i < 8; i++) {
516
4.24k
        md->sha256.state[i] = md->sha256.state[i] + S[i];
517
4.24k
    }
518
530
    return CRYPT_OK;
519
530
}
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
293
{
538
293
    LTC_ARGCHK(md != NULL);
539
540
293
    md->sha256.curlen = 0;
541
293
    md->sha256.length = 0;
542
293
    md->sha256.state[0] = 0x6A09E667UL;
543
293
    md->sha256.state[1] = 0xBB67AE85UL;
544
293
    md->sha256.state[2] = 0x3C6EF372UL;
545
293
    md->sha256.state[3] = 0xA54FF53AUL;
546
293
    md->sha256.state[4] = 0x510E527FUL;
547
293
    md->sha256.state[5] = 0x9B05688CUL;
548
293
    md->sha256.state[6] = 0x1F83D9ABUL;
549
293
    md->sha256.state[7] = 0x5BE0CD19UL;
550
293
    return CRYPT_OK;
551
293
}
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
293
{
570
293
    int i;
571
572
293
    LTC_ARGCHK(md  != NULL);
573
293
    LTC_ARGCHK(out != NULL);
574
575
293
    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
293
    md->sha256.length += md->sha256.curlen * 8;
582
583
    /* append the '1' bit */
584
293
    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
293
    if (md->sha256.curlen > 56) {
591
120
        while (md->sha256.curlen < 64) {
592
96
            md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
593
96
        }
594
24
        s_sha256_compress(md, md->sha256.buf);
595
24
        md->sha256.curlen = 0;
596
24
    }
597
598
    /* pad upto 56 bytes of zeroes */
599
11.9k
    while (md->sha256.curlen < 56) {
600
11.6k
        md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
601
11.6k
    }
602
603
    /* store length */
604
293
    STORE64H(md->sha256.length, md->sha256.buf+56);
605
293
    s_sha256_compress(md, md->sha256.buf);
606
607
    /* copy output */
608
2.63k
    for (i = 0; i < 8; i++) {
609
2.34k
        STORE32H(md->sha256.state[i], out+(4*i));
610
2.34k
    }
611
#ifdef LTC_CLEAN_STACK
612
    zeromem(md, sizeof(hash_state));
613
#endif
614
293
    return CRYPT_OK;
615
293
}
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
293
std::vector<uint8_t> sha256(const uint8_t* data, const size_t size) {
635
293
    uint8_t out[32];
636
637
293
    impl::hash_state md;
638
293
    impl::sha256_init(&md);
639
293
    impl::sha256_process(&md, data, size);
640
293
    impl::sha256_done(&md, out);
641
642
293
    return std::vector<uint8_t>(out, out + sizeof(out));
643
293
}
644
645
293
std::vector<uint8_t> sha256(const std::vector<uint8_t> data) {
646
293
    return sha256(data.data(), data.size());
647
293
}
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 */