Skip to content

Instantly share code, notes, and snippets.

@justanotherminh
Last active November 2, 2022 21:44
Show Gist options
  • Save justanotherminh/91b26ecaa13110b877dcc4f21fd4e3f8 to your computer and use it in GitHub Desktop.
Save justanotherminh/91b26ecaa13110b877dcc4f21fd4e3f8 to your computer and use it in GitHub Desktop.
OpenSSL examples
#include <openssl/evp.h>
#include <openssl/kdf.h>
#include <openssl/objects.h>
#include <openssl/crypto.h>
#include <openssl/core_names.h>
#include <openssl/obj_mac.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/ec.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/bn.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
// Helper functions
void print_bn(BIGNUM* bn) {
int size = BN_num_bytes(bn);
uint8_t buffer[size];
BN_bn2bin(bn, buffer);
for (int i = 0; i < size; i++) {
printf("%02X ", buffer[i]);
}
printf("\n");
printf("%d bytes written\n", size);
}
// Toy code
void foo1() {
uint8_t x_data[32];
uint8_t y_data[32];
for (int i = 0; i < 32; i++) {
x_data[i] = 0x01;
y_data[i] = 0x02;
}
uint8_t pub_data[65];
pub_data[0] = (uint8_t) POINT_CONVERSION_UNCOMPRESSED;
memcpy(&pub_data[1], &x_data[0], 32);
memcpy(&pub_data[33], &y_data[0], 32);
for (int i = 0; i < 65; i++) {
printf("%X ", pub_data[i]);
}
printf("\n");
// BN_CTX * ctx = BN_CTX_new();
BIGNUM * x = BN_new();
BIGNUM * y = BN_new();
BN_bin2bn(x_data, 32, x);
BN_bin2bn(y_data, 32, y);
const EC_GROUP * group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
const EC_POINT * point = EC_POINT_new(group);
EC_POINT_set_affine_coordinates(group, point, x, y, NULL);
size_t bufsize = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
printf("Buffer size: %d\n", bufsize);
unsigned char buffer[22];
size_t bytes_written = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, &buffer[0], bufsize, NULL);
for (int i = 0; i < 65; i++) {
printf("%02X ", buffer[i]);
}
printf("%d\n", bytes_written);
}
void foo2() {
EC_KEY* key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
EC_KEY_set_asn1_flag(key, OPENSSL_EC_NAMED_CURVE);
if (!EC_KEY_generate_key(key)) {
fprintf(stderr, "Error generating key\n");
}
EVP_PKEY* pkey = EVP_PKEY_new();
if (!EVP_PKEY_assign_EC_KEY(pkey, key)) {
fprintf(stderr, "Error assigning pkey\n");
}
printf("pkey size: %d bits\n", EVP_PKEY_bits(pkey));
EC_GROUP* group = EC_KEY_get0_group(key);
EC_POINT* point = EC_POINT_new(group);
point = EC_KEY_get0_public_key(key);
BIGNUM* priv = BN_new();
priv = EC_KEY_get0_private_key(key);
int priv_size = BN_num_bytes(priv);
uint8_t priv_data[priv_size];
BN_bn2bin(priv, priv_data);
printf("Private key:\n");
for (int i = 0; i < priv_size; i++) {
printf("%02X ", priv_data[i]);
}
printf("\n");
BIGNUM* x = BN_new();
BIGNUM* y = BN_new();
EC_POINT_get_affine_coordinates(group, point, x, y, NULL);
int x_size = BN_num_bytes(x);
int y_size = BN_num_bytes(y);
uint8_t x_data[x_size];
uint8_t y_data[y_size];
BN_bn2bin(x, x_data);
BN_bn2bin(y, y_data);
printf("Public key x:\n");
for (int i = 0; i < x_size; i++) {
printf("%02X ", x_data[i]);
}
printf("\n");
printf("Public key y:\n");
for (int i = 0; i < y_size; i++) {
printf("%02X ", y_data[i]);
}
printf("\n");
BN_free(x);
BN_free(y);
BN_free(priv);
EC_POINT_free(point);
EC_GROUP_free(group);
// EC_KEY_free(key);
// EVP_PKEY_free(pkey);
}
void foo3() {
EC_KEY* key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
EC_GROUP* group = EC_KEY_get0_group(key);
EC_KEY_set_asn1_flag(key, OPENSSL_EC_NAMED_CURVE);
const unsigned char priv_data[] = {
0xb9, 0x2f, 0x3c, 0xe6, 0x2f, 0xfb, 0x45, 0x68,
0x39, 0x96, 0xf0, 0x2a, 0xaf, 0x6c, 0xda, 0xf2,
0x89, 0x8a, 0x27, 0xbf, 0x39, 0x9b, 0x7e, 0x54,
0x21, 0xc2, 0xa1, 0xe5, 0x36, 0x12, 0x48, 0x5d
};
BIGNUM* priv_bn = BN_bin2bn(priv_data, 32, NULL);
if (EC_KEY_set_private_key(key, priv_bn) == 0)
fprintf(stderr, "Error setting private key\n");
// Allocate memory for public key
EC_POINT* public_point = EC_POINT_new(EC_KEY_get0_group(key));
// Performs multiplication
EC_POINT_mul(group, public_point, priv_bn, NULL, NULL, NULL);
BIGNUM* x = BN_new();
BIGNUM* y = BN_new();
EC_POINT_get_affine_coordinates(group, public_point, x, y, NULL);
int x_size = BN_num_bytes(x);
int y_size = BN_num_bytes(y);
uint8_t x_data[x_size];
uint8_t y_data[y_size];
BN_bn2bin(x, x_data);
BN_bn2bin(y, y_data);
printf("Public key x:\n");
for (int i = 0; i < x_size; i++) {
printf("%02X ", x_data[i]);
}
printf("\n");
printf("Public key y:\n");
for (int i = 0; i < y_size; i++) {
printf("%02X ", y_data[i]);
}
printf("\n");
}
void foo4() {
EVP_PKEY* pkey = EVP_EC_gen(SN_X9_62_prime256v1);
// EVP_PKEY* pkey = EVP_RSA_gen(1024);
if (!pkey) {
fprintf(stderr, "pkey creation failed\n");
abort();
}
EC_KEY* key = EVP_PKEY_get1_EC_KEY(pkey);
if (!key) {
fprintf(stderr, "failed to get key type from EVP_PKEY\n");
abort();
}
BIGNUM* priv = EC_KEY_get0_private_key(key);
if (!priv) {
fprintf(stderr, "failed to obtain private key from pkey\n");
abort();
}
int size = BN_num_bytes(priv);
uint8_t priv_data[size];
printf("Private key:\n");
for (int i = 0; i < size; i++) {
printf("%02X ", priv_data[i]);
}
printf("\n");
EC_POINT* pub = EC_KEY_get0_public_key(key);
EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
if (!pub) {
fprintf(stderr, "failed to obtain public key from pkey\n");
abort();
}
BIGNUM* x = BN_new();
BIGNUM* y = BN_new();
EC_POINT_get_affine_coordinates(group, pub, x, y, NULL);
int x_size = BN_num_bytes(x);
int y_size = BN_num_bytes(y);
uint8_t x_data[x_size];
uint8_t y_data[y_size];
BN_bn2bin(x, x_data);
BN_bn2bin(y, y_data);
printf("Public key x:\n");
for (int i = 0; i < x_size; i++) {
printf("%02X ", x_data[i]);
}
printf("\n");
printf("Public key y:\n");
for (int i = 0; i < y_size; i++) {
printf("%02X ", y_data[i]);
}
printf("\n");
BIO* bio = BIO_new(BIO_s_file());
bio = BIO_new_fp(stdout, BIO_NOCLOSE);
PEM_write_bio_ECPrivateKey(bio, key, NULL, NULL, 0, 0, NULL);
unsigned char* buffer = NULL;
size_t bytes_written = 0;
OSSL_ENCODER_CTX* ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, EVP_PKEY_KEYPAIR, "PEM", NULL, NULL);
if (!ctx) {
fprintf(stderr, "Failed to create context\n");
abort();
}
if (!OSSL_ENCODER_to_data(ctx, &buffer, &bytes_written)) {
fprintf(stderr, "Writing to buffer failed\n");
abort();
}
// BIO_dump_fp(stdout, buffer, bytes_written);
// BIO* bio = BIO_new_file("keypair.pem", "wb");
BIO_write(bio, buffer, bytes_written);
BN_free(priv);
BN_free(x);
BN_free(y);
EC_GROUP_free(group);
EC_POINT_free(pub);
// EC_KEY_free(key);
EVP_PKEY_free(pkey);
// OSSL_ENCODER_CTX_free(ctx);
BIO_free_all(bio);
}
void foo5() {
EVP_PKEY* pkey = EVP_RSA_gen(1024);
RSA* key = EVP_PKEY_get1_RSA(pkey);
BIO* bio = BIO_new(BIO_s_file());
bio = BIO_new_fp(stdout, BIO_NOCLOSE);
PEM_write_bio_RSAPrivateKey(bio, key, NULL, NULL, 0, 0, NULL);
unsigned char *buffer = NULL;
size_t bytes_written;
OSSL_ENCODER_CTX* ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, EVP_PKEY_KEYPAIR, "PEM", NULL, NULL);
OSSL_ENCODER_to_data(ctx, &buffer, &bytes_written);
BIO_write(bio, buffer, (int) bytes_written);
}
void foo6() {
EVP_PKEY* pkey = EVP_RSA_gen(1024);
const BIGNUM* n = NULL;
const BIGNUM* e = NULL;
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &n);
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &e);
printf("n:\n");
print_bn(n);
printf("e:\n");
print_bn(e);
// EVP_PKEY* pkey = EVP_EC_gen(SN_X9_62_prime256v1);
// const BIGNUM* x = BN_new();
// const BIGNUM* y = BN_new();
// EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_X, &x);
// EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &y);
// printf("X:\n");
// print_bn(x);
// printf("Y:\n");
// print_bn(y);
BN_free(n);
BN_free(e);
// BN_free(x);
// BN_free(y);
EVP_PKEY_free(pkey);
}
void foo7() {
// Create content buffer
char buffer[128];
for (int i = 0; i < 128; i++) {
buffer[i] = (5*i+13)%128;
}
// Deprecated code
unsigned char hash1[SHA256_DIGEST_LENGTH];
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, buffer, 128);
SHA256_Final(hash1, &ctx);
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
printf("%02X ", hash1[i]);
}
printf("\n");
// Migrated code
unsigned char hash2[SHA256_DIGEST_LENGTH];
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
EVP_DigestUpdate(mdctx, buffer, 128);
EVP_DigestFinal_ex(mdctx, hash2, NULL);
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
printf("%02X ", hash2[i]);
}
printf("\n");
EVP_MD_CTX_free(mdctx);
}
void foo8() {
unsigned char key[128];
for (int i = 0; i < 128; i++) {
key[i] = (13*i + 101)%256;
}
unsigned char data[128];
for (int i = 0; i < 128; i++) {
data[i] = (i*i + 5*i + 13)%256;
}
printf("Key:\n");
for (int i = 0; i < 128; i++) {
printf("%02X", key[i]);
}
printf("\nData:\n");
for (int i = 0; i < 128; i++) {
printf("%02X", data[i]);
}
printf("\n");
unsigned char buffer[32] = {0};
unsigned int hmac_size;
HMAC_CTX* ctx;
if (!(ctx = HMAC_CTX_new()))
printf("441\n");
if (!HMAC_Init_ex(ctx, (const void *)&key[0], 128, EVP_sha256(), NULL))
printf("443\n");
if (!HMAC_Update(ctx, (const unsigned char *)&data[0], 128))
printf("445\n");
if (!HMAC_Final(ctx, &buffer[0], &hmac_size))
printf("447\n");
printf("Bytes written: %d\n", hmac_size);
for (int i=0; i < hmac_size; i++) {
printf("%02X", buffer[i]);
}
printf("\n");
unsigned char buffer2[32] = {0};
unsigned int hmac_size2;
EVP_MAC* mac;
if (!(mac = EVP_MAC_fetch(NULL, OSSL_MAC_NAME_HMAC, NULL)))
printf("458\n");
EVP_MAC_CTX* ctx2;
if (!(ctx2 = EVP_MAC_CTX_new(mac)))
printf("461\n");
OSSL_PARAM params[3];
params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, (const void *)&key[0], 128);
params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, OSSL_DIGEST_NAME_SHA2_256, 0);
params[2] = OSSL_PARAM_construct_end();
if (!EVP_MAC_init(ctx2, NULL, 0, params))
printf("463\n");
if (!EVP_MAC_update(ctx2, (const unsigned char *)&data[0], 128))
printf("465\n");
if (!EVP_MAC_final(ctx2, &buffer2[0], &hmac_size2, 32))
printf("467\n");
printf("Bytes written: %d\n", hmac_size2);
for (int i=0; i < hmac_size2; i++) {
printf("%02X", buffer2[i]);
}
printf("\n");
}
int main() {
printf("OpenSSL version %x\n", OPENSSL_VERSION_NUMBER);
foo8();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment