Coverage Report

Created: 2026-02-07 07:14

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