Botan
1.11.15
|
00001 /* 00002 * Merkle-Damgard Hash Function 00003 * (C) 1999-2008 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/mdx_hash.h> 00009 #include <botan/exceptn.h> 00010 #include <botan/loadstor.h> 00011 00012 namespace Botan { 00013 00014 /* 00015 * MDx_HashFunction Constructor 00016 */ 00017 MDx_HashFunction::MDx_HashFunction(size_t block_len, 00018 bool byte_end, 00019 bool bit_end, 00020 size_t cnt_size) : 00021 buffer(block_len), 00022 BIG_BYTE_ENDIAN(byte_end), 00023 BIG_BIT_ENDIAN(bit_end), 00024 COUNT_SIZE(cnt_size) 00025 { 00026 count = position = 0; 00027 } 00028 00029 /* 00030 * Clear memory of sensitive data 00031 */ 00032 void MDx_HashFunction::clear() 00033 { 00034 zeroise(buffer); 00035 count = position = 0; 00036 } 00037 00038 /* 00039 * Update the hash 00040 */ 00041 void MDx_HashFunction::add_data(const byte input[], size_t length) 00042 { 00043 count += length; 00044 00045 if(position) 00046 { 00047 buffer_insert(buffer, position, input, length); 00048 00049 if(position + length >= buffer.size()) 00050 { 00051 compress_n(&buffer[0], 1); 00052 input += (buffer.size() - position); 00053 length -= (buffer.size() - position); 00054 position = 0; 00055 } 00056 } 00057 00058 const size_t full_blocks = length / buffer.size(); 00059 const size_t remaining = length % buffer.size(); 00060 00061 if(full_blocks) 00062 compress_n(input, full_blocks); 00063 00064 buffer_insert(buffer, position, input + full_blocks * buffer.size(), remaining); 00065 position += remaining; 00066 } 00067 00068 /* 00069 * Finalize a hash 00070 */ 00071 void MDx_HashFunction::final_result(byte output[]) 00072 { 00073 buffer[position] = (BIG_BIT_ENDIAN ? 0x80 : 0x01); 00074 for(size_t i = position+1; i != buffer.size(); ++i) 00075 buffer[i] = 0; 00076 00077 if(position >= buffer.size() - COUNT_SIZE) 00078 { 00079 compress_n(&buffer[0], 1); 00080 zeroise(buffer); 00081 } 00082 00083 write_count(&buffer[buffer.size() - COUNT_SIZE]); 00084 00085 compress_n(&buffer[0], 1); 00086 copy_out(output); 00087 clear(); 00088 } 00089 00090 /* 00091 * Write the count bits to the buffer 00092 */ 00093 void MDx_HashFunction::write_count(byte out[]) 00094 { 00095 if(COUNT_SIZE < 8) 00096 throw Invalid_State("MDx_HashFunction::write_count: COUNT_SIZE < 8"); 00097 if(COUNT_SIZE >= output_length() || COUNT_SIZE >= hash_block_size()) 00098 throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big"); 00099 00100 const u64bit bit_count = count * 8; 00101 00102 if(BIG_BYTE_ENDIAN) 00103 store_be(bit_count, out + COUNT_SIZE - 8); 00104 else 00105 store_le(bit_count, out + COUNT_SIZE - 8); 00106 } 00107 00108 }