Unable to import an RSA keypair with P=Q=0 #189
Labels
No labels
api-spec
bug
CLA requested
CLA valid
compliance
DO NOT MERGE
duplicate
enhancement
feature branch
good first issue
HEADER FORMATTING ISSUE
help wanted
Information
invalid
Jira status: AWAITING REVIEW
Jira status: CLOSED
Jira status: DONE
Jira status: IN PROGRESS
Jira status: IN REVIEW
Jira status: OPEN
Jira status: REOPENED
Jira status: RESOLVED
mirrored
mirror internally
needs: backports
needs: ci
needs: design review
needs: preceding PR
needs: review
needs: work
notabug
open for community contribution
Product Backlog
question
ready for merge
security
stale
type: bug
type: enhancement
type: question
web pages
wontfix
writing
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-ARMmbed/mbed-crypto#189
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Description
Hello everyone,
First of all sorry for all the mistake(s) that you will find in the following part, but english is not my first language.
I'm currenlty trying to do a RSA sign with the function RSA_PKCS1v15_Sign and it seem that i came accross an issue in psa_import_key.
To be more accurate, this issue is in the function pk_parse_key_pkcs1_der. (see at the end for the complete path to this function)
After all imports (in my case i have only the parameters n, d and e), the function call mbedtls_rsa_complete. This function is trying to find p and q. Until here nothing wrong.
And now for the strange part :), in mbedtls_rsa_deduce_primes (the function call by mbedtls_rsa_complete) the first line is a check:
if( P == NULL || Q == NULL || P->p != NULL || Q->p != NULL )
but just before (in pk_parse_key_pkcs1_der), the mbedtls_rsa_import_raw is initialising P->p and Q->p to something not NULL, so i got MBEDTLS_ERR_MPI_BAD_INPUT_DATA everytime.
And here is my issue.
Maybe my code is wrong, i'm pretty confident about it, but i'm open to every sugestions and comments...
path:
RSA_PKCS1v15_Sign
->psa_import_key
->psa_import_key_into_slot
->psa_import_rsa_key
->mbedtls_pk_parse_key
->pk_parse_key_pkcs1_der
->mbedtls_rsa_complete
->mbedtls_rsa_deduce_primes
Have a good day,
Best regards,
userMF
Issue request type
Hi userMF,
What exact version of Mbed Crypto are you using?
Can you please attach a sample key that causes this problem?
Note that
psa_import_keyis not guaranteed to work if the key only contains {n,e,d}. See the description ofpsa_export_keyfor exactly what is required. That being said, it should currently work, becausepsa_import_keycallsmbedtls_pk_parse_keywhich supports several different formats. But we do not guarantee that it will keep working in the future.Internal Jira reference: https://jira.arm.com/browse/IOTCRYPT-837
Hi,
My bad, i forgot to put the sha1:
521dbc67daand according to gitk it is from 2019/04/17 and it should be mbedcrypto-1.0.0.
Here are the keypair that cause my issue:
Modulus (n): size 128 bytes
0xa56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137Private Exponent (d) : size 128 bytes
0x33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325Public Exponent (e):
0x010001, size 3The pcks1 structure pass to
psa_import_key:0x3082012002810100028180a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a213702810301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325028100028100028100028100028100Have a good day,
Best regards,
userMF
Summary
The key is not valid according to PKCS#1, and Mbed Crypto does not recognize this particular extension of the PKCS#1 format. How did you produce this key? We may add this feature for interoperability, but it is not a bug.
Do note, however, that the PSA Cryptography API specification only promises to support one canonical representation, which is the DER encoding of the PKCS#1 format (without optional parts). Right now Mbed Crypto allows many other formats, but we are actually planning to remove this ability (I don't know when) to decrease the code size. So I recommend that you arrange to pass input with P and Q.
Detailed analysis
How did you obtain the pkcs1 structure? It declares a length of
0x0120= 288 bytes, but only 287 bytes follow. If I replace30820120…by3082011f…, the ASN.1 structure is well-formed (it isn't a valid RSAPrivateKey as we'll see below, and it doesn't follow DER, but it's valid ASN.1) and I do observe the failure ofmbedtls_rsa_deduce_primes.The ASN.1 structure declares P and Q as having the value 0 using the encoding
028100. This is not DER, since it has a non-minimal length encoding: DER would be020100. This is not the source of the problem, though: the behavior I describe below is the same with020100.mbedtls_asn1_get_mpiproduces an MPI which has the value 0, but encoded as having one limb. Inmbedtls_rsa_complete,pq_missingis set to true because P and Q are both zero. So it callsmbedtls_rsa_deduce_primes, which complains becausePandQhave a limb (they happen to be zero, but with a non-canonical internal representation).I see two potential issues here:
mbedtls_asn1_get_mpishould produce{s=1, n=0, p=NULL}when the input is zero, rather than allocating one limb to match the number of source digits. However this is not clear-cut to me:mbedtls_asn1_get_mpicould skip leading zeroes, but this may lead to new side channels where the number of leading zeroes is more visible through timing than before.mbedtls_rsa_deduce_primesand the checks inmbedtls_rsa_complete: complete() tests for numerical zero whereas deduce_primes() wants an empty bignum (which is the canonical internal representation for zero). I'd rate that as a low-priority maintenance issue rather than a bug since this should mostly not happen: whenmbedtls_rsa_completehas to complete P and Q, those should be empty (which happens to be interpreted as zero) and not some arbitrary representation of zero.All of this is triggered by
prime1=0andprime2=0in an RSAPrivateKey. But PKCS#1 specifyRSAPrivateKeywith “prime1 is the prime factor p of n” and “prime2 is the prime factor q of n”. It doesn't state that these may be 0 in which case they need to be reconstructed from D.Mbed Crypto already supports calculating P and Q from D (and then always calculates DP, DdQ and U from the others). We could make it recognize that when P=Q=0 when parsing a key, it should treat them as missing. But that would be for added interoperability rather than to comply with PKCS#1.
Hello again,
Well, i got it from a STMicroelectronic example on RSA and in their example, they don't give any P or Q. They only give n, d and e :( .
https://www.st.com/en/embedded-software/x-cube-cryptolib.html
(It is located in Project/STM32_Cryptographic_Examples/RSA/RSA_Signature)
My first goal, was to do a Sign operation with those data and mbed-crypto, but, of what i understand so far, i can't.
Do you know if is it even possible ?
I create it from scratch with the data that i got. And also, by looking in the code to know what i needed to have to use the function. (because i tryied following wikipedia on DER but got bad result with the format)
This explain why the size is not good ...
Have a good day,
Best regards,
userMF
Ok, I see. So Mbed Crypto can work with such a key, but you would need to import it using lower-level APIs:
mbedtls_pk_setupwithMBEDTLS_PK_RSA, then get thembedtls_rsa_contextwithmbedtls_pk_rsa, and callmbedtls_rsa_import(rsa_ctx, N, NULL, NULL, D, E)thenmbedtls_rsa_complete.We currently don't have plans to support this through the
psa_xxxAPI. One way to convert it would be to usembedtls_xxxAPIs as above to import it, thenmbedtls_pk_write_key_derto output a key thatpsa_import_keysupports.:O, so it is possible :)
I'll try,
Thanks a lot.
Have a really good day,
userMF
edit: It works :)
Apologies, this was closed in error by the automated bot - re-opening.