Skip to content

Instantly share code, notes, and snippets.

@shawnfeng0
Last active April 15, 2021 09:03
Show Gist options
  • Save shawnfeng0/695a43f5b32bf5dbdbe576990fb4f073 to your computer and use it in GitHub Desktop.
Save shawnfeng0/695a43f5b32bf5dbdbe576990fb4f073 to your computer and use it in GitHub Desktop.
Use openssl crypt
#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