Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aventra MyEID cards fail to sign data with more than 51 bytes #2173

Closed
CendioOssman opened this issue Dec 4, 2020 · 47 comments
Closed

Aventra MyEID cards fail to sign data with more than 51 bytes #2173

CendioOssman opened this issue Dec 4, 2020 · 47 comments

Comments

@CendioOssman
Copy link
Contributor

Problem Description

Aventra MyEID cards fail to sign data with more than 51 bytes when the key size is 1024 bits. The card reports 0x6700/"Wrong Length" at this point.

Discovered when trying to use SHA512 as the hash algorithm.

Tested with MyEID 3.3.3, 4.0.0 and 4.5.5.

opensc-0.20.0-6.fc32.x86_64

This limit seems to scale with the key size. For 2048 bit keys the limit is 102 bytes, and for 4096 bit keys the limit is 204 bytes.

Proposed Resolution

No idea.

Steps to reproduce

  1. Generate PKCS#15 structure with a 1024 bit RSA key.
  2. Run echo -n 0123456789012345678901234567890123456789012345678901 | pkcs11-tool --login --pin <PIN> --mechanism RSA-PKCS --sign

Logs

Relevant snippet:

P:19526; T:0x140446610601792 17:12:59.871 [opensc-pkcs11] sec.c:59:sc_compute_signature: called
P:19526; T:0x140446610601792 17:12:59.871 [opensc-pkcs11] card-myeid.c:1087:myeid_compute_signature: called
P:19526; T:0x140446610601792 17:12:59.871 [opensc-pkcs11] card-myeid.c:1090:myeid_compute_signature: key type 0, key length 0
P:19526; T:0x140446610601792 17:12:59.871 [opensc-pkcs11] apdu.c:546:sc_transmit_apdu: called
P:19526; T:0x140446610601792 17:12:59.871 [opensc-pkcs11] card.c:473:sc_lock: called
P:19526; T:0x140446610601792 17:12:59.871 [opensc-pkcs11] card.c:513:sc_lock: returning with: 0 (Success)
P:19526; T:0x140446610601792 17:12:59.871 [opensc-pkcs11] apdu.c:513:sc_transmit: called
P:19526; T:0x140446610601792 17:12:59.871 [opensc-pkcs11] apdu.c:363:sc_single_transmit: called
P:19526; T:0x140446610601792 17:12:59.871 [opensc-pkcs11] apdu.c:367:sc_single_transmit: CLA:0, INS:2A, P1:9E, P2:9A, data(52) 0x7ffd3d5a5a60
P:19526; T:0x140446610601792 17:12:59.871 [opensc-pkcs11] reader-pcsc.c:297:pcsc_transmit: reader 'SCM Microsystems Inc. SCR 3311 [CCID Interface] (21120608441518) 00 00'
P:19526; T:0x140446610601792 17:12:59.871 [opensc-pkcs11] reader-pcsc.c:298:pcsc_transmit: 
Outgoing APDU (58 bytes):
00 2A 9E 9A 34 30 31 32 33 34 35 36 37 38 39 30 .*..401234567890
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 1234567890123456
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 7890123456789012
33 34 35 36 37 38 39 30 31 00                   345678901.
P:19526; T:0x140446610601792 17:12:59.871 [opensc-pkcs11] reader-pcsc.c:216:pcsc_internal_transmit: called
P:19526; T:0x140446610601792 17:12:59.896 [opensc-pkcs11] reader-pcsc.c:307:pcsc_transmit: 
Incoming APDU (2 bytes):
67 00 g.
P:19526; T:0x140446610601792 17:12:59.896 [opensc-pkcs11] apdu.c:382:sc_single_transmit: returning with: 0 (Success)
P:19526; T:0x140446610601792 17:12:59.896 [opensc-pkcs11] apdu.c:535:sc_transmit: returning with: 0 (Success)
P:19526; T:0x140446610601792 17:12:59.896 [opensc-pkcs11] card.c:523:sc_unlock: called
P:19526; T:0x140446610601792 17:12:59.896 [opensc-pkcs11] iso7816.c:128:iso7816_check_sw: Wrong length
P:19526; T:0x140446610601792 17:12:59.896 [opensc-pkcs11] card-myeid.c:1126:myeid_compute_signature: compute_signature failed: -1206 (Wrong length)

Complete log can be arranged if desired.

@popovec
Copy link
Member

popovec commented Dec 4, 2020

I can reproduce this on MyEID 4.0.1.

Just for completeness, MSE APDU:

00 22 41 B6 0A 80 01 02 81 02 4B 01 84 01 00 

TAG 80, value 02 corresponds to "no hash mechanism, only pad data to key modulus"

From MyEID documentation (2.3.0, page 31):

- DigestInfo is padded to RSA key modulus length according to
  PKCS#1 v1.5, block type 01h. Size of the DigestInfo must
  not exceed 40% of the RSA key modulus length.

This corresponds to about 51 bytes for 1024 RSA key..

There is way to run RAW RSA operation .. but data len must match key modulus.

I can't comment on how exactly pkcs11-tool --mechanism RSA-PKCS should work.

@dengert
Copy link
Member

dengert commented Dec 4, 2020

Using an RSA 1024 bit key is not considered secure these days. When it was considered secure, these was no SHA-512.
SHA-512 is normally used with 4096 bit keys. Depending on how old you card is, it may not larger keys, and some cards will check the digest to see if it is valid. Some cards will allow RSA_RAW, and the hashing is done in software.

See:
https://webservices.aventra.fi/wordpress/wp-content/downloads/MyEID_PKI_JavaCard_Applet_Reference_Manual_2-1-4.pdf
Not the same as @popovec sent, but does talk about SHA-512 and RSA 4096 and EC.

This shows the APDUs and card capabilities. The APDU in the trace is 00 2A 9E 9A from Section 4.13. The important APDU would be 00 22 XX YY from section 4.12. With the data from Tables 48 and 49.

This would be the APDU before the the one you sent above.

@CendioOssman
Copy link
Contributor Author

I agree that 1024 bits is hardly recommended these days, but unfortunately users are still using it. That's how we initially got this bug report.

Hashing is already done in software with RSA-PKCS and that's how we ended up with the odd combination of 512 bit SHA and 1024 bit RSA.

Still, those two should work together if not for MyEID's odd restriction of 40% of the key size. And since we've seen this in the wild some handling in OpenSC would be better. Or at least a check and better error message.

@popovec
Copy link
Member

