Steffen Jaeckel 11 månader sedan
förälder
incheckning
39e8c51e4b
1 ändrade filer med 32 tillägg och 27 borttagningar
  1. 32 27
      src/pk/ecc/ecc_rfc6979_key.c

+ 32 - 27
src/pk/ecc/ecc_rfc6979_key.c

@@ -1,11 +1,5 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- */
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 #include "tomcrypt_private.h"
 
@@ -20,14 +14,15 @@
 /**
   Make deterministic ECC key using the RFC6979 method
   @param priv         [in] Private key for HMAC
+  @param hash         The hash idx to use or -1 for automatic determination depending on `inlen`.
   @param in           Message to sign for HMAC
   @param inlen        Length of the message
   @param key          [out] Newly created deterministic key
   @return CRYPT_OK if successful, upon error all allocated memory will be freed
 */
-int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, int inlen, ecc_key *key)
+int ecc_rfc6979_key(const ecc_key *priv, int hash, const unsigned char *in, unsigned long inlen, ecc_key *key)
 {
-   int            err, hash, i;
+   int            err, hash_ = -1, i;
    unsigned char  v[32], k[32], digest[32]; /* No way to determine hash so always use SHA256 */
    unsigned char  buffer[256];
    unsigned long  outlen, buflen, qlen;
@@ -36,8 +31,22 @@ int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, int inlen, ecc
    LTC_ARGCHK(key         != NULL);
    LTC_ARGCHK(key->dp.size > 0);
 
-   hash = find_hash("sha256");
-   if (hash == -1) {err = CRYPT_ERROR; goto error;}
+   if (hash_is_valid(hash) == CRYPT_OK) {
+      hash_ = hash;
+   } else {
+      if (inlen == 20)
+         hash_ = find_hash("sha1");
+      else if (inlen == 28)
+         hash_ = find_hash("sha224");
+      else if (inlen == 32)
+         hash_ = find_hash("sha256");
+      else if (inlen == 48)
+         hash_ = find_hash("sha384");
+      else if (inlen == 64)
+         hash_ = find_hash("sha512");
+      if ((err = hash_is_valid(hash_)) != CRYPT_OK)
+         goto error;
+   }
 
    /* Length, in bytes, of key */
    i = mp_count_bits(key->dp.order);
@@ -52,47 +61,47 @@ int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, int inlen, ecc
    /* RFC6979 3.2d, set K to HMAC_K(V::0x00::priv::in) */
    XMEMCPY(&buffer[0], v, 32);
    buffer[32] = 0x00;
-   if ((err = mp_to_unsigned_bin(priv->k, &buffer[33]) != CRYPT_OK))                                   { goto error; }
+   if ((err = mp_to_unsigned_bin(priv->k, &buffer[33]) != CRYPT_OK))                                    { goto error; }
    XMEMCPY(&buffer[33+qlen], in, inlen);
    buflen = 32 + 1 + qlen + inlen;
    outlen = sizeof(digest);
-   if((err = hmac_memory(hash, k, 32, buffer, buflen, digest, &outlen)) != CRYPT_OK)                   { goto error; }
+   if((err = hmac_memory(hash_, k, 32, buffer, buflen, digest, &outlen)) != CRYPT_OK)                   { goto error; }
    XMEMCPY(k, digest, 32);
 
    /* RFC6979 3.2e, set V = HMAC_K(V) */
    outlen = sizeof(digest);
-   if((err = hmac_memory(hash, k, 32, v, 32, digest, &outlen)) != CRYPT_OK)                            { goto error; }
+   if((err = hmac_memory(hash_, k, 32, v, 32, digest, &outlen)) != CRYPT_OK)                            { goto error; }
    XMEMCPY(v, digest, 32);
 
    /* RFC6979 3.2f, set K to HMAC_K(V::0x01::priv::in) */
    XMEMCPY(&buffer[0], v, 32);
    buffer[32] = 0x01;
-   if ((err = mp_to_unsigned_bin(priv->k, &buffer[33]) != CRYPT_OK))                                   { goto error; }
+   if ((err = mp_to_unsigned_bin(priv->k, &buffer[33]) != CRYPT_OK))                                    { goto error; }
    XMEMCPY(&buffer[33+qlen], in, inlen);
    buflen = 32 + 1 + qlen + inlen;
    outlen = sizeof(digest);
-   if((err = hmac_memory(hash, k, 32, buffer, buflen, digest, &outlen)) != CRYPT_OK)                   { goto error; }
+   if((err = hmac_memory(hash_, k, 32, buffer, buflen, digest, &outlen)) != CRYPT_OK)                   { goto error; }
    XMEMCPY(k, digest, 32);
 
    /* RFC6979 3.2g, set V = HMAC_K(V) */
    outlen = sizeof(digest);
-   if((err = hmac_memory(hash, k, 32, v, 32, digest, &outlen)) != CRYPT_OK)                            { goto error; }
+   if((err = hmac_memory(hash_, k, 32, v, 32, digest, &outlen)) != CRYPT_OK)                            { goto error; }
    XMEMCPY(v, digest, 32);
 
    /* RFC6979 3.2h, generate and check key */
    do {
-      /* concatenate hash bits into T */
+      /* concatenate hash_ bits into T */
       buflen = 0;
       while (buflen < qlen) {
          outlen = sizeof(digest);
-         if((err = hmac_memory(hash, k, 32, v, 32, digest, &outlen)) != CRYPT_OK)                      { goto error; }
+         if((err = hmac_memory(hash_, k, 32, v, 32, digest, &outlen)) != CRYPT_OK)                      { goto error; }
          XMEMCPY(v, digest, 32);
          XMEMCPY(&buffer[buflen], v, 32);
          buflen += 32;
       }
 
       /* key->k = bits2int(T) */
-      if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buffer, qlen)) != CRYPT_OK)             { goto error; }
+      if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buffer, qlen)) != CRYPT_OK)              { goto error; }
 
       /* make the public key */
       if ((err = ltc_mp.ecc_ptmul(key->k, &key->dp.base, &key->pubkey, key->dp.A, key->dp.prime, 1)) != CRYPT_OK) {
@@ -111,12 +120,12 @@ int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, int inlen, ecc
          buffer[32] = 0x00;
          buflen = 32 + 1;
          outlen = sizeof(digest);
-         if((err = hmac_memory(hash, k, 32, buffer, buflen, digest, &outlen)) != CRYPT_OK)             { goto error; }
+         if((err = hmac_memory(hash_, k, 32, buffer, buflen, digest, &outlen)) != CRYPT_OK)             { goto error; }
          XMEMCPY(k, digest, 32);
 
          /* V = HMAC_K(V) */
          outlen = sizeof(digest);
-         if((err = hmac_memory(hash, k, 32, v, 32, digest, &outlen)) != CRYPT_OK)                      { goto error; }
+         if((err = hmac_memory(hash_, k, 32, v, 32, digest, &outlen)) != CRYPT_OK)                      { goto error; }
          XMEMCPY(v, digest, 32);
 
          /* ... and try again! */
@@ -137,7 +146,3 @@ cleanup:
 
 #endif
 #endif
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
-