Nitrokey HSM 2 with Updated Firmware Can Only Sign Up to 1222 Bytes at a Time

I am using a Nitrokey HSM 2 to sign data with stored keys. On a brand new Nitrokey HSM 2 that has not been updated, it is able to sign as much data (via python-pkcs11) as needed in each sign function call.

But after updating the firmware (SmartCard-HSM Firmware Update), it seems the Nitrokey HSM 2 can only sign up to 1222 bytes at a time.

Why did this happen?

I’m looking to incorporate the Nitrokey HSM 2 as a vital component of a project but this limitation may be a dealbreaker.

are you sure it did work before? which firmware version is old/new?
what is the exact command you are using to sign stuff?
I don’t think you are supposed to sign raw data, only the hashes.

1 Like

So it gets even more interesting…

I have two Nitrokey HSM 2s in my possession:

  1. NKHSM-A which has undergone the “firmware update” via the PKI-as-a-Service and fails to sign the bytes I need
  2. NKHSM-B which has not been updated and successfully signs the bytes I need

The interesting thing is that NKHSM-A shows as being on version 3.6 and does not let me update any further. When I try, I get the message Firmware is already the latest available version (Edit). It might be worth noting that yesterday it was only updating as far as 3.5. Not sure if 3.6 was newly “released” since yesterday since it let me upgrade again from 3.5 → 3.6 today but is not updating any further.

NKHSM-B, on the other hand, which has not been “updated,” is actually on version 4.0. I don’t want to “update” it since I suspect it will stop working correctly similar to NKHSM-A.

As an additional datapoint, I have a colleague who has done the same test on a single Nitrokey HSM 2 (which is how we discovered this issue to begin with) and has the exact same experience, so the issue is not likely isolated to my environment.

Based on all this info, it seems there is not regression in later FW versions, but rather that the PKI-as-a-Service is mistakenly downgrading the FW version.

Please advise on how this can be resolved.

There is no firmware upgrade path from 3.x to 4.x, as this is different hardware (JCOP3 vs JCOP4). There is also no downgrade path, as firmware updates only fix issue. 3.5 to 3.6 and 4.0 to 4.1 is just a fix of a bug when 3K keys are generated with an algorithm list.

The firmware upgrade does not explain the issue with a signing length limitation.

Generally, the device signs the hash value, but there are variants in the middleware used.

How did you access the device (OpenSC, sc-hsm-pkcs11, Java, OCF, Natively) ?


Thanks for checking that @sc-hsm, it definitely adds clarity to the problem but I’d still like to know what’s going on. Or rather, I’d like the guarantee that this does not present itself as an issue with the HSMs I buy in the future.

I used the python-pkcs11 library to do the signing, although it looks like this person had a similar issue which you both were involved in.

We discussed this over e-mail, but you mentioned I did an upgrade from 3.5 to 3.6 on a Nitrokey HSM 2, and another upgrade from 4.0 to 4.1 on a SmartCard-HSM. You’re likely right that I may have accidentally upgraded the SmartCard-HSM instead of the Nitrokey HSM 2 the first time around, which explains my earlier comment:

It might be worth noting that yesterday it was only updating as far as 3.5. Not sure if 3.6 was newly “released” since yesterday since it let me upgrade again from 3.5 → 3.6 today

Sorry, I didn’t want to bring the SmartCard-HSMs into the conversation to avoid confusion, but I guess that happened anyway.

But what I’m concerned about now is that I have some Nitrokey HSM 2s with FW version 4.0 (never tried updating these) and others with FW version 3.6 (these have undergone update).

This brings up a few questions:

  1. Does that mean there’s different Nitrokey HSM 2s being shipped, and some cannot be updated to 4.0+?
  2. Is the culprit a hardware issue or software or both?
  3. How can I guarantee I only get those with 4.0+ when ordering?
  4. Does this same issue affect SmartCard-HSMs?

New devices should always be 4.1, based on JCOP4. We started shipping JCOP4 SIMs in Oct’23.

JCOP4 devices provide more memory for keys and a larger APDU buffer and are slightly faster.

The internal hash+sign method is only meant for small signature inputs. For larger inputs you need to hash before passing the hash into the device (using CKM_ECDSA). OpenSC should automatically do the hash before passing the hash value into the device. This is different in our own PKCS#11 module, that provides a one-to-one mapping of the PKCS#11 to SC-HSM API.

To further diagnose the issue, please provide an OpenSC log by setting OPENSC_DEBUG=9.

1 Like

I think it is clear that it might be not possible to let the card sign data that are larger than the APDU limit.

Can you demonstrate somehow (preferably with the code and the hw/sw configuration) that this has worked before indeed? Maybe the working setup involved different PKCS#11 drivers, their version, OpenSC? For example I could imagine the middleware could hash the input data before handing over to the card.

But for this, we need hard data (exact versions of hw/sw/middleware, the code).

1 Like

I understand that just hashing the data then signing it would avoid this problem completely, but the issue is that we have a system already in place that does the signing of the full data using another HSM which we’re looking to replace with either the SmartCard-HSM or the Nitrokey HSM 2. I am trying to find out in the background whether our larger system has a hard dependency on the signature being generated from the full data or if we can switch to the hash, but I’d like to be prepared if we cannot, hence why I’m trying to weigh my options.

@saper Unfortunately I cannot demonstrate because all the older Nitrokey HSM 2s I have access to have been firmware-updated. We can ignore this angle about the firmware-update possibly causing it to stop working since I’m more interested in the shipped hardware version going forward.

@sc-hsm when you say

New devices should always be 4.1, based on JCOP4. We started shipping JCOP4 SIMs in Oct’23.

are you referring to the Smartcard-HSMs or Nitrokey HSM 2s or both?
I purchased 2 more Nitrokey HSM 2s very recently and they arrived with 4.0, which is perfectly acceptable but conflicts with the statement of new devices being 4.1. At the same time, I ordered 2 Smartcard-HSMs, but those have not arrived yet so I can’t check their versions.

Can either of you give me the guarantee that any Smartcard-HSM and/or Nitrokey HSM 2 I buy in the future will ship with JCOP4 hardware? If so, then we can close on this issue since my problem would be mitigated.

You could tweak OpenSC, so that the hash is always computed by OpenSC. Just comment the lines


from src/libopensc/card-sc-hsm.c#1814.

We actually started shipping SmartCard-HSMs with JCOP4 and V4.0 in Sep’21. Nitrokey is using the JCOP4 chip starting Oct’23. The firmware updates V3.6 and V4.1 were released Feb 28th, 2024.

1 Like

I’d actually like to avoid having to modify any software since the HSMs will not necessarily always interface with the same machine throughout their lifetimes.

You say both SmartCard-HSM and Nitrokey HSM 2 are now shipping with JCOP4. Does that mean there is no chance I end up receiving one with JCOP3 upon purchase going forward?

As a side note, what really is the difference between the the SmartCard-HSM and Nitrokey HSM 2? I have yet to find a definitive answer, but in my experience they are exactly the same except the SmartCard-HSM performs a little faster during my benchmarking, not to mention the difference in the procurement process.

You could specifically ask for a 4.x version, then the secure element will be a JCOP4 chip.

1 Like

Good enough for me. Thank you both!