Hello,

I can see that the wc_ecc_verify_hash functions takes a non constant ecc_key* instance as last parameter.

I also checked the code and it seems it modifies the key's state.

My question now is this -- is it safe to always use the same ecc instance for multipe wc_ecc_verify_hash calls even they seem to get modified?

If not what's the fastest and most efficient way on embedded to clone the public ecc_key instance to be used one for the wc_ecc_verify_hash call?

thanks
Alex

2

(1 replies, posted in wolfCrypt)

Hello,

We've sadly discovered huge performance issues with wolfSSL trying to get it running on a nRF52840 chip which runs an ARM CORTEX M4.

We are using ECC (ECDH and ECDSA) and compared wolfSSL basic functions for this with the uECC library made for embedded and the results are quite shocking:

-- wolfcrypt ---
wc_sha256: 0 ms
wc_ecc_sign_hash: 606 ms, 71 bytes
wc_sha256: 0 ms
wc_ecc_init: 0 ms
wc_EccPublicKeyDecode: 1 ms
wc_ecc_verify_hash: 1163 ms - valid_signature: 1

-- uECC --
uECC_make_key: 129 ms, private_key_size 32
uECC_sign: 158 ms
uECC_verify: 135 ms - valid signature: 1

Note that both are using the same setup (curve SECP256R1)


These are the user_settings we are using for wolfcrypt/wolfssl:

//
// Wolf stuff
//
#define WOLFCRYPT_ONLY

// Set 32-Bit mode by default
// This must be set to either 32 or 64 bit depending on target here, may NOT be removed
// Same applies for the ULONG definition
#define SP_WORD_SIZE 32
#undef ULLONG_MAX
#define ULLONG_MAX 18446744073709551615ULL

// add some options that are disabled by default
#define SINGLE_THREADED
#define WOLFSSL_STATIC_MEMORY
#define HAVE_ENCRYPT_THEN_MAC
#define HAVE_ECC
#define HAVE_ECC_ENCRYPT
#define ECC_TIMING_RESISTANT
#define TFM_TIMING_RESISTANT
#define HAVE_HKDF
#define DEFAULT_ECC_KEY_CURVE ECC_SECP256R1
#define WOLFSSL_ECIES_ISO18033

// TODO : Check if useful for ARM
// #define WOLFSSL_ARMASM
// /TODO

// TODO : Enable once understood and make sure to build correctly for each arch
// #define USE_FAST_MATH
// /TODO

// remove some options that are enabled by default
#define NO_FILESYSTEM
#define NO_ERROR_STRINGS
#define NO_WOLFSSL_CLIENT
#define NO_WOLFSSL_SERVER
#define NO_DES3
#define NO_DSA
#define NO_MD4
#define NO_MD5
#define NO_SHA
#define NO_PSK
#define NO_PWDBASED
#define NO_RC4
#define NO_SESSION_CACHE
#define NO_TLS
#define NO_RSA
#define WC_NO_RSA_OAEP
#define NO_DEV_URANDOM
#define WOLFSSL_NO_SIGALG
#define NO_RESUME_SUITE_CHECK
#define NO_OLD_TLS
#define WOLFSSL_AEAD_ONLY
#define WOLFSSL_SP_NO_2048
#define WOLFSSL_SP_NO_3072
#define WOLFSSL_SP_NO_256
#define WOLFSSL_NO_TLS12

#define WOLFSSL_CMSIS_RTOSv2
#define WOLFSSL_USER_IO
#define WOLFSSL_SMALL_STACK_CACHE
#define NO_DEV_RANDOM

// #define WOLFSSL_SP_MATH
// #define USE_FAST_MATH
// #define TFM_NO_ASM

#define NO_WOLFSSL_DIR
#define NO_DH
#define NO_SESSION_CACHE
#undef NO_INLINE

#define FP_MAX_BITS (1024 * 2)

/* Random Seed Source */
#define CUSTOM_RAND_GENERATE_SEED blue_arduino_rand_generate_seed


We are now in a bit of trouble because we actually wanted to pick the commercial license for wolf_ssl but we can't explain this issue at all. Can you help by any means? Did we do something fundamentally wrong on the setup?

Please note we couldn't use FAST_MATH because veryfing signatures fails then saying the key length is invalid.

Alex

Obviously its not changeable could someone shed some light on this?

I am curious why we are then even exchanging the peer's public key at all as it seems for decrypt its not required at all only for encrypting?

Alex

So I tried providing a fresh empty new key as public key to the wc_ecc_decrypt function and it still works perfectly well.

I am confused now as all the samples and the doc says it should be the peer's public key but as said it seems to extract another public key from the message itself.

Why is it done this way and how to change it as it also doubles the encrypted message size for me as the whole public key is appended too?

thanks
Alex

Hello,

The documentation of wc_ecc_decrypt states it requires the following parameter:

pubKey    pointer to the ecc_key object containing the public key of the peer with whom one wishes to communicate

I am providing this key however it seems its never used. Looking into the code of wc_ecc_decrypt I can see the public key is actually getting extracted from the message to decrypt itself:

    if (ret == 0) {
        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
    }
    if (ret == 0) {
        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
    }

