Switched to ephemeral DH

This commit is contained in:
John Jones 2017-03-08 07:23:32 -05:00
parent f182fb8857
commit e092a0e974
3 changed files with 32 additions and 20 deletions

View file

@ -2,7 +2,7 @@
#include <string.h> #include <string.h>
#include "mbedtls/config.h" #include "mbedtls/config.h"
#include "mbedtls/ecdsa.h" #include "mbedtls/ecdh.h"
#include "mbedtls/entropy.h" #include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h" #include "mbedtls/ctr_drbg.h"
#include "libp2p/crypto/ephemeral.h" #include "libp2p/crypto/ephemeral.h"
@ -32,19 +32,16 @@ void libp2p_crypto_ephemeral_stretched_key_free(struct StretchedKey* key) {
} }
} }
struct EphemeralPrivateKey* libp2p_crypto_ephemeral_key_new(uint64_t priv, uint64_t x, uint64_t y, size_t num_bits) { struct EphemeralPrivateKey* libp2p_crypto_ephemeral_key_new() {
struct EphemeralPrivateKey* results = (struct EphemeralPrivateKey*)malloc(sizeof(struct EphemeralPrivateKey)); struct EphemeralPrivateKey* results = (struct EphemeralPrivateKey*)malloc(sizeof(struct EphemeralPrivateKey));
if (results != NULL) { if (results != NULL) {
results->secret_key = priv; results->num_bits = 0;
results->num_bits = num_bits; results->secret_key = 0;
results->public_key = (struct EphemeralPublicKey*)malloc(sizeof(struct EphemeralPublicKey)); results->public_key = (struct EphemeralPublicKey*)malloc(sizeof(struct EphemeralPublicKey));
if (results->public_key == NULL) { if (results->public_key == NULL) {
free(results); free(results);
results = NULL; results = NULL;
} else { } else {
results->public_key->num_bits = num_bits;
results->public_key->x = x;
results->public_key->y = y;
results->public_key->bytes = NULL; results->public_key->bytes = NULL;
results->public_key->bytes_size = 0; results->public_key->bytes_size = 0;
results->public_key->shared_key = NULL; results->public_key->shared_key = NULL;
@ -56,6 +53,7 @@ struct EphemeralPrivateKey* libp2p_crypto_ephemeral_key_new(uint64_t priv, uint6
void libp2p_crypto_ephemeral_key_free(struct EphemeralPrivateKey* in) { void libp2p_crypto_ephemeral_key_free(struct EphemeralPrivateKey* in) {
if (in != NULL) { if (in != NULL) {
mbedtls_ecdh_free(&in->ctx);
if (in->public_key != NULL) { if (in->public_key != NULL) {
if (in->public_key->bytes != NULL) if (in->public_key->bytes != NULL)
free(in->public_key->bytes); free(in->public_key->bytes);
@ -104,6 +102,7 @@ uint64_t unserialize_uint64(unsigned char in[8]) {
int libp2p_crypto_ephemeral_point_marshal(int bit_size, uint64_t x, uint64_t y, unsigned char** results, size_t* bytes_written) { int libp2p_crypto_ephemeral_point_marshal(int bit_size, uint64_t x, uint64_t y, unsigned char** results, size_t* bytes_written) {
int byteLen = (bit_size + 7) >> 3; int byteLen = (bit_size + 7) >> 3;
// bytelen is 32, and we never fill in from 1 to 33. hmmm....
*results = (unsigned char*)malloc(2*byteLen+1); *results = (unsigned char*)malloc(2*byteLen+1);
memset(*results, 0, 2*byteLen+1); memset(*results, 0, 2*byteLen+1);
*results[0] = 4; // uncompressed point *results[0] = 4; // uncompressed point
@ -142,7 +141,7 @@ int libp2p_crypto_ephemeral_point_unmarshal(int bit_size, unsigned char* buffer,
*/ */
int libp2p_crypto_ephemeral_keypair_generate(char* curve, struct EphemeralPrivateKey** private_key_ptr) { int libp2p_crypto_ephemeral_keypair_generate(char* curve, struct EphemeralPrivateKey** private_key_ptr) {
int retVal = 0; int retVal = 0;
mbedtls_ecdsa_context ctx; //mbedtls_ecdh_context ctx;
mbedtls_entropy_context entropy; mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_context ctr_drbg;
struct EphemeralPrivateKey* private_key = NULL; struct EphemeralPrivateKey* private_key = NULL;
@ -157,7 +156,12 @@ int libp2p_crypto_ephemeral_keypair_generate(char* curve, struct EphemeralPrivat
else else
selected_curve = MBEDTLS_ECP_DP_SECP521R1; selected_curve = MBEDTLS_ECP_DP_SECP521R1;
mbedtls_ecdsa_init(&ctx); // allocate memory for result storage
*private_key_ptr = libp2p_crypto_ephemeral_key_new();
private_key = *private_key_ptr;
public_key = private_key->public_key;
mbedtls_ecdh_init(&private_key->ctx);
// seed random number generator // seed random number generator
mbedtls_entropy_init(&entropy); mbedtls_entropy_init(&entropy);
@ -165,19 +169,20 @@ int libp2p_crypto_ephemeral_keypair_generate(char* curve, struct EphemeralPrivat
if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char*)pers, strlen(pers)) != 0) if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char*)pers, strlen(pers)) != 0)
goto exit; goto exit;
// generate key // generate public key
if (mbedtls_ecdsa_genkey(&ctx, selected_curve, mbedtls_ctr_drbg_random, &ctr_drbg) != 0) if (mbedtls_ecp_group_load(&private_key->ctx.grp, selected_curve) != 0)
goto exit; goto exit;
*private_key_ptr = libp2p_crypto_ephemeral_key_new(*ctx.d.p, *ctx.Q.X.p, *ctx.Q.Y.p, ctx.grp.nbits); if (mbedtls_ecdh_gen_public(&private_key->ctx.grp, &private_key->ctx.d, &private_key->ctx.Q, mbedtls_ctr_drbg_random, &ctr_drbg) != 0)
goto exit;
private_key = *private_key_ptr; public_key->bytes_size = 32;
public_key = private_key->public_key; public_key->bytes = (unsigned char*)malloc(public_key->bytes_size);
if (mbedtls_mpi_write_binary(&private_key->ctx.Q.X, (char*)public_key->bytes, public_key->bytes_size) != 0)
// Fill in more of the public key goto exit;
libp2p_crypto_ephemeral_point_marshal(public_key->num_bits, public_key->x, public_key->y, &public_key->bytes, &public_key->bytes_size);
// build shared key, another part of public_key // build shared key, another part of public_key
/*
//mbedtls_ecp_group grp; //mbedtls_ecp_group grp;
mbedtls_ecp_point point; mbedtls_ecp_point point;
//mbedtls_ecp_group_init(&grp); //mbedtls_ecp_group_init(&grp);
@ -187,17 +192,15 @@ int libp2p_crypto_ephemeral_keypair_generate(char* curve, struct EphemeralPrivat
public_key->shared_key_size = 8; public_key->shared_key_size = 8;
public_key->shared_key = (unsigned char*)malloc(8); public_key->shared_key = (unsigned char*)malloc(8);
serialize_uint64(*point.X.p, public_key->shared_key); serialize_uint64(*point.X.p, public_key->shared_key);
*/
// ship all this stuff back to the caller // ship all this stuff back to the caller
retVal = 1; retVal = 1;
exit: exit:
mbedtls_ecp_point_free(&point);
mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy); mbedtls_entropy_free(&entropy);
mbedtls_ecdsa_free(&ctx);
return retVal; return retVal;
} }

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include "mbedtls/ecdh.h"
/** /**
* General helpers for ephemeral keys * General helpers for ephemeral keys
@ -28,6 +29,7 @@ struct EphemeralPublicKey {
struct EphemeralPrivateKey { struct EphemeralPrivateKey {
size_t num_bits; size_t num_bits;
uint64_t secret_key; uint64_t secret_key;
mbedtls_ecdh_context ctx;
struct EphemeralPublicKey* public_key; struct EphemeralPublicKey* public_key;
}; };

View file

@ -63,6 +63,13 @@ int test_ephemeral_key_sign() {
if (!libp2p_crypto_ephemeral_keypair_generate("P-256", &e_private_key)) if (!libp2p_crypto_ephemeral_keypair_generate("P-256", &e_private_key))
goto exit; goto exit;
// print the ephemeral public key bytes
fprintf(stdout, "Public Key Bytes: ");
for(int i = 0; i < e_private_key->public_key->bytes_size; i++) {
fprintf(stdout, "%02x", e_private_key->public_key->bytes[i]);
}
fprintf(stdout, "\n");
// attempt to sign // attempt to sign
libp2p_crypto_rsa_sign(rsa_private_key, e_private_key->public_key->bytes, e_private_key->public_key->bytes_size, &result, &result_size); libp2p_crypto_rsa_sign(rsa_private_key, e_private_key->public_key->bytes, e_private_key->public_key->bytes_size, &result, &result_size);