IBM Cloud Docs
Introducing PKCS #11 - Unified Key Orchestrator Plan

Introducing PKCS #11 - Unified Key Orchestrator Plan

PKCS #11 is a standard that specifies an application programming interface (API), called Cryptoki, for devices that hold cryptographic information and perform cryptographic functions. The Cryptoki API follows a simple object-based approach. The approach addresses the goals of technology independence and resource sharing, presenting to applications a common, logical view of the device called a cryptographic token.

Cryptoki isolates an application from the details of the cryptographic device. The application does not have to change the interface to a different type of device or to run in a different environment. Thus, the application is portable. The functions of the Cryptoki API are organized into the following categories:

Not all PKCS #11 functions are implemented by IBM Cloud® Hyper Protect Crypto Services. For the implemented PKCS #11 functions, see Supported PKCS #11 functions.

To review the PKCS #11 standard documentation, see:

PKCS #11 implementation components

To connect and use the PKCS #11 API, you need to understand the PKCS #11 API that is implemented by Hyper Protect Crypto Services and the relationship with the GREP11 API. For more information, see Comparing the PKCS #11 API with the GREP11 API. With the support of the PKCS #11 API, you don't need to change your existing applications that use the PKCS #11 standard. Hyper Protect Crypto Services also provides the isolated keystores to store cryptographic keys generated by the PKCS #11 functions. These keys are protected by the master key and the applications never see the key files locally.

Before you can use the PKCS #11 API, first install the PKCS #11 library. In this way, the PKCS #11 application can interact with the PKCS #11 library, which then calls cryptographic functions that are implemented by Hyper Protect Crypto Services through gRPC. The following diagram shows the key components that are implemented by the Hyper Protect Crypto Services PKCS #11 library and the interactions among different components.

Performing cryptographic operations with the PKCS #11 API
Figure 1. Performing cryptographic operations with the PKCS #11 API

The following sections explain each PKCS #11 component in detail.

Application

An application runs within a single address space. All threads of control are running in the application. An application becomes a Cryptoki application by calling the Cryptoki function C_Initialize from one of the threads. After this call is made, the application can call other Cryptoki functions. When the application finishes using Cryptoki, it calls the Cryptoki function C_Finalize and ceases to be a Cryptoki application.

User

The PKCS #11 standard defines two types of users for login: a security officer (SO) and a normal user. If a user does not log in using the C_Login Cryptoki function, the user is also known as an anonymous user. Only the normal user can access private objects on the token, and that access is granted only after the normal user is authenticated. In the Hyper Protect Crypto Services PKCS #11 implementation, security officers and normal users are authenticated by API keys. Anonymous users are also supported. For instructions on setting up PKCS #11 user types, see Best practices for setting up PKCS #11 user types.

Session

The Cryptoki API requires that an application opens one or more sessions with a token to gain access to the objects and functions of the token. A session provides a logical connection between the application and the token. A session can be a read/write (R/W) session or a read-only (R/O) session.

To gain access to the private objects of the token, the normal user needs to log in and is authenticated. See PKCS #11 Cryptographic Token Interface Usage Guide for an in-depth look at sessions.

Key object

Key objects are stored in either the in-memory keystore that resides with the PKCS #11 application or in a database-backed keystore. If the CKA_TOKEN attribute is set to true for the key object, the key object is stored in the database-backed keystore. Otherwise, the key object is stored in the in-memory keystore.

Key objects in the in-memory keystore are not automatically rotated after the master key rotation. If PKCS #11 keystores are enabled in your service instance, you need to restart all active PKCS #11 applications to clear the in-memory keystore after the master key rotation is complete.

As shown in the following diagram, a PKCS #11 key object is an example of a PKCS #11 object class:

  • Data: A data object is defined by an application.
  • Certificates: A certificate object stores a certificate.
  • Keys: A key object stores a cryptographic key. The key can be a public key, a private key, or a secret key. Each type of these keys has subtypes for use in specific mechanisms.
    • Public key: The public component of a key pair that is used by anyone to encrypt messages intended for a particular recipient that has access to the private key of the key pair. The public key is also used to verify signatures created by the private key.
    • Private key: The private component of a key pair that is used to decrypt messages. The private key is also used to create signatures.
    • Secret key: A secret key is a generated stream of bits that is used to encrypt and decrypt messages symmetrically.

PKCS #11 object classes
Figure 2. PKCS #11 object classes

Currently, the data object class is not supported and only X.509 Public Key Certificate objects are supported in this implementation.

Cloud Identity and Access Management

IBM Cloud Identity and Access Management (IAM) provides user authentication and access control for the implementation of the PKCS #11 API. By using API keys, the PKCS #11 library obtains bearer tokens that are used to perform Cryptoki API calls.

This implementation of PKCS #11 equates an API key with a user's PIN. For more information about setting up the service ID and the corresponding API key, see Create service IDs for the SO user, normal user, and anonymous user.

