Log in / Register Account

OASIS has announced that its members have approved Version 3.0 of the Public-Key Cryptography Standard (PKCS) #11. In this post we'll look at what's new in Version 3.0 and what you can expect to see in Red Hat Enterprise Linux (RHEL).

What's PKCS and why do I care?

The PKCS #11 standard specifies a generalized loadable cryptographic API which allows third parties to supply cryptographic implementations which can be used by our security libraries and applications. The standard supports loading more than one module, so that applications can use more than one PKCS #11 module at once.

PKCS #11 was developed in 1994 as part of the RSA PKCS standards, used to bootstrap security protocols and standards. In 2012, RSA turned the standard over to the OASIS PKCS #11 working group, which released the first new version of the standard in 2015. Since it’s release, PKCS #11 has been used in both open source and closed source environments.

In RHEL 8.0, PKCS #11 became the main medium to access cryptographic hardware operations from our applications. Our core crypto components (OpenSSL, NSS, gnutls), and their dependent applications (e.g., Apache httpd) take advantage of PKCS #11 driver modules to support cryptographic hardware from hardware security modules (HSM)s, that are mostly applicable to server applications like httpd, to smart cards, applicable in applications like Firefox. 

In addition PKCS #11 is also used in RHEL as a way to access the CA certificate trust store via p11-kit. For an overview of the PKCS #11 enhancements in RHEL 8.0 see Jakub Jelen's post, "Consistent PKCS #11 support in Red Hat Enterprise Linux 8." In addition network security services (NSS), the library used by Firefox, uses PKCS #11 for its cryptographic operations.

What does the new PKCS #11 standard support?

Authenticated Encryption with Associated Data (AEAD)

PKCS #11 3.0 is the first major revision of PKCS #11 since RSA released version 2.01 in 1997. Between version 2.10 (1999) and 3.0, no new functions were added to PKCS #11. All new features were added as new mechanisms or new attributes. 

Since that time, the IETF created a new cryptographic mode called Authenticated Encryption with Associated Data (AEAD). AEAD supports both encryption as well as authentication for both the original plain text and additional data that’s not part of the encryption. 

Unlike regular encryption and decryption, AEAD requires additional parameters to store the returned authentication tag and to add any additional data that needs to be authenticated. This data doesn’t fit into the existing PKCS #11 C_EncryptUpdate and C_EncryptFinal functions. A whole new set of functions were defined that added the new AEAD parameters, as well as adding mechanism specific parameters to each AEAD update call. These new interfaces are called C_MessageXXXX interfaces, and come in flavors for Encrypt, Decrypt, Sign, and Verify (even though AEAD only supports encryption and decryption).

The new APIs in Version 3.0 allow PKCS #11 to support AES_GCM (an AEAD mechanism), including modes that can pass government FIPS validations. PKCS #11 v2.4 could not supply the extra parameters AEAD needed on each encrypted block operation, so AEAD could only be supported through single shot operations, where the key setup is done again and again for each operation. 

This means important per session state information (like how much data has been encrypted with a single key, or how many Initialization Vectors (IVs) have been used for that key) could not be kept in the token, but had to be managed at the application level. Now with PKCS #11 v3.0, the token can enforce AEAD encryption limits and enforce unique IVs for each encrypted block, making AEAD operations more secure.

New Function Table

Since PKCS #11 is a loadable cryptographic interface, and since multiple PKCS #11 modules can be loaded in the same program, PKCS #11 uses a unique way to present its API. A single function is queried at load time and that function provides a table to all the rest of the functions in the module, so applications don’t need to query each function it uses for every module. 

Since this is the first time new functions have been added to the PKCS #11 spec in 20 years, there were potential conflicts with vendors who added their own vendor specific functions at the end of the current PKCS #11 table.

To solve that, PKCS #11 create a new way to query the PKCS #11 table: C_GetInterfaces. C_GetInterfaces allows you to query multiple tables from your PKCS #11 device based on an identifier string, a version number, and a set of flags. 

More than one table can be returned in a single call. In the future PKCS #11 may define domain specific interfaces (like token initialization). Part of the string space is reserved for vendor specific interfaces, which allows the vendors to put their specific functions in their own space and not at the end of the PKCS #11 function table.

Fork semantics

When PKCS #11 is running on UNIX-like systems (like Linux), one particular challenge is what happens when the process forks after PKCS #11 has been initialized. Software implementations normally handle forks without a problem and all objects are just copied to each address space, but hardware can have issues as two separate processes are now trying to access the same hardware. 

PKCS #11 has traditionally put the onus on the application to handle this, requiring that forked child has to close down and restart PKCS #11 before it can continue. This causes problems for applications using NSS because NSS has to export that semantic to the application. PKCS #11 v3.0 allows the application to request a fork-safe interface using the flags in the new C_GetInterfaces. If your system is only using the software version of NSS, that feature is available now in the latest version of NSS. We encourage hardware HSMs to move to PKCS #11 v3.0 so that systems that use those HSMs can take advantage of this feature as well.

New mechanisms

In PKCS #11 mechanisms are usually new cryptographic algorithms, specified separately from the base PKCS #11 spec. Each algorithm has its own number and semantic, and the Mechanism Spec specifies which functions are supported by each algorithm. This is the most dynamic part of the PKCS #11 spec as new cryptographic algorithms are constantly being added. PKCS #11 v3.0 adds several new algorithms as well, including:

  • CKM_HKDF_DERIVE, used by TLS to manipulate keys in TLS 1.3,

  • Numerous mechanisms to support the new SHA3 hash algorithms, including all the RSA, DSA, and ECDSA hash then sign mechanisms.

  • CKM_AES_XTS, used to create a block version of AES that has cipher text length = plain text length (normally block ciphers have larger cipher text lengths).

  • CKM_AES_KEY_WRAP_KWP, the NIST version of padded AES Key Wrap.

  • BLAKE2B hashing mechanism.

  • CKM_CHACHA20_POLY1305 AEAD mechanism.

  • Update CKM_AES_GCM and CKM_AES_CCM to use the new Message interfaces

  • CKM_EDDSA – Edwards curve ECC Signing.

  • CKM_XEDDSA – Montgomery ECC Signing.

  • CKM_SP800_108_COUNTER_KDF, CKM_SP800_108_FEEDBACK_KDF, and CKM_SP800_108_DOUBLE_PIPELINE_KDF NIST’s parameterized KDF.

New Profile object

PKCS #11 defines a number of objects to support cryptography, either directly or through important meta data. PKCS #11 v3.0 defines a new object, called CKO_PROFILE. This object lets applications query if a given PKCS #11 module supports a given PKCS #11 profile programmatically. 

Applications and libraries that use PKCS#11 can now check if a module supports the minimum functionality to support the operations it needs. Along with the new profile object, PKCS #11 v3.0 also defines a new profile, which indicates that a smart card can tell you all the information you need to know about the certificates before you log into the token. Expect new profiles to come out in PKCS #11 in future releases.

How this all affects RHEL

The most noticeable effect will be that TLS 1.3 will work in Firefox in FIPS mode. Also expect, that in the future, there will be less fork related issues with hardware tokens as more hardware tokens move to PKCS #11 v3.0. PKCS #11 v3.0 support has been added to NSS 3.53, which is available now in RHEL 8.2.z and RHEL 7.9.z.

You can check out the new PKCS #11 spec at the OASIS PKCS 11 TC page.


About the author

Robert Relyea is a Principal Software Engineer and has been with Red Hat for more than 24 years