"Fossies" - the Fresh Open Source Software Archive

Member "geoipupdate-3.1.1/bin/md5.c" (23 Aug 2018, 10981 Bytes) of package /linux/misc/geoipupdate-3.1.1.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.

    1 /* md5.c - MD5 Message-Digest Algorithm
    2  * Copyright (C) 1995, 1996, 1998, 1999,
    3  *               2000, 2001 Free Software Foundation, Inc.
    4  *
    5  * This program is free software; you can redistribute it and/or modify it
    6  * under the terms of the GNU General Public License as published by the
    7  * Free Software Foundation; either version 2, or (at your option) any
    8  * later version.
    9  *
   10  * This program is distributed in the hope that it will be useful,
   11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13  * GNU General Public License for more details.
   14  *
   15  * You should have received a copy of the GNU General Public License
   16  * along with this program; if not, write to the Free Software Foundation,
   17  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   18  *
   19  * According to the definition of MD5 in RFC 1321 from April 1992.
   20  * NOTE: This is *not* the same file as the one from glibc.
   21  */
   22 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
   23 /* Heavily modified for GnuPG by <wk@gnupg.org> */
   24 
   25 #include <assert.h>
   26 #include <stdio.h>
   27 #include <stdlib.h>
   28 #include <string.h>
   29 
   30 #include "types.h"
   31 
   32 #ifdef WORDS_BIGENDIAN
   33 #define BIG_ENDIAN_HOST
   34 #endif
   35 
   36 //#define DIM(v) (sizeof(v)/sizeof((v)[0]))
   37 #define wipememory2(_ptr, _set, _len)                                          \
   38     do {                                                                       \
   39         volatile char *_vptr = (volatile char *)(_ptr);                        \
   40         size_t _vlen = (_len);                                                 \
   41         while (_vlen) {                                                        \
   42             *_vptr = (_set);                                                   \
   43             _vptr++;                                                           \
   44             _vlen--;                                                           \
   45         }                                                                      \
   46     } while (0)
   47 #define wipememory(_ptr, _len) wipememory2(_ptr, 0, _len)
   48 #define rol(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
   49 
   50 typedef struct {
   51     u32 A, B, C, D; /* chaining variables */
   52     u32 nblocks;
   53     byte buf[64];
   54     int count;
   55 } MD5_CONTEXT;
   56 
   57 void md5_init(MD5_CONTEXT *ctx) {
   58     ctx->A = 0x67452301;
   59     ctx->B = 0xefcdab89;
   60     ctx->C = 0x98badcfe;
   61     ctx->D = 0x10325476;
   62 
   63     ctx->nblocks = 0;
   64     ctx->count = 0;
   65 }
   66 
   67 /* These are the four functions used in the four steps of the MD5 algorithm
   68    and defined in the RFC 1321.  The first function is a little bit optimized
   69    (as found in Colin Plumbs public domain implementation).  */
   70 /* #define FF(b, c, d) ((b & c) | (~b & d)) */
   71 #define FF(b, c, d) (d ^ (b & (c ^ d)))
   72 #define FG(b, c, d) FF(d, b, c)
   73 #define FH(b, c, d) (b ^ c ^ d)
   74 #define FI(b, c, d) (c ^ (b | ~d))
   75 
   76 static void burn_stack(int bytes) {
   77     char buf[128];
   78 
   79     wipememory(buf, sizeof buf);
   80     bytes -= sizeof buf;
   81     if (bytes > 0) {
   82         burn_stack(bytes);
   83     }
   84 }
   85 
   86 /****************
   87  * transform n*64 bytes
   88  */
   89 static void
   90 /*transform( MD5_CONTEXT *ctx, const void *buffer, size_t len )*/
   91 transform(MD5_CONTEXT *ctx, byte *data) {
   92     u32 correct_words[16];
   93     u32 A = ctx->A;
   94     u32 B = ctx->B;
   95     u32 C = ctx->C;
   96     u32 D = ctx->D;
   97     u32 *cwp = correct_words;
   98 
   99 #ifdef BIG_ENDIAN_HOST
  100     {
  101         int i;
  102         byte *p2, *p1;
  103         for (i = 0, p1 = data, p2 = (byte *)correct_words; i < 16;
  104              i++, p2 += 4) {
  105             p2[3] = *p1++;
  106             p2[2] = *p1++;
  107             p2[1] = *p1++;
  108             p2[0] = *p1++;
  109         }
  110     }
  111 #else
  112     memcpy(correct_words, data, 64);
  113 #endif
  114 
  115 #define OP(a, b, c, d, s, T)                                                   \
  116     do {                                                                       \
  117         a += FF(b, c, d) + (*cwp++) + T;                                       \
  118         a = rol(a, s);                                                         \
  119         a += b;                                                                \
  120     } while (0)
  121 
  122     /* Before we start, one word about the strange constants.
  123          They are defined in RFC 1321 as
  124 
  125          T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
  126      */
  127 
  128     /* Round 1.  */
  129     OP(A, B, C, D, 7, 0xd76aa478);
  130     OP(D, A, B, C, 12, 0xe8c7b756);
  131     OP(C, D, A, B, 17, 0x242070db);
  132     OP(B, C, D, A, 22, 0xc1bdceee);
  133     OP(A, B, C, D, 7, 0xf57c0faf);
  134     OP(D, A, B, C, 12, 0x4787c62a);
  135     OP(C, D, A, B, 17, 0xa8304613);
  136     OP(B, C, D, A, 22, 0xfd469501);
  137     OP(A, B, C, D, 7, 0x698098d8);
  138     OP(D, A, B, C, 12, 0x8b44f7af);
  139     OP(C, D, A, B, 17, 0xffff5bb1);
  140     OP(B, C, D, A, 22, 0x895cd7be);
  141     OP(A, B, C, D, 7, 0x6b901122);
  142     OP(D, A, B, C, 12, 0xfd987193);
  143     OP(C, D, A, B, 17, 0xa679438e);
  144     OP(B, C, D, A, 22, 0x49b40821);
  145 
  146 #undef OP
  147 #define OP(f, a, b, c, d, k, s, T)                                             \
  148     do {                                                                       \
  149         a += f(b, c, d) + correct_words[k] + T;                                \
  150         a = rol(a, s);                                                         \
  151         a += b;                                                                \
  152     } while (0)
  153 
  154     /* Round 2.  */
  155     OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
  156     OP(FG, D, A, B, C, 6, 9, 0xc040b340);
  157     OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
  158     OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
  159     OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
  160     OP(FG, D, A, B, C, 10, 9, 0x02441453);
  161     OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
  162     OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
  163     OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
  164     OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
  165     OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
  166     OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
  167     OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
  168     OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
  169     OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
  170     OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
  171 
  172     /* Round 3.  */
  173     OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
  174     OP(FH, D, A, B, C, 8, 11, 0x8771f681);
  175     OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
  176     OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
  177     OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
  178     OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
  179     OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
  180     OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
  181     OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
  182     OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
  183     OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
  184     OP(FH, B, C, D, A, 6, 23, 0x04881d05);
  185     OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
  186     OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
  187     OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
  188     OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
  189 
  190     /* Round 4.  */
  191     OP(FI, A, B, C, D, 0, 6, 0xf4292244);
  192     OP(FI, D, A, B, C, 7, 10, 0x432aff97);
  193     OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
  194     OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
  195     OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
  196     OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
  197     OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
  198     OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
  199     OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
  200     OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
  201     OP(FI, C, D, A, B, 6, 15, 0xa3014314);
  202     OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
  203     OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
  204     OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
  205     OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
  206     OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
  207 
  208     /* Put checksum in context given as argument.  */
  209     ctx->A += A;
  210     ctx->B += B;
  211     ctx->C += C;
  212     ctx->D += D;
  213 }
  214 
  215 /* The routine updates the message-digest context to
  216  * account for the presence of each of the characters inBuf[0..inLen-1]
  217  * in the message whose digest is being computed.
  218  */
  219 void md5_write(MD5_CONTEXT *hd, byte *inbuf, size_t inlen) {
  220     if (hd->count == 64) { /* flush the buffer */
  221         transform(hd, hd->buf);
  222         burn_stack(80 + 6 * sizeof(void *));
  223         hd->count = 0;
  224         hd->nblocks++;
  225     }
  226     if (!inbuf) {
  227         return;
  228     }
  229     if (hd->count) {
  230         for (; inlen && hd->count < 64; inlen--) {
  231             hd->buf[hd->count++] = *inbuf++;
  232         }
  233         md5_write(hd, NULL, 0);
  234         if (!inlen) {
  235             return;
  236         }
  237     }
  238 
  239     while (inlen >= 64) {
  240         transform(hd, inbuf);
  241         hd->count = 0;
  242         hd->nblocks++;
  243         inlen -= 64;
  244         inbuf += 64;
  245     }
  246     burn_stack(80 + 6 * sizeof(void *));
  247     for (; inlen && hd->count < 64; inlen--) {
  248         hd->buf[hd->count++] = *inbuf++;
  249     }
  250 }
  251 /* The routine final terminates the message-digest computation and
  252  * ends with the desired message digest in mdContext->digest[0...15].
  253  * The handle is prepared for a new MD5 cycle.
  254  * Returns 16 bytes representing the digest.
  255  */
  256 
  257 void md5_final(MD5_CONTEXT *hd) {
  258     u32 t, msb, lsb;
  259     byte *p;
  260 
  261     md5_write(hd, NULL, 0); /* flush */
  262     ;
  263 
  264     t = hd->nblocks;
  265     /* multiply by 64 to make a byte count */
  266     lsb = t << 6;
  267     msb = t >> 26;
  268     /* add the count */
  269     t = lsb;
  270     if ((lsb += hd->count) < t) {
  271         msb++;
  272     }
  273     /* multiply by 8 to make a bit count */
  274     t = lsb;
  275     lsb <<= 3;
  276     msb <<= 3;
  277     msb |= t >> 29;
  278 
  279     if (hd->count < 56) {            /* enough room */
  280         hd->buf[hd->count++] = 0x80; /* pad */
  281         while (hd->count < 56) {
  282             hd->buf[hd->count++] = 0; /* pad */
  283         }
  284     } else {                         /* need one extra block */
  285         hd->buf[hd->count++] = 0x80; /* pad character */
  286         while (hd->count < 64) {
  287             hd->buf[hd->count++] = 0;
  288         }
  289         md5_write(hd, NULL, 0); /* flush */
  290         ;
  291         memset(hd->buf, 0, 56); /* fill next block with zeroes */
  292     }
  293     /* append the 64 bit count */
  294     hd->buf[56] = lsb;
  295     hd->buf[57] = lsb >> 8;
  296     hd->buf[58] = lsb >> 16;
  297     hd->buf[59] = lsb >> 24;
  298     hd->buf[60] = msb;
  299     hd->buf[61] = msb >> 8;
  300     hd->buf[62] = msb >> 16;
  301     hd->buf[63] = msb >> 24;
  302     transform(hd, hd->buf);
  303     burn_stack(80 + 6 * sizeof(void *));
  304 
  305     p = hd->buf;
  306 #ifdef BIG_ENDIAN_HOST
  307 #define X(a)                                                                   \
  308     do {                                                                       \
  309         *p++ = hd->a;                                                          \
  310         *p++ = hd->a >> 8;                                                     \
  311         *p++ = hd->a >> 16;                                                    \
  312         *p++ = hd->a >> 24;                                                    \
  313     } while (0)
  314 #else /* little endian */
  315 #define X(a)                                                                   \
  316     do {                                                                       \
  317         *(u32 *)p = hd->a;                                                     \
  318         p += 4;                                                                \
  319     } while (0)
  320 #endif
  321     X(A);
  322     X(B);
  323     X(C);
  324     X(D);
  325 #undef X
  326 }