Botan  1.11.15
src/lib/hash/md2/md2.cpp
Go to the documentation of this file.
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 }