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

GemSafe Card: Can't sign a SHA256 hash #508

Closed
velter opened this issue Aug 2, 2015 · 53 comments
Closed

GemSafe Card: Can't sign a SHA256 hash #508

velter opened this issue Aug 2, 2015 · 53 comments

Comments

@velter
Copy link
Contributor

velter commented Aug 2, 2015

I'm trying to use a GemSafe card (OpenTrust KSign) with opensc pkcs11 interface (windows x64). All is work well except that I can't sign a SHA256 hash. Pkcs11 return a general error.
After enabling logging, the error come from

2015-08-02 13:08:58.513 [opensc-pkcs11] card-gemsafeV1.c:430:gemsafe_compute_signature: called
2015-08-02 13:08:58.513 error: input data too long: 51 bytes
2015-08-02 13:08:58.513 [opensc-pkcs11] sec.c:58:sc_compute_signature: returning with: -1300 (Invalid arguments)

There seem to be a hard limit in the code to 36 bytes.

I know the card is able to process more data than this with the Gemalto provided pkcs11 lib.

Is this check really necessary ?

Card ATR : 3b:7d:96:00:00:80:31:80:65:b0:83:11:00:c8:83:00:90:00

@dengert
Copy link
Member

dengert commented Aug 2, 2015

Looks like some bugs. This driver has bee around a long time, and looks like it needs some work, to use with larger hashes.
the card can do PKCS#1 padding on the card, so it should be able to take a sha256 hash.

Can you try removing the check for 36?

There may also be issues with 2048 bit keys as it appears some cards using this driver do not support 2048 RSA keys.
If that is the cards, line 205 _sc_card_add_rsa_alg(card, 2048, flags, 0); should not be set for these older cards.

On 8/2/2015 6:42 AM, velter wrote:

I'm trying to use a GemSafe card (OpenTrust KSign) with opensc pkcs11 interface (windows x64). All is work well except that I can't sign a SHA256 hash. Pkcs11 return a general error.
After enabling logging, the error come from

2015-08-02 13:08:58.513 [opensc-pkcs11] card-gemsafeV1.c:430:gemsafe_compute_signature: called
2015-08-02 13:08:58.513 error: input data too long: 51 bytes
2015-08-02 13:08:58.513 [opensc-pkcs11] sec.c:58:sc_compute_signature: returning with: -1300 (Invalid arguments)

There seem to be a hard limit in the code to 36 bytes.

I know the card is able to process more data than this with the Gemalto provided pkcs11 lib.

Is this check really necessary ?

Card ATR : 3b:7d:96:00:00:80:31:80:65:b0:83:11:00:c8:83:00:90:00


Reply to this email directly or view it on GitHub #508.

Douglas E. Engert [email protected]

@velter
Copy link
Contributor Author

velter commented Aug 2, 2015

