Coverage Report

Created: 2024-09-11 06:39

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