Annotation of embedaddon/quagga/lib/md5.c, revision 1.1
1.1 ! misho 1: /* $USAGI: md5.c,v 1.2 2000/11/02 11:59:24 yoshfuji Exp $ */
! 2: /* $KAME: md5.c,v 1.2 2000/05/27 07:07:48 jinmei Exp $ */
! 3: /* $Id: md5.c,v 1.6 2006/01/17 23:39:04 vincent Exp $ */
! 4:
! 5: /*
! 6: * Copyright (C) 2004 6WIND
! 7: * <Vincent.Jardin@6WIND.com>
! 8: * All rights reserved.
! 9: *
! 10: * This MD5 code is Big endian and Little Endian compatible.
! 11: */
! 12:
! 13: /*
! 14: * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
! 15: * All rights reserved.
! 16: *
! 17: * Redistribution and use in source and binary forms, with or without
! 18: * modification, are permitted provided that the following conditions
! 19: * are met:
! 20: * 1. Redistributions of source code must retain the above copyright
! 21: * notice, this list of conditions and the following disclaimer.
! 22: * 2. Redistributions in binary form must reproduce the above copyright
! 23: * notice, this list of conditions and the following disclaimer in the
! 24: * documentation and/or other materials provided with the distribution.
! 25: * 3. Neither the name of the project nor the names of its contributors
! 26: * may be used to endorse or promote products derived from this software
! 27: * without specific prior written permission.
! 28: *
! 29: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
! 30: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 31: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 32: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
! 33: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 34: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 35: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 36: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 37: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 38: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 39: * SUCH DAMAGE.
! 40: */
! 41:
! 42: #include <zebra.h>
! 43: #include "md5.h"
! 44:
! 45: #define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
! 46:
! 47: #define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
! 48: #define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
! 49: #define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
! 50: #define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
! 51:
! 52: #define ROUND1(a, b, c, d, k, s, i) { \
! 53: (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
! 54: (a) = SHIFT((a), (s)); \
! 55: (a) = (b) + (a); \
! 56: }
! 57:
! 58: #define ROUND2(a, b, c, d, k, s, i) { \
! 59: (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
! 60: (a) = SHIFT((a), (s)); \
! 61: (a) = (b) + (a); \
! 62: }
! 63:
! 64: #define ROUND3(a, b, c, d, k, s, i) { \
! 65: (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
! 66: (a) = SHIFT((a), (s)); \
! 67: (a) = (b) + (a); \
! 68: }
! 69:
! 70: #define ROUND4(a, b, c, d, k, s, i) { \
! 71: (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
! 72: (a) = SHIFT((a), (s)); \
! 73: (a) = (b) + (a); \
! 74: }
! 75:
! 76: #define Sa 7
! 77: #define Sb 12
! 78: #define Sc 17
! 79: #define Sd 22
! 80:
! 81: #define Se 5
! 82: #define Sf 9
! 83: #define Sg 14
! 84: #define Sh 20
! 85:
! 86: #define Si 4
! 87: #define Sj 11
! 88: #define Sk 16
! 89: #define Sl 23
! 90:
! 91: #define Sm 6
! 92: #define Sn 10
! 93: #define So 15
! 94: #define Sp 21
! 95:
! 96: #define MD5_A0 0x67452301
! 97: #define MD5_B0 0xefcdab89
! 98: #define MD5_C0 0x98badcfe
! 99: #define MD5_D0 0x10325476
! 100:
! 101: /* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
! 102: static const uint32_t T[65] = {
! 103: 0,
! 104: 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
! 105: 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
! 106: 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
! 107: 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
! 108:
! 109: 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
! 110: 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
! 111: 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
! 112: 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
! 113:
! 114: 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
! 115: 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
! 116: 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
! 117: 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
! 118:
! 119: 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
! 120: 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
! 121: 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
! 122: 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
! 123: };
! 124:
! 125: static const uint8_t md5_paddat[MD5_BUFLEN] = {
! 126: 0x80, 0, 0, 0, 0, 0, 0, 0,
! 127: 0, 0, 0, 0, 0, 0, 0, 0,
! 128: 0, 0, 0, 0, 0, 0, 0, 0,
! 129: 0, 0, 0, 0, 0, 0, 0, 0,
! 130: 0, 0, 0, 0, 0, 0, 0, 0,
! 131: 0, 0, 0, 0, 0, 0, 0, 0,
! 132: 0, 0, 0, 0, 0, 0, 0, 0,
! 133: 0, 0, 0, 0, 0, 0, 0, 0,
! 134: };
! 135:
! 136: static void md5_calc (const uint8_t *, md5_ctxt *);
! 137:
! 138: void md5_init(md5_ctxt *ctxt)
! 139: {
! 140: ctxt->md5_n = 0;
! 141: ctxt->md5_i = 0;
! 142: ctxt->md5_sta = MD5_A0;
! 143: ctxt->md5_stb = MD5_B0;
! 144: ctxt->md5_stc = MD5_C0;
! 145: ctxt->md5_std = MD5_D0;
! 146: memset (ctxt->md5_buf, 0, sizeof(ctxt->md5_buf));
! 147: }
! 148:
! 149: void md5_loop(md5_ctxt *ctxt, const void *vinput, uint len)
! 150: {
! 151: uint gap, i;
! 152: const uint8_t *input = vinput;
! 153:
! 154: ctxt->md5_n += len * 8; /* byte to bit */
! 155: gap = MD5_BUFLEN - ctxt->md5_i;
! 156:
! 157: if (len >= gap) {
! 158: memcpy (ctxt->md5_buf + ctxt->md5_i, input, gap);
! 159: md5_calc(ctxt->md5_buf, ctxt);
! 160:
! 161: for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
! 162: md5_calc((input + i), ctxt);
! 163: }
! 164:
! 165: ctxt->md5_i = len - i;
! 166: memcpy (ctxt->md5_buf, (input + i), ctxt->md5_i);
! 167: } else {
! 168: memcpy (ctxt->md5_buf + ctxt->md5_i, input, len);
! 169: ctxt->md5_i += len;
! 170: }
! 171: }
! 172:
! 173: void md5_pad(md5_ctxt *ctxt)
! 174: {
! 175: uint gap;
! 176:
! 177: /* Don't count up padding. Keep md5_n. */
! 178: gap = MD5_BUFLEN - ctxt->md5_i;
! 179: if (gap > 8) {
! 180: memcpy (ctxt->md5_buf + ctxt->md5_i, md5_paddat,
! 181: gap - sizeof(ctxt->md5_n));
! 182: } else {
! 183: /* including gap == 8 */
! 184: memcpy (ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap);
! 185: md5_calc (ctxt->md5_buf, ctxt);
! 186: memcpy (ctxt->md5_buf, md5_paddat + gap,
! 187: MD5_BUFLEN - sizeof(ctxt->md5_n));
! 188: }
! 189:
! 190: /* 8 byte word */
! 191: if (BYTE_ORDER == LITTLE_ENDIAN)
! 192: memcpy (&ctxt->md5_buf[56], &ctxt->md5_n8[0], 8);
! 193: else
! 194: {
! 195: ctxt->md5_buf[56] = ctxt->md5_n8[7];
! 196: ctxt->md5_buf[57] = ctxt->md5_n8[6];
! 197: ctxt->md5_buf[58] = ctxt->md5_n8[5];
! 198: ctxt->md5_buf[59] = ctxt->md5_n8[4];
! 199: ctxt->md5_buf[60] = ctxt->md5_n8[3];
! 200: ctxt->md5_buf[61] = ctxt->md5_n8[2];
! 201: ctxt->md5_buf[62] = ctxt->md5_n8[1];
! 202: ctxt->md5_buf[63] = ctxt->md5_n8[0];
! 203: }
! 204: md5_calc(ctxt->md5_buf, ctxt);
! 205: }
! 206:
! 207: void md5_result(uint8_t *digest, md5_ctxt *ctxt)
! 208: {
! 209: /* 4 byte words */
! 210: if (BYTE_ORDER == LITTLE_ENDIAN)
! 211: memcpy (digest, &ctxt->md5_st8[0], 16);
! 212: else if (BYTE_ORDER == BIG_ENDIAN)
! 213: {
! 214: digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
! 215: digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
! 216: digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
! 217: digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
! 218: digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
! 219: digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
! 220: digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
! 221: digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
! 222: }
! 223: }
! 224:
! 225: static void md5_calc(const uint8_t *b64, md5_ctxt * ctxt)
! 226: {
! 227: uint32_t A = ctxt->md5_sta;
! 228: uint32_t B = ctxt->md5_stb;
! 229: uint32_t C = ctxt->md5_stc;
! 230: uint32_t D = ctxt->md5_std;
! 231: #if (BYTE_ORDER == LITTLE_ENDIAN)
! 232: const uint32_t *X = (const uint32_t *)b64;
! 233: #elif (BYTE_ORDER == BIG_ENDIAN)
! 234: uint32_t X[16];
! 235:
! 236: if (BYTE_ORDER == BIG_ENDIAN)
! 237: {
! 238: /* 4 byte words */
! 239: /* what a brute force but fast! */
! 240: uint8_t *y = (uint8_t *)X;
! 241: y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
! 242: y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
! 243: y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
! 244: y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
! 245: y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
! 246: y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
! 247: y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
! 248: y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
! 249: y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
! 250: y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
! 251: y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
! 252: y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
! 253: y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
! 254: y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
! 255: y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
! 256: y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
! 257: }
! 258: #endif
! 259:
! 260: ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
! 261: ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
! 262: ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
! 263: ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
! 264: ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
! 265: ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
! 266: ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
! 267: ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
! 268:
! 269: ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
! 270: ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
! 271: ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
! 272: ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
! 273: ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
! 274: ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
! 275: ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
! 276: ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
! 277:
! 278: ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
! 279: ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
! 280: ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
! 281: ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
! 282: ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
! 283: ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
! 284: ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
! 285: ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
! 286:
! 287: ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
! 288: ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
! 289: ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
! 290: ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
! 291: ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
! 292: ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
! 293: ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
! 294: ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
! 295:
! 296: ctxt->md5_sta += A;
! 297: ctxt->md5_stb += B;
! 298: ctxt->md5_stc += C;
! 299: ctxt->md5_std += D;
! 300: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>