"Fossies" - the Fresh Open Source Software Archive

Member "fdupes-2.1.2/md5/md5.c" (12 Aug 2020, 11568 Bytes) of package /linux/privat/fdupes-2.1.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "md5.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.51_vs_1.6.1.

    1 /*
    2   Copyright (C) 1999 Aladdin Enterprises.  All rights reserved.
    3 
    4   This software is provided 'as-is', without any express or implied
    5   warranty.  In no event will the authors be held liable for any damages
    6   arising from the use of this software.
    7 
    8   Permission is granted to anyone to use this software for any purpose,
    9   including commercial applications, and to alter it and redistribute it
   10   freely, subject to the following restrictions:
   11 
   12   1. The origin of this software must not be misrepresented; you must not
   13      claim that you wrote the original software. If you use this software
   14      in a product, an acknowledgment in the product documentation would be
   15      appreciated but is not required.
   16   2. Altered source versions must be plainly marked as such, and must not be
   17      misrepresented as being the original software.
   18   3. This notice may not be removed or altered from any source distribution.
   19 
   20   L. Peter Deutsch
   21   ghost@aladdin.com
   22 
   23  */
   24 /*$Id: md5.c $ */
   25 /*
   26   Independent implementation of MD5 (RFC 1321).
   27 
   28   This code implements the MD5 Algorithm defined in RFC 1321.
   29   It is derived directly from the text of the RFC and not from the
   30   reference implementation.
   31 
   32   The original and principal author of md5.c is L. Peter Deutsch
   33   <ghost@aladdin.com>.  Other authors are noted in the change history
   34   that follows (in reverse chronological order):
   35 
   36   contributors
   37    chl - Charles Longeau <chl@tuxfamily.org>
   38    tom - Tom Hoover <tom@hisword.net>
   39 
   40   2015-02-04 tom Added #ifdef __APPLE__ for proper compilation under OSX.
   41   2002-05-31 chl Relocated string.h to avoid memcpy warning. 
   42   1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
   43   1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
   44   1999-05-03 lpd Original version.
   45  */
   46 
   47 #include "md5.h"
   48 #include <string.h>
   49 
   50 /* endianness check using glibc endian.h */
   51 #ifdef __APPLE__
   52 # include <machine/endian.h>
   53 #else
   54 # include <endian.h>
   55 #endif
   56 
   57 #if __BYTE_ORDER == __BIG_ENDIAN
   58 # define ARCH_IS_BIG_ENDIAN 1
   59 #elif __BYTE_ORDER == __LITTLE_ENDIAN
   60 # define ARCH_IS_BIG_ENDIAN 0
   61 #endif
   62 
   63 #ifdef TEST
   64 /*
   65  * Compile with -DTEST to create a self-contained executable test program.
   66  * The test program should print out the same values as given in section
   67  * A.5 of RFC 1321, reproduced below.
   68  */
   69 main()
   70 {
   71     static const char *const test[7] = {
   72     "", /*d41d8cd98f00b204e9800998ecf8427e*/
   73     "a", /*0cc175b9c0f1b6a831c399e269772661*/
   74     "abc", /*900150983cd24fb0d6963f7d28e17f72*/
   75     "message digest", /*f96b697d7cb7938d525a2f31aaf161d0*/
   76     "abcdefghijklmnopqrstuvwxyz", /*c3fcd3d76192e4007dfb496cca67e13b*/
   77     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
   78                 /*d174ab98d277d9f5a5611c2c9f419d9f*/
   79     "12345678901234567890123456789012345678901234567890123456789012345678901234567890" /*57edf4a22be3c955ac49da2e2107b67a*/
   80     };
   81     int i;
   82 
   83     for (i = 0; i < 7; ++i) {
   84     md5_state_t state;
   85     md5_byte_t digest[16];
   86     int di;
   87 
   88     md5_init(&state);
   89     md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i]));
   90     md5_finish(&state, digest);
   91     printf("MD5 (\"%s\") = ", test[i]);
   92     for (di = 0; di < 16; ++di)
   93         printf("%02x", digest[di]);
   94     printf("\n");
   95     }
   96     return 0;
   97 }
   98 #endif /* TEST */
   99 
  100 
  101 /*
  102  * For reference, here is the program that computed the T values.
  103  */
  104 #if 0
  105 #include <math.h>
  106 main()
  107 {
  108     int i;
  109     for (i = 1; i <= 64; ++i) {
  110     unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i)));
  111     printf("#define T%d 0x%08lx\n", i, v);
  112     }
  113     return 0;
  114 }
  115 #endif
  116 /*
  117  * End of T computation program.
  118  */
  119 #define T1 0xd76aa478
  120 #define T2 0xe8c7b756
  121 #define T3 0x242070db
  122 #define T4 0xc1bdceee
  123 #define T5 0xf57c0faf
  124 #define T6 0x4787c62a
  125 #define T7 0xa8304613
  126 #define T8 0xfd469501
  127 #define T9 0x698098d8
  128 #define T10 0x8b44f7af
  129 #define T11 0xffff5bb1
  130 #define T12 0x895cd7be
  131 #define T13 0x6b901122
  132 #define T14 0xfd987193
  133 #define T15 0xa679438e
  134 #define T16 0x49b40821
  135 #define T17 0xf61e2562
  136 #define T18 0xc040b340
  137 #define T19 0x265e5a51
  138 #define T20 0xe9b6c7aa
  139 #define T21 0xd62f105d
  140 #define T22 0x02441453
  141 #define T23 0xd8a1e681
  142 #define T24 0xe7d3fbc8
  143 #define T25 0x21e1cde6
  144 #define T26 0xc33707d6
  145 #define T27 0xf4d50d87
  146 #define T28 0x455a14ed
  147 #define T29 0xa9e3e905
  148 #define T30 0xfcefa3f8
  149 #define T31 0x676f02d9
  150 #define T32 0x8d2a4c8a
  151 #define T33 0xfffa3942
  152 #define T34 0x8771f681
  153 #define T35 0x6d9d6122
  154 #define T36 0xfde5380c
  155 #define T37 0xa4beea44
  156 #define T38 0x4bdecfa9
  157 #define T39 0xf6bb4b60
  158 #define T40 0xbebfbc70
  159 #define T41 0x289b7ec6
  160 #define T42 0xeaa127fa
  161 #define T43 0xd4ef3085
  162 #define T44 0x04881d05
  163 #define T45 0xd9d4d039
  164 #define T46 0xe6db99e5
  165 #define T47 0x1fa27cf8
  166 #define T48 0xc4ac5665
  167 #define T49 0xf4292244
  168 #define T50 0x432aff97
  169 #define T51 0xab9423a7
  170 #define T52 0xfc93a039
  171 #define T53 0x655b59c3
  172 #define T54 0x8f0ccc92
  173 #define T55 0xffeff47d
  174 #define T56 0x85845dd1
  175 #define T57 0x6fa87e4f
  176 #define T58 0xfe2ce6e0
  177 #define T59 0xa3014314
  178 #define T60 0x4e0811a1
  179 #define T61 0xf7537e82
  180 #define T62 0xbd3af235
  181 #define T63 0x2ad7d2bb
  182 #define T64 0xeb86d391
  183 
  184 static void
  185 md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
  186 {
  187     md5_word_t
  188     a = pms->abcd[0], b = pms->abcd[1],
  189     c = pms->abcd[2], d = pms->abcd[3];
  190     md5_word_t t;
  191 
  192 #ifndef ARCH_IS_BIG_ENDIAN
  193 # define ARCH_IS_BIG_ENDIAN 1   /* slower, default implementation */
  194 #endif
  195 #if ARCH_IS_BIG_ENDIAN
  196 
  197     /*
  198      * On big-endian machines, we must arrange the bytes in the right
  199      * order.  (This also works on machines of unknown byte order.)
  200      */
  201     md5_word_t X[16];
  202     const md5_byte_t *xp = data;
  203     int i;
  204 
  205     for (i = 0; i < 16; ++i, xp += 4)
  206     X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
  207 
  208 #else  /* !ARCH_IS_BIG_ENDIAN */
  209 
  210     /*
  211      * On little-endian machines, we can process properly aligned data
  212      * without copying it.
  213      */
  214     md5_word_t xbuf[16];
  215     const md5_word_t *X;
  216 
  217     if (!((data - (const md5_byte_t *)0) & 3)) {
  218     /* data are properly aligned */
  219     X = (const md5_word_t *)data;
  220     } else {
  221     /* not aligned */
  222     memcpy(xbuf, data, 64);
  223     X = xbuf;
  224     }
  225 #endif
  226 
  227 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
  228 
  229     /* Round 1. */
  230     /* Let [abcd k s i] denote the operation
  231        a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
  232 #define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
  233 #define SET(a, b, c, d, k, s, Ti)\
  234   t = a + F(b,c,d) + X[k] + Ti;\
  235   a = ROTATE_LEFT(t, s) + b
  236     /* Do the following 16 operations. */
  237     SET(a, b, c, d,  0,  7,  T1);
  238     SET(d, a, b, c,  1, 12,  T2);
  239     SET(c, d, a, b,  2, 17,  T3);
  240     SET(b, c, d, a,  3, 22,  T4);
  241     SET(a, b, c, d,  4,  7,  T5);
  242     SET(d, a, b, c,  5, 12,  T6);
  243     SET(c, d, a, b,  6, 17,  T7);
  244     SET(b, c, d, a,  7, 22,  T8);
  245     SET(a, b, c, d,  8,  7,  T9);
  246     SET(d, a, b, c,  9, 12, T10);
  247     SET(c, d, a, b, 10, 17, T11);
  248     SET(b, c, d, a, 11, 22, T12);
  249     SET(a, b, c, d, 12,  7, T13);
  250     SET(d, a, b, c, 13, 12, T14);
  251     SET(c, d, a, b, 14, 17, T15);
  252     SET(b, c, d, a, 15, 22, T16);
  253 #undef SET
  254 
  255      /* Round 2. */
  256      /* Let [abcd k s i] denote the operation
  257           a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
  258 #define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
  259 #define SET(a, b, c, d, k, s, Ti)\
  260   t = a + G(b,c,d) + X[k] + Ti;\
  261   a = ROTATE_LEFT(t, s) + b
  262      /* Do the following 16 operations. */
  263     SET(a, b, c, d,  1,  5, T17);
  264     SET(d, a, b, c,  6,  9, T18);
  265     SET(c, d, a, b, 11, 14, T19);
  266     SET(b, c, d, a,  0, 20, T20);
  267     SET(a, b, c, d,  5,  5, T21);
  268     SET(d, a, b, c, 10,  9, T22);
  269     SET(c, d, a, b, 15, 14, T23);
  270     SET(b, c, d, a,  4, 20, T24);
  271     SET(a, b, c, d,  9,  5, T25);
  272     SET(d, a, b, c, 14,  9, T26);
  273     SET(c, d, a, b,  3, 14, T27);
  274     SET(b, c, d, a,  8, 20, T28);
  275     SET(a, b, c, d, 13,  5, T29);
  276     SET(d, a, b, c,  2,  9, T30);
  277     SET(c, d, a, b,  7, 14, T31);
  278     SET(b, c, d, a, 12, 20, T32);
  279 #undef SET
  280 
  281      /* Round 3. */
  282      /* Let [abcd k s t] denote the operation
  283           a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
  284 #define H(x, y, z) ((x) ^ (y) ^ (z))
  285 #define SET(a, b, c, d, k, s, Ti)\
  286   t = a + H(b,c,d) + X[k] + Ti;\
  287   a = ROTATE_LEFT(t, s) + b
  288      /* Do the following 16 operations. */
  289     SET(a, b, c, d,  5,  4, T33);
  290     SET(d, a, b, c,  8, 11, T34);
  291     SET(c, d, a, b, 11, 16, T35);
  292     SET(b, c, d, a, 14, 23, T36);
  293     SET(a, b, c, d,  1,  4, T37);
  294     SET(d, a, b, c,  4, 11, T38);
  295     SET(c, d, a, b,  7, 16, T39);
  296     SET(b, c, d, a, 10, 23, T40);
  297     SET(a, b, c, d, 13,  4, T41);
  298     SET(d, a, b, c,  0, 11, T42);
  299     SET(c, d, a, b,  3, 16, T43);
  300     SET(b, c, d, a,  6, 23, T44);
  301     SET(a, b, c, d,  9,  4, T45);
  302     SET(d, a, b, c, 12, 11, T46);
  303     SET(c, d, a, b, 15, 16, T47);
  304     SET(b, c, d, a,  2, 23, T48);
  305 #undef SET
  306 
  307      /* Round 4. */
  308      /* Let [abcd k s t] denote the operation
  309           a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
  310 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
  311 #define SET(a, b, c, d, k, s, Ti)\
  312   t = a + I(b,c,d) + X[k] + Ti;\
  313   a = ROTATE_LEFT(t, s) + b
  314      /* Do the following 16 operations. */
  315     SET(a, b, c, d,  0,  6, T49);
  316     SET(d, a, b, c,  7, 10, T50);
  317     SET(c, d, a, b, 14, 15, T51);
  318     SET(b, c, d, a,  5, 21, T52);
  319     SET(a, b, c, d, 12,  6, T53);
  320     SET(d, a, b, c,  3, 10, T54);
  321     SET(c, d, a, b, 10, 15, T55);
  322     SET(b, c, d, a,  1, 21, T56);
  323     SET(a, b, c, d,  8,  6, T57);
  324     SET(d, a, b, c, 15, 10, T58);
  325     SET(c, d, a, b,  6, 15, T59);
  326     SET(b, c, d, a, 13, 21, T60);
  327     SET(a, b, c, d,  4,  6, T61);
  328     SET(d, a, b, c, 11, 10, T62);
  329     SET(c, d, a, b,  2, 15, T63);
  330     SET(b, c, d, a,  9, 21, T64);
  331 #undef SET
  332 
  333      /* Then perform the following additions. (That is increment each
  334         of the four registers by the value it had before this block
  335         was started.) */
  336     pms->abcd[0] += a;
  337     pms->abcd[1] += b;
  338     pms->abcd[2] += c;
  339     pms->abcd[3] += d;
  340 }
  341 
  342 void
  343 md5_init(md5_state_t *pms)
  344 {
  345     pms->count[0] = pms->count[1] = 0;
  346     pms->abcd[0] = 0x67452301;
  347     pms->abcd[1] = 0xefcdab89;
  348     pms->abcd[2] = 0x98badcfe;
  349     pms->abcd[3] = 0x10325476;
  350 }
  351 
  352 void
  353 md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
  354 {
  355     const md5_byte_t *p = data;
  356     int left = nbytes;
  357     int offset = (pms->count[0] >> 3) & 63;
  358     md5_word_t nbits = (md5_word_t)(nbytes << 3);
  359 
  360     if (nbytes <= 0)
  361     return;
  362 
  363     /* Update the message length. */
  364     pms->count[1] += nbytes >> 29;
  365     pms->count[0] += nbits;
  366     if (pms->count[0] < nbits)
  367     pms->count[1]++;
  368 
  369     /* Process an initial partial block. */
  370     if (offset) {
  371     int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
  372 
  373     memcpy(pms->buf + offset, p, copy);
  374     if (offset + copy < 64)
  375         return;
  376     p += copy;
  377     left -= copy;
  378     md5_process(pms, pms->buf);
  379     }
  380 
  381     /* Process full blocks. */
  382     for (; left >= 64; p += 64, left -= 64)
  383     md5_process(pms, p);
  384 
  385     /* Process a final partial block. */
  386     if (left)
  387     memcpy(pms->buf, p, left);
  388 }
  389 
  390 void
  391 md5_finish(md5_state_t *pms, md5_byte_t digest[16])
  392 {
  393     static const md5_byte_t pad[64] = {
  394     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  395     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  396     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  397     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  398     };
  399     md5_byte_t data[8];
  400     int i;
  401 
  402     /* Save the length before padding. */
  403     for (i = 0; i < 8; ++i)
  404     data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
  405     /* Pad to 56 bytes mod 64. */
  406     md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
  407     /* Append the length. */
  408     md5_append(pms, data, 8);
  409     for (i = 0; i < 16; ++i)
  410     digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
  411 }