Coverage Report

Created: 2026-10-17 06:43

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