linux/drivers/staging/rt3090/common/crypt_md5.c
<<
>>
Prefs
   1/*
   2 *************************************************************************
   3 * Ralink Tech Inc.
   4 * 5F., No.36, Taiyuan St., Jhubei City,
   5 * Hsinchu County 302,
   6 * Taiwan, R.O.C.
   7 *
   8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
   9 *
  10 * This program is free software; you can redistribute it and/or modify  *
  11 * it under the terms of the GNU General Public License as published by  *
  12 * the Free Software Foundation; either version 2 of the License, or     *
  13 * (at your option) any later version.                                   *
  14 *                                                                       *
  15 * This program is distributed in the hope that it will be useful,       *
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  18 * GNU General Public License for more details.                          *
  19 *                                                                       *
  20 * You should have received a copy of the GNU General Public License     *
  21 * along with this program; if not, write to the                         *
  22 * Free Software Foundation, Inc.,                                       *
  23 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  24 *                                                                       *
  25 *************************************************************************/
  26
  27#include "../crypt_md5.h"
  28
  29
  30#ifdef MD5_SUPPORT
  31/*
  32 * F, G, H and I are basic MD5 functions.
  33 */
  34#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
  35#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
  36#define H(x, y, z) ((x) ^ (y) ^ (z))
  37#define I(x, y, z) ((y) ^ ((x) | (~z)))
  38
  39#define ROTL(x,n,w) ((x << n) | (x >> (w - n)))
  40#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
  41
  42#define ROUND1(a, b, c, d, x, s, ac) {          \
  43    (a) += F((b),(c),(d)) + (x) + (UINT32)(ac); \
  44    (a)  = ROTL32((a),(s));                     \
  45    (a) += (b);                                 \
  46}
  47#define ROUND2(a, b, c, d, x, s, ac) {          \
  48    (a) += G((b),(c),(d)) + (x) + (UINT32)(ac); \
  49    (a)  = ROTL32((a),(s));                     \
  50    (a) += (b);                                 \
  51}
  52#define ROUND3(a, b, c, d, x, s, ac) {          \
  53    (a) += H((b),(c),(d)) + (x) + (UINT32)(ac); \
  54    (a)  = ROTL32((a),(s));                     \
  55    (a) += (b);                                 \
  56}
  57#define ROUND4(a, b, c, d, x, s, ac) {          \
  58    (a) += I((b),(c),(d)) + (x) + (UINT32)(ac); \
  59    (a)  = ROTL32((a),(s));                     \
  60    (a) += (b);                                 \
  61}
  62static const UINT32 MD5_DefaultHashValue[4] = {
  63    0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL
  64};
  65#endif /* MD5_SUPPORT */
  66
  67
  68#ifdef MD5_SUPPORT
  69/*
  70========================================================================
  71Routine Description:
  72    Initial Md5_CTX_STRUC
  73
  74Arguments:
  75    pMD5_CTX        Pointer to Md5_CTX_STRUC
  76
  77Return Value:
  78    None
  79
  80Note:
  81    None
  82========================================================================
  83*/
  84VOID MD5_Init (
  85    IN  MD5_CTX_STRUC *pMD5_CTX)
  86{
  87    NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue,
  88        sizeof(MD5_DefaultHashValue));
  89    NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
  90    pMD5_CTX->BlockLen   = 0;
  91    pMD5_CTX->MessageLen = 0;
  92} /* End of MD5_Init */
  93
  94
  95/*
  96========================================================================
  97Routine Description:
  98    MD5 computation for one block (512 bits)
  99
 100Arguments:
 101    pMD5_CTX        Pointer to Md5_CTX_STRUC
 102
 103Return Value:
 104    None
 105
 106Note:
 107    T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round
 108========================================================================
 109*/
 110VOID MD5_Hash (
 111    IN  MD5_CTX_STRUC *pMD5_CTX)
 112{
 113    UINT32 X_i;
 114    UINT32 X[16];
 115    UINT32 a,b,c,d;
 116
 117    /* Prepare the message schedule, {X_i} */
 118    NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE);
 119    for (X_i = 0; X_i < 16; X_i++)
 120        X[X_i] = cpu2le32(X[X_i]); /* Endian Swap */
 121        /* End of for */
 122
 123    /* MD5 hash computation */
 124    /* Initialize the working variables */
 125    a = pMD5_CTX->HashValue[0];
 126    b = pMD5_CTX->HashValue[1];
 127    c = pMD5_CTX->HashValue[2];
 128    d = pMD5_CTX->HashValue[3];
 129
 130    /*
 131     *  Round 1
 132     *  Let [abcd k s i] denote the operation
 133     *  a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
 134     */
 135    ROUND1(a, b, c, d, X[ 0],  7, 0xd76aa478); /* 1 */
 136    ROUND1(d, a, b, c, X[ 1], 12, 0xe8c7b756); /* 2 */
 137    ROUND1(c, d, a, b, X[ 2], 17, 0x242070db); /* 3 */
 138    ROUND1(b, c, d, a, X[ 3], 22, 0xc1bdceee); /* 4 */
 139    ROUND1(a, b, c, d, X[ 4],  7, 0xf57c0faf); /* 5 */
 140    ROUND1(d, a, b, c, X[ 5], 12, 0x4787c62a); /* 6 */
 141    ROUND1(c, d, a, b, X[ 6], 17, 0xa8304613); /* 7 */
 142    ROUND1(b, c, d, a, X[ 7], 22, 0xfd469501); /* 8 */
 143    ROUND1(a, b, c, d, X[ 8],  7, 0x698098d8); /* 9 */
 144    ROUND1(d, a, b, c, X[ 9], 12, 0x8b44f7af); /* 10 */
 145    ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1); /* 11 */
 146    ROUND1(b, c, d, a, X[11], 22, 0x895cd7be); /* 12 */
 147    ROUND1(a, b, c, d, X[12],  7, 0x6b901122); /* 13 */
 148    ROUND1(d, a, b, c, X[13], 12, 0xfd987193); /* 14 */
 149    ROUND1(c, d, a, b, X[14], 17, 0xa679438e); /* 15 */
 150    ROUND1(b, c, d, a, X[15], 22, 0x49b40821); /* 16 */
 151
 152    /*
 153     *  Round 2
 154     *  Let [abcd k s i] denote the operation
 155     *  a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
 156     */
 157    ROUND2(a, b, c, d, X[ 1],  5, 0xf61e2562); /* 17 */
 158    ROUND2(d, a, b, c, X[ 6],  9, 0xc040b340); /* 18 */
 159    ROUND2(c, d, a, b, X[11], 14, 0x265e5a51); /* 19 */
 160    ROUND2(b, c, d, a, X[ 0], 20, 0xe9b6c7aa); /* 20 */
 161    ROUND2(a, b, c, d, X[ 5],  5, 0xd62f105d); /* 21 */
 162    ROUND2(d, a, b, c, X[10],  9,  0x2441453); /* 22 */
 163    ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681); /* 23 */
 164    ROUND2(b, c, d, a, X[ 4], 20, 0xe7d3fbc8); /* 24 */
 165    ROUND2(a, b, c, d, X[ 9],  5, 0x21e1cde6); /* 25 */
 166    ROUND2(d, a, b, c, X[14],  9, 0xc33707d6); /* 26 */
 167    ROUND2(c, d, a, b, X[ 3], 14, 0xf4d50d87); /* 27 */
 168    ROUND2(b, c, d, a, X[ 8], 20, 0x455a14ed); /* 28 */
 169    ROUND2(a, b, c, d, X[13],  5, 0xa9e3e905); /* 29 */
 170    ROUND2(d, a, b, c, X[ 2],  9, 0xfcefa3f8); /* 30 */
 171    ROUND2(c, d, a, b, X[ 7], 14, 0x676f02d9); /* 31 */
 172    ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a); /* 32 */
 173
 174    /*
 175     *  Round 3
 176     *  Let [abcd k s t] denote the operation
 177     *  a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
 178     */
 179    ROUND3(a, b, c, d, X[ 5],  4, 0xfffa3942); /* 33 */
 180    ROUND3(d, a, b, c, X[ 8], 11, 0x8771f681); /* 34 */
 181    ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122); /* 35 */
 182    ROUND3(b, c, d, a, X[14], 23, 0xfde5380c); /* 36 */
 183    ROUND3(a, b, c, d, X[ 1],  4, 0xa4beea44); /* 37 */
 184    ROUND3(d, a, b, c, X[ 4], 11, 0x4bdecfa9); /* 38 */
 185    ROUND3(c, d, a, b, X[ 7], 16, 0xf6bb4b60); /* 39 */
 186    ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70); /* 40 */
 187    ROUND3(a, b, c, d, X[13],  4, 0x289b7ec6); /* 41 */
 188    ROUND3(d, a, b, c, X[ 0], 11, 0xeaa127fa); /* 42 */
 189    ROUND3(c, d, a, b, X[ 3], 16, 0xd4ef3085); /* 43 */
 190    ROUND3(b, c, d, a, X[ 6], 23,  0x4881d05); /* 44 */
 191    ROUND3(a, b, c, d, X[ 9],  4, 0xd9d4d039); /* 45 */
 192    ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5); /* 46 */
 193    ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8); /* 47 */
 194    ROUND3(b, c, d, a, X[ 2], 23, 0xc4ac5665); /* 48 */
 195
 196    /*
 197     *  Round 4
 198     *  Let [abcd k s t] denote the operation
 199     *  a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
 200     */
 201    ROUND4(a, b, c, d, X[ 0],  6, 0xf4292244); /* 49 */
 202    ROUND4(d, a, b, c, X[ 7], 10, 0x432aff97); /* 50 */
 203    ROUND4(c, d, a, b, X[14], 15, 0xab9423a7); /* 51 */
 204    ROUND4(b, c, d, a, X[ 5], 21, 0xfc93a039); /* 52 */
 205    ROUND4(a, b, c, d, X[12],  6, 0x655b59c3); /* 53 */
 206    ROUND4(d, a, b, c, X[ 3], 10, 0x8f0ccc92); /* 54 */
 207    ROUND4(c, d, a, b, X[10], 15, 0xffeff47d); /* 55 */
 208    ROUND4(b, c, d, a, X[ 1], 21, 0x85845dd1); /* 56 */
 209    ROUND4(a, b, c, d, X[ 8],  6, 0x6fa87e4f); /* 57 */
 210    ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0); /* 58 */
 211    ROUND4(c, d, a, b, X[ 6], 15, 0xa3014314); /* 59 */
 212    ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1); /* 60 */
 213    ROUND4(a, b, c, d, X[ 4],  6, 0xf7537e82); /* 61 */
 214    ROUND4(d, a, b, c, X[11], 10, 0xbd3af235); /* 62 */
 215    ROUND4(c, d, a, b, X[ 2], 15, 0x2ad7d2bb); /* 63 */
 216    ROUND4(b, c, d, a, X[ 9], 21, 0xeb86d391); /* 64 */
 217
 218    /* Compute the i^th intermediate hash value H^(i) */
 219    pMD5_CTX->HashValue[0] += a;
 220    pMD5_CTX->HashValue[1] += b;
 221    pMD5_CTX->HashValue[2] += c;
 222    pMD5_CTX->HashValue[3] += d;
 223
 224    NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
 225    pMD5_CTX->BlockLen = 0;
 226} /* End of MD5_Hash */
 227
 228
 229/*
 230========================================================================
 231Routine Description:
 232    The message is appended to block. If block size > 64 bytes, the MD5_Hash
 233will be called.
 234
 235Arguments:
 236    pMD5_CTX        Pointer to MD5_CTX_STRUC
 237    message         Message context
 238    messageLen      The length of message in bytes
 239
 240Return Value:
 241    None
 242
 243Note:
 244    None
 245========================================================================
 246*/
 247VOID MD5_Append (
 248    IN  MD5_CTX_STRUC *pMD5_CTX,
 249    IN  const UINT8 Message[],
 250    IN  UINT MessageLen)
 251{
 252    UINT appendLen = 0;
 253    UINT diffLen = 0;
 254
 255    while (appendLen != MessageLen) {
 256        diffLen = MessageLen - appendLen;
 257        if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) {
 258            NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
 259                Message + appendLen, diffLen);
 260            pMD5_CTX->BlockLen += diffLen;
 261            appendLen += diffLen;
 262        }
 263        else
 264        {
 265            NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
 266                Message + appendLen, MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
 267            appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
 268            pMD5_CTX->BlockLen = MD5_BLOCK_SIZE;
 269            MD5_Hash(pMD5_CTX);
 270        } /* End of if */
 271    } /* End of while */
 272    pMD5_CTX->MessageLen += MessageLen;
 273} /* End of MD5_Append */
 274
 275
 276/*
 277========================================================================
 278Routine Description:
 279    1. Append bit 1 to end of the message
 280    2. Append the length of message in rightmost 64 bits
 281    3. Transform the Hash Value to digest message
 282
 283Arguments:
 284    pMD5_CTX        Pointer to MD5_CTX_STRUC
 285
 286Return Value:
 287    digestMessage   Digest message
 288
 289Note:
 290    None
 291========================================================================
 292*/
 293VOID MD5_End (
 294    IN  MD5_CTX_STRUC *pMD5_CTX,
 295    OUT UINT8 DigestMessage[])
 296{
 297    UINT index;
 298    UINT64 message_length_bits;
 299
 300    /* append 1 bits to end of the message */
 301    NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80);
 302
 303    /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
 304    if (pMD5_CTX->BlockLen > 55)
 305        MD5_Hash(pMD5_CTX);
 306        /* End of if */
 307
 308    /* Append the length of message in rightmost 64 bits */
 309    message_length_bits = pMD5_CTX->MessageLen*8;
 310    message_length_bits = cpu2le64(message_length_bits);
 311    NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8);
 312    MD5_Hash(pMD5_CTX);
 313
 314    /* Return message digest, transform the UINT32 hash value to bytes */
 315    for (index = 0; index < 4;index++)
 316        pMD5_CTX->HashValue[index] = cpu2le32(pMD5_CTX->HashValue[index]);
 317        /* End of for */
 318    NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE);
 319} /* End of MD5_End */
 320
 321
 322/*
 323========================================================================
 324Routine Description:
 325    MD5 algorithm
 326
 327Arguments:
 328    message         Message context
 329    messageLen      The length of message in bytes
 330
 331Return Value:
 332    digestMessage   Digest message
 333
 334Note:
 335    None
 336========================================================================
 337*/
 338VOID RT_MD5 (
 339    IN  const UINT8 Message[],
 340    IN  UINT MessageLen,
 341    OUT UINT8 DigestMessage[])
 342{
 343    MD5_CTX_STRUC md5_ctx;
 344
 345    NdisZeroMemory(&md5_ctx, sizeof(MD5_CTX_STRUC));
 346    MD5_Init(&md5_ctx);
 347    MD5_Append(&md5_ctx, Message, MessageLen);
 348    MD5_End(&md5_ctx, DigestMessage);
 349} /* End of RT_MD5 */
 350
 351#endif /* MD5_SUPPORT */
 352
 353/* End of crypt_md5.c */
 354
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.