]> git.saurik.com Git - apt.git/blob - apt-pkg/contrib/sha256.cc
* merged the apt-ftparchive improvments by aj (thanks dude!)
[apt.git] / apt-pkg / contrib / sha256.cc
1 /*
2 * Cryptographic API.
3 *
4 * SHA-256, as specified in
5 * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
6 *
7 * SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>.
8 *
9 * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
10 * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
11 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
12 *
13 * Ported from the Linux kernel to Apt by Anthony Towns <ajt@debian.org>
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the Free
17 * Software Foundation; either version 2 of the License, or (at your option)
18 * any later version.
19 *
20 */
21 #define SHA256_DIGEST_SIZE 32
22 #define SHA256_HMAC_BLOCK_SIZE 64
23
24 #define ror32(value,bits) (((value) >> (bits)) | ((value) << (32 - (bits))))
25
26 #include <apt-pkg/sha256.h>
27 #include <apt-pkg/strutl.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <stdint.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <arpa/inet.h>
34
35 typedef uint32_t u32;
36 typedef uint8_t u8;
37
38 static inline u32 Ch(u32 x, u32 y, u32 z)
39 {
40 return z ^ (x & (y ^ z));
41 }
42
43 static inline u32 Maj(u32 x, u32 y, u32 z)
44 {
45 return (x & y) | (z & (x | y));
46 }
47
48 #define e0(x) (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22))
49 #define e1(x) (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25))
50 #define s0(x) (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3))
51 #define s1(x) (ror32(x,17) ^ ror32(x,19) ^ (x >> 10))
52
53 #define H0 0x6a09e667
54 #define H1 0xbb67ae85
55 #define H2 0x3c6ef372
56 #define H3 0xa54ff53a
57 #define H4 0x510e527f
58 #define H5 0x9b05688c
59 #define H6 0x1f83d9ab
60 #define H7 0x5be0cd19
61
62 static inline void LOAD_OP(int I, u32 *W, const u8 *input)
63 {
64 W[I] = ntohl( ((u32*)(input))[I] );
65 }
66
67 static inline void BLEND_OP(int I, u32 *W)
68 {
69 W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
70 }
71
72 static void sha256_transform(u32 *state, const u8 *input)
73 {
74 u32 a, b, c, d, e, f, g, h, t1, t2;
75 u32 W[64];
76 int i;
77
78 /* load the input */
79 for (i = 0; i < 16; i++)
80 LOAD_OP(i, W, input);
81
82 /* now blend */
83 for (i = 16; i < 64; i++)
84 BLEND_OP(i, W);
85
86 /* load the state into our registers */
87 a=state[0]; b=state[1]; c=state[2]; d=state[3];
88 e=state[4]; f=state[5]; g=state[6]; h=state[7];
89
90 /* now iterate */
91 t1 = h + e1(e) + Ch(e,f,g) + 0x428a2f98 + W[ 0];
92 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
93 t1 = g + e1(d) + Ch(d,e,f) + 0x71374491 + W[ 1];
94 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
95 t1 = f + e1(c) + Ch(c,d,e) + 0xb5c0fbcf + W[ 2];
96 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
97 t1 = e + e1(b) + Ch(b,c,d) + 0xe9b5dba5 + W[ 3];
98 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
99 t1 = d + e1(a) + Ch(a,b,c) + 0x3956c25b + W[ 4];
100 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
101 t1 = c + e1(h) + Ch(h,a,b) + 0x59f111f1 + W[ 5];
102 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
103 t1 = b + e1(g) + Ch(g,h,a) + 0x923f82a4 + W[ 6];
104 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
105 t1 = a + e1(f) + Ch(f,g,h) + 0xab1c5ed5 + W[ 7];
106 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
107
108 t1 = h + e1(e) + Ch(e,f,g) + 0xd807aa98 + W[ 8];
109 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
110 t1 = g + e1(d) + Ch(d,e,f) + 0x12835b01 + W[ 9];
111 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
112 t1 = f + e1(c) + Ch(c,d,e) + 0x243185be + W[10];
113 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
114 t1 = e + e1(b) + Ch(b,c,d) + 0x550c7dc3 + W[11];
115 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
116 t1 = d + e1(a) + Ch(a,b,c) + 0x72be5d74 + W[12];
117 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
118 t1 = c + e1(h) + Ch(h,a,b) + 0x80deb1fe + W[13];
119 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
120 t1 = b + e1(g) + Ch(g,h,a) + 0x9bdc06a7 + W[14];
121 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
122 t1 = a + e1(f) + Ch(f,g,h) + 0xc19bf174 + W[15];
123 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
124
125 t1 = h + e1(e) + Ch(e,f,g) + 0xe49b69c1 + W[16];
126 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
127 t1 = g + e1(d) + Ch(d,e,f) + 0xefbe4786 + W[17];
128 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
129 t1 = f + e1(c) + Ch(c,d,e) + 0x0fc19dc6 + W[18];
130 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
131 t1 = e + e1(b) + Ch(b,c,d) + 0x240ca1cc + W[19];
132 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
133 t1 = d + e1(a) + Ch(a,b,c) + 0x2de92c6f + W[20];
134 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
135 t1 = c + e1(h) + Ch(h,a,b) + 0x4a7484aa + W[21];
136 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
137 t1 = b + e1(g) + Ch(g,h,a) + 0x5cb0a9dc + W[22];
138 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
139 t1 = a + e1(f) + Ch(f,g,h) + 0x76f988da + W[23];
140 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
141
142 t1 = h + e1(e) + Ch(e,f,g) + 0x983e5152 + W[24];
143 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
144 t1 = g + e1(d) + Ch(d,e,f) + 0xa831c66d + W[25];
145 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
146 t1 = f + e1(c) + Ch(c,d,e) + 0xb00327c8 + W[26];
147 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
148 t1 = e + e1(b) + Ch(b,c,d) + 0xbf597fc7 + W[27];
149 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
150 t1 = d + e1(a) + Ch(a,b,c) + 0xc6e00bf3 + W[28];
151 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
152 t1 = c + e1(h) + Ch(h,a,b) + 0xd5a79147 + W[29];
153 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
154 t1 = b + e1(g) + Ch(g,h,a) + 0x06ca6351 + W[30];
155 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
156 t1 = a + e1(f) + Ch(f,g,h) + 0x14292967 + W[31];
157 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
158
159 t1 = h + e1(e) + Ch(e,f,g) + 0x27b70a85 + W[32];
160 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
161 t1 = g + e1(d) + Ch(d,e,f) + 0x2e1b2138 + W[33];
162 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
163 t1 = f + e1(c) + Ch(c,d,e) + 0x4d2c6dfc + W[34];
164 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
165 t1 = e + e1(b) + Ch(b,c,d) + 0x53380d13 + W[35];
166 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
167 t1 = d + e1(a) + Ch(a,b,c) + 0x650a7354 + W[36];
168 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
169 t1 = c + e1(h) + Ch(h,a,b) + 0x766a0abb + W[37];
170 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
171 t1 = b + e1(g) + Ch(g,h,a) + 0x81c2c92e + W[38];
172 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
173 t1 = a + e1(f) + Ch(f,g,h) + 0x92722c85 + W[39];
174 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
175
176 t1 = h + e1(e) + Ch(e,f,g) + 0xa2bfe8a1 + W[40];
177 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
178 t1 = g + e1(d) + Ch(d,e,f) + 0xa81a664b + W[41];
179 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
180 t1 = f + e1(c) + Ch(c,d,e) + 0xc24b8b70 + W[42];
181 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
182 t1 = e + e1(b) + Ch(b,c,d) + 0xc76c51a3 + W[43];
183 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
184 t1 = d + e1(a) + Ch(a,b,c) + 0xd192e819 + W[44];
185 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
186 t1 = c + e1(h) + Ch(h,a,b) + 0xd6990624 + W[45];
187 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
188 t1 = b + e1(g) + Ch(g,h,a) + 0xf40e3585 + W[46];
189 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
190 t1 = a + e1(f) + Ch(f,g,h) + 0x106aa070 + W[47];
191 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
192
193 t1 = h + e1(e) + Ch(e,f,g) + 0x19a4c116 + W[48];
194 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
195 t1 = g + e1(d) + Ch(d,e,f) + 0x1e376c08 + W[49];
196 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
197 t1 = f + e1(c) + Ch(c,d,e) + 0x2748774c + W[50];
198 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
199 t1 = e + e1(b) + Ch(b,c,d) + 0x34b0bcb5 + W[51];
200 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
201 t1 = d + e1(a) + Ch(a,b,c) + 0x391c0cb3 + W[52];
202 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
203 t1 = c + e1(h) + Ch(h,a,b) + 0x4ed8aa4a + W[53];
204 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
205 t1 = b + e1(g) + Ch(g,h,a) + 0x5b9cca4f + W[54];
206 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
207 t1 = a + e1(f) + Ch(f,g,h) + 0x682e6ff3 + W[55];
208 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
209
210 t1 = h + e1(e) + Ch(e,f,g) + 0x748f82ee + W[56];
211 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
212 t1 = g + e1(d) + Ch(d,e,f) + 0x78a5636f + W[57];
213 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
214 t1 = f + e1(c) + Ch(c,d,e) + 0x84c87814 + W[58];
215 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
216 t1 = e + e1(b) + Ch(b,c,d) + 0x8cc70208 + W[59];
217 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
218 t1 = d + e1(a) + Ch(a,b,c) + 0x90befffa + W[60];
219 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
220 t1 = c + e1(h) + Ch(h,a,b) + 0xa4506ceb + W[61];
221 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
222 t1 = b + e1(g) + Ch(g,h,a) + 0xbef9a3f7 + W[62];
223 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
224 t1 = a + e1(f) + Ch(f,g,h) + 0xc67178f2 + W[63];
225 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
226
227 state[0] += a; state[1] += b; state[2] += c; state[3] += d;
228 state[4] += e; state[5] += f; state[6] += g; state[7] += h;
229
230 /* clear any sensitive info... */
231 a = b = c = d = e = f = g = h = t1 = t2 = 0;
232 memset(W, 0, 64 * sizeof(u32));
233 }
234
235 SHA256Summation::SHA256Summation()
236 {
237 Sum.state[0] = H0;
238 Sum.state[1] = H1;
239 Sum.state[2] = H2;
240 Sum.state[3] = H3;
241 Sum.state[4] = H4;
242 Sum.state[5] = H5;
243 Sum.state[6] = H6;
244 Sum.state[7] = H7;
245 Sum.count[0] = Sum.count[1] = 0;
246 memset(Sum.buf, 0, sizeof(Sum.buf));
247 Done = false;
248 }
249
250 bool SHA256Summation::Add(const u8 *data, unsigned long len)
251 {
252 struct sha256_ctx *sctx = &Sum;
253 unsigned int i, index, part_len;
254
255 if (Done) return false;
256
257 /* Compute number of bytes mod 128 */
258 index = (unsigned int)((sctx->count[0] >> 3) & 0x3f);
259
260 /* Update number of bits */
261 if ((sctx->count[0] += (len << 3)) < (len << 3)) {
262 sctx->count[1]++;
263 sctx->count[1] += (len >> 29);
264 }
265
266 part_len = 64 - index;
267
268 /* Transform as many times as possible. */
269 if (len >= part_len) {
270 memcpy(&sctx->buf[index], data, part_len);
271 sha256_transform(sctx->state, sctx->buf);
272
273 for (i = part_len; i + 63 < len; i += 64)
274 sha256_transform(sctx->state, &data[i]);
275 index = 0;
276 } else {
277 i = 0;
278 }
279
280 /* Buffer remaining input */
281 memcpy(&sctx->buf[index], &data[i], len-i);
282
283 return true;
284 }
285
286 SHA256SumValue SHA256Summation::Result()
287 {
288 struct sha256_ctx *sctx = &Sum;
289 if (!Done) {
290 u8 bits[8];
291 unsigned int index, pad_len, t;
292 static const u8 padding[64] = { 0x80, };
293
294 /* Save number of bits */
295 t = sctx->count[0];
296 bits[7] = t; t >>= 8;
297 bits[6] = t; t >>= 8;
298 bits[5] = t; t >>= 8;
299 bits[4] = t;
300 t = sctx->count[1];
301 bits[3] = t; t >>= 8;
302 bits[2] = t; t >>= 8;
303 bits[1] = t; t >>= 8;
304 bits[0] = t;
305
306 /* Pad out to 56 mod 64. */
307 index = (sctx->count[0] >> 3) & 0x3f;
308 pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
309 Add(padding, pad_len);
310
311 /* Append length (before padding) */
312 Add(bits, 8);
313 }
314
315 Done = true;
316
317 /* Store state in digest */
318
319 SHA256SumValue res;
320 u8 *out = res.Sum;
321
322 int i, j;
323 unsigned int t;
324 for (i = j = 0; i < 8; i++, j += 4) {
325 t = sctx->state[i];
326 out[j+3] = t; t >>= 8;
327 out[j+2] = t; t >>= 8;
328 out[j+1] = t; t >>= 8;
329 out[j ] = t;
330 }
331
332 return res;
333 }
334
335 // SHA256SumValue::SHA256SumValue - Constructs the sum from a string /*{{{*/
336 // ---------------------------------------------------------------------
337 /* The string form of a SHA256 is a 64 character hex number */
338 SHA256SumValue::SHA256SumValue(string Str)
339 {
340 memset(Sum,0,sizeof(Sum));
341 Set(Str);
342 }
343
344 /*}}}*/
345 // SHA256SumValue::SHA256SumValue - Default constructor /*{{{*/
346 // ---------------------------------------------------------------------
347 /* Sets the value to 0 */
348 SHA256SumValue::SHA256SumValue()
349 {
350 memset(Sum,0,sizeof(Sum));
351 }
352
353 /*}}}*/
354 // SHA256SumValue::Set - Set the sum from a string /*{{{*/
355 // ---------------------------------------------------------------------
356 /* Converts the hex string into a set of chars */
357 bool SHA256SumValue::Set(string Str)
358 {
359 return Hex2Num(Str,Sum,sizeof(Sum));
360 }
361 /*}}}*/
362 // SHA256SumValue::Value - Convert the number into a string /*{{{*/
363 // ---------------------------------------------------------------------
364 /* Converts the set of chars into a hex string in lower case */
365 string SHA256SumValue::Value() const
366 {
367 char Conv[16] =
368 { '0','1','2','3','4','5','6','7','8','9','a','b',
369 'c','d','e','f'
370 };
371 char Result[65];
372 Result[64] = 0;
373
374 // Convert each char into two letters
375 int J = 0;
376 int I = 0;
377 for (; I != 64; J++,I += 2)
378 {
379 Result[I] = Conv[Sum[J] >> 4];
380 Result[I + 1] = Conv[Sum[J] & 0xF];
381 }
382
383 return string(Result);
384 }
385
386
387
388 // SHA256SumValue::operator == - Comparator /*{{{*/
389 // ---------------------------------------------------------------------
390 /* Call memcmp on the buffer */
391 bool SHA256SumValue::operator == (const SHA256SumValue & rhs) const
392 {
393 return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0;
394 }
395 /*}}}*/
396
397
398 // SHA256Summation::AddFD - Add content of file into the checksum /*{{{*/
399 // ---------------------------------------------------------------------
400 /* */
401 bool SHA256Summation::AddFD(int Fd,unsigned long Size)
402 {
403 unsigned char Buf[64 * 64];
404 int Res = 0;
405 int ToEOF = (Size == 0);
406 while (Size != 0 || ToEOF)
407 {
408 unsigned n = sizeof(Buf);
409 if (!ToEOF) n = min(Size,(unsigned long)n);
410 Res = read(Fd,Buf,n);
411 if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read
412 return false;
413 if (ToEOF && Res == 0) // EOF
414 break;
415 Size -= Res;
416 Add(Buf,Res);
417 }
418 return true;
419 }
420 /*}}}*/
421