Table of Contents

PIN, touch, and biometric policies

The YubiKey's PIN, touch, and biometric policies determine when PIN verification, biometric verification, and touch are required in order to perform an operation with a private key from one of the YubiKey's PIV slots, including the management key.

These policies apply to operations such as signing, decrypting, performing a key agreement, and authenticating the management key (required when generating a key pair, importing a private key or certificate, etc).

Policy properties

PIN and touch policies can be configured when a private key is generated or imported into a YubiKey's PIV slot. Once the policies have been set during key generation/import, they cannot be changed. If a PIN and/or touch policy is not specified at that time, the slot's default policies will be applied to the key. Default policies vary depending on the slot and are programmed into the YubiKey's firmware. Note that policy configuration is supported on YubiKeys with firmware version 4 and later; earlier YubiKeys are limited to the slots' default policies.

A key's policies, whether explicitly configured or not, are properties of the key itself. This means that you can move a key from one slot to another (for example, from slot 9A to one of the retired key slots), and its policies do not change.

Biometric policies are a type of PIN policy and can only be used with YubiKey Bio Series — Multi-protocol Edition keys. (YubiKey Bio Series – FIDO Edition keys do not support PIV.)

The management key (slot 9B) only has a touch policy. The PIN is never needed to perform a management key operation (with the exception of SetPinRetriesCommand because it is related to the PIN itself). The PIN and PUK (slots 80 and 81) do not have PIN or touch policies.

Keys generated or imported into the following slots have both PIN and touch policies:

  • 9A (Authentication)
  • 9C (Digital Signature)
  • 9D (Key Management)
  • 9E (Card Authentication)
  • F9 (Attestation)
  • 82-95 (Retired Key Slots)

PIN policy options

The three main PIN policy options are as follows:

  • Never: the PIN is never needed.
  • Always: the PIN is needed for every key operation.
  • Once: the PIN is needed once per session.

Due to PIV card activation requirements in section 4.3 of the FIPS 201-3 specification, YubiKey FIPS Series keys with firmware version 5.7.1 or later cannot set PIN policy to Never.

Warning

It is important to note that setting the PIN policy to Never reduces security dramatically. This feature was added only because of customer demand for convenience. Yubico recommends setting the PIN policy to Always or Once.

Biometric policy options

Biometric policies are a type of PIN policy that are available for YubiKey Bio Series — Multi-protocol Edition keys with firmware 5.7 or later. There are two biometric policy options:

  • Match Once: a biometric or PIN verification is required for each session.
  • Match Always: a biometric or PIN verification is required for every key operation.

Touch policy options

There are three touch policy options:

  • Never: a touch is never needed.
  • Always: a touch is needed for every key operation.
  • Cached: if more than 15 seconds have elapsed since the last time the YubiKey was touched, a touch is needed.

Cached is only available for YubiKeys with firmware version 4.3 and later.

Default policies

The default PIN and touch policies are programmed into the YubiKey's firmware upon manufacture. Starting with firmware version 4, YubiKeys (with the exception of YubiKey FIPS Series keys with firmware version 5.7.1 and later) have the following default policies:

  • Slot 9C PIN policy: Always
  • Slot 9E PIN policy: Never
  • General PIN policy: Once
  • Touch policy: Never

Due to PIV card activation requirements in section 4.3 of the FIPS 201-3 specification, YubiKey FIPS Series keys with firmware version 5.7.1 and later have a default 9E PIN policy of Once. The other default polices listed above are the same for these keys.

Slots 9C and 9E have different default PIN policies than all other slots due to the requirements mandated by the PIV standard (see NIST SP 800-73pt1, section 3). Touch is not a part of the PIV standard, which is why the default touch policy is Never. The ability to require touch was added to the YubiKey in firmware version 4 to augment security.

When generating or importing a key into one of the PIV slots, these default policies will be applied to the key unless otherwise specified.

Setting a key's PIN and touch policies (all slots other than 80, 81, and 9B)

You can set a private key's PIN and touch policies to something other than the slot's default options only when generating or importing the key onto the YubiKey (firmware version 4 and later). Note that you can specify different policies for keys in different slots. For example, you can generate a new key in slot 9A that has a PIN policy of Always, while a key imported into slot 86 has a PIN policy of Once.

When specifying the PIN policy with the SDK, you must select one of the PivPinPolicy enum fields:

  • Always
  • Default
  • MatchAlways
  • MatchOnce
  • Never
  • None
  • Once

However, note that if you choose MatchOnce or MatchAlways and your YubiKey is not a YubiKey Bio Series — Multi-protocol Edition key, the SDK will throw an exception. And as a reminder, setting the PIN policy to Never reduces security dramatically and is not recommended by Yubico.

When specifying the touch policy with the SDK, you must select one of the PivTouchPolicy enum fields:

  • Always
  • Cached
  • Default
  • Never
  • None

Selecting None for either the PIN policy or touch policy during generation/import does not remove the policy field from the private key. The YubiKey's firmware interprets None as an invalid policy and will use the slot's default policy instead.

GenerateKeyPair() and ImportPrivateKey() example

In this example, we will generate a key in slot 9C and import a key into slot 9D using the GenerateKeyPair and ImportPrivateKey PIV session methods, respectively. When calling each method, we will specify the intended slot via the PivSlot class. For the 9C key, we will set its PIN policy to Once and its touch policy to Always. For the 9D key, we will set its PIN policy to Always and its touch policy to Cached.

With GenerateKeyPair, we must also specify the key's algorithm via the KeyType class. For ImportPrivateKey, we must provide the private key to be imported, which must be an implementation of the PrivateKey class.

