VeraCrypt encryption with Nitrokey error

I am trying to use the Nitrokey Pro 2 to serve as authentication for Veracrypt containers following these directions. When using PKCS#11 library, I am unable to store the generated Keyfile in Slot ([0] User PIN), only Slot 2 which, while does allow the use of the Nitrokey to decrypt containers, doesn’t require the use of the PIN so all that’s required is the Nitrokey is plugged into the computer. Not ideal, but certainly convenient!

When I went back and tried to use OpenSC, I was (eventually) able to find the right .so file and proceed with the Keyfile generation. When I went to import the keyfile, Slot 0 and Slot 1 were both available! However, even the 64 bit keyfile returned the following error:

The security token does not have enough memory/space to perform the requested operation.

If you are attempting to import a keyfile, you should select a smaller file or use a keyfile generated by VeraCrypt (select 'Tools' > 'Keyfile Generator').

I’m unsure what to do at this point. I’m assuming that means that I cannot use any file in Slot 0. Out of curiosity, I also tried to use a text file of the exported public key that is already on my Nitrokey and it returned the same error.

Ideally, I’d like to be able to have a VeraCrypt container that can be decrypted using the Nitrokey with the input of my PIN, but if I can’t use the PIN I guess just the Nitrokey alone will suffice.

Any suggestions would be appreciated!

The “keyfile protected by the PIN” part should be addressed within https://github.com/veracrypt/VeraCrypt/issues/689 (though there seems to be no easy way given the limitations).

As for the other part (storing the keyfile) - I personally had no troubles doing that on Pro and Windows 10 using OpenSC-provided PKCS#11 lib. Care to describe your actions step by step to see what could be wrong here?

Yeah for sure! This is all with my Nitrokey Pro 2 plugged in.

  1. In VeraCrypt, I go to Settings > Security Tokens and select /the/filepath/to/opensc-pksc11.so (I assume that opensc-pksc11.so is the right file, it matches the format for the regular pksc11 file but this could be the issue and I just need to know the right replacement.)
  2. Tools > Keyfile Generator and use the default settings (Mixing PRF is set to SHA-512, Number of keyfiles is 1, Keyfile size in bits is 64) and save.
  3. Tools > Manage Security Token Keyfiles and select the keyfile

I then get the error mentioned above that the security token doesn’t have enough memory/space.

This ONLY occurs when I have the opensc-pksc11.so selected in step 1 and am trying to set it to Slot [0] or Slot [1]in step 3 (the only slots available to me when I use the opensc-pksc11.so). If I use the regular PKSC#11 library .so (also mentioned in the Nitrokey applications section) I’m only able to select Slot [2], which lets the same file be used without the error.

If there’s any other information that will help, please let me know! I’m using the latest Nitrokey firmware, VeraCrypt 1.24-Update4, and am doing this on a System76 laptop running Pop_Os (their version of Ubuntu 20.04).

That’s a bit too old and I’d recommend to update, however this is not the root cause - current git also has that - on Linux, as I now understand from your additional description.

FWIW here’s the error message I get when trying to import the keyfile (and it doesn’t matter if the existing keyfile is deleted before that). I didn’t have that on Windows, but seemingly Linux is different (or it’s introduced after Update7 release - that’s what I tested on Windows vs git tip on Linux).

image

@gonzalothought, this actually looks like a bug, though I’m not sure where (NK or VC or maybe OpenSC - but IMHO NK is the least likely reason), so some additional debugging will be needed. Unless someone chimes in sooner, I will try to get to that on the next weekend - unlikely to be able to do this earlier than that, sorry.

1 Like

Upon further look, the Windows version actually does this as well, so there’s no difference.

The root cause (at least in my test case - the original description in this thread is slightly different, but my educated guess is that it’s the same thing) is around the deletion of the existing data in DO1 not being recognized until OpenSC’s PKCS#11 library is re-initialized. It goes like this:

  1. If there’s already a keyfile (or any other data) in the DO - the OpenSC will return the “no space available” PKCS#11 error that results in the corresponding VC error the OP and I posted earlier.
  2. VC has a “Delete” button in the token/keyfile management window that allows for removing keyfiles from the token and clicking it generates proper delete sequence in OpenSC and the Nitrokey’s smartcard confirms deletion.
  3. However if you try to import a keyfile immediately after that (after all, you’ve just freed the space, right?), it will again fail with the same “no space available” error, because that’s what OpenSC will return - based on my debugging, sc_read_binary() still returns non-zero here.
  4. If you however restart the VC (and that will reinitialize the OpenSC underneath) - the deletion is now recognized and you can import the file just fine. Same happens if I insert the PKCS#11 C_Finalize()/C_Initialize() sequence into the VC’s token file deletion function - so apparently that’s the key here (just closing the session with the token is not enough).
  5. Using command-line pkcs11-tool works fine, because you can’t delete and write a DO in the same command invocation, so OpenSC is always reinitialized between those two operations.

So the workaround is just to restart VeraCrypt after deleting the existing keyfile from the token, before importing a new one.

I’ve run out of time today to find the actual root cause, but essentially there seems to be some caching going on within OpenSC and I’m not yet sure whether it’s a PKCS#11 requirement to do a reinit like that (that would mean a bug in VeraCrypt - but I see nothing like that in the PKCS#11 standard yet) or there’s a bug in OpenSC - I’ll look further into that. However the Nitrokey’s fault is almost excluded, unless there’s a very peculiar situation where it confirms the deletion, but doesn’t actually do it until OpenSC reinitialization triggers it, which sounds too artificial to me to be true.

Stay tuned 8)

All right, so there’s indeed a bug in OpenSC where a blob update logic creates a state discrepancy after deletion: the object is deleted on the card, but the OpenSC’s blob itself it not updated, so the test read upon the next attempt to save the keyfile returns non-zero data as if it’s still there.

I’ve submitted a proposed fix in OpenSC pull request at https://github.com/OpenSC/OpenSC/pull/2215.

1 Like

Thank you so much! I’d never have figured any of this out. I’ll try your workaround later today and let you know how it goes.

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐

JFYI, the OpenSC PR got merged, so the next release should have the fix and no longer need a workaround.

1 Like

I got an email that this thread was referenced again. I upgraded my OpenSC to 0.22 and… it’s not flawless but I think I got it to work?

The issue seems to be that Veracrypt doesn’t always register that I have my NK plugged in or that the keyfile is present. I’ve tried it with the password vault both locked and unlocked and neither seems to make a difference. And I can certainly see that the keyfile is present (using gpg --card-status). But there are times when the token shows in Veracrypt and it doesn’t work, and other times when it doesn’t show at all, and occasionally it shows and actually works.

I’ll have to play around with it more to see if there’s an actual consistent method, but for the time being I’m definitely keeping backups of all the containers without the need for the keyfile until I figure this out lol.

Thank you so much for your help!

1 Like

@gonzalothought In case you are using Linux and GnuPG older than 2.3.x, the latter might compete over the Nitrokey with OpenSC, and either can lock it making the other one not able to reach it. If so, for your use case you may need to stop the GnuPG’s scdaemon by calling:

$ gpgconf --kill scdaemon

After that OpenSC should be able to connect.

1 Like