popovec commented Dec 4, 2020

There is way to use RSA-X-509 mechanism, but message must be constructed in software, by concatenating parts:

  • PKCS#1 v1.5 padding 0x00, 0x01, 0xff, 0xff ... 0xff, 0x00
  • SHA512 prefix 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
  • SHA512 digest from your message

1st part size is to be calculated from modulus size.

BTW 40% payload size is used to prevent padding oracle attack....

@dengert
Copy link
Member

dengert commented Dec 4, 2020

Based on @popovec APDU of 00 22 41 B6 0A 80 01 02 81 02 4B 01 84 01 00

SHA-512 is not involved at all.
It is doing no hash and PKCS#1 v1.5

And your test pkcs11-test is doing the same.
So it looks like the 40% is a feature of the card.

Best I can tell, the driver does check for the 40% limitation. And it could not do this until runtime after the key is selected.
But the user would have selected the key and the hash.

And error message would have to fit within PKCS11 CKR_* values. And other cards might start doing the same.

There is a why in PKCS11 to limit mechanisms to individual keys. "CKA_ALLOWED_MECHANISMS -
CK_MECHANISM_TYPE _PTR, pointer to a CK_MECHANISM_TYPE array -
A list of mechanisms allowed to be used with this key. The number of mechanisms in the array is the ulValueLen component of the attribute divided by the size of CK_MECHANISM_TYPE."

But it looks like OpenSC does not support this at the PKCS11 layer, or driver layer. /pkcs11-tool.c has 4 references to it.

When you say "we" do you mean https://www.cendio.com/ ?

Pull requests are always welcome.

@dengert
Copy link
Member

dengert commented Dec 4, 2020

Correction : Best I can tell, the driver does NOT check for the 40% limitation

@popovec
Copy link
Member

popovec commented Dec 4, 2020

So it looks like the 40% is a feature of the card.

Yes, this is checked by card..... for example same driver (myeid) with OsEID card is able to sign modulus - 11 bytes in this mode.

@dengert
Copy link
Member

dengert commented Dec 4, 2020

You said: "Discovered when trying to use SHA512 as the hash algorithm."

So does this only happen when the user specifies a specific hash?
Or doe it default to this?

@popovec
Copy link
Member

popovec commented Dec 5, 2020

Supported RSA padding/hashes (from card-myeid.c):

SC_ALGORITHM_RSA_RAW
SC_ALGORITHM_RSA_PAD_PKCS1
SC_ALGORITHM_RSA_HASH_NONE
SC_ALGORITHM_RSA_HASH_SHA1

This is indicated by pkcs11-tool -M:

  RSA-X-509, keySize={512,2048}, hw, decrypt, sign, verify, wrap, unwrap
  RSA-PKCS, keySize={512,2048}, hw, decrypt, sign, verify, wrap, unwrap
  SHA1-RSA-PKCS, keySize={512,2048}, sign, verify
  RSA-PKCS-PSS, keySize={512,2048}, hw, sign, verify, wrap, unwrap
  SHA1-RSA-PKCS-PSS, keySize={512,2048}, sign, verify

What card really can do before real RSA operation is done:

  1. add PKCS#1 v1.5 padding (block 1 - sign)
  2. if input is SHA1 hash (20 bytes), card internally add SHA1 prefix and then add PKCS#1 v1.5 block 1 padding

SHA1 is never computed in card. (BTW, I am missing "hw" flag in lines reported by pkcs11-tool if there is SHA1 operation - is this because SHA1 is computed outside card ?, If this is the case, why there is "hw" in RSA-PKCS-PSS ? there is no PSS support internally in card.. )

There is a way to add support SHA256-RSA-PKCS and other hashes into card-myeid.c. Driver only need to signalize support for this hash. If sign with this hash is requested, driver insert internally SHA256 prefix and request the card to do PKCS#1 padding before RSA sign operation. Of course, for small key and SHA512 this fail, because limit of 40% payload .. in this case driver must add PKCS#1 padding and request the card to do RAW RSA operation. IMHO, it is better to accept 40% limit and not force this operation...

@popovec
Copy link
Member

popovec commented Dec 5, 2020

Here draft for SHA256-RSA-PKCS support in MyEID driver:

diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c
index 677e068f..4b071085 100644
--- a/src/libopensc/card-myeid.c
+++ b/src/libopensc/card-myeid.c
@@ -62,6 +62,10 @@
 
 #define MYEID_MAX_EXT_APDU_BUFFER_SIZE (MYEID_MAX_RSA_KEY_LEN/8+16)
 
+static const uint8_t SHA_256_PKCS_PREFIX[] = {
+  0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 };
+
 static const char *myeid_card_name = "MyEID";
 static const char *oseid_card_name = "OsEID";
 static char card_name_buf[MYEID_CARD_NAME_MAX_LEN];
@@ -225,7 +229,7 @@ static int myeid_init(struct sc_card *card)
        }
 
        flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_ONBOARD_KEY_GEN;
-       flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1;
+       flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_HASH_SHA256;
 
        _sc_card_add_rsa_alg(card,  512, flags, 0);
        _sc_card_add_rsa_alg(card,  768, flags, 0);
@@ -1098,6 +1102,13 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen,
        priv = (myeid_private_data_t*) card->drv_data;
        sc_log(ctx, "key type %i, key length %i", priv->sec_env->algorithm, priv->sec_env->algorithm_ref);
 
+        if (priv->sec_env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) {
+               sc_log(ctx, "SHA256 hash required, inserting SHA256 prefix");
+               pad_chars = sizeof(SHA_256_PKCS_PREFIX);
+               memcpy (sbuf, SHA_256_PKCS_PREFIX, pad_chars);
+        }
+
        if (priv->sec_env->algorithm == SC_ALGORITHM_EC ) {
 
            field_length = priv->sec_env->algorithm_ref;

Now pkcs11-tool -M inform us about SHA256-RSA-PKCS:

  RSA-X-509, keySize={512,2048}, hw, decrypt, sign, verify, wrap, unwrap
  RSA-PKCS, keySize={512,2048}, hw, decrypt, sign, verify, wrap, unwrap
  SHA1-RSA-PKCS, keySize={512,2048}, sign, verify
  SHA256-RSA-PKCS, keySize={512,2048}, sign, verify
  RSA-PKCS-PSS, keySize={512,2048}, hw, sign, verify, wrap, unwrap
  SHA1-RSA-PKCS-PSS, keySize={512,2048}, sign, verify
  SHA256-RSA-PKCS-PSS, keySize={512,2048}, sign, verify

Now I can use pkcs11-tool --sign -m SHA256-RSA-PKCS ... and verify this signature by openssl dgst -sha256 -verify ...

This patch is draft, but if this is acceptable method to extend MyEID functionality, I create PR with more error checking and support for more hashes.

@hhonkanen What is your opinion?

@dengert
Copy link
Member

dengert commented Dec 5, 2020

Your patch looks like a nice addition.

The PKCS11 "hw" bit means the mechanism is done in hardware. But there is no clear way to map this to what some cards can or can not do in hardware. Some can actually do the hash or the last round of the hash if presented with all the data to be hashed. From what you have said, the MyEID card will expects either a SHA1 or SHA256 to be done in software and the card will add the digest and do the PKCS1.5 padding on the card.

Your card appears to only support key up to 2048. myeid_get_card_caps uses a 00 CA 01 AA GET DATA APDU to read the max key sizes from the card "Table 11 - – MyEID card capabilities" The code tests for cards that can do 3072 and 4096.

I have a MYEID Aventra card from 2017. opensc-tool -s "00:CA:01:AA:00" returns01 00 7F 08 00 00 C0 01 00 02 09 Which says max RSA only supports 2048 bit keys. (And PIV which is why I was interested in it. )

Table 49 - Values for Algorithm Reference lists RFU (RIPEMD-160), RFU (SHA-224), RFU (SHA-256), RFU (SHA-384) and RFU (SHA-512). But "RFU" is reserve for future use, and I don't see how to tell if the card understands these.

One could assume if card supports RSA 3072, then it supports SHA384, and if it supports RSA 4096 it supports SHA512. So your mod could be extended to support SHA384-RSA-PKCS and SHA512-RSA-PKCS.

Someone with a newer card, and documentation could say if the assumption is correct and worth adding code for it.

Going back to the original question, Your mod with SHA384-RSA-PKCS and SHA512-RSA-PKCS could help address the misuse, by indicating which of the hash/key sizes are supported by the card. But the 40% of key size with RSA_RAW will still be enforced by the card. I don't see any easy fix for this.

@popovec
Copy link
Member

popovec commented Dec 5, 2020

40% is limit is forced by card, only if card is requested to do PKCS#1 v1.5 padding. If I have 1024 bit RSA key, then RAW RSA operation is running for 128 bytes (64 bytes SHA512, 19 bytes SHA512 prefix, 45 bytes padding) , .. but PKCS#1 padding and SHA512 prefix handling must be done in driver - and this is no problem, only sec env must be changed before PSO. However, I would not yet implement this procedure (this can even decrease the security of the 1024 bit key if SHA512 is used only with 45 bytes of padding).

IMHO any assumption (related to MyEID card) about SHA512 SHA384 etc. is irrelevant .. we doing HASH inside opensc, not inside card, card is requested only for padding and prefix handling. Because this can be done in driver, we can ignore the RFU algo references in Aventra doc.

For example (used patch above, MyEID 4.0.1, max 2048 bit key), SHA256-RSA-PKCS-PSS and SHA256-RSA-PKCS is not working for 512 and 768 bit RSA KEY - but that, of course, was to be expected - and this is not problem, using RSA keys below 1024 bit is really deprecated and unsecure.

From what you have said, the MyEID card will expects either a SHA1 or SHA256 to be done in software and the card will add the digest and do the PKCS1.5 padding on the card.

Yes, I deduced this from MyEID doc and card-myeid.c - I analyzed it when I wrote the OsEID implementation.

@popovec
Copy link
Member

popovec commented Dec 5, 2020

The patch above is only partial workaround.. it doesn't solve another important thing.

  1. If SC_ALGORITHM_RSA_HASH_SHA256 is not set in card driver, I am unable to call pkcs11-too1 with -m SHA256-RSA-PKCS (error: PKCS11 function C_SignInit failed: rv = CKR_MECHANISM_INVALID (0x70)
  2. If SC_ALGORITHM_RSA_HASH_SHA256 is set, I am unable to verify the signature (because missing digest info ..)

There is already support for adding digest info prefix in opensc code: src/libopensc/padding.c, function sc_pkcs1_encode(). For example card-starcos.c uses them. But why this is not done globally for all cards (or at least for cards that have support for RSA RAW)? Any card with RAW RSA support can run SHA256-RSA-PKCS or SHA512-RSA-PKCS etc ..

The same goes for padding - if SC_ALGORITHM_RSA_RAW is set, there is no problem to run PKCS1 or PSS or OAEP padding..

But after reading the comment in src/pkcs11/framework-pkcs15.c

   5726         /* all our software hashes are in OpenSSL */
   5727         /* Only if card did not list the hashes, will we
   5728          * help it a little, by adding all the OpenSSL hashes
   5729          * that have PKCS#11 mechanisms.
   5730          */
   5731         if (!(rsa_flags & (SC_ALGORITHM_RSA_HASHES & ~SC_ALGORITHM_RSA_HASH_NONE))) {
   5732                 rsa_flags |= SC_ALGORITHM_RSA_HASHES;
   5733         }

I made a new patch

diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c
index 677e068f..d811b6a6 100644
--- a/src/libopensc/card-myeid.c
+++ b/src/libopensc/card-myeid.c
@@ -225,7 +225,7 @@ static int myeid_init(struct sc_card *card)
        }
 
        flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_ONBOARD_KEY_GEN;
-       flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1;
+//     flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1;
 
        _sc_card_add_rsa_alg(card,  512, flags, 0);
        _sc_card_add_rsa_alg(card,  768, flags, 0);

and now if I run pkcs11-tool -M :

  RSA-X-509, keySize={512,2048}, hw, decrypt, sign, verify, wrap, unwrap
  RSA-PKCS, keySize={512,2048}, hw, decrypt, sign, verify, wrap, unwrap
  SHA1-RSA-PKCS, keySize={512,2048}, sign, verify
  SHA224-RSA-PKCS, keySize={512,2048}, sign, verify
  SHA256-RSA-PKCS, keySize={512,2048}, sign, verify
  SHA384-RSA-PKCS, keySize={512,2048}, sign, verify
  SHA512-RSA-PKCS, keySize={512,2048}, sign, verify
  MD5-RSA-PKCS, keySize={512,2048}, sign, verify
  RIPEMD160-RSA-PKCS, keySize={512,2048}, sign, verify
  RSA-PKCS-PSS, keySize={512,2048}, hw, sign, verify, wrap, unwrap
  SHA1-RSA-PKCS-PSS, keySize={512,2048}, sign, verify
  SHA224-RSA-PKCS-PSS, keySize={512,2048}, sign, verify
  SHA256-RSA-PKCS-PSS, keySize={512,2048}, sign, verify
  SHA384-RSA-PKCS-PSS, keySize={512,2048}, sign, verify
  SHA512-RSA-PKCS-PSS, keySize={512,2048}, sign, verify

Tested by pkcs11-tool - SHA1-RSA-PKCS, SHA256-RSA-PKCS, SHA1-RSA-PKCS-PSS, SHA256-RSA-PKCS-PSS - all OK but RAW signature is not working (tested by pkcs15-crypt,I'll look into it later)

OpenSC interprets SC_ALGORITHM_RSA_HASHES in a strange way. Hashes and digest info prefixes are mixed ..pkcs11-tool does not inform about hashes but digest prefixes ..

  1. we need a flag that announces the card is able to run PSO compute HASH (this is to be signalized by "hw" flag - that's the answer to my question above)
  2. we need a flag that announces the card is able to add specific digest info in PSO compute signature
  3. we need a flag that announces the card is able to add padding ..
  4. we need flag for RSA RAW - without padding and digest info ..

It is necessary to distinguish mainly points 1 and 2.

According to the flags, we then present which mechanisms are supported by hw / sw

For example the MyEID card then need flags by categories:

  1. SC_ALGORITHM_RSA_HASH_NONE (there is no support for PSO compute HASH inside card)
  2. SC_ALGORITHM_RSA_DIGEST_INFO_SHA1 (there is support for adding SHA1 digest by card)
  3. SC_ALGORITHM_RSA_PAD_PKCS1 (card can add pkcs1 v1.1 padding)
  4. SC_ALGORITHM_RSA_RAW (card can sign any data - of course value of this data must be in range 0 .. modulus-1)

@popovec
Copy link
Member

popovec commented Dec 6, 2020

@CendioOssman

The simplest way to use 1024 bit key and SHA512 with MyEID is recompiling OpenSC, here patch:

diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c
index 677e068f..70e47adc 100644
--- a/src/libopensc/card-myeid.c
+++ b/src/libopensc/card-myeid.c
@@ -225,7 +225,7 @@ static int myeid_init(struct sc_card *card)
        }
 
        flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_ONBOARD_KEY_GEN;
-       flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1;
+       flags |= SC_ALGORITHM_RSA_HASH_NONE;
 
        _sc_card_add_rsa_alg(card,  512, flags, 0);

Tested, MyEID 4.0.1

SHA512-RSA-PKCS is now working for key size 1024,1536 2048 ..

  • for 512 bit rv = CKR_ARGUMENTS_BAD (0x7)
  • for 768 bit rv = CKR_FUNCTION_NOT_SUPPORTED (0x54)

SHA512-RSA-PKCS-PSS is now working for key size 1536 and bigger,
for keys 512..1024 rv = CKR_FUNCTION_NOT_SUPPORTED (0x54)

Patch above affect only MyEID card, there is not used card hardware for PKCS#1 v1.5 padding, this padding is now inserted in software. (MSE APDU 00 22 41 B6 0A 80 01 00 81 02 4B 01 84 01 0 TAG 0x80 = 00, card is running raw RSA, no padding, no digest info is added inside card).

This patch does not affect normal functionality i.e. RSA decipher, RSA raw signature or RSA signature with SHA1 etc.. However, this is only a temporary fix for the strange behavior of OpenSC to the SC_ALGORITHM_RSA_HASH_* flags.

@dengert
Copy link
Member

dengert commented Dec 6, 2020

Removing SC_ALGORITHM_RSA_HASH_SHA1 is reasonable, but that is only my option. The 40% size is enforced by the card when doing PKCS1. I am not convinced this is to thwart a RSA padding oracle attack or some other reason. I consider using RSA 1024 is more of a security risk.

This could be an option in opensc.conf. (4 drivers do grep scconf_find_blocks card-*)
For a test you could do:

card_driver myeid {
  flags = "0x00000001";
}

Then change your patch to something like:
flags |= SC_ALGORITHM_RSA_HASH_NONE | ((card->flags & 0x0000001) ? 0 : SC_ALGORITHM_RSA_HASH_SHA1);

Anyone else have a thought on the 40% rule?

@mouse07410
Copy link
Contributor

In short, I don't see benefits in 40% rule.

@popovec
Copy link
Member

popovec commented Dec 6, 2020

Making MyEID driver configurable - to disable/enable internal PKCS#1 padding function and disable/enable internal digest info prefix insertion - from opensc.conf or environment variable make a sense.

There is bigger problem .., all HASH functions except SHA1 are currently blocked with SC_ALGORITHM_RSA_HASH_SHA1 enabled. And this has nothing to do with 40% payload limit. SHA256-RSA-PKCS can be used with this limit but is not listed in pkcs11-tool -M, why ? because mixing HASH and digest info prefix in SC_ALGORITHM_RSA_HASH_* .

I wonder which other cards are affected by this problem.

@dengert
Copy link
Member

dengert commented Dec 6, 2020

What happens if you add SC_ALGORITHM_RSA_HASH_SHA256 to the flags in the card driver and 128, 384 and 512.

pkcs11/framework-pkcs15.c register_mechanisms is where the PKCS11 Mechanisms are created from see
https://github.com/OpenSC/OpenSC/blob/master/src/pkcs11/framework-pkcs15.c#L5726

The point here is that later pkcs15-sec.c calls sc_get_encoding_flags in padding.c which tries to separate the padding, digest, hash, and crypto operations in to what need to be done in software and what is done on the card.

look in debug logs for this message https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/pkcs15-sec.c#L670

This is some of the more complicated code in OpenSC and should not be changed if at all possible. All cards depend on this code.

One problem is there are only 32 SC_ALGORITHM_* bits. I think 30 are used. Some future change need to make this 64.

@popovec
Copy link
Member

popovec commented Dec 7, 2020

@dengert I did the test as you suggested:

diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c
index 677e068f..321f5027 100644
--- a/src/libopensc/card-myeid.c
+++ b/src/libopensc/card-myeid.c
@@ -225,7 +225,7 @@ static int myeid_init(struct sc_card *card)
        }
 
        flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_ONBOARD_KEY_GEN;
-       flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1;
+       flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1| SC_ALGORITHM_RSA_HASH_SHA256;

debug info: DEE flags:0x00002002 alg_info->flags:0x80002303 pad:0x00000000 sec:0x00002002

SHA1 is working but SHA256 no ..

for SHA256-RSA-PKCS wrong signature is returned (missing sha256 digest info)

00000000  00 01 ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000040  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000050  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff 00  |................|
00000060  4b 5b fc 41 26 0b c6 df  a5 bd ec 4c c2 67 cc 2c  |K[.A&......L.g.,|
00000070  a5 f6 5c a1 93 c8 68 2b  b6 d1 d0 e5 79 07 b8 b0  |..\...h+....y...|

Why this is not working is clear from the code in padding.c .... here if SC_ALGORITHM_RSA_HASH_SHA256 is set, code assumes that card generates the digest info prefix and padding. But this is wrong... here complette different flag is needed (for example SC_ALGORITHM_RSA_PAD_PKCS1_WITH_DIGEST_INFO_SHA256).

In another place of OpenSC code if SC_ALGORITHM_RSA_HASH_SHA256 is set, the corresponding mechnisms (SHA256-RSA-PKCS and SHA256-RSA-PKCS-PSS) are generated (as documented above by pkcs11-tool -M). But this is wrong, because card does not support SHA256 or SHA1 hashing. Hasing is always done in openssl.

I repeat, one flag is used for two different purposes.

One problem is there are only 32 SC_ALGORITHM_* bits. I think 30 are used. Some future change need to make this 64.

What about separate flags for padding ..

  1. SC_PADDING_NODE
  2. SC_PADDING_PKCS1 - the cad add pkcs1 v1.5 padding
  3. SC_PADDING_PKCS1_SHA1 - the card add pkcs1 v1.5 pdding and SHA1 digest info prefix

@dengert
Copy link
Member

dengert commented Dec 7, 2020

Have a look at: https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/card-myeid.c#L722
and the APDU it sends from myeid_set_security_env_rsa but first some background.

sc_pkcs1_strip_digest_info_prefix is used by some card drivers and pkcs15-sec.c. This is most likely being used to strip the digest prefix. https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/pkcs15-sec.c#L653

Debug info from above comment looks correct: DEE flags:0x00002002 alg_info->flags:0x80002303 pad:0x00000000 sec:0x00002002. It says:

  • We want to do: flags=SC_ALGORITHM_RSA_HASH_SHA256 | SC_ALGORITHM_RSA_PAD_PKCS1

  • Software, card driver or card can do this: alg_info= SC_ALGORITHM_RSA_HASH_SHA256 | SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_PAD_NONE | SC_ALGORITHM_RSA_PAD_PKCS1

  • We will not do any padding, hash or digest info in software, just pass them to the card driver pad=0 i.e. nothing;

  • Driver or card needs to do: sec= SC_ALGORITHM_RSA_HASH_SHA256 | SC_ALGORITHM_RSA_PAD_PKCS1

The card driver's myeid_set_security_env_rsa would be passed the sec, and it looks like it should send this APDU:
00 22 41 B6 LL 80 01 XX ... (based on Table 49 in the doc I have) XX should be 42 for SHA256 It is probably sending 02, no hash just data to be padded. 00 is RSA RAW.

Have a look at sc_pkcs1_strip_digest_info_prefix. It is used by some card drivers and pkcs15-sec.c. This is most likely being used to strip the digest prefix. https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/pkcs15-sec.c#L653 Some card drivers actually call this.

A debug log, gdb debugging could show more. More code maybe needed in the card driver to indicate which digest is to be passed i.e. the '42rather then02or00`. (The table 49 on second page with "X2h" has the 40% comment.)

And there is a also a sc_pkcs1_add_digest_info_prefix which can be used to add back the digest while in the driver, if the card can not be told to add it back in https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/card-myeid.c#L722

But the original bug report was to allow handling of RSA 1024 with SHA512 and avoid the 40% restriction by doing RSA_RAW.
adding back a SHA prefix prefix with a 1024 key, will still exceed the 40%.
If the 40% would be exceed, if a config option say its OK to override this, the digest, and padding could still be done to use RSA_RAW.

It might also be possible to use one of the two unused SC_ALGORITHM_* bits 0x3000000 so sc_pkcs1_strip_digest_info_prefix will not be called, if is indeed being called when it should not be. (As I said this is section of code is used by every card, and is very touchy. But adding a bit should not cause any problems.)

Questions for debugging to help answer what is going on:

  • When using the SHA256 is sc_pkcs1_strip_digest_info_prefix? (may need to use GDB, extra sc_log or printf for testing)

  • What is passed to myeid_set_security_env_rsa in env? (Will need to use GDB sc_log or printf)

  • What is the full SEC APDU i.e. 00 22 41 B6? (GDB or opensc debug log)

@popovec
Copy link
Member

popovec commented Dec 7, 2020

@dengert
For now we can ignore 40% limitation, and even if, RSA1024 with SHA256 meet this limit .. (I also run tests with RSA2048 and SHA256 .. same wrong results) Same results for MyEID 4.0.1 and OsEID card .. (OsEID card does not limit payload to 40%, here only 11 bytes for block1 pkcs1 v1.5 padding is requested).

As I said, we have a bigger problem (related to this issue)... except for SHA1, no other hash works if SC_ALGORITHM_RSA_HASH_SHA1 is set. Setting the SC_ALGORITHM_RSA_HASH_SHA256 flag does not help either, I will document once more:

Tests below with patched driver ..
flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1|SC_ALGORITHM_RSA_HASH_SHA256;

problematic part: (padding.c line 490... and this is consequence of mixing SC_ALGORITHM_RSA_HASH_* flag functions..)

P:31775; T:0x139663518450112 16:22:07.989 [opensc-pkcs11] pkcs15-sec.c:613:sc_pkcs15_compute_signature: supported algorithm flags 0x80002303, private key usage 0x2E
P:31775; T:0x139663518450112 16:22:07.989 [opensc-pkcs11] padding.c:470:sc_get_encoding_flags: called
P:31775; T:0x139663518450112 16:22:07.989 [opensc-pkcs11] padding.c:474:sc_get_encoding_flags: iFlags 0x2002, card capabilities 0x80002303
P:31775; T:0x139663518450112 16:22:07.989 [opensc-pkcs11] padding.c:490:sc_get_encoding_flags: Card supports the signature operation we want to do, great, let's go with it then  <<<<<< added for debug .. 
P:31775; T:0x139663518450112 16:22:07.989 [opensc-pkcs11] padding.c:527:sc_get_encoding_flags: pad flags 0x0, secure algorithm flags 0x2002
P:31775; T:0x139663518450112 16:22:07.989 [opensc-pkcs11] padding.c:528:sc_get_encoding_flags: returning with: 0 (Success)

Here is already prepared message for card and in wrong format .. (without digest info, see below)

MSE:
00 22 41 B6 0A 80 01 02 81 02 4B 01 84 01 00 Tag 0x80 = 2 = pkcs1 padding in card ..
PSO: Only hash here .. but card is unable to add digest info for SHA256 ..

Outgoing APDU (38 bytes):
00 2A 9E 9A 20 38 74 D5 C9 CC 5A B7 26 E6 BB EB .*.. 8t...Z.&...
AD EE 22 C6 80 CE 53 00 04 D4 F0 BB 32 F7 65 D4 .."...S.....2.e.
2A 0A 6C 6D C1 00                               *.lm..

verification: openssl rsautl -verify -in tmp/rsa_sign_testfile.txt.sign -inkey tmp/exported_rsa_key.pub -pubin -raw -hexdump
(correct hash, missing digest info, padding added by card ...)

0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff   ................
0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff   ................
.
.
00d0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff 00   ................
00e0 - 38 74 d5 c9 cc 5a b7 26-e6 bb eb ad ee 22 c6 80   8t...Z.&....."..
00f0 - ce 53 00 04 d4 f0 bb 32-f7 65 d4 2a 0a 6c 6d c1   .S.....2.e.*.lm.

For completeness sc_pkcs1_strip_digest_info_prefix() is not called (I added debug info into this function, but there was no hit).

..... edited, appended ..
for SHA1-RSA-PKCS - signature is correct..

MSE:
00 22 41 B6 0A 80 01 12 81 02 4B 02 84 01 00
PSO:
00 2A 9E 9A 14 0D 27 EE 26 9E EC FB 57 67 29 5A 95 75 53 18 D3 45 7A 43 1D 00

signature:

0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff   ................
.
.
00c0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff   ................
00d0 - ff ff ff ff ff ff ff ff-ff ff ff ff 00 30 21 30   .............0!0
00e0 - 09 06 05 2b 0e 03 02 1a-05 00 04 14 0d 27 ee 26   ...+.........'.&
00f0 - 9e ec fb 57 67 29 5a 95-75 53 18 d3 45 7a 43 1d   ...Wg)Z.uS..EzC.

@dengert
Copy link
Member

dengert commented Dec 7, 2020

OK, I think we are close:
SHA256 sends: 00 22 41 B6 0A 80 01 02 81 02 4B 01 84 01 00 Tag 0x80 = 2 = pkcs1 padding in card ..
SHA1 sends: 00 22 41 B6 0A 80 01 12 81 02 4B 02 84 01 00

Note that tag 80 01 XY is really from table 49 and consists of 2 - 4 bit values.
X is 0-7: 0 is no hash, 1 is sha1. 4 would be sha256.

Y is 2 = PSO: COMPUTE DIGITAL SIGNATURE which says what it will do.
Y = 0 would be RSA_RAW which has a foot note that says RAW_RSA can not be used with 2048 bit keys. (Bbut this is not important now. )

I would expect that for the SHA256 if this was set to XY was set 42 it would work. I think the card driver is setting both in line
https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/card-myeid.c#L722
As a test can you try:

diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c
index 677e068f..06b822a6 100644
--- a/src/libopensc/card-myeid.c
+++ b/src/libopensc/card-myeid.c
@@ -719,6 +719,9 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t *
        {
                *p++ = 0x80;    /* algorithm reference */
                *p++ = 0x01;
+               if (env->algorithm_ref & 0xFF == 0x02)
+                       *p++ = 0x42;
+               else
                *p++ = env->algorithm_ref & 0xFF;
        }
        if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT)