Generating and importing keys, however, requires management key authentication before those operations can complete. When you call GenerateKeyPair or ImportPrivateKey, the SDK will call on your KeyCollector to collect the management key from the user and perform authentication automatically. However, we can also perform management key authentication manually (by providing the management key directly instead of using the KeyCollector) via TryAuthenticateManagementKey, which we will call in this example:

using (PivSession pivSession = new PivSession(yubiKey))
{
    // Perform management key authentication first (managementKey set elsewhere).
    pivSession.TryAuthenticateManagementKey(managementKey);

    pivSession.GenerateKeyPair(
        PivSlot.Signing, 
        KeyType.RSA2048, 
        PivPinPolicy.Once, 
        PivTouchPolicy.Always);

    // privateKey set elsewhere.
    pivSession.ImportPrivateKey(
        PivSlot.KeyManagement, 
        privateKey, 
        PivPinPolicy.Always, 
        PivTouchPolicy.Cached);
}

After performing this configuration, every time a signing operation is performed with the key in slot 9C, the YubiKey must be touched, but the PIN will only need to be authenticated once per session. And when performing a decryption operation with the key in slot 9D, the PIN must be authenticated every time, but the YubiKey will only need to be touched if more than 15 seconds have elapsed since the previous touch.

Changing the touch policy for the management key (slot 9B)

The management key (slot 9B) has a touch policy only, and its default value is Never. However, when changing the management key, you can set this policy to one of the other touch policy options (Always or Cached). Once reconfigured with one of these other policies, the user will be required to touch the YubiKey at the specified frequency to perform management key operations.

To change the management key with the SDK, there are two options: the PivSession method, TryChangeManagementKey(), or the lower-level SetManagementKeyCommand().

TryChangeManagementKey() example

To change the management key and set a new touch policy using the PivSession, simply call TryChangeManagementKey() and provide the current management key, the new management key, and the desired touch policy. In this example, let's set the touch policy to Always:

using (PivSession pivSession = new PivSession(yubiKey))
{
    // currentKey and newKey set elsewhere.
    pivSession.TryChangeManagementKey(currentKey, newKey, PivTouchPolicy.Always);
}

Note that TryChangeManagementKey() is an overloaded method. In addition to specifying the new key's touch policy, you can also specify a particular algorithm. If these properties are not specified, the slot's default touch policy and default algorithm will be used for the new management key. Also, if you call the method without providing the current and new management keys directly, the SDK will call upon your KeyCollector to fetch them from the user.

SetManagementKeyCommand() example

Unlike the PivSession, using the PIV command classes to change the management key requires three steps:

  1. First we must initiate the PIV management key authentication process with InitializeAuthenticateManagementKeyCommand.
  2. Then we can finish management key authentication with CompleteAuthenticateManagementKeyCommand().
  3. And finally we can set the new management key and touch policy via SetManagementKeyCommand().
IYubiKeyConnection connection = yubiKey.Connect(YubiKeyApplication.Piv);

// Specify the current management key's algorithm. (If you aren't sure about the
// algorithm, retrieve it from the key's metadata first.)
InitializeAuthenticateManagementKeyCommand initAuthManKeyCommand = 
    new InitializeAuthenticateManagementKeyCommand(PivAlgorithm.Aes192);

InitializeAuthenticateManagementKeyResponse initAuthManKeyResponse = 
    connection.SendCommand(initAuthManKeyCommand);

// Pass in the initialization response and the current management key 
// (currentKey set elsewhere).
CompleteAuthenticateManagementKeyCommand authManKeyCommand = 
    new CompleteAuthenticateManagementKeyCommand(initAuthManKeyResponse, currentKey);

CompleteAuthenticateManagementKeyResponse authManKeyResponse = 
    connection.SendCommand(authManKeyCommand);

// Also specify the new key's algorithm.
SetManagementKeyCommand setManKeyCommand = 
    new SetManagementKeyCommand(newKey, PivTouchPolicy.Always, PivAlgorithm.Aes192);

SetManagementKeyResponse setManKeyResponse = 
    connection.SendCommand(setManKeyCommand);

In this example, we set the management key's touch policy to Always. This means that all future calls to CompleteAuthenticateManagementKeyCommand will not complete until the YubiKey has been touched.

Retrieving an existing key's PIN and touch policies

Once a key has been generated or imported into a slot, you can check the PIN and touch policies it was configured with via the key's PIV metadata. Note that this feature is only available for YubiKeys with firmware version 5.3 and later. On older YubiKeys, there is no way to retrieve a key's policies after configuration.

To check a key's policies, create an instance of a PivSession with the desired YubiKey, call GetMetadata on a specific PIV slot, and extract the PinPolicy and TouchPolicy properties:

using (PivSession pivSession = new PivSession(yubiKey))
{
    // Get the metadata from the key in slot 9A.
    PivMetadata metadata = pivSession.GetMetadata(0x9A);

    // Extract the properties from the metadata.
    PivPinPolicy pinPolicy = metadata.PinPolicy;
    PivTouchPolicy touchPolicy = metadata.TouchPolicy;
}

Note that if the slot does not contain a key, the SDK will throw an exception when trying to call GetMetadata. Slots 80 and 81 (PIN and PUK) do not have PIN or touch policies and will always return None for those properties in the metadata.

The management key (9B) has a touch policy but no PIN policy. In order to maintain consistency with the data format, the YubiKey will return the undefined value "0" for 9B's PIN policy. This is not a valid PIN policy, and the SDK translates it to Default in the metadata.

PIV access control

The PIV PIN, PUK, and management key