Botan: src/pbe/pbes1/pbes1.cpp Source File

Botan 1.10.16

pbes1.cpp
Go to the documentation of this file.
1 /*
2 * PKCS #5 PBES1
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7
8 #include <botan/pbes1.h>
9 #include <botan/pbkdf1.h>
10 #include <botan/der_enc.h>
11 #include <botan/ber_dec.h>
12 #include <botan/cbc.h>
13 #include <algorithm>
14
15 namespace Botan {
16
17 /*
18 * Encrypt some bytes using PBES1
19 */
20 void PBE_PKCS5v15::write(const byte input[], size_t length)
21 {
22 pipe.write(input, length);
23 flush_pipe(true);
24 }
25
26 /*
27 * Start encrypting with PBES1
28 */
29 void PBE_PKCS5v15::start_msg()
30 {
31 if(direction == ENCRYPTION)
32 pipe.append(new CBC_Encryption(block_cipher->clone(),
33 new PKCS7_Padding,
34 key, iv));
35 else
36 pipe.append(new CBC_Decryption(block_cipher->clone(),
37 new PKCS7_Padding,
38 key, iv));
39
40 pipe.start_msg();
41 if(pipe.message_count() > 1)
42 pipe.set_default_msg(pipe.default_msg() + 1);
43 }
44
45 /*
46 * Finish encrypting with PBES1
47 */
48 void PBE_PKCS5v15::end_msg()
49 {
50 pipe.end_msg();
51 flush_pipe(false);
52 pipe.reset();
53 }
54
55 /*
56 * Flush the pipe
57 */
58 void PBE_PKCS5v15::flush_pipe(bool safe_to_skip)
59 {
60 if(safe_to_skip && pipe.remaining() < 64)
61 return;
62
63 SecureVector<byte> buffer(DEFAULT_BUFFERSIZE);
64 while(pipe.remaining())
65 {
66 size_t got = pipe.read(&buffer[0], buffer.size());
67 send(buffer, got);
68 }
69 }
70
71 /*
72 * Set the passphrase to use
73 */
74 void PBE_PKCS5v15::set_key(const std::string& passphrase)
75 {
76 PKCS5_PBKDF1 pbkdf(hash_function->clone());
77
78 SecureVector<byte> key_and_iv = pbkdf.derive_key(16, passphrase,
79 &salt[0], salt.size(),
80 iterations).bits_of();
81
82 key.resize(8);
83 iv.resize(8);
84 copy_mem(&key[0], &key_and_iv[0], 8);
85 copy_mem(&iv[0], &key_and_iv[8], 8);
86 }
87
88 /*
89 * Create a new set of PBES1 parameters
90 */
91 void PBE_PKCS5v15::new_params(RandomNumberGenerator& rng)
92 {
93 iterations = 50000;
94 salt = rng.random_vec(8);
95 }
96
97 /*
98 * Encode PKCS#5 PBES1 parameters
99 */
100 MemoryVector<byte> PBE_PKCS5v15::encode_params() const
101 {
102 return DER_Encoder()
103 .start_cons(SEQUENCE)
104 .encode(salt, OCTET_STRING)
105 .encode(iterations)
106 .end_cons()
107 .get_contents();
108 }
109
110 /*
111 * Decode PKCS#5 PBES1 parameters
112 */
113 void PBE_PKCS5v15::decode_params(DataSource& source)
114 {
115 BER_Decoder(source)
116 .start_cons(SEQUENCE)
117 .decode(salt, OCTET_STRING)
118 .decode(iterations)
119 .verify_end()
120 .end_cons();
121
122 if(salt.size() != 8)
123 throw Decoding_Error("PBES1: Encoded salt is not 8 octets");
124 }
125
126 /*
127 * Return an OID for this PBES1 type
128 */
129 OID PBE_PKCS5v15::get_oid() const
130 {
131 const OID base_pbes1_oid("1.2.840.113549.1.5");
132
133 const std::string cipher = block_cipher->name();
134 const std::string digest = hash_function->name();
135
136 if(cipher == "DES" && digest == "MD2")
137 return (base_pbes1_oid + 1);
138 else if(cipher == "DES" && digest == "MD5")
139 return (base_pbes1_oid + 3);
140 else if(cipher == "DES" && digest == "SHA-160")
141 return (base_pbes1_oid + 10);
142 else if(cipher == "RC2" && digest == "MD2")
143 return (base_pbes1_oid + 4);
144 else if(cipher == "RC2" && digest == "MD5")
145 return (base_pbes1_oid + 6);
146 else if(cipher == "RC2" && digest == "SHA-160")
147 return (base_pbes1_oid + 11);
148 else
149 throw Internal_Error("PBE-PKCS5 v1.5: get_oid() has run out of options");
150 }
151
152 std::string PBE_PKCS5v15::name() const
153 {
154 return "PBE-PKCS5v15(" + block_cipher->name() + "," +
155 hash_function->name() + ")";
156 }
157
158 /*
159 * PKCS#5 v1.5 PBE Constructor
160 */
161 PBE_PKCS5v15::PBE_PKCS5v15(BlockCipher* cipher,
162 HashFunction* hash,
163 Cipher_Dir dir) :
164 direction(dir), block_cipher(cipher), hash_function(hash), iterations(0)
165 {
166 if(cipher->name() != "DES" && cipher->name() != "RC2")
167 {
168 throw Invalid_Argument("PBE_PKCS5v1.5: Unknown cipher " +
169 cipher->name());
170 }
171
172 if(hash->name() != "MD2" && hash->name() != "MD5" &&
173 hash->name() != "SHA-160")
174 {
175 throw Invalid_Argument("PBE_PKCS5v1.5: Unknown hash " +
176 hash->name());
177 }
178 }
179
180 PBE_PKCS5v15::~PBE_PKCS5v15()
181 {
182 delete block_cipher;
183 delete hash_function;
184 }
185
186 }
Botan::Pipe::start_msg
void start_msg()
Definition: pipe.cpp:152
Botan::PBE_PKCS5v15::end_msg
void end_msg()
Definition: pbes1.cpp:48
Botan::MemoryRegion::resize
void resize(size_t n)
Definition: secmem.h:211
Botan::Pipe::remaining
size_t remaining(message_id msg=DEFAULT_MESSAGE) const
Definition: pipe_rw.cpp:138
Botan::DER_Encoder::get_contents
SecureVector< byte > get_contents()
Definition: der_enc.cpp:122
Botan::Pipe::append
void append(Filter *filt)
Definition: pipe.cpp:215
Botan::Pipe::default_msg
size_t default_msg() const
Definition: pipe.h:209
Botan::Pipe::read
size_t read(byte output[], size_t length)
Definition: pipe_rw.cpp:89
Botan::PBE_PKCS5v15::~PBE_PKCS5v15
~PBE_PKCS5v15()
Definition: pbes1.cpp:180
Botan::RandomNumberGenerator
Definition: rng.h:20
Botan::RandomNumberGenerator::random_vec
SecureVector< byte > random_vec(size_t bytes)
Definition: rng.h:40
Botan::ENCRYPTION
Definition: sym_algo.h:87
Botan::Pipe::write
void write(const byte in[], size_t length)
Definition: pipe_rw.cpp:34
Botan::BER_Decoder::decode
BER_Decoder & decode(bool &)
Definition: ber_dec.cpp:344
Botan::BlockCipher::clone
virtual BlockCipher * clone() const =0
Botan::Internal_Error
Definition: exceptn.h:45
Botan::Invalid_Argument
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
Botan::DER_Encoder::end_cons
DER_Encoder & end_cons()
Definition: der_enc.cpp:145
Botan::DataSource
Definition: data_src.h:20
Botan::BER_Decoder::start_cons
BER_Decoder start_cons(ASN1_Tag, ASN1_Tag=UNIVERSAL)
Definition: ber_dec.cpp:238
Botan::Pipe::reset
void reset()
Definition: pipe.cpp:76
Botan::HashFunction::clone
virtual HashFunction * clone() const =0
Botan::CBC_Decryption
Definition: cbc.h:61
Botan::PKCS5_PBKDF1
Definition: pbkdf1.h:21
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::CBC_Encryption
Definition: cbc.h:21
Botan::DER_Encoder::encode
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:209
Botan::Filter::send
void send(const byte in[], size_t length)
Definition: filter.cpp:28
Botan::OCTET_STRING
Definition: asn1_int.h:31
Botan::DER_Encoder
Definition: der_enc.h:22
Botan::Pipe::end_msg
void end_msg()
Definition: pipe.cpp:166
Botan::BER_Decoder::end_cons
BER_Decoder & end_cons()
Definition: ber_dec.cpp:252
Botan::Decoding_Error
Definition: exceptn.h:138
Botan::SEQUENCE
Definition: asn1_int.h:35
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:22
Botan
Definition: algo_base.h:14
Botan::PBE_PKCS5v15::write
void write(const byte[], size_t)
Definition: pbes1.cpp:20
Botan::Algorithm::name
virtual std::string name() const =0
Botan::MemoryVector< byte >
Botan::Pipe::message_count
message_id message_count() const
Definition: pipe.cpp:282
Botan::HashFunction
Definition: hash.h:20
Botan::MemoryRegion::size
size_t size() const
Definition: secmem.h:29
Botan::PBE_PKCS5v15::PBE_PKCS5v15
PBE_PKCS5v15(BlockCipher *cipher, HashFunction *hash, Cipher_Dir direction)
Definition: pbes1.cpp:161
Botan::BER_Decoder::verify_end
BER_Decoder & verify_end()
Definition: ber_dec.cpp:163
Botan::PKCS7_Padding
Definition: mode_pad.h:72
Botan::DER_Encoder::start_cons
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:135
Botan::SecureVector< byte >
Botan::Pipe::set_default_msg
void set_default_msg(message_id msg)
Definition: pipe.cpp:106
Botan::PBE_PKCS5v15::name
std::string name() const
Definition: pbes1.cpp:152
Botan::Cipher_Dir
Cipher_Dir
Definition: sym_algo.h:87
Botan::PBE_PKCS5v15::start_msg
void start_msg()
Definition: pbes1.cpp:29
Botan::OID
Definition: asn1_oid.h:20
Botan::BER_Decoder
Definition: ber_dec.h:19
Botan::BlockCipher
Definition: block_cipher.h:18