1 | #include <stdint.h> |
2 | |
3 | /* Process LEN bytes of BUFFER, accumulating context into CTX. |
4 | It is assumed that LEN % 128 == 0. */ |
5 | void |
6 | __sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx) |
7 | { |
8 | const uint64_t *words = buffer; |
9 | size_t nwords = len / sizeof (uint64_t); |
10 | uint64_t a = ctx->H[0]; |
11 | uint64_t b = ctx->H[1]; |
12 | uint64_t c = ctx->H[2]; |
13 | uint64_t d = ctx->H[3]; |
14 | uint64_t e = ctx->H[4]; |
15 | uint64_t f = ctx->H[5]; |
16 | uint64_t g = ctx->H[6]; |
17 | uint64_t h = ctx->H[7]; |
18 | |
19 | /* First increment the byte count. FIPS 180-2 specifies the possible |
20 | length of the file up to 2^128 bits. Here we only compute the |
21 | number of bytes. Do a double word increment. */ |
22 | #ifdef USE_TOTAL128 |
23 | ctx->total128 += len; |
24 | #else |
25 | uint64_t lolen = len; |
26 | ctx->total[TOTAL128_low] += lolen; |
27 | ctx->total[TOTAL128_high] += ((len >> 31 >> 31 >> 2) |
28 | + (ctx->total[TOTAL128_low] < lolen)); |
29 | #endif |
30 | |
31 | /* Process all bytes in the buffer with 128 bytes in each round of |
32 | the loop. */ |
33 | while (nwords > 0) |
34 | { |
35 | uint64_t W[80]; |
36 | uint64_t a_save = a; |
37 | uint64_t b_save = b; |
38 | uint64_t c_save = c; |
39 | uint64_t d_save = d; |
40 | uint64_t e_save = e; |
41 | uint64_t f_save = f; |
42 | uint64_t g_save = g; |
43 | uint64_t h_save = h; |
44 | |
45 | /* Operators defined in FIPS 180-2:4.1.2. */ |
46 | #define Ch(x, y, z) ((x & y) ^ (~x & z)) |
47 | #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) |
48 | #define S0(x) (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39)) |
49 | #define S1(x) (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41)) |
50 | #define R0(x) (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7)) |
51 | #define R1(x) (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6)) |
52 | |
53 | /* It is unfortunate that C does not provide an operator for |
54 | cyclic rotation. Hope the C compiler is smart enough. */ |
55 | #define CYCLIC(w, s) ((w >> s) | (w << (64 - s))) |
56 | |
57 | /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */ |
58 | for (unsigned int t = 0; t < 16; ++t) |
59 | { |
60 | W[t] = SWAP (*words); |
61 | ++words; |
62 | } |
63 | for (unsigned int t = 16; t < 80; ++t) |
64 | W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16]; |
65 | |
66 | /* The actual computation according to FIPS 180-2:6.3.2 step 3. */ |
67 | for (unsigned int t = 0; t < 80; ++t) |
68 | { |
69 | uint64_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t]; |
70 | uint64_t T2 = S0 (a) + Maj (a, b, c); |
71 | h = g; |
72 | g = f; |
73 | f = e; |
74 | e = d + T1; |
75 | d = c; |
76 | c = b; |
77 | b = a; |
78 | a = T1 + T2; |
79 | } |
80 | |
81 | /* Add the starting values of the context according to FIPS 180-2:6.3.2 |
82 | step 4. */ |
83 | a += a_save; |
84 | b += b_save; |
85 | c += c_save; |
86 | d += d_save; |
87 | e += e_save; |
88 | f += f_save; |
89 | g += g_save; |
90 | h += h_save; |
91 | |
92 | /* Prepare for the next round. */ |
93 | nwords -= 16; |
94 | } |
95 | |
96 | /* Put checksum in context given as argument. */ |
97 | ctx->H[0] = a; |
98 | ctx->H[1] = b; |
99 | ctx->H[2] = c; |
100 | ctx->H[3] = d; |
101 | ctx->H[4] = e; |
102 | ctx->H[5] = f; |
103 | ctx->H[6] = g; |
104 | ctx->H[7] = h; |
105 | } |
106 | |