nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
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 */