26 #include <openssl/conf.h>
27 #include <openssl/err.h>
34 const std::string &key,
37 EVP_CIPHER_CTX *ctx =
nullptr;
39 if ( !( ctx = EVP_CIPHER_CTX_new() ) )
52 rc = EVP_EncryptInit_ex( ctx, EVP_aes_128_gcm(),
nullptr, k.
getArray(), iv.
getArray() );
55 rc = EVP_EncryptInit_ex( ctx, EVP_aes_192_gcm(),
nullptr, k.
getArray(), iv.
getArray() );
58 rc = EVP_EncryptInit_ex( ctx, EVP_aes_256_gcm(),
nullptr, k.
getArray(), iv.
getArray() );
60 case Cipher::Invalid :
66 EVP_CIPHER_CTX_ctrl( ctx, EVP_CTRL_AEAD_SET_IVLEN,
ivOctets( cipher ) * 8,
nullptr );
70 rc = EVP_EncryptUpdate( ctx,
78 rc = EVP_EncryptFinal_ex( ctx,
87 if ( EVP_CIPHER_CTX_ctrl( ctx, EVP_CTRL_GCM_GET_TAG, (
int)tag.
getSize(), tag.
getArray() ) != 1 )
98 EVP_CIPHER_CTX_cleanup( ctx );
110 if ( src.substr(0,4) !=
"ENC[" )
return false;
111 size_t close_pos = src.length() -1;
112 while ( std::isspace( src[close_pos] ) && close_pos > 0 ) close_pos--;
113 if ( src.substr(close_pos,1) !=
"]" )
return false;
114 std::vector<std::string> sections =
split( src.substr(4,close_pos-4),
',' );
115 if ( sections.size() != 4 )
return false;
116 for (
auto s : sections ) {
117 std::vector<std::string> tokens =
split( s,
':' );
118 if ( tokens.size() != 2 )
return false;
119 if ( tokens[0] ==
"cipher" ) cipher = tokens[1];
120 else if ( tokens[0] ==
"data" ) data = tokens[1];
121 else if ( tokens[0] ==
"iv" ) iv = tokens[1];
122 else if ( tokens[0] ==
"tag" ) tag = tokens[1];
125 if ( cipher.length() == 0 || data.length() == 0 || iv.length() == 0 || tag.length() == 0 )
return false;
130 const std::string src,
138 if ( !
decode( src, scipher, sdata, siv, stag ) )
return 1;
149 EVP_CIPHER_CTX *ctx =
nullptr;
151 if ( !( ctx = EVP_CIPHER_CTX_new() ) )
157 rc = EVP_DecryptInit_ex( ctx, EVP_aes_128_gcm(),
nullptr, k.
getArray(), iv.
getArray() );
160 rc = EVP_DecryptInit_ex( ctx, EVP_aes_192_gcm(),
nullptr, k.
getArray(), iv.
getArray() );
163 rc = EVP_DecryptInit_ex( ctx, EVP_aes_256_gcm(),
nullptr, k.
getArray(), iv.
getArray() );
165 case Cipher::Invalid :
171 EVP_CIPHER_CTX_ctrl( ctx, EVP_CTRL_AEAD_SET_IVLEN,
ivOctets( cipher ) * 8,
nullptr );
173 EVP_CIPHER_CTX_ctrl( ctx, EVP_CTRL_AEAD_SET_TAG, (
int)tag.
getSize(), tag.
getArray() );
181 rc = EVP_DecryptUpdate( ctx,
190 rc = EVP_DecryptFinal_ex( ctx,
193 if ( rc != 1 ) result = 2;
196 EVP_CIPHER_CTX_cleanup(ctx);
203 std::stringstream ss;
205 while( ss.str().length() < (
size_t)
keyOctets( cipher ) ) {
207 if ( ++idx > key.length() - 1 ) idx = 0;