|
|
@@ -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$ */
|
|
|
-
|