/* * EMSA1 * (C) 1999-2007 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include namespace Botan { namespace { secure_vector emsa1_encoding(const secure_vector& msg, size_t output_bits) { if(8*msg.size() <= output_bits) return msg; size_t shift = 8*msg.size() - output_bits; size_t byte_shift = shift / 8, bit_shift = shift % 8; secure_vector digest(msg.size() - byte_shift); for(size_t j = 0; j != msg.size() - byte_shift; ++j) digest[j] = msg[j]; if(bit_shift) { byte carry = 0; for(size_t j = 0; j != digest.size(); ++j) { byte temp = digest[j]; digest[j] = (temp >> bit_shift) | carry; carry = (temp << (8 - bit_shift)); } } return digest; } } EMSA* EMSA1::clone() { return new EMSA1(m_hash->clone()); } void EMSA1::update(const byte input[], size_t length) { m_hash->update(input, length); } secure_vector EMSA1::raw_data() { return m_hash->final(); } secure_vector EMSA1::encoding_of(const secure_vector& msg, size_t output_bits, RandomNumberGenerator&) { if(msg.size() != hash_output_length()) throw Encoding_Error("EMSA1::encoding_of: Invalid size for input"); return emsa1_encoding(msg, output_bits); } bool EMSA1::verify(const secure_vector& input, const secure_vector& raw, size_t key_bits) { try { if(raw.size() != m_hash->output_length()) throw Encoding_Error("EMSA1::encoding_of: Invalid size for input"); // Call emsa1_encoding to handle any required bit shifting const secure_vector our_coding = emsa1_encoding(raw, key_bits); if(our_coding.size() < input.size()) return false; const size_t offset = our_coding.size() - input.size(); // must be >= 0 per check above // If our encoding is longer, all the bytes in it must be zero for(size_t i = 0; i != offset; ++i) if(our_coding[i] != 0) return false; return same_mem(input.data(), &our_coding[offset], input.size()); } catch(Invalid_Argument) { return false; } } }