MADARA  3.2.3
AESBufferFilter.cpp
Go to the documentation of this file.
1 
2 #ifdef _USE_SSL_
3 
4 #include <algorithm>
5 #include <string.h>
6 #include <openssl/evp.h>
7 #include <openssl/aes.h>
8 #include "AESBufferFilter.h"
9 
10 #include "madara/utility/Utility.h"
11 
13 
15  : key_ (new unsigned char[32]), iv_ (new unsigned char[16])
16 {
17  memset ((void *)key_.get_ptr (), 0, 32);
18  memset ((void *)iv_.get_ptr (), 0, 16);
19 }
20 
22  const AESBufferFilter & input)
23  : key_ (new unsigned char[32]), iv_ (new unsigned char[16])
24 {
25  memcpy (key_.get_ptr (), input.key_.get_ptr (), 32);
26  memset ((void *)iv_.get_ptr (), 0, 16);
27 }
28 
30  unsigned char * key, int key_length)
31 : key_ (new unsigned char[32]), iv_ (new unsigned char[16])
32 {
33  memcpy (key_.get_ptr (), key, std::min (32, key_length));
34  memset ((void *)iv_.get_ptr (), 0, 16);
35 }
36 
38 {
39 }
40 
42  const std::string & password)
43 {
44  int i, rounds = 5;
45 
46  // use a random salt and a zero'd initialization vector
47  int64_t salt = 0;
48 
49  i = EVP_BytesToKey (EVP_aes_256_cbc (), EVP_sha1 (),
50  (unsigned char *)&salt, (unsigned char *)password.c_str (),
51  (int)password.length (), rounds,
52  (unsigned char *)key_.get_ptr (),
53  (unsigned char *)iv_.get_ptr ());
54 
55  if (i != 32)
56  {
58  " Unable to initialize 256 bit AES. Only received %d bytes.\n",
59  i);
60 
61  return -1;
62  }
63 
64  return 0;
65 }
66 
67 
68 int
70  unsigned char * source, int size, int max_size) const
71 {
72  int result = 0;
73 
75  EVP_CIPHER_CTX * ctx = EVP_CIPHER_CTX_new ();
76 
77  int len = 0;
78  int ciphertext_len = 0;
79 
80  // size == plaintext_len
81  size = std::min (size, max_size);
82 
83  // initialize the context
84 
85  EVP_CIPHER_CTX_init (ctx);
86 
87  // init the encryption with our key and IV
88  result = EVP_EncryptInit_ex (ctx, EVP_aes_256_cbc (), NULL,
89  key_.get_ptr (), iv_.get_ptr ());
90 
91  if (result != 1)
92  {
95  "AESBufferFilter::encode: Cannot init key/iv. Result=%d.\n",
96  result);
97 
98  return 0;
99  }
100 
101 
102  // encrypt the buffer
103  result = EVP_EncryptUpdate (ctx,
104  source, &len,
105  source, size);
106 
107  if (result != 1)
108  {
111  "AESBufferFilter::encode: Cannot perform encrypt. Result=%d.\n",
112  result);
113 
114  return 0;
115  }
116 
117  ciphertext_len = len;
118 
120  "AESBufferFilter::encode:EVP_EncryptUpdate:2: len=%d, ciphertext_len=%d.\n",
121  len, ciphertext_len);
122 
123 
124  // finalize the encryption with padding
125  result = EVP_EncryptFinal_ex (ctx, source + len, &len);
126 
127  if (result != 1)
128  {
131  "AESBufferFilter::encode: Cannot finalize encrypt. Result=%d.\n",
132  result);
133 
134  return 0;
135  }
136 
137  ciphertext_len += len;
138 
140  "AESBufferFilter::encode:EVP_EncryptFinal_ex: "
141  "len=%d, ciphertext_len=%d.\n",
142  len, ciphertext_len);
143 
144  EVP_CIPHER_CTX_free (ctx);
145 
146  return ciphertext_len;
147 }
148 
149 int
151  unsigned char * source, int size, int max_size) const
152 {
153  int result = 0;
154 
156  EVP_CIPHER_CTX * ctx = EVP_CIPHER_CTX_new ();
157 
158  int len (0);
159  int plaintext_len (0);
160 
161  // size == cyphertext_len
162  size = std::min (size, max_size);
163 
164  // initialize the context
165  EVP_CIPHER_CTX_init (ctx);
166 
167  result = EVP_DecryptInit_ex (ctx, EVP_aes_256_cbc (), NULL,
168  key_.get_ptr (), iv_.get_ptr ());
169 
170  if (result != 1)
171  {
174  "AESBufferFilter::decode: Cannot init key/iv. Result=%d.\n",
175  result);
176 
177  return 0;
178  }
179 
181  "AESBufferFilter::decode:EVP_DecryptUpdate:1: len=%d, size=%d.\n",
182  len, size);
183 
184  result = EVP_DecryptUpdate (ctx, source, &len,
185  source, size);
186  plaintext_len = len;
187 
188  if (result != 1)
189  {
192  "AESBufferFilter::decode: Cannot perform decrypt. Result=%d.\n",
193  result);
194 
195  return 0;
196  }
197 
199  "AESBufferFilter::decode:EVP_DecryptUpdate:2: len=%d, plaintext_len=%d.\n",
200  len, plaintext_len);
201 
202  result = EVP_DecryptFinal_ex (ctx, source + len, &len);
203 
204  if (result != 1)
205  {
208  "AESBufferFilter::decode: Cannot finalize decrypt. Result=%d.\n",
209  result);
210 
211  return 0;
212  }
213 
214  plaintext_len += len;
215 
217  "AESBufferFilter::decode:EVP_DecryptFinal_ex: "
218  "len=%d, plaintext_len=%d.\n",
219  len, plaintext_len);
220 
221  EVP_CIPHER_CTX_free (ctx);
222 
223  return plaintext_len;
224 }
225 
226 #endif // _USE_SSL_
virtual int encode(unsigned char *source, int size, int max_size) const
Encodes the buffer in place using AES encryption.
utility::ScopedArray< unsigned char > key_
the user&#39;s cypher key
MADARA_EXPORT utility::Refcounter< logger::Logger > global_logger
int generate_key(const std::string &password)
Generates a 256 bit key from a password.
static struct madara::knowledge::tags::string_t string
virtual int decode(unsigned char *source, int size, int max_size) const
Decodes the buffer in place using AES encryption.
T * get_ptr(void)
get the underlying pointer
Definition: ScopedArray.inl:68
#define madara_logger_ptr_log(logger, level,...)
Fast version of the madara::logger::log method for Logger pointers.
Definition: Logger.h:32
virtual ~AESBufferFilter()
Destructor.
utility::ScopedArray< unsigned char > iv_
initialization vector
Encrypts a buffer with 256 bit AES via OpenSSL.