• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavutil/sha.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
00003  * Copyright (C) 2009 Konstantin Shishkov
00004  * based on public domain SHA-1 code by Steve Reid <steve@edmweb.com>
00005  * and on BSD-licensed SHA-2 code by Aaron D. Gifford
00006  *
00007  * This file is part of Libav.
00008  *
00009  * Libav is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  * Libav is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with Libav; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
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 /* Hash a single 512-bit block. This is the core of the algorithm. */
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, 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: // SHA-1
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: // SHA-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: // SHA-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); /* Should cause a transform() */
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             //test vectors (from FIPS PUB 180-1)
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             //test vectors (from FIPS PUB 180-2 Appendix A)
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             //test vectors (from FIPS PUB 180-2)
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
Generated on Sat Mar 17 2012 12:57:58 for Libav by doxygen 1.7.1