openzfs / zfs

OpenZFS on Linux and FreeBSD
https://openzfs.github.io/openzfs-docs
Other
10.34k stars 1.72k forks source link

support for PIV [keylocation=pkcs11] #8571

Open c3ph3us opened 5 years ago

c3ph3us commented 5 years ago

i understand that keysource=X,Y is replaced here with keformat and keylocation

@tcaputi i want to be able to use PKCS11 as keylocation exactly to use a pkcs11 piv feature from Yubikey

The YubiKey 4 and 5 series along with the YubiKey NEO support the Personal Identity Verification (PIV) interface specified in NIST SP 800-73 document "Cryptographic Algorithms and Key Sizes for PIV". This enables you to perform RSA or ECC sign/decrypt operations using a private key stored on the smartcard, through common interfaces like PKCS#11.

RSA signature supported mechanisms are RSA-X-509 (raw RSA), PKCS1 (unhashed), PKCS1 with SHA1/256/384/512 and PSS with SHA1/256/384/512. The latter is implemented but has not been tested, hence is provided as is;

ECDSA signature supported mechanism are ECDSA (raw) and ECDSA with SHA1;

https://developers.yubico.com/PIV/ https://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html

as i understand NOW i can use zpool/zfs "promptom for passphrase" feature and emited static password form it

https://www.yubico.com/wp-content/uploads/2015/11/Yubico_WhitePaper_Static_Password_Function.pdf

arekinath commented 5 years ago

In case it's interesting, we're currently working on a scheme for managing dataset encryption keys using PIV which is based around "boxes" (based on the design of libnacl/libsodium crypto_box_sealed) holding the key material, arranged so that a given dataset can be unlocked either by a primary PIV token in the server itself, or by using N/M (e.g. any 2 out of 3) of a set of backup keys stored on other devices offline.

Currently we store the boxes in a ZFS user property on the dataset, so at boot we fetch that property, then use ECDH on the PIV token to unlock the box, then put that key into zfs load-key, which works pretty well. The backup boxes contain GF^256 Shamir-style secret sharing pieces of the main key (and we implemented a challenge-response type protocol so those backup keys can be remote and not on the machine itself for recovery). We'd be interested in some future way to integrate this more deeply, but I also acknowledge this scheme (primary token + N/M backup tokens) might not appeal to everybody, so we might always be going our own way on it. Still, PKCS#11 support would be interesting to us even if only to have a good example of how to add a new mechanism here.

(An overview of the design is contained in this RFD in case anyone wants to read it. Some of the finer details are getting a bit out of date against the implementation as we're prototyping it out though, sorry.)

c3ph3us commented 5 years ago

perform RSA or ECC sign/decrypt operations using a private key stored on the smartcard, through common interfaces like PKCS#11.

so:

1) when the key is generated on the device "YubiKey" the key is not exposed to user in any way - it's not accessible, we can do the OP's via PKCS11 interface 2) key can be stored on thevice by user by WRITE OP to one of available slots - the user contains copy of the key (for own purposes) outside the device but the key still is not accessible to the user

so... i don't know "exact" how the encryption in ZFS works byt can we instead of all this bulshit like wrapping unwrapping master keys etc SEND data through provided PKCS11 interface to DECRYPT/ENCRYPT it by the device "on the fly" what is it made for and it suposed to do?
in one word or sentence DELEGATE THE ENCRYPT/DECRYPT OP TO DEVICE VIA PKCS11

EXAMPLES:

https://developers.yubico.com/YubiHSM2/Usage_Guides/OpenSSL_with_libp11.html https://developers.yubico.com/YubiHSM2/Usage_Guides/Using_OpenSC_pkcs11-tool.html

DOCS: https://developers.yubico.com/PIV/Guides/ https://csrc.nist.gov/projects/piv/piv-standards-and-supporting-documentation

tcaputi commented 5 years ago

Just got back from vacation so sorry for the slow response. I'm not an expert on drivers for external devices, but here is my understanding of the situation from some very quick research. If anything I say here isn't true please correct me:

From looking at the documentation, I'm not seeing anything that would indicate that the device is meant to be used for encrypting or decrypting large streams of data. This makes sense to me since a USB device has very limited bandwidth. So I'm fairly certain that these devices are mostly useful for storing wrapping keys and doing the wrapping / unwrapping in a secure fashion.

Another problem is that we are a kernel module so the normal userspace libraries aren't applicable. Usually, kernel modules could communicate with devices like these through the kernel, but these interfaces are only accessible to GPL-licensed modules. I would need to do more research to figure out how to get this to work with the ICP code (which was ported from Illumos), but a quick search of the OpenSC github page doesn't seem to have any mentions of some basic symbols that almost all kernel modules have (ex module_exit, THIS_MODULE, etc), so it would seem we would need to write this from scratch. This isn't an impossible thing to do, but it makes it a lot harder to do.

Let me know if anything I have said here isn't true.

ajaderberg commented 5 years ago

Along the lines of where @arekinath was pointing this is as close as I have gotten to protecting the symmetrical ZFS key using the Yubikey. Encrypt the key using gpg (I opted for a 32 byte key) and store it in a file. Correct configuration of gpg-agent will require the Yubikey for loading the key:

gpg --decrypt --armor < encrypted_zfs_key_file.gpg | zfs load-key pool/users

As for the intention of placing the Yubikey or a similar device in the middle of ZFS crypto internals there may still be some distance to cover. From a users perspective more elegant ways of managing and loading/unloading the ZFS keys would be helpful and an area where the Yubikey could be made more useful.

no-usernames-left commented 8 months ago

Resurrecting this, a SmartCard-HSM (aka Nitrokey HSM 2) might work great here. Has there been any progress not reflected in this issue?