carblue / acos5

ACS ACOS5 Smart Card / CryptoMate64 / CryptoMate Nano: Driver and pkcs15init shared libraries for the OpenSC framework.
GNU Lesser General Public License v2.1
13 stars 3 forks source link

This file id will be chosen for the private RSA key: #7

Closed johughes99 closed 3 years ago

johughes99 commented 3 years ago

My key generation tests are working fine - but when I generate a RSA key pair I'm getting the following displayed on the console

This file id will be chosen for the private RSA key: XXXXX

is this some debug output?

carblue commented 3 years ago

That is just to inform the user. I like to have that info. If You don't like that, then You can easily comment-out the source code lines responsible: Locate in file ~/path/to/acos5_root_downloaded/acos5_pkcs15/src/lib.rs the 2 lines that are responsible by searching text This file id will be chosen and place 2 consecutive slashes // in the beginning of those lines and rebuild the driver. In my current master the lines are:

$ grep -rn 'This file id will be chosen'
...
acos5_pkcs15/src/lib.rs:628:    println!("This file id will be chosen for the private RSA key:  {:X}", fid_priv_possible_min);
acos5_pkcs15/src/lib.rs:658:    println!("This file id will be chosen for the public  RSA key:  {:X}", file_pub.id);

Note that I never managed to generate with CryptoMate Nano RSA modulus len > 3328, see subject C_GenerateKeyPair failure with ACS CryptoMate (T2), ...shouldwork.html#0x072F0xB106 Carsten Blüggel in http://lists.infradead.org/pipermail/pcsclite-muscle/2017-April/subject.html the "final" answer by Godfrey Chung

johughes99 commented 3 years ago

OK,

I have generated 4096 RSA keys fine - and also used the private key to sign data. Although got some other issue going on with CKA_ALWAYS_AUTHENTICATE - which I need to dig into.

carblue commented 3 years ago

I forgot to mention: My german ACS supplier did send that ACOS5-Cyptomate Client Kit v4.5 (as I had bought one before) and I did re-initialize, but that didn't change anything about the problem, so my conclusion was: ACS doesn't seem to want to disclose the reason for that limitation or ? Hence my driver implements that limit (only for V3.00/CryptoMate Nano; CryptoMate64 is capable to generate 4096 bit RSA keys)

johughes99 commented 3 years ago

Just looked. My client kit is v4.6.0.3

johughes99 commented 3 years ago

OK,

I have generated 4096 RSA keys fine - and also used the private key to sign data.

carblue commented 3 years ago

OK, thanks, that's good to know, so I can remove the "CryptoMate Nano" limitation from code line

    let     rsa_key_len_to   : u32 = if is_fips_compliant && card.type_==SC_CARD_TYPE_ACOS5_64_V3 { 3072 } else { 4096 };

which seems to apply only when generating keys via opensc-pkcs11.so, but not via pkcs15-init --generate-key

I assume You initialized Your CryptoMate Nano with card_initialization.scriptor line

## If it's an ACOS5-64 V3.00 (Smart card or CryptoNano) the next sets 64K mode:
00 D6 C1 91 01 02

The other choice would have set it to FIPS 140-2 Level 3-Compliant mode. There is some uncertainty in the reference manual what exactly triggers the limitation: Whether its the FIPS mode (Operations Mode byte) on its own or additionally the card content actually being FIPS compliant according to the long list of requirements to be satisfied (last chapter "9.0. FIPS Mode File System Requirements" in reference manual; actually I never succeeded to set up my CryptoMate Nano as FIPS compliant such that the respective card command "Verify FIPS Compliance" reports success. It always ended in some undocumented error codes, and after having lost 1 USB token due to irreversible being read-only by some COS bug, I gave up and concentrated solely on the 64K mode)

So I consider my CryptoMate64 being the better (supported and reliable) hardware than CryptoMate Nano, and I'm eagerly awaiting the new CryptoMate EVO from my supplier, which will hopefully eliminate some other deficiencies of ACOS5-64 (mainly, that card's signature operation acc. PKCS#1 supports only SHA-1 and SHA-256). Didn't You wonder why You can sign SHA-512 hashes? Well, it's a lot of workaround code required to securely perform RSA signing by RSA decryption in this case (i.e. for SHA-512 hashes not using the card function dedicated to compute signature, but using raw RSA exponentiation, and the key must be created with capability sign+decrypt for a sign-only key ! Firefox, Thunderbird, ssh, they all prefer to use the SHA-512 hashes nowadays. The "verified FIPS Mode" introduces another complication. Again, as the ACS tool initialization does, it restricts access to SE files (what a nonsense to require a PIN for that, what has fixed content and is publicly disclosed: And it would require more workaround code to work with OpenSC/my driver; I believe it's more secure to require a legitimation only for important actions, like OpenSC does)

