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