Crypto service

As part of the PKCS #11 library initialization process, a gRPC connection is made from the PKCS #11 library to the IBM Cloud. The gRPC connection facilitates the PKCS #11 library to call Cryptoki functions, such as C_Encrypt, C_Decrypt, C_Sign, and C_Verify, which requires the use of a Hardware Security Module (HSM).

Keystore

Two major types of keystores are available:

  • In-memory keystores: Stores key objects temporarily in memory. Key objects that are stored in the in-memory keystore are also known as session objects. Session objects in a specific session are destroyed when you call the C_CloseSession function for that session. Session objects in all sessions are destroyed after the C_Finalize function is called.
  • Database-backed keystores: Stores key objects in databases. Key objects that are stored in the database-backed keystore are also known as token objects. If the sessionauth parameter is enabled and a password for the keystore is configured, the database-backed keystore is encrypted and authenticated. By default, the sessionauth parameter is disabled. For each service instance, a maximum of five authenticated keystores are supported. You can enable the sessionauth parameter to encrypt the generated keys into the keystore or to decrypt the key before you use it. The password can be 6 - 8 characters.

Keystore passwords are not stored in the service instance. You, as the keystore administrator, are responsible for maintaining a local copy of the passwords. If a password is lost, you need to contact the Support team to reset the keystore, which means all data in the keystore is cleared.

Both the in-memory keystores and the database-backed keystores are composed of the following types of keystores:

  • Public keystore: Stores keys that are less sensitive and that are to be accessed by any user types.
  • Private keystore: Stores keys that encrypt sensitive data and that are to be accessed by normal users only.

Depending on the user types and key attributes settings, the generated keys are stored in different keystores. The following list summarizes the criteria of how keys are stored:

  • The CKA_TOKEN attribute value decides whether the generated key is stored in an in-memory keystore or in a database-backed keystore.

    If you want to store the key in the database-backed keystore, set CKA_TOKEN to TRUE in key or key pair generation templates. The PKCS #11 library initialization process establishes a gRPC connection with the IBM Cloud, which facilitates the storing and retrieval of key objects to or from the database-backed keystore. By default, CKA_TOKEN is set to FALSE, which means the key object is stored in an in-memory keystore within the process address space of the PKCS #11 application.

  • The CKA_PRIVATE attribute value decides whether a key that is generated by normal users is to be stored in a public or private keystore.

    By default, if a user is logged in as a normal user, generated keys are stored in the private keystores, except for the case where CKA_PRIVATE is set to FALSE. If a user is logged in as an SO user or is not logged in (known as an anonymous user), then generated keys are always stored in the public keystores. If an SO user or an anonymous user specifies CKA_PRIVATE to TRUE in the key generation templates, an error is returned from the server.

    For an asymmetric key pair, you need to set the CKA_PRIVATE attribute separately for both the public and private keys, which means the key pairs can be stored in different keystores.

Refer to the following table for detailed explanations of the relationship between user types, key attributes, and keystores, and how keys are stored.

Table 1. Cases of storing EP11 keys in different keystores
User type CKA_TOKEN CKA_PRIVATE Keystore for keys Private or public?
SO user FALSE N/A In-memory keystore Public
SO user TRUE N/A Database-backed keystore Public
Anonymous user FALSE N/A In-memory keystore Public
Anonymous user TRUE N/A Database-backed keystore Public
Normal user FALSE FALSE In-memory keystore Public
Normal user FALSE TRUE In-memory keystore Private
Normal user TRUE FALSE Database-backed keystore Public
Normal user TRUE TRUE Database-backed keystore Private

Post-quantum cryptography support

With the PKCS #11 API, you can also perform post-quantum cryptographic operations. Traditional cryptography relies on complicated mathematical problems that are difficult for classical computers to solve. However, with the computing capabilities, quantum computers can solve these problems. Post-quantum cryptography is considered to be resistant to cryptanalytic attacks from quantum computers. It usually uses asymmetric algorithms and has multiple approaches.

The PKCS #11 API provides the Dilithium algorithm for post-quantum cryptography. It is a lattice-based digital signature scheme and can be used for signature generation and verification. Currently, only the high-security version of round 2 Dilithium is supported and it is not available for C_SignUpdate and C_VerifyUpdate operations.

The Dilithium algorithm is supported only by the IBM 4769 crypto card, also referred to as Crypto Express 7S (CEX7S). If you create your instances in Virtual Private Cloud (VPC) based regions, where the CEX7S crypto cards are used, you can use the Dilithium algorithm for post-quantum cryptography with the PKCS #11 API. For a list of VPC-based regions, see Regions and locations.

For more information about Dilithium algorithm support in PKCS #11, see PKCS #11 API reference. You can also find Dilithium algorithm code examples in the GitHub sample repository.