home *** CD-ROM | disk | FTP | other *** search
/ ftp.shrubbery.net / 2015-02-07.ftp.shrubbery.net.tar / ftp.shrubbery.net / pub / tac_plus / tacacs+-F4.0.4.27a.tar.gz / tacacs+-F4.0.4.27a.tar / tacacs+-F4.0.4.27a / md5.c < prev    next >
C/C++ Source or Header  |  2012-01-23  |  12KB  |  364 lines

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