KEYS: trusted: allow use of kernel RNG for key material
The two existing trusted key sources don't make use of the kernel RNG, but instead let the hardware doing the sealing/unsealing also generate the random key material. However, both users and future backends may want to place less trust into the quality of the trust source's random number generator and instead reuse the kernel entropy pool, which can be seeded from multiple entropy sources. Make this possible by adding a new trusted.rng parameter, that will force use of the kernel RNG. In its absence, it's up to the trust source to decide, which random numbers to use, maintaining the existing behavior. Suggested-by: Jarkko Sakkinen <jarkko@kernel.org> Acked-by: Sumit Garg <sumit.garg@linaro.org> Acked-by: Pankaj Gupta <pankaj.gupta@nxp.com> Reviewed-by: David Gstir <david@sigma-star.at> Reviewed-by: Pankaj Gupta <pankaj.gupta@nxp.com> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Tested-by: Pankaj Gupta <pankaj.gupta@nxp.com> Tested-by: Michael Walle <michael@walle.cc> # on ls1028a (non-E and E) Tested-by: John Ernberg <john.ernberg@actia.se> # iMX8QXP Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
This commit is contained in:
parent
be07858fbf
commit
fcd7c26901
|
@ -5963,6 +5963,16 @@
|
||||||
first trust source as a backend which is initialized
|
first trust source as a backend which is initialized
|
||||||
successfully during iteration.
|
successfully during iteration.
|
||||||
|
|
||||||
|
trusted.rng= [KEYS]
|
||||||
|
Format: <string>
|
||||||
|
The RNG used to generate key material for trusted keys.
|
||||||
|
Can be one of:
|
||||||
|
- "kernel"
|
||||||
|
- the same value as trusted.source: "tpm" or "tee"
|
||||||
|
- "default"
|
||||||
|
If not specified, "default" is used. In this case,
|
||||||
|
the RNG's choice is left to each individual trust source.
|
||||||
|
|
||||||
tsc= Disable clocksource stability checks for TSC.
|
tsc= Disable clocksource stability checks for TSC.
|
||||||
Format: <string>
|
Format: <string>
|
||||||
[x86] reliable: mark tsc clocksource as reliable, this
|
[x86] reliable: mark tsc clocksource as reliable, this
|
||||||
|
|
|
@ -87,22 +87,26 @@ Key Generation
|
||||||
Trusted Keys
|
Trusted Keys
|
||||||
------------
|
------------
|
||||||
|
|
||||||
New keys are created from random numbers generated in the trust source. They
|
New keys are created from random numbers. They are encrypted/decrypted using
|
||||||
are encrypted/decrypted using a child key in the storage key hierarchy.
|
a child key in the storage key hierarchy. Encryption and decryption of the
|
||||||
Encryption and decryption of the child key must be protected by a strong
|
child key must be protected by a strong access control policy within the
|
||||||
access control policy within the trust source.
|
trust source. The random number generator in use differs according to the
|
||||||
|
selected trust source:
|
||||||
|
|
||||||
* TPM (hardware device) based RNG
|
* TPM: hardware device based RNG
|
||||||
|
|
||||||
Strength of random numbers may vary from one device manufacturer to
|
Keys are generated within the TPM. Strength of random numbers may vary
|
||||||
another.
|
from one device manufacturer to another.
|
||||||
|
|
||||||
* TEE (OP-TEE based on Arm TrustZone) based RNG
|
* TEE: OP-TEE based on Arm TrustZone based RNG
|
||||||
|
|
||||||
RNG is customizable as per platform needs. It can either be direct output
|
RNG is customizable as per platform needs. It can either be direct output
|
||||||
from platform specific hardware RNG or a software based Fortuna CSPRNG
|
from platform specific hardware RNG or a software based Fortuna CSPRNG
|
||||||
which can be seeded via multiple entropy sources.
|
which can be seeded via multiple entropy sources.
|
||||||
|
|
||||||
|
Users may override this by specifying ``trusted.rng=kernel`` on the kernel
|
||||||
|
command-line to override the used RNG with the kernel's random number pool.
|
||||||
|
|
||||||
Encrypted Keys
|
Encrypted Keys
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ struct trusted_key_ops {
|
||||||
/* Unseal a key. */
|
/* Unseal a key. */
|
||||||
int (*unseal)(struct trusted_key_payload *p, char *datablob);
|
int (*unseal)(struct trusted_key_payload *p, char *datablob);
|
||||||
|
|
||||||
/* Get a randomized key. */
|
/* Optional: Get a randomized key. */
|
||||||
int (*get_random)(unsigned char *key, size_t key_len);
|
int (*get_random)(unsigned char *key, size_t key_len);
|
||||||
|
|
||||||
/* Exit key interface. */
|
/* Exit key interface. */
|
||||||
|
|
|
@ -16,12 +16,17 @@
|
||||||
#include <linux/key-type.h>
|
#include <linux/key-type.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/parser.h>
|
#include <linux/parser.h>
|
||||||
|
#include <linux/random.h>
|
||||||
#include <linux/rcupdate.h>
|
#include <linux/rcupdate.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/static_call.h>
|
#include <linux/static_call.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
|
static char *trusted_rng = "default";
|
||||||
|
module_param_named(rng, trusted_rng, charp, 0);
|
||||||
|
MODULE_PARM_DESC(rng, "Select trusted key RNG");
|
||||||
|
|
||||||
static char *trusted_key_source;
|
static char *trusted_key_source;
|
||||||
module_param_named(source, trusted_key_source, charp, 0);
|
module_param_named(source, trusted_key_source, charp, 0);
|
||||||
MODULE_PARM_DESC(source, "Select trusted keys source (tpm or tee)");
|
MODULE_PARM_DESC(source, "Select trusted keys source (tpm or tee)");
|
||||||
|
@ -312,8 +317,14 @@ struct key_type key_type_trusted = {
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(key_type_trusted);
|
EXPORT_SYMBOL_GPL(key_type_trusted);
|
||||||
|
|
||||||
|
static int kernel_get_random(unsigned char *key, size_t key_len)
|
||||||
|
{
|
||||||
|
return get_random_bytes_wait(key, key_len) ?: key_len;
|
||||||
|
}
|
||||||
|
|
||||||
static int __init init_trusted(void)
|
static int __init init_trusted(void)
|
||||||
{
|
{
|
||||||
|
int (*get_random)(unsigned char *key, size_t key_len);
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(trusted_key_sources); i++) {
|
for (i = 0; i < ARRAY_SIZE(trusted_key_sources); i++) {
|
||||||
|
@ -322,6 +333,28 @@ static int __init init_trusted(void)
|
||||||
strlen(trusted_key_sources[i].name)))
|
strlen(trusted_key_sources[i].name)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We always support trusted.rng="kernel" and "default" as
|
||||||
|
* well as trusted.rng=$trusted.source if the trust source
|
||||||
|
* defines its own get_random callback.
|
||||||
|
*/
|
||||||
|
get_random = trusted_key_sources[i].ops->get_random;
|
||||||
|
if (trusted_rng && strcmp(trusted_rng, "default")) {
|
||||||
|
if (!strcmp(trusted_rng, "kernel")) {
|
||||||
|
get_random = kernel_get_random;
|
||||||
|
} else if (strcmp(trusted_rng, trusted_key_sources[i].name) ||
|
||||||
|
!get_random) {
|
||||||
|
pr_warn("Unsupported RNG. Supported: kernel");
|
||||||
|
if (get_random)
|
||||||
|
pr_cont(", %s", trusted_key_sources[i].name);
|
||||||
|
pr_cont(", default\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!get_random)
|
||||||
|
get_random = kernel_get_random;
|
||||||
|
|
||||||
static_call_update(trusted_key_init,
|
static_call_update(trusted_key_init,
|
||||||
trusted_key_sources[i].ops->init);
|
trusted_key_sources[i].ops->init);
|
||||||
static_call_update(trusted_key_seal,
|
static_call_update(trusted_key_seal,
|
||||||
|
@ -329,7 +362,7 @@ static int __init init_trusted(void)
|
||||||
static_call_update(trusted_key_unseal,
|
static_call_update(trusted_key_unseal,
|
||||||
trusted_key_sources[i].ops->unseal);
|
trusted_key_sources[i].ops->unseal);
|
||||||
static_call_update(trusted_key_get_random,
|
static_call_update(trusted_key_get_random,
|
||||||
trusted_key_sources[i].ops->get_random);
|
get_random);
|
||||||
static_call_update(trusted_key_exit,
|
static_call_update(trusted_key_exit,
|
||||||
trusted_key_sources[i].ops->exit);
|
trusted_key_sources[i].ops->exit);
|
||||||
migratable = trusted_key_sources[i].ops->migratable;
|
migratable = trusted_key_sources[i].ops->migratable;
|
||||||
|
|
Loading…
Reference in New Issue