Created
September 27, 2023 11:54
-
-
Save pushkarnk/9202f74ec6599a53ee8af26c59ad4e5f to your computer and use it in GitHub Desktop.
Key Agreement
This file contains 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 <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