This should only be a test. The real code should involve format_senv and what is in the PKCS15 structures.

what is output of pkcs15-tool --list-info or pkcs15-tool -D Use opensc 0.21.0 if possible.

This problem is very similar to #1987 where key refs was a combination of algrothms and key ref.

@popovec
Copy link
Member

popovec commented Dec 7, 2020

@dengert

TAG 0x80 with value 0x42 is not accepted by MyEID card, because this value is RFU (from Aventra doc .. ).. and even if this add this prefix, we need to do this for all (in card) supported and unsupported hashes.

Be aware if I block SC_ALGORITHM_RSA_HASH_SHA1, i have lot of mechanisms available #2173 (comment) and fully functional !

If I add SC_ALGORITHM_RSA_HASH_SHA256 .. only SHA256-RSA-PKCS algo is added and I miss sha384, sha512 which in the previous case will be added.

Before I try any tests and document anything else, I would like you to explain to me, which of the following points is marked with the SC_ALGORITHM_RSA_HASH_* flag.

The card run RSA operation on concatenated:

  1. PKCS#1 v1.5 signature padding - A) added by card B) by opensc
  2. digest information about SHA1(256,384..) A) added by card card B) by opensc
  3. HASH (SHA1 (256, 384...) A) calculated in card B) calculated in opensc (openssl)

