MADARA  3.1.8
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"
12 
14 
15 madara::filters::AESBufferFilter::AESBufferFilter ()
16  : key_ (new unsigned char[32]), iv_ (new unsigned char[16])
17 {
18  memset ((void *)key_.get_ptr (), 0, 32);
19  memset ((void *)iv_.get_ptr (), 0, 16);
20 }
21 
22 madara::filters::AESBufferFilter::AESBufferFilter (
23  const AESBufferFilter & input)
24  : key_ (new unsigned char[32]), iv_ (new unsigned char[16])
25 {
26  memcpy (key_.get_ptr (), input.key_.get_ptr (), 32);
27  memset ((void *)iv_.get_ptr (), 0, 16);
28 }
29 
30 madara::filters::AESBufferFilter::AESBufferFilter (
31  unsigned char * key, int key_length)
32 : key_ (new unsigned char[32]), iv_ (new unsigned char[16])
33 {
34  memcpy (key_.get_ptr (), key, 32);
35  memset ((void *)iv_.get_ptr (), 0, 16);
36 }
37 
38 madara::filters::AESBufferFilter::~AESBufferFilter ()
39 {
40 }
41 
42 int madara::filters::AESBufferFilter::generate_key (
43  const std::string & password)
44 {
45  int i, rounds = 5;
46 
47  // use a random salt and a zero'd initialization vector
48  int64_t salt = 0;
49 
50  i = EVP_BytesToKey (EVP_aes_256_cbc (), EVP_sha1 (),
51  (unsigned char *)&salt, (unsigned char *)password.c_str (),
52  (int)password.length (), rounds,
53  (unsigned char *)key_.get_ptr (),
54  (unsigned char *)iv_.get_ptr ());
55 
56  if (i != 32)
57  {
59  " Unable to initialize 256 bit AES. Only received %d bytes.\n",
60  i);
61 
62  return -1;
63  }
64 
65  return 0;
66 }
67 
68 
69 int
70 madara::filters::AESBufferFilter::encode (
71  unsigned char * source, int size, int max_size) const
72 {
73  int result = 0;
74 
76  EVP_CIPHER_CTX * ctx = EVP_CIPHER_CTX_new ();
77 
78  int len = 0;
79  int ciphertext_len = 0;
80 
81  // size == plaintext_len
82  size = std::min (size, max_size);
83 
84  // initialize the context
85 
86  EVP_CIPHER_CTX_init (ctx);
87 
88  // init the encryption with our key and IV
89  result = EVP_EncryptInit_ex (ctx, EVP_aes_256_cbc (), NULL,
90  key_.get_ptr (), iv_.get_ptr ());
91 
92  if (result != 1)
93  {
96  "AESBufferFilter::encode: Cannot init key/iv. Result=%d.\n",
97  result);
98 
99  return 0;
100  }
101 
102 
103  // encrypt the buffer
104  result = EVP_EncryptUpdate (ctx,
105  source, &len,
106  source, size);
107 
108  if (result != 1)
109  {
112  "AESBufferFilter::encode: Cannot perform encrypt. Result=%d.\n",
113  result);
114 
115  return 0;
116  }
117 
118  ciphertext_len = len;
119 
121  "AESBufferFilter::encode:EVP_EncryptUpdate:2: len=%d, ciphertext_len=%d.\n",
122  len, ciphertext_len);
123 
124 
125  // finalize the encryption with padding
126  result = EVP_EncryptFinal_ex (ctx, source + len, &len);
127 
128  if (result != 1)
129  {
132  "AESBufferFilter::encode: Cannot finalize encrypt. Result=%d.\n",
133  result);
134 
135  return 0;
136  }
137 
138  ciphertext_len += len;
139 
141  "AESBufferFilter::encode:EVP_EncryptFinal_ex: "
142  "len=%d, ciphertext_len=%d.\n",
143  len, ciphertext_len);
144 
145  EVP_CIPHER_CTX_free (ctx);
146 
147  return ciphertext_len;
148 }
149 
150 int
151 madara::filters::AESBufferFilter::decode (
152  unsigned char * source, int size, int max_size) const
153 {
154  int result = 0;
155 
157  EVP_CIPHER_CTX * ctx = EVP_CIPHER_CTX_new ();
158 
159  int len (0);
160  int plaintext_len (0);
161 
162  // size == cyphertext_len
163  size = std::min (size, max_size);
164 
165  // initialize the context
166  EVP_CIPHER_CTX_init (ctx);
167 
168  result = EVP_DecryptInit_ex (ctx, EVP_aes_256_cbc (), NULL,
169  key_.get_ptr (), iv_.get_ptr ());
170 
171  if (result != 1)
172  {
175  "AESBufferFilter::decode: Cannot init key/iv. Result=%d.\n",
176  result);
177 
178  return 0;
179  }
180 
182  "AESBufferFilter::decode:EVP_DecryptUpdate:1: len=%d, size=%d.\n",
183  len, size);
184 
185  result = EVP_DecryptUpdate (ctx, source, &len,
186  source, size);
187  plaintext_len = len;
188 
189  if (result != 1)
190  {
193  "AESBufferFilter::decode: Cannot perform decrypt. Result=%d.\n",
194  result);
195 
196  return 0;
197  }
198 
200  "AESBufferFilter::decode:EVP_DecryptUpdate:2: len=%d, plaintext_len=%d.\n",
201  len, plaintext_len);
202 
203  result = EVP_DecryptFinal_ex (ctx, source + len, &len);
204 
205  if (result != 1)
206  {
209  "AESBufferFilter::decode: Cannot finalize decrypt. Result=%d.\n",
210  result);
211 
212  return 0;
213  }
214 
215  plaintext_len += len;
216 
218  "AESBufferFilter::decode:EVP_DecryptFinal_ex: "
219  "len=%d, plaintext_len=%d.\n",
220  len, plaintext_len);
221 
222  EVP_CIPHER_CTX_free (ctx);
223 
224  return plaintext_len;
225 }
226 
227 #endif // _USE_SSL_
MADARA_Export utility::Refcounter< logger::Logger > global_logger
#define madara_logger_ptr_log(logger, level,...)
Fast version of the madara::logger::log method for Logger pointers.
Definition: Logger.h:32
static constexpr struct madara::knowledge::tags::string_t string