Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmd2.c
Go to the documentation of this file.
00001 /* 00002 * dlls/rsaenh/md2.c 00003 * MD2 (RFC 1319) hash function implementation by Tom St Denis 00004 * 00005 * Copyright 2004 Michael Jung 00006 * Based on public domain code by Tom St Denis (tomstdenis@iahu.ca) 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00021 */ 00022 00023 /* 00024 * This file contains code from the LibTomCrypt cryptographic 00025 * library written by Tom St Denis (tomstdenis@iahu.ca). LibTomCrypt 00026 * is in the public domain. The code in this file is tailored to 00027 * special requirements. Take a look at http://libtomcrypt.org for the 00028 * original version. 00029 */ 00030 00031 #include "tomcrypt.h" 00032 00033 static const unsigned char PI_SUBST[256] = { 00034 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 00035 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 00036 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 00037 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 00038 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, 00039 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, 00040 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, 00041 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, 00042 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, 00043 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, 00044 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, 00045 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 00046 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 00047 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 00048 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, 00049 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, 00050 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, 00051 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 00052 }; 00053 00054 /* adds 16 bytes to the checksum */ 00055 static void md2_update_chksum(md2_state *md2) 00056 { 00057 int j; 00058 unsigned char L; 00059 L = md2->chksum[15]; 00060 for (j = 0; j < 16; j++) { 00061 00062 /* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say 00063 otherwise. 00064 */ 00065 L = (md2->chksum[j] ^= PI_SUBST[(int)(md2->buf[j] ^ L)] & 255); 00066 } 00067 } 00068 00069 static void md2_compress(md2_state *md2) 00070 { 00071 int j, k; 00072 unsigned char t; 00073 00074 /* copy block */ 00075 for (j = 0; j < 16; j++) { 00076 md2->X[16+j] = md2->buf[j]; 00077 md2->X[32+j] = md2->X[j] ^ md2->X[16+j]; 00078 } 00079 00080 t = 0; 00081 00082 /* do 18 rounds */ 00083 for (j = 0; j < 18; j++) { 00084 for (k = 0; k < 48; k++) { 00085 t = (md2->X[k] ^= PI_SUBST[(int)(t & 255)]); 00086 } 00087 t = (t + (unsigned char)j) & 255; 00088 } 00089 } 00090 00091 int md2_init(md2_state *md2) 00092 { 00093 /* MD2 uses a zero'ed state... */ 00094 memset(md2->X, 0, sizeof(md2->X)); 00095 memset(md2->chksum, 0, sizeof(md2->chksum)); 00096 memset(md2->buf, 0, sizeof(md2->buf)); 00097 md2->curlen = 0; 00098 return CRYPT_OK; 00099 } 00100 00101 int md2_process(md2_state *md2, const unsigned char *buf, unsigned long len) 00102 { 00103 unsigned long n; 00104 00105 if (md2->curlen > sizeof(md2->buf)) { 00106 return CRYPT_INVALID_ARG; 00107 } 00108 while (len > 0) { 00109 n = MIN(len, (16 - md2->curlen)); 00110 memcpy(md2->buf + md2->curlen, buf, (size_t)n); 00111 md2->curlen += n; 00112 buf += n; 00113 len -= n; 00114 00115 /* is 16 bytes full? */ 00116 if (md2->curlen == 16) { 00117 md2_compress(md2); 00118 md2_update_chksum(md2); 00119 md2->curlen = 0; 00120 } 00121 } 00122 return CRYPT_OK; 00123 } 00124 00125 int md2_done(md2_state * md2, unsigned char *hash) 00126 { 00127 unsigned long i, k; 00128 00129 if (md2->curlen >= sizeof(md2->buf)) { 00130 return CRYPT_INVALID_ARG; 00131 } 00132 00133 /* pad the message */ 00134 k = 16 - md2->curlen; 00135 for (i = md2->curlen; i < 16; i++) { 00136 md2->buf[i] = (unsigned char)k; 00137 } 00138 00139 /* hash and update */ 00140 md2_compress(md2); 00141 md2_update_chksum(md2); 00142 00143 /* hash checksum */ 00144 memcpy(md2->buf, md2->chksum, 16); 00145 md2_compress(md2); 00146 00147 /* output is lower 16 bytes of X */ 00148 memcpy(hash, md2->X, 16); 00149 00150 return CRYPT_OK; 00151 } Generated on Sun May 27 2012 04:26:07 for ReactOS by
1.7.6.1
|