md2.c
上传用户:zbbssh
上传日期:2007-01-08
资源大小:196k
文件大小:6k
源码类别:

CA认证

开发平台:

C/C++

  1. #pragma ident "@(#)md2.c 1.2 95/11/16 Sun Microsystems"
  2. /* 
  3.  * An implementation of the MD2 message-digest algorithm.
  4.  */
  5. #include <string.h>     /* For memcpy and memset */
  6. #include "md2.h"
  7. /*
  8.  * The temporary buffer is permanently allocated here because it
  9.  * makes the implementation easier, it's not a lot of overhead
  10.  * to pre-allocate, and it avoids having to wipe a separate temporary
  11.  * buffer in the transform routine each time.
  12.  */
  13. static void
  14. md2Transform(struct xMD2Context *md2)
  15. {
  16.         unsigned i, j;
  17.         unsigned char t;
  18.         /* Non-linear permutation table, derived from the digits of Pi. */
  19.         static unsigned char const permutation[256] = {
  20.              41, 46, 67,201,162,216,124,  1, 61, 54, 84,161,236,240,  6, 19,
  21.              98,167,  5,243,192,199,115,140,152,147, 43,217,188, 76,130,202,
  22.              30,155, 87, 60,253,212,224, 22,103, 66,111, 24,138, 23,229, 18,
  23.             190, 78,196,214,218,158,222, 73,160,251,245,142,187, 47,238,122,
  24.             169,104,121,145, 21,178,  7, 63,148,194, 16,137, 11, 34, 95, 33,
  25.             128,127, 93,154, 90,144, 50, 39, 53, 62,204,231,191,247,151,  3,
  26.             255, 25, 48,179, 72,165,181,209,215, 94,146, 42,172, 86,170,198,
  27.              79,184, 56,210,150,164,125,182,118,252,107,226,156,116,  4,241,
  28.              69,157,112, 89,100,113,135, 32,134, 91,207,101,230, 45,168,  2,
  29.              27, 96, 37,173,174,176,185,246, 28, 70, 97,105, 52, 64,126, 15,
  30.              85, 71,163, 35,221, 81,175, 58,195, 92,249,206,186,197,234, 38,
  31.              44, 83, 13,110,133, 40,132,  9,211,223,205,244, 65,129, 77, 82,
  32.             106,220, 55,200,108,193,171,250, 36,225,123,  8, 12,189,177, 74,
  33.             120,136,149,139,227, 99,232,109,233,203,213,254, 59,  0, 29, 57,
  34.             242,239,183, 14,102, 88,208,228,166,119,114,248,235,117, 75, 10,
  35.              49, 68, 80,180,143,237, 31, 26,219,153,141, 51,159, 17,131, 20
  36.         };
  37.         /* Fill in the temp buf */
  38.         for (i = 0; i < 16; i++)
  39.                 md2->buf[i+32] = md2->buf[i+16] ^ md2->buf[i];
  40.         /* Update the checksum in the last 16 bytes of the buf */
  41.         t = md2->buf[63];
  42.         for (i = 0; i < 16; i++)
  43.             t = md2->buf[48+i] ^= permutation[md2->buf[16+i] ^ t];
  44.         /* 18 passes of encryption over the first 48 bytes of the buf */
  45.         t = 0;
  46.         for (i = 0; i < 18; i++) {
  47.                 for (j = 0; j < 48; j++)
  48.                         t = md2->buf[j] ^= permutation[t];
  49.                 t += i;
  50.         }
  51. }
  52. void
  53. xMD2Init(struct xMD2Context *md2)
  54. {
  55.         memset(md2->buf, 0, sizeof(md2->buf));
  56.         md2->len = 0;
  57. }
  58. /*
  59.  * Take an arbitrary number of bytes, break it into 16-byte chunks,
  60.  * and apply the core transformation routine.  The transformation is
  61.  * done eagerly, so there is always at least one byte of free space in
  62.  * the input buffer.
  63.  */
  64. void
  65. xMD2Update(struct xMD2Context *md2, unsigned char const *buf, unsigned len)
  66. {
  67.         unsigned space = 16 - md2->len; /* Amount of free space */
  68.         /* No need to transform at all */
  69.         if (len < space) {
  70.                 memcpy(md2->buf+16+md2->len, buf, len);
  71.                 md2->len += len;
  72.                 return;
  73.         }
  74.         /* Copy in and transform the leading partial block (1 <= len <= 16) */
  75.         memcpy(md2->buf+16+md2->len, buf, space);
  76.         len -= space;
  77.         buf += space;
  78.         md2Transform(md2);
  79.         /* Copy in and transform intermediate partial blocks */
  80.         while (len >= 16) {
  81.                 memcpy(md2->buf+16, buf, 16);
  82.                 buf += 16;
  83.                 len -= 16;
  84.                 md2Transform(md2);
  85.         }
  86.         /* Copy in the trailing partial block (0 <= len <= 15) */
  87.         memcpy(md2->buf+16, buf, len);
  88.         md2->len = len;
  89. }
  90. /*
  91.  * Wrap up an MD2 computation.  Pad the last block and then append a
  92.  * running checksum.
  93.  */
  94. void
  95. xMD2Final(struct xMD2Context *md2, unsigned char hash[16])
  96. {
  97.         unsigned space = 16 - md2->len; /* Amount of free space */
  98.         /* Pad with "space" bytes of value "space" */
  99.         memset(md2->buf+16+md2->len, space, space);
  100.         md2Transform(md2);
  101.         /* Append checksum */
  102.         memcpy(md2->buf+16, md2->buf+48, 16);
  103.         md2Transform(md2);
  104.         /*
  105.          * The transform redundantly updates the checksum, but it's not worth
  106.          * optimizing away.
  107.          */
  108.         /* Copy hash out */
  109.         memcpy(hash, md2->buf, 16);
  110.         /* Burn the md2 context */
  111.         memset(md2, 0, sizeof(*md2));
  112. }
  113. #ifdef TEST
  114. #include <stdio.h>
  115. void
  116. printhash(char const *prompt, unsigned char const hash[16])
  117. {
  118.         int i;
  119.         fputs(prompt, stdout);
  120.         for (i = 0; i < 16; i++)
  121.                 printf(" %02X", hash[i]);
  122.         putchar('n');
  123. }
  124. int
  125. main(void)
  126. {
  127.         struct xMD2Context md2;
  128.         unsigned char hash[16];
  129.         unsigned i;
  130.         md2Init(&md2);
  131.         md2Final(&md2, hash);
  132.         printhash("Hash of "" is ", hash);
  133.         md2Init(&md2);
  134.         md2Update(&md2, (unsigned char const *)"a", 1);
  135.         md2Final(&md2, hash);
  136.         printhash("Hash of "a" is ", hash);
  137.         md2Init(&md2);
  138.         md2Update(&md2, (unsigned char const *)"abc", 3);
  139.         md2Final(&md2, hash);
  140.         printhash("Hash of "abc" is ", hash);
  141.         md2Init(&md2);
  142.         for (i = 0; i < 1000/5; i++)
  143.                 md2Update(&md2, (unsigned char const *)"aaaaa", 5);
  144.         md2Final(&md2, hash);
  145.         printhash("Hash of 1000 a's is ", hash);
  146.         md2Init(&md2);
  147.         for (i = 0; i < 1000/25; i++)
  148.                 md2Update(&md2, (unsigned char const *)"aaaaaaaaaaaaaaaaaaaaaaaaa", 25);
  149.         md2Final(&md2, hash);
  150.         printhash("Hash of 1000 a's is ", hash);
  151.         md2Init(&md2);
  152.         for (i = 0; i < 1000/125; i++)
  153.                 md2Update(&md2, (unsigned char const *)"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 125);
  154.         md2Final(&md2, hash);
  155.         printhash("Hash of 1000 a's is ", hash);
  156.         return 0;
  157. }
  158. #endif