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 _______________________________________________ Tech mailing list Tech@cryptech.is https://lists.cryptech.is/listinfo/tech