Hi, I’m implementing ecdsa verification with getting R,S rather than ASN.1
In order to do that, my understanding is to use “mbedtls_ecdsa_sign_det()”.
Do i have to only call this function? is this enough?
What is the verification function for this?
Is there any good example?
mbedtls_ecdsa_sign_det() is used for deterministic ecdsa.
If you want the “regular” ecdsa, you should call mbedtls_ecdsa_sign().
As you can see in the code, the function mbedtls_ecdsa_write_signature() calls mbedtls_ecdsa_sign() to sign the hash, and then encodes the signature to asn.1 via ecdsa_signature_to_asn1().
The opposite function, mbedtls_ecdsa_read_signature() gets the data from the asn.1 encoding, and then calls mbedtls_ecdsa_verify().
So, if you don’t use the asn.a encoding, you should call mbedtls_ecdsa_verify to verify the signature.
Although our sample applications use the asn.1 encoded signature, our test suites also test the signature without asn.1 encoding.
Regards,
Mbed TLS Support
Ron
Thank you for your kind explanation.
I have one more question. Now, I’d like to make a digest through using SHA256 and then verify this.
It seems that I have to pass the hash data to mbedtls_ecdsa_verify() manually. Do I understand correctly?
Can I get some example code for this?
I feel my questions is not well organized.
Previously, I completed the ecdsa verification without hash based on your advice.
From now on, I hope to add the hash such as SHA256.
Normally, verification code support hash algorithm as a argument like following.
→ mbedtls_ecdsa_sign_det( &grp, &r, &s, &d, hash, hlen, md_alg )
But, mbedtls_ecdsa_verify doesn’t support hash algorithm as an argument.
So, do I have to make digest before calling mbedtls_ecdsa_verify()?
What is the best and simple way for verification with using R,S and Hash?
Hi @matthewc
Asymetric authentication does the verification process on the message hash. Mbed TLS API suggests the hash to be the input. ( You can sign the full message, however sometimes it may take long time, if the message is long).
First off, I appreciate your help.
It’s very clear to me. Before calling mbedtls_ecdsa_verify(), I better to make digest with hash like md_alg in mbedtls_ecdsa_sign_det() .
Can you show the example code for SHA384 or SHA512? It seems that the code for SHA512 can be used for SHA384. I hope to know how to initialize and get the digest from SHA384 API.
Hi @matthewc
SHA384 is basically truncated SHA512 ( with different initial state)
the API is same, except that in SHA 384, you need to set 1 as the is384 parameter in mbedtls_sha512_starts_ret(), or mbedtls_sha512_ret() if you want to do a one call Hash calculations in the full input.
Note that the Hash size of SHA384 is 384 bits( 48 bytes) and not 512 bits (64 bytes), so you will need to take the first 48 bytes of your 64 bytes output.
Regards
I appreciate your help. It’s very clear to me. I have more questions.
Now, I have DER public key and raw r and s bit value.
As you recommendation, I can use mbedtls_ecdsa_verify() for r and s bit value.
In this case, Do I have to extract public key from DER format?
Which function do I have to use it to get the public key and send it as Q value?
For these, can I also use below function?
mbedtls_pk_verify_ext(MBEDTLS_PK_ECDSA,…)
From the ECDSA point of view, I’m wondering what is difference between mbedtls_pk_verify_ext and mbedtls_ecdsa_verify.
Hi @matthewc
In order to convert the DER public key format, to mbedtls_pk_context, you will need to call mbedtls_pk_parse_public_key().
The PK module is a wrapper for the public key cryptography, and you may consider using mbedtls_pk_verify_ext(), however internally it calls mbedtls_ecdsa_read_signature() which is not what you want, AFAIK.
However, once you parsed the key to mbedtls_pk_context, you can call mbedtls_pk_ec() on this context, to get the mbedtls_ecp_keypair, and extract r,s, and group from this structure.
Regards.
This is not ideal, as it accesses the internals of a structure, and as such not future compatible.
Regards
mbedtls_pk_verify_ext() cannot be used with binary R,S.
mbedtls_pk_ec() can be called. It’s not recommended.
mbedtls_pk_parse_public_key(), mbedtls_ecdsa_veryfy() seems to be recommended.
mbedtls_pk_parse_public_key() produce mbedtls_pk_context.
mbedtls_ecdsa_veryfy() requires mbedtls_ecp_point Q as an argument.
How to translate mbedtls_pk_context to mbedtls_ecp_point?
How to translate mbedtls_pk_context to mbedtls_ecp_point?
Calling mbedtls_pk_ec() on the pk context will retreive you the mbedtls_ecp_keypair structure.
You can access the mbedtls_ecp_point member of this struct, however there isn’t an API that retrieves this point to your convenience. In case there will be an ABI breakage of the structure in the future, it might not work.
Regards
I hope you’re doing well. Your last explanation was very helpful for me. I appreciate it.
I have one more question.
I made binary format signature(r,s) with using python script and loaded this to the array.
And then I hope to store this array to mbedtls_mpi r, s.
This is the purpose of sending these r,s as an argument of mbedtls_ecdsa_verify().
What I want to do is to import raw r, s data to mbedtls_mpi r, s value.
How to store this array to this structure? Can you show me some example?
For example, you can look at this example, how a binary signature is translated into r and s.
You should take into consideration the endianess of your buffer.
Regards
Thanks again. It is also very helpful. I have one more question. It would be the last question I think.
I’m using some function in memory_buffer_alloc.c which got many exit(). I’m not using std library.
Thus, It’s causing undefined reference to ‘exit’ in function ‘buffer_calloc_free’ and 'buffer_alloc_free.
I simply redefine “#define mbedtls_exit return”. It seems to work well.
Is there any good solution you have? If so, I hope to get some advice.
Hi @matthewc
May I know why you are using the memory_buffer_alloc.c feature?
Is it only to replace the calloc and free functions or is it because you would like to use static memory?
If it is only to replace the calloc and free, I would suggest you use your platfomr’s implementation of calloc and free, as the alternatives. As mentioned in this article and this post.
If it is a matter of reducing heap memory usage, note that the feature is not a full Memory Management Unit implementation, and was used only for the Mbed TLS needs. Perhaps you could consider modifying the platform’s linker file in this case, to modify the heap memory on the expence of the static memory ( to keep same RAM usage.)
Regards
I would like to replace the calloc and free function.
My platform’s calloc and free have got some problem, so, it’s not useful.
That’s why I’m trying to use memory_buffer_alloc.c feature.
Could this not be a solution that “#define mbedtls_exit return” is redefined.
Otherwise, what am I supposed for exit function?
Hi @matthewc
Yes, if your platform doesn’t have and exit function, and you need it, you can define mbedtls_exit as you see fit
Note that return and exit do not have same functionality, as exit aborts the application, while return simply returns to the caller. You should be careful what s the value that you return to the caller.
From a brief look, the mbedtls_calloc function may have a fatal error, so, instead of aborting the application with status 1, you return to the caller the value 1. Since this is not NULL the application will then use address 1 as a valid pointer, and will cause undefined behavior in your system.
So, replacing mbedtls_exit to simply be return will not work in cases where you have fatal errors.
If you have an abort function or an assertions, I would use these, and see how to port the (1) value to its implementation.
Regards
As you can see, Q, r, s comes from outside. This code only needs to verify signature.
I didn’t call the “mbedtls_ecp_gen_keypair() and mbedtls_ecdsa_sign()”
In this case, I’m assuming I don’t need to free memory like below.
The reason is that above code doesn’t allocate memory for grp, Q, r, s.
Is this correct?
Well, you should call them. When you read into mbedtls_mpi you allocate enough memory to fit the buffer.
In addition, all the data that was initiated in the xxx_init functions should be freed.
Regards
My issue is that “mbedtls_ecp_point_free(&Q)” shows error which is “FATAL: mbedtls_free() outside of managed space”. The others doesn’t make any errors.
This is my opinion. In case of Q, keyparser_der_import() is called before “mbedtls_memory_buffer_alloc_init()” is called. Memory for Q seems to be allocated by standard library rather than “buffer_alloc_calloc()”. At this point, there is no memory to free by “mbedtls_ecp_point_free(&Q)”. That’s why it makes above error.
What do you think about it?