[Cryptech Tech] export/import of "raw" keys

Paul Selkirk paul at psgd.org
Wed Nov 6 22:28:04 UTC 2019


I finally got around to implementing export/import of "raw" keys for
external storage. These are keys, straight out of the keystore, wrapped
with the MKM KEK. The use case is an operator with more keys than will
fit on the HSM, who wants to securely cycle keys in and out of the HSM
from an external database.

What we have until now is a mechanism designed for copying keys from one
HSM to another (for disaster recovery, load balancing, or whatever). The
destination HSM generates an RSA key (the transit KEK), and the user
loads the public key into the source HSM. On the source HSM, the EXPORT
RPC fetches the key-of-interest (unwrapping it with the MKM KEK), wraps
it with a randomly-generated AES key, encrypts the AES key with the
transit KEK, and hands the wrapped key and the encrypted wrapping key to
the user. On the destination HSM, the IMPORT RPC decrypts the AES key
with the transit KEK private key, unwraps the key-of-interest, and loads
it into the local keystore (wrapping it with the local MKM KEK).

My initial thought was to have one HSM be both source and destination,
with both halves of the RSA transit KEK (public for export, private for
import). But there's a chicken-and-egg problem where the transit KEK
can't be exported securely, so if the HSM fails, all the keys are lost.
Or the transit KEK is generated on the external host, and loaded onto
the HSM in plaintext.

Instead, this scenario calls for exporting keys straight out of the
keystore, wrapped with the MKM KEK.

In addition to the thousands-of-keys use case, this could be used for
disaster recovery; in the case of explosion or tampering, you could
bring up a blank HSM, re-enter the KEK from the console, and raw-import
keys from the external keystore.

For reasons, it made sense to create two new RPCs: EXPORT_RAW and
IMPORT_RAW, similar to EXPORT and IMPORT, but without the kek and kekek
arguments. It would be possible to shoe-horn them into EXPORT and
IMPORT, by supplying null kek and kekek arguments, but they're actually
implemented as separate functions internally.

Note that hashsig keys require extra care. Because they have internal
state that is updated on every signing operation, we cannot allow the
key to be re-used with the same state. On a "normal" export (for copying
to another HSM, as above), the keyspace is partitioned. On "raw" export
(for external storage, as described here), the hashsig key is disabled,
and must be deleted. Likewise, when a hashsig key is raw-imported, it
must be re-exported after being used, because the internal state will be
changed. (We don't have a mechanism to enforce this, but just have to
count on the user to understand what hashsig keys are, and how to use them.)

Anyway, this is all in sw/libhal, branch import_export_raw.

				paul


More information about the Tech mailing list