Coverage Report

Created: 2023-06-07 06:09

/src/pycryptodome/src/hash_SHA2_template.c
Line
Count
Source (jump to first uncovered line)
1
/* ===================================================================
2
 *
3
 * Copyright (c) 2018, Helder Eijs <helderijs@gmail.com>
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in
14
 *    the documentation and/or other materials provided with the
15
 *    distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
 * POSSIBILITY OF SUCH DAMAGE.
29
 * ===================================================================
30
 */
31
32
#include <stdio.h>
33
#include "common.h"
34
#include "endianess.h"
35
36
FAKE_INIT(MODULE_NAME)
37
38
0
#define FUNC_NAME(pf) _PASTE2(MODULE_NAME, pf)
39
40
/**
41
 * SHA-2 as defined in FIPS 180-4 http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
42
 */
43
44
20.0M
#define CH(x,y,z)       (((x) & (y)) ^ (~(x) & (z)))
45
20.0M
#define MAJ(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
46
47
180M
#define ROTR32(n, x)    (((x)>>(n)) | ((x)<<(32-(n))))
48
#define ROTR64(n, x)    (((x)>>(n)) | ((x)<<(64-(n))))
49
30.0M
#define SHR(n,x)        ((x)>>(n))
50
51
#if WORD_SIZE==4
52
53
/** SHA-224, SHA-256 **/
54
55
typedef uint32_t sha2_word_t;
56
57
15.3M
#define SCHEDULE_SIZE 64
58
940k
#define BLOCK_SIZE 64
59
60
20.0M
#define SIGMA_0_256(x)    (ROTR32(2,x)  ^ ROTR32(13,x) ^ ROTR32(22,x))
61
20.0M
#define SIGMA_1_256(x)    (ROTR32(6,x)  ^ ROTR32(11,x) ^ ROTR32(25,x))
62
15.0M
#define sigma_0_256(x)    (ROTR32(7,x)  ^ ROTR32(18,x) ^ SHR(3,x))
63
15.0M
#define sigma_1_256(x)    (ROTR32(17,x) ^ ROTR32(19,x) ^ SHR(10,x))
64
65
static const sha2_word_t K[SCHEDULE_SIZE] = {
66
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
67
    0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
68
    0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
69
    0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
70
    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
71
    0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
72
    0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
73
    0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
74
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
75
    0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
76
    0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
77
    0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
78
    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
79
};
80
81
15.0M
#define SCHEDULE(i) (sigma_1_256(W[i-2]) + W[i-7] + sigma_0_256(W[i-15]) + W[i-16])
82
83
#define CYCLE(a,b,c,d,e,f,g,h,t) \
84
20.0M
    h += SIGMA_1_256(e) + CH(e,f,g) + K[t]  + W[t]; \
85
20.0M
    d += h; \
86
20.0M
    h += SIGMA_0_256(a) + MAJ(a,b,c);
87
88
5.00M
#define LOAD_WORD_BIG(p)        LOAD_U32_BIG(p)
89
330
#define STORE_WORD_BIG(p, w)    STORE_U32_BIG(p, w)
90
91
#elif WORD_SIZE==8
92
93
/** SHA-384, SHA-512 **/
94
95
typedef uint64_t sha2_word_t;
96
97
#define SCHEDULE_SIZE 80
98
#define BLOCK_SIZE 128
99
100
#define SIGMA_0_512(x)    (ROTR64(28,x) ^ ROTR64(34,x) ^ ROTR64(39,x))
101
#define SIGMA_1_512(x)    (ROTR64(14,x) ^ ROTR64(18,x) ^ ROTR64(41,x))
102
#define sigma_0_512(x)    (ROTR64(1,x)  ^ ROTR64(8,x)  ^ SHR(7,x))
103
#define sigma_1_512(x)    (ROTR64(19,x) ^ ROTR64(61,x) ^ SHR(6,x))
104
105
static const sha2_word_t K[SCHEDULE_SIZE] = {
106
    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
107
    0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
108
    0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
109
    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
110
    0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
111
    0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
112
    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
113
    0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
114
    0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
115
    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
116
    0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
117
    0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
118
    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
119
    0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
120
    0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
121
    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
122
    0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
123
    0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
124
    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
125
    0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
126
};
127
128
#define SCHEDULE(i) (sigma_1_512(W[i-2]) + W[i-7] + sigma_0_512(W[i-15]) + W[i-16])
129
130
#define CYCLE(a,b,c,d,e,f,g,h,t) \
131
    h += SIGMA_1_512(e) + CH(e,f,g) + K[t]  + W[t]; \
