PIV Enhancements Technical Description
Background: How PIV Attestation Works
A technical description of YubiKey PIV attestation is available at the Yubico developer website.
Attestation is performed on a public key that has been generated on the YubiKey. For example, consider an asymmetric key-pair that is generated on the YubiKey with the following ykman (YubiKey Manager) command:
ykman piv generate-key 9c -
This command generates an asymmetric key-pair, and stores the private key in the specified slot (9c in this example). The public key that has been generated is returned as output.
The ykman attestation command can be executed for the key-pair at the slot (9c):
ykman piv attest 9c C:\Test\attestation-cert-9c.cer
The generated certificate is generated in real time at the YubiKey. The attestation certificate and private key, which are stored in slot f9, are used for signing the generated certificate for the slot (9c). The attestation certificate is used as template when creating the generated certificate for the slot (9c). In addition to the template attestation certificate, the extensions and subject details are appended to the generated certificate.
However, the generated certificate is not the same as the X.509 certificate that may be issued by an external CA or self-signed on the YubiKey. For example, the X.509 certificate could be issued by the Microsoft ADCS and written to the YubiKey. The YubiKey Manager GUI can be used to generate a key-pair and self-sign the public key at the YubiKey.
The public key at slot 9a can be attested (signed in real time by the CA attestation certificate) with the same ykman command as above:
ykman piv attest 9a C:\Test\attestation-cert-9a.cer
And the X.509 self-signed certificate can be exported from the YubiKey with the following ykman command:
ykman piv export-certificate 9a C:\Test\self-signed-9a.cer
The Shortcomings of PIV Attestation
PIV attestation only works for asymmetric keys that have been generated on the YubiKey; it does not work for asymmetric keys that have been imported into the YubiKey.
For example, the following ykman command imports a PKCS #12 file into the YubiKey at slot 9e:
ykman piv import-key 9e C:\\Test\\TestUser1.p12 -P 123456
ykman piv import-certificate 9e C:\\Test\\TestUser1.p12 -P 123456
These ykman commands unpack the PKCS #12 file, store the private key in the private key slot (9e), and store the X.509 certificate in the corresponding certificate slot.
Now, if one tries to attest the public key at slot 9e with the YkMan attestation command, the operation will fail:
ykman piv attest 9e C:\\Test\\attestation-9e.cer
Error: Attestation failed.
One more drawback with PIV attestation is performance, since generation of multiple PIV attestation certificates can be time-consuming.
When To Use PIV Metadata
PIV metadata should be used for the following cases:
- If PIV attestation cannot be used (for imported keys),
- If an attestation certificate is not required, PIV metadata can be used for achieving higher performance.
Yubico PIV Library and Metadata API
PIV metadata is supported by YubiKey v5.3.0 and above. YubiKey PIV metadata can be accessed by using the libykpiv library.
The Yubico PIV Tool contains the library
The source code of the
libykpiv library is published at the Yubico GitHub repo.
The libykpiv library exposes a C API in the header file ykpiv.h, which includes the functions
ykpiv_util_parse_metadata(). The source code of these functions is available in the file ykpiv.c.
In particular, the function
ykpiv_get_metadata() calls the underlying function
_ykpiv_transfer_data(), which transfers APDUs to the YubiKey PIV applet over the CCID interface.
_ykpiv_transfer_data() takes the input parameter
templ, which is populated with the APDUs (CLA, INS, P1, P2) that are specified at the Yubico developer website for PIV extensions under the section GET METADATA. The YubiKey returns the tag length values (TLVs) (Algorithm, Policy, Origin, etc) that are specified in the same section, and the TLV-encoded output is returned in the
ykpiv_get_metadata() parameter data.
|Algorithm||0x01||Algorithm/type of the key|
|Policy||0x02||PIN and Touch policy of the key (keys only)|
|Origin||0x03||Origin of the key: imported or generated|
|Public key||0x04||Public key associated with the private key|
Whether the PIN/key has a default value
PIN and PUK and Mgmt key only)
|Retries||0x06||Number of retries left (PIN and PUK only)|
It is even possible to invoke the function
ykpiv_transfer_data() directly for low-level APDU communication with the YubiKey’s PIV applet.
ykpiv_util_parse_metadata() can be used for parsing the returned TLV-encoded object.
Therefore, the developer can integrate the
libykpiv library for low level programming with YubiKey PIV metadata.
Using PIV Metadata with YKCS11
When the PKCS #11 function
C_OpenSession() is called for a YubiKey PKCS #11 slot (which is a YubiKey PIV application in a PC/SC reader), then the YKCS11 library will parse out the public keys for all PIV key slots. If PIV attestation is supported, the PIV attestation certificate will be used for parsing out the public key.
If PIV attestation is not supported, i.e., if the key-pair has been imported into a YubiKey, then the YKCS11 library calls the functions
ykpiv_util_parse_metadata() to parse out the requested public key.
If both attestation and PIV metadata fail, in that order, YKCS11 will fall back to parse the public key from the X.509 certificate.
The X.509 certificate’s public key may not match the private key in the YubiKey PIV slot.
PIV AES Management Key
Historically, the YubiKey PIV management key is a 3DES key. With the release of the YubiKey v5.4.0 firmware, the YubiKey PIV management key can also be an AES key.
Technically speaking, this feature expands the management key type held in PIV slot 9b to include AES keys (128, 192 and 256) as defined in the PIV specification (SP800-78-4, section 5). PIV management key in AES format allows for the YubiKey to be compatible with current or future FIPS compliant CMS services.