The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/lib/libkern/md5c.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: md5c.c,v 1.10 2003/12/04 12:42:54 keihan Exp $ */
    2 
    3 /*
    4  * This file is derived from the RSA Data Security, Inc. MD5 Message-Digest
    5  * Algorithm and has been modifed by Jason R. Thorpe <thorpej@NetBSD.org>
    6  * for portability and formatting.
    7  */
    8 
    9 /*
   10  * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
   11  * rights reserved.
   12  *
   13  * License to copy and use this software is granted provided that it
   14  * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
   15  * Algorithm" in all material mentioning or referencing this software
   16  * or this function.
   17  *
   18  * License is also granted to make and use derivative works provided
   19  * that such works are identified as "derived from the RSA Data
   20  * Security, Inc. MD5 Message-Digest Algorithm" in all material
   21  * mentioning or referencing the derived work.
   22  *
   23  * RSA Data Security, Inc. makes no representations concerning either
   24  * the merchantability of this software or the suitability of this
   25  * software for any particular purpose. It is provided "as is"
   26  * without express or implied warranty of any kind.
   27  *
   28  * These notices must be retained in any copies of any part of this
   29  * documentation and/or software.
   30  */
   31 
   32 #include <sys/param.h>
   33 #if defined(_KERNEL) || defined(_STANDALONE)
   34 #include <sys/md5.h>
   35 #include <lib/libkern/libkern.h>
   36 #else
   37 #include "namespace.h"
   38 #include <string.h>
   39 #include <md5.h>
   40 #endif /* _KERNEL || _STANDALONE */
   41 
   42 #define ZEROIZE(d, l)           memset((d), 0, (l))
   43 
   44 typedef unsigned char *POINTER;
   45 typedef u_int16_t UINT2;
   46 typedef u_int32_t UINT4;
   47 
   48 /*
   49  * Constants for MD5Transform routine.
   50  */
   51 #define S11 7
   52 #define S12 12
   53 #define S13 17
   54 #define S14 22
   55 #define S21 5
   56 #define S22 9
   57 #define S23 14
   58 #define S24 20
   59 #define S31 4
   60 #define S32 11
   61 #define S33 16
   62 #define S34 23
   63 #define S41 6
   64 #define S42 10
   65 #define S43 15
   66 #define S44 21
   67 
   68 #if !defined(_KERNEL) && !defined(_STANDALONE) && defined(__weak_alias)
   69 __weak_alias(MD5Init,_MD5Init);
   70 __weak_alias(MD5Update,_MD5Update);
   71 __weak_alias(MD5Final,_MD5Final);
   72 #endif
   73 
   74 static void MD5Transform __P((UINT4 [4], const unsigned char [64]));
   75 
   76 static void Encode __P((unsigned char *, UINT4 *, unsigned int));
   77 static void Decode __P((UINT4 *, const unsigned char *, unsigned int));
   78 
   79 /*
   80  * Encodes input (UINT4) into output (unsigned char).  Assumes len is
   81  * a multiple of 4.
   82  */
   83 static void
   84 Encode (output, input, len)
   85         unsigned char *output;
   86         UINT4 *input;
   87         unsigned int len;
   88 {
   89         unsigned int i, j;
   90 
   91         for (i = 0, j = 0; j < len; i++, j += 4) {
   92                 output[j] = (unsigned char)(input[i] & 0xff);
   93                 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
   94                 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
   95                 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
   96         }
   97 }
   98 
   99 /*
  100  * Decodes input (unsigned char) into output (UINT4).  Assumes len is
  101  * a multiple of 4.
  102  */
  103 static void
  104 Decode (output, input, len)
  105         UINT4 *output;
  106         const unsigned char *input;
  107         unsigned int len;
  108 {
  109         unsigned int i, j;
  110 
  111         for (i = 0, j = 0; j < len; i++, j += 4)
  112                 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
  113                     (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
  114 }
  115 
  116 static const unsigned char PADDING[64] = {
  117         0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  118         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  119         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  120 };
  121 
  122 /*
  123  * F, G, H and I are basic MD5 functions.
  124  */
  125 #define F(x, y, z)      (((x) & (y)) | ((~x) & (z)))
  126 #define G(x, y, z)      (((x) & (z)) | ((y) & (~z)))
  127 #define H(x, y, z)      ((x) ^ (y) ^ (z))
  128 #define I(x, y, z)      ((y) ^ ((x) | (~z)))
  129 
  130 /*
  131  * ROTATE_LEFT rotates x left n bits.
  132  */
  133 #define ROTATE_LEFT(x, n)       (((x) << (n)) | ((x) >> (32-(n))))
  134 
  135 /*
  136  * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
  137  * Rotation is separate from addition to prevent recomputation.
  138  */
  139 #define FF(a, b, c, d, x, s, ac) { \
  140         (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
  141         (a) = ROTATE_LEFT ((a), (s)); \
  142         (a) += (b); \
  143 }
  144 
  145 #define GG(a, b, c, d, x, s, ac) { \
  146         (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
  147         (a) = ROTATE_LEFT ((a), (s)); \
  148         (a) += (b); \
  149 }
  150 
  151 #define HH(a, b, c, d, x, s, ac) { \
  152         (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
  153         (a) = ROTATE_LEFT ((a), (s)); \
  154         (a) += (b); \
  155 }
  156 
  157 #define II(a, b, c, d, x, s, ac) { \
  158         (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
  159         (a) = ROTATE_LEFT ((a), (s)); \
  160         (a) += (b); \
  161 }
  162 
  163 /*
  164  * MD5 initialization. Begins an MD5 operation, writing a new context.
  165  */
  166 void
  167 MD5Init(context)
  168         MD5_CTX *context;               /* context */
  169 {
  170 
  171         context->count[0] = context->count[1] = 0;
  172 
  173         /* Load magic initialization constants. */
  174         context->state[0] = 0x67452301;
  175         context->state[1] = 0xefcdab89;
  176         context->state[2] = 0x98badcfe;
  177         context->state[3] = 0x10325476;
  178 }
  179 
  180 /*
  181  * MD5 block update operation.  Continues an MD5 message-digest
  182  * operation, processing another message block, and updating the
  183  * context.
  184  */
  185 void
  186 MD5Update(context, input, inputLen)
  187         MD5_CTX *context;               /* context */
  188         const unsigned char *input;     /* input block */
  189         unsigned int inputLen;          /* length of input block */
  190 {
  191         unsigned int i, idx, partLen;
  192 
  193         /* Compute number of bytes mod 64 */
  194         idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
  195 
  196         /* Update number of bits */
  197         if ((context->count[0] += ((UINT4)inputLen << 3))
  198             < ((UINT4)inputLen << 3))
  199                 context->count[1]++;
  200         context->count[1] += ((UINT4)inputLen >> 29);
  201 
  202         partLen = 64 - idx;
  203 
  204         /* Transform as many times as possible. */
  205         if (inputLen >= partLen) {
  206                 /* LINTED const castaway ok */
  207                 memcpy((POINTER)&context->buffer[idx],
  208                     (POINTER)input, partLen);
  209                 MD5Transform(context->state, context->buffer);
  210 
  211                 for (i = partLen; i + 63 < inputLen; i += 64)
  212                         MD5Transform(context->state, &input[i]);
  213 
  214                 idx = 0;
  215         } else
  216                 i = 0;
  217 
  218         /* Buffer remaining input */
  219         /* LINTED const castaway ok */
  220         memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i],
  221             inputLen - i);
  222 }
  223 
  224 /*
  225  * MD5 finalization.  Ends an MD5 message-digest operation, writing the
  226  * message digest and zeroing the context.
  227  */
  228 void
  229 MD5Final(digest, context)
  230         unsigned char digest[16];       /* message digest */
  231         MD5_CTX *context;               /* context */
  232 {
  233         unsigned char bits[8];
  234         unsigned int idx, padLen;
  235 
  236         /* Save number of bits */
  237         Encode(bits, context->count, 8);
  238 
  239         /* Pad out to 56 mod 64. */
  240         idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
  241         padLen = (idx < 56) ? (56 - idx) : (120 - idx);
  242         MD5Update (context, PADDING, padLen);
  243 
  244         /* Append length (before padding) */
  245         MD5Update(context, bits, 8);
  246 
  247         /* Store state in digest */
  248         Encode(digest, context->state, 16);
  249 
  250         /* Zeroize sensitive information. */
  251         ZEROIZE((POINTER)(void *)context, sizeof(*context));
  252 }
  253 
  254 /*
  255  * MD5 basic transformation. Transforms state based on block.
  256  */
  257 static void
  258 MD5Transform(state, block)
  259         UINT4 state[4];
  260         const unsigned char block[64];
  261 {
  262         UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
  263 
  264         Decode(x, block, 64);
  265 
  266         /* Round 1 */
  267         FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
  268         FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
  269         FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
  270         FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
  271         FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
  272         FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
  273         FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
  274         FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
  275         FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
  276         FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
  277         FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
  278         FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
  279         FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
  280         FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
  281         FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
  282         FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
  283 
  284         /* Round 2 */
  285         GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
  286         GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
  287         GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
  288         GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
  289         GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
  290         GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
  291         GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
  292         GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
  293         GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
  294         GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
  295         GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
  296         GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
  297         GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
  298         GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
  299         GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
  300         GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
  301 
  302         /* Round 3 */
  303         HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
  304         HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
  305         HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
  306         HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
  307         HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
  308         HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
  309         HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
  310         HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
  311         HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
  312         HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
  313         HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
  314         HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
  315         HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
  316         HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
  317         HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
  318         HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
  319 
  320         /* Round 4 */
  321         II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
  322         II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
  323         II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
  324         II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
  325         II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
  326         II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
  327         II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
  328         II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
  329         II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
  330         II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
  331         II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
  332         II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
  333         II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
  334         II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
  335         II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
  336         II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
  337 
  338         state[0] += a;
  339         state[1] += b;
  340         state[2] += c;
  341         state[3] += d;
  342 
  343         /* Zeroize sensitive information. */
  344         ZEROIZE((POINTER)(void *)x, sizeof (x));
  345 }

Cache object: ed4ca853417bf5db29ecee29e4614e86


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.