This effort aims to improve on the scalability of the existing KMIP integration offered by Barbican. Specifically by removing possible scale limitations imposed by the number of project secrets that can be stored in a KMIP attached HSM. We propose adding a new plugin that implements a Master Key Encryption (MKEK) based model. Under this model, locally stored project secrets, termed Data Encryption Keys (DEKs), are protected by per-project Key Encryption Keys (KEKs) that are themselves protected by the use of a Master Key Encryption Key (MKEK). This functionality mirrors that offered by similar MKEK operations available to users of the PKCS11 ‘p11’ plugin.
Currently, Barbican can utilise HSMs that communicate via KMIP to generate and store key material on behalf of projects. However, several HSM appliances are restricted by the maximum number of keys that can be stored. This maximum could be easily exceeded in large cloud deployments.
To combat this problem a model is presented here that stores project key material locally within the Barbican database. This will be implemented as a plugin following the same basic design as the PKCS11 plugin and deriving from the CryptoPluginBase interface.
To protect the local key material it is itself encrypted using a per-project Key Encryption Key. This process is referred to as wrapping the key and a wrapped key refers to the cipher text version of a given key value. All project key material is wrapped using that project’s unique KEK prior to storage, and this wrapping is performed by the attached HSM appliance. By wrapping all keys belonging to a project with a unique KEK we gain two advantages. Firstly, project separation is enhanced, a project acquiring another project’s wrapped keys will be unable to utilise them. Secondly, in the event that a project’s key material must be presented to a third party (on the issuing of a warrant or other access demand) only that specific project’s KEK must be surrendered, other projects remain fully protected.
The KEKs belonging to various projects are themselves stored locally within the Barbican database. To protect the KEKs from exposure should the database be compromised, they themselves will be wrapped using a single Master Key Encryption Key, or MKEK. No unwrapped project KEKs will be stored and this wrapping process will again be performed by the HSM. The MKEK used is global to the running Barbican deployment and is considered to be owned by the deployer, rather than by any project. It is generated on the backend HSM and stored there, the MKEK is never fetched locally into Barbican process memory as (un)wrapping operations are performed within the HSM.
The following operations are required:
Key Initialisation, MKEK generation. Initially a new MKEK will be created on the HSM and a reference will be stored to it in the local Barbican database. Note that the MKEK itself remains on the HSM and only its reference is stored. This logic will be placed within the bind_kek_metadata() method, when discovering that a MKEK is not available for use a new one will be generated.
Project Initialisation, KEK generation. A new project will be initialised by using the HSM to create a KEK for the project. This KEK will then be retrieved, as a wrapped key using the MKEK that resides on the HSM as a wrapping key. The wrapped KEK is stored in Barbican’s database and the KEK will be removed from the HSM. This logic will be placed within the bind_kek_metadata() method. Either a pre-existing KEK will be returned or a new one will be generated if no KEK exists for the project.
Project Data Encryption Key (DEK) generation. A new key will be generated by the HSM and its reference returned to Barbican. Barbican will then send the wrapped project KEK to the HSM as a wrapped key, and provide its reference to the MKEK as the wrapping key so the HSM may unwrap it. Finally, using the DEK reference, Barbican will request the newly generated DEK be returned, wrapped by the now unwrapped KEK. This wrapped DEK is stored in the local database and the DEK and KEK will be removed from the HSM. This logic will be placed within the generate_symmetric() and generate_asymmetric() methods for symmetric and asymmetric DEKs respectively.
Project Data Encryption Key (DEK) storage. Barbican will send the wrapped project KEK to the HSM as a wrapped key, and provide its reference to the MKEK as the wrapping key so the HSM may unwrap it. An unwrapped DEK, provided by the project, will be sent to the HSM and then retrieved, wrapped by the projects KEK. This wrapped DEK will be stored in the local Barbican database. The unwrapped DEK and KEK will now be removed from the HSM. This logic will placed within the the encrypt() interface method.
Project Data Encryption Key (DEK) retrieval. A project wrapped DEK (its encrypted secret) will be retrieved from Barbican’s database by first sending the wrapped project KEK to the HSM and a reference to the MKEK to unwrap it, this results in a reference to the unwrapped KEK. Barbican will then send the wrapped DEK to the HSM and the reference to the unwrapped KEK to unwrap the DEK. Finally, Barbican can now retrieve the unwrapped DEK and return it to the requesting user. The unwrapped DEK and KEK will now be removed from the HSM. This logic will placed within the decrypt() interface method.
Master Key Encryption Key Rotation. The specifics of MKEK rotation and re-keying are beyond the scope of this spec and will be tackled independently. However, information is provided here to illustrate how this might be accomplished under the proposed model.
Should it be required that the MKEK be rotated out and a new one created, then this might be accomplish as follows. Firstly a new MKEK is generated on the HSM and its reference retrieved and stored as the active MKEK version, termed ‘originator-usage’. When a new project KEK must be created, the MKEK currently operating in originator-usage will be used for wrapping and its reference stored alongside the wrapped KEK as meta data. This MKEK reference data will allow Barbican to indicate the correct master key to be used during unwrapping. Former MKEKs are maintained in the HSM for retrieval of data only, termed ‘recipient-usage’. In this way new KEKs are protected by the new MKEK and older ones remain viable by referencing the earlier MKEKs stored in the HSM.
After a recipient-usage MKEK reaches a defined age, all KEKs wrapped by it should be re-keyed, that is unwrapped and then re-wrapped, using the originator-usage key. The period of time that an MKEK may remain valid for recipient-usage is termed the crypto-period and is defined via a config setting.
An existing plugin, the KMIPSecretStore is already available to Barbican and can be considered as an alternative to the MKEK model. It uses KMIP to communicate with a backend HSM and stores all key material within the HSM itself. As such it is limited by the HSMs own storage capacity.
No changes to the data model are required. All needed data can be stored as plugin specific meta-data. The wrapped per-project KEK will be stored, along with a reference to the MKEK in the kek_meta_dto object. If some form of key rotation is in effect (again, the specific details of key rotation are beyond the scope of this spec) then MKEK version info will be stored in the per-secret kek_extended_meta_dto object.
No changes need to be made to the REST API.
This change uses encryption on the HSM to protect key material, however it introduces no additional security concerns over the existing KMIPSecretStore plugin. Project DEKs are stored in the local database but they are protected by the project KEK. The project KEK is store in the local database and this is protected by the MKEK. The MKEK is never stored or used outside of the HSM.
This change will incur a performance impact through additional communication to the backend HSM. These communications will need to be protected through the use of a TLS secured link. Additionally operations at scale will be limited to how rapidly the HSM can (un)wrap and return key material. Generally this is a fast operation but will be subject to network latency communicating to the HSM.
We expect this overhead to be exaggerated initially owing to the use of simple atomic KMIP operations. Once more complex compound operations are supported by the underlying library this situation will be improved.
No additional deployment impact is created by this proposed change over that required by the KMIPSecretStore. That is, a backend HSM that can communicate via KMIP must be available and contactable for successful operation.
Note also that although the plugin contract remains the same as the existing KMIPSecretStore plugin, the semantics of the stored data are incompatible. Since this is a new plugin rather than a modification to the existing KMIP plugin it is believed that no data versioning should be required since data generated by the respective plugins should be considered entirely incompatible.
N/A the plugin is self contained.
This will require no new dependencies over KMIPSecretStore, that is it will require PyKMIP library v0.2 or greater.
A suite of unit tests will be produced to test the new code. In order to test the plugin functionality fully a KMIP capable HSM will need to be available to gate tests.
No changes to documented APIs will be needed. New plugin specific configuration options will be created, and these should be documented.
|mkek_crypto_plugin.crt_file_path||KMIP client certificate file path.|
|mkek_crypto_plugin.key_file_path||KMIP client key file.|
|mkek_crypto_plugin.key_password||KMIP client key password.|
|mkek_crypto_plugin.user_name||KMIP user name.|
|mkek_crypto_plugin.user_pass||KMIP user password.|
|mkek_crypto_plugin.hsm_host||HSM host IPs, comma separated.|
|mkek_crypto_plugin.hsm_port||HSM port number.|
Please refer to KMIPSecretStore plugin documentation. Please refer to the PKCS11 plugin MKEK implementation. Please refer to the previously merged spec for PKCS11 that solves a similar problem: https://review.openstack.org/#/c/107775/4/specs/juno/restructure-pkcs11-plugin.rst
The KMIP specification can be found at: http://docs.oasis-open.org/kmip/spec/v1.2/kmip-spec-v1.2.html