Annotation of elwix/tools/uboot_mkimage/lib/sha1.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  *  Heiko Schocher, DENX Software Engineering, hs@denx.de.
        !             3:  *  based on:
        !             4:  *  FIPS-180-1 compliant SHA-1 implementation
        !             5:  *
        !             6:  *  Copyright (C) 2003-2006  Christophe Devine
        !             7:  *
        !             8:  *  This library is free software; you can redistribute it and/or
        !             9:  *  modify it under the terms of the GNU Lesser General Public
        !            10:  *  License, version 2.1 as published by the Free Software Foundation.
        !            11:  *
        !            12:  *  This library is distributed in the hope that it will be useful,
        !            13:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            15:  *  Lesser General Public License for more details.
        !            16:  *
        !            17:  *  You should have received a copy of the GNU Lesser General Public
        !            18:  *  License along with this library; if not, write to the Free Software
        !            19:  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
        !            20:  *  MA  02110-1301  USA
        !            21:  */
        !            22: /*
        !            23:  *  The SHA-1 standard was published by NIST in 1993.
        !            24:  *
        !            25:  *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
        !            26:  */
        !            27: 
        !            28: #ifndef _CRT_SECURE_NO_DEPRECATE
        !            29: #define _CRT_SECURE_NO_DEPRECATE 1
        !            30: #endif
        !            31: 
        !            32: #ifndef USE_HOSTCC
        !            33: #include <common.h>
        !            34: #include <linux/string.h>
        !            35: #else
        !            36: #include <string.h>
        !            37: #endif /* USE_HOSTCC */
        !            38: #include <watchdog.h>
        !            39: #include "sha1.h"
        !            40: 
        !            41: /*
        !            42:  * 32-bit integer manipulation macros (big endian)
        !            43:  */
        !            44: #ifndef GET_UINT32_BE
        !            45: #define GET_UINT32_BE(n,b,i) {                         \
        !            46:        (n) = ( (unsigned long) (b)[(i)    ] << 24 )    \
        !            47:            | ( (unsigned long) (b)[(i) + 1] << 16 )    \
        !            48:            | ( (unsigned long) (b)[(i) + 2] <<  8 )    \
        !            49:            | ( (unsigned long) (b)[(i) + 3]       );   \
        !            50: }
        !            51: #endif
        !            52: #ifndef PUT_UINT32_BE
        !            53: #define PUT_UINT32_BE(n,b,i) {                         \
        !            54:        (b)[(i)    ] = (unsigned char) ( (n) >> 24 );   \
        !            55:        (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );   \
        !            56:        (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );   \
        !            57:        (b)[(i) + 3] = (unsigned char) ( (n)       );   \
        !            58: }
        !            59: #endif
        !            60: 
        !            61: /*
        !            62:  * SHA-1 context setup
        !            63:  */
        !            64: void sha1_starts (sha1_context * ctx)
        !            65: {
        !            66:        ctx->total[0] = 0;
        !            67:        ctx->total[1] = 0;
        !            68: 
        !            69:        ctx->state[0] = 0x67452301;
        !            70:        ctx->state[1] = 0xEFCDAB89;
        !            71:        ctx->state[2] = 0x98BADCFE;
        !            72:        ctx->state[3] = 0x10325476;
        !            73:        ctx->state[4] = 0xC3D2E1F0;
        !            74: }
        !            75: 
        !            76: static void sha1_process (sha1_context * ctx, unsigned char data[64])
        !            77: {
        !            78:        unsigned long temp, W[16], A, B, C, D, E;
        !            79: 
        !            80:        GET_UINT32_BE (W[0], data, 0);
        !            81:        GET_UINT32_BE (W[1], data, 4);
        !            82:        GET_UINT32_BE (W[2], data, 8);
        !            83:        GET_UINT32_BE (W[3], data, 12);
        !            84:        GET_UINT32_BE (W[4], data, 16);
        !            85:        GET_UINT32_BE (W[5], data, 20);
        !            86:        GET_UINT32_BE (W[6], data, 24);
        !            87:        GET_UINT32_BE (W[7], data, 28);
        !            88:        GET_UINT32_BE (W[8], data, 32);
        !            89:        GET_UINT32_BE (W[9], data, 36);
        !            90:        GET_UINT32_BE (W[10], data, 40);
        !            91:        GET_UINT32_BE (W[11], data, 44);
        !            92:        GET_UINT32_BE (W[12], data, 48);
        !            93:        GET_UINT32_BE (W[13], data, 52);
        !            94:        GET_UINT32_BE (W[14], data, 56);
        !            95:        GET_UINT32_BE (W[15], data, 60);
        !            96: 
        !            97: #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
        !            98: 
        !            99: #define R(t) (                                         \
        !           100:        temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
        !           101:               W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],  \
        !           102:        ( W[t & 0x0F] = S(temp,1) )                     \
        !           103: )
        !           104: 
        !           105: #define P(a,b,c,d,e,x) {                               \
        !           106:        e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);    \
        !           107: }
        !           108: 
        !           109:        A = ctx->state[0];
        !           110:        B = ctx->state[1];
        !           111:        C = ctx->state[2];
        !           112:        D = ctx->state[3];
        !           113:        E = ctx->state[4];
        !           114: 
        !           115: #define F(x,y,z) (z ^ (x & (y ^ z)))
        !           116: #define K 0x5A827999
        !           117: 
        !           118:        P (A, B, C, D, E, W[0]);
        !           119:        P (E, A, B, C, D, W[1]);
        !           120:        P (D, E, A, B, C, W[2]);
        !           121:        P (C, D, E, A, B, W[3]);
        !           122:        P (B, C, D, E, A, W[4]);
        !           123:        P (A, B, C, D, E, W[5]);
        !           124:        P (E, A, B, C, D, W[6]);
        !           125:        P (D, E, A, B, C, W[7]);
        !           126:        P (C, D, E, A, B, W[8]);
        !           127:        P (B, C, D, E, A, W[9]);
        !           128:        P (A, B, C, D, E, W[10]);
        !           129:        P (E, A, B, C, D, W[11]);
        !           130:        P (D, E, A, B, C, W[12]);
        !           131:        P (C, D, E, A, B, W[13]);
        !           132:        P (B, C, D, E, A, W[14]);
        !           133:        P (A, B, C, D, E, W[15]);
        !           134:        P (E, A, B, C, D, R (16));
        !           135:        P (D, E, A, B, C, R (17));
        !           136:        P (C, D, E, A, B, R (18));
        !           137:        P (B, C, D, E, A, R (19));
        !           138: 
        !           139: #undef K
        !           140: #undef F
        !           141: 
        !           142: #define F(x,y,z) (x ^ y ^ z)
        !           143: #define K 0x6ED9EBA1
        !           144: 
        !           145:        P (A, B, C, D, E, R (20));
        !           146:        P (E, A, B, C, D, R (21));
        !           147:        P (D, E, A, B, C, R (22));
        !           148:        P (C, D, E, A, B, R (23));
        !           149:        P (B, C, D, E, A, R (24));
        !           150:        P (A, B, C, D, E, R (25));
        !           151:        P (E, A, B, C, D, R (26));
        !           152:        P (D, E, A, B, C, R (27));
        !           153:        P (C, D, E, A, B, R (28));
        !           154:        P (B, C, D, E, A, R (29));
        !           155:        P (A, B, C, D, E, R (30));
        !           156:        P (E, A, B, C, D, R (31));
        !           157:        P (D, E, A, B, C, R (32));
        !           158:        P (C, D, E, A, B, R (33));
        !           159:        P (B, C, D, E, A, R (34));
        !           160:        P (A, B, C, D, E, R (35));
        !           161:        P (E, A, B, C, D, R (36));
        !           162:        P (D, E, A, B, C, R (37));
        !           163:        P (C, D, E, A, B, R (38));
        !           164:        P (B, C, D, E, A, R (39));
        !           165: 
        !           166: #undef K
        !           167: #undef F
        !           168: 
        !           169: #define F(x,y,z) ((x & y) | (z & (x | y)))
        !           170: #define K 0x8F1BBCDC
        !           171: 
        !           172:        P (A, B, C, D, E, R (40));
        !           173:        P (E, A, B, C, D, R (41));
        !           174:        P (D, E, A, B, C, R (42));
        !           175:        P (C, D, E, A, B, R (43));
        !           176:        P (B, C, D, E, A, R (44));
        !           177:        P (A, B, C, D, E, R (45));
        !           178:        P (E, A, B, C, D, R (46));
        !           179:        P (D, E, A, B, C, R (47));
        !           180:        P (C, D, E, A, B, R (48));
        !           181:        P (B, C, D, E, A, R (49));
        !           182:        P (A, B, C, D, E, R (50));
        !           183:        P (E, A, B, C, D, R (51));
        !           184:        P (D, E, A, B, C, R (52));
        !           185:        P (C, D, E, A, B, R (53));
        !           186:        P (B, C, D, E, A, R (54));
        !           187:        P (A, B, C, D, E, R (55));
        !           188:        P (E, A, B, C, D, R (56));
        !           189:        P (D, E, A, B, C, R (57));
        !           190:        P (C, D, E, A, B, R (58));
        !           191:        P (B, C, D, E, A, R (59));
        !           192: 
        !           193: #undef K
        !           194: #undef F
        !           195: 
        !           196: #define F(x,y,z) (x ^ y ^ z)
        !           197: #define K 0xCA62C1D6
        !           198: 
        !           199:        P (A, B, C, D, E, R (60));
        !           200:        P (E, A, B, C, D, R (61));
        !           201:        P (D, E, A, B, C, R (62));
        !           202:        P (C, D, E, A, B, R (63));
        !           203:        P (B, C, D, E, A, R (64));
        !           204:        P (A, B, C, D, E, R (65));
        !           205:        P (E, A, B, C, D, R (66));
        !           206:        P (D, E, A, B, C, R (67));
        !           207:        P (C, D, E, A, B, R (68));
        !           208:        P (B, C, D, E, A, R (69));
        !           209:        P (A, B, C, D, E, R (70));
        !           210:        P (E, A, B, C, D, R (71));
        !           211:        P (D, E, A, B, C, R (72));
        !           212:        P (C, D, E, A, B, R (73));
        !           213:        P (B, C, D, E, A, R (74));
        !           214:        P (A, B, C, D, E, R (75));
        !           215:        P (E, A, B, C, D, R (76));
        !           216:        P (D, E, A, B, C, R (77));
        !           217:        P (C, D, E, A, B, R (78));
        !           218:        P (B, C, D, E, A, R (79));
        !           219: 
        !           220: #undef K
        !           221: #undef F
        !           222: 
        !           223:        ctx->state[0] += A;
        !           224:        ctx->state[1] += B;
        !           225:        ctx->state[2] += C;
        !           226:        ctx->state[3] += D;
        !           227:        ctx->state[4] += E;
        !           228: }
        !           229: 
        !           230: /*
        !           231:  * SHA-1 process buffer
        !           232:  */
        !           233: void sha1_update (sha1_context * ctx, unsigned char *input, int ilen)
        !           234: {
        !           235:        int fill;
        !           236:        unsigned long left;
        !           237: 
        !           238:        if (ilen <= 0)
        !           239:                return;
        !           240: 
        !           241:        left = ctx->total[0] & 0x3F;
        !           242:        fill = 64 - left;
        !           243: 
        !           244:        ctx->total[0] += ilen;
        !           245:        ctx->total[0] &= 0xFFFFFFFF;
        !           246: 
        !           247:        if (ctx->total[0] < (unsigned long) ilen)
        !           248:                ctx->total[1]++;
        !           249: 
        !           250:        if (left && ilen >= fill) {
        !           251:                memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
        !           252:                sha1_process (ctx, ctx->buffer);
        !           253:                input += fill;
        !           254:                ilen -= fill;
        !           255:                left = 0;
        !           256:        }
        !           257: 
        !           258:        while (ilen >= 64) {
        !           259:                sha1_process (ctx, input);
        !           260:                input += 64;
        !           261:                ilen -= 64;
        !           262:        }
        !           263: 
        !           264:        if (ilen > 0) {
        !           265:                memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
        !           266:        }
        !           267: }
        !           268: 
        !           269: static const unsigned char sha1_padding[64] = {
        !           270:        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           271:           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           272:           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        !           273:           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        !           274: };
        !           275: 
        !           276: /*
        !           277:  * SHA-1 final digest
        !           278:  */
        !           279: void sha1_finish (sha1_context * ctx, unsigned char output[20])
        !           280: {
        !           281:        unsigned long last, padn;
        !           282:        unsigned long high, low;
        !           283:        unsigned char msglen[8];
        !           284: 
        !           285:        high = (ctx->total[0] >> 29)
        !           286:                | (ctx->total[1] << 3);
        !           287:        low = (ctx->total[0] << 3);
        !           288: 
        !           289:        PUT_UINT32_BE (high, msglen, 0);
        !           290:        PUT_UINT32_BE (low, msglen, 4);
        !           291: 
        !           292:        last = ctx->total[0] & 0x3F;
        !           293:        padn = (last < 56) ? (56 - last) : (120 - last);
        !           294: 
        !           295:        sha1_update (ctx, (unsigned char *) sha1_padding, padn);
        !           296:        sha1_update (ctx, msglen, 8);
        !           297: 
        !           298:        PUT_UINT32_BE (ctx->state[0], output, 0);
        !           299:        PUT_UINT32_BE (ctx->state[1], output, 4);
        !           300:        PUT_UINT32_BE (ctx->state[2], output, 8);
        !           301:        PUT_UINT32_BE (ctx->state[3], output, 12);
        !           302:        PUT_UINT32_BE (ctx->state[4], output, 16);
        !           303: }
        !           304: 
        !           305: /*
        !           306:  * Output = SHA-1( input buffer )
        !           307:  */
        !           308: void sha1_csum (unsigned char *input, int ilen, unsigned char output[20])
        !           309: {
        !           310:        sha1_context ctx;
        !           311: 
        !           312:        sha1_starts (&ctx);
        !           313:        sha1_update (&ctx, input, ilen);
        !           314:        sha1_finish (&ctx, output);
        !           315: }
        !           316: 
        !           317: /*
        !           318:  * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
        !           319:  * bytes of input processed.
        !           320:  */
        !           321: void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20],
        !           322:                        unsigned int chunk_sz)
        !           323: {
        !           324:        sha1_context ctx;
        !           325: #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
        !           326:        unsigned char *end, *curr;
        !           327:        int chunk;
        !           328: #endif
        !           329: 
        !           330:        sha1_starts (&ctx);
        !           331: 
        !           332: #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
        !           333:        curr = input;
        !           334:        end = input + ilen;
        !           335:        while (curr < end) {
        !           336:                chunk = end - curr;
        !           337:                if (chunk > chunk_sz)
        !           338:                        chunk = chunk_sz;
        !           339:                sha1_update (&ctx, curr, chunk);
        !           340:                curr += chunk;
        !           341:                WATCHDOG_RESET ();
        !           342:        }
        !           343: #else
        !           344:        sha1_update (&ctx, input, ilen);
        !           345: #endif
        !           346: 
        !           347:        sha1_finish (&ctx, output);
        !           348: }
        !           349: 
        !           350: /*
        !           351:  * Output = HMAC-SHA-1( input buffer, hmac key )
        !           352:  */
        !           353: void sha1_hmac (unsigned char *key, int keylen,
        !           354:                unsigned char *input, int ilen, unsigned char output[20])
        !           355: {
        !           356:        int i;
        !           357:        sha1_context ctx;
        !           358:        unsigned char k_ipad[64];
        !           359:        unsigned char k_opad[64];
        !           360:        unsigned char tmpbuf[20];
        !           361: 
        !           362:        memset (k_ipad, 0x36, 64);
        !           363:        memset (k_opad, 0x5C, 64);
        !           364: 
        !           365:        for (i = 0; i < keylen; i++) {
        !           366:                if (i >= 64)
        !           367:                        break;
        !           368: 
        !           369:                k_ipad[i] ^= key[i];
        !           370:                k_opad[i] ^= key[i];
        !           371:        }
        !           372: 
        !           373:        sha1_starts (&ctx);
        !           374:        sha1_update (&ctx, k_ipad, 64);
        !           375:        sha1_update (&ctx, input, ilen);
        !           376:        sha1_finish (&ctx, tmpbuf);
        !           377: 
        !           378:        sha1_starts (&ctx);
        !           379:        sha1_update (&ctx, k_opad, 64);
        !           380:        sha1_update (&ctx, tmpbuf, 20);
        !           381:        sha1_finish (&ctx, output);
        !           382: 
        !           383:        memset (k_ipad, 0, 64);
        !           384:        memset (k_opad, 0, 64);
        !           385:        memset (tmpbuf, 0, 20);
        !           386:        memset (&ctx, 0, sizeof (sha1_context));
        !           387: }
        !           388: 
        !           389: static const char _sha1_src[] = "_sha1_src";
        !           390: 
        !           391: #ifdef SELF_TEST
        !           392: /*
        !           393:  * FIPS-180-1 test vectors
        !           394:  */
        !           395: static const char sha1_test_str[3][57] = {
        !           396:        {"abc"},
        !           397:        {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
        !           398:        {""}
        !           399: };
        !           400: 
        !           401: static const unsigned char sha1_test_sum[3][20] = {
        !           402:        {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
        !           403:         0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
        !           404:        {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
        !           405:         0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
        !           406:        {0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
        !           407:         0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
        !           408: };
        !           409: 
        !           410: /*
        !           411:  * Checkup routine
        !           412:  */
        !           413: int sha1_self_test (void)
        !           414: {
        !           415:        int i, j;
        !           416:        unsigned char buf[1000];
        !           417:        unsigned char sha1sum[20];
        !           418:        sha1_context ctx;
        !           419: 
        !           420:        for (i = 0; i < 3; i++) {
        !           421:                printf ("  SHA-1 test #%d: ", i + 1);
        !           422: 
        !           423:                sha1_starts (&ctx);
        !           424: 
        !           425:                if (i < 2)
        !           426:                        sha1_update (&ctx, (unsigned char *) sha1_test_str[i],
        !           427:                                     strlen (sha1_test_str[i]));
        !           428:                else {
        !           429:                        memset (buf, 'a', 1000);
        !           430:                        for (j = 0; j < 1000; j++)
        !           431:                                sha1_update (&ctx, buf, 1000);
        !           432:                }
        !           433: 
        !           434:                sha1_finish (&ctx, sha1sum);
        !           435: 
        !           436:                if (memcmp (sha1sum, sha1_test_sum[i], 20) != 0) {
        !           437:                        printf ("failed\n");
        !           438:                        return (1);
        !           439:                }
        !           440: 
        !           441:                printf ("passed\n");
        !           442:        }
        !           443: 
        !           444:        printf ("\n");
        !           445:        return (0);
        !           446: }
        !           447: #else
        !           448: int sha1_self_test (void)
        !           449: {
        !           450:        return (0);
        !           451: }
        !           452: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>