Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor ED25519_keypair into hw and nohw backend #1271

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 41 additions & 11 deletions crypto/curve25519/curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ OPENSSL_INLINE int x25519_s2n_bignum_capable(void) {
#endif
}

// Return 0 until ED25519 lands in s2n-bignum
OPENSSL_INLINE int ed25519_s2n_bignum_capable(void) {
return 0;
}

// Stub functions if implementations are not compiled.
// These functions have to abort, otherwise we risk applications assuming they
// did work without actually doing anything.
Expand Down Expand Up @@ -234,28 +239,53 @@ static void x25519_s2n_bignum_public_from_private(
#endif
}

// Stub function until ED25519 lands in s2n-bignum
static void ed25519_public_key_from_hashed_seed_s2n_bignum(
uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN],
uint8_t az[SHA512_DIGEST_LENGTH]) {
abort();
}

void ED25519_keypair_from_seed(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN],
uint8_t out_private_key[ED25519_PRIVATE_KEY_LEN],
const uint8_t seed[ED25519_SEED_LEN]) {

void ED25519_keypair_from_seed(uint8_t out_public_key[32],
uint8_t out_private_key[64],
const uint8_t seed[ED25519_SEED_LEN]) {
// Step: rfc8032 5.1.5.1
// Compute SHA512(seed).
uint8_t az[SHA512_DIGEST_LENGTH];
SHA512(seed, ED25519_SEED_LEN, az);

az[0] &= 248;
az[31] &= 127;
az[31] |= 64;
// Step: rfc8032 5.1.5.2
az[0] &= 248; // 11111000_2
az[31] &= 127; // 01111111_2
az[31] |= 64; // 01000000_2

ge_p3 A;
x25519_ge_scalarmult_base(&A, az);
ge_p3_tobytes(out_public_key, &A);
// Step: rfc8032 5.1.5.[3,4]
// Compute [az]B and encode public key to a 32 byte octet.
if (ed25519_s2n_bignum_capable() == 1) {
ed25519_public_key_from_hashed_seed_s2n_bignum(out_public_key, az);
} else {
ed25519_public_key_from_hashed_seed_nohw(out_public_key, az);
}

// Encoded public key is a suffix in the private key. Avoids having to
// generate the public key from the private key when signing.
OPENSSL_STATIC_ASSERT(ED25519_PRIVATE_KEY_LEN == (ED25519_SEED_LEN + ED25519_PUBLIC_KEY_LEN), ed25519_parameter_length_mismatch)
OPENSSL_memcpy(out_private_key, seed, ED25519_SEED_LEN);
OPENSSL_memcpy(out_private_key + ED25519_SEED_LEN, out_public_key, 32);
OPENSSL_memcpy(out_private_key + ED25519_SEED_LEN, out_public_key,
ED25519_PUBLIC_KEY_LEN);
}

void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) {
void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN],
uint8_t out_private_key[ED25519_PRIVATE_KEY_LEN]) {

// Ed25519 key generation: rfc8032 5.1.5
// Private key is 32 octets of random data.
uint8_t seed[ED25519_SEED_LEN];
RAND_bytes(seed, ED25519_SEED_LEN);

// Public key generation is handled in a separate function. See function
// description why this is useful.
torben-hansen marked this conversation as resolved.
Show resolved Hide resolved
torben-hansen marked this conversation as resolved.
Show resolved Hide resolved
ED25519_keypair_from_seed(out_public_key, out_private_key, seed);
OPENSSL_cleanse(seed, ED25519_SEED_LEN);
}
Expand Down
7 changes: 7 additions & 0 deletions crypto/curve25519/curve25519_nohw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1968,3 +1968,10 @@ void x25519_public_from_private_nohw(uint8_t out_public_value[32],
fe_tobytes(out_public_value, &zminusy_inv);
CONSTTIME_DECLASSIFY(out_public_value, 32);
}

void ed25519_public_key_from_hashed_seed_nohw(uint8_t out_public_key[32],
uint8_t az[SHA512_DIGEST_LENGTH]) {
ge_p3 A;
x25519_ge_scalarmult_base(&A, az);
ge_p3_tobytes(out_public_key, &A);
}
4 changes: 4 additions & 0 deletions crypto/curve25519/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extern "C" {
#endif

#include <openssl/base.h>
#include <openssl/curve25519.h>

#include "../internal.h"

Expand Down Expand Up @@ -114,6 +115,9 @@ void x25519_scalar_mult_generic_nohw(uint8_t out[32],
const uint8_t point[32]);
void x25519_public_from_private_nohw(uint8_t out_public_value[32],
const uint8_t private_key[32]);
void ed25519_public_key_from_hashed_seed_nohw(
uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN],
uint8_t az[SHA512_DIGEST_LENGTH]);

// Port to internal linkage in curve25519_nohw.c when adding implementation
// from s2n-bignum ed25519
Expand Down
Loading