37 #include <protobuf_comm/crypto.h> 38 #include <protobuf_comm/frame_header.h> 42 # include <openssl/evp.h> 43 # include <openssl/rand.h> 44 # include <openssl/sha.h> 66 cipher_ = cipher_by_name(cipher_name.c_str());
67 cipher_id_ = cipher_name_to_id(cipher_name.c_str());
69 const size_t key_size = EVP_CIPHER_key_length(cipher_);
70 const size_t iv_size = EVP_CIPHER_iv_length(cipher_);
71 key_ = (
unsigned char *)malloc(key_size);
72 unsigned char iv[iv_size];
73 if( ! EVP_BytesToKey(cipher_, EVP_sha256(), NULL,
74 (
const unsigned char *)key.c_str(), key.size(), 8, key_, iv))
76 throw std::runtime_error(
"Failed to generate key");
79 if (!RAND_bytes((
unsigned char *)&iv_,
sizeof(iv_))) {
80 throw std::runtime_error(
"Failed to generate IV");
100 #ifdef HAVE_LIBCRYPTO 101 const EVP_CIPHER *evp_cipher = cipher_by_id(cipher_id_);
103 const size_t iv_size = EVP_CIPHER_iv_length(evp_cipher);
104 unsigned char iv_hash[SHA256_DIGEST_LENGTH];
106 unsigned char *enc_m = (
unsigned char *)enc.c_str();
111 if (! SHA256((
unsigned char *)&iv_,
sizeof(iv_), iv_hash)) {
112 throw std::runtime_error(
"Failed to generate IV");
114 enc.replace(0, iv_size, (
char *)iv_hash, iv_size);
118 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
119 if ( ! EVP_EncryptInit(ctx, evp_cipher, key_, iv_hash))
121 EVP_CIPHER_CTX_free(ctx);
122 throw std::runtime_error(
"Could not initialize cipher context");
125 int outl = enc.size() - iv_size;
126 if ( ! EVP_EncryptUpdate(ctx, enc_m, &outl,
127 (
unsigned char *)plain.c_str(), plain.size()) )
129 EVP_CIPHER_CTX_free(ctx);
130 throw std::runtime_error(
"EncryptUpdate failed");
134 if ( ! EVP_EncryptFinal_ex(ctx, enc_m + outl, &plen) ) {
135 EVP_CIPHER_CTX_free(ctx);
136 throw std::runtime_error(
"EncryptFinal failed");
140 EVP_CIPHER_CTX_free(ctx);
141 enc.resize(outl + iv_size);
143 throw std::runtime_error(
"Encryption support not available");
156 #ifdef HAVE_LIBCRYPTO 157 const EVP_CIPHER *evp_cipher = cipher_by_id(cipher_id_);
159 const size_t iv_size = EVP_CIPHER_iv_length(evp_cipher);
160 size_t block_size = EVP_CIPHER_block_size(evp_cipher);
162 return (((plain_length / block_size) + 1) * block_size) + iv_size;
164 throw std::runtime_error(
"Encryption not supported");
192 BufferDecryptor::generate_key(
int cipher)
194 const EVP_CIPHER *evp_cipher = cipher_by_id(cipher);
196 const size_t key_size = EVP_CIPHER_key_length(evp_cipher);
197 const size_t iv_size = EVP_CIPHER_iv_length(evp_cipher);
198 unsigned char *key = (
unsigned char *)malloc(key_size);
199 unsigned char iv[iv_size];
200 if( ! EVP_BytesToKey(evp_cipher, EVP_sha256(), NULL,
201 (
const unsigned char *)key_.c_str(), key_.size(), 8, key, iv))
204 throw std::runtime_error(
"Failed to generate key");
207 std::string ks((
const char *)key, key_size);
226 #ifdef HAVE_LIBCRYPTO 227 if (keys_.find(cipher) == keys_.end()) {
228 generate_key(cipher);
231 const EVP_CIPHER *evp_cipher = cipher_by_id(cipher);
233 const size_t iv_size = EVP_CIPHER_iv_length(evp_cipher);
234 const unsigned char *iv = (
const unsigned char *)enc;
235 unsigned char *enc_m = (
unsigned char *)enc + iv_size;
238 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
239 if ( ! EVP_DecryptInit(ctx, evp_cipher, (
const unsigned char *)keys_[cipher].c_str(), iv))
241 EVP_CIPHER_CTX_free(ctx);
242 throw std::runtime_error(
"Could not initialize cipher context");
245 int outl = plain_size;
246 if ( ! EVP_DecryptUpdate(ctx,
247 (
unsigned char *)plain, &outl, enc_m, enc_size))
249 EVP_CIPHER_CTX_free(ctx);
250 throw std::runtime_error(
"DecryptUpdate failed");
254 if ( ! EVP_DecryptFinal(ctx, (
unsigned char *)plain + outl, &plen) ) {
255 EVP_CIPHER_CTX_free(ctx);
256 throw std::runtime_error(
"DecryptFinal failed");
260 EVP_CIPHER_CTX_free(ctx);
263 throw std::runtime_error(
"Decryption support not available");
273 cipher_name_by_id(
int cipher)
276 case PB_ENCRYPTION_AES_128_ECB:
277 return SN_aes_128_ecb;
278 case PB_ENCRYPTION_AES_128_CBC:
279 return SN_aes_128_cbc;
281 case PB_ENCRYPTION_AES_256_ECB:
282 return SN_aes_256_ecb;
283 case PB_ENCRYPTION_AES_256_CBC:
284 return SN_aes_256_cbc;
287 throw std::runtime_error(
"Unknown cipher type");
297 cipher_by_id(
int cipher)
300 case PB_ENCRYPTION_AES_128_ECB:
301 return EVP_aes_128_ecb();
302 case PB_ENCRYPTION_AES_128_CBC:
303 return EVP_aes_128_cbc();
305 case PB_ENCRYPTION_AES_256_ECB:
306 return EVP_aes_256_ecb();
307 case PB_ENCRYPTION_AES_256_CBC:
308 return EVP_aes_256_cbc();
311 throw std::runtime_error(
"Unknown cipher type");
320 cipher_name_to_id(
const char *cipher)
322 if (strcmp(cipher, LN_aes_128_ecb) == 0) {
323 return PB_ENCRYPTION_AES_128_ECB;
324 }
else if (strcmp(cipher, LN_aes_128_cbc) == 0) {
325 return PB_ENCRYPTION_AES_128_CBC;
326 }
else if (strcmp(cipher, LN_aes_256_ecb) == 0) {
327 return PB_ENCRYPTION_AES_256_ECB;
328 }
else if (strcmp(cipher, LN_aes_256_cbc) == 0) {
329 return PB_ENCRYPTION_AES_256_CBC;
331 throw std::runtime_error(
"Unknown cipher type");
341 cipher_by_name(
const char *cipher)
343 if (strcmp(cipher, LN_aes_128_ecb) == 0) {
344 return EVP_aes_128_ecb();
345 }
else if (strcmp(cipher, LN_aes_128_cbc) == 0) {
346 return EVP_aes_128_cbc();
347 }
else if (strcmp(cipher, LN_aes_256_ecb) == 0) {
348 return EVP_aes_256_ecb();
349 }
else if (strcmp(cipher, LN_aes_256_cbc) == 0) {
350 return EVP_aes_256_cbc();
352 throw std::runtime_error(
"Unknown cipher type");
BufferEncryptor(const std::string &key, std::string cipher_name="AES-128-ECB")
Constructor.
~BufferEncryptor()
Destructor.
~BufferDecryptor()
Destructor.
size_t encrypted_buffer_size(size_t plain_length)
Get required size for an encrypted buffer of the given plain text length.
size_t decrypt(int cipher, const void *enc, size_t enc_size, void *plain, size_t plain_size)
Decrypt a buffer.
BufferDecryptor(const std::string &key)
Constructor.
void encrypt(const std::string &plain, std::string &enc)
Encrypt a buffer.