Merge "Adding spec for Barbican MKEK Model."
This commit is contained in:
commit
3d426624de
|
@ -0,0 +1,271 @@
|
|||
..
|
||||
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
||||
License.
|
||||
|
||||
http://creativecommons.org/licenses/by/3.0/legalcode
|
||||
|
||||
==========================================
|
||||
KMIP MKEK Model Plugin
|
||||
==========================================
|
||||
|
||||
https://blueprints.launchpad.net/barbican/+spec/babrican-mkek-model
|
||||
|
||||
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.
|
||||
|
||||
Problem Description
|
||||
===================
|
||||
|
||||
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.
|
||||
|
||||
Proposed Change
|
||||
===============
|
||||
|
||||
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.
|
||||
|
||||
Alternatives
|
||||
------------
|
||||
|
||||
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.
|
||||
|
||||
Data model impact
|
||||
-----------------
|
||||
|
||||
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.
|
||||
|
||||
REST API impact
|
||||
---------------
|
||||
|
||||
No changes need to be made to the REST API.
|
||||
|
||||
Security impact
|
||||
---------------
|
||||
|
||||
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.
|
||||
|
||||
Notifications & Audit Impact
|
||||
----------------------------
|
||||
|
||||
N/A
|
||||
|
||||
Other end user impact
|
||||
---------------------
|
||||
|
||||
N/A
|
||||
|
||||
Performance Impact
|
||||
------------------
|
||||
|
||||
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.
|
||||
|
||||
Other deployer impact
|
||||
---------------------
|
||||
|
||||
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.
|
||||
|
||||
Developer impact
|
||||
----------------
|
||||
|
||||
N/A the plugin is self contained.
|
||||
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
Assignee(s)
|
||||
-----------
|
||||
|
||||
Primary assignee:
|
||||
tim-kelsey <tkelsey>
|
||||
rob-clark <hyakuhei>
|
||||
|
||||
Other contributors:
|
||||
None
|
||||
|
||||
Work Items
|
||||
----------
|
||||
|
||||
- Create spec (this spec).
|
||||
- Write the plugin and tests.
|
||||
- Confirm all Barbican tests, new and old, still pass.
|
||||
- Review the code.
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
This will require no new dependencies over KMIPSecretStore, that is it will
|
||||
require PyKMIP library v0.2 or greater.
|
||||
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Documentation Impact
|
||||
====================
|
||||
|
||||
No changes to documented APIs will be needed. New plugin specific configuration
|
||||
options will be created, and these should be documented.
|
||||
|
||||
+----------------------------------+-----------------------------------+
|
||||
| Option | Meaning |
|
||||
+==================================+===================================+
|
||||
| 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. |
|
||||
+----------------------------------+-----------------------------------+
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
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
|
Loading…
Reference in New Issue