8 #include <botan/cms_enc.h>     9 #include <botan/der_enc.h>    10 #include <botan/sha160.h>    11 #include <botan/cbc.h>    12 #include <botan/filters.h>    13 #include <botan/libstate.h>    15 #if defined(BOTAN_HAS_RC2)    16   #include <botan/rc2.h>    26 SecureVector<byte> do_rfc3217_wrap(RandomNumberGenerator& rng,
    27                                    const std::string& cipher_name,
    29                                    const SecureVector<byte>& input)
    31    class Flip_Bytes : 
public Filter
    34          std::string name()
 const { 
return "Fip_Bytes"; }
    36          void write(
const byte data[], 
size_t length)
    38             buf += std::make_pair(data, length);
    42             for(
size_t j = 0; j != buf.size(); j++)
    43                send(buf[buf.size()-j-1]);
    47          Flip_Bytes(
const SecureVector<byte>& prefix) : buf(prefix) {}
    49          SecureVector<byte> buf;
    56    if(!cipher || cipher->block_size() != 8)
    57       throw Encoding_Error(
"do_rfc3217_wrap: Bad cipher: " + cipher_name);
    59    Pipe icv(
new Hash_Filter(
new SHA_160, 8));
    60    icv.process_msg(input);
    65    Pipe pipe(
new CBC_Encryption(cipher->clone(), 
new Null_Padding, kek, iv),
    66              new Flip_Bytes(iv.bits_of()),
    67              new CBC_Encryption(cipher->clone(), 
new Null_Padding, kek, iv));
    71    pipe.write(icv.read_all());
    73    return pipe.read_all();
    81 SecureVector<byte> CMS_Encoder::wrap_key(RandomNumberGenerator& rng,
    82                                          const std::string& cipher,
    86 #if defined(BOTAN_HAS_DES)    87    if(cipher == 
"TripleDES")
    91       return do_rfc3217_wrap(rng, cipher, kek, cek_parity.bits_of());
    95 #if defined(BOTAN_HAS_RC2) || defined(BOTAN_HAS_CAST)    96    if(cipher == 
"RC2" || cipher == 
"CAST-128")
    98       if(kek.length() != 16)
    99          throw Encoding_Error(
"CMS: 128-bit KEKs must be used with " + cipher);
   101       SecureVector<byte> lcekpad;
   102       lcekpad.push_back(static_cast<byte>(cek.length()));
   103       lcekpad += cek.bits_of();
   104       while(lcekpad.size() % 8)
   105          lcekpad.push_back(rng.next_byte());
   106       return do_rfc3217_wrap(rng, cipher, kek, lcekpad);
   116 SecureVector<byte> CMS_Encoder::encode_params(
const std::string& cipher,
   122 #if defined(BOTAN_HAS_RC2)   129       return encoder.get_contents();
   133    if(cipher == 
"CAST-128")
   143    return encoder.get_contents();
   149 SymmetricKey CMS_Encoder::setup_key(RandomNumberGenerator& rng,
   150                                     const std::string& cipher)
   154    if(cipher == 
"TripleDES") keysize = 24;
   155    if(cipher == 
"RC2")       keysize = 16;
   156    if(cipher == 
"CAST-128")  keysize = 16;
   162    if(cipher == 
"DES" || cipher == 
"TripleDES")
   163       key.set_odd_parity();
 Algorithm_Factory & algorithm_factory() const
const BlockCipher * prototype_block_cipher(const std::string &algo_spec, const std::string &provider="")
std::invalid_argument Invalid_Argument
Library_State & global_state()
std::string encode(const byte der[], size_t length, const std::string &label, size_t width)
static byte EKB_code(size_t bits)
OctetString InitializationVector