Thanks for looking at this. Unfortunately I have no build environment for opensc at hand (I'm calling opensc from a delphi app on windows x64). Will try to setup one. The key on my card is 2048bit, but as I understand it the problem will only arise when trying for example to generate a 2048bit keypair on an old card not supporting 2048bits.

@frankmorgner
Copy link
Member

The key on my card is 2048bit, but as I understand it the problem will only arise when trying for example to generate a 2048bit keypair on an old card not supporting 2048bits.

What is your expected result/behavior of OpenSC in this case?

@velter
Copy link
Contributor Author

velter commented Aug 4, 2015

It was just a comment on dengert reply. Currently I only use my key for signing (my concern is that signing more than 36 bytes raise an error with this key). I have not even tried to generate a keypair.

@frankmorgner
Copy link
Member

Maybe I'm missing some content. Is there something that does not work for you? Or did you simply want to have feedback about that single check (though it has never been a problem for your card)?

@velter
Copy link
Contributor Author

velter commented Aug 4, 2015

Sorry for not being clear about this. My only problem right now is about the check in card-gemsafeV1.c which put a hard limit of 36 bytes to the size of the data being signed. This check prevent for example to sign a SHA256 hash. My card can handle this as it works with the gemalto provided pkcs11 lib.
I currently don't have a build environment for open-sc so I can't test if just removing the check solves the issue. I will try to setup one to make this test.

@frankmorgner frankmorgner changed the title GemSafe Card input data too long GemSafe Card: Can't sign a SHA256 hash Aug 4, 2015
@velter
Copy link
Contributor Author

velter commented Sep 2, 2015

I finally got an opensc build environment up. I tried to just remove the check for datelen>36, but this does not work. Here are the relevant log. Let me know if I can do something else to help resolve this.

0x7f67f5d4f740 12:06:59.493 [opensc-pkcs11] card-gemsafeV1.c:430:gemsafe_compute_signature: called
0x7f67f5d4f740 12:06:59.493 [opensc-pkcs11] apdu.c:563:sc_transmit_apdu: called
0x7f67f5d4f740 12:06:59.493 [opensc-pkcs11] card.c:352:sc_lock: called
0x7f67f5d4f740 12:06:59.493 [opensc-pkcs11] apdu.c:530:sc_transmit: called
0x7f67f5d4f740 12:06:59.493 [opensc-pkcs11] apdu.c:384:sc_single_transmit: called
0x7f67f5d4f740 12:06:59.493 [opensc-pkcs11] apdu.c:389:sc_single_transmit: CLA:0, INS:2A, P1:90, P2:A0, data(53) 0x7fff3eaf2bd0
0x7f67f5d4f740 12:06:59.493 [opensc-pkcs11] reader-pcsc.c:251:pcsc_transmit: reader 'Gemalto USB Shell Token V2 00 00'
0x7f67f5d4f740 12:06:59.493 [opensc-pkcs11] apdu.c:187:sc_apdu_log:
Outgoing APDU data [   58 bytes] =====================================
00 2A 90 A0 35 90 33 30 31 30 0D 06 09 60 86 48 .*..5.3010...`.H
01 65 03 04 02 01 05 00 04 20 8C 5C 66 BD F3 71 .e....... .\f..q
AC 24 44 A5 F1 7C B2 67 97 B6 62 4F 43 84 D8 E3 .$D..|.g..bOC...
07 B4 2E A3 7F 1D D3 E0 CE 3E                   .........>
======================================================================
0x7f67f5d4f740 12:06:59.493 [opensc-pkcs11] reader-pcsc.c:184:pcsc_internal_transmit: called
0x7f67f5d4f740 12:06:59.510 [opensc-pkcs11] apdu.c:187:sc_apdu_log:
Incoming APDU data [    2 bytes] =====================================
69 85 i.
======================================================================
0x7f67f5d4f740 12:06:59.510 [opensc-pkcs11] apdu.c:399:sc_single_transmit: returning with: 0 (Success)
0x7f67f5d4f740 12:06:59.510 [opensc-pkcs11] apdu.c:552:sc_transmit: returning with: 0 (Success)
0x7f67f5d4f740 12:06:59.510 [opensc-pkcs11] card.c:392:sc_unlock: called
0x7f67f5d4f740 12:06:59.510 [opensc-pkcs11] iso7816.c:139:iso7816_check_sw: Conditions of use not satisfied
0x7f67f5d4f740 12:06:59.510 [opensc-pkcs11] card-gemsafeV1.c:476:gemsafe_compute_signature: returning with: -1209 (Not allowed)

@frankmorgner
Copy link
Member

"not allowed" sounds like you forgot to verify your PIN first. does the same test case work for something else than SHA256?

By the way, the check for data_len cannot simply be removed because it could break the ASN.1 blob that is edited "by hand" in gemsafe_compute_signature. It should be improved by using OpenSC's ASN.1 encoder...

@velter
Copy link
Contributor Author

velter commented Sep 2, 2015

I don't forgot. I also tried with SHA1 which does work. Here a the exact commands I used (just obscured the pin) :
./pkcs11-tool -s -m SHA1-RSA-PKCS --pin XXXXXX -d 1d228aeee53d5b320aaede6715592afa6491791a -i mytest -o sha1.out => works
./pkcs11-tool -s -m SHA256-RSA-PKCS --pin XXXXXX -d 1d228aeee53d5b320aaede6715592afa6491791a -i mytest -o sha256.out => fail

Regarding the asn encoding you are right, but if I'm not wrong, the limit for a one byte length is 127. With sha256, data_len is 51 so the asn1 length is correct in this case.

@frankmorgner
Copy link
Member

Could you use the pkcs11-tool together with gemalto's pkcs11 lib? Make sure to log the APDUs via pcscd. This might reveal the relevant differences to OpenSC's implementation of this card.

@velter
Copy link
Contributor Author

velter commented Sep 2, 2015

I only have access to the gemalto pkcs11 lib under windows. I confirm that pkcs11-tool + gclib.dll works with both SHA1 and SHA256. But I don't know how to capture APDUs on windows.

@frankmorgner
Copy link
Member

@dengert
Copy link
Member

dengert commented Sep 2, 2015

From previous note you card appears to be SC_CARD_TYPE_GEMSAFEV1_SEEID
The card-gmsafeV1.c driver says the card supports SC_ALGORITHM_RSA_PAD_PKCS1 on the card but not SC_ALGORITHM_RSA_RAW
This means that you must send the digest header and the digest.

For SHA1 the header is 15 and the hash is 20 so the data_len is 35.
It is not clear why the code has "if (data_len > 36) {" when it should be > 35.

The data sent in your modified APDU looks correct for a SHA256 header and
card-gemsafeV1.c added the tag and length.

See the tables in padding.c as about hash headers.

The issue may be the card may have a built in test to only accept sha1 hashes if you have the card do the padding.
If you can find a technical manual for the application, that might show something.

If other drivers can sign a SHA256 hash, they could be doing a number of things:

The ADPU command is different from what is in card-gemsafeV1.c to send a different size hash.

The card can do RAW RSA and so the padding could be done in software rather then on the card.
card-gemsafeV1.c does not set SC_ALGORITHM_RSA_RAW, so raw is not done.

They use a trick where a decipher APDU of a padded hash returns the signature.
See pkcs15-sec.c
391 /* if the card has SC_ALGORITHM_NEED_USAGE set, and the
392 key is for signing and decryption, we need to emulate signing */

So a APDU trace of a working sha256 signature would show what is getting sent to the card.

On windows one way to get a APDU trace is to do a USB trace. There is a lot of extra data, but you
can find the APDUs. I have not don't one on these in years, looks like Microsoft now has a USB trace program.

Google for: Windows USB trace

On 9/2/2015 6:19 AM, velter wrote:

I don't forgot. I also tried with SHA1 which does work. Here a the exact commands I used (just obscured the pin) :
./pkcs11-tool -s -m SHA1-RSA-PKCS --pin XXXXXX -d 1d228aeee53d5b320aaede6715592afa6491791a -i mytest -o sha1.out => works
./pkcs11-tool -s -m SHA256-RSA-PKCS --pin XXXXXX -d 1d228aeee53d5b320aaede6715592afa6491791a -i mytest -o sha256.out => fail

Regarding the asn encoding you are right, but if I'm not wrong, the limit for a one byte length is 127. With sha256, data_len is 51 so the asn1 length is correct in this case.


Reply to this email directly or view it on GitHub #508 (comment).

Douglas E. Engert [email protected]

@dengert
Copy link
Member

dengert commented Sep 2, 2015

Wireshark has some USB tracing too, even on Windows:
https://wiki.wireshark.org/CaptureSetup/USB#Windows
http:https://desowin.org/usbpcap/

@velter
Copy link
Contributor Author

velter commented Sep 2, 2015

I gave apdu inspect a try. Here is the log for a successful sha256 sign with gclib.dll

The relevant apdu seem to be

transmitted:00 2a 90 a0 22 90 20 08 27 6a cd b3 d6 f7 cc 4d b2 2c 32 ce 60 11 a7 42 1e fb cc 56 22 b9 2a 12 6a 15 13 de 7d b8 aa
received:61 20

data_len = $20 => 32 => 256bits

The same for sha1 is

transmitted:00 2a 90 a0 16 90 14 aa bb e2 eb 84 d1 af 9a f0 2d ae b3 a5 3a 9a eb 45 32 48 c5
received:61 14

data_len = $14 => 20 => 160bits

so it definitly seem to be a padding problem

SCardTransmit (handle 0xEA010000)#
apduCounter:0#
totalBytesINCounter:1#
transmitted:80 ca 9f 7f
responseTime:609#
SCardTransmit result:0x0#
received:6e 00

SCardTransmit (handle 0xEA010000)#
apduCounter:1#
totalBytesINCounter:5#
transmitted:00 ca 9f 7f
responseTime:0#
SCardTransmit result:0x0#
received:6c 2d

SCardTransmit (handle 0xEA010000)#
apduCounter:2#
totalBytesINCounter:9#
transmitted:00 ca 9f 7f 2d
responseTime:16#
SCardTransmit result:0x0#
received:9f 7f 2a 42 50 32 72 12 91 81 72 13 00 10 36 00 03 84 89 10 8e 12 92 11 19 20 03 11 19 20 04 11 19 00 00 00 14 00 00 00 00 00 00 00 00 90 00

SCardTransmit (handle 0xEA010000)#
apduCounter:3#
totalBytesINCounter:14#
transmitted:00 a4 04 00 0c a0 00 00 00 18 0a 00 00 01 63 42 00
responseTime:16#
SCardTransmit result:0x0#
received:6a 82

SCardTransmit (handle 0xEA020000)#
apduCounter:4#
totalBytesINCounter:31#
transmitted:80 ca 9f 7f
responseTime:15#
SCardTransmit result:0x0#
received:6e 00

SCardTransmit (handle 0xEA020000)#
apduCounter:5#
totalBytesINCounter:35#
transmitted:00 ca 9f 7f
responseTime:0#
SCardTransmit result:0x0#
received:6c 2d

SCardTransmit (handle 0xEA020000)#
apduCounter:6#
totalBytesINCounter:39#
transmitted:00 ca 9f 7f 2d
responseTime:16#
SCardTransmit result:0x0#
received:9f 7f 2a 42 50 32 72 12 91 81 72 13 00 10 36 00 03 82 89 10 8e 12 92 11 19 20 03 11 19 20 04 11 19 00 00 00 14 00 00 00 00 00 00 00 00 90 00

SCardTransmit (handle 0xEA020000)#
apduCounter:7#
totalBytesINCounter:44#
transmitted:00 a4 04 00 0c a0 00 00 00 18 0a 00 00 01 63 42 00
responseTime:15#
SCardTransmit result:0x0#
received:6a 82

SCardTransmit (handle 0xEA070000)#
apduCounter:8#
totalBytesINCounter:61#
transmitted:00 ca 9f 7f 2d
responseTime:16#
SCardTransmit result:0x0#
received:9f 7f 2a 42 50 32 72 12 91 81 72 13 00 10 36 00 03 84 89 10 8e 12 92 11 19 20 03 11 19 20 04 11 19 00 00 00 14 00 00 00 00 00 00 00 00 90 00

SCardTransmit (handle 0xEA010001)#
apduCounter:9#
totalBytesINCounter:66#
transmitted:00 ca 9f 7f 2d
responseTime:0#
SCardTransmit result:0x0#
received:9f 7f 2a 42 50 32 72 12 91 81 72 13 00 10 36 00 03 82 89 10 8e 12 92 11 19 20 03 11 19 20 04 11 19 00 00 00 14 00 00 00 00 00 00 00 00 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:10#
totalBytesINCounter:71#
transmitted:00 ca df 30
responseTime:0#
SCardTransmit result:0x0#
received:6c 08

SCardTransmit (handle 0xEA070000)#
apduCounter:11#
totalBytesINCounter:75#
transmitted:00 ca df 30 08
responseTime:16#
SCardTransmit result:0x0#
received:df 30 05 76 33 2e 30 31 90 00

SCardTransmit (handle 0xEA010001)#
apduCounter:12#
totalBytesINCounter:80#
transmitted:00 ca df 30
responseTime:16#
SCardTransmit result:0x0#
received:6c 08

SCardTransmit (handle 0xEA010001)#
apduCounter:13#
totalBytesINCounter:84#
transmitted:00 ca df 30 08
responseTime:0#
SCardTransmit result:0x0#
received:df 30 05 76 33 2e 30 31 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:14#
totalBytesINCounter:89#
transmitted:00 20 00 81 10 34 33 34 31 32 31 00 00 00 00 00 00 00 00 00 00
responseTime:31#
SCardTransmit result:0x0#
received:90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:15#
totalBytesINCounter:110#
transmitted:00 a4 02 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
responseTime:16#
SCardTransmit result:0x0#
received:67 00

SCardTransmit (handle 0xEA070000)#
apduCounter:16#
totalBytesINCounter:131#
transmitted:00 cb 00 ff 0a b6 03 83 01 06 7f 49 02 81 00
responseTime:62#
SCardTransmit result:0x0#
received:61 00

SCardTransmit (handle 0xEA070000)#
apduCounter:17#
totalBytesINCounter:146#
transmitted:00 c0 00 00 00
responseTime:47#
SCardTransmit result:0x0#
received:b6 03 83 01 06 7f 49 82 01 04 81 82 01 00 bf c7 f9 dc 39 b6 f0 b8 1f 56 f5 27 4e ed e8 82 89 57 2d 86 b2 f5 be 77 c5 e6 66 ea 78 5f 81 f6 03 83 6f 03 cb c6 c1 c1 66 43 48 c9 86 90 27 d5 19 e2 62 78 80 78 d4 c4 1f 51 98 a8 03 fa bf a6 31 44 40 3c eb 97 2b 64 86 b4 f9 87 6c 23 2d 3e c9 f6 7c 2b c5 6e a1 6e fa 87 7e 32 15 fc b3 3f f0 77 c5 55 86 6a 11 0f 21 fa ef b0 23 4b b2 0f 3c ea c4 97 db d8 21 f8 ab e2 3e 5b fe 94 06 d2 31 84 20 31 ea 4c b6 0b 51 ff dd ad 2a 93 7f 3d 38 45 15 d2 92 a9 e0 1c bc 38 fa 8d 0e 8e 81 e1 ea 97 b7 ce 6c 56 6c d8 58 10 ca 46 f2 a3 59 41 22 3e 5a f0 d5 3e 23 86 e9 e8 a2 c0 8d e4 2b 3c dc b5 33 2b 2e c2 df 23 5c c1 b7 8b d8 5d dd dd fb 6a b0 eb dd c3 1b b9 75 1c 79 5e 2f d9 54 0b 7d 87 f9 70 a3 0a c3 0f 54 43 bc bb 9c 4f df 33 0e 1c 61 0e

SCardTransmit (handle 0xEA070000)#
apduCounter:18#
totalBytesINCounter:151#
transmitted:00 c0 00 00 0e
responseTime:31#
SCardTransmit result:0x0#
received:89 ec 22 f4 2a da 15 e3 a1 d3 dc 54 c4 f1 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:19#
totalBytesINCounter:156#
transmitted:00 cb 00 ff 0a b6 03 83 01 06 7f 49 02 82 00
responseTime:32#
SCardTransmit result:0x0#
received:61 10

SCardTransmit (handle 0xEA070000)#
apduCounter:20#
totalBytesINCounter:171#
transmitted:00 c0 00 00 10
responseTime:16#
SCardTransmit result:0x0#
received:b6 03 83 01 06 7f 49 82 00 06 82 81 03 01 00 01 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:21#
totalBytesINCounter:176#
transmitted:00 22 41 b6 06 80 01 42 84 01 06
responseTime:15#
SCardTransmit result:0x0#
received:90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:22#
totalBytesINCounter:187#
transmitted:00 2a 90 a0 22 90 20 08 27 6a cd b3 d6 f7 cc 4d b2 2c 32 ce 60 11 a7 42 1e fb cc 56 22 b9 2a 12 6a 15 13 de 7d b8 aa
responseTime:47#
SCardTransmit result:0x0#
received:61 20

SCardTransmit (handle 0xEA070000)#
apduCounter:23#
totalBytesINCounter:226#
transmitted:00 c0 00 00 20
responseTime:0#
SCardTransmit result:0x0#
received:08 27 6a cd b3 d6 f7 cc 4d b2 2c 32 ce 60 11 a7 42 1e fb cc 56 22 b9 2a 12 6a 15 13 de 7d b8 aa 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:24#
totalBytesINCounter:231#
transmitted:00 2a 9e 9a 00
responseTime:2562#
SCardTransmit result:0x0#
received:06 b1 21 e1 50 8f 83 0e 87 19 14 a1 87 39 87 16 67 c7 ab 18 e3 2c f8 8e 9f 8d 22 5e 0d 96 64 41 11 cb 10 4b bb e0 87 4d a7 bf 30 c1 6a a8 1d 46 0a 04 f8 6f 4b dd ab ea 1d 81 05 5e 97 ff 4c c5 fc 0b f1 d2 c2 b2 69 e3 89 05 6a e7 25 7d 71 bb d8 5d 7b b3 ae a2 60 e6 4e 0f 3b 99 8c 22 5e 37 41 53 d7 63 1e ee 36 dc 32 e6 a7 c5 62 8d 2a 96 f8 d3 9b 61 b4 f6 82 89 50 66 d9 62 2e 01 eb 30 da 1c 25 17 89 44 33 d0 72 7c d4 8a 9b 88 00 cd eb 10 5b 50 44 97 04 9f 5c 74 6d 6b 76 b1 66 6d b1 57 62 e7 e8 53 0b e5 7f bc 7c 9f 8e f0 d6 de 99 30 b4 4e 7b 77 c8 8c 90 f7 1a 7e 83 b5 76 8d bb 73 01 5c 35 bc 81 7f 91 cd 40 6b 4c 55 91 bc 9e 66 85 a3 39 b4 36 40 7f 24 23 2c 13 3e 12 1b 64 e5 f6 4a b2 1b 69 03 e5 d6 3f e1 bb 70 55 95 ca 7c 22 10 7c 9d 0f 03 61 e8 60 27 8d 6b 0f 4d 90 00

@dengert
Copy link
Member

dengert commented Sep 2, 2015

Interesting, it is sending just the hash, and not the header and the hash as required by PKCS#1 padding.
sc_pkcs1_strip_digest_info_prefix can do that, but not clear if it is called.

This could result in what looks like a valid signature, but will not verify with software that is expecting
the header to be present.

If the signature verifies with the public key, The card must be smart enough to add the header, based on the length of the hash:
SHA1=20, SHA256=32 see padding.c info_prefix.

OpenSC debug output starting after the PIN is verified till after the sc_pkcs15_compute_signature fails
will also show how the sec_env is set, and why sc_pkcs1_strip_digest_info_prefix was not called.

In the glib trace the sec_env is sent:
00 22 41 b6 06 80 01 42 84 01 06

Do you have a OpenSC debug output of a SHA1 signature starting after the PIN is verified till after the sc_pkcs15_compute_signature
works.

On 9/2/2015 3:00 PM, velter wrote:

I gave apdu inspect a try. Here is the log for a successful sha256 sign with gclib.dll

The relevant apdu seem to be

transmitted:00 2a 90 a0 22 90 20 08 27 6a cd b3 d6 f7 cc 4d b2 2c 32 ce 60 11 a7 42 1e fb cc 56 22 b9 2a 12 6a 15 13 de 7d b8 aa
received:61 20

data_len = $20 => 32 => 256bits

The same for sha1 is

transmitted:00 2a 90 a0 16 90 14 aa bb e2 eb 84 d1 af 9a f0 2d ae b3 a5 3a 9a eb 45 32 48 c5
received:61 14

data_len = $14 => 20 => 160bits

so it definitly seem to be a padding problem

[begin]
SCardTransmit (handle 0xEA010000)#
apduCounter:0#
totalBytesINCounter:1#
transmitted:80 ca 9f 7f
responseTime:609#
SCardTransmit result:0x0#
received:6e 00

SCardTransmit (handle 0xEA010000)#
apduCounter:1#
totalBytesINCounter:5#
transmitted:00 ca 9f 7f
responseTime:0#
SCardTransmit result:0x0#
received:6c 2d

SCardTransmit (handle 0xEA010000)#
apduCounter:2#
totalBytesINCounter:9#
transmitted:00 ca 9f 7f 2d
responseTime:16#
SCardTransmit result:0x0#
received:9f 7f 2a 42 50 32 72 12 91 81 72 13 00 10 36 00 03 84 89 10 8e 12 92 11 19 20 03 11 19 20 04 11 19 00 00 00 14 00 00 00 00 00 00 00 00 90 00

SCardTransmit (handle 0xEA010000)#
apduCounter:3#
totalBytesINCounter:14#
transmitted:00 a4 04 00 0c a0 00 00 00 18 0a 00 00 01 63 42 00
responseTime:16#
SCardTransmit result:0x0#
received:6a 82

SCardTransmit (handle 0xEA020000)#
apduCounter:4#
totalBytesINCounter:31#
transmitted:80 ca 9f 7f
responseTime:15#
SCardTransmit result:0x0#
received:6e 00

SCardTransmit (handle 0xEA020000)#
apduCounter:5#
totalBytesINCounter:35#
transmitted:00 ca 9f 7f
responseTime:0#
SCardTransmit result:0x0#
received:6c 2d

SCardTransmit (handle 0xEA020000)#
apduCounter:6#
totalBytesINCounter:39#
transmitted:00 ca 9f 7f 2d
responseTime:16#
SCardTransmit result:0x0#
received:9f 7f 2a 42 50 32 72 12 91 81 72 13 00 10 36 00 03 82 89 10 8e 12 92 11 19 20 03 11 19 20 04 11 19 00 00 00 14 00 00 00 00 00 00 00 00 90 00

SCardTransmit (handle 0xEA020000)#
apduCounter:7#
totalBytesINCounter:44#
transmitted:00 a4 04 00 0c a0 00 00 00 18 0a 00 00 01 63 42 00
responseTime:15#
SCardTransmit result:0x0#
received:6a 82

SCardTransmit (handle 0xEA070000)#
apduCounter:8#
totalBytesINCounter:61#
transmitted:00 ca 9f 7f 2d
responseTime:16#
SCardTransmit result:0x0#
received:9f 7f 2a 42 50 32 72 12 91 81 72 13 00 10 36 00 03 84 89 10 8e 12 92 11 19 20 03 11 19 20 04 11 19 00 00 00 14 00 00 00 00 00 00 00 00 90 00

SCardTransmit (handle 0xEA010001)#
apduCounter:9#
totalBytesINCounter:66#
transmitted:00 ca 9f 7f 2d
responseTime:0#
SCardTransmit result:0x0#
received:9f 7f 2a 42 50 32 72 12 91 81 72 13 00 10 36 00 03 82 89 10 8e 12 92 11 19 20 03 11 19 20 04 11 19 00 00 00 14 00 00 00 00 00 00 00 00 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:10#
totalBytesINCounter:71#
transmitted:00 ca df 30
responseTime:0#
SCardTransmit result:0x0#
received:6c 08

SCardTransmit (handle 0xEA070000)#
apduCounter:11#
totalBytesINCounter:75#
transmitted:00 ca df 30 08
responseTime:16#
SCardTransmit result:0x0#
received:df 30 05 76 33 2e 30 31 90 00

SCardTransmit (handle 0xEA010001)#
apduCounter:12#
totalBytesINCounter:80#
transmitted:00 ca df 30
responseTime:16#
SCardTransmit result:0x0#
received:6c 08

SCardTransmit (handle 0xEA010001)#
apduCounter:13#
totalBytesINCounter:84#
transmitted:00 ca df 30 08
responseTime:0#
SCardTransmit result:0x0#
received:df 30 05 76 33 2e 30 31 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:14#
totalBytesINCounter:89#
transmitted:00 20 00 81 10 34 33 34 31 32 31 00 00 00 00 00 00 00 00 00 00
responseTime:31#
SCardTransmit result:0x0#
received:90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:15#
totalBytesINCounter:110#
transmitted:00 a4 02 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
responseTime:16#
SCardTransmit result:0x0#
received:67 00

SCardTransmit (handle 0xEA070000)#
apduCounter:16#
totalBytesINCounter:131#
transmitted:00 cb 00 ff 0a b6 03 83 01 06 7f 49 02 81 00
responseTime:62#
SCardTransmit result:0x0#
received:61 00

SCardTransmit (handle 0xEA070000)#
apduCounter:17#
totalBytesINCounter:146#
transmitted:00 c0 00 00 00
responseTime:47#
SCardTransmit result:0x0#
received:b6 03 83 01 06 7f 49 82 01 04 81 82 01 00 bf c7 f9 dc 39 b6 f0 b8 1f 56 f5 27 4e ed e8 82 89 57 2d 86 b2 f5 be 77 c5 e6 66 ea 78 5f 81 f6 03 83 6f 03 cb c6 c1 c1 66 43 48 c9 86 90 27 d5 19 e2
62 78 80 78 d4 c4 1f 51 98 a8 03 fa bf a6 31 44 40 3c eb 97 2b 64 86 b4 f9 87 6c 23 2d 3e c9 f6 7c 2b c5 6e a1 6e fa 87 7e 32 15 fc b3 3f f0 77 c5 55 86 6a 11 0f 21 fa ef b0 23 4b b2 0f 3c ea c4 97 db
d8 21 f8 ab e2 3e 5b fe 94 06 d2 31 84 20 31 ea 4c b6 0b 51 ff dd ad 2a 93 7f 3d 38 45 15 d2 92 a9 e0 1c bc 38 fa 8d 0e 8e 81 e1 ea 97 b7 ce 6c 56 6c d8 58 10 ca 46 f2 a3 59 41 22 3e 5a f0 d5 3e 23 86
e9 e8 a2 c0 8d e4 2b 3c dc b5 33 2b 2e c2 df 23 5c c1 b7 8b d8 5d dd dd fb 6a b0 eb dd c3 1b b9 75 1c 79 5e 2f d9 54 0b 7d 87 f9 70 a3 0a c3 0f 54 43 bc bb 9c 4f df 33 0e 1c 61 0e

SCardTransmit (handle 0xEA070000)#
apduCounter:18#
totalBytesINCounter:151#
transmitted:00 c0 00 00 0e
responseTime:31#
SCardTransmit result:0x0#
received:89 ec 22 f4 2a da 15 e3 a1 d3 dc 54 c4 f1 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:19#
totalBytesINCounter:156#
transmitted:00 cb 00 ff 0a b6 03 83 01 06 7f 49 02 82 00
responseTime:32#
SCardTransmit result:0x0#
received:61 10

SCardTransmit (handle 0xEA070000)#
apduCounter:20#
totalBytesINCounter:171#
transmitted:00 c0 00 00 10
responseTime:16#
SCardTransmit result:0x0#
received:b6 03 83 01 06 7f 49 82 00 06 82 81 03 01 00 01 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:21#
totalBytesINCounter:176#
transmitted:00 22 41 b6 06 80 01 42 84 01 06
responseTime:15#
SCardTransmit result:0x0#
received:90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:22#
totalBytesINCounter:187#
transmitted:00 2a 90 a0 22 90 20 08 27 6a cd b3 d6 f7 cc 4d b2 2c 32 ce 60 11 a7 42 1e fb cc 56 22 b9 2a 12 6a 15 13 de 7d b8 aa
responseTime:47#
SCardTransmit result:0x0#
received:61 20

SCardTransmit (handle 0xEA070000)#
apduCounter:23#
totalBytesINCounter:226#
transmitted:00 c0 00 00 20
responseTime:0#
SCardTransmit result:0x0#
received:08 27 6a cd b3 d6 f7 cc 4d b2 2c 32 ce 60 11 a7 42 1e fb cc 56 22 b9 2a 12 6a 15 13 de 7d b8 aa 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:24#
totalBytesINCounter:231#
transmitted:00 2a 9e 9a 00
responseTime:2562#
SCardTransmit result:0x0#
received:06 b1 21 e1 50 8f 83 0e 87 19 14 a1 87 39 87 16 67 c7 ab 18 e3 2c f8 8e 9f 8d 22 5e 0d 96 64 41 11 cb 10 4b bb e0 87 4d a7 bf 30 c1 6a a8 1d 46 0a 04 f8 6f 4b dd ab ea 1d 81 05 5e 97 ff 4c c5
fc 0b f1 d2 c2 b2 69 e3 89 05 6a e7 25 7d 71 bb d8 5d 7b b3 ae a2 60 e6 4e 0f 3b 99 8c 22 5e 37 41 53 d7 63 1e ee 36 dc 32 e6 a7 c5 62 8d 2a 96 f8 d3 9b 61 b4 f6 82 89 50 66 d9 62 2e 01 eb 30 da 1c 25
17 89 44 33 d0 72 7c d4 8a 9b 88 00 cd eb 10 5b 50 44 97 04 9f 5c 74 6d 6b 76 b1 66 6d b1 57 62 e7 e8 53 0b e5 7f bc 7c 9f 8e f0 d6 de 99 30 b4 4e 7b 77 c8 8c 90 f7 1a 7e 83 b5 76 8d bb 73 01 5c 35 bc
81 7f 91 cd 40 6b 4c 55 91 bc 9e 66 85 a3 39 b4 36 40 7f 24 23 2c 13 3e 12 1b 64 e5 f6 4a b2 1b 69 03 e5 d6 3f e1 bb 70 55 95 ca 7c 22 10 7c 9d 0f 03 61 e8 60 27 8d 6b 0f 4d 90 00


Reply to this email directly or view it on GitHub #508 (comment).

Douglas E. Engert [email protected]

@frankmorgner
Copy link
Member

Yes, the difference should be in the command 00 22 41 b6 06 80 01 42 84 01 06 which means:

MSE:Set DST, Decipherment: Cryptographic mechanism reference (0x80) = 0x41, Reference of a private key (0x84) = 0x06

Could you check which command precedes the signature operation in OpenSC (i.e. what does the MSE:Set DST look like)?

OpenSC's gemsafe_flags2algref only uses 0x02 or 0x12 for the Cryptographic mechanism reference, but never 0x41. It seems that 0x41 should be used when sc_security_env->algorithm_flags is SC_ALGORITHM_HASH_NONE. However, this case (SC_ALGORITHM_HASH_NONE) is missing in gemsafe_flags2algref. If so, a workaround should be:

  1. disable SC_ALGORITHM_RSA_PAD_PKCS1 in the card flags (https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/card-gemsafeV1.c#L197)
  2. add handling for SC_ALGORITHM_HASH_NONE in gemsafe_flags2algref by returning 0x41 (see https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/card-gemsafeV1.c#L372)

@mouse07410
Copy link
Contributor

I apologize for jumping up on this thread without contributing to it. My question is rather naive, and related to the example signature you’re debugging for GemSafe.

My card is not GemSafe but NEO. And the following seems to work fine (02 identifies the signing key):

pkcs11-tool -s -m SHA256-RSA-PKCS --pin XXXXXX -d 02 -i mytest -o sha256.out

The question is: how can I verify this signature, preferably using pkcs11-tool? Probably I should’ve been able to figure that out from the man page, but I couldn’t. :-(

Thanks!

On Sep 2, 2015, at 20:03 , Frank Morgner <[email protected]mailto:[email protected]> wrote:

Yes, the difference should be in the command 00 22 41 b6 06 80 01 42 84 01 06 which means:

MSE:Set DST, Decipherment: Cryptographic mechanism reference (0x80) = 0x41, Reference of a private key (0x84) = 0x06

Could you check which command precedes the signature operation in OpenSC (i.e. what does the MSE:Set DST look like)?

OpenSC's gemsafe_flags2algref only uses 0x02 or 0x12 for the Cryptographic mechanism reference, but never 0x41. It seems that 0x41 should be used when sc_security_env->algorithm_flags is SC_ALGORITHM_HASH_NONE. However, this case (SC_ALGORITHM_HASH_NONE) is missing in gemsafe_flags2algref. If so, a workaround should be:

  1. disable SC_ALGORITHM_RSA_PAD_PKCS1 in the card flags (https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/card-gemsafeV1.c#L197)
  2. add handling for SC_ALGORITHM_HASH_NONE in gemsafe_flags2algref by returning 0x41 (see https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/card-gemsafeV1.c#L372)


Reply to this email directly or view it on GitHubhttps://github.com//issues/508#issuecomment-137276959.

Uri Blumenthal
[email protected]:[email protected]

@dengert
Copy link
Member

dengert commented Sep 3, 2015

One way is to use openssl. Something like this:

$# generate signature using card
$ pkcs11-tool -s -m SHA256-RSA-PKCS -d 02 -i mytest -o signature
Logging in to "PIV_II (PIV Card Holder pin)".
Please enter User PIN:
Using signature algorithm SHA256-RSA-PKCS

read pubkey from card:

$ pkcs11-tool -r -y pubkey -d 02 -o pubkey.02

use openssl to verify signatire using pubkey

$ openssl dgst -sha256 -verify pubkey.02 -keyform DER -signature signature < mytest
Verified OK

openssl dgst -verify -signature sha256.out < mytest

On 9/3/2015 12:57 AM, Mouse wrote:

I apologize for jumping up on this thread without contributing to it. My question is rather naive, and related to the example signature you’re debugging for GemSafe.

My card is not GemSafe but NEO. And the following seems to work fine (02 identifies the signing key):

pkcs11-tool -s -m SHA256-RSA-PKCS --pin XXXXXX -d 02 -i mytest -o sha256.out

The question is: how can I verify this signature, preferably using pkcs11-tool? Probably I should’ve been able to figure that out from the man page, but I couldn’t. :-(

Thanks!

On Sep 2, 2015, at 20:03 , Frank Morgner <[email protected]mailto:[email protected]> wrote:

Yes, the difference should be in the command 00 22 41 b6 06 80 01 42 84 01 06 which means:

MSE:Set DST, Decipherment: Cryptographic mechanism reference (0x80) = 0x41, Reference of a private key (0x84) = 0x06

Could you check which command precedes the signature operation in OpenSC (i.e. what does the MSE:Set DST look like)?

OpenSC's gemsafe_flags2algref only uses 0x02 or 0x12 for the Cryptographic mechanism reference, but never 0x41. It seems that 0x41 should be used when sc_security_env->algorithm_flags is
SC_ALGORITHM_HASH_NONE. However, this case (SC_ALGORITHM_HASH_NONE) is missing in gemsafe_flags2algref. If so, a workaround should be:

  1. disable SC_ALGORITHM_RSA_PAD_PKCS1 in the card flags (https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/card-gemsafeV1.c#L197)
  2. add handling for SC_ALGORITHM_HASH_NONE in gemsafe_flags2algref by returning 0x41 (see https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/card-gemsafeV1.c#L372)


Reply to this email directly or view it on GitHubhttps://github.com//issues/508#issuecomment-137276959.

Uri Blumenthal
[email protected]:[email protected]


Reply to this email directly or view it on GitHub #508 (comment).

Douglas E. Engert [email protected]

@mouse07410
Copy link
Contributor

Thank you!! Perfect! It worked exactly as you said. E.g.:

$ pkcs11-tool -s -m SHA384-RSA-PKCS -d 02 -i mytest -o sha384.out
$ pkcs11-tool -r -y pubkey -d 02 -o pubkey.02
$ openssl dgst -verify pubkey.02 -keyform DER -sha384 -signature sha384.out < mytest
Verified OK

Is there an analog for file encryption (probably openssl?) and decryption (using PKCS11 on the card)?

NEO supports the following mechanisms:

$ pkcs11-tool -M

Using slot 1 with a present token (0x1)

Supported mechanisms:

SHA-1, digest

SHA256, digest

SHA384, digest

SHA512, digest

MD5, digest

RIPEMD160, digest

ECDSA, keySize={256,384}, hw, sign, other flags=0x1800000

ECDH1-COFACTOR-DERIVE, keySize={256,384}, hw, derive, other flags=0x1800000

ECDH1-DERIVE, keySize={256,384}, hw, derive, other flags=0x1800000

RSA-X-509, keySize={1024,3072}, hw, decrypt, sign, verify

RSA-PKCS, keySize={1024,3072}, hw, decrypt, sign, verify

SHA1-RSA-PKCS, keySize={1024,3072}, sign, verify

SHA256-RSA-PKCS, keySize={1024,3072}, sign, verify

SHA384-RSA-PKCS, keySize={1024,3072}, sign, verify

SHA512-RSA-PKCS, keySize={1024,3072}, sign, verify

MD5-RSA-PKCS, keySize={1024,3072}, sign, verify

RIPEMD160-RSA-PKCS, keySize={1024,3072}, sign, verify

From that I figure that only RSA-based encryption/decryption is available? Or is there something that pkcs11-tool does not show me? Like the ability to to ECIES or otherwise encrypt/decrypt using EC keys?

Thanks!


From: Doug Engert [[email protected]]
Sent: Thursday, September 03, 2015 13:55
To: OpenSC/OpenSC
Cc: Uri Blumenthal
Subject: Re: [OpenSC] GemSafe Card: Can't sign a SHA256 hash (#508)

One way is to use openssl. Something like this:

$# generate signature using card
$ pkcs11-tool -s -m SHA256-RSA-PKCS -d 02 -i mytest -o signature
Logging in to "PIV_II (PIV Card Holder pin)".
Please enter User PIN:
Using signature algorithm SHA256-RSA-PKCS

read pubkey from card:

$ pkcs11-tool -r -y pubkey -d 02 -o pubkey.02

use openssl to verify signatire using pubkey

$ openssl dgst -sha256 -verify pubkey.02 -keyform DER -signature signature < mytest
Verified OK

openssl dgst -verify -signature sha256.out < mytest

On 9/3/2015 12:57 AM, Mouse wrote:

I apologize for jumping up on this thread without contributing to it. My question is rather naive, and related to the example signature you’re debugging for GemSafe.

My card is not GemSafe but NEO. And the following seems to work fine (02 identifies the signing key):

pkcs11-tool -s -m SHA256-RSA-PKCS --pin XXXXXX -d 02 -i mytest -o sha256.out

The question is: how can I verify this signature, preferably using pkcs11-tool? Probably I should’ve been able to figure that out from the man page, but I couldn’t. :-(

Thanks!


Reply to this email directly or view it on GitHubhttps://github.com//issues/508#issuecomment-137527950.

@dengert
Copy link
Member

dengert commented Sep 5, 2015

Looking at the debug output you sent, the problem may be in
pkcs15-sec.c in these lines:
423 if ((flags == (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) &&
424 !(alg_info->flags & (SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE))) {

where this line is not executed for your card:
428 r = sc_pkcs1_strip_digest_info_prefix(&algo, tmp, inlen, tmp, &tmplen);

card-gemsafe.c sets:
197 flags = SC_ALGORITHM_RSA_PAD_PKCS1;
198 flags |= SC_ALGORITHM_RSA_PAD_ISO9796;
199 flags |= SC_ALGORITHM_ONBOARD_KEY_GEN;
200 flags |= SC_ALGORITHM_RSA_HASH_NONE;

The reason I say this is because you are trying to send 51 bytes, rather then just the SHA256 32 byte hash
The 51 bytes includes the digest header. sc_pkcs1_strip_digest_info_prefix should have been called to strip it.

I believe I asked you earlier to send an opensc-debug output that includes the sc_pkcs15_compute_signature up to the failure
of 51 > 36 or the APDU fails.

The debug output you have sent start with gemsafe_compute_signature which is too late.

On 9/2/2015 3:00 PM, velter wrote:

I gave apdu inspect a try. Here is the log for a successful sha256 sign with gclib.dll

The relevant apdu seem to be

transmitted:00 2a 90 a0 22 90 20 08 27 6a cd b3 d6 f7 cc 4d b2 2c 32 ce 60 11 a7 42 1e fb cc 56 22 b9 2a 12 6a 15 13 de 7d b8 aa
received:61 20

data_len = $20 => 32 => 256bits

The same for sha1 is

transmitted:00 2a 90 a0 16 90 14 aa bb e2 eb 84 d1 af 9a f0 2d ae b3 a5 3a 9a eb 45 32 48 c5
received:61 14

data_len = $14 => 20 => 160bits

so it definitly seem to be a padding problem

[begin]
SCardTransmit (handle 0xEA010000)#
apduCounter:0#
totalBytesINCounter:1#
transmitted:80 ca 9f 7f
responseTime:609#
SCardTransmit result:0x0#
received:6e 00

SCardTransmit (handle 0xEA010000)#
apduCounter:1#
totalBytesINCounter:5#
transmitted:00 ca 9f 7f
responseTime:0#
SCardTransmit result:0x0#
received:6c 2d

SCardTransmit (handle 0xEA010000)#
apduCounter:2#
totalBytesINCounter:9#
transmitted:00 ca 9f 7f 2d
responseTime:16#
SCardTransmit result:0x0#
received:9f 7f 2a 42 50 32 72 12 91 81 72 13 00 10 36 00 03 84 89 10 8e 12 92 11 19 20 03 11 19 20 04 11 19 00 00 00 14 00 00 00 00 00 00 00 00 90 00

SCardTransmit (handle 0xEA010000)#
apduCounter:3#
totalBytesINCounter:14#
transmitted:00 a4 04 00 0c a0 00 00 00 18 0a 00 00 01 63 42 00
responseTime:16#
SCardTransmit result:0x0#
received:6a 82

SCardTransmit (handle 0xEA020000)#
apduCounter:4#
totalBytesINCounter:31#
transmitted:80 ca 9f 7f
responseTime:15#
SCardTransmit result:0x0#
received:6e 00

SCardTransmit (handle 0xEA020000)#
apduCounter:5#
totalBytesINCounter:35#
transmitted:00 ca 9f 7f
responseTime:0#
SCardTransmit result:0x0#
received:6c 2d

SCardTransmit (handle 0xEA020000)#
apduCounter:6#
totalBytesINCounter:39#
transmitted:00 ca 9f 7f 2d
responseTime:16#
SCardTransmit result:0x0#
received:9f 7f 2a 42 50 32 72 12 91 81 72 13 00 10 36 00 03 82 89 10 8e 12 92 11 19 20 03 11 19 20 04 11 19 00 00 00 14 00 00 00 00 00 00 00 00 90 00

SCardTransmit (handle 0xEA020000)#
apduCounter:7#
totalBytesINCounter:44#
transmitted:00 a4 04 00 0c a0 00 00 00 18 0a 00 00 01 63 42 00
responseTime:15#
SCardTransmit result:0x0#
received:6a 82

SCardTransmit (handle 0xEA070000)#
apduCounter:8#
totalBytesINCounter:61#
transmitted:00 ca 9f 7f 2d
responseTime:16#
SCardTransmit result:0x0#
received:9f 7f 2a 42 50 32 72 12 91 81 72 13 00 10 36 00 03 84 89 10 8e 12 92 11 19 20 03 11 19 20 04 11 19 00 00 00 14 00 00 00 00 00 00 00 00 90 00

SCardTransmit (handle 0xEA010001)#
apduCounter:9#
totalBytesINCounter:66#
transmitted:00 ca 9f 7f 2d
responseTime:0#
SCardTransmit result:0x0#
received:9f 7f 2a 42 50 32 72 12 91 81 72 13 00 10 36 00 03 82 89 10 8e 12 92 11 19 20 03 11 19 20 04 11 19 00 00 00 14 00 00 00 00 00 00 00 00 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:10#
totalBytesINCounter:71#
transmitted:00 ca df 30
responseTime:0#
SCardTransmit result:0x0#
received:6c 08

SCardTransmit (handle 0xEA070000)#
apduCounter:11#
totalBytesINCounter:75#
transmitted:00 ca df 30 08
responseTime:16#
SCardTransmit result:0x0#
received:df 30 05 76 33 2e 30 31 90 00

SCardTransmit (handle 0xEA010001)#
apduCounter:12#
totalBytesINCounter:80#
transmitted:00 ca df 30
responseTime:16#
SCardTransmit result:0x0#
received:6c 08

SCardTransmit (handle 0xEA010001)#
apduCounter:13#
totalBytesINCounter:84#
transmitted:00 ca df 30 08
responseTime:0#
SCardTransmit result:0x0#
received:df 30 05 76 33 2e 30 31 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:14#
totalBytesINCounter:89#
transmitted:00 20 00 81 10 34 33 34 31 32 31 00 00 00 00 00 00 00 00 00 00
responseTime:31#
SCardTransmit result:0x0#
received:90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:15#
totalBytesINCounter:110#
transmitted:00 a4 02 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
responseTime:16#
SCardTransmit result:0x0#
received:67 00

SCardTransmit (handle 0xEA070000)#
apduCounter:16#
totalBytesINCounter:131#
transmitted:00 cb 00 ff 0a b6 03 83 01 06 7f 49 02 81 00
responseTime:62#
SCardTransmit result:0x0#
received:61 00

SCardTransmit (handle 0xEA070000)#
apduCounter:17#
totalBytesINCounter:146#
transmitted:00 c0 00 00 00
responseTime:47#
SCardTransmit result:0x0#
received:b6 03 83 01 06 7f 49 82 01 04 81 82 01 00 bf c7 f9 dc 39 b6 f0 b8 1f 56 f5 27 4e ed e8 82 89 57 2d 86 b2 f5 be 77 c5 e6 66 ea 78 5f 81 f6 03 83 6f 03 cb c6 c1 c1 66 43 48 c9 86 90 27 d5 19 e2
62 78 80 78 d4 c4 1f 51 98 a8 03 fa bf a6 31 44 40 3c eb 97 2b 64 86 b4 f9 87 6c 23 2d 3e c9 f6 7c 2b c5 6e a1 6e fa 87 7e 32 15 fc b3 3f f0 77 c5 55 86 6a 11 0f 21 fa ef b0 23 4b b2 0f 3c ea c4 97 db
d8 21 f8 ab e2 3e 5b fe 94 06 d2 31 84 20 31 ea 4c b6 0b 51 ff dd ad 2a 93 7f 3d 38 45 15 d2 92 a9 e0 1c bc 38 fa 8d 0e 8e 81 e1 ea 97 b7 ce 6c 56 6c d8 58 10 ca 46 f2 a3 59 41 22 3e 5a f0 d5 3e 23 86
e9 e8 a2 c0 8d e4 2b 3c dc b5 33 2b 2e c2 df 23 5c c1 b7 8b d8 5d dd dd fb 6a b0 eb dd c3 1b b9 75 1c 79 5e 2f d9 54 0b 7d 87 f9 70 a3 0a c3 0f 54 43 bc bb 9c 4f df 33 0e 1c 61 0e

SCardTransmit (handle 0xEA070000)#
apduCounter:18#
totalBytesINCounter:151#
transmitted:00 c0 00 00 0e
responseTime:31#
SCardTransmit result:0x0#
received:89 ec 22 f4 2a da 15 e3 a1 d3 dc 54 c4 f1 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:19#
totalBytesINCounter:156#
transmitted:00 cb 00 ff 0a b6 03 83 01 06 7f 49 02 82 00
responseTime:32#
SCardTransmit result:0x0#
received:61 10

SCardTransmit (handle 0xEA070000)#
apduCounter:20#
totalBytesINCounter:171#
transmitted:00 c0 00 00 10
responseTime:16#
SCardTransmit result:0x0#
received:b6 03 83 01 06 7f 49 82 00 06 82 81 03 01 00 01 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:21#
totalBytesINCounter:176#
transmitted:00 22 41 b6 06 80 01 42 84 01 06
responseTime:15#
SCardTransmit result:0x0#
received:90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:22#
totalBytesINCounter:187#
transmitted:00 2a 90 a0 22 90 20 08 27 6a cd b3 d6 f7 cc 4d b2 2c 32 ce 60 11 a7 42 1e fb cc 56 22 b9 2a 12 6a 15 13 de 7d b8 aa
responseTime:47#
SCardTransmit result:0x0#
received:61 20

SCardTransmit (handle 0xEA070000)#
apduCounter:23#
totalBytesINCounter:226#
transmitted:00 c0 00 00 20
responseTime:0#
SCardTransmit result:0x0#
received:08 27 6a cd b3 d6 f7 cc 4d b2 2c 32 ce 60 11 a7 42 1e fb cc 56 22 b9 2a 12 6a 15 13 de 7d b8 aa 90 00

SCardTransmit (handle 0xEA070000)#
apduCounter:24#
totalBytesINCounter:231#
transmitted:00 2a 9e 9a 00
responseTime:2562#
SCardTransmit result:0x0#
received:06 b1 21 e1 50 8f 83 0e 87 19 14 a1 87 39 87 16 67 c7 ab 18 e3 2c f8 8e 9f 8d 22 5e 0d 96 64 41 11 cb 10 4b bb e0 87 4d a7 bf 30 c1 6a a8 1d 46 0a 04 f8 6f 4b dd ab ea 1d 81 05 5e 97 ff 4c c5
fc 0b f1 d2 c2 b2 69 e3 89 05 6a e7 25 7d 71 bb d8 5d 7b b3 ae a2 60 e6 4e 0f 3b 99 8c 22 5e 37 41 53 d7 63 1e ee 36 dc 32 e6 a7 c5 62 8d 2a 96 f8 d3 9b 61 b4 f6 82 89 50 66 d9 62 2e 01 eb 30 da 1c 25
17 89 44 33 d0 72 7c d4 8a 9b 88 00 cd eb 10 5b 50 44 97 04 9f 5c 74 6d 6b 76 b1 66 6d b1 57 62 e7 e8 53 0b e5 7f bc 7c 9f 8e f0 d6 de 99 30 b4 4e 7b 77 c8 8c 90 f7 1a 7e 83 b5 76 8d bb 73 01 5c 35 bc
81 7f 91 cd 40 6b 4c 55 91 bc 9e 66 85 a3 39 b4 36 40 7f 24 23 2c 13 3e 12 1b 64 e5 f6 4a b2 1b 69 03 e5 d6 3f e1 bb 70 55 95 ca 7c 22 10 7c 9d 0f 03 61 e8 60 27 8d 6b 0f 4d 90 00


Reply to this email directly or view it on GitHub #508 (comment).

Douglas E. Engert [email protected]

@velter
Copy link
Contributor Author

velter commented Sep 6, 2015

Sorry the delay.

Here are the logs

0x7f7679674740 14:55:35.703 [opensc-pkcs11] mechanism.c:429:sc_pkcs11_signature_final: called
0x7f7679674740 14:55:35.703 [opensc-pkcs11] mechanism.c:431:sc_pkcs11_signature_final: data length 140144782868480
0x7f7679674740 14:55:35.703 [opensc-pkcs11] mechanism.c:444:sc_pkcs11_signature_final: 140144782868512 bytes to sign
0x7f7679674740 14:55:35.703 [opensc-pkcs11] framework-pkcs15.c:3517:pkcs15_prkey_sign: Initiating signing operation, mechanism 0x40.
0x7f7679674740 14:55:35.703 [opensc-pkcs11] card.c:352:sc_lock: called
0x7f7679674740 14:55:35.703 [opensc-pkcs11] reader-pcsc.c:519:pcsc_lock: called
0x7f7679674740 14:55:35.703 [opensc-pkcs11] framework-pkcs15.c:3578:pkcs15_prkey_sign: Selected flags 202. Now computing signature for 32 bytes. 512 bytes reserved.
0x7f7679674740 14:55:35.703 [opensc-pkcs11] pkcs15-sec.c:312:sc_pkcs15_compute_signature: called
0x7f7679674740 14:55:35.703 [opensc-pkcs11] pkcs15-sec.c:313:sc_pkcs15_compute_signature: security operation flags 0x202
0x7f7679674740 14:55:35.703 [opensc-pkcs11] pkcs15-sec.c:395:sc_pkcs15_compute_signature: supported algorithm flags 0x8000001A, private key usage 0x2E
0x7f7679674740 14:55:35.703 [opensc-pkcs11] padding.c:283:sc_get_encoding_flags: called
0x7f7679674740 14:55:35.703 [opensc-pkcs11] padding.c:287:sc_get_encoding_flags: iFlags 0x202, card capabilities 0x8000001A
0x7f7679674740 14:55:35.703 [opensc-pkcs11] padding.c:316:sc_get_encoding_flags: pad flags 0x200, secure algorithm flags 0x2
0x7f7679674740 14:55:35.703 [opensc-pkcs11] padding.c:317:sc_get_encoding_flags: returning with: 0 (Success)
0x7f7679674740 14:55:35.703 [opensc-pkcs11] pkcs15-sec.c:446:sc_pkcs15_compute_signature: DEE flags:0x00000202 alg_info->flags:0x8000001a pad:0x00000200 sec:0x00000002
0x7f7679674740 14:55:35.703 [opensc-pkcs11] padding.c:242:sc_pkcs1_encode: called
0x7f7679674740 14:55:35.703 [opensc-pkcs11] padding.c:246:sc_pkcs1_encode: hash algorithm 0x200, pad algorithm 0x0
0x7f7679674740 14:55:35.704 [opensc-pkcs11] padding.c:265:sc_pkcs1_encode: returning with: 0 (Success)
0x7f7679674740 14:55:35.704 [opensc-pkcs11] card.c:352:sc_lock: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] pkcs15-sec.c:481:sc_pkcs15_compute_signature: Private key path ''
0x7f7679674740 14:55:35.704 [opensc-pkcs11] sec.c:68:sc_set_security_env: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] card-gemsafeV1.c:404:gemsafe_set_security_env: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] apdu.c:563:sc_transmit_apdu: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] card.c:352:sc_lock: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] apdu.c:530:sc_transmit: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] apdu.c:384:sc_single_transmit: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] apdu.c:389:sc_single_transmit: CLA:0, INS:22, P1:41, P2:B6, data(6) 0x7fffc61191e0
0x7f7679674740 14:55:35.704 [opensc-pkcs11] reader-pcsc.c:251:pcsc_transmit: reader 'Gemalto USB Shell Token V2 00 00'
0x7f7679674740 14:55:35.704 [opensc-pkcs11] apdu.c:187:sc_apdu_log:
Outgoing APDU data [   11 bytes] =====================================
00 22 41 B6 06 80 01 02 84 01 05 ."A........
======================================================================
0x7f7679674740 14:55:35.704 [opensc-pkcs11] reader-pcsc.c:184:pcsc_internal_transmit: called
0x7f7679674740 14:55:35.739 [opensc-pkcs11] apdu.c:187:sc_apdu_log:
Incoming APDU data [    2 bytes] =====================================
90 00 ..
======================================================================
0x7f7679674740 14:55:35.739 [opensc-pkcs11] apdu.c:399:sc_single_transmit: returning with: 0 (Success)
0x7f7679674740 14:55:35.739 [opensc-pkcs11] apdu.c:552:sc_transmit: returning with: 0 (Success)
0x7f7679674740 14:55:35.739 [opensc-pkcs11] card.c:392:sc_unlock: called
0x7f7679674740 14:55:35.739 [opensc-pkcs11] sec.c:72:sc_set_security_env: returning with: 0 (Success)
0x7f7679674740 14:55:35.739 [opensc-pkcs11] sec.c:54:sc_compute_signature: called
0x7f7679674740 14:55:35.739 [opensc-pkcs11] card-gemsafeV1.c:430:gemsafe_compute_signature: called
0x7f7679674740 14:55:35.739 [opensc-pkcs11] card-gemsafeV1.c:433:gemsafe_compute_signature: error: input data too long: 51 bytes
0x7f7679674740 14:55:35.739 [opensc-pkcs11] sec.c:58:sc_compute_signature: returning with: -1300 (Invalid arguments)

@velter
Copy link
Contributor Author

velter commented Sep 6, 2015

Looking at it more closely it seems that sc_pkcs1_encode line 452 of pkcs15-sec.c should not be called.
This is caused by sc_get_encoding_flags setting pflags to SC_ALGORITHM_RSA_HASH_SHA256 and sc_pkcs15_compute_signature comparing pflags to 0 instead of SC_ALGORITHM_RSA_PAD_PKCS1.

so replacing line 449 of pkcs15-sec.c with

if (pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) {

Make the card compute the signature without error, but the computed signatures are INVALID for both sha1 AND sha256. There must be something else.

I also hacked the source to have set_security_env send the same apdu than gclib, but this give an error agin (return 0x42 in gemsafe_flags2algref and setting key_ref[0] to 6).

As this seem very tricky, I will probably stay with an SHA1 hash.

@dengert
Copy link
Member

dengert commented Sep 6, 2015

What was the command used for this?
Do you have more of the log, it is not clear how it got to the first line.

It looks like the hash has been done, and 0x20 or 32 bytes are to be signed,
but the mechanism is is 0x40 CKM_SHA256_RSA_PKCS and the flags 202 is being passed, and this is not handled correctly

See other comments below.

On 9/6/2015 8:02 AM, velter wrote:

Sorry the delay.

Here are the logs

0x7f7679674740 14:55:35.703 [opensc-pkcs11] mechanism.c:429:sc_pkcs11_signature_final: called
0x7f7679674740 14:55:35.703 [opensc-pkcs11] mechanism.c:431:sc_pkcs11_signature_final: data length 140144782868480

Line 431 is printing the debug wrong, using %li, should be %i as buffer_len is unsigned int.
Using hex calculator and discarding first 4 bytes, looks data length is 0.

0x7f7679674740 14:55:35.703 [opensc-pkcs11] mechanism.c:444:sc_pkcs11_signature_final: 140144782868512 bytes to sign

Line 444 is also using "%li but should be %i looks like x20 or 32 bytes need to be signed.

0x7f7679674740 14:55:35.703 [opensc-pkcs11] framework-pkcs15.c:3517:pkcs15_prkey_sign: Initiating signing operation, mechanism 0x40.
0x7f7679674740 14:55:35.703 [opensc-pkcs11] card.c:352:sc_lock: called
0x7f7679674740 14:55:35.703 [opensc-pkcs11] reader-pcsc.c:519:pcsc_lock: called
0x7f7679674740 14:55:35.703 [opensc-pkcs11] framework-pkcs15.c:3578:pkcs15_prkey_sign: Selected flags 202. Now computing signature for 32 bytes. 512 bytes reserved.

If the hash was already done, it not clear why 202 is not just 02.

0x7f7679674740 14:55:35.703 [opensc-pkcs11] pkcs15-sec.c:312:sc_pkcs15_compute_signature: called
0x7f7679674740 14:55:35.703 [opensc-pkcs11] pkcs15-sec.c:313:sc_pkcs15_compute_signature: security operation flags 0x202
0x7f7679674740 14:55:35.703 [opensc-pkcs11] pkcs15-sec.c:395:sc_pkcs15_compute_signature: supported algorithm flags 0x8000001A, private key usage 0x2E
0x7f7679674740 14:55:35.703 [opensc-pkcs11] padding.c:283:sc_get_encoding_flags: called
0x7f7679674740 14:55:35.703 [opensc-pkcs11] padding.c:287:sc_get_encoding_flags: iFlags 0x202, card capabilities 0x8000001A
0x7f7679674740 14:55:35.703 [opensc-pkcs11] padding.c:316:sc_get_encoding_flags: pad flags 0x200, secure algorithm flags 0x2
0x7f7679674740 14:55:35.703 [opensc-pkcs11] padding.c:317:sc_get_encoding_flags: returning with: 0 (Success)
0x7f7679674740 14:55:35.703 [opensc-pkcs11] pkcs15-sec.c:446:sc_pkcs15_compute_signature: DEE flags:0x00000202 alg_info->flags:0x8000001a pad:0x00000200 sec:0x00000002

Based on the 51 later, it looks like padding.c:248 and 249:
if (hash_algo != SC_ALGORITHM_RSA_HASH_NONE) {
i = sc_pkcs1_add_digest_info_prefix(hash_algo, in, in_len, out, &tmp_len);

are called to put the hash header back on 19+32=51 card-gensafeV1.c indicates it sets SC_ALGORITHM_RSA_HASH_NONE

Looks like the line 248 should either be
if (!(hash_algo & SC_ALGORITHM_RSA_HASH_NONE)) {

or the flag 0x202 should have been set to 0x02 once the hash was computed.

Need to see more of the beginning of the log...

0x7f7679674740 14:55:35.703 [opensc-pkcs11] padding.c:242:sc_pkcs1_encode: called
0x7f7679674740 14:55:35.703 [opensc-pkcs11] padding.c:246:sc_pkcs1_encode: hash algorithm 0x200, pad algorithm 0x0
0x7f7679674740 14:55:35.704 [opensc-pkcs11] padding.c:265:sc_pkcs1_encode: returning with: 0 (Success)
0x7f7679674740 14:55:35.704 [opensc-pkcs11] card.c:352:sc_lock: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] pkcs15-sec.c:481:sc_pkcs15_compute_signature: Private key path ''
0x7f7679674740 14:55:35.704 [opensc-pkcs11] sec.c:68:sc_set_security_env: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] card-gemsafeV1.c:404:gemsafe_set_security_env: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] apdu.c:563:sc_transmit_apdu: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] card.c:352:sc_lock: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] apdu.c:530:sc_transmit: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] apdu.c:384:sc_single_transmit: called
0x7f7679674740 14:55:35.704 [opensc-pkcs11] apdu.c:389:sc_single_transmit: CLA:0, INS:22, P1:41, P2:B6, data(6) 0x7fffc61191e0
0x7f7679674740 14:55:35.704 [opensc-pkcs11] reader-pcsc.c:251:pcsc_transmit: reader 'Gemalto USB Shell Token V2 00 00'
0x7f7679674740 14:55:35.704 [opensc-pkcs11] apdu.c:187:sc_apdu_log:
Outgoing APDU data [ 11 bytes] =====================================

00 22 41 B6 06 80 01 02 84 01 05 ."A........

0x7f7679674740 14:55:35.704 [opensc-pkcs11] reader-pcsc.c:184:pcsc_internal_transmit: called
0x7f7679674740 14:55:35.739 [opensc-pkcs11] apdu.c:187:sc_apdu_log:
Incoming APDU data [ 2 bytes] =====================================

90 00 ..

0x7f7679674740 14:55:35.739 [opensc-pkcs11] apdu.c:399:sc_single_transmit: returning with: 0 (Success)
0x7f7679674740 14:55:35.739 [opensc-pkcs11] apdu.c:552:sc_transmit: returning with: 0 (Success)
0x7f7679674740 14:55:35.739 [opensc-pkcs11] card.c:392:sc_unlock: called
0x7f7679674740 14:55:35.739 [opensc-pkcs11] sec.c:72:sc_set_security_env: returning with: 0 (Success)
0x7f7679674740 14:55:35.739 [opensc-pkcs11] sec.c:54:sc_compute_signature: called
0x7f7679674740 14:55:35.739 [opensc-pkcs11] card-gemsafeV1.c:430:gemsafe_compute_signature: called
0x7f7679674740 14:55:35.739 [opensc-pkcs11] card-gemsafeV1.c:433:gemsafe_compute_signature: error: input data too long: 51 bytes
0x7f7679674740 14:55:35.739 [opensc-pkcs11] sec.c:58:sc_compute_signature: returning with: -1300 (Invalid arguments)


Reply to this email directly or view it on GitHub #508 (comment).

Douglas E. Engert [email protected]

@velter
Copy link
Contributor Author

velter commented Sep 6, 2015

I can send you the full log. But is there a way to send you an attachment ? this is pretty big.

@frankmorgner
Copy link
Member

@velter you could use pastebin or gist...

@velter
Copy link
Contributor Author

velter commented Sep 7, 2015

@dengert
Copy link
Member

dengert commented Sep 7, 2015

The more I look at this, the problem appears to come from the code to add software hashes and the way the code in ./framework-pkcs15.c such as:
3542 case CKM_SHA256_RSA_PKCS:
3543 flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA256;

This causes problems with the flags when trying to do the PKCS on the card.

Can you try doing something like:
openssl dgst -sha256 -binary -out mytest.dgst < mytest

pkcs11-tool -s -m RSA-PKCS --pin XXXXXX
-d 1d228aeee53d5b320aaede6715592afa6491791a
-i mytest.dgst -o sha256.out

This does the the hash externally, then signs it with the card. What it should show is the card
An opensc-debug output would help either way

@velter
Copy link
Contributor Author

velter commented Sep 8, 2015

I tried this. There is no error while creating the signature, but the signature does not verify with

openssl dgst -sha256 -verify pubkey.pem -keyform pem -signature sha256.out mytest

This behavior is the same as with the fix of line 449 in pkcs15-sec.c

I also tried the same with sha1 which also result in a bogus signature

Logs : https://gist.github.com/9eb15d2bac37de2dfffb.git

@dengert
Copy link
Member

dengert commented Sep 8, 2015

A signature requires the hash header and the hash. Which is length 19 + 32 = 51 for sha256.
Without the hash header, the RSA operation is just an encrypt operation of 32 bytes of data.

Without the manual for your card, it is not clear if it can sign a SHA256 hash by doing the padding on the card.
From the OpenSC code for the card, it says the card can not do RAW RSA, but can do padding on the card.

As @frankmorgner pointed out the gclib is using the fact that a decrypt operation passed a padded hash header + hash
can return a signature.

"MSE:Set DST, Decipherment: Cryptographic mechanism reference (0x80) = 0x41, Reference of a private key (0x84) = 0x06"

OpenSC has a number of routines, that can add a hash header, remove a hash header and can also use decipher in place of an sign/encrypt operation,
(pkcs15-sec.c sc_pkcs15_compute_signature at line 423 calls sc_pkcs15_decipher) if the card will allow it...

So if the gclib can do it, OpenSC could do it, but it will take some work and testing to get it to work.

On 9/8/2015 3:18 AM, velter wrote:

I tried this. There is no error while creating the signature, but the signature does not verify with

openssl dgst -sha256 -verify pubkey.pem -keyform pem -signature sha256.out mytest

This behavior is the same as with the fix of line 449 in pkcs15-sec.c

I also tried the same with sha1 which also result in a bogus signature

Logs : https://gist.github.com/9eb15d2bac37de2dfffb.git


Reply to this email directly or view it on GitHub #508 (comment).

Douglas E. Engert [email protected]

@mouse07410
Copy link
Contributor

A very naive question (+ my apologies). Are you sure your public key is in PEM format rather than in DER?

On Sep 8, 2015, at 4:18 , velter <[email protected]mailto:[email protected]> wrote:

I tried this. There is no error while creating the signature, but the signature does not verify with

openssl dgst -sha256 -verify pubkey.pem -keyform pem -signature sha256.out mytest

                                                               ^^^^^^^^^^^^^

This behavior is the same as with the fix of line 449 in pkcs15-sec.c

I also tried the same with sha1 which also result in a bogus signature

Logs : https://gist.github.com/9eb15d2bac37de2dfffb.git


Reply to this email directly or view it on GitHubhttps://github.com//issues/508#issuecomment-138472554.

Uri Blumenthal
[email protected]:[email protected]

@velter
Copy link
Contributor Author

velter commented Sep 8, 2015

@dengert I didn't imagine that this problem will open such a can of worms :(
For myself, I can live with the current behavior. SHA1 is not that bad for what I'm using it for right now. I reach the limit of my knowledge about smartcards, but if you want me to do more tests I can do them. Unfortunatly I have no doc at all about this card.

@mouse07410 yes my pubkey is in PEM format. And I'm sure it's right because

pkcs11-tool -s -m SHA1-RSA-PKCS --pin XXXXXX -d 1d228aeee53d5b320aaede6715592afa6491791a -i mytest -o sha1-2.out
Using slot 1 with a present token (0x1)
Using signature algorithm SHA1-RSA-PKCS
openssl dgst -sha1 -verify pubkey.pem -keyform pem -signature sha1-2.out mytest
Verified OK

openssl dgst -sha1 -binary -out mytest1.dgst < mytest
pkcs11-tool -s -m RSA-PKCS --pin XXXXXX -d 1d228aeee53d5b320aaede6715592afa6491791a -i mytest1.dgst -o sha1.out
Using slot 1 with a present token (0x1)
Using signature algorithm RSA-PKCS
openssl dgst -sha1 -verify pubkey.pem -keyform pem -signature sha1.out mytest
Verification Failure

SHA256 result in the same failure.

@dengert
Copy link
Member

dengert commented Sep 8, 2015

Yes a can of worms... What usually happens is someone with a card ends up writting a driver or making changes, as it is almost impossible to debug code like this without a card.

@l1k
Copy link
Contributor

l1k commented Sep 30, 2015

I've gotten my hands on a GemSAFE V3 card, it's not a Swedish eID card but uses the same applet and exhibits the same problems when signing a SHA256 hash.

Reverse engineering Gemalto's gclib, it turns out the only differences between opensc and gclib are:

  • In the Manage Security Environment command, opensc always sets the algorithm tag to 0x02, whereas gclib sets it to different values depending on the hash algorithm: MD5 is 0x02, SHA1 is 0x12, SHA256 is 0x42.
  • In the Perform Security Operation command, opensc sends the hash with header, whereas gclib sends it without header.

(There are some further differences which I believe to be irrelevant: gclib sends the PIN before MSE, opensc sends it after Compute Digital Signature fails with 0x69 82 and retries PSO plus Compute Digital Signature. gclib reads the hash after sending it, opensc just ignores the 0x61 result. gclib sets Le to 0x00 in the Compute Digital Signature command and receives the whole 256 byte signature from the card, opensc sets Le to 0x80 and receives it in two 128 byte chunks.)

Bottom line: The card seems to be smart enough to prepend the proper header to the hash before signing it and it seems to select the header based on the algorithm tag. This is gclib's mode of use.

Alternatively, the hash is passed with header and the algorithm tag is always set to 0x02. The card will then not prepend a header and sign the data as is. This is opensc's mode of use. Unfortunately this doesn't work with SHA256 hashes, the card always rejects these with 0x69 85 in response to the PSO command.

If we want to emulate gclib's behaviour, we need to adjust the return value of gemsafe_flags2algref() based on the hash algorithm. And it seems the hash algorithm cannot be determined from struct sc_security_env.

Now what? Can we extend struct sc_security_env to contain the hash algorithm that is to be signed?

@l1k
Copy link
Contributor

l1k commented Sep 30, 2015

I just looked at the APDUs sent by gclib once more and realized that it sends MD5 hashes with header but SHA1 and SHA256 hashes without header. This clears up the confusion why gclib uses algo tag 0x02 for MD5 and opensc uses that same tag for all algorithms: 0x02 seems to mean "no header prepended, sign as is".

@l1k
Copy link
Contributor

l1k commented Sep 30, 2015

@dengert wondered above why gemsafe_compute_signature() contains the check if (data_len > 36) even though a SHA1 hash with header is 35 bytes. It looks like the card is able to sign free form data if algo tag 0x02 is used, but there's an upper limit for this of 36 bytes. I've just verified that, signing 36 bytes works, 37 bytes gives the error 0x69 85 (Conditions of use not satisfied). So SHA1 with header fits just within that limit, SHA256 doesn't.

I guess I could hack gemsafe_compute_signature() to send another MSE if algorithm is SHA256, as a workaround to gemsafe_flags2algref() not being able to determine the hash algorithm. But that's kind of a kludge, can anyone think of a better solution?

@dengert
Copy link
Member

dengert commented Sep 30, 2015

Interesting. So in gemsafe_flags2algref
ret = (card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID ||
card->type == SC_CARD_TYPE_GEMSAFEV1_SEEID) ? 0x02 : 0x12;
is really seting what hash is being used based on the card type to either free form or SHA1.

Also look at sc_pkcs15_compute_signature, sc_pkcs15_derive, and sc_pkcs15_decipher.
They all try and determine what needs to be done in software vs hardware, and can call
sc_pkcs1_strip_digest_info_prefix or eventially sc_pkcs1_add_digest_info_prefix from padding.c

There really needs to be more debug information logged from these routines, as they are complicated and hard to understand. Each card has a different path through the code, making it hard to test.

The information you need may already be in the sc_security_env in the algorithm_flags or supported sc_supported_algo_info. More debug info would help.

For some reason line 423 and 424 in pkcs15-sec.c don't look correct to me:

 if ((flags == (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) &&
       !(alg_info->flags & (SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE))) {

They deal with stripping the hash header, but flags may have other bit set.

@l1k
Copy link
Contributor

l1k commented Sep 30, 2015

@dengert:

Interesting. So in gemsafe_flags2algref ret = (card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID || card->type == SC_CARD_TYPE_GEMSAFEV1_SEEID) ? 0x02 : 0x12; is really seting what hash is being used based on the card type to either free form or SHA1.

It's a bit different. One has to differentiate between GemSAFE V1 and V2V3 cards. On GemSAFE V1 cards, the cryptographic mechanism reference to sign free form data is 0x12. On GemSAFE V2V3, it's 0x02. The Swedish eID card seems to be a GemSAFE V3, the Portuguese eID card likewise (judging only by the code.)

I also have an older GemSAFE V1 card here and just verified that opensc uses cryptographic mechanism reference 0x12 with it and sends the hash with header. gclib behaves identically.

Basically on GemSAFE V2V3, gclib behaves differently if a SHA1 and SHA256 hash is signed: It sends those hashes without header to the card and indicates the header to prepend via the cryptographic mechanism reference, which is 0x42 for SHA256 and 0x12 for SHA1.

I think it's a good thing to stay with free form signing, this allows us to support e.g. RIPEMD160 which gclib doesn't support. We only need to special case SHA256. However unless I'm mistaken, opensc is not flexible enough to indicate in the flags that the header needs to be present on all but one hash algorithm. So I think I'll solve this by hacking gemsafe_compute_signature() to check if the algorithm is SHA256, and in that case strip the header and send another MSE to the card with cryptographic mechanism reference 0x42.

@l1k
Copy link
Contributor

l1k commented Oct 1, 2015

A preliminary patch is now at l1k/OpenSC@d1e222b. Kludgy but works.

@l1k
Copy link
Contributor

l1k commented Oct 1, 2015

For a less kludgy solution, we'd need to add new functions to card.c which allow specification of flags when finding algorithms. And likewise we'd need to extend struct sc_security_env by those flags so that the ->set_security_env callback knows what we're trying to do accomplish after the MSE command (i.e. sign a SHA256 hash). Without these changes to opensc core I'm afraid the commit referenced above is the best we can do.

@l1k
Copy link
Contributor

l1k commented Oct 3, 2015

After endless fiddling I've come up with a somewhat less kludgy solution which is at l1k/OpenSC@a3fdc53.

@velter: Please test if this works for you, it does for me.

@dengert, @frankmorgner: Please let me know if you would consider a pull request with this solution. This is the simplest solution I've found that doesn't need changes to opensc core. It involves registering a fake RSA algorithm, the commit message explains this in detail. An alternative solution would e.g. be to extend sc_algorithm_info.u._rsa with an ext_flags member and change register_mechanisms() to OR that to the rsa_flags variable. We'd have to extend _sc_card_add_rsa_alg() to accept this additional variable and we'd have to change all invocations of that function.

Running pkcs11-tool --test returns OK now for all the signing tests (including SHA256) but fails on the first deciphering test. That's because gemsafe_decipher() checks right at the beginning that crgram_len > 255 and with the 2048 bit key on this card, crgram_len is 256. So there's more work to do here.

@frankmorgner
Copy link
Member

Thanks, @l1k, for the detailed and comprehensive problem description in your commit message. I had a similar problem in #419 where the quick solution also was to modify (and break) the upper layers. While your commit is much less intrusive and impressingly small to achieve such a complex operation I think it is not very good to maintain.

I solved my problem with 643080b and I think this would also be the correct (tm) solution for yours: Make the key capabilities explicit instead of using _sc_card_add_rsa_alg as shorthand. For this, you need to make all combinations which the card supports explicit in pkcs15-gemsafeV1.c by initializing p15card->tokeninfo->supported_algos. Although this is a bit cumbersome (because you need to write more code), it allows you to specify all combinations of:

  • hash functions
  • with/without digest info
  • signature/decryption

You may use sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, (struct sc_pkcs15_object **) &object, sizeof object); to extract the private keys from a parsed pkcs15 structure for modification.

@frankmorgner
Copy link
Member

And as bonus, you may even specify the algorithm reference accordingly.

@frankmorgner
Copy link
Member

I forgot to say that you need to link the extracted private keys to p15card->tokeninfo->supported_algos by using something like

                                        switch (object[i]->type) {
                    case SC_PKCS15_TYPE_PRKEY_RSA:
                        prkey_info = (struct sc_pkcs15_prkey_info *) object[i]->data;
                        j = 0;
                        if (prkey_info->usage & SC_PKCS15_PRKEY_USAGE_DECRYPT) {
                            prkey_info->algo_refs[j] = YOURREFERENCE;
                            j++;
                        }

@velter
Copy link
Contributor Author

velter commented Oct 4, 2015

@l1k, I just did the test with my gemsafe card and your patch allow me to successfully sign SHA1 and SHA256 hashs. Thanks for your work.

@l1k
Copy link
Contributor

l1k commented Oct 5, 2015

@frankmorgner: Thanks a lot for your feedback.

The interpretation of the card flags in sc_pkcs15_compute_signature() works just fine, the problem is that register_mechanisms() no longer advertises SHA1, RIPEMD160 and MD5 to the application once SC_ALGORITHM_RSA_HASH_SHA256 is added to the card flags.

After starring at the code for a while I don't see how defining all supported algorithms in p15card->tokeninfo->supported_algos would help here: register_mechanisms() does not honor the supported_algos list. Am I missing something?

For EC algorithms, we already declare an ext_flags member in struct sc_algorithm_info to define additional flags for use by register_mechanisms(). If we had that for RSA algorithms as well, I could use that to signal the missing SHA1, RIPEMD160 and MD5 algorithms to register_mechanisms(). I cannot use the flags member because it has the side effect that algorithms declared there are sent without DigestInfo header (which is what I want for SHA256, but not the other algorithms).

@l1k
Copy link
Contributor

l1k commented Oct 5, 2015

@dengert: Regarding the comment you left on l1k/OpenSC@a3fdc53:

Would a more general fix be to look at the cards algorithm list and have the list define different flags for the sha256?

Well yes, we could solve this by adding multiple RSA algorithms to the list, with the same key_length but different flags. It would look the same as in l1k/OpenSC@a3fdc53, except that the fake algorithm there is only added for key length 512 and we'd also have to add that for 768, 1024 and 2048. And then in sc_card_find_alg() we'd take the flags into account, like this:

                if (flags && !(info->flags & SC_ALGORITHM_RSA_HASH_NONE) &&
                    (info->flags & flags) != flags)
                        continue;
Or do we need a seperate flag to indicate that the hash header should not be sent to the card?
#define SC_ALGORITHM_RSA_NO_HASH_HEADER 0x20000000
This would only be set for SHA256 for the GemSafe cards.

It's the other way round, we'd need an additional PAD flag to indicate that the DigestInfo header needs to be prepended, but the PKCS11 padding is done on the card. We'd need to add that new flag to the algorithm definitions for SHA1, RIPEMD160 and MD5.

That's because sc_pkcs15_compute_signature() determines whether the DigestInfo header should be added based on the absence of the hash algorithm from the flags. On the other hand register_mechanisms() determines whether it should advertise a mechanism to the application based on the presence of the hash algorithm in the flags. (With the exception that if there are no hash algorithms defined in the flags, all are added.)

register_mechanism has comments like:
4639 /*
4640 * Mechanism handling
4641 * FIXME: We should consult the card's algorithm list to
4642 * find out what operations it supports
4643 */

That comment was added by @okirch 13 years ago. What @frankmorgner wrote sounds a bit like he wants to solve this by having register_mechanisms() derive the supported algorithms from p15card->tokeninfo->supported_algos rather than sc_card->algorithms. That would probably solve the FIXME in the comment.

@frankmorgner
Copy link
Member

@dengert What is in the comment is already solved, in my opinion. Unfortunately nobody updated the docs...

@l1k do the following:

  1. announce all Hash functions for all keys, something like:
flags = SC_ALGORITHM_RSA_HASH_SHA1| SC_ALGORITHM_RSA_HASH_MD5|SC_ALGORITHM_RSA_HASH_MD5_SHA1|SC_ALGORITHM_RSA_HASH_RIPEMD160|SC_ALGORITHM_RSA_HASH_SHA1|SC_ALGORITHM_RSA_HASH_SHA256;
_sc_card_add_rsa_alg(card,  512, flags, 0);
  1. modify p15card->tokeninfo->supported_algos as described:
...
token_algos->mechanism = CKM_RSA_X_509; /* raw */
...
token_algos++;
token_algos->mechanism =CKM_RIPEMD128_RSA_PKCS; /* NOT CKM_SHA256_RSA_PKCS */
...

An application (such as pkcs11-tool --test) should do the following:

  1. iterate through all mechanisms announced (raw/pkcs1 from ripemd to sha256
  2. application checks the key's can_do with the combination of padding and hash function
  3. your p15card->tokeninfo->supported_algos says "suported" to every raw hash, but it only says "suported" to pkcs1 padding if the hash function is not sha256.
  4. the signature/decryption operation is performed
  5. goto 1

(I hope, I got all the bits and flags correctly...)

@frankmorgner
Copy link
Member

@l1k maybe this can get you started: frankmorgner@dcbaa3b

@frankmorgner
Copy link
Member

adopting 4734721 in absence of a better solution

@l1k
Copy link
Contributor

l1k commented Dec 14, 2015

@frankmorgner: Apologies, I've been swamped with kernel work plus the usual year-end stress. I'll see to it that I test your proposed solution over the holidays. Thank you!

@l1k
Copy link
Contributor

l1k commented Feb 18, 2016

@frankmorgner: I finally got around to take a closer look at your suggested solution.

First of all, by default the card is bound with sc_pkcs15_bind_internal() instead of sc_pkcs15_bind_synthetic(). Your code is only executed if the latter is used. Thus one has to explicitly enable try_emulation_first = yes.

Second, sc_pkcs15emu_gemsafeV1_init() sends an APDU to the card which looks like this: 80 CA DF 03 08. As it turns out, this command no longer works on GemSAFE V2V3 cards, the card responds with 6E 00 (File not found). On an older GemSAFE V1 card I have here it works fine.

SHA256 signing is only supported by V2V3 cards but not by V1 cards. Since PKCS#15 emulation apparently no longer works with V2V3 cards, I'm afraid the suggested approach is not viable.

Once again apologies for my tardiness and sorry that I couldn't report success for the suggested solution. The (somewhat hacky) patch you've merged is probably the simplest way to solve this given the existing limitations of core libopensc code. (I.e., inability to specify that the hash header needs to be prepended only to some hashes.)

@frankmorgner
Copy link
Member

OK, no problem. Thanks for the feedback!

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

No branches or pull requests

5 participants