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>