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

PKCS11 function C_SignFinal failed: rv = CKR_ARGUMENTS_BAD with PKCS#15 Card [CardOS V5.3] using 3072 bit RSA key #1764

Closed
saper opened this issue Aug 7, 2019 · 5 comments · Fixed by #1776

Comments

@saper
Copy link
Contributor

saper commented Aug 7, 2019

Problem Description

Using opensc 0.19.0 with pcsc-lite 1.8.24,2 on FreeBSD 11.2-STABLE

Applied a small patch to get key length 3072 and 4096 recognized and get some extra debug output:

--- src/libopensc/card-cardos.c.orig    2018-09-13 11:52:42 UTC
+++ src/libopensc/card-cardos.c
@@ -239,6 +239,8 @@ static int cardos_init(sc_card_t *card)
        }
 
        if (card->type == SC_CARD_TYPE_CARDOS_V5_0) {
+               _sc_card_add_rsa_alg(card, 3072, flags, 0);
+               _sc_card_add_rsa_alg(card, 4096, flags, 0);
                /* Starting with CardOS 5, the card supports PIN query commands */
                card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO;
        }
@@ -888,6 +890,7 @@ cardos_compute_signature(sc_card_t *card
        assert(card != NULL && data != NULL && out != NULL);
        ctx = card->ctx;
        SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
+       sc_log(card->ctx,  "datalen/outlen/max %zd/%zd/%d", datalen, outlen, SC_MAX_APDU_BUFFER_SIZE);
 
        if (datalen > SC_MAX_APDU_BUFFER_SIZE)
                LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);

I try to sign the following uuencoded bytes:

begin 644 COPYRIGHT.hash
MIUF]LQ'?J!%"LOTGV]28=<X(>U>XR!`_X^8#P(#WSKVRRSD4P%73")*]L,!&
3FLE%NQ;J%6QK(_$$PPKT'E,5Y```
`
end

My opensc.conf:

app default {
        debug = 4;
        debug_file = /home/saper/pki/cardos/opensc-debug.txt;
        reader_driver pcsc {
                max_send_size = 32767;
                max_recv_size = 32767;
        }
}

My test script:

script /home/saper/pki/cardos/cardlog env OPENSC_CONF=/home/saper/pki/cardos/opensc.conf /usr/local/bin/pkcs11-tool -m SHA384-RSA-PKCS  -i /tmp/COPYRIGHT.hash -o /tmp/COPYRIGHT.sign -s -vvvv

Output in the cardlog file:

Script started on Wed Aug  7 10:58:41 2019
Command: env OPENSC_CONF=/home/saper/pki/cardos/opensc.conf /usr/local/bin/pkcs11-tool -m SHA384-RSA-PKCS -i /home/saper/pki/cardos/COPYRIGHT.hash -o /home/saper/pki/cardos/COPYRIGHT.sign -s -vvvv
Using slot 0 with a present token (0x0)
Logging in to "CardOS V5.3 | EC0025873".
Please enter User PIN: 
Using signature algorithm SHA384-RSA-PKCS
error: PKCS11 function C_SignFinal failed: rv = CKR_ARGUMENTS_BAD (0x7)
Aborting.

Command exit status: 1
Script done on Wed Aug  7 10:58:49 2019

If I don't patch OpenSC as above, I am getting CKR_FUNCTION_NOT_SUPPORTED instead.

Proposed Resolution

Looking at my extra debug line added by a patch above:

0x803016000 10:58:49.925 [opensc-pkcs11] card-cardos.c:893:cardos_compute_signature: datalen/outlen/max 384/512/261

https://gist.github.com/saper/9febbea30f9e0fb57e4599f3b102378c#file-opensc-debug-redacted-txt-L1425

I think the problem is with too small buffers for the signing operation with larger keys.

Steps to reproduce

as above

Card identification:

> /usr/local/bin/cardos-tool -i
Using reader with a card: Gemalto USB Shell Token V2 (457FF72B) 00 00
3b:d2:18:00:81:31:fe:58:c9:03:16
Info : CardOS V5.3, 2014
Serial number: 02 08 c1 1a 00 06 32 3b
OS Version: 201.3 (that's CardOS V5.3)
Current life cycle: 16 (operational)
Security Status of current DF:
Free memory : 496
ATR Status: 0x0 ROM-ATR
Packages installed:
Ram size: 7, Eeprom size: 83, cpu type: 78, chip config: 63, chip manufacturer: 5
Free eeprom memory: 72943
Current Maximum Data Field Length: 640
Complete chip production data:
CC 78 33 CE 01 00 01 00 0E 00 00 01 0B 02 00 00 .x3.............
00 00 00 00 00 00 00 61 75 38 30 FF FF FF FF 78 .......au80....x
01 51 41 78 05 16 07 00 00 83 12 05 E7 55 21 02 .QAx.........U!.
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00             ............
System keys: PackageLoadKey (version 0x00, retries 10)
System keys: StartKey (version 0xff, retries 10)
Path to current DF:
50 15 P.

Logs

https://gist.github.com/9febbea30f9e0fb57e4599f3b102378c

@dengert
Copy link
Member

dengert commented Aug 7, 2019

It looks like the problem is with line 873: u8 buf[SC_MAX_APDU_BUFFER_SIZE]; which is large enough for only RSA 2048. And line 884: if (datalen > SC_MAX_APDU_BUFFER_SIZE) which tests for that size.

See if you can get farther by defining u8 buf[4096]; and changing 884 to if (datalen > sizeof(buf)) If that works, a better fix could be provided based on what size the code actually needs.
There may be other places in the code that has similar problems.

The card is capable of doing extended APDUs. card->caps |= SC_CARD_CAP_APDU_EXT; so that should work.

@saper
Copy link
Contributor Author

saper commented Aug 7, 2019

I've tried that (I've put 1000 instead of SC_MAX_APDU_BUFFER_SIZE), but then we get datalen less than outlen and those are just parameters.

@dengert
Copy link
Member

dengert commented Aug 7, 2019

Di you have a new debug log?
Where is test for datalen less than outlen that is now failing?

Based on you first debug log lines 1424-26:

0x803016000 10:58:49.925 [opensc-pkcs11] card-cardos.c:892:cardos_compute_signature: called
0x803016000 10:58:49.925 [opensc-pkcs11] card-cardos.c:893:cardos_compute_signature: datalen/outlen/max 384/512/261
0x803016000 10:58:49.925 [opensc-pkcs11] card-cardos.c:896:cardos_compute_signature: returning with: -1300 (Invalid arguments)

In git master code:

        SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

        if (datalen > SC_MAX_APDU_BUFFER_SIZE)
                LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
        if (outlen < datalen)

Your diff has:

@@ -888,6 +890,7 @@ cardos_compute_signature(sc_card_t *card
        assert(card != NULL && data != NULL && out != NULL);
        ctx = card->ctx;
        SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
+       sc_log(card->ctx,  "datalen/outlen/max %zd/%zd/%d", datalen, outlen, SC_MAX_APDU_BUFFER_SIZE);
 
        if (datalen > SC_MAX_APDU_BUFFER_SIZE)
                LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);

It look like failure in first debug log is from if (datalen > SC_MAX_APDU_BUFFER_SIZE) Was this line changed in code?

frankmorgner added a commit to frankmorgner/OpenSC that referenced this issue Aug 28, 2019
@frankmorgner
Copy link
Member

please check if #1776 fixes the problem

@saper
Copy link
Contributor Author

saper commented Aug 28, 2019

Yes, now it works, thanks! I don't know how to verify the signature though.

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

Successfully merging a pull request may close this issue.

3 participants