Convert Curve448 internals to use OpenSSL shake256
authorMatt Caswell <matt@openssl.org>
Tue, 28 Nov 2017 12:09:23 +0000 (12:09 +0000)
committerMatt Caswell <matt@openssl.org>
Tue, 20 Feb 2018 12:59:30 +0000 (12:59 +0000)
Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
(Merged from https://github.com/openssl/openssl/pull/5105)

crypto/ec/curve448/curve448_lcl.h
crypto/ec/curve448/ed448.h
crypto/ec/curve448/eddsa.c

index d859d52e64a2466d20cbff15a433a91139aba847..2228dc88d20a8e4bdd21d1231691c822426e6089 100644 (file)
@@ -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]);
index ebab7c29850d79b9294b5cde4647bb070c4f70f1..915908270b75be5ff3425e764d906c7bd832b30c 100644 (file)
@@ -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]
 );
index bf348a921e94b3cfc3726427a9216ac390fa7c2c..b220a6fa2d48a0507ca775442b34470394b3795a 100644 (file)
  * 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;
 }