And within the wc_ecc_encrypt I can see the public key of the provided private key is actually prepended to the encrypted message.

So why are we even providing the peer's public key when its never used? The ecies sample seems also to use the peer's public key but as said according to the wc_ecc_encrypt / wc_ecc_decrypt code its never in use?

thanks for clarifications on this topic,
Alex

6

(1 replies, posted in wolfSSL)

Hello,

We are using wc_ecc_sign_hash and wc_ecc_verify_hash to authenticate parties with each other.

How does the actuall ecc_key`s size affect the security of this process? We're currently using a keysize of 32. Is this too less? Should we use bigger keys?

And what's the most efficient curve algorithm that could be used for the keys to have sign / verify work as fast as possible? We're currently using the default one.

thanks
Alex

Sean

Thank you very much.

So I assume my initial concept should be workable reading your lines:

- Using ECIES with two temporary keys to establish a secure connection which provides also perfect forward secrecy
- Once a secure connection is established with a salt, transfer the certificate from the client
- Verify the certificate from the client server side with a trusted root certificate

However in this scenario, I can authenticate the client but not the server. My intention was to keep the public key of the server in the client and have the server send a a signature to the client based on a random hash the server sends as well and that the client verifies to authenticate the server. However, what I understand if only one key of the secure connection is temporary and the other one is static we'd loose the perfect forward secrecy correct?

I am also curious how could we safely encrypt and read permissions from a user certificate? (Create + Read it with wolfSSL).

thank you very much, thins becoming way clearer now.

Thank you very much.

Btw we're also currently in inquiry to buy commercial licenses so this is very helpful here to solve our issue to implement it properly.

My approach was actually just following the sample code in here:

https://github.com/wolfSSL/wolfssl-exam … ver.c#L113

Where it says one should implement signing (hashing + sign) the generated public key on server side and verify that signature on client side. This is actually what I am doing just vice versa (generating the public key on client side, signing it there with my private key and the server verifying it).

Can you tell me where this is wrong or did I missunderstand the sample?

Furthermore my approach is to have one side using a static key while the other side generates a dynamic key for the session. In the example given both sides generate a dynamic/temporary key for each session. The only difference I understood from reading some documentation is that your approach provides forward secrecy and mine doesn't correct? (Reading about the ECIES they also seem to use one static key?)

However because a secret and a salt is generated for each session even with one side being a static key we still would have  forward secrecy or not?

Or should we simply go the exact route of the sample (both sides generate a temporary key) but why would the signing be required then as the code states?

And then do the authentication later over secure connection ie via a certificate sent by the client?

Sorry for those dumb questions I am trying to wrap my head around this since days and everytime I think I got it I understand I didn't ;-)

Alex

David,

Thank you so much. Last question on this topic promised so I really get this right please forgive me ;-)

We want to authenticate the client on the server. The server holds the public key of the client.

The client generates a new session key via wc_ecc_make_key()
Then it creates a sha256 hash out of this session key and signs it with its client key via wc_ecc_sign_hash()

The server receives both the session key plain text and the signature. It hashes the session key with sha256 and verifies the signature via wc_ecc_verify_hash() and the known client's public key the server has.

Is this a correct approach or does it have any flaws because its not the server sending random which the client signs and returns back but the client signs its own generated session key and sends it?

Thanks so much
Alex

David,

Yes we use different keys, unique per server / client each. We have the public key of the server installed at the client to avoid rundtroup and the client generates its key at connection for each session and lets the server know including the signature to verify authencity.

For certificates -- yes the overhead is quite big. What would be the alternative actually to have something the user could send that we could verify for authencity (without the server knowing about it) and ensuring ie the user can not change things like the expiration and such?

thanks
Alex

David,

Thanks for your reply. We wanted to avoid using TLS due the overhead and thus wanted to go the ECIES way.

Would it be feasible to do authentication via ecc signing the public exchanged keys on both sides? This seems still be be way cheaper than TLS right?

We'd, however, want to send a certificate at the end from the client to the server to verify that the client is allowed to execute certain actions on our server, does this make sense? I understand via wolfSSL we could manually verify the complete chain of certificates to understand whether the incoming certificate is valid or not.

We wanted to make sure to exchange the certificate from client -> server via an already encrypted channel as we don't use it for authentication but for understanding if the user is allowed to do certain actions means we must prevent anyone catching the certificate from the client via a MITM.

hope this all makes sense,
thanks
Alex

We had been looking into the ECC-Based exchange sample for BLE:

https://github.com/wolfSSL/wolfssl-exam … change.pdf

The main questions are that we do not really understand how authentication is actually done in this sample. We understand that the
transfer of data is safely encrypted but with this implementation, everyone could exchange data with each other.

What we'd care about is a safe way to authenticate the client (using PKI and provisioned certifcate on server) so we know for sure the client is
allowed to access.

Furthermore I am confused how would we be able to validate a certificate on client side for expiration? For example the client might use
a certificate that is already expired and the server should understand that and being unable to establish a connection then.

And is it possible for someone if he'd have access to the client certificate but its expired to extend its expirationa and re-use it?

thanks a lot
Ale