If some of card driver set the SC_ALGORITHM_RSA_HASH_SHA1 flag.. what is affected ? point 2. or 3. or both ?

@dengert
Copy link
Member

dengert commented Dec 7, 2020

The above was meant to be a test, to see if the 042 value really is RFU.

So you tried the patch to send 0x42? And card did not accept it?
If it worked, then need a better patch that looks at the senv-> to find the hash requested, and try the 512 too.

If it does not work, then we are back to using RSA RAW.

The other logic that might help is pkcs15-sec.c lines 605-619 where opensc uses sc_pkcs15_decipher to in effect do a RSA_RAW sign.

Has Aventra be contacted on these issues. The wrote the driver.
Copyright (C) 2008-2019 Aventra Ltd.

https://github.com/hhonkanen any comments?

@popovec
Copy link
Member

popovec commented Dec 7, 2020

@dengert You forgot to answer me ..

Before I try any tests and document anything else, I would like you to explain to me, which of the following points is marked with the SC_ALGORITHM_RSA_HASH_* flag.

The card run RSA operation on concatenated:

  1. PKCS#1 v1.5 signature padding - A) added by card B) by opensc
  2. digest information about SHA1(256,384..) A) added by card card B) by opensc
  3. HASH (SHA1 (256, 384...) A) calculated in card B) calculated in opensc (openssl)

