diff --git a/block/keyslot-manager.c b/block/keyslot-manager.c index 52f94a5a9680..8209db5ab1e1 100644 --- a/block/keyslot-manager.c +++ b/block/keyslot-manager.c @@ -425,3 +425,41 @@ void keyslot_manager_destroy(struct keyslot_manager *ksm) } } EXPORT_SYMBOL_GPL(keyslot_manager_destroy); + +/** + * keyslot_manager_derive_raw_secret() - Derive software secret from wrapped key + * @ksm: The keyslot manager + * @wrapped_key: The wrapped key + * @wrapped_key_size: Size of the wrapped key in bytes + * @secret: (output) the software secret + * @secret_size: (output) the number of secret bytes to derive + * + * Given a hardware-wrapped key, ask the hardware to derive a secret which + * software can use for cryptographic tasks other than inline encryption. The + * derived secret is guaranteed to be cryptographically isolated from the key + * with which any inline encryption with this wrapped key would actually be + * done. I.e., both will be derived from the unwrapped key. + * + * Return: 0 on success, -EOPNOTSUPP if hardware-wrapped keys are unsupported, + * or another -errno code. + */ +int keyslot_manager_derive_raw_secret(struct keyslot_manager *ksm, + const u8 *wrapped_key, + unsigned int wrapped_key_size, + u8 *secret, unsigned int secret_size) +{ + int err; + + down_write(&ksm->lock); + if (ksm->ksm_ll_ops.derive_raw_secret) { + err = ksm->ksm_ll_ops.derive_raw_secret(ksm, wrapped_key, + wrapped_key_size, + secret, secret_size); + } else { + err = -EOPNOTSUPP; + } + up_write(&ksm->lock); + + return err; +} +EXPORT_SYMBOL_GPL(keyslot_manager_derive_raw_secret); diff --git a/include/linux/keyslot-manager.h b/include/linux/keyslot-manager.h index fbc423fe5cd5..17dfcaf208fb 100644 --- a/include/linux/keyslot-manager.h +++ b/include/linux/keyslot-manager.h @@ -18,6 +18,9 @@ struct keyslot_manager; * The key is provided so that e.g. dm layers can evict * keys from the devices that they map over. * Returns 0 on success, -errno otherwise. + * @derive_raw_secret: (Optional) Derive a software secret from a + * hardware-wrapped key. Returns 0 on success, -EOPNOTSUPP + * if unsupported on the hardware, or another -errno code. * * This structure should be provided by storage device drivers when they set up * a keyslot manager - this structure holds the function ptrs that the keyslot @@ -30,6 +33,10 @@ struct keyslot_mgmt_ll_ops { int (*keyslot_evict)(struct keyslot_manager *ksm, const struct blk_crypto_key *key, unsigned int slot); + int (*derive_raw_secret)(struct keyslot_manager *ksm, + const u8 *wrapped_key, + unsigned int wrapped_key_size, + u8 *secret, unsigned int secret_size); }; struct keyslot_manager *keyslot_manager_create(unsigned int num_slots, @@ -57,4 +64,9 @@ void *keyslot_manager_private(struct keyslot_manager *ksm); void keyslot_manager_destroy(struct keyslot_manager *ksm); +int keyslot_manager_derive_raw_secret(struct keyslot_manager *ksm, + const u8 *wrapped_key, + unsigned int wrapped_key_size, + u8 *secret, unsigned int secret_size); + #endif /* __LINUX_KEYSLOT_MANAGER_H */