Advertisement
FlyFar

md5/md5.c

May 16th, 2024
440
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.10 KB | Cybersecurity | 0 0
  1.  
  2.  
  3. #ifdef HAVE_CONFIG_H
  4. # include <config.h>
  5. #endif
  6.  
  7. #include <sys/types.h>
  8.  
  9. #if STDC_HEADERS || defined _LIBC
  10. # include <stdlib.h>
  11. # include <string.h>
  12. #else
  13. # ifndef HAVE_MEMCPY
  14. #  define memcpy(d, s, n) bcopy ((s), (d), (n))
  15. # endif
  16. #endif
  17.  
  18. #include "md5.h"
  19.  
  20. #ifdef _LIBC
  21. # include <endian.h>
  22. # if __BYTE_ORDER == __BIG_ENDIAN
  23. #  define WORDS_BIGENDIAN 1
  24. # endif
  25. #endif
  26.  
  27. #ifdef WORDS_BIGENDIAN
  28. # define SWAP(n)                            \
  29.     (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
  30. #else
  31. # define SWAP(n) (n)
  32. #endif
  33.  
  34.  
  35. static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
  36.  
  37.  
  38. /* Initialize structure containing state of computation.
  39.    (RFC 1321, 3.3: Step 3)  */
  40. void
  41. md5_init_ctx (ctx)
  42.      struct md5_ctx *ctx;
  43. {
  44.   ctx->A = 0x67452301;
  45.   ctx->B = 0xefcdab89;
  46.   ctx->C = 0x98badcfe;
  47.   ctx->D = 0x10325476;
  48.  
  49.   ctx->total[0] = ctx->total[1] = 0;
  50.   ctx->buflen = 0;
  51. }
  52.  
  53.  
  54. void *
  55. md5_read_ctx (ctx, resbuf)
  56.      const struct md5_ctx *ctx;
  57.      void *resbuf;
  58. {
  59.   ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
  60.   ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
  61.   ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
  62.   ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
  63.  
  64.   return resbuf;
  65. }
  66.  
  67.  
  68.   md5_uint32 bytes = ctx->buflen;
  69.   size_t pad;
  70.  
  71.   /* Now count remaining bytes.  */
  72.   ctx->total[0] += bytes;
  73.   if (ctx->total[0] < bytes)
  74.     ++ctx->total[1];
  75.  
  76.   pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
  77.   memcpy (&ctx->buffer[bytes], fillbuf, pad);
  78.  
  79.   /* Put the 64-bit file length in *bits* at the end of the buffer.  */
  80.   *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
  81.   *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
  82.                             (ctx->total[0] >> 29));
  83.  
  84.   /* Process last bytes.  */
  85.   md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
  86.  
  87.   return md5_read_ctx (ctx, resbuf);
  88. }
  89.  
  90.  
  91. int
  92. md5_stream (stream, resblock)
  93.      FILE *stream;
  94.      void *resblock;
  95. {
  96.   /* Important: BLOCKSIZE must be a multiple of 64.  */
  97. #define BLOCKSIZE 4096
  98.   struct md5_ctx ctx;
  99.   char buffer[BLOCKSIZE + 72];
  100.   size_t sum;
  101.  
  102.   /* Initialize the computation context.  */
  103.   md5_init_ctx (&ctx);
  104.  
  105.   /* Iterate over full file contents.  */
  106.   while (1)
  107.     {
  108.      
  109.       size_t n;
  110.       sum = 0;
  111.  
  112.       /* Read block.  Take care for partial reads.  */
  113.       do
  114.     {
  115.       n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
  116.  
  117.       sum += n;
  118.     }
  119.       while (sum < BLOCKSIZE && n != 0);
  120.       if (n == 0 && ferror (stream))
  121.         return 1;
  122.  
  123.       /* If end of file is reached, end the loop.  */
  124.       if (n == 0)
  125.     break;
  126.  
  127.       /* Process buffer with BLOCKSIZE bytes.  Note that
  128.             BLOCKSIZE % 64 == 0
  129.        */
  130.       md5_process_block (buffer, BLOCKSIZE, &ctx);
  131.     }
  132.  
  133.   /* Add the last bytes if necessary.  */
  134.   if (sum > 0)
  135.     md5_process_bytes (buffer, sum, &ctx);
  136.  
  137.   /* Construct result in desired memory.  */
  138.   md5_finish_ctx (&ctx, resblock);
  139.   return 0;
  140. }
  141.  
  142.  
  143. void *
  144. md5_buffer (buffer, len, resblock)
  145.      const char *buffer;
  146.      size_t len;
  147.      void *resblock;
  148. {
  149.   struct md5_ctx ctx;
  150.  
  151.   /* Initialize the computation context.  */
  152.   md5_init_ctx (&ctx);
  153.  
  154.  
  155.   md5_process_bytes (buffer, len, &ctx);
  156.  
  157.   /* Put result in desired memory area.  */
  158.   return md5_finish_ctx (&ctx, resblock);
  159. }
  160.  
  161.  
  162. void
  163. md5_process_bytes (buffer, len, ctx)
  164.      const void *buffer;
  165.      size_t len;
  166.      struct md5_ctx *ctx;
  167. {
  168.  
  169.   if (ctx->buflen != 0)
  170.     {
  171.       size_t left_over = ctx->buflen;
  172.       size_t add = 128 - left_over > len ? len : 128 - left_over;
  173.  
  174.       memcpy (&ctx->buffer[left_over], buffer, add);
  175.       ctx->buflen += add;
  176.  
  177.       if (left_over + add > 64)
  178.     {
  179.       md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx);
  180.       memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
  181.           (left_over + add) & 63);
  182.       ctx->buflen = (left_over + add) & 63;
  183.     }
  184.  
  185.       buffer = (const char *) buffer + add;
  186.       len -= add;
  187.     }
  188.  
  189.   /* Process available complete blocks.  */
  190.   if (len > 64)
  191.     {
  192.       md5_process_block (buffer, len & ~63, ctx);
  193.       buffer = (const char *) buffer + (len & ~63);
  194.       len &= 63;
  195.     }
  196.  
  197.   /* Move remaining bytes in internal buffer.  */
  198.   if (len > 0)
  199.     {
  200.       memcpy (ctx->buffer, buffer, len);
  201.       ctx->buflen = len;
  202.     }
  203. }
  204.  
  205.  
  206.  
  207. #define FF(b, c, d) (d ^ (b & (c ^ d)))
  208. #define FG(b, c, d) FF (d, b, c)
  209. #define FH(b, c, d) (b ^ c ^ d)
  210. #define FI(b, c, d) (c ^ (b | ~d))
  211.  
  212.  
  213. void
  214. md5_process_block (buffer, len, ctx)
  215.      const void *buffer;
  216.      size_t len;
  217.      struct md5_ctx *ctx;
  218. {
  219.   md5_uint32 correct_words[16];
  220.   const md5_uint32 *words = buffer;
  221.   size_t nwords = len / sizeof (md5_uint32);
  222.   const md5_uint32 *endp = words + nwords;
  223.   md5_uint32 A = ctx->A;
  224.   md5_uint32 B = ctx->B;
  225.   md5_uint32 C = ctx->C;
  226.   md5_uint32 D = ctx->D;
  227.  
  228.  
  229.   ctx->total[0] += len;
  230.   if (ctx->total[0] < len)
  231.     ++ctx->total[1];
  232.  
  233.   /* Process all bytes in the buffer with 64 bytes in each round of
  234.      the loop.  */
  235.   while (words < endp)
  236.     {
  237.       md5_uint32 *cwp = correct_words;
  238.       md5_uint32 A_save = A;
  239.       md5_uint32 B_save = B;
  240.       md5_uint32 C_save = C;
  241.       md5_uint32 D_save = D;
  242.  
  243.      
  244.  
  245. #define OP(a, b, c, d, s, T)                        \
  246.       do                                \
  247.         {                               \
  248.       a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;     \
  249.       ++words;                          \
  250.       CYCLIC (a, s);                        \
  251.       a += b;                           \
  252.         }                               \
  253.       while (0)
  254.  
  255.      
  256. #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
  257.  
  258.       /* Before we start, one word to the strange constants.
  259.      They are defined in RFC 1321 as
  260.  
  261.      T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
  262.        */
  263.  
  264.       /* Round 1.  */
  265.       OP (A, B, C, D,  7, 0xd76aa478);
  266.       OP (D, A, B, C, 12, 0xe8c7b756);
  267.       OP (C, D, A, B, 17, 0x242070db);
  268.       OP (B, C, D, A, 22, 0xc1bdceee);
  269.       OP (A, B, C, D,  7, 0xf57c0faf);
  270.       OP (D, A, B, C, 12, 0x4787c62a);
  271.       OP (C, D, A, B, 17, 0xa8304613);
  272.       OP (B, C, D, A, 22, 0xfd469501);
  273.       OP (A, B, C, D,  7, 0x698098d8);
  274.       OP (D, A, B, C, 12, 0x8b44f7af);
  275.       OP (C, D, A, B, 17, 0xffff5bb1);
  276.       OP (B, C, D, A, 22, 0x895cd7be);
  277.       OP (A, B, C, D,  7, 0x6b901122);
  278.       OP (D, A, B, C, 12, 0xfd987193);
  279.       OP (C, D, A, B, 17, 0xa679438e);
  280.       OP (B, C, D, A, 22, 0x49b40821);
  281.  
  282.      
  283. #undef OP
  284. #define OP(f, a, b, c, d, k, s, T)                  \
  285.       do                                \
  286.     {                               \
  287.       a += f (b, c, d) + correct_words[k] + T;          \
  288.       CYCLIC (a, s);                        \
  289.       a += b;                           \
  290.     }                               \
  291.       while (0)
  292.  
  293.       /* Round 2.  */
  294.       OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
  295.       OP (FG, D, A, B, C,  6,  9, 0xc040b340);
  296.       OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
  297.       OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
  298.       OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
  299.       OP (FG, D, A, B, C, 10,  9, 0x02441453);
  300.       OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
  301.       OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
  302.       OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
  303.       OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
  304.       OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
  305.       OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
  306.       OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
  307.       OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
  308.       OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
  309.       OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
  310.  
  311.       /* Round 3.  */
  312.       OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
  313.       OP (FH, D, A, B, C,  8, 11, 0x8771f681);
  314.       OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
  315.       OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
  316.       OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
  317.       OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
  318.       OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
  319.       OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
  320.       OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
  321.       OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
  322.       OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
  323.       OP (FH, B, C, D, A,  6, 23, 0x04881d05);
  324.       OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
  325.       OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
  326.       OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
  327.       OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
  328.  
  329.       /* Round 4.  */
  330.       OP (FI, A, B, C, D,  0,  6, 0xf4292244);
  331.       OP (FI, D, A, B, C,  7, 10, 0x432aff97);
  332.       OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
  333.       OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
  334.       OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
  335.       OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
  336.       OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
  337.       OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
  338.       OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
  339.       OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
  340.       OP (FI, C, D, A, B,  6, 15, 0xa3014314);
  341.       OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
  342.       OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
  343.       OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
  344.       OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
  345.       OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
  346.  
  347.       /* Add the starting values of the context.  */
  348.       A += A_save;
  349.       B += B_save;
  350.       C += C_save;
  351.       D += D_save;
  352.     }
  353.  
  354.   /* Put checksum in context given as argument.  */
  355.   ctx->A = A;
  356.   ctx->B = B;
  357.   ctx->C = C;
  358.   ctx->D = D;
  359. }
  360.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement