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,
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();
const BlockCipher * prototype_block_cipher(const std::string &algo_spec, const std::string &provider="")
std::invalid_argument Invalid_Argument
Algorithm_Factory & algorithm_factory() const
RandomNumberGenerator * rng
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