132
    d += h; \
133
    h += SIGMA_0_512(a) + MAJ(a,b,c);
134
135
#define LOAD_WORD_BIG(p)        LOAD_U64_BIG(p)
136
#define STORE_WORD_BIG(p, w)    STORE_U64_BIG(p, w)
137
138
#else
139
#error Invalid WORD_SIZE
140
#endif
141
142
static inline void put_be(sha2_word_t number, uint8_t *p)
143
1.32k
{
144
1.32k
    int i;
145
146
6.60k
    for (i=0; i<WORD_SIZE; i++) {
147
5.28k
        p[WORD_SIZE-1-i] = (uint8_t)(number >> (i*8));
148
5.28k
    }
149
1.32k
}
150
151
typedef struct t_hash_state {
152
    sha2_word_t h[8];
153
    uint8_t buf[BLOCK_SIZE];    /** 16 words **/
154
    unsigned curlen;            /** Useful message bytes in buf[] (leftmost) **/
155
    sha2_word_t totbits[2];     /** Total message length in bits **/
156
    size_t digest_size;         /** Actual digest size in bytes **/
157
} hash_state;
158
159
static int add_bits(hash_state *hs, sha2_word_t bits)
160
312k
{
161
312k
    hs->totbits[0] += bits;
162
312k
    if (hs->totbits[0] >= bits) {
163
312k
        return 0;
164
312k
    }
165
166
    /** Overflow **/
167
0
    hs->totbits[1] += 1;
168
0
    if (hs->totbits[1] > 0) {
169
0
        return 0;
170
0
    }
171
172
0
    return ERR_MAX_DATA;
173
0
}
174
175
static void sha_compress(hash_state * hs)
176
312k
{
177
312k
    sha2_word_t a, b, c, d, e, f, g, h;
178
312k
    sha2_word_t W[SCHEDULE_SIZE];
179
312k
    int i;
180
181
    /** Words flow in in big-endian mode **/
182
5.31M
    for (i=0; i<16; i++) {
183
5.00M
        W[i] = LOAD_WORD_BIG(&hs->buf[i*WORD_SIZE]);
184
5.00M
    }
185
15.3M
    for (;i<SCHEDULE_SIZE; i++) {
186
15.0M
        W[i] = SCHEDULE(i);
187
15.0M
    }
188
189
312k
    a = hs->h[0];
190
312k
    b = hs->h[1];
191
312k
    c = hs->h[2];
192
312k
    d = hs->h[3];
193
312k
    e = hs->h[4];
194
312k
    f = hs->h[5];
195
312k
    g = hs->h[6];
196
312k
    h = hs->h[7];
197
198
312k
    CYCLE(a,b,c,d,e,f,g,h, 0);
199
312k
    CYCLE(h,a,b,c,d,e,f,g, 1);
200
312k
    CYCLE(g,h,a,b,c,d,e,f, 2);
201
312k
    CYCLE(f,g,h,a,b,c,d,e, 3);
202
312k
    CYCLE(e,f,g,h,a,b,c,d, 4);
203
312k
    CYCLE(d,e,f,g,h,a,b,c, 5);
204
312k
    CYCLE(c,d,e,f,g,h,a,b, 6);
205
312k
    CYCLE(b,c,d,e,f,g,h,a, 7);
206
312k
    CYCLE(a,b,c,d,e,f,g,h, 8);
207
312k
    CYCLE(h,a,b,c,d,e,f,g, 9);
208
312k
    CYCLE(g,h,a,b,c,d,e,f, 10);
209
312k
    CYCLE(f,g,h,a,b,c,d,e, 11);
210
312k
    CYCLE(e,f,g,h,a,b,c,d, 12);
211
312k
    CYCLE(d,e,f,g,h,a,b,c, 13);
212
312k
    CYCLE(c,d,e,f,g,h,a,b, 14);
213
312k
    CYCLE(b,c,d,e,f,g,h,a, 15);
214
312k
    CYCLE(a,b,c,d,e,f,g,h, 16);
215
312k
    CYCLE(h,a,b,c,d,e,f,g, 17);
216
312k
    CYCLE(g,h,a,b,c,d,e,f, 18);
217
312k
    CYCLE(f,g,h,a,b,c,d,e, 19);
218
312k
    CYCLE(e,f,g,h,a,b,c,d, 20);
219
312k
    CYCLE(d,e,f,g,h,a,b,c, 21);
220
312k
    CYCLE(c,d,e,f,g,h,a,b, 22);
221
312k
    CYCLE(b,c,d,e,f,g,h,a, 23);
222
312k
    CYCLE(a,b,c,d,e,f,g,h, 24);
223
312k
    CYCLE(h,a,b,c,d,e,f,g, 25);
224
312k
    CYCLE(g,h,a,b,c,d,e,f, 26);
225
312k
    CYCLE(f,g,h,a,b,c,d,e, 27);
226
312k
    CYCLE(e,f,g,h,a,b,c,d, 28);
227
312k
    CYCLE(d,e,f,g,h,a,b,c, 29);
228
312k
    CYCLE(c,d,e,f,g,h,a,b, 30);
229
312k
    CYCLE(b,c,d,e,f,g,h,a, 31);
230
312k
    CYCLE(a,b,c,d,e,f,g,h, 32);
231
312k
    CYCLE(h,a,b,c,d,e,f,g, 33);
232
312k
    CYCLE(g,h,a,b,c,d,e,f, 34);
233
312k
    CYCLE(f,g,h,a,b,c,d,e, 35);
234
312k
    CYCLE(e,f,g,h,a,b,c,d, 36);
235
312k
    CYCLE(d,e,f,g,h,a,b,c, 37);
236
312k
    CYCLE(c,d,e,f,g,h,a,b, 38);
237
312k
    CYCLE(b,c,d,e,f,g,h,a, 39);
238
312k
    CYCLE(a,b,c,d,e,f,g,h, 40);
239
312k
    CYCLE(h,a,b,c,d,e,f,g, 41);
240
312k
    CYCLE(g,h,a,b,c,d,e,f, 42);
241
312k
    CYCLE(f,g,h,a,b,c,d,e, 43);
242
312k
    CYCLE(e,f,g,h,a,b,c,d, 44);
243
312k
    CYCLE(d,e,f,g,h,a,b,c, 45);
244
312k
    CYCLE(c,d,e,f,g,h,a,b, 46);
245
312k
    CYCLE(b,c,d,e,f,g,h,a, 47);
246
312k
    CYCLE(a,b,c,d,e,f,g,h, 48);
247
312k
    CYCLE(h,a,b,c,d,e,f,g, 49);
248
312k
    CYCLE(g,h,a,b,c,d,e,f, 50);
249
312k
    CYCLE(f,g,h,a,b,c,d,e, 51);
250
312k
    CYCLE(e,f,g,h,a,b,c,d, 52);
251
312k
    CYCLE(d,e,f,g,h,a,b,c, 53);
252
312k
    CYCLE(c,d,e,f,g,h,a,b, 54);
253
312k
    CYCLE(b,c,d,e,f,g,h,a, 55);
254
312k
    CYCLE(a,b,c,d,e,f,g,h, 56);
255
312k
    CYCLE(h,a,b,c,d,e,f,g, 57);
256
312k
    CYCLE(g,h,a,b,c,d,e,f, 58);
257
312k
    CYCLE(f,g,h,a,b,c,d,e, 59);
258
312k
    CYCLE(e,f,g,h,a,b,c,d, 60);
259
312k
    CYCLE(d,e,f,g,h,a,b,c, 61);
260
312k
    CYCLE(c,d,e,f,g,h,a,b, 62);
261
312k
    CYCLE(b,c,d,e,f,g,h,a, 63);
262
263
#if SCHEDULE_SIZE==80
264
    CYCLE(a,b,c,d,e,f,g,h, 64);
265
    CYCLE(h,a,b,c,d,e,f,g, 65);
266
    CYCLE(g,h,a,b,c,d,e,f, 66);
267
    CYCLE(f,g,h,a,b,c,d,e, 67);
268
    CYCLE(e,f,g,h,a,b,c,d, 68);
269
    CYCLE(d,e,f,g,h,a,b,c, 69);
270
    CYCLE(c,d,e,f,g,h,a,b, 70);
271
    CYCLE(b,c,d,e,f,g,h,a, 71);
272
    CYCLE(a,b,c,d,e,f,g,h, 72);
273
    CYCLE(h,a,b,c,d,e,f,g, 73);
274
    CYCLE(g,h,a,b,c,d,e,f, 74);
275
    CYCLE(f,g,h,a,b,c,d,e, 75);
276
    CYCLE(e,f,g,h,a,b,c,d, 76);
277
    CYCLE(d,e,f,g,h,a,b,c, 77);
278
    CYCLE(c,d,e,f,g,h,a,b, 78);
279
    CYCLE(b,c,d,e,f,g,h,a, 79);
280
#endif
281
282
    /** compute new intermediate hash **/
283
312k
    hs->h[0] += a;
284
312k
    hs->h[1] += b;
285
312k
    hs->h[2] += c;
286
312k
    hs->h[3] += d;
287
312k
    hs->h[4] += e;
288
312k
    hs->h[5] += f;
289
312k
    hs->h[6] += g;
290
312k
    hs->h[7] += h;
291
312k
}
292
293
EXPORT_SYM int FUNC_NAME(_init)(hash_state **shaState
294
#if DIGEST_SIZE == (512/8)
295
        , size_t digest_size
296
#endif
297
        )