From the reference manual: October 2015 ACOS5-64 revision 3.00 • FIPS140-2 Level 3–certified o Secure Key/PIN entry o RSA Key Generation, Signature 2048 and 3072 o 3DES o Key data Zeroization o FIPS approved Deterministic Random Number Generation • Operations Modes: o ACOS5-64 FIPS 140-2 (Default) o ACOS5-32 mode o ACOS5-64 v2.00 mode o ACOS5-64 NSH-1 mode Table 1: History of Modifications

johughes99 commented 3 years ago

Seems you can remove that line.

Yes I initialized using that scriptor file and uncommented the V3.00 line

As said I have an EVO - so it would be great to get that to work. What do I need to do?

BTW your email address is not in the cargo.toml address

carblue commented 3 years ago

I will move printing "This file id will be chosen for the ..." into a conditionally compiled block such that everybody can choose yes/no whether that gets printed, default: no.

The max. RSA modulus bit length with CryptoMate Nano still is a mystery to me. My assumption is, when I set Operations Mode "ACOS5-64 v2.00 also named 64K" as You did, then it behaves like a CryptoMate64 which unconditionally allows RSA/4096. But our tokens behave differently in same Operations Mode. Perhaps You can help me with that by comparing Your debug log with mine: Within the first 85 lines there is the call to get_cos_version and the last line reported here is my tokens answer (8+2 bytes):

P:3614; T:0x140083104534400 17:10:04.713 [opensc-tool] acos5:235:get_cos_version: called
P:3614; T:0x140083104534400 17:10:04.713 [opensc-tool] apdu.c:761:sc_bytes2apdu: Case 2 short APDU, 5 bytes:    ins=14 p1=06 p2=00 lc=0000 le=0008
P:3614; T:0x140083104534400 17:10:04.713 [opensc-tool] apdu.c:546:sc_transmit_apdu: called
P:3614; T:0x140083104534400 17:10:04.713 [opensc-tool] card.c:473:sc_lock: called
P:3614; T:0x140083104534400 17:10:04.713 [opensc-tool] reader-pcsc.c:684:pcsc_lock: called
P:3614; T:0x140083104534400 17:10:04.713 [opensc-tool] card.c:513:sc_lock: returning with: 0 (Success)
P:3614; T:0x140083104534400 17:10:04.713 [opensc-tool] apdu.c:513:sc_transmit: called
P:3614; T:0x140083104534400 17:10:04.713 [opensc-tool] apdu.c:363:sc_single_transmit: called
P:3614; T:0x140083104534400 17:10:04.713 [opensc-tool] apdu.c:370:sc_single_transmit: CLA:80, INS:14, P1:6, P2:0, data(0) (nil)
P:3614; T:0x140083104534400 17:10:04.713 [opensc-tool] reader-pcsc.c:323:pcsc_transmit: reader 'ACS CryptoMate (T2) 00 00'
P:3614; T:0x140083104534400 17:10:04.713 [opensc-tool] reader-pcsc.c:324:pcsc_transmit: 
Outgoing APDU (5 bytes):
80 14 06 00 08 .....
P:3614; T:0x140083104534400 17:10:04.713 [opensc-tool] reader-pcsc.c:242:pcsc_internal_transmit: called
P:3614; T:0x140083104534400 17:10:04.722 [opensc-tool] reader-pcsc.c:333:pcsc_transmit: 
Incoming APDU (10 bytes):
41 43 4F 53 05 03 01 40 90 00 ACOS...@..

From ref. manual Card OS Version: Card OS version is returned as 8 bytes with the following information. ACOS5 Revision XX.YY ZZ (41 43 4F 53 05 XX YY ZZh). XX is the major version YY is the minor version ZZ is the user EEPROM capacity in kilobytes

So my minor version is 01. What is Yours? maybe that makes a difference? or perhaps I just got EAP/beta hardware/firmware (I observed it was always slower than CryptoMate64). I insist in clarifying that, because it's no fun letting users experience the same things I have seen, including severe errors while generating large RSA keys, including card data corruption unrelated to key generation and finally having lost a token.

BTW there is acos5/Cargo.toml

ACOS5 EVO Well, it's out since ~ 1.5 years now (as card version) and since I have a REF-ACOS5-EVO-1.03.pdf covering ACOS5-EVO revision 4.00 and revision 4.10, but I'm still waiting for latest revision 4.20 reference manual and CryptoMate-EVO. It's announced to arrive this month. The step in adding driver support for Nano was small, but the step for adding full EVO support will be huge: A lot changed, some additions like Elliptic Curve Cryptography (I'm not familiar with that so far) and many many minor to major modifications (e.g. subtle ones like different algorithm encodings), a major one being e.g. support of extended ADPU syntax as default and also the previous (short APDU syntax) as supported by ACOS5-64. Some is covered already but more or less arbitrary as I came along. It needs a systematic go-through-the-manual (185 pages) and implement/modify as required. That's complicated given that the driver shall support 3 hw versions (V2.00, V3.00, V4.X + possibly its sub-versions) and a couple of OpenSC versions (Linux distributions tend to lag behind the current version substantially). Another major task is to test as the past experience has shown: Not all works as documented by ACS, or may be undocumented at all and needs to be figured out by trial and error. Hence this will take some time and I'm eagerly awaiting to operate a CryptoMate EVO with my driver, apparently same as You do.

