Last active
April 15, 2021 09:03
-
-
Save shawnfeng0/695a43f5b32bf5dbdbe576990fb4f073 to your computer and use it in GitHub Desktop.
Use openssl crypt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <openssl/evp.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <string> | |
#include <vector> | |
// From https://www.openssl.org/docs/man1.1.1/man3/EVP_EncryptInit.html | |
static bool CryptAes256Cfb(const std::vector<uint8_t> &key, | |
const std::vector<uint8_t> &iv, | |
const std::vector<uint8_t> &in, | |
std::vector<uint8_t> &out, int do_encrypt) { | |
/* Don't set key or IV right away; we want to check lengths */ | |
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); | |
EVP_CipherInit_ex(ctx, EVP_aes_256_cfb(), nullptr, nullptr, nullptr, | |
do_encrypt); | |
OPENSSL_assert(EVP_CIPHER_CTX_key_length(ctx) == 32); | |
OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == 16); | |
/* Now we can set key and IV */ | |
EVP_CipherInit_ex(ctx, nullptr, nullptr, key.data(), iv.data(), do_encrypt); | |
/* Allow enough space in output buffer for additional block */ | |
uint8_t out_buffer[in.size() + EVP_MAX_BLOCK_LENGTH]; | |
int out_length; | |
if (!EVP_CipherUpdate(ctx, out_buffer, &out_length, in.data(), in.size())) { | |
/* Error */ | |
EVP_CIPHER_CTX_free(ctx); | |
return false; | |
} | |
out.insert(out.end(), out_buffer, out_buffer + out_length); | |
if (!EVP_CipherFinal_ex(ctx, out_buffer, &out_length)) { | |
/* Error */ | |
EVP_CIPHER_CTX_free(ctx); | |
return false; | |
} | |
out.insert(out.end(), out_buffer, out_buffer + out_length); | |
EVP_CIPHER_CTX_free(ctx); | |
return true; | |
} | |
static bool CryptAes256Cfb(const uint8_t *key, const uint8_t *iv, | |
const char *in, size_t in_len, char *out, | |
size_t *out_len, bool do_encrypt) { | |
if (!key || !iv || !in || !out || !out_len) return false; | |
std::vector<uint8_t> out_vec; | |
if (CryptAes256Cfb({key, key + 32}, {iv, iv + 16}, {in, in + in_len}, out_vec, | |
do_encrypt)) { | |
memcpy(out, out_vec.data(), out_vec.size()); | |
out[out_vec.size()] = '\0'; | |
*out_len = out_vec.size(); | |
return true; | |
} | |
return false; | |
} | |
bool EncryptAes256Cfb(const uint8_t *key, const uint8_t *iv, const char *in, | |
size_t in_len, char *out, size_t *out_len) { | |
return CryptAes256Cfb(key, iv, in, in_len, out, out_len, true); | |
} | |
bool DecryptAes256Cfb(const uint8_t *key, const uint8_t *iv, const char *in, | |
size_t in_len, char *out, size_t *out_len) { | |
return CryptAes256Cfb(key, iv, in, in_len, out, out_len, false); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment