veracrypt / VeraCrypt

Disk encryption with strong security based on TrueCrypt
https://www.veracrypt.fr
Other
6.77k stars 937 forks source link

Expand the list of available slots of token keyfiles for use with Yubikey PIV to more than the 3 slots shown #889

Open ghost opened 2 years ago

ghost commented 2 years ago

Desired behavior

I would like to be able to use more than 2 keyfiles on the Yubikey, so that I can apply each to a different Veracrypt container.

The Veracrypt > Tools > Manage Security Token Keyfiles dialog only shows 3 slots:

With a Yubikey 5 NFC, I'm able to put keyfiles in Fingerprints and Facial Image. Printed Information seems to already contain data written by Yubikey Manager if you Generated PIV certificates with it, so may not be a safe place to store keyfiles as it may get overwritten. This leaves only 2 usable slots displayed in the Veracrypt dialog.

There are several other unused slots on the Yubikey, such as Cardholder Iris Images, Discovery Object, Retired X.509 Certificate for Key Management. I wonder if it's possible for Veracrypt to show these slots in the dialog. However, I'm not sure if this is a limitation by specification. I'm using OpenSC PKCS11 library. But Iris Images which doesn't show, is similar to Fingerprints which shows, except for Iris Images being an optional slot by specification.

I had a look at the Veracrypt code in:

src/Common/SecurityToken.cpp
src/PKCS11/pkcs11f.h

SecurityToken::GetAvailableKeyfiles
SecurityToken::GetTokenSlots
Pkcs11Functions->C_GetSlotList

I was wondering if tokenPresent being TRUE instead of FALSE would have an effect, but Fingerprints is also empty by default and still shows in the dialog. There is also the !(slotInfo.flags & CKF_TOKEN_PRESENT) which I'm not sure is related.

CK_RV status = Pkcs11Functions->C_GetSlotList (TRUE, NULL_PTR, &slotCount);
status = Pkcs11Functions->C_GetSlotList (TRUE, &slotArray.front(), &slotCount);

CK_BBOOL       tokenPresent,  /* only slots with token present */

if (status != CKR_OK || !(slotInfo.flags & CKF_TOKEN_PRESENT)) continue;

I'm also unsure if any of these other functions have an effect:

SecurityToken::GetObjects 
Pkcs11Functions->C_FindObjects 

SecurityToken::GetObjectAttribute 
Pkcs11Functions->C_GetAttributeValue 

I also wonder if the 4 main certificate slots could be used if sure of not using them for any other purposes and won't be overwritten. Although the access rules are "always" instead of "PIN", which I'm not sure of the meaning.

The table below was copied from the specifications PDF: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf Untitled-2

Your Environment

VeraCrypt version: 1.24-Update7

Operating system and version: Windows 10

System type: 64-bit

idrassi commented 2 years ago

Thank you for this detailed description. The current VeraCrypt implementation only displays PIN-protected data objects (also called private data objects in PKCS#11 terms). Always-access data objects (also called public data objects in PKCS#11 terms) are ignored because they can be read without PIN authentication.

One could argue that since VeraCrypt allows using key files stored in normal USB sticks, it should allow using public data objects stored in smart cards. I have nothing against it as long as the user is aware that using public data objects reduces security compared to PIN-protected data objects, especially if they don't contain sufficiently random data.

The code that performs this search is in the method SecurityToken::GetAvailableKeyfiles in the file src/Common/SecurityToken.cpp:

vector <byte> privateAttrib;
GetObjectAttribute (slotId, dataHandle, CKA_PRIVATE, privateAttrib);

if (privateAttrib.size() == sizeof (CK_BBOOL) && *(CK_BBOOL *) &privateAttrib.front() != CK_TRUE)
    continue;

It reads the CKA_PRIVATE attribute of the data object and if it is different from TRUE then it skips this data object.

I can implement an option that would make VeraCrypt look for public data objects in addition to PIN-protected data objects by skipping the above check if the option is specified. This will allow users like you to select additional data objects on the Yubikey.

Concerning the certificates, they are not really adapted for key files since,by definition, they are issued to the user by a third party. Using the same USB sticks analogy as above, once can argue that they should still be allowed. So probably the new option would make certificates and public data objects usable.

In order to take advantage of full security offered by Yubikey and smart cards in general, we should implement a cryptographic mechanism that uses the RSA/EC private keys stored in the card to perform mounting instead of just using keyfiles. This will require a breaking change to the format of VeraCrypt volume but it is worth the effort.

I will let you know when the option to allow using public data object and certificates is implemented.

ghost commented 2 years ago

Thanks for the explanation. I think having PIN protected objects is more secure, so that if you left the yubikey out somewhere, someone can't simply plug it in and quickly copy the keyfile tokens.

But the Iris Images is also PIN protected, so I'm not sure why it's not showing in the dialog? From the table, the only difference seems to be that it's an optional slot instead of mandatory for smart cards to have.

I kind of like the convenience of the current implementation, because in case you've lost all your yubikeys, you can still use the original keyfile from any storage device (plus the extra 2 bytes at the beginning that Veracrypt or the PKCS11 prepends to the token) to mount the container, if you've backed it up somewhere.

The keyfile on the yubikey is protected from brute force by pin/puk locking from limited retries, and I have other things like TOTP, FIDO, and challenge-response stored on the yubikey, so that I can carry them all together.

Although it's good to also have the additional options for smart card integration, hopefully doing this won't remove the possibility of continuing to import the keyfiles to a slot?

One problem with proper smart card integration, maybe it's more difficult to recover in case of losing the smart card without hardware (I'm not very familiar with it)? I just ran through a simulation of how to recover a KeepassXC database in case of losing a Yubikey with the challenge-response. Luckily, someone has written a script to extract the challenge from the database, and with your secret key, can generate the response, which you load as a keyfile to unlock the database, without needing to buy another Yubikey and wait for it to arrive.

idrassi commented 2 years ago

I have to have access to a Yubikey 5 NFC and I don't see any Iris Images data objects in the list of objects returned by OpenSC PKCS#11. I have put below a dump of all data objects on the Yubikey 5 NFC as returned by the pkcs11-tool program. so it seems that Yubikey PIV implementation doesn't support it.

Concerning adding support for private keys stored in smart card, this will not remove keyfile import and usage support. Those two features can live together.

Also, using private keys can be in a way that is friendly to backup scenarios: one can create such keys by importing Pfx files (also called PKCS#12 files) into the card. Pfx files are password protected and they are used to store private keys in a secure way. Users can backup these Pfx files like any other files and later then they can import them into the smart card in case the original card is lost. Pfx files have a big advantage compared to key files since they are password protected: they can't be used with the proper password.

Anyway, supporting private keys stored in smart cards will be a bug plus for security although the target audience is limited.

pkcs11-tool --slot 0 --login --pin 123456 --list-objects --type data

Data object 2599508736
  label:          'Cardholder Fingerprints'
  application:    'Cardholder Fingerprints'
  app_id:         2.16.840.1.101.3.7.2.96.16
  flags:           private
Data object 2599508832
  label:          'Printed Information'
  application:    'Printed Information'
  app_id:         2.16.840.1.101.3.7.2.48.1
  flags:           private
Data object 2599508928
  label:          'Cardholder Facial Image'
  application:    'Cardholder Facial Image'
  app_id:         2.16.840.1.101.3.7.2.96.48
  flags:           private
Data object 2599508352
  label:          'Card Capability Container'
  application:    'Card Capability Container'
  app_id:         2.16.840.1.101.3.7.1.219.0
  flags:          <empty>
Data object 2599508448
  label:          'Card Holder Unique Identifier'
  application:    'Card Holder Unique Identifier'
  app_id:         2.16.840.1.101.3.7.2.48.0
  flags:          <empty>
Data object 2599508544
  label:          'Unsigned Card Holder Unique Identifier'
  application:    'Unsigned Card Holder Unique Identifier'
  app_id:         2.16.840.1.101.3.7.2.48.2
  flags:          <empty>
Data object 2599508640
  label:          'X.509 Certificate for PIV Authentication'
  application:    'X.509 Certificate for PIV Authentication'
  app_id:         2.16.840.1.101.3.7.2.1.1
  flags:          <empty>
Data object 2599509024
  label:          'X.509 Certificate for Digital Signature'
  application:    'X.509 Certificate for Digital Signature'
  app_id:         2.16.840.1.101.3.7.2.1.0
  flags:          <empty>
Data object 2599509120
  label:          'X.509 Certificate for Key Management'
  application:    'X.509 Certificate for Key Management'
  app_id:         2.16.840.1.101.3.7.2.1.2
  flags:          <empty>
Data object 2599509216
  label:          'X.509 Certificate for Card Authentication'
  application:    'X.509 Certificate for Card Authentication'
  app_id:         2.16.840.1.101.3.7.2.5.0
  flags:          <empty>
Data object 2599509312
  label:          'Security Object'
  application:    'Security Object'
  app_id:         2.16.840.1.101.3.7.2.144.0
  flags:          <empty>
Data object 2599511136
  label:          'Discovery Object'
  application:    'Discovery Object'
  app_id:         2.16.840.1.101.3.7.2.96.80
  flags:          <empty>
ghost commented 2 years ago

I tried the same command on my Yubikey 5 NFC and got the same dump that you posted.

I also tried using the Yubico library. Initially I thought I saw a longer list, but I accidentally closed command prompt, and when I tried it again, it only shows 4 objects. I may have been mistaken. So the Yubico library doesn't seem to work well with openSC tool.

pkcs11-tool --module "%PROGRAMFILES%\Yubico\Yubico PIV Tool\bin\libykcs11.dll" --slot 0 --login --pin 123456 --list-objects
Data object 24
  label:          'X.509 Certificate for PIV Attestation'
  application:    'X.509 Certificate for PIV Attestation'
  app_id:         1.3.6.1.4.1.41482.3
  flags:          <empty>
Data object 31
  label:          'Discovery Object'
  application:    'Discovery Object'
  app_id:         2.16.840.1.101.3.7.2.96.80
  flags:          <empty>
Certificate Object; type = X.509 cert
  label:      X.509 Certificate for PIV Attestation
  subject:    DN: CN=Yubico PIV Attestation
  ID:         19
Private Key Object; RSA
  label:      Private key for PIV Attestation
  ID:         19
  Usage:      none
  Access:     sensitive, always sensitive, never extractable
Public Key Object; RSA 2048 bits
  label:      Public key for PIV Attestation
  ID:         19
  Usage:      encrypt, verify
  Access:     none

I previously imported a keyfile into Cardholder Facial Image. pkcs11-tool was able to read the object: pkcs11-tool --slot 0 --login --pin 123456 --read-object --type data --label "Cardholder Facial Image" pkcs11-tool --slot 0 --login --pin 123456 --read-object --type data --application-id 2.16.840.1.101.3.7.2.96.48

However, if I tried --label "Cardholder Iris Images" or --application-id 2.16.840.1.101.3.7.2.16.21 it does not work.

But, I did successfully import and export a keyfile into Cardholder Iris Images, using Yubikey Manager CLI. It just doesn't seem to be visible anywhere else. ykman piv objects import 0x5fc121 test.txt ykman piv objects export 0x5fc121 testexport.txt

In Veracrypt > Settings > Security Tokens > PKCS11 Library Path it usually gives an error if you try to select The Yubico library Yubico\Yubico PIV Tool\bin\libykcs11.dll. But if you copy all of the DLLs from the bin folder into Windows\System32 and select the path from there (recommended on a Yubico forum), the error goes away. However, when you actually go to Veracrypt >Tools > Manage Security Token Keyfiles then the dialog is empty and shows no objects. So it's better to use the OpenSC DLL.

Anyway, I will continue using the 2 slots Cardholder Fingerprints and Cardholder Facial Image. It's enough for me at the moment. Thanks for the help.

ghost commented 2 years ago

Cardholder Iris Images

I was curious if Yubico support would know why Cardholder Iris Images is not detected by other software, but they wouldn't answer the question. They wrote that (private?) data written to the Yubikey cannot be read, which is kind of a generic answer for the other features, but not related to PIV data objects which are supposed to be read. ¯\_(ツ)_/¯

Token Sessions

I'm curious, when you select "Close Token Sessions" in Veracrypt > Tools, what exactly is open to be closed?

Are the Yubikey PIV slots open for access after the first PIN entry? Or were all of the data objects read on the PIN entry and stored in memory, so closing the session means deleting the data objects from memory?

jmiguel-hdez commented 1 year ago

I would also like to have the smartcard support. is there any way we can help?