Ref. "What do I need to do?" If You expect some quick instructions to put Your EVO to work seamlessly as Your Nano obviously does, then I need to beg you to be patient for a few more ...s. If You are willing to support/help/contriute/cooperate, then there are various ways to do so and I appreciate any kind, You don't need to be a Rust developper. E.g.

  1. The first thing to clarify are the EVO ATRs that the driver shall recognize as EVO card With Your EVO (and nothing else) plugged in You can run $ opensc-tool --atr

Inform me about Your EVO ATR and copy/paste that into https://smartcard-atr.apdu.fr/

Dr. Ludovic Rousseau is the maintainer, the (co-)author of pcscd, libpcsclite1, pcsc-tools, libccid and more. If that finds the ATR in his smartcard_list.txt, then fine, nothing else to be done here and it will/is supported already by libccid. Otherwise, please visit https://ccid.apdu.fr/ section "Check reader's compliance to CCID specification" and send to him the generated output.txt file. That's the fastest way to get CryptoMate EVO supported by libccid (I would like to have CryptoMate EVO/Smart Card EVO support from there and not depend on an additional installation from https://www.acs.com.hk/en/products/494/cryptomate-evo-cryptographic-usb-tokens/ Downloads Driver or https://github.com/acshk/acsccid)

There was https://github.com/carblue/acos5/issues/4 which probably is an EVO, but erroneously identified as V3.00 in libccid/smartcard_list.txt/https://smartcard-atr.apdu.fr/ I asked him to check/correct, but no reply so far

  1. When Your ATR is known to me and matching in my driver works for Your EVO, then we can start together some testing how far You can get: First again, as before, I need cards answer to get_cos_version (8 bytes). This will take part in match_card code, possibly required to identify a sub-version. Then next, You test some command(s), report what happened/errored, send me Your opensc-debug.log with comment which was the command tested such that I can relate that exactly to which part/time of log and possibly I can quickly adapt code and remove first obstacles. Maybe its that easy to get some solid ground.
johughes99 commented 3 years ago

I will have a look at this in the morning

For some reason my Nano stopped working doing signing with RSA - kept getting CKR_GENERAL_ERROR. So have had to re-nit the device again - and that worked fine and cleaned the error. I wondered whether that was a memory full issue. I have noticed that very few tokens actually report back the proper error of CKR_DEVICE_MEMORY.

johughes99 commented 3 years ago

opensc-debug.log

Here is the debug log with the info you need.

RE helping on Evo - I'm pretty busy with other stuff for 3 to 4 weeks - but do not mind helping out. I'm not familiar with rust at all. I'm more of a C/C++ and Java guy (with a bit of python)

carblue commented 3 years ago

Not yet studied Your debug-log.

"memory full issue" With my next commit You'll have a print to console (short before finishing driver process) about memory consumption

    if #[cfg(finish_verbose)] {
        println!("EEPROM remaining free memory space: ~ {} of {}, in kB", get_free_space(card).unwrap()/1000_u32,
            if card.type_> SC_CARD_TYPE_ACOS5_64_V3 {192} else {64});
...
    }

You can switch-off that in file acos5/build.rs by commenting-out/placing 2 consecutive slashes // in the beginning of line

    println!("cargo:rustc-cfg=finish_verbose"); // enable to print to console some info short before finishing driver process (see function acos5_finish)

