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_be2ne32(((const uint32_t*)buffer)[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_be2ne32(((uint32_t*)buffer)[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, av_unused(T2);
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 if (i < 16)
00197 T1 = blk0(i);
00198 else
00199 T1 = blk(i);
00200 T1 += h + Sigma1_256(e) + Ch(e, f, g) + K256[i];
00201 T2 = Sigma0_256(a) + Maj(a, b, c);
00202 h = g;
00203 g = f;
00204 f = e;
00205 e = d + T1;
00206 d = c;
00207 c = b;
00208 b = a;
00209 a = T1 + T2;
00210 }
00211 #else
00212 for (i = 0; i < 16;) {
00213 ROUND256_0_TO_15(a, b, c, d, e, f, g, h);
00214 ROUND256_0_TO_15(h, a, b, c, d, e, f, g);
00215 ROUND256_0_TO_15(g, h, a, b, c, d, e, f);
00216 ROUND256_0_TO_15(f, g, h, a, b, c, d, e);
00217 ROUND256_0_TO_15(e, f, g, h, a, b, c, d);
00218 ROUND256_0_TO_15(d, e, f, g, h, a, b, c);
00219 ROUND256_0_TO_15(c, d, e, f, g, h, a, b);
00220 ROUND256_0_TO_15(b, c, d, e, f, g, h, a);
00221 }
00222
00223 for (; i < 64;) {
00224 ROUND256_16_TO_63(a, b, c, d, e, f, g, h);
00225 ROUND256_16_TO_63(h, a, b, c, d, e, f, g);
00226 ROUND256_16_TO_63(g, h, a, b, c, d, e, f);
00227 ROUND256_16_TO_63(f, g, h, a, b, c, d, e);
00228 ROUND256_16_TO_63(e, f, g, h, a, b, c, d);
00229 ROUND256_16_TO_63(d, e, f, g, h, a, b, c);
00230 ROUND256_16_TO_63(c, d, e, f, g, h, a, b);
00231 ROUND256_16_TO_63(b, c, d, e, f, g, h, a);
00232 }
00233 #endif
00234 state[0] += a;
00235 state[1] += b;
00236 state[2] += c;
00237 state[3] += d;
00238 state[4] += e;
00239 state[5] += f;
00240 state[6] += g;
00241 state[7] += h;
00242 }
00243
00244
00245 int av_sha_init(AVSHA* ctx, int bits)
00246 {
00247 ctx->digest_len = bits >> 5;
00248 switch (bits) {
00249 case 160:
00250 ctx->state[0] = 0x67452301;
00251 ctx->state[1] = 0xEFCDAB89;
00252 ctx->state[2] = 0x98BADCFE;
00253 ctx->state[3] = 0x10325476;
00254 ctx->state[4] = 0xC3D2E1F0;
00255 ctx->transform = sha1_transform;
00256 break;
00257 case 224:
00258 ctx->state[0] = 0xC1059ED8;
00259 ctx->state[1] = 0x367CD507;
00260 ctx->state[2] = 0x3070DD17;
00261 ctx->state[3] = 0xF70E5939;
00262 ctx->state[4] = 0xFFC00B31;
00263 ctx->state[5] = 0x68581511;
00264 ctx->state[6] = 0x64F98FA7;
00265 ctx->state[7] = 0xBEFA4FA4;
00266 ctx->transform = sha256_transform;
00267 break;
00268 case 256:
00269 ctx->state[0] = 0x6A09E667;
00270 ctx->state[1] = 0xBB67AE85;
00271 ctx->state[2] = 0x3C6EF372;
00272 ctx->state[3] = 0xA54FF53A;
00273 ctx->state[4] = 0x510E527F;
00274 ctx->state[5] = 0x9B05688C;
00275 ctx->state[6] = 0x1F83D9AB;
00276 ctx->state[7] = 0x5BE0CD19;
00277 ctx->transform = sha256_transform;
00278 break;
00279 default:
00280 return -1;
00281 }
00282 ctx->count = 0;
00283 return 0;
00284 }
00285
00286 void av_sha_update(AVSHA* ctx, const uint8_t* data, unsigned int len)
00287 {
00288 unsigned int i, j;
00289
00290 j = ctx->count & 63;
00291 ctx->count += len;
00292 #if CONFIG_SMALL
00293 for (i = 0; i < len; i++) {
00294 ctx->buffer[j++] = data[i];
00295 if (64 == j) {
00296 ctx->transform(ctx->state, ctx->buffer);
00297 j = 0;
00298 }
00299 }
00300 #else
00301 if ((j + len) > 63) {
00302 memcpy(&ctx->buffer[j], data, (i = 64 - j));
00303 ctx->transform(ctx->state, ctx->buffer);
00304 for (; i + 63 < len; i += 64)
00305 ctx->transform(ctx->state, &data[i]);
00306 j = 0;
00307 } else
00308 i = 0;
00309 memcpy(&ctx->buffer[j], &data[i], len - i);
00310 #endif
00311 }
00312
00313 void av_sha_final(AVSHA* ctx, uint8_t *digest)
00314 {
00315 int i;
00316 uint64_t finalcount = av_be2ne64(ctx->count << 3);
00317
00318 av_sha_update(ctx, "\200", 1);
00319 while ((ctx->count & 63) != 56)
00320 av_sha_update(ctx, "", 1);
00321 av_sha_update(ctx, (uint8_t *)&finalcount, 8);
00322 for (i = 0; i < ctx->digest_len; i++)
00323 AV_WB32(digest + i*4, ctx->state[i]);
00324 }
00325
00326 #ifdef TEST
00327 #include <stdio.h>
00328 #undef printf
00329
00330 int main(void)
00331 {
00332 int i, j, k;
00333 AVSHA ctx;
00334 unsigned char digest[32];
00335 const int lengths[3] = { 160, 224, 256 };
00336
00337 for (j = 0; j < 3; j++) {
00338 printf("Testing SHA-%d\n", lengths[j]);
00339 for (k = 0; k < 3; k++) {
00340 av_sha_init(&ctx, lengths[j]);
00341 if (k == 0)
00342 av_sha_update(&ctx, "abc", 3);
00343 else if (k == 1)
00344 av_sha_update(&ctx, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56);
00345 else
00346 for (i = 0; i < 1000*1000; i++)
00347 av_sha_update(&ctx, "a", 1);
00348 av_sha_final(&ctx, digest);
00349 for (i = 0; i < lengths[j] >> 3; i++)
00350 printf("%02X", digest[i]);
00351 putchar('\n');
00352 }
00353 switch (j) {
00354 case 0:
00355
00356 printf("A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D\n"
00357 "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1\n"
00358 "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F\n");
00359 break;
00360 case 1:
00361
00362 printf("23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7\n"
00363 "75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525\n"
00364 "20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67\n");
00365 break;
00366 case 2:
00367
00368 printf("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad\n"
00369 "248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1\n"
00370 "cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0\n");
00371 break;
00372 }
00373 }
00374
00375 return 0;
00376 }
00377 #endif