Return to sha1.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / elwix / tools / uboot_mkimage / lib |
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