Line | Count | Source |
1 | | /* |
2 | | * FIPS 180-2 SHA-224/256/384/512 implementation |
3 | | * Last update: 02/02/2007 |
4 | | * Issue date: 04/30/2005 |
5 | | * |
6 | | * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch> |
7 | | * All rights reserved. |
8 | | * |
9 | | * Redistribution and use in source and binary forms, with or without |
10 | | * modification, are permitted provided that the following conditions |
11 | | * are met: |
12 | | * 1. Redistributions of source code must retain the above copyright |
13 | | * notice, this list of conditions and the following disclaimer. |
14 | | * 2. Redistributions in binary form must reproduce the above copyright |
15 | | * notice, this list of conditions and the following disclaimer in the |
16 | | * documentation and/or other materials provided with the distribution. |
17 | | * 3. Neither the name of the project nor the names of its contributors |
18 | | * may be used to endorse or promote products derived from this software |
19 | | * without specific prior written permission. |
20 | | * |
21 | | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND |
22 | | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
23 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
24 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE |
25 | | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
26 | | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
27 | | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
28 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
29 | | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
30 | | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
31 | | * SUCH DAMAGE. |
32 | | */ |
33 | | |
34 | | #include <znc/SHA256.h> |
35 | | |
36 | | #include <string.h> |
37 | | |
38 | 0 | #define SHFR(x, n) (x >> n) |
39 | 0 | #define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n))) |
40 | | #define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n))) |
41 | 0 | #define CH(x, y, z) ((x & y) ^ (~x & z)) |
42 | 0 | #define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) |
43 | | |
44 | 0 | #define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) |
45 | 0 | #define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) |
46 | 0 | #define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3)) |
47 | 0 | #define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10)) |
48 | | |
49 | | #define UNPACK32(x, str) \ |
50 | 0 | { \ |
51 | 0 | *((str)+3) = (uint8_t)((x)); \ |
52 | 0 | *((str)+2) = (uint8_t)((x) >> 8); \ |
53 | 0 | *((str)+1) = (uint8_t)((x) >> 16); \ |
54 | 0 | *((str)+0) = (uint8_t)((x) >> 24); \ |
55 | 0 | } |
56 | | |
57 | | #define PACK32(str, x) \ |
58 | 0 | { \ |
59 | 0 | *(x) = ((uint32_t) * ((str)+3)) | ((uint32_t) * ((str)+2) << 8) | \ |
60 | 0 | ((uint32_t) * ((str)+1) << 16) | \ |
61 | 0 | ((uint32_t) * ((str)+0) << 24); \ |
62 | 0 | } |
63 | | |
64 | | /* Macros used for loops unrolling */ |
65 | | |
66 | | #define SHA256_SCR(i) \ |
67 | 0 | { \ |
68 | 0 | w[i] = \ |
69 | 0 | SHA256_F4(w[i - 2]) + w[i - 7] + SHA256_F3(w[i - 15]) + w[i - 16]; \ |
70 | 0 | } |
71 | | |
72 | | #define SHA256_EXP(a, b, c, d, e, f, g, h, j) \ |
73 | | { \ |
74 | | t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) + \ |
75 | | sha256_k[j] + w[j]; \ |
76 | | t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ |
77 | | wv[d] += t1; \ |
78 | | wv[h] = t1 + t2; \ |
79 | | } |
80 | | |
81 | | uint32_t sha256_h0[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, |
82 | | 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; |
83 | | |
84 | | uint32_t sha256_k[64] = { |
85 | | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, |
86 | | 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, |
87 | | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, |
88 | | 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, |
89 | | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, |
90 | | 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, |
91 | | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, |
92 | | 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, |
93 | | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, |
94 | | 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, |
95 | | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; |
96 | | |
97 | | /* SHA-256 functions */ |
98 | | |
99 | | static void sha256_transf(sha256_ctx* ctx, const unsigned char* message, |
100 | 0 | size_t block_nb) { |
101 | 0 | uint32_t w[64]; |
102 | 0 | uint32_t wv[8]; |
103 | 0 | uint32_t t1, t2; |
104 | 0 | const unsigned char* sub_block; |
105 | 0 | int i; |
106 | |
|
107 | 0 | int j; |
108 | |
|
109 | 0 | for (i = 0; i < (int)block_nb; i++) { |
110 | 0 | sub_block = message + (i << 6); |
111 | |
|
112 | 0 | for (j = 0; j < 16; j++) { |
113 | 0 | PACK32(&sub_block[j << 2], &w[j]); |
114 | 0 | } |
115 | |
|
116 | 0 | for (j = 16; j < 64; j++) { |
117 | 0 | SHA256_SCR(j); |
118 | 0 | } |
119 | |
|
120 | 0 | for (j = 0; j < 8; j++) { |
121 | 0 | wv[j] = ctx->h[j]; |
122 | 0 | } |
123 | |
|
124 | 0 | for (j = 0; j < 64; j++) { |
125 | 0 | t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + |
126 | 0 | sha256_k[j] + w[j]; |
127 | 0 | t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]); |
128 | 0 | wv[7] = wv[6]; |
129 | 0 | wv[6] = wv[5]; |
130 | 0 | wv[5] = wv[4]; |
131 | 0 | wv[4] = wv[3] + t1; |
132 | 0 | wv[3] = wv[2]; |
133 | 0 | wv[2] = wv[1]; |
134 | 0 | wv[1] = wv[0]; |
135 | 0 | wv[0] = t1 + t2; |
136 | 0 | } |
137 | |
|
138 | 0 | for (j = 0; j < 8; j++) { |
139 | 0 | ctx->h[j] += wv[j]; |
140 | 0 | } |
141 | 0 | } |
142 | 0 | } |
143 | | |
144 | 0 | void sha256(const unsigned char* message, size_t len, unsigned char* digest) { |
145 | 0 | sha256_ctx ctx; |
146 | |
|
147 | 0 | sha256_init(&ctx); |
148 | 0 | sha256_update(&ctx, message, len); |
149 | 0 | sha256_final(&ctx, digest); |
150 | 0 | } |
151 | | |
152 | 0 | void sha256_init(sha256_ctx* ctx) { |
153 | 0 | int i; |
154 | 0 | for (i = 0; i < 8; i++) { |
155 | 0 | ctx->h[i] = sha256_h0[i]; |
156 | 0 | } |
157 | |
|
158 | 0 | ctx->len = 0; |
159 | 0 | ctx->tot_len = 0; |
160 | 0 | } |
161 | | |
162 | 0 | void sha256_update(sha256_ctx* ctx, const unsigned char* message, size_t len) { |
163 | 0 | size_t block_nb; |
164 | 0 | size_t new_len, rem_len, tmp_len; |
165 | 0 | const unsigned char* shifted_message; |
166 | |
|
167 | 0 | tmp_len = SHA256_BLOCK_SIZE - ctx->len; |
168 | 0 | rem_len = len < tmp_len ? len : tmp_len; |
169 | |
|
170 | 0 | memcpy(&ctx->block[ctx->len], message, rem_len); |
171 | |
|
172 | 0 | if (ctx->len + len < SHA256_BLOCK_SIZE) { |
173 | 0 | ctx->len += len; |
174 | 0 | return; |
175 | 0 | } |
176 | | |
177 | 0 | new_len = len - rem_len; |
178 | 0 | block_nb = new_len / SHA256_BLOCK_SIZE; |
179 | |
|
180 | 0 | shifted_message = message + rem_len; |
181 | |
|
182 | 0 | sha256_transf(ctx, ctx->block, 1); |
183 | 0 | sha256_transf(ctx, shifted_message, block_nb); |
184 | |
|
185 | 0 | rem_len = new_len % SHA256_BLOCK_SIZE; |
186 | |
|
187 | 0 | memcpy(ctx->block, &shifted_message[block_nb << 6], rem_len); |
188 | |
|
189 | 0 | ctx->len = rem_len; |
190 | 0 | ctx->tot_len += (block_nb + 1) << 6; |
191 | 0 | } |
192 | | |
193 | 0 | void sha256_final(sha256_ctx* ctx, unsigned char* digest) { |
194 | 0 | unsigned int block_nb; |
195 | 0 | unsigned int pm_len; |
196 | 0 | size_t len_b; |
197 | |
|
198 | 0 | int i; |
199 | |
|
200 | 0 | block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) < (ctx->len % SHA256_BLOCK_SIZE))); |
201 | |
|
202 | 0 | len_b = (ctx->tot_len + ctx->len) << 3; |
203 | 0 | pm_len = block_nb << 6; |
204 | |
|
205 | 0 | memset(ctx->block + ctx->len, 0, pm_len - ctx->len); |
206 | 0 | ctx->block[ctx->len] = 0x80; |
207 | 0 | UNPACK32(len_b, ctx->block + pm_len - 4); |
208 | |
|
209 | 0 | sha256_transf(ctx, ctx->block, block_nb); |
210 | |
|
211 | 0 | for (i = 0; i < 8; i++) { |
212 | 0 | UNPACK32(ctx->h[i], &digest[i << 2]); |
213 | 0 | } |
214 | 0 | } |