-
Notifications
You must be signed in to change notification settings - Fork 896
Description
Contact Details
No response
Version
latest master
Description
Note this issues has been edited since first created. Additional details and examples of fp_cmp
problems have been added.
This issue is directly related, and very likely part of the root cause of #6205 and #6286.
The fp_add
problem is addressed in #6382. Issue with fp_cmp
TBD.
These problems have been manifested by plugging in alternative hardware acceleration algorithms into the wolfcrypt/tfm library. See blog about math libraries.
fp_cmp problem
One of the first interesting things is the TFM fp_cmp() only compares the number of used
words in when calling fp_cmp_mag().
After numerous tests of HW acceleration vs software calculations claimed the properly matching results, imagine my surprise when I added this code and the breakpoint was actually hit:
Yes, in this case the fp_cmp()
claimed the values were equal, yet memcmp
detected a difference.
The cause of the difference was the presence of non-zero bytes in positions beyond the used
length. For example:
In theory, if everything actually honored the used
length, we'd have no problem. It makes sense to only look at the bytes actually being used, those less than the used
value.
Note that #6382 does not address the fundamental problem with fp_cmp()
, or more specifically the incorrect assumption that if (a->used) > (b->used) that the result must be FP_GT
or that if (a->used) < (b->used) that the result must be FP_LT
.
Take for example:
In the case shown above, both memcmp
and fp_cmp
fail for the same reason: the used
values for Y
and Y2
are different. Yet the actual fp_int
value is the same: a value of 1. I have a different Espressif HW solution that trims any trailing zeros and adjusts the z.used
size.
Any thoughts on if the fp_cmp
should be modified? Or perhaps have just some notes and possibly optional debug code that gives a warning?
Note that I asked the OpenAI ChatGPT this question:
And received this answer:
After reviewing those issues, I asked again:
This time there was a more interesting answer (yes, for some time, I thought the 1
was a hardware calc error).
So yes: over the course of calculating Z = X^Y mod M
sometimes the answer is indeed just one, even when not obviously expected.
fp_add problem
Although at first glance, it looks like s_fp_add() honors the fp_int
used length, it does not. It currently just grabs the longest length of the two operands and assumes all values beyond a possible shorter length in the other operand are zeros. If the values are not zero, an incorrect result is returned.
Here's where the problem occurred during with the hardware-accelerated call to mp_exptmod
for Y = (G ^ X) mod P
:
In this case the interesting value (non-zero words beyond used
length) is in &tmpb
which is later used in an addition with mp_add()
.
mp_add()
returns an incorrect result. The rest of the entire operation is now corrupted.
Yes, there's probably yet another lesson in variable initialization here. ;)
The wolfcrypt tests do not currently test or detect this issue.
I have a fix for this. PR coming soon. Update: see #6382
Reproduction steps
I have a key generating example. Included in the output is a certificate request:
-----BEGIN CERTIFICATE REQUEST-----
MIIBOTCB5AIBADB/MQswCQYDVQQGEwJOWjEQMA4GA1UECAwHV2Fpa2F0bzERMA8G
A1UEBwwISGFtaWx0b24xIDAeBgNVBAoMF0JsdWUgTGVhZiBTb2Z0d2FyZSwgTHRk
MSkwJwYDVQQDDCBMdW1vcyBIVywgc2VyaWFsTnVtYmVyID0gQkxTLTAwMjBcMA0G
CSqGSIb3DQEBAQUAA0sAMEgCQQC9kBMfwxAIy1Fu2bTN+rHH0EXCRfhX8Y7RDF7D
dekeMwGGhA5KVckoy39fVleXMpmclGSBzcIbYVetnQdSADcFAgMBAAGgADANBgkq
hkiG9w0BAQsFAANBAExzucmR1vn5ts7Pcto+3pVXpJ2GJzYMmPtvy8lRScjDw1Iq
uDM5eSs5vSaqW/nzOfKC/vp3rR00buulvO0Uw74=
-----END CERTIFICATE REQUEST-----
Although the certificate was apparently generated successfully, some of the math operations were incorrect and undetected.
I have this script that attempts to sign the request:
$ cat ./inspect_test.sh
#!/bin/bash
openssl asn1parse -in "./output/test_request.crt" | tee test_request.asn.txt
openssl x509 -req -outform der -in "./output/test_request.crt" -out "./output/test_request.der"
openssl x509 -req -in "./output/test_request.crt" -days 10 \
-CA "private/CertificateAuthority-4096-PublicKey.crt" \
-CAkey "private/CertificateAuthority-4096-PrivateKey.pem" \
-passin pass:secret -CAcreateserial \
-extfile "private/CertificateExtensions.txt" \
-extensions LumosDevice \
-out "./output/test-Device-Certificate_hw.crt" -text
openssl x509 -req -outform der -in "./output/test_request.crt" -out "./output/test_request.der"
Relevant log output
For the example shown, OpenSSL fails to sign the certificate:
$ ./inspect_test.sh
0:d=0 hl=4 l= 313 cons: SEQUENCE
4:d=1 hl=3 l= 228 cons: SEQUENCE
7:d=2 hl=2 l= 1 prim: INTEGER :00
10:d=2 hl=2 l= 127 cons: SEQUENCE
12:d=3 hl=2 l= 11 cons: SET
14:d=4 hl=2 l= 9 cons: SEQUENCE
16:d=5 hl=2 l= 3 prim: OBJECT :countryName
21:d=5 hl=2 l= 2 prim: PRINTABLESTRING :NZ
25:d=3 hl=2 l= 16 cons: SET
27:d=4 hl=2 l= 14 cons: SEQUENCE
29:d=5 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
34:d=5 hl=2 l= 7 prim: UTF8STRING :Waikato
43:d=3 hl=2 l= 17 cons: SET
45:d=4 hl=2 l= 15 cons: SEQUENCE
47:d=5 hl=2 l= 3 prim: OBJECT :localityName
52:d=5 hl=2 l= 8 prim: UTF8STRING :Hamilton
62:d=3 hl=2 l= 32 cons: SET
64:d=4 hl=2 l= 30 cons: SEQUENCE
66:d=5 hl=2 l= 3 prim: OBJECT :organizationName
71:d=5 hl=2 l= 23 prim: UTF8STRING :Blue Leaf Software, Ltd
96:d=3 hl=2 l= 41 cons: SET
98:d=4 hl=2 l= 39 cons: SEQUENCE
100:d=5 hl=2 l= 3 prim: OBJECT :commonName
105:d=5 hl=2 l= 32 prim: UTF8STRING :Lumos HW, serialNumber = BLS-002
139:d=2 hl=2 l= 92 cons: SEQUENCE
141:d=3 hl=2 l= 13 cons: SEQUENCE
143:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption
154:d=4 hl=2 l= 0 prim: NULL
156:d=3 hl=2 l= 75 prim: BIT STRING
233:d=2 hl=2 l= 0 cons: cont [ 0 ]
235:d=1 hl=2 l= 13 cons: SEQUENCE
237:d=2 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption
248:d=2 hl=2 l= 0 prim: NULL
250:d=1 hl=2 l= 65 prim: BIT STRING
Certificate request self-signature did not match the contents
400732DABD7F0000:error:0200008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding:crypto/rsa/rsa_pk1.c:79:
400732DABD7F0000:error:02000072:rsa routines:rsa_ossl_public_decrypt:padding check failed:crypto/rsa/rsa_ossl.c:732:
400732DABD7F0000:error:1C880004:Provider routines:rsa_verify:RSA lib:providers/implementations/signature/rsa_sig.c:785:
400732DABD7F0000:error:06880006:asn1 encoding routines:ASN1_item_verify_ctx:EVP lib:crypto/asn1/a_verify.c:215:
Certificate request self-signature did not match the contents
4007767DC17F0000:error:0200008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding:crypto/rsa/rsa_pk1.c:79:
4007767DC17F0000:error:02000072:rsa routines:rsa_ossl_public_decrypt:padding check failed:crypto/rsa/rsa_ossl.c:732:
4007767DC17F0000:error:1C880004:Provider routines:rsa_verify:RSA lib:providers/implementations/signature/rsa_sig.c:785:
4007767DC17F0000:error:06880006:asn1 encoding routines:ASN1_item_verify_ctx:EVP lib:crypto/asn1/a_verify.c:215:
Certificate request self-signature did not match the contents
4007CA12D47F0000:error:0200008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding:crypto/rsa/rsa_pk1.c:79:
4007CA12D47F0000:error:02000072:rsa routines:rsa_ossl_public_decrypt:padding check failed:crypto/rsa/rsa_ossl.c:732:
4007CA12D47F0000:error:1C880004:Provider routines:rsa_verify:RSA lib:providers/implementations/signature/rsa_sig.c:785:
4007CA12D47F0000:error:06880006:asn1 encoding routines:ASN1_item_verify_ctx:EVP lib:crypto/asn1/a_verify.c:215:
gojimmypi:/mnt/c/workspace/wolfssl-gojimmypi/IDE/Espressif/ESP-IDF5/examples/wolfssl_server_6205_new