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> 49 namespace protobuf_comm {
65 cipher_ = cipher_by_name(cipher_name.c_str());
66 cipher_id_ = cipher_name_to_id(cipher_name.c_str());
68 const size_t key_size = EVP_CIPHER_key_length(cipher_);
69 const size_t iv_size = EVP_CIPHER_iv_length(cipher_);
70 key_ = (
unsigned char *)malloc(key_size);
71 unsigned char iv[iv_size];
73 cipher_, EVP_sha256(), NULL, (
const unsigned char *)key.c_str(), key.size(), 8, key_, iv)) {
74 throw std::runtime_error(
"Failed to generate key");
77 if (!RAND_bytes((
unsigned char *)&iv_,
sizeof(iv_))) {
78 throw std::runtime_error(
"Failed to generate IV");
81 throw std::runtime_error(
"Encryption support not available");
100 const EVP_CIPHER *evp_cipher = cipher_by_id(cipher_id_);
102 const size_t iv_size = EVP_CIPHER_iv_length(evp_cipher);
103 unsigned char iv_hash[SHA256_DIGEST_LENGTH];
105 unsigned char *enc_m = (
unsigned char *)enc.c_str();
110 if (!SHA256((
unsigned char *)&iv_,
sizeof(iv_), iv_hash)) {
111 throw std::runtime_error(
"Failed to generate IV");
113 enc.replace(0, iv_size, (
char *)iv_hash, iv_size);
117 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
118 if (!EVP_EncryptInit(ctx, evp_cipher, key_, iv_hash)) {
119 EVP_CIPHER_CTX_free(ctx);
120 throw std::runtime_error(
"Could not initialize cipher context");
123 int outl = enc.size() - iv_size;
124 if (!EVP_EncryptUpdate(ctx, enc_m, &outl, (
unsigned char *)plain.c_str(), plain.size())) {
125 EVP_CIPHER_CTX_free(ctx);
126 throw std::runtime_error(
"EncryptUpdate failed");
130 if (!EVP_EncryptFinal_ex(ctx, enc_m + outl, &plen)) {
131 EVP_CIPHER_CTX_free(ctx);
132 throw std::runtime_error(
"EncryptFinal failed");
136 EVP_CIPHER_CTX_free(ctx);
137 enc.resize(outl + iv_size);
139 throw std::runtime_error(
"Encryption support not available");
150 #ifdef HAVE_LIBCRYPTO 151 const EVP_CIPHER *evp_cipher = cipher_by_id(cipher_id_);
153 const size_t iv_size = EVP_CIPHER_iv_length(evp_cipher);
154 size_t block_size = EVP_CIPHER_block_size(evp_cipher);
156 return (((plain_length / block_size) + 1) * block_size) + iv_size;
158 throw std::runtime_error(
"Encryption not supported");
181 BufferDecryptor::generate_key(
int cipher)
183 #ifdef HAVE_LIBCRYPTO 184 const EVP_CIPHER *evp_cipher = cipher_by_id(cipher);
186 const size_t key_size = EVP_CIPHER_key_length(evp_cipher);
187 const size_t iv_size = EVP_CIPHER_iv_length(evp_cipher);
188 unsigned char *key = (
unsigned char *)malloc(key_size);
189 unsigned char iv[iv_size];
190 if (!EVP_BytesToKey(evp_cipher,
193 (
const unsigned char *)key_.c_str(),
200 throw std::runtime_error(
"Failed to generate key");
201 #ifdef HAVE_LIBCRYPTO 204 std::string ks((
const char *)key, key_size);
227 #ifdef HAVE_LIBCRYPTO 228 if (keys_.find(cipher) == keys_.end()) {
229 generate_key(cipher);
232 const EVP_CIPHER *evp_cipher = cipher_by_id(cipher);
234 const size_t iv_size = EVP_CIPHER_iv_length(evp_cipher);
235 const unsigned char *iv = (
const unsigned char *)enc;
236 unsigned char * enc_m = (
unsigned char *)enc + iv_size;
239 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
240 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, (
unsigned char *)plain, &outl, enc_m, enc_size)) {
247 EVP_CIPHER_CTX_free(ctx);
248 throw std::runtime_error(
"DecryptUpdate failed");
252 if (!EVP_DecryptFinal(ctx, (
unsigned char *)plain + outl, &plen)) {
253 EVP_CIPHER_CTX_free(ctx);
254 throw std::runtime_error(
"DecryptFinal failed");
258 EVP_CIPHER_CTX_free(ctx);
261 throw std::runtime_error(
"Decryption support not available");
265 #ifdef HAVE_LIBCRYPTO 271 cipher_name_by_id(
int cipher)
274 case PB_ENCRYPTION_AES_128_ECB:
return SN_aes_128_ecb;
275 case PB_ENCRYPTION_AES_128_CBC:
return SN_aes_128_cbc;
277 case PB_ENCRYPTION_AES_256_ECB:
return SN_aes_256_ecb;
278 case PB_ENCRYPTION_AES_256_CBC:
return SN_aes_256_cbc;
280 default:
throw std::runtime_error(
"Unknown cipher type");
289 cipher_by_id(
int cipher)
292 case PB_ENCRYPTION_AES_128_ECB:
return EVP_aes_128_ecb();
293 case PB_ENCRYPTION_AES_128_CBC:
return EVP_aes_128_cbc();
295 case PB_ENCRYPTION_AES_256_ECB:
return EVP_aes_256_ecb();
296 case PB_ENCRYPTION_AES_256_CBC:
return EVP_aes_256_cbc();
298 default:
throw std::runtime_error(
"Unknown cipher type");
307 cipher_name_to_id(
const char *cipher)
309 if (strcmp(cipher, LN_aes_128_ecb) == 0) {
310 return PB_ENCRYPTION_AES_128_ECB;
311 }
else if (strcmp(cipher, LN_aes_128_cbc) == 0) {
312 return PB_ENCRYPTION_AES_128_CBC;
313 }
else if (strcmp(cipher, LN_aes_256_ecb) == 0) {
314 return PB_ENCRYPTION_AES_256_ECB;
315 }
else if (strcmp(cipher, LN_aes_256_cbc) == 0) {
316 return PB_ENCRYPTION_AES_256_CBC;
318 throw std::runtime_error(
"Unknown cipher type");
327 cipher_by_name(
const char *cipher)
329 if (strcmp(cipher, LN_aes_128_ecb) == 0) {
330 return EVP_aes_128_ecb();
331 }
else if (strcmp(cipher, LN_aes_128_cbc) == 0) {
332 return EVP_aes_128_cbc();
333 }
else if (strcmp(cipher, LN_aes_256_ecb) == 0) {
334 return EVP_aes_256_ecb();
335 }
else if (strcmp(cipher, LN_aes_256_cbc) == 0) {
336 return EVP_aes_256_cbc();
338 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.