00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <string.h>
00025 #include "avutil.h"
00026 #include "bswap.h"
00027 #include "sha.h"
00028 #include "intreadwrite.h"
00029
00031 typedef struct AVSHA {
00032 uint8_t digest_len;
00033 uint64_t count;
00034 uint8_t buffer[64];
00035 uint32_t state[8];
00036
00037 void (*transform)(uint32_t *state, const uint8_t buffer[64]);
00038 } AVSHA;
00039
00040 const int av_sha_size = sizeof(AVSHA);
00041
00042 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
00043
00044
00045 #define blk0(i) (block[i] = AV_RB32(buffer + 4 * (i)))
00046 #define blk(i) (block[i] = rol(block[i-3] ^ block[i-8] ^ block[i-14] ^ block[i-16], 1))
00047
00048 #define R0(v,w,x,y,z,i) z += ((w&(x^y))^y) + blk0(i) + 0x5A827999 + rol(v, 5); w = rol(w, 30);
00049 #define R1(v,w,x,y,z,i) z += ((w&(x^y))^y) + blk (i) + 0x5A827999 + rol(v, 5); w = rol(w, 30);
00050 #define R2(v,w,x,y,z,i) z += ( w^x ^y) + blk (i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
00051 #define R3(v,w,x,y,z,i) z += (((w|x)&y)|(w&x)) + blk (i) + 0x8F1BBCDC + rol(v, 5); w = rol(w, 30);
00052 #define R4(v,w,x,y,z,i) z += ( w^x ^y) + blk (i) + 0xCA62C1D6 + rol(v, 5); w = rol(w, 30);
00053
00054
00055
00056 static void sha1_transform(uint32_t state[5], const uint8_t buffer[64])
00057 {
00058 uint32_t block[80];
00059 unsigned int i, a, b, c, d, e;
00060
00061 a = state[0];
00062 b = state[1];
00063 c = state[2];
00064 d = state[3];
00065 e = state[4];
00066 #if CONFIG_SMALL
00067 for (i = 0; i < 80; i++) {
00068 int t;
00069 if (i < 16)
00070 t = AV_RB32(buffer + 4 * i);
00071 else
00072 t = rol(block[i-3] ^ block[i-8] ^ block[i-14] ^ block[i-16], 1);
00073 block[i] = t;
00074 t += e + rol(a, 5);
00075 if (i < 40) {
00076 if (i < 20)
00077 t += ((b&(c^d))^d) + 0x5A827999;
00078 else
00079 t += ( b^c ^d) + 0x6ED9EBA1;
00080 } else {
00081 if (i < 60)
00082 t += (((b|c)&d)|(b&c)) + 0x8F1BBCDC;
00083 else
00084 t += ( b^c ^d) + 0xCA62C1D6;
00085 }
00086 e = d;
00087 d = c;
00088 c = rol(b, 30);
00089 b = a;
00090 a = t;
00091 }
00092 #else
00093 for (i = 0; i < 15; i += 5) {
00094 R0(a, b, c, d, e, 0 + i);
00095 R0(e, a, b, c, d, 1 + i);
00096 R0(d, e, a, b, c, 2 + i);
00097 R0(c, d, e, a, b, 3 + i);
00098 R0(b, c, d, e, a, 4 + i);
00099 }
00100 R0(a, b, c, d, e, 15);
00101 R1(e, a, b, c, d, 16);
00102 R1(d, e, a, b, c, 17);
00103 R1(c, d, e, a, b, 18);
00104 R1(b, c, d, e, a, 19);
00105 for (i = 20; i < 40; i += 5) {
00106 R2(a, b, c, d, e, 0 + i);
00107 R2(e, a, b, c, d, 1 + i);
00108 R2(d, e, a, b, c, 2 + i);
00109 R2(c, d, e, a, b, 3 + i);
00110 R2(b, c, d, e, a, 4 + i);
00111 }
00112 for (; i < 60; i += 5) {
00113 R3(a, b, c, d, e, 0 + i);
00114 R3(e, a, b, c, d, 1 + i);
00115 R3(d, e, a, b, c, 2 + i);
00116 R3(c, d, e, a, b, 3 + i);
00117 R3(b, c, d, e, a, 4 + i);
00118 }
00119 for (; i < 80; i += 5) {
00120 R4(a, b, c, d, e, 0 + i);
00121 R4(e, a, b, c, d, 1 + i);
00122 R4(d, e, a, b, c, 2 + i);
00123 R4(c, d, e, a, b, 3 + i);
00124 R4(b, c, d, e, a, 4 + i);
00125 }
00126 #endif
00127 state[0] += a;
00128 state[1] += b;
00129 state[2] += c;
00130 state[3] += d;
00131 state[4] += e;
00132 }
00133
00134 static const uint32_t K256[64] = {
00135 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
00136 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00137 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
00138 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00139 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
00140 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00141 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
00142 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00143 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
00144 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00145 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
00146 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00147 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
00148 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00149 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
00150 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
00151 };
00152
00153
00154 #define Ch(x,y,z) (((x) & ((y) ^ (z))) ^ (z))
00155 #define Maj(x,y,z) ((((x) | (y)) & (z)) | ((x) & (y)))
00156
00157 #define Sigma0_256(x) (rol((x), 30) ^ rol((x), 19) ^ rol((x), 10))
00158 #define Sigma1_256(x) (rol((x), 26) ^ rol((x), 21) ^ rol((x), 7))
00159 #define sigma0_256(x) (rol((x), 25) ^ rol((x), 14) ^ ((x) >> 3))
00160 #define sigma1_256(x) (rol((x), 15) ^ rol((x), 13) ^ ((x) >> 10))
00161
00162 #undef blk
00163 #define blk(i) (block[i] = block[i - 16] + sigma0_256(block[i - 15]) + \
00164 sigma1_256(block[i - 2]) + block[i - 7])
00165
00166 #define ROUND256(a,b,c,d,e,f,g,h) \
00167 T1 += (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[i]; \
00168 (d) += T1; \
00169 (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
00170 i++
00171
00172 #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
00173 T1 = blk0(i); \
00174 ROUND256(a,b,c,d,e,f,g,h)
00175
00176 #define ROUND256_16_TO_63(a,b,c,d,e,f,g,h) \
00177 T1 = blk(i); \
00178 ROUND256(a,b,c,d,e,f,g,h)
00179
00180 static void sha256_transform(uint32_t *state, const uint8_t buffer[64])
00181 {
00182 unsigned int i, a, b, c, d, e, f, g, h;
00183 uint32_t block[64];
00184 uint32_t T1;
00185
00186 a = state[0];
00187 b = state[1];
00188 c = state[2];
00189 d = state[3];
00190 e = state[4];
00191 f = state[5];
00192 g = state[6];
00193 h = state[7];
00194 #if CONFIG_SMALL
00195 for (i = 0; i < 64; i++) {
00196 uint32_t T2;
00197 if (i < 16)
00198 T1 = blk0(i);
00199 else
00200 T1 = blk(i);
00201 T1 += h + Sigma1_256(e) + Ch(e, f, g) + K256[i];
00202 T2 = Sigma0_256(a) + Maj(a, b, c);
00203 h = g;
00204 g = f;
00205 f = e;
00206 e = d + T1;
00207 d = c;
00208 c = b;
00209 b = a;
00210 a = T1 + T2;
00211 }
00212 #else
00213 for (i = 0; i < 16;) {
00214 ROUND256_0_TO_15(a, b, c, d, e, f, g, h);
00215 ROUND256_0_TO_15(h, a, b, c, d, e, f, g);
00216 ROUND256_0_TO_15(g, h, a, b, c, d, e, f);
00217 ROUND256_0_TO_15(f, g, h, a, b, c, d, e);
00218 ROUND256_0_TO_15(e, f, g, h, a, b, c, d);
00219 ROUND256_0_TO_15(d, e, f, g, h, a, b, c);
00220 ROUND256_0_TO_15(c, d, e, f, g, h, a, b);
00221 ROUND256_0_TO_15(b, c, d, e, f, g, h, a);
00222 }
00223
00224 for (; i < 64;) {
00225 ROUND256_16_TO_63(a, b, c, d, e, f, g, h);
00226 ROUND256_16_TO_63(h, a, b, c, d, e, f, g);
00227 ROUND256_16_TO_63(g, h, a, b, c, d, e, f);
00228 ROUND256_16_TO_63(f, g, h, a, b, c, d, e);
00229 ROUND256_16_TO_63(e, f, g, h, a, b, c, d);
00230 ROUND256_16_TO_63(d, e, f, g, h, a, b, c);
00231 ROUND256_16_TO_63(c, d, e, f, g, h, a, b);
00232 ROUND256_16_TO_63(b, c, d, e, f, g, h, a);
00233 }
00234 #endif
00235 state[0] += a;
00236 state[1] += b;
00237 state[2] += c;
00238 state[3] += d;
00239 state[4] += e;
00240 state[5] += f;
00241 state[6] += g;
00242 state[7] += h;
00243 }
00244
00245
00246 int av_sha_init(AVSHA* ctx, int bits)
00247 {
00248 ctx->digest_len = bits >> 5;
00249 switch (bits) {
00250 case 160:
00251 ctx->state[0] = 0x67452301;
00252 ctx->state[1] = 0xEFCDAB89;
00253 ctx->state[2] = 0x98BADCFE;
00254 ctx->state[3] = 0x10325476;
00255 ctx->state[4] = 0xC3D2E1F0;
00256 ctx->transform = sha1_transform;
00257 break;
00258 case 224:
00259 ctx->state[0] = 0xC1059ED8;
00260 ctx->state[1] = 0x367CD507;
00261 ctx->state[2] = 0x3070DD17;
00262 ctx->state[3] = 0xF70E5939;
00263 ctx->state[4] = 0xFFC00B31;
00264 ctx->state[5] = 0x68581511;
00265 ctx->state[6] = 0x64F98FA7;
00266 ctx->state[7] = 0xBEFA4FA4;
00267 ctx->transform = sha256_transform;
00268 break;
00269 case 256:
00270 ctx->state[0] = 0x6A09E667;
00271 ctx->state[1] = 0xBB67AE85;
00272 ctx->state[2] = 0x3C6EF372;
00273 ctx->state[3] = 0xA54FF53A;
00274 ctx->state[4] = 0x510E527F;
00275 ctx->state[5] = 0x9B05688C;
00276 ctx->state[6] = 0x1F83D9AB;
00277 ctx->state[7] = 0x5BE0CD19;
00278 ctx->transform = sha256_transform;
00279 break;
00280 default:
00281 return -1;
00282 }
00283 ctx->count = 0;
00284 return 0;
00285 }
00286
00287 void av_sha_update(AVSHA* ctx, const uint8_t* data, unsigned int len)
00288 {
00289 unsigned int i, j;
00290
00291 j = ctx->count & 63;
00292 ctx->count += len;
00293 #if CONFIG_SMALL
00294 for (i = 0; i < len; i++) {
00295 ctx->buffer[j++] = data[i];
00296 if (64 == j) {
00297 ctx->transform(ctx->state, ctx->buffer);
00298 j = 0;
00299 }
00300 }
00301 #else
00302 if ((j + len) > 63) {
00303 memcpy(&ctx->buffer[j], data, (i = 64 - j));
00304 ctx->transform(ctx->state, ctx->buffer);
00305 for (; i + 63 < len; i += 64)
00306 ctx->transform(ctx->state, &data[i]);
00307 j = 0;
00308 } else
00309 i = 0;
00310 memcpy(&ctx->buffer[j], &data[i], len - i);
00311 #endif
00312 }
00313
00314 void av_sha_final(AVSHA* ctx, uint8_t *digest)
00315 {
00316 int i;
00317 uint64_t finalcount = av_be2ne64(ctx->count << 3);
00318
00319 av_sha_update(ctx, "\200", 1);
00320 while ((ctx->count & 63) != 56)
00321 av_sha_update(ctx, "", 1);
00322 av_sha_update(ctx, (uint8_t *)&finalcount, 8);
00323 for (i = 0; i < ctx->digest_len; i++)
00324 AV_WB32(digest + i*4, ctx->state[i]);
00325 }
00326
00327 #ifdef TEST
00328 #include <stdio.h>
00329 #undef printf
00330
00331 int main(void)
00332 {
00333 int i, j, k;
00334 AVSHA ctx;
00335 unsigned char digest[32];
00336 const int lengths[3] = { 160, 224, 256 };
00337
00338 for (j = 0; j < 3; j++) {
00339 printf("Testing SHA-%d\n", lengths[j]);
00340 for (k = 0; k < 3; k++) {
00341 av_sha_init(&ctx, lengths[j]);
00342 if (k == 0)
00343 av_sha_update(&ctx, "abc", 3);
00344 else if (k == 1)
00345 av_sha_update(&ctx, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56);
00346 else
00347 for (i = 0; i < 1000*1000; i++)
00348 av_sha_update(&ctx, "a", 1);
00349 av_sha_final(&ctx, digest);
00350 for (i = 0; i < lengths[j] >> 3; i++)
00351 printf("%02X", digest[i]);
00352 putchar('\n');
00353 }
00354 switch (j) {
00355 case 0:
00356
00357 printf("A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D\n"
00358 "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1\n"
00359 "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F\n");
00360 break;
00361 case 1:
00362
00363 printf("23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7\n"
00364 "75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525\n"
00365 "20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67\n");
00366 break;
00367 case 2:
00368
00369 printf("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad\n"
00370 "248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1\n"
00371 "cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0\n");
00372 break;
00373 }
00374 }
00375
00376 return 0;
00377 }
00378 #endif