Botan
1.11.15
|
00001 /* 00002 * MD2 00003 * (C) 1999-2007 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/hash_utils.h> 00009 #include <botan/md2.h> 00010 #include <botan/internal/xor_buf.h> 00011 00012 namespace Botan { 00013 00014 BOTAN_REGISTER_HASH_NOARGS(MD2); 00015 00016 /** 00017 * MD2 Compression Function 00018 */ 00019 void MD2::hash(const byte input[]) 00020 { 00021 static const byte SBOX[256] = { 00022 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 00023 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 00024 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 00025 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 00026 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 00027 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 00028 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, 0x80, 0x7F, 0x5D, 0x9A, 00029 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 00030 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 00031 0xAC, 0x56, 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 00032 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D, 0x70, 0x59, 00033 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02, 00034 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 00035 0x34, 0x40, 0x7E, 0x0F, 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 00036 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E, 00037 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52, 00038 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 00039 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 00040 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 00041 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, 00042 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 00043 0x9F, 0x11, 0x83, 0x14 }; 00044 00045 buffer_insert(X, 16, input, hash_block_size()); 00046 xor_buf(&X[32], &X[0], &X[16], hash_block_size()); 00047 byte T = 0; 00048 00049 for(size_t i = 0; i != 18; ++i) 00050 { 00051 for(size_t k = 0; k != 48; k += 8) 00052 { 00053 T = X[k ] ^= SBOX[T]; T = X[k+1] ^= SBOX[T]; 00054 T = X[k+2] ^= SBOX[T]; T = X[k+3] ^= SBOX[T]; 00055 T = X[k+4] ^= SBOX[T]; T = X[k+5] ^= SBOX[T]; 00056 T = X[k+6] ^= SBOX[T]; T = X[k+7] ^= SBOX[T]; 00057 } 00058 00059 T += static_cast<byte>(i); 00060 } 00061 00062 T = checksum[15]; 00063 for(size_t i = 0; i != hash_block_size(); ++i) 00064 T = checksum[i] ^= SBOX[input[i] ^ T]; 00065 } 00066 00067 /** 00068 * Update the hash 00069 */ 00070 void MD2::add_data(const byte input[], size_t length) 00071 { 00072 buffer_insert(buffer, position, input, length); 00073 00074 if(position + length >= hash_block_size()) 00075 { 00076 hash(&buffer[0]); 00077 input += (hash_block_size() - position); 00078 length -= (hash_block_size() - position); 00079 while(length >= hash_block_size()) 00080 { 00081 hash(input); 00082 input += hash_block_size(); 00083 length -= hash_block_size(); 00084 } 00085 copy_mem(&buffer[0], input, length); 00086 position = 0; 00087 } 00088 position += length; 00089 } 00090 00091 /** 00092 * Finalize a MD2 Hash 00093 */ 00094 void MD2::final_result(byte output[]) 00095 { 00096 for(size_t i = position; i != hash_block_size(); ++i) 00097 buffer[i] = static_cast<byte>(hash_block_size() - position); 00098 00099 hash(&buffer[0]); 00100 hash(&checksum[0]); 00101 copy_mem(output, &X[0], output_length()); 00102 clear(); 00103 } 00104 00105 /** 00106 * Clear memory of sensitive data 00107 */ 00108 void MD2::clear() 00109 { 00110 zeroise(X); 00111 zeroise(checksum); 00112 zeroise(buffer); 00113 position = 0; 00114 } 00115 00116 }