Botan 1.10.17
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
15namespace Botan {
16
17/*
18* Encrypt some bytes using PBES1
19*/
20void 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*/
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*/
49 {
50 pipe.end_msg();
51 flush_pipe(false);
52 pipe.reset();
53 }
54
55/*
56* Flush the pipe
57*/
58void 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*/
74void 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*/
91void 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*/
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*/
113void 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*/
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
152std::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*/
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
181 {
182 delete block_cipher;
183 delete hash_function;
184 }
185
186}
virtual std::string name() const =0
BER_Decoder(DataSource &)
Definition ber_dec.cpp:264
CBC_Decryption(BlockCipher *cipher, BlockCipherModePaddingMethod *padding)
Definition cbc.cpp:115
CBC_Encryption(BlockCipher *cipher, BlockCipherModePaddingMethod *padding)
Definition cbc.cpp:17
void send(const byte in[], size_t length)
Definition filter.cpp:28
void write(const byte[], size_t)
Definition pbes1.cpp:20
std::string name() const
Definition pbes1.cpp:152
PBE_PKCS5v15(BlockCipher *cipher, HashFunction *hash, Cipher_Dir direction)
Definition pbes1.cpp:161
virtual OID get_oid() const =0
virtual MemoryVector< byte > encode_params() const =0
size_t remaining(message_id msg=DEFAULT_MESSAGE) const
Definition pipe_rw.cpp:138
size_t read(byte output[], size_t length)
Definition pipe_rw.cpp:89
void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:22
@ SEQUENCE
Definition asn1_int.h:35
@ OCTET_STRING
Definition asn1_int.h:31
Cipher_Dir
Definition sym_algo.h:87
@ ENCRYPTION
Definition sym_algo.h:87
Decoding_Error(const std::string &name)
Definition exceptn.h:140
Internal_Error(const std::string &err)
Definition exceptn.h:47