Botan  1.11.15
src/lib/pk_pad/emsa_x931/emsa_x931.cpp
Go to the documentation of this file.
00001 /*
00002 * EMSA_X931
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/pad_utils.h>
00009 #include <botan/emsa_x931.h>
00010 
00011 namespace Botan {
00012 
00013 BOTAN_REGISTER_EMSA_1HASH(EMSA_X931, "EMSA_X931");
00014 
00015 namespace {
00016 
00017 secure_vector<byte> emsa2_encoding(const secure_vector<byte>& msg,
00018                                    size_t output_bits,
00019                                    const secure_vector<byte>& empty_hash,
00020                                    byte hash_id)
00021    {
00022    const size_t HASH_SIZE = empty_hash.size();
00023 
00024    size_t output_length = (output_bits + 1) / 8;
00025 
00026    if(msg.size() != HASH_SIZE)
00027       throw Encoding_Error("EMSA_X931::encoding_of: Bad input length");
00028    if(output_length < HASH_SIZE + 4)
00029       throw Encoding_Error("EMSA_X931::encoding_of: Output length is too small");
00030 
00031    const bool empty_input = (msg == empty_hash);
00032 
00033    secure_vector<byte> output(output_length);
00034 
00035    output[0] = (empty_input ? 0x4B : 0x6B);
00036    output[output_length - 3 - HASH_SIZE] = 0xBA;
00037    set_mem(&output[1], output_length - 4 - HASH_SIZE, 0xBB);
00038    buffer_insert(output, output_length - (HASH_SIZE + 2), &msg[0], msg.size());
00039    output[output_length-2] = hash_id;
00040    output[output_length-1] = 0xCC;
00041 
00042    return output;
00043    }
00044 
00045 }
00046 
00047 void EMSA_X931::update(const byte input[], size_t length)
00048    {
00049    m_hash->update(input, length);
00050    }
00051 
00052 secure_vector<byte> EMSA_X931::raw_data()
00053    {
00054    return m_hash->final();
00055    }
00056 
00057 /*
00058 * EMSA_X931 Encode Operation
00059 */
00060 secure_vector<byte> EMSA_X931::encoding_of(const secure_vector<byte>& msg,
00061                                       size_t output_bits,
00062                                       RandomNumberGenerator&)
00063    {
00064    return emsa2_encoding(msg, output_bits, m_empty_hash, m_hash_id);
00065    }
00066 
00067 /*
00068 * EMSA_X931 Verify Operation
00069 */
00070 bool EMSA_X931::verify(const secure_vector<byte>& coded,
00071                    const secure_vector<byte>& raw,
00072                    size_t key_bits)
00073    {
00074    try
00075       {
00076       return (coded == emsa2_encoding(raw, key_bits,
00077                                       m_empty_hash, m_hash_id));
00078       }
00079    catch(...)
00080       {
00081       return false;
00082       }
00083    }
00084 
00085 /*
00086 * EMSA_X931 Constructor
00087 */
00088 EMSA_X931::EMSA_X931(HashFunction* hash) : m_hash(hash)
00089    {
00090    m_empty_hash = m_hash->final();
00091 
00092    m_hash_id = ieee1363_hash_id(hash->name());
00093 
00094    if(!m_hash_id)
00095       throw Encoding_Error("EMSA_X931 no hash identifier for " + hash->name());
00096    }
00097 
00098 }