Storage Encryption
------------------
A PKCS#11 token uses a storage component to save keys.
In the case of a software token, it is a good idea to encrypt sensitive
information in the storage so that keys cannot be easily stolen or tampered
with.
Kryoptic adopts a flexible and agile encryption system that allows for future
changes while maintaining reasonable compatibility.
The aim of the v1 scheme identified here is to provide reasonable security
while allowing simplified operations.
The token allows for two PINs to be used, the SO PIN and the USER PIN.
The SO PIN is considered a recovery PIN. Both PINs allow for access to the
key material.
The PINs are used in conjunction with PBKDF2 to derive a KEK that is used to
decrypt the storage Encryption key. The Encryption key is versioned and is used
to encrypt each secret attribute individually by using a key derivation step to
obtain an object specific key. The Key Derivation algorithms and parameters are
flexibly defined by wrapping the keys and encrypted values using PKCS#5 like
ASN.1 structures.
This OID has been defined to identify the HKDF-Expand Key Derivation function:
1.3.6.1.4.1.2312.20.1.1
KKBPS - Kryoptic Key Based Protection Scheme v1
===============================================
The object identifier id-KKBPS1 identifies this scheme: 1.3.6.1.4.1.2312.20.2.1
This is the structure used to define all the parameters and identify the keys
used to encrypt or integrity protect keys or other secrets.
For object encryption the Key derivation is a simple HKDF-Expand operation that
uses a key generated via a cryptographic RNG.
HKDF-Expand(RK, info, L) -> EK
where:
- RK: randomly generated key
- info: a string uniquely identifying the object carrying the attribute
- L: the length of the derived EK
- EK: The key used for the actual encryption
Encryption is performed using AES-GCM
AES-GCM(EK, IV, AAD, data) -> ED, TAG
where:
- EK: The Key generated by the Key derivation Step
- IV: A nonce generated via a cryptographic RNG
- AAD: The attribute type represented as a little endian u32
- data: The data to be protected
- ED: The encrypted data
- TAG: The authentication tag (64bit in length)
The standard PBKDF2 to derive the encryption key used to protect the Key
Encryption Key, also referenced as RK above.
The ASN.1 structure used to encode the parameters:
KKBPS1-params ::= SEQUENCE {
keyVersionNumber INTEGER,
keyDerivationFunc AlgorithmIdentifier {{KKBPS1-KDFs}},
encryptionScheme AlgorithmIdentifier {{KKBPS1-Encs}}
}
KKBPS1-KDFs ALGORITHM-IDENTIFIER ::= {
{KKDF1-params IDENTIFIED BY id-KKDF1},
{PBKDF2-params IDENTIFIED BY id-PBKDF2},
...
}
KKDF1-params ::= SEQUENCE {
prf AlgorithmIdentifier
info OCTET STRING,
keyLength INTEGER (16 | 24 | 32),
}
KKBPS1-Encs ALGORITHM-IDENTIFIER ::= {
{aes128gcm IDENTIFIED BY id-aes128-GCM},
{aes192gcm IDENTIFIED BY id-aes192-GCM},
{aes256gcm IDENTIFIED BY id-aes256-GCM},
...
}
The GCM Paramters are defined as:
KGCMParameters::= SEQUENCE {
aesIv OCTET STRING (SIZE(12)),
aesTag OCTET STRING (SIZE(8)),
}
Kryoptic Protected Data
=======================
This structure encapsulates the data and all the parameters needed for
protection, whether that is encryption/decryption or just integrity tags.
It is defined as:
KPD1 ::= SEQUENCE {
algorithm AlgorithmIdentifier {
{KKBPS1-params IDENTIFIED BY id-KKBPS1}
},
data OCTET STRING,
signature OCTET STRING OPTIONAL
}