nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * FIPS-180-2 compliant SHA-2 implementation (only sha256 so far) |
||
3 | * |
||
4 | * This program is free software; you can redistribute it and/or modify |
||
5 | * it under the terms of the GNU General Public License as published by |
||
6 | * the Free Software Foundation; either version 2 of the License, or |
||
7 | * (at your option) any later version. |
||
8 | * |
||
9 | * This program is distributed in the hope that it will be useful, |
||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
12 | * GNU General Public License for more details. |
||
13 | * |
||
14 | * You should have received a copy of the GNU General Public License |
||
15 | * along with this program; if not, write to the Free Software |
||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||
17 | * |
||
18 | */ |
||
19 | #include <string.h> |
||
20 | #include <glib.h> |
||
21 | |||
22 | #include "sha2.h" |
||
23 | |||
24 | /* the K array */ |
||
25 | static const guint32 K[64] = { |
||
26 | 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, |
||
27 | 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, |
||
28 | 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, |
||
29 | 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, |
||
30 | 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, |
||
31 | 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, |
||
32 | 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, |
||
33 | 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, |
||
34 | 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, |
||
35 | 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, |
||
36 | 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, |
||
37 | 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, |
||
38 | 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL |
||
39 | }; |
||
40 | |||
41 | |||
42 | #define GET_UINT32(n,b,i) \ |
||
43 | { \ |
||
44 | (n) = ( (guint32) (b)[(i) ] << 24 ) \ |
||
45 | | ( (guint32) (b)[(i) + 1] << 16 ) \ |
||
46 | | ( (guint32) (b)[(i) + 2] << 8 ) \ |
||
47 | | ( (guint32) (b)[(i) + 3] ); \ |
||
48 | } |
||
49 | |||
50 | #define PUT_UINT32(n,b,i) \ |
||
51 | { \ |
||
52 | (b)[(i) ] = (guint8) ( (n) >> 24 ); \ |
||
53 | (b)[(i) + 1] = (guint8) ( (n) >> 16 ); \ |
||
54 | (b)[(i) + 2] = (guint8) ( (n) >> 8 ); \ |
||
55 | (b)[(i) + 3] = (guint8) ( (n) ); \ |
||
56 | } |
||
57 | |||
58 | /* Initialize the hash state */ |
||
59 | void sha256_starts( sha256_context *ctx ) |
||
60 | { |
||
61 | ctx->total = 0; |
||
62 | ctx->state[0] = 0x6A09E667UL; |
||
63 | ctx->state[1] = 0xBB67AE85UL; |
||
64 | ctx->state[2] = 0x3C6EF372UL; |
||
65 | ctx->state[3] = 0xA54FF53AUL; |
||
66 | ctx->state[4] = 0x510E527FUL; |
||
67 | ctx->state[5] = 0x9B05688CUL; |
||
68 | ctx->state[6] = 0x1F83D9ABUL; |
||
69 | ctx->state[7] = 0x5BE0CD19UL; |
||
70 | } |
||
71 | |||
72 | static void sha256_process( sha256_context *ctx, const guint8 *data ) |
||
73 | { |
||
74 | guint32 i, temp1, temp2, W[64], A, B, C, D, E, F, G, H; |
||
75 | |||
76 | /* init W */ |
||
77 | GET_UINT32( W[0], data, 0 ); |
||
78 | GET_UINT32( W[1], data, 4 ); |
||
79 | GET_UINT32( W[2], data, 8 ); |
||
80 | GET_UINT32( W[3], data, 12 ); |
||
81 | GET_UINT32( W[4], data, 16 ); |
||
82 | GET_UINT32( W[5], data, 20 ); |
||
83 | GET_UINT32( W[6], data, 24 ); |
||
84 | GET_UINT32( W[7], data, 28 ); |
||
85 | GET_UINT32( W[8], data, 32 ); |
||
86 | GET_UINT32( W[9], data, 36 ); |
||
87 | GET_UINT32( W[10], data, 40 ); |
||
88 | GET_UINT32( W[11], data, 44 ); |
||
89 | GET_UINT32( W[12], data, 48 ); |
||
90 | GET_UINT32( W[13], data, 52 ); |
||
91 | GET_UINT32( W[14], data, 56 ); |
||
92 | GET_UINT32( W[15], data, 60 ); |
||
93 | |||
94 | #define RR(x,n) ((x << (32 - n)) | ((x & 0xFFFFFFFF) >> n)) |
||
95 | #define S0(x) (RR(x, 7) ^ RR(x, 18) ^ (x >> 3)) |
||
96 | #define S1(x) (RR(x, 17) ^ RR(x, 19) ^ (x >> 10)) |
||
97 | |||
98 | for (i = 16; i < 64 ; i++) |
||
99 | { |
||
100 | W[i] = W[i - 16] + S0(W[i - 15]) + W[i - 7] + S1(W[i - 2]); |
||
101 | } |
||
102 | |||
103 | /* Compression */ |
||
104 | A = ctx->state[0]; |
||
105 | B = ctx->state[1]; |
||
106 | C = ctx->state[2]; |
||
107 | D = ctx->state[3]; |
||
108 | E = ctx->state[4]; |
||
109 | F = ctx->state[5]; |
||
110 | G = ctx->state[6]; |
||
111 | H = ctx->state[7]; |
||
112 | |||
113 | #undef S0 |
||
114 | #undef S1 |
||
115 | #define S0(x) (RR(x, 2) ^ RR(x, 13) ^ RR(x, 22)) |
||
116 | #define S1(x) (RR(x, 6) ^ RR(x, 11) ^ RR(x, 25)) |
||
117 | #define CH(x,y,z) (z ^ (x & (y ^ z))) |
||
118 | #define MAJ(x,y,z) (((x | y) & z) | (x & y)) |
||
119 | |||
120 | for (i = 0; i < 64; ++i) { |
||
121 | temp1 = H + S1(E) + CH(E, F, G) + K[i] + W[i]; |
||
122 | temp2 = S0(A) + MAJ(A, B, C); |
||
123 | H = G; |
||
124 | G = F; |
||
125 | F = E; |
||
126 | E = D + temp1; |
||
127 | D = C; |
||
128 | C = B; |
||
129 | B = A; |
||
130 | A = temp1 + temp2; |
||
131 | |||
132 | } |
||
133 | |||
134 | ctx->state[0] += A; |
||
135 | ctx->state[1] += B; |
||
136 | ctx->state[2] += C; |
||
137 | ctx->state[3] += D; |
||
138 | ctx->state[4] += E; |
||
139 | ctx->state[5] += F; |
||
140 | ctx->state[6] += G; |
||
141 | ctx->state[7] += H; |
||
142 | } |
||
143 | |||
144 | void sha256_update( sha256_context *ctx, const guint8 *input, guint32 length ) |
||
145 | { |
||
146 | guint32 left, fill; |
||
147 | |||
148 | if( ! length ) return; |
||
149 | |||
150 | left = (guint32)(ctx->total % SHA256_BLOCK_SIZE); |
||
151 | fill = SHA256_BLOCK_SIZE - left; |
||
152 | |||
153 | ctx->total += length; |
||
154 | |||
155 | if( left && length >= fill ) |
||
156 | { |
||
157 | memcpy( (void *) (ctx->buffer + left), |
||
158 | (const void *) input, fill ); |
||
159 | sha256_process( ctx, ctx->buffer ); |
||
160 | length -= fill; |
||
161 | input += fill; |
||
162 | left = 0; |
||
163 | } |
||
164 | |||
165 | while( length >= SHA256_BLOCK_SIZE ) |
||
166 | { |
||
167 | sha256_process( ctx, input ); |
||
168 | length -= SHA256_BLOCK_SIZE; |
||
169 | input += SHA256_BLOCK_SIZE; |
||
170 | } |
||
171 | |||
172 | if( length ) |
||
173 | { |
||
174 | memcpy( (void *) (ctx->buffer + left), |
||
175 | (const void *) input, length ); |
||
176 | } |
||
177 | } |
||
178 | |||
179 | static guint8 sha256_padding[64] = |
||
180 | { |
||
181 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
182 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
183 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
184 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
||
185 | }; |
||
186 | |||
187 | void sha256_finish( sha256_context *ctx, guint8 digest[SHA256_DIGEST_LEN] ) |
||
188 | { |
||
189 | guint32 last, padn; |
||
190 | guint64 total_length; |
||
191 | guint8 msglen[8]; |
||
192 | |||
193 | total_length = ctx->total * 8; |
||
194 | |||
195 | last = (guint32)(ctx->total % SHA256_BLOCK_SIZE); |
||
196 | padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); |
||
197 | |||
198 | PUT_UINT32( total_length >> 32, msglen, 0 ); |
||
199 | PUT_UINT32( total_length, msglen, 4 ); |
||
200 | |||
201 | sha256_update( ctx, sha256_padding, padn ); |
||
202 | sha256_update( ctx, msglen, 8 ); |
||
203 | |||
204 | PUT_UINT32( ctx->state[0], digest, 0 ); |
||
205 | PUT_UINT32( ctx->state[1], digest, 4 ); |
||
206 | PUT_UINT32( ctx->state[2], digest, 8 ); |
||
207 | PUT_UINT32( ctx->state[3], digest, 12 ); |
||
208 | PUT_UINT32( ctx->state[4], digest, 16 ); |
||
209 | PUT_UINT32( ctx->state[5], digest, 20 ); |
||
210 | PUT_UINT32( ctx->state[6], digest, 24 ); |
||
211 | PUT_UINT32( ctx->state[7], digest, 28 ); |
||
212 | } |
||
213 | |||
214 | void sha256_hmac_starts( sha256_hmac_context *hctx, const guint8 *key, guint32 keylen ) |
||
215 | { |
||
216 | guint32 i; |
||
217 | guint8 k_ipad[SHA256_BLOCK_SIZE]; |
||
218 | guint8 key_compress[SHA256_DIGEST_LEN]; |
||
219 | |||
220 | memset( k_ipad, 0x36, SHA256_BLOCK_SIZE ); |
||
221 | memset( hctx->k_opad, 0x5C, SHA256_BLOCK_SIZE ); |
||
222 | |||
223 | if (keylen > SHA256_BLOCK_SIZE) |
||
224 | { |
||
225 | sha256_starts( &hctx->ctx ); |
||
226 | sha256_update( &hctx->ctx, key, keylen ); |
||
227 | sha256_finish( &hctx->ctx, key_compress ); |
||
228 | key = key_compress; |
||
229 | keylen = SHA256_DIGEST_LEN; |
||
230 | } |
||
231 | |||
232 | for( i = 0; i < keylen; i++ ) |
||
233 | { |
||
234 | k_ipad[i] ^= key[i]; |
||
235 | hctx->k_opad[i] ^= key[i]; |
||
236 | } |
||
237 | |||
238 | sha256_starts( &hctx->ctx ); |
||
239 | sha256_update( &hctx->ctx, k_ipad, SHA256_BLOCK_SIZE ); |
||
240 | } |
||
241 | |||
242 | void sha256_hmac_update( sha256_hmac_context *hctx, const guint8 *buf, guint32 buflen ) |
||
243 | { |
||
244 | sha256_update( &hctx->ctx, buf, buflen ); |
||
245 | } |
||
246 | |||
247 | void sha256_hmac_finish( sha256_hmac_context *hctx, guint8 digest[SHA256_DIGEST_LEN] ) |
||
248 | { |
||
249 | guint8 tmpbuf[SHA256_DIGEST_LEN]; |
||
250 | |||
251 | sha256_finish( &hctx->ctx, tmpbuf ); |
||
252 | |||
253 | sha256_starts( &hctx->ctx ); |
||
254 | sha256_update( &hctx->ctx, hctx->k_opad, SHA256_BLOCK_SIZE ); |
||
255 | sha256_update( &hctx->ctx, tmpbuf, SHA256_DIGEST_LEN ); |
||
256 | sha256_finish( &hctx->ctx, digest ); |
||
257 | } |
||
258 | |||
259 | void sha256_hmac( const guint8 *key, guint32 keylen, const guint8 *buf, guint32 buflen, |
||
260 | guint8 digest[SHA256_DIGEST_LEN] ) |
||
261 | { |
||
262 | sha256_hmac_context hctx; |
||
263 | |||
264 | sha256_hmac_starts( &hctx, key, keylen ); |
||
265 | sha256_hmac_update( &hctx, buf, buflen ); |
||
266 | sha256_hmac_finish( &hctx, digest ); |
||
267 | } |
||
268 | |||
269 | |||
270 | /* |
||
271 | * Editor modelines - http://www.wireshark.org/tools/modelines.html |
||
272 | * |
||
273 | * Local variables: |
||
274 | * c-basic-offset: 4 |
||
275 | * tab-width: 8 |
||
276 | * indent-tabs-mode: nil |
||
277 | * End: |
||
278 | * |
||
279 | * vi: set shiftwidth=4 tabstop=8 expandtab: |
||
280 | * :indentSize=4:tabSize=8:noTabs=true: |
||
281 | */ |