Botan  1.11.15
src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp
Go to the documentation of this file.
00001 /*
00002 * PKCS #1 v1.5 signature padding
00003 * (C) 1999-2008 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_pkcs1.h>
00010 
00011 namespace Botan {
00012 
00013 namespace {
00014 
00015 EMSA* make_pkcs1v15(const EMSA::Spec& spec)
00016    {
00017    if(spec.arg(0) == "Raw")
00018       return new EMSA_PKCS1v15_Raw;
00019    else
00020       return new EMSA_PKCS1v15(make_a<HashFunction>(spec.arg(0)));
00021    }
00022 
00023 }
00024 
00025 BOTAN_REGISTER_NAMED_T(EMSA, "EMSA_PKCS1", EMSA_PCS1v15, make_pkcs1v15);
00026 
00027 namespace {
00028 
00029 secure_vector<byte> emsa3_encoding(const secure_vector<byte>& msg,
00030                                    size_t output_bits,
00031                                    const byte hash_id[],
00032                                    size_t hash_id_length)
00033    {
00034    size_t output_length = output_bits / 8;
00035    if(output_length < hash_id_length + msg.size() + 10)
00036       throw Encoding_Error("emsa3_encoding: Output length is too small");
00037 
00038    secure_vector<byte> T(output_length);
00039    const size_t P_LENGTH = output_length - msg.size() - hash_id_length - 2;
00040 
00041    T[0] = 0x01;
00042    set_mem(&T[1], P_LENGTH, 0xFF);
00043    T[P_LENGTH+1] = 0x00;
00044    buffer_insert(T, P_LENGTH+2, hash_id, hash_id_length);
00045    buffer_insert(T, output_length-msg.size(), &msg[0], msg.size());
00046    return T;
00047    }
00048 
00049 }
00050 
00051 void EMSA_PKCS1v15::update(const byte input[], size_t length)
00052    {
00053    m_hash->update(input, length);
00054    }
00055 
00056 secure_vector<byte> EMSA_PKCS1v15::raw_data()
00057    {
00058    return m_hash->final();
00059    }
00060 
00061 secure_vector<byte>
00062 EMSA_PKCS1v15::encoding_of(const secure_vector<byte>& msg,
00063                            size_t output_bits,
00064                            RandomNumberGenerator&)
00065    {
00066    if(msg.size() != m_hash->output_length())
00067       throw Encoding_Error("EMSA_PKCS1v15::encoding_of: Bad input length");
00068 
00069    return emsa3_encoding(msg, output_bits,
00070                          &m_hash_id[0], m_hash_id.size());
00071    }
00072 
00073 bool EMSA_PKCS1v15::verify(const secure_vector<byte>& coded,
00074                            const secure_vector<byte>& raw,
00075                            size_t key_bits)
00076    {
00077    if(raw.size() != m_hash->output_length())
00078       return false;
00079 
00080    try
00081       {
00082       return (coded == emsa3_encoding(raw, key_bits,
00083                                       &m_hash_id[0], m_hash_id.size()));
00084       }
00085    catch(...)
00086       {
00087       return false;
00088       }
00089    }
00090 
00091 EMSA_PKCS1v15::EMSA_PKCS1v15(HashFunction* hash) : m_hash(hash)
00092    {
00093    m_hash_id = pkcs_hash_id(m_hash->name());
00094    }
00095 
00096 void EMSA_PKCS1v15_Raw::update(const byte input[], size_t length)
00097    {
00098    message += std::make_pair(input, length);
00099    }
00100 
00101 secure_vector<byte> EMSA_PKCS1v15_Raw::raw_data()
00102    {
00103    secure_vector<byte> ret;
00104    std::swap(ret, message);
00105    return ret;
00106    }
00107 
00108 secure_vector<byte>
00109 EMSA_PKCS1v15_Raw::encoding_of(const secure_vector<byte>& msg,
00110                                size_t output_bits,
00111                                RandomNumberGenerator&)
00112    {
00113    return emsa3_encoding(msg, output_bits, nullptr, 0);
00114    }
00115 
00116 bool EMSA_PKCS1v15_Raw::verify(const secure_vector<byte>& coded,
00117                                const secure_vector<byte>& raw,
00118                                size_t key_bits)
00119    {
00120    try
00121       {
00122       return (coded == emsa3_encoding(raw, key_bits, nullptr, 0));
00123       }
00124    catch(...)
00125       {
00126       return false;
00127       }
00128    }
00129 
00130 }