If some of card driver set the SC_ALGORITHM_RSA_HASH_SHA1 flag.. what is affected ? point 2. or 3. or both ?

@dengert
Copy link
Member

dengert commented Dec 7, 2020

I did not answer, as I said this is very complicated and I have not looked at it in years.
Anytime I need to look at it I do it with a test case, source code, grep and GDB. Most of this code is in pkcs15-sec.c, padding.c and pkcs11/framework-pkcs15.c

#2173 (comment) showed how if user asked for SC_ALGORITHM_RSA_HASH_SHA256, how the opensc code (other then driver) would need to do via pad= and what card driver or card would do in the sec=

run a test using RSA SHA1 debug and look for the DEE flags:0x00002002 alg_info->flags:0xxxxxxxxx pad:0xxxxxxxxx sec:0xxxxxxxxx
The also grep for any SC_ALGORITHM_RSA_ to see where it is tested.

@popovec
Copy link
Member

popovec commented Dec 7, 2020

@dengert Thank you for your opinion.

@dengert
Copy link
Member

dengert commented Dec 7, 2020

@fabled Can you comment on this discussion? Your commit 3f832ca#diff-37e30f9c78a5e1d99108d1466121e487527aa413eb132b7738345b20452923cf in April, 2019 made some changes for newer cards and included a "use the 2K signing kludge only on cards that need it"

