- C_GetSlotList(), C_GetSlotInfo() obtains a list of available slots and information on each slot (e.g., whether a token is present or the token represents a removable device).
- C_WaitFor Slot Event() waits for a token to be inserted or removed.
- C_InitToken(), C_GetTokenInfo() initializes an inserted token and provides information on the token (e.g., whether a login is required to use the token, a count of failed logins, information on whether the token has a random number generator, etc.).
- C_InitPIN(), C_SetPIN() manages the PIN used to protect a token from unauthorized access.
Figure 1 shows a cryptoki with different tokens plugged into its slots. The first token uses a cryptographic adapter, the second token uses a smart card, the third token is a self-contained cryptographic library and the forth token interfaces to another cryptographic library. The application uses the second token for signing and the fourth token for decryption.
Roles and Sessions
PKCS#11 knows two different roles per token. Each role can authenticate itself by a PIN specific to that role and a token. The first role is that of the security officer (SO). The SO initializes the token and can set the PIN of the user. The second role is that of the (normal) user. The user can log-in to sessions, create and access private objects and perform cryptographic operations (which will be explained later).
A session is a token-specific context for one or more cryptographic operations. It maintains the intermediate state of multipart functions such as encryption of a message that’s worked on one network packet at a time. Roughly speaking, within one session, only one cryptographic operation can be processed at a time, but a program may open multiple sessions concurrently.
There are different types of sessions: Each session is either a read-only session or a readwrite session and each session is either a public session or user session. Read-only sessions may not create or modify objects. A public session can only access public objects whereas a user session can access the user’s private objects. All sessions of a token become user sessions after a log-in to one of the sessions of that token.
The PKCS#11 API provides session functions such as:
- C_OpenSession(), C_CloseSession() to open and close a session
- C_GetSessionInfo() to provide information on the type of a session
- C_GetOperationState() and C_SetOperationState() to allow checkpoint and restart of a multipart cryptographic operation
- C_Login(), Logout() to toggle sessions from being public to being user sessions and vice versa. The user PIN is required to log-in.
Generic Cryptographic Functions and Mechanisms
The PKCS#11 API defines a small set of generic cryptographic functions to do the following tasks:
- Encrypt and decrypt messages
- Computing digests (aka hashes) of messages
- Sign messages and verify signatures
- Generate symmetric keys or asymmetric key pairs and deriving keys
- Wrap and unwrap keys
- Generate random numbers.
With the exception of generating random numbers, these generic cryptographic functions accept a mechanism parameter that defines the specific instance of that function. Figure 2 shows an example of a specific call to a generic cryptographic function where the generic encryption function takes an AES_CBC mechanism as argument to encrypt a message with AES encryption in the cipher block chaining (CBC) mode of operation using a key (and an initialization vector not shown in the figure). Each cryptographic function is executed in the context of a session.
Most cryptographic functions must be initialized by calling an initialization function that takes a session parameter, a mechanism parameter and function-specific parameters such as keys. For cryptographic function xyz, the initialization function is called C_XyzInit(). Once a function is initialized, the actual function invocation can take place either as a single-part function of the form C_Xyz() or as a multipart function where one or more calls to a function of the form C_XyzUpdate() are finalized by a call to C_XyzFinal(). Figure 3 lists the set of generic cryptographic functions together with their variants to initialize, update and finalize the operation. Here the occurrence of x in the line of Verify and the column headed by C_FktUpdate denotes the function C_VerifyUpdate() as belonging to the PKCS#11 API.