src/test/SDL_test_md5.c
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Sun, 08 Jun 2014 12:51:02 +0200
changeset 8844 d35c1b1798c8
parent 8149 681eb46b8ac4
child 9619 b94b6d0bff0f
permissions -rw-r--r--
Fixed typo in source comment.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 
    22 /*
    23  ***********************************************************************
    24  ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
    25  ** Created: 2/17/90 RLR                                              **
    26  ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
    27  ***********************************************************************
    28  */
    29 
    30 /*
    31  ***********************************************************************
    32  ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
    33  **                                                                   **
    34  ** License to copy and use this software is granted provided that    **
    35  ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
    36  ** Digest Algorithm" in all material mentioning or referencing this  **
    37  ** software or this function.                                        **
    38  **                                                                   **
    39  ** License is also granted to make and use derivative works          **
    40  ** provided that such works are identified as "derived from the RSA  **
    41  ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
    42  ** material mentioning or referencing the derived work.              **
    43  **                                                                   **
    44  ** RSA Data Security, Inc. makes no representations concerning       **
    45  ** either the merchantability of this software or the suitability    **
    46  ** of this software for any particular purpose.  It is provided "as  **
    47  ** is" without express or implied warranty of any kind.              **
    48  **                                                                   **
    49  ** These notices must be retained in any copies of any part of this  **
    50  ** documentation and/or software.                                    **
    51  ***********************************************************************
    52  */
    53 
    54 #include "SDL_config.h"
    55 
    56 #include "SDL_test.h"
    57 
    58 /* Forward declaration of static helper function */
    59 static void SDLTest_Md5Transform(MD5UINT4 * buf, MD5UINT4 * in);
    60 
    61 static unsigned char MD5PADDING[64] = {
    62   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    63   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    64   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    65   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    66   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    67   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    68   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    69   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    70 };
    71 
    72 /* F, G, H and I are basic MD5 functions */
    73 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
    74 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
    75 #define H(x, y, z) ((x) ^ (y) ^ (z))
    76 #define I(x, y, z) ((y) ^ ((x) | (~z)))
    77 
    78 /* ROTATE_LEFT rotates x left n bits */
    79 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
    80 
    81 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
    82 
    83 /* Rotation is separate from addition to prevent recomputation */
    84 #define FF(a, b, c, d, x, s, ac) \
    85   {(a) += F ((b), (c), (d)) + (x) + (MD5UINT4)(ac); \
    86    (a) = ROTATE_LEFT ((a), (s)); \
    87    (a) += (b); \
    88   }
    89 #define GG(a, b, c, d, x, s, ac) \
    90   {(a) += G ((b), (c), (d)) + (x) + (MD5UINT4)(ac); \
    91    (a) = ROTATE_LEFT ((a), (s)); \
    92    (a) += (b); \
    93   }
    94 #define HH(a, b, c, d, x, s, ac) \
    95   {(a) += H ((b), (c), (d)) + (x) + (MD5UINT4)(ac); \
    96    (a) = ROTATE_LEFT ((a), (s)); \
    97    (a) += (b); \
    98   }
    99 #define II(a, b, c, d, x, s, ac) \
   100   {(a) += I ((b), (c), (d)) + (x) + (MD5UINT4)(ac); \
   101    (a) = ROTATE_LEFT ((a), (s)); \
   102    (a) += (b); \
   103   }
   104 
   105 /*
   106   The routine MD5Init initializes the message-digest context
   107   mdContext. All fields are set to zero.
   108 */
   109 
   110 void SDLTest_Md5Init(SDLTest_Md5Context * mdContext)
   111 {
   112   if (mdContext==NULL) return;
   113 
   114   mdContext->i[0] = mdContext->i[1] = (MD5UINT4) 0;
   115 
   116   /*
   117    * Load magic initialization constants.
   118    */
   119   mdContext->buf[0] = (MD5UINT4) 0x67452301;
   120   mdContext->buf[1] = (MD5UINT4) 0xefcdab89;
   121   mdContext->buf[2] = (MD5UINT4) 0x98badcfe;
   122   mdContext->buf[3] = (MD5UINT4) 0x10325476;
   123 }
   124 
   125 /*
   126  The routine MD5Update updates the message-digest context to
   127  account for the presence of each of the characters inBuf[0..inLen-1]
   128  in the message whose digest is being computed.
   129 */
   130 
   131 void SDLTest_Md5Update(SDLTest_Md5Context * mdContext, unsigned char *inBuf,
   132           unsigned int inLen)
   133 {
   134   MD5UINT4  in[16];
   135   int       mdi;
   136   unsigned int i, ii;
   137 
   138   if (mdContext == NULL) return;
   139   if (inBuf == NULL || inLen < 1) return;
   140 
   141   /*
   142    * compute number of bytes mod 64
   143    */
   144   mdi = (int) ((mdContext->i[0] >> 3) & 0x3F);
   145 
   146   /*
   147    * update number of bits
   148    */
   149   if ((mdContext->i[0] + ((MD5UINT4) inLen << 3)) < mdContext->i[0])
   150     mdContext->i[1]++;
   151   mdContext->i[0] += ((MD5UINT4) inLen << 3);
   152   mdContext->i[1] += ((MD5UINT4) inLen >> 29);
   153 
   154   while (inLen--) {
   155     /*
   156      * add new character to buffer, increment mdi
   157      */
   158     mdContext->in[mdi++] = *inBuf++;
   159 
   160     /*
   161      * transform if necessary
   162      */
   163     if (mdi == 0x40) {
   164       for (i = 0, ii = 0; i < 16; i++, ii += 4)
   165     in[i] = (((MD5UINT4) mdContext->in[ii + 3]) << 24) |
   166       (((MD5UINT4) mdContext->in[ii + 2]) << 16) |
   167       (((MD5UINT4) mdContext->in[ii + 1]) << 8) |
   168       ((MD5UINT4) mdContext->in[ii]);
   169       SDLTest_Md5Transform(mdContext->buf, in);
   170       mdi = 0;
   171     }
   172   }
   173 }
   174 
   175 /*
   176  The routine MD5Final terminates the message-digest computation and
   177  ends with the desired message digest in mdContext->digest[0...15].
   178 */
   179 
   180 void SDLTest_Md5Final(SDLTest_Md5Context * mdContext)
   181 {
   182   MD5UINT4  in[16];
   183   int       mdi;
   184   unsigned int i, ii;
   185   unsigned int padLen;
   186 
   187   if (mdContext == NULL) return;
   188 
   189   /*
   190    * save number of bits
   191    */
   192   in[14] = mdContext->i[0];
   193   in[15] = mdContext->i[1];
   194 
   195   /*
   196    * compute number of bytes mod 64
   197    */
   198   mdi = (int) ((mdContext->i[0] >> 3) & 0x3F);
   199 
   200   /*
   201    * pad out to 56 mod 64
   202    */
   203   padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
   204   SDLTest_Md5Update(mdContext, MD5PADDING, padLen);
   205 
   206   /*
   207    * append length in bits and transform
   208    */
   209   for (i = 0, ii = 0; i < 14; i++, ii += 4)
   210     in[i] = (((MD5UINT4) mdContext->in[ii + 3]) << 24) |
   211       (((MD5UINT4) mdContext->in[ii + 2]) << 16) |
   212       (((MD5UINT4) mdContext->in[ii + 1]) << 8) |
   213       ((MD5UINT4) mdContext->in[ii]);
   214   SDLTest_Md5Transform(mdContext->buf, in);
   215 
   216   /*
   217    * store buffer in digest
   218    */
   219   for (i = 0, ii = 0; i < 4; i++, ii += 4) {
   220     mdContext->digest[ii] = (unsigned char) (mdContext->buf[i] & 0xFF);
   221     mdContext->digest[ii + 1] =
   222       (unsigned char) ((mdContext->buf[i] >> 8) & 0xFF);
   223     mdContext->digest[ii + 2] =
   224       (unsigned char) ((mdContext->buf[i] >> 16) & 0xFF);
   225     mdContext->digest[ii + 3] =
   226       (unsigned char) ((mdContext->buf[i] >> 24) & 0xFF);
   227   }
   228 }
   229 
   230 /* Basic MD5 step. Transforms buf based on in.
   231  */
   232 static void SDLTest_Md5Transform(MD5UINT4 * buf, MD5UINT4 * in)
   233 {
   234   MD5UINT4  a = buf[0], b = buf[1], c = buf[2], d = buf[3];
   235 
   236   /*
   237    * Round 1
   238    */
   239 #define S11 7
   240 #define S12 12
   241 #define S13 17
   242 #define S14 22
   243   FF(a, b, c, d, in[0], S11, 3614090360u);  /* 1 */
   244   FF(d, a, b, c, in[1], S12, 3905402710u);  /* 2 */
   245   FF(c, d, a, b, in[2], S13, 606105819u);   /* 3 */
   246   FF(b, c, d, a, in[3], S14, 3250441966u);  /* 4 */
   247   FF(a, b, c, d, in[4], S11, 4118548399u);  /* 5 */
   248   FF(d, a, b, c, in[5], S12, 1200080426u);  /* 6 */
   249   FF(c, d, a, b, in[6], S13, 2821735955u);  /* 7 */
   250   FF(b, c, d, a, in[7], S14, 4249261313u);  /* 8 */
   251   FF(a, b, c, d, in[8], S11, 1770035416u);  /* 9 */
   252   FF(d, a, b, c, in[9], S12, 2336552879u);  /* 10 */
   253   FF(c, d, a, b, in[10], S13, 4294925233u); /* 11 */
   254   FF(b, c, d, a, in[11], S14, 2304563134u); /* 12 */
   255   FF(a, b, c, d, in[12], S11, 1804603682u); /* 13 */
   256   FF(d, a, b, c, in[13], S12, 4254626195u); /* 14 */
   257   FF(c, d, a, b, in[14], S13, 2792965006u); /* 15 */
   258   FF(b, c, d, a, in[15], S14, 1236535329u); /* 16 */
   259 
   260   /*
   261    * Round 2
   262    */
   263 #define S21 5
   264 #define S22 9
   265 #define S23 14
   266 #define S24 20
   267   GG(a, b, c, d, in[1], S21, 4129170786u);  /* 17 */
   268   GG(d, a, b, c, in[6], S22, 3225465664u);  /* 18 */
   269   GG(c, d, a, b, in[11], S23, 643717713u);  /* 19 */
   270   GG(b, c, d, a, in[0], S24, 3921069994u);  /* 20 */
   271   GG(a, b, c, d, in[5], S21, 3593408605u);  /* 21 */
   272   GG(d, a, b, c, in[10], S22, 38016083u);   /* 22 */
   273   GG(c, d, a, b, in[15], S23, 3634488961u); /* 23 */
   274   GG(b, c, d, a, in[4], S24, 3889429448u);  /* 24 */
   275   GG(a, b, c, d, in[9], S21, 568446438u);   /* 25 */
   276   GG(d, a, b, c, in[14], S22, 3275163606u); /* 26 */
   277   GG(c, d, a, b, in[3], S23, 4107603335u);  /* 27 */
   278   GG(b, c, d, a, in[8], S24, 1163531501u);  /* 28 */
   279   GG(a, b, c, d, in[13], S21, 2850285829u); /* 29 */
   280   GG(d, a, b, c, in[2], S22, 4243563512u);  /* 30 */
   281   GG(c, d, a, b, in[7], S23, 1735328473u);  /* 31 */
   282   GG(b, c, d, a, in[12], S24, 2368359562u); /* 32 */
   283 
   284   /*
   285    * Round 3
   286    */
   287 #define S31 4
   288 #define S32 11
   289 #define S33 16
   290 #define S34 23
   291   HH(a, b, c, d, in[5], S31, 4294588738u);  /* 33 */
   292   HH(d, a, b, c, in[8], S32, 2272392833u);  /* 34 */
   293   HH(c, d, a, b, in[11], S33, 1839030562u); /* 35 */
   294   HH(b, c, d, a, in[14], S34, 4259657740u); /* 36 */
   295   HH(a, b, c, d, in[1], S31, 2763975236u);  /* 37 */
   296   HH(d, a, b, c, in[4], S32, 1272893353u);  /* 38 */
   297   HH(c, d, a, b, in[7], S33, 4139469664u);  /* 39 */
   298   HH(b, c, d, a, in[10], S34, 3200236656u); /* 40 */
   299   HH(a, b, c, d, in[13], S31, 681279174u);  /* 41 */
   300   HH(d, a, b, c, in[0], S32, 3936430074u);  /* 42 */
   301   HH(c, d, a, b, in[3], S33, 3572445317u);  /* 43 */
   302   HH(b, c, d, a, in[6], S34, 76029189u);    /* 44 */
   303   HH(a, b, c, d, in[9], S31, 3654602809u);  /* 45 */
   304   HH(d, a, b, c, in[12], S32, 3873151461u); /* 46 */
   305   HH(c, d, a, b, in[15], S33, 530742520u);  /* 47 */
   306   HH(b, c, d, a, in[2], S34, 3299628645u);  /* 48 */
   307 
   308   /*
   309    * Round 4
   310    */
   311 #define S41 6
   312 #define S42 10
   313 #define S43 15
   314 #define S44 21
   315   II(a, b, c, d, in[0], S41, 4096336452u);  /* 49 */
   316   II(d, a, b, c, in[7], S42, 1126891415u);  /* 50 */
   317   II(c, d, a, b, in[14], S43, 2878612391u); /* 51 */
   318   II(b, c, d, a, in[5], S44, 4237533241u);  /* 52 */
   319   II(a, b, c, d, in[12], S41, 1700485571u); /* 53 */
   320   II(d, a, b, c, in[3], S42, 2399980690u);  /* 54 */
   321   II(c, d, a, b, in[10], S43, 4293915773u); /* 55 */
   322   II(b, c, d, a, in[1], S44, 2240044497u);  /* 56 */
   323   II(a, b, c, d, in[8], S41, 1873313359u);  /* 57 */
   324   II(d, a, b, c, in[15], S42, 4264355552u); /* 58 */
   325   II(c, d, a, b, in[6], S43, 2734768916u);  /* 59 */
   326   II(b, c, d, a, in[13], S44, 1309151649u); /* 60 */
   327   II(a, b, c, d, in[4], S41, 4149444226u);  /* 61 */
   328   II(d, a, b, c, in[11], S42, 3174756917u); /* 62 */
   329   II(c, d, a, b, in[2], S43, 718787259u);   /* 63 */
   330   II(b, c, d, a, in[9], S44, 3951481745u);  /* 64 */
   331 
   332   buf[0] += a;
   333   buf[1] += b;
   334   buf[2] += c;
   335   buf[3] += d;
   336 }