298
329
{
299
329
    hash_state *hs;
300
329
    int i;
301
#if DIGEST_SIZE == (512/8)
302
    size_t variant;
303
#endif
304
305
329
    if (NULL == shaState) {
306
0
        return ERR_NULL;
307
0
    }
308
309
329
    *shaState = hs = (hash_state*) calloc(1, sizeof(hash_state));
310
329
    if (NULL == hs)
311
0
        return ERR_MEMORY;
312
313
329
    hs->curlen = 0;
314
329
    hs->totbits[0] = hs->totbits[1] = 0;
315
316
    /** Digest size and initial intermediate hash value **/
317
#if DIGEST_SIZE == (512/8)
318
    hs->digest_size = digest_size;
319
320
    switch (digest_size) {
321
        case 28: variant = 1;   /** SHA-512/224 **/
322
                 break;
323
        case 32: variant = 2;   /** SHA-512/256 **/
324
                 break;
325
        default: variant = 0;   /** Vanilla SHA-512 **/
326
    }
327
    
328
    for (i=0; i<8; i++) {
329
        hs->h[i] = H_SHA_512[variant][i];
330
    }
331
#else
332
329
    hs->digest_size = DIGEST_SIZE;
333
2.96k
    for (i=0; i<8; i++) {
334
2.63k
        hs->h[i] = H[i];
335
2.63k
    }
336
329
#endif
337
338
329
    return 0;
339
329
}
340
341
EXPORT_SYM int FUNC_NAME(_destroy)(hash_state *shaState)
342
329
{
343
329
    free(shaState);
344
329
    return 0;
345
329
}
346
347
EXPORT_SYM int FUNC_NAME(_update)(hash_state *hs, const uint8_t *buf, size_t len)
348
1.31k
{
349
1.31k
    if (NULL == hs || NULL == buf) {
350
164
        return ERR_NULL;
351
164
    }
352
353
1.15k
    assert(hs->curlen < BLOCK_SIZE);
354
355
314k
    while (len>0) {
356
313k
        unsigned btc, left;
357
358
313k
        left = BLOCK_SIZE - hs->curlen;
359
313k
        btc = (unsigned)MIN(left, len);
360
313k
        memcpy(&hs->buf[hs->curlen], buf, btc);
361
313k
        buf += btc;
362
313k
        hs->curlen += btc;
363
313k
        len -= btc;
364
365
313k
        if (hs->curlen == BLOCK_SIZE) {
366
312k
            sha_compress(hs);
367
312k
            hs->curlen = 0;
368
312k
            if (add_bits(hs, BLOCK_SIZE*8)) {
369
0
                return ERR_MAX_DATA;
370
0
            }
371
312k
        }
372
313k
    }
373
374
1.15k
    return 0;
375
1.15k
}
376
377
static int sha_finalize(hash_state *hs, uint8_t *hash, size_t digest_size)
378
165
{
379
165
    unsigned left, i;
380
165
    uint8_t hash_tmp[WORD_SIZE*8];
381
382
165
    if (digest_size != hs->digest_size) {
383
0
        return ERR_DIGEST_SIZE;
384
0
    }
385
386
    /* remaining length of the message */
387
165
    if (add_bits(hs, hs->curlen*8)) {
388
0
        return ERR_MAX_DATA;
389
0
    }
390
391
    /* append the '1' bit */
392
    /* buf[] is guaranteed to have at least 1 byte free */
393
165
    hs->buf[hs->curlen++] = 0x80;
394
395
    /** if there are less then 64/128 bits left, just pad with zeroes and compress **/
396
165
    left = BLOCK_SIZE - hs->curlen;
397
165
    if (left < WORD_SIZE*2) {
398
61
        memset(&hs->buf[hs->curlen], 0, left);
399
61
        sha_compress(hs);
400
61
        hs->curlen = 0;
401
61
    }
402
403
    /**
404
     * pad with zeroes and close the block with the bit length
405
     * encoded as 64-bit integer big endian.
406
     **/
407
165
    left = BLOCK_SIZE - hs->curlen;
408
165
    memset(&hs->buf[hs->curlen], 0, left);
409
165
    STORE_WORD_BIG(&hs->buf[BLOCK_SIZE-(2*WORD_SIZE)], hs->totbits[1]);
410
165
    STORE_WORD_BIG(&hs->buf[BLOCK_SIZE-(  WORD_SIZE)], hs->totbits[0]);
411
412
    /** compress one last time **/
413
165
    sha_compress(hs);
414
415
    /** create final hash **/
416
1.48k
    for (i=0; i<8; i++) {
417
1.32k
        put_be(hs->h[i], &hash_tmp[i*WORD_SIZE]);
418
1.32k
    }
419
165
    memcpy(hash, hash_tmp, hs->digest_size);
420
421
165
    return 0;
422
165
}
423
424
EXPORT_SYM int FUNC_NAME(_digest)(const hash_state *shaState, uint8_t *digest, size_t digest_size)
425
165
{
426
165
    hash_state temp;
427
428
165
    if (NULL == shaState) {
429
0
        return ERR_NULL;
430
0
    }
431
432
165
    if (digest_size != shaState->digest_size) {
433
0
        return ERR_DIGEST_SIZE;
434
0
    }
435
436
165
    temp = *shaState;
437
165
    sha_finalize(&temp, digest, digest_size);
438
165
    return 0;
439
165
}
440
441
EXPORT_SYM int FUNC_NAME(_copy)(const hash_state *src, hash_state *dst)
442
0
{
443
0
    if (NULL == src || NULL == dst) {
444
0
        return ERR_NULL;
445
0
    }
446
447
0
    *dst = *src;
448
0
    return 0;
449
0
}
450
451
/**
452
 * This is a specialized function to efficiently perform the inner loop of PBKDF2-HMAC.
453
 *
454
 * - inner, the hash after the inner padded secret has been absorbed
455
 * - outer, the hash after the outer padded secret has been absorbed
456
 * - first_hmac, the output of the first HMAC iteration (with salt and counter)
457
 * - result, the XOR of the HMACs from all iterations
458
 * - iterations, the total number of PBKDF2 iterations (>0)
459
 *
460
 * This function does not change the state of either hash.
461
 */
462
EXPORT_SYM int FUNC_NAME(_pbkdf2_hmac_assist)(const hash_state *inner, const hash_state *outer,
463
                                             const uint8_t *first_hmac,
464
                                             uint8_t *result,
465
                                             size_t iterations,
466
                                             size_t digest_size)
467
0
{
468
0
    hash_state inner_temp, outer_temp;
469
0
    size_t i;
470
0
    uint8_t last_hmac[DIGEST_SIZE]; /** MAX DIGEST SIZE **/
471
472
0
    if (NULL == inner || NULL == outer || NULL == first_hmac || NULL == result) {
473
0
        return ERR_NULL;
474
0
    }
475
476
0
    if (iterations == 0) {
477
0
        return ERR_NR_ROUNDS;
478
0
    }
479
480
0
    if (digest_size != inner->digest_size || digest_size != outer->digest_size) {
481
0
        return ERR_DIGEST_SIZE;
482
0
    }
483
    
484
0
    memcpy(result, first_hmac, digest_size);
485
0
    memcpy(last_hmac, first_hmac, digest_size);
486
487
0
    for (i=1; i<iterations; i++) {
488
0
        unsigned j;
489
490
0
        inner_temp = *inner;
491
0
        outer_temp = *outer;
492
493
0
        FUNC_NAME(_update)(&inner_temp, last_hmac, digest_size);
494
0
        sha_finalize(&inner_temp, last_hmac, digest_size);
495
496
        /** last_hmac is now the intermediate digest **/
497
498
0
        FUNC_NAME(_update)(&outer_temp, last_hmac, digest_size);
499
0
        sha_finalize(&outer_temp, last_hmac, digest_size);
500
501
0
        for (j=0; j<digest_size; j++) {
502
0
            result[j] ^= last_hmac[j];
503
0
        }
504
0
    }
505
506
0
    return 0;
507
0
}
508
509
#ifdef MAIN
510
511
void initialize(hash_state **hs)
512
{
513
#if DIGEST_SIZE == (512/8)
514
    FUNC_NAME(_init)(hs, 512);
515
#else
516
    FUNC_NAME(_init)(hs);
517
#endif
518
 
519
}
520
521
int main(void)
522
{
523
    hash_state *hs;
524
    const uint8_t tv[] = "The quick brown fox jumps over the lazy dog";
525
    uint8_t result[DIGEST_SIZE];
526
    int i;
527
528
    initialize(&hs);
529
    FUNC_NAME(_update)(hs, tv, sizeof tv - 1);
530
    FUNC_NAME(_digest)(hs, result);
531
    FUNC_NAME(_destroy)(hs);
532
533
    for (i=0; i < hs->digest_size; i++) {
534
        printf("%02X", result[i]);
535
    }
536
    printf("\n");
537
538
    initialize(&hs);
539
    FUNC_NAME(_digest)(hs, result);
540
    FUNC_NAME(_destroy)(hs);
541
542
    for (i=0; i< hs->digest_size; i++) {
543
        printf("%02X", result[i]);
544
    }
545
    printf("\n");
546
547
    initialize(&hs);
548
    for (i=0; i<10000000; i++) {
549
        FUNC_NAME(_update)(hs, tv, sizeof tv - 1);
550
    }
551
    FUNC_NAME(_destroy)(hs);
552
553
    printf("\n");
554
}
555
#endif