Skip to content

Instantly share code, notes, and snippets.

@pushkarnk
Created September 27, 2023 11:54
Show Gist options
  • Save pushkarnk/9202f74ec6599a53ee8af26c59ad4e5f to your computer and use it in GitHub Desktop.
Save pushkarnk/9202f74ec6599a53ee8af26c59ad4e5f to your computer and use it in GitHub Desktop.
Key Agreement
#include <openssl/evp.h>
#include <stdio.h>
typedef enum Algo {
AlgoDH, AlgoEC
} Algo;
int generate_shared_secret(EVP_PKEY *private_key,
EVP_PKEY *peer_public_key,
unsigned char **secret) {
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(private_key, NULL);
if (ctx == NULL) {
printf("EVP_KEY_CTX_new failed\n");
}
if (EVP_PKEY_derive_init(ctx) <= 0) {
printf("EVP_PKEY_derive_init failed\n");
}
if (EVP_PKEY_derive_set_peer(ctx, peer_public_key) <= 0) {
printf("EVP_PKEY_derive_set_peer failed\n");
}
size_t len = 0;
if (EVP_PKEY_derive(ctx, NULL, &len) <= 0) {
printf("EVP_PKEY_derive with NULL buffer failed\n");
}
*secret = OPENSSL_malloc(len);
if (!*secret) {
printf("Could not allocate memory\n");
}
if (EVP_PKEY_derive(ctx, *secret, &len) <= 0) {
printf("EVP_PKEY_dervice failed\n");
}
printf("Returning secret = %x, len = %ld\n", secret, len);
return len;
}
void compare(unsigned char *s1, size_t l1, unsigned char *s2, size_t l2) {
if (l1 != l2) {
printf("The secrets don't match\n");
return;
}
for (size_t i = 0; i < l1; i++) {
if (s1[i] != s2[i]) {
printf("The secrets don't match\n");
}
}
printf("The secrets match!\n");
}
EVP_PKEY* create_key(Algo algo, EVP_PKEY ** ppkey) {
EVP_PKEY_CTX *pctx = NULL;
EVP_PKEY *key = NULL;
OSSL_PARAM params[2];
if (algo == AlgoDH) {
if(NULL == (pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL)))
printf("Error in DH key generation\n");
params[0] = OSSL_PARAM_construct_utf8_string("group", "ffdhe2048", 0);
params[1] = OSSL_PARAM_construct_end();
} else {
if(NULL == (pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)))
printf("Error in DH key generation\n");
params[0] = OSSL_PARAM_construct_utf8_string("group", "prime256v1", 0);
params[1] = OSSL_PARAM_construct_end();
}
if(EVP_PKEY_keygen_init(pctx) <= 0)
printf("EVP_PKEY_keygen_init failed\n");
EVP_PKEY_CTX_set_params(pctx, params);
if(EVP_PKEY_keygen(pctx, &key) <= 0)
printf("EVP_PKEY_keygen failed\n");
*ppkey = key;
}
void test(Algo type) {
EVP_PKEY *key1 = NULL, *key2 = NULL;
unsigned char *secret1 = NULL, *secret2 = NULL;
create_key(type, &key1);
create_key(type, &key2);
int len1 = generate_shared_secret(key1, key2, &secret1);
int len2 = generate_shared_secret(key2, key1, &secret2);
compare(secret1, len1, secret2, len2);
}
int main(int argc, char *argv[]) {
test(AlgoEC);
test(AlgoDH);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment