Topic: ECC signing and verify

Hi,

I have looked into ECC signature, especially into the example at \wolfssl-examples-master\signature\ecc-sign-verify. This compiles and runs. In the example a key is produced and with this key signing and subsequent verification is done. I wanted to have it more realistic, so that the key generation, the code signing and the verification are separated from each others.
So I splitted this into 4 independent files "keymake", "sign", "verify" and a "main"  (here for simplicity put together). in "keymake" I generated "der" data for the public key and the private key , in "sign" I signed a hash, in "validate" I validated the signature, and in "main" I call all three others, taking care that these others only know what they need to know.


(condensed) code is:

//some stuff, used separately in all modules, here  put in one place for simplicity
#define BYTE_SZ 8
static ecc_key key;   //got stack corruption when I use it as a local var
static WC_RNG rng;

//creates a key and corresponding public and private der data
int keymake(  int eccKeySz,  char* der_file_private,  int* der_file_private_size,
  char* der_file_public,  int* der_file_public_size)
{
  int ret;
  int verified = 0;
  int byteField = (512 + (BYTE_SZ - 1)) / BYTE_SZ;

  wolfCrypt_Init();
  ret = wc_ecc_init(&key);
  ret = wc_InitRng(&rng);
  ret = wc_ecc_make_key(&rng, byteField, &key);
  *der_file_private_size = wc_EccPrivateKeyToDer(&key, der_file_private, *der_file_private_size);
  //???? what is parameter 4 ?
  *der_file_public_size = wc_EccPublicKeyToDer(&key, der_file_public, *der_file_public_size, ECC_SECP256R1);
}

//creates a signature of a hash using private der data
int sign(  char* hash,  int hash_size,  char* der_file_private,  int der_file_private_size,
  char* signature,  int* signature_size)
{
  int ret;
  wc_ecc_init(&key);
  word32 idx = 0;
  wc_EccPrivateKeyDecode(der_file_private, &idx, &key, der_file_private_size);
  ret = wc_InitRng(&rng);
  ret = wc_ecc_sign_hash(hash, sizeof(hash), signature, signature_size, &rng, &key);
}

//verifies a signature of a hash using public der data
int verify(  char* hash,  int hash_size,  char* der_file_public,  int der_file_public_size,
  char* signature,  int signature_size)
{
  int ret;
  int verified = 0;
  word32 idx = 0;
  wc_ecc_init(&key);  //set up a new one
  ret = wc_EccPublicKeyDecode(der_file_public, &idx, &key, der_file_public_size);
  ret = wc_ecc_verify_hash(signature, signature_size, hash, hash_size, &verified, &key);
  if ((ret != 0) || verified != 1) { printf("verification failed\n"); return(-1)}
  return(0);
}

int main(int argc, char** argv)
{
  unsigned char hash[32] = {
                            0x3b, 0x07, 0x54, 0x5c, 0xfd, 0x4f, 0xb7, 0xb5,
                            0xaf, 0xa7, 0x7a, 0x25, 0x33, 0xa5, 0x50, 0x70,
                            0x4a, 0x65, 0x3e, 0x72, 0x7e, 0xcd, 0xd4, 0x5b,
                            0x1b, 0x36, 0x96, 0x96, 0xca, 0x4f, 0x9b, 0x6f
  };
  byte der_file_private[1000];
  int der_file_private_size = 1000;
  byte der_file_public[1000];
  int  der_file_public_size = 1000;
  byte signature[ECC_MAX_SIG_SIZE];
  int signature_size = ECC_MAX_SIG_SIZE;

  int ret;

  ret = keymake(256, der_file_private, &der_file_private_size, der_file_public, &der_file_public_size);
  ret = sign(hash, sizeof(hash), der_file_private, der_file_private_size, signature, &signature_size);
  ret = verify(hash, sizeof(hash), der_file_public, der_file_public_size, signature, signature_size);
  printf("verify ret=%i\n", ret);
}

All this compiles, runs, there are no run time errors, but the last thing in verify(),  wc_ecc_verify_hash(signature, signature_size, hash, hash_size, &verified, &key), returns a 0 in "verified", failing the whole thing.

Can anyone of the people who do that all the time point me to my mistake? The only change to the (working) \wolfssl-examples-master\signature\ecc-sign-verify example  is that I tried to create public and private key as "der"-data and use them instead of the generated key. Also, there is the 4th parameter in wc_EccPublicKeyToDer(), which I just guessed as ECC_SECP256R1, This may be an issue.

Share

2 (edited by Kaleb J. Himes 2020-12-01 10:17:27)

Re: ECC signing and verify

Hi @Vitus,

Can you tell us a bit about your project and what the end goals are? This helps us to better qualify the inquiry, thank you!


Can you double check that <wolfssl/options.h> is included in any .c source files running wolfSSL operations BEFORE all other wolfSSL headers? This ensures the application and library have the same settings. If this does not resolve the issue you are seeing let us know and we can dig deeper.

Warm Regards,

K

P.S. take care to pass by REFERENCE when buffer is going to be updated with new values and those values need to persist beyond scope of the called function. A simple sanity check:

1) Run the app before it is split up, dump out buffer contents and relevant size values
2) Run the app after it is split up, dump out buffer contents and relevant sizes FROM MAIN ONLY.
3) Do the buffers contain the expected information in case 2 and are the relevant length values correct?

Re: ECC signing and verify

Hi Vitus,

The last argument to `wc_EccPublicKeyToDer` is "with_AlgCurve" is a flag for when to include a header that has the Algorithm and Curve information". You should have it set to 1. Also you are not checking the return code from wc_EccPublicKeyDecode in the "verify" function.

You might find the wolfcrypt/test/test.c examples for `crypto_ecc_verify` and `crypto_ecc_sign` helpful. Those are around line 21646.

Thanks,
David Garske, wolfSSL

Share

4 (edited by Vitus 2020-12-02 00:30:40)

Re: ECC signing and verify

Hi,

the code I posted was a sort of  compressed summary. I did not want to overload the forum (and overload the patience of the readers) by attaching a Visual studio project here. Actually I have created a sub project in the wolfssl64.sln project and there I checked all return codes from the wc_xxx() calls,dumped the results, included <wolfssl/options.h> and more, and (hopefully) did the passing by reference correctly. This looked all ok, besides the result of the last wc_ecc_verify_hash(...) . I attach the sub-project folder, could be placed in the \wolfssl-4.5.0\ directory and added to the sln
I only posted my problem here in the forum because maybe there would be an obvious thinking errror in the code which someone in the community can immediately spot and point me to.

I will check the last argument in wc_EccPublicKeyToDer()
I also will look into wolfcrypt/test/test.c, the routine crypto_ecc_verify()

Goal of the project is to evaluate the WolfSSL stack for usage in embedded devices in our company, and the signature is just one first part. I will soon (today) have a meeting with WolfSSL to make contact.

Post's attachments

Woodward_3.zip 9.25 kb, 2 downloads since 2020-12-02 

You don't have the permssions to download the attachments of this post.

Share

Re: ECC signing and verify

@Vitus,

One thing I noted, you are building on windows which does not support <wolfssl/options.h>. <wolfssl/options.h> is for use on *NIX systems where the ./configure script was run and options.h was auto-generated.

On windows please replace all occurrances of <wolfssl/options.h> with:

#include <wolfssl/wolfcrypt/settings.h>
#ifndef WOLFSSL_USER_SETTINGS
    #error "Sanity Check: Please add the PreProcessor setting WOLFSSL_USER_SETTINGS to the project"
#endif

If the above sanity check is seen please right-click on the project in the solution explorer window and open "Properties" ->C/C++ -> "Preprocessor" -> "Preprocessor Definitions" and add "WOLFSSL_USER_SETTINGS" to the project pre-processor settings. (See attached screen shot 1)

If you then get an error about "user_settings.h" not being found go to "Properties" ->C/C++ -> "General" -> "Additional Include Directories" and add a path to "C:\path-to-wolfssl-root\IDE\WIN" where the windows user_settings.h header resides. (See attached screen shot 2)

Warm Regards,

K

Post's attachments

screen shot 1.png
screen shot 1.png 96.65 kb, file has never been downloaded. 

You don't have the permssions to download the attachments of this post.

Re: ECC signing and verify

Can only attach 1 file at a time, here is screen shot 2 mentioned in last post

Post's attachments

screen shot 2.png
screen shot 2.png 99.65 kb, file has never been downloaded. 

You don't have the permssions to download the attachments of this post.

Re: ECC signing and verify

Hi Vitus,

I see your bug. In the sign.c see this line `if ((ret = wc_ecc_sign_hash(hash, sizeof(hash), signature, signature_size, &rng, &key)) != 0)`. You are using `sizeof(hash)` and it should be `hash_size`.

Thanks,
David Garske, wolfSSL

Share

Re: ECC signing and verify

Thanks David, this solved it


(I feel a little ashamed, I should have seen that)

Vitus

Share