"very few tokens actually report back the proper error of CKR_DEVICE_MEMORY" I've never run into card memory errors (EEPROM remaining free memory space: ~ 40 of 64, in kB). With OpenSC based tokens, that's the responsibility of OpenSC framework code, not of any specific driver. These can only marginally influence in that what they return as error. Many do (so does acos5_external as well) use function iso7816_create_file https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/iso7816.c The included r = sc_check_sw(... maps card's status word (response code) to some static const struct sc_card_error iso7816_errors[]

ACOS5 reference manual documents (among others) an error code 6A84h Not enough free space in the card to create file thus the mapping is - besides an exact wording - okay with { 0x6A84, SC_ERROR_NOT_ENOUGH_MEMORY, "Not enough memory space in the file" },

johughes99 commented 3 years ago

One of my many test groups for PKCS#11 tokens is to determine the capacity of the device. So basically I loop around generating key pairs of different types - then delete them all. I try private tokens, public session etc etc for both EC and RSA (depending on what is supported) - and different key sizes.

quite illuminating - some tokens have different sizes depending on whether its token or session keys. Many also have a fixed number of key pairs that obviously is hard coded into the firmware

carblue commented 3 years ago

I did communicate 48 RSA key pairs, which is arbitrary, the real/actual limit is free user-available EEPROM memory. My calculation was: Given that with ACOS5 (and my driver setting ChineseRemainderTheorem mode to store priv. key data) an RSA/4096 bit key pair requires RSAPUB_MAX_LEN (533) + RSAPRIV_MAX_LEN_CRT(1285) = a total of 1818 bytes, then ACOS5-64 allows max. 35 such keys, in reality less due to some inevitable memory requirement for PKCS#15 files and iEF files etc. (not yet measured), and some more, if smaller bit length are used. So I settled with figure 48, witch fits nicely into (0x4200 -0x41A0)/2 But that figure and file id organization needs to be reviewed with EVO (192 kB + ECC key pairs) anyway.

277+645= 922 bytes total for RSA/2048 allowing max. 69 minus x (less than RSA/2048 is not recommended anyway). Maybe Your testing runs into problems with my current file id organization, because more smaller keys are possible (from EEPROM mem. view) than reserved by my file id organization.

ACOS5 does not support session objects as defined by hhonkanen. My understanding of session objects(i.e. CKA_TOKEN==CK_FALSE) is: They get stored to card temporarily (erased in function finish or next call to init ?) but there will be no entries in EF.PrKDF/EF.PuKDF. OpenSC handles updating latter mentioned files autonomously, deleting (if full) and re-creating larger sized ones. Thus it's absolutely okay when "some tokens have different sizes depending on whether its token or session keys". Note that You can't currently rely on CKA_EXTRACTABLE in OpenSC PKCS#11layer. More via eMail.

johughes99 commented 3 years ago

My tests demonstrated 13 key pairs - not matter what size

Most products I have tested (and I have tested over 10 - and a lot which don't use OpenSC) have the same number of keys pairs for both token and session keys. The one exception is MIRkey.

When I get a chance I will let my tool go through my PKCS#11 tests - and see what happens. Then its tryingt o determine e whether its a openSC bug or a device specific bug. I will send you the user manual of my tool

carblue commented 3 years ago

I experienced the same "problem": No new 14th RSA key pair generatable, or more precisely, a 14th RSA key pair generation actually succeeded (and there is free EEPROM memory for many more), but EF.PrKDK unused/free space is exhausted (can not hold data of 14th key). card_initialization.scriptor did assign a file size of 0x300 for EF.PrKDK. With ACOS5, file size can't be enlarged, but the file needs to be deleted and re-created with a larger size. I've seen in the past, that OpenSC was capable to do that, but here it stopped with error -1510 (File too small)

pkcs15-lib.c:4013:sc_pkcs15init_update_file: File 3f0041004110 too small (require 775, have 768)
pkcs15-lib.c:4015:sc_pkcs15init_update_file: Update file failed: -1510 (File too small)
pkcs15-lib.c:3147:sc_pkcs15init_update_any_df: Failed to encode or update xDF: -1510 (File too small)
pkcs15-lib.c:3212:sc_pkcs15init_add_object: returning with: -1510 (File too small)
pkcs15-lib.c:1553:sc_pkcs15init_generate_key: Failed to add generated private key object: -1510 (File too small)

I need to dig into that ...

carblue commented 3 years ago

Solved: 37 RSA/3072 key pairs generated until EEPROM free space is exhausted. Error code -1217 (Not enough memory on card) 52 RSA/2048 key pairs generated until EEPROM free space is exhausted. " 65 RSA/512 key pairs generated until "hard" limit in OpenSC applies: #define MAX_OBJECTS 128 in framework-pkcs15.c That results in an error code -1405 SC_ERROR_TOO_MANY_OBJECTS

carblue commented 3 years ago

Scrub all I've told about generating RSA/4096 with CryptoMate Nano in mode 64K: Encouraged by Your success in generating RSA/4096 key pairs, I dared once more, in a batch run,, after a card re-initialization:

28 RSA/4096 key pairs generated until EEPROM free space is exhausted. Error code -1217 (Not enough memory on card)

So, what the heck was going on before, resulting in failures? Note well, success in generating RSA/4096 key pairs is possible with CryptoMate Nano only in "Operation Mode 64K" and I would swear my card was in that mode when it failed, but ??? Of course, for testing reasons, I often did switch op. modes in card re-initializations: Perhaps once it happened, that the card internally didn't accept the new operation mode setting? Whatever it was, we shall never know, but it works now as expected.

Again, as before, there is an enormous spread/variance in generation times, from ~ 1 to15 minutes.

new function check_enlarge_prkdf_pukdf: