Created
August 25, 2017 19:33
-
-
Save melvyniandrag/42e577d69e2350082f3b01fef686772d to your computer and use it in GitHub Desktop.
Integrating OpenSSL and MPI for testing purposes.
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 <mpi.h> | |
#include <openssl/evp.h> | |
#include <openssl/ec.h> | |
#include <iostream> | |
#include <cstring> | |
#include <cassert> | |
void handleErrors(){ | |
; | |
} | |
void ecdh(size_t *secret_len) | |
{ | |
MPI_Init(NULL, NULL); | |
// Find out rank, size | |
int world_rank; | |
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); | |
int world_size; | |
MPI_Comm_size(MPI_COMM_WORLD, &world_size); | |
std::cout << "starting computation on processor :" << world_rank << std::endl; | |
EVP_PKEY_CTX *pctx; | |
EVP_PKEY_CTX *kctx; | |
EVP_PKEY_CTX *ctx; | |
unsigned char *secret; | |
EVP_PKEY *pkey = NULL; | |
EVP_PKEY *peerkey; | |
EVP_PKEY *params = NULL; | |
/* NB: assumes pkey, peerkey have been already set up */ | |
/* Create the context for parameter generation */ | |
if(NULL == (pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) | |
handleErrors(); | |
/* Initialise the parameter generation */ | |
if(1 != EVP_PKEY_paramgen_init(pctx)) handleErrors(); | |
/* We're going to use the ANSI X9.62 Prime 256v1 curve */ | |
if(1 != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1)) handleErrors(); | |
/* Create the parameter object params */ | |
if (!EVP_PKEY_paramgen(pctx, ¶ms)) handleErrors(); | |
/* Create the context for the key generation */ | |
if(NULL == (kctx = EVP_PKEY_CTX_new(params, NULL))) handleErrors(); | |
/* Generate the key */ | |
if(1 != EVP_PKEY_keygen_init(kctx)) handleErrors(); | |
if (1 != EVP_PKEY_keygen(kctx, &pkey)) handleErrors(); | |
/* Get the peer's public key, and provide the peer with our public key - | |
* how this is done will be specific to your circumstances */ | |
assert( ( world_rank == 1 ) || ( world_rank == 0 ) ); | |
const size_t KeySize = sizeof( EVP_PKEY ); | |
std::cout << "Data transmission size: " << KeySize << std::endl; | |
const int Destination = ( world_rank + 1 ) % 2; | |
const int Source = Destination; | |
const int Tag = 0; | |
std::cout << "Begining mpi transaction on processor: " << world_rank << ", talking to processor: " << Destination << std::endl; | |
if( world_rank == 0 ) | |
{ | |
MPI_Send(pkey, KeySize, MPI_BYTE, Destination, Tag, MPI_COMM_WORLD); | |
} | |
else | |
{ | |
MPI_Recv(peerkey, KeySize, MPI_BYTE, Source, Tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE); | |
} | |
std::cout << "Finishing first transmission and begining the next one." << std::endl; | |
if( world_rank == 0 ) | |
{ | |
MPI_Recv(peerkey, KeySize, MPI_BYTE, Source, Tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE); | |
} | |
else | |
{ | |
MPI_Send(pkey, KeySize, MPI_BYTE, Destination, Tag, MPI_COMM_WORLD); | |
} | |
std::cout << "Finishing mpi transaction on processor: " << world_rank << std::endl; | |
/* Create the context for the shared secret derivation */ | |
if(NULL == (ctx = EVP_PKEY_CTX_new(pkey, NULL))) handleErrors(); | |
/* Initialise */ | |
if(1 != EVP_PKEY_derive_init(ctx)) handleErrors(); | |
/* Provide the peer public key */ | |
if(1 != EVP_PKEY_derive_set_peer(ctx, peerkey)) handleErrors(); | |
/* Determine buffer length for shared secret */ | |
if(1 != EVP_PKEY_derive(ctx, NULL, secret_len)) handleErrors(); | |
/* Create the buffer */ | |
if(NULL == (secret = static_cast<unsigned char*>( OPENSSL_malloc(*secret_len)) )) handleErrors(); | |
/* Derive the shared secret */ | |
if(1 != (EVP_PKEY_derive(ctx, secret, secret_len))) handleErrors(); | |
EVP_PKEY_CTX_free(ctx); | |
EVP_PKEY_free(peerkey); | |
EVP_PKEY_free(pkey); | |
EVP_PKEY_CTX_free(kctx); | |
EVP_PKEY_free(params); | |
EVP_PKEY_CTX_free(pctx); | |
/* Never use a derived secret directly. Typically it is passed | |
* through some hash function to produce a key */ | |
std::cout << world_rank << " made secret : " << secret << std::endl; | |
MPI_Finalize(); | |
} | |
int main(int argc, char** argv){ | |
size_t secretLen = 0; | |
ecdh( &secretLen ); | |
std::cout << secretLen << std::endl; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment