summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2017-11-28 12:09:23 +0000
committerMatt Caswell <matt@openssl.org>2018-02-20 12:59:30 +0000
commita242839f75846b9bfa87774a85090651d2ec17c6 (patch)
tree2a7a39cf9e0e4e26f59c1e3024e23e06bb29186d
parentc255e98ed2f6cc686b8fd22eba403fb2e828b5cd (diff)
Convert Curve448 internals to use OpenSSL shake256
Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de> (Merged from https://github.com/openssl/openssl/pull/5105)
-rw-r--r--crypto/ec/curve448/curve448_lcl.h4
-rw-r--r--crypto/ec/curve448/ed448.h12
-rw-r--r--crypto/ec/curve448/eddsa.c176
3 files changed, 125 insertions, 67 deletions
diff --git a/crypto/ec/curve448/curve448_lcl.h b/crypto/ec/curve448/curve448_lcl.h
index d859d52e64..2228dc88d2 100644
--- a/crypto/ec/curve448/curve448_lcl.h
+++ b/crypto/ec/curve448/curve448_lcl.h
@@ -22,5 +22,5 @@ int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[112],
const uint8_t public_key[56], const uint8_t *context,
size_t context_len);
-void ED448_public_from_private(uint8_t out_public_key[56],
- const uint8_t private_key[56]);
+int ED448_public_from_private(uint8_t out_public_key[56],
+ const uint8_t private_key[56]);
diff --git a/crypto/ec/curve448/ed448.h b/crypto/ec/curve448/ed448.h
index ebab7c2985..915908270b 100644
--- a/crypto/ec/curve448/ed448.h
+++ b/crypto/ec/curve448/ed448.h
@@ -53,7 +53,7 @@ extern "C" {
* @param [out] pubkey The public key.
* @param [in] privkey The private key.
*/
-void decaf_ed448_derive_public_key (
+decaf_error_t decaf_ed448_derive_public_key (
uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES],
const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES]
);
@@ -75,7 +75,7 @@ void decaf_ed448_derive_public_key (
* safe. The C++ wrapper is designed to make it harder to screw this up, but this C code gives
* you no seat belt.
*/
-void decaf_ed448_sign (
+decaf_error_t decaf_ed448_sign (
uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES],
const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES],
const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES],
@@ -83,7 +83,7 @@ void decaf_ed448_sign (
size_t message_len,
uint8_t prehashed,
const uint8_t *context,
- uint8_t context_len
+ size_t context_len
) __attribute__((nonnull(1,2,3)));
/**
@@ -101,13 +101,13 @@ void decaf_ed448_sign (
* safe. The C++ wrapper is designed to make it harder to screw this up, but this C code gives
* you no seat belt.
*/
-void decaf_ed448_sign_prehash (
+decaf_error_t decaf_ed448_sign_prehash (
uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES],
const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES],
const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES],
const uint8_t hash[64],
const uint8_t *context,
- uint8_t context_len
+ size_t context_len
) __attribute__((nonnull(1,2,3,4)));
/**
@@ -238,7 +238,7 @@ void decaf_ed448_convert_public_key_to_x448 (
* @param[out] x The ECDH private key as in RFC7748
* @param[in] ed The EdDSA private key
*/
-void decaf_ed448_convert_private_key_to_x448 (
+decaf_error_t decaf_ed448_convert_private_key_to_x448 (
uint8_t x[DECAF_X448_PRIVATE_BYTES],
const uint8_t ed[DECAF_EDDSA_448_PRIVATE_BYTES]
);
diff --git a/crypto/ec/curve448/eddsa.c b/crypto/ec/curve448/eddsa.c
index bf348a921e..b220a6fa2d 100644
--- a/crypto/ec/curve448/eddsa.c
+++ b/crypto/ec/curve448/eddsa.c
@@ -13,12 +13,14 @@
* Please do not edit it.
*/
#include <openssl/crypto.h>
+#include <openssl/evp.h>
#include "curve448_lcl.h"
#include "word.h"
#include "ed448.h"
#include "shake.h"
#include <string.h>
+#include "internal/numbers.h"
#define API_NAME "decaf_448"
@@ -45,6 +47,26 @@ const uint8_t * const DECAF_ED448_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE;
*/
#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY) /* TODO: remove */
+static decaf_error_t oneshot_hash(uint8_t *out, size_t outlen,
+ const uint8_t *in, size_t inlen)
+{
+ EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
+
+ if (hashctx == NULL)
+ return DECAF_FAILURE;
+
+ if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL)
+ || !EVP_DigestUpdate(hashctx, in, inlen)
+ || !EVP_DigestFinalXOF(hashctx, out, outlen)) {
+ EVP_MD_CTX_free(hashctx);
+ return DECAF_FAILURE;
+ }
+
+ EVP_MD_CTX_free(hashctx);
+ return DECAF_SUCCESS;
+}
+
+
static void clamp (
uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES]
) {
@@ -60,14 +82,21 @@ static void clamp (
}
}
-static void hash_init_with_dom(
- hash_ctx_t hash,
+static decaf_error_t hash_init_with_dom(
+ EVP_MD_CTX *hashctx,
uint8_t prehashed,
uint8_t for_prehash,
const uint8_t *context,
- uint8_t context_len
+ size_t context_len
) {
- hash_init(hash);
+ const char *dom_s = "SigEd448";
+ const uint8_t dom[2] = {
+ 2 + word_is_zero(prehashed) + word_is_zero(for_prehash),
+ (uint8_t)context_len
+ };
+
+ if (context_len > UINT8_MAX)
+ return DECAF_FAILURE;
#if NO_CONTEXT
if (context_len == 0 && context == DECAF_ED448_NO_CONTEXT) {
@@ -75,14 +104,17 @@ static void hash_init_with_dom(
(void)for_prehash;
(void)context;
(void)context_len;
- return;
+ return DECAF_SUCCESS;
}
#endif
- const char *dom_s = "SigEd448";
- const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len};
- hash_update(hash,(const unsigned char *)dom_s, strlen(dom_s));
- hash_update(hash,dom,2);
- hash_update(hash,context,context_len);
+
+ if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL)
+ || !EVP_DigestUpdate(hashctx, dom_s, strlen(dom_s))
+ || !EVP_DigestUpdate(hashctx, dom, sizeof(dom))
+ || !EVP_DigestUpdate(hashctx, context, context_len))
+ return DECAF_FAILURE;
+
+ return DECAF_SUCCESS;
}
void decaf_ed448_prehash_init (
@@ -92,13 +124,13 @@ void decaf_ed448_prehash_init (
}
/* In this file because it uses the hash */
-void decaf_ed448_convert_private_key_to_x448 (
+decaf_error_t decaf_ed448_convert_private_key_to_x448 (
uint8_t x[DECAF_X448_PRIVATE_BYTES],
const uint8_t ed[DECAF_EDDSA_448_PRIVATE_BYTES]
) {
- /* pass the private key through hash_hash function */
+ /* pass the private key through oneshot_hash function */
/* and keep the first DECAF_X448_PRIVATE_BYTES bytes */
- hash_hash(
+ return oneshot_hash(
x,
DECAF_X448_PRIVATE_BYTES,
ed,
@@ -106,19 +138,17 @@ void decaf_ed448_convert_private_key_to_x448 (
);
}
-void decaf_ed448_derive_public_key (
+decaf_error_t decaf_ed448_derive_public_key (
uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES],
const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES]
) {
/* only this much used for keygen */
uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES];
- hash_hash(
- secret_scalar_ser,
- sizeof(secret_scalar_ser),
- privkey,
- DECAF_EDDSA_448_PRIVATE_BYTES
- );
+ if (!oneshot_hash(secret_scalar_ser, sizeof(secret_scalar_ser), privkey,
+ DECAF_EDDSA_448_PRIVATE_BYTES)) {
+ return DECAF_FAILURE;
+ }
clamp(secret_scalar_ser);
curve448_scalar_t secret_scalar;
@@ -143,9 +173,11 @@ void decaf_ed448_derive_public_key (
curve448_scalar_destroy(secret_scalar);
curve448_point_destroy(p);
OPENSSL_cleanse(secret_scalar_ser, sizeof(secret_scalar_ser));
+
+ return DECAF_SUCCESS;
}
-void decaf_ed448_sign (
+decaf_error_t decaf_ed448_sign (
uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES],
const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES],
const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES],
@@ -153,29 +185,36 @@ void decaf_ed448_sign (
size_t message_len,
uint8_t prehashed,
const uint8_t *context,
- uint8_t context_len
+ size_t context_len
) {
curve448_scalar_t secret_scalar;
- hash_ctx_t hash;
+ EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
+ decaf_error_t ret = DECAF_FAILURE;
+
+ if (hashctx == NULL)
+ return DECAF_FAILURE;
+
{
/* Schedule the secret key */
struct {
uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES];
uint8_t seed[DECAF_EDDSA_448_PRIVATE_BYTES];
} __attribute__((packed)) expanded;
- hash_hash(
- (uint8_t *)&expanded,
- sizeof(expanded),
- privkey,
- DECAF_EDDSA_448_PRIVATE_BYTES
- );
+
+ if (!oneshot_hash((uint8_t *)&expanded, sizeof(expanded), privkey,
+ DECAF_EDDSA_448_PRIVATE_BYTES))
+ goto err;
clamp(expanded.secret_scalar_ser);
curve448_scalar_decode_long(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser));
/* Hash to create the nonce */
- hash_init_with_dom(hash,prehashed,0,context,context_len);
- hash_update(hash,expanded.seed,sizeof(expanded.seed));
- hash_update(hash,message,message_len);
+ if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len)
+ || !EVP_DigestUpdate(hashctx, expanded.seed,
+ sizeof(expanded.seed))
+ || !EVP_DigestUpdate(hashctx, message, message_len)) {
+ OPENSSL_cleanse(&expanded, sizeof(expanded));
+ goto err;
+ }
OPENSSL_cleanse(&expanded, sizeof(expanded));
}
@@ -183,7 +222,9 @@ void decaf_ed448_sign (
curve448_scalar_t nonce_scalar;
{
uint8_t nonce[2*DECAF_EDDSA_448_PRIVATE_BYTES];
- hash_final(hash,nonce,sizeof(nonce));
+
+ if (!EVP_DigestFinalXOF(hashctx, nonce, sizeof(nonce)))
+ goto err;
curve448_scalar_decode_long(nonce_scalar, nonce, sizeof(nonce));
OPENSSL_cleanse(nonce, sizeof(nonce));
}
@@ -206,14 +247,17 @@ void decaf_ed448_sign (
curve448_scalar_t challenge_scalar;
{
- /* Compute the challenge */
- hash_init_with_dom(hash,prehashed,0,context,context_len);
- hash_update(hash,nonce_point,sizeof(nonce_point));
- hash_update(hash,pubkey,DECAF_EDDSA_448_PUBLIC_BYTES);
- hash_update(hash,message,message_len);
uint8_t challenge[2*DECAF_EDDSA_448_PRIVATE_BYTES];
- hash_final(hash,challenge,sizeof(challenge));
- hash_destroy(hash);
+
+ /* Compute the challenge */
+ if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len)
+ || !EVP_DigestUpdate(hashctx, nonce_point, sizeof(nonce_point))
+ || !EVP_DigestUpdate(hashctx, pubkey,
+ DECAF_EDDSA_448_PUBLIC_BYTES)
+ || !EVP_DigestUpdate(hashctx, message, message_len)
+ || !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge)))
+ goto err;
+
curve448_scalar_decode_long(challenge_scalar,challenge,sizeof(challenge));
OPENSSL_cleanse(challenge,sizeof(challenge));
}
@@ -228,18 +272,24 @@ void decaf_ed448_sign (
curve448_scalar_destroy(secret_scalar);
curve448_scalar_destroy(nonce_scalar);
curve448_scalar_destroy(challenge_scalar);
+
+ ret = DECAF_SUCCESS;
+ err:
+ EVP_MD_CTX_free(hashctx);
+ return ret;
}
-void decaf_ed448_sign_prehash (
+decaf_error_t decaf_ed448_sign_prehash (
uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES],
const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES],
const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES],
const uint8_t hash[64],
const uint8_t *context,
- uint8_t context_len
+ size_t context_len
) {
- decaf_ed448_sign(signature,privkey,pubkey,hash,64,1,context,context_len);
+ return decaf_ed448_sign(signature,privkey,pubkey,hash,64,1,context,
+ context_len);
/*OPENSSL_cleanse(hash,sizeof(hash));*/
}
@@ -262,14 +312,23 @@ decaf_error_t decaf_ed448_verify (
curve448_scalar_t challenge_scalar;
{
/* Compute the challenge */
- hash_ctx_t hash;
- hash_init_with_dom(hash,prehashed,0,context,context_len);
- hash_update(hash,signature,DECAF_EDDSA_448_PUBLIC_BYTES);
- hash_update(hash,pubkey,DECAF_EDDSA_448_PUBLIC_BYTES);
- hash_update(hash,message,message_len);
+ EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
uint8_t challenge[2*DECAF_EDDSA_448_PRIVATE_BYTES];
- hash_final(hash,challenge,sizeof(challenge));
- hash_destroy(hash);
+
+ if (hashctx == NULL
+ || !hash_init_with_dom(hashctx, prehashed, 0, context,
+ context_len)
+ || !EVP_DigestUpdate(hashctx, signature,
+ DECAF_EDDSA_448_PUBLIC_BYTES)
+ || !EVP_DigestUpdate(hashctx, pubkey,
+ DECAF_EDDSA_448_PUBLIC_BYTES)
+ || !EVP_DigestUpdate(hashctx, message, message_len)
+ || !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge))) {
+ EVP_MD_CTX_free(hashctx);
+ return DECAF_FAILURE;
+ }
+
+ EVP_MD_CTX_free(hashctx);
curve448_scalar_decode_long(challenge_scalar,challenge,sizeof(challenge));
OPENSSL_cleanse(challenge,sizeof(challenge));
}
@@ -317,10 +376,9 @@ int ED448_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
const uint8_t *context, size_t context_len)
{
- decaf_ed448_sign(out_sig, private_key, public_key, message, message_len, 0,
- context, context_len);
-
- return 1;
+ return decaf_ed448_sign(out_sig, private_key, public_key, message,
+ message_len, 0, context, context_len)
+ == DECAF_SUCCESS;
}
@@ -336,10 +394,9 @@ int ED448ph_sign(uint8_t *out_sig, const uint8_t hash[64],
const uint8_t public_key[56], const uint8_t private_key[56],
const uint8_t *context, size_t context_len)
{
- decaf_ed448_sign_prehash(out_sig, private_key, public_key, hash, context,
- context_len);
+ return decaf_ed448_sign_prehash(out_sig, private_key, public_key, hash,
+ context, context_len) == DECAF_SUCCESS;
- return 1;
}
int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[112],
@@ -350,8 +407,9 @@ int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[112],
context_len) == DECAF_SUCCESS;
}
-void ED448_public_from_private(uint8_t out_public_key[56],
+int ED448_public_from_private(uint8_t out_public_key[56],
const uint8_t private_key[56])
{
- decaf_ed448_derive_public_key(out_public_key, private_key);
+ return decaf_ed448_derive_public_key(out_public_key, private_key)
+ == DECAF_SUCCESS;
}