Some of the issues we are having with this discussion include using 2K keys.
OpenSC also has changes in pkcs15-sec.c to use a decrypt operation if signature wont work as expected. It is not clear if these changes cover all the cases.

Also is the MYEID 4.5+ documentation available? Is this "MyEID PKI JavaCard Applet Reference manual
Ver. 2.3.0" last update "25.3.2019 2.3.0 Added PUT DATA: Initialise PIV emulation"

Can you say anything about Table 49 and the RFU? If these are really reserved and not supported on any card then the card must do RSA_RAW when the hash is not SHA1.

@fabled
Copy link
Contributor

fabled commented Dec 8, 2020

I think @hhonkanen is in better position to answer the above questions.

popovec added a commit to popovec/oseid that referenced this issue Dec 8, 2020
Warning, working only with patched opensc..
OpenSC/OpenSC#2173
	modified:   tools/OsEID-tool
popovec added a commit to popovec/OpenSC that referenced this issue Dec 8, 2020
This patch enables using of: SHA224-RSA-PKCS, SHA256-RSA-PKCS,
SHA384-RSA-PKCS, SHA512-RSA-PKCS and PSS variants of these mechanism for
MyEID users. (This patch is related to issue OpenSC#2173.)

CI tests for these mechanisms are also enabled (using OsEID emulation).
@hhonkanen
Copy link
Contributor

Newest MyEID reference manual, which covers also 4.5, is now available at OpenSC's MyEID wiki page.

MyEID cards didn't officially support raw RSA signature with 2K keys before version 4.5, but it could be done using Decipher APDU. Since 4.5 MyEID cards support APDU chaining, which can be used to calculate raw RSA with key lengths up to 4096 bits, using PSO: Compute Digital Signature APDU. 4.5 is backwards compatible, so also the old way can be used. Decipher can be done using two alternative ways in 4.5, either using the old way of splitting the ciphered data to two APDUs, or by using the new APDU chaining mechanism.

popovec added a commit to popovec/oseid that referenced this issue Dec 8, 2020
Warning, working only with patched opensc..
OpenSC/OpenSC#2173
	modified:   tools/OsEID-tool
@popovec
Copy link
Member

popovec commented Dec 8, 2020

@hhonkanen Is for You acceptable to enable more pkcs11 mechanisms, even if the generating padding and digest info would be moved from card to opensc? Please look at #2178, travis CI check for RSA-PKCS is already fixed (due different locale - utf8/posix - settings).

Relevant log at https://travis-ci.org/github/OpenSC/OpenSC/jobs/748304326 line 1800 - 2033

@hhonkanen
Copy link
Contributor

@popovec I think it's good to support as many mechanisms as possible and I see no problem in doing digestinfo and padding in software. The card's functionality on them is quite limited, as it can only make digestinfo for SHA1 and do PKCS#1 padding. If it is significant for someone whether they are done on card or in software, the card's capabilities can be found from the reference manual.

frankmorgner pushed a commit that referenced this issue Dec 9, 2020
This patch enables using of: SHA224-RSA-PKCS, SHA256-RSA-PKCS,
SHA384-RSA-PKCS, SHA512-RSA-PKCS and PSS variants of these mechanism for
MyEID users. (This patch is related to issue #2173.)

CI tests for these mechanisms are also enabled (using OsEID emulation).
@popovec
Copy link
Member

popovec commented Jan 1, 2021

I am trying to fix this issue in MyEID driver. If I turn off the hardware PKCS1 padding (by removing the SC_ALGORITHM_RSA_PAD_PKCS1 flag from the driver), then RAW RSA is applied to all operations and the size of the signature data is not limited in any way.

I would like this feature to be enabled and disabled according to user requirements (not just from opensc.conf).

Does anyone have any idea how to do this? For example, use an environment variable that describes what will be done?

OPENSC_MyEID_DISABLE_PKCS1_PADDING = 0
OPENSC_MyEID_DISABLE_PKCS1_PADDING = 1

@dengert
Copy link
Member

dengert commented Jan 1, 2021

Card drivers card-edo.c and card-piv.c both use getenv()
If your card can not do this on the card, maybe the ATR or card capabilities could indicate this.

Not sure why you want to do this. If PKCS11 says use RSA_RAW i.e. CKM_RSA_X_509, that is what it will do as it expects the caller has done some padding or knows what they are doing. RSA padding is a security feature, which lets the recipient know the signature or encrypted data is valid. It should not be bypassed. Some form of padding should be done.

See 2.1.12 X.509 (raw) RSA

@dengert
Copy link
Member

dengert commented Jan 1, 2021

I may have misunderstood your last post. PKCS11 V2.40 (and older versions) in section "2.1.6 PKCS #1 v1.5 RSA" says size of the data to be padded is limited to k-11 bytes.
The 11 comes from the 11 bytes needed for padding. If your card imposes additional restrictions, such as limiting to 51 bytes,
then it does not truly implement PKCS1 V1.5 padding. One could argue that CKM_RSA_PKCS i.e. SC_ALGORITHM_RSA_PAD_PKCS1 should not be set by the driver if this is really card limitation: "not exceed 40% of the RSA key modulus length" which is a card imposed non standard limitation. One could also argue that the driver could "fix" the problem by padding in software, and using RSA RAW, or RSA decryption. But this is deceptive if the user expects padding is done on card.
This is also complicated by: "MyEID cards didn't officially support raw RSA signature with 2K keys before version 4.5".

@popovec
Copy link
Member

popovec commented Jan 2, 2021

My suggestion:

  • Default setting: PKCS1 padding is running on card ..
  • If the user sets the above environment variable, the pkcs#1 v1.5 padding is then generated in the card driver.

The user is not deceived, it is his choice how to set the specified variable. If OpenSC does not offer this option, the user can recompile OpenSC with disabled SC_ALGORITHM_RSA_PAD_PKCS1.

I'm just suggesting a simplification so that users who need this option don't have to recompile OpenSC. But I expect someone to say whether the name of the variable is acceptable and if this is a reasonable solution. Or someone has a idea about another option than the user can turn on / off HW padding according to his requirements....

This is also complicated by: "MyEID cards didn't officially support raw RSA signature with 2K keys before version 4.5".

RSA operation security: If the card has an RSA RAW operation (regardless of whether it is a PSO: decipher or PSO: compute signature operation), it is possible to send any data to the card. The card will still perform a private operation with the data and the result for the PSO: decipher and the PSO: compute signature will end with the same result. If an attacker tries to extract the private key using a RAW RSA operation (using specially prepared messages), it doesn't matter which operation (decipher/sign) he uses.

MyEID restriction (versions without official support for RAW RSA signature 2048 bit) only applies to APDU transport for PSO: compute signature) not RSA operation itself.

@dengert
Copy link
Member

dengert commented Jan 4, 2021

Setting environment variable will not work for login.

Most users have one smart card (usually gov issued) and use only one computer and don't know how to compile anything.
People on this list are more developers then users.

So if you are going to provide a choice it should be via opensc.conf.

This is a EID issue and the developers who use EID cards should make the decision. I am not one of them.

@popovec
Copy link
Member

popovec commented Jan 4, 2021

Thanks for the warning. As you indicated, login will be a problem, of course for applications like ssh and openvpn the environment variable could be used but it is less convenient than using opensc.conf. The user can use the environment variable to set his own opensc.conf....

@hhonkanen
Copy link
Contributor

I think it's important that the default options, which don't required modifying opensc.conf, work in most use cases.

It has been a problem that mechanism SHA256-RSA-PKCS or SHA512-RSA-PKCS have been missing with MyEID and it's a good improvement to add them. In most cases the 40% of modulus length limitation doesn't matter, as SHA512 is rarely used with 1024 bit RSA keys. Legacy systems which still use 1024 bit RSA typically also use SHA1 or sometimes SHA256 which still fits in. Typical use cases are using SHA256 or SHA512 with 2048 bit or 4096 bit keys, and they work fine even if you let MyEID do PKCS1 padding. I don't know where the 40% limitation originally came from, it might be to prevent Oracle attack as @popovec suggested, or from some recommendation - or even from the Javacard platform.

If you consider it important that PKCS1 padding is done by hardware if possible, I suggest the following:

  • we should support SHA256-RSA-PKCS and SHA512-RSA-PKCS by default and we can let MyEID do padding. When using 1024 bit keys SHA512 results into an error.
  • using a setting in opensc.conf, one could force MyEID driver to always do raw RSA, and force OpenSC to calculate padding in software. Users who need RSA 1025 with SHA512, which I think is not very common, could get it working by setting the special option in opensc.conf.

Regardless of the setting, users could always use CMK_RSA_X509 if they need full control of the data to be signed.

@CendioOssman
Copy link
Contributor Author

Legacy systems which still use 1024 bit RSA typically also use SHA1 or sometimes SHA256 which still fits in.

As a FYI, in our scenario it was a legacy card setup, but they were using the cards to connect to non-legacy systems. The newer systems couldn't do much about the size of the RSA key, but they could request better hash algorithms.

I don't know how common this is, but it might be dangerous to assume that just because one part is old that all parts are.

@popovec
Copy link
Member

popovec commented Jan 5, 2021

@CendioOssman

Here possible solution for your problem:

#2193

opensc.conf

app default {
        card_driver myeid {
                disable_hw_pkcs1_padding = 1;
        }
}

@hhonkanen
Copy link
Contributor

@CendioOssman I see. I don't object against resolving it so that OpenSC and MyEID driver would automatically use raw RSA in case the data is too long for on card padding. As it seems that the 40% limitation is MyEID specific (not only, I found that at least older Finnish official EID cards have this too, according to FINEID v2.1 specification), the logic should be in the MyEID driver I think.

Does anybody know, could it be significant for someone in sense of security, whether the PKCS#1 padding is done by card or by OpenSC? Increasingly users want to use PSS padding instead of PKCS#1 and MyEID doesn't do that on card, so it has to be done in software anyway. PKCS#11 compliance is another thing to consider. Is it clearly defined, if we announce some mechanism is done in hardware, which parts of it must be done in hardware? The signature calculation of course, but hashing is not usually done on card anyway.

@CendioOssman
Copy link
Contributor Author

As a FYI, this also happens with SetCOS 4 cards. More modern SetCOS cards don't seem to have this restriction though.

@popovec
Copy link
Member

popovec commented Feb 7, 2023

This issue can be considered resolved (since pull request #2193 is already part of opensc). @CendioOssman are you satisfied with the solution to this problem? Can we close this issue?

@CendioOssman
Copy link
Contributor Author

I'll try to find some time to test, but the description sounds like that PR is sufficient, yes.

Does it cover the SetCOS cards as well, though?

@popovec
Copy link
Member

popovec commented Feb 8, 2023

No, #2193 does not apply to SetCOS cards, this PR is sprecific only for MyEID cards. If there is a similar problem with the SetCOS card, I suggest closing this issue (since it is resolved) and opening a new issue for the SetCOS card.

@CendioOssman
Copy link
Contributor Author

Sorry for the delay. I've tested #2193 now, and it seems to resolve the issue with the cards I have here. :)

I seem to have misplaced that old SetCOS card, unfortunately. I'll add a new issue if it becomes an issue in practice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants