Commit e9c5048c authored by Ahmad Fatoum's avatar Ahmad Fatoum Committed by Jarkko Sakkinen
Browse files

KEYS: trusted: Introduce support for NXP CAAM-based trusted keys



The Cryptographic Acceleration and Assurance Module (CAAM) is an IP core
built into many newer i.MX and QorIQ SoCs by NXP.

The CAAM does crypto acceleration, hardware number generation and
has a blob mechanism for encapsulation/decapsulation of sensitive material.

This blob mechanism depends on a device specific random 256-bit One Time
Programmable Master Key that is fused in each SoC at manufacturing
time. This key is unreadable and can only be used by the CAAM for AES
encryption/decryption of user data.

This makes it a suitable backend (source) for kernel trusted keys.

Previous commits generalized trusted keys to support multiple backends
and added an API to access the CAAM blob mechanism. Based on these,
provide the necessary glue to use the CAAM for trusted keys.

Reviewed-by: default avatarDavid Gstir <david@sigma-star.at>
Reviewed-by: default avatarPankaj Gupta <pankaj.gupta@nxp.com>
Reviewed-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
Tested-by: default avatarTim Harvey <tharvey@gateworks.com>
Tested-by: default avatarMatthias Schiffer <matthias.schiffer@ew.tq-group.com>
Tested-by: default avatarPankaj 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: default avatarAhmad Fatoum <a.fatoum@pengutronix.de>
Signed-off-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
parent 007c3ff1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5958,6 +5958,7 @@
			sources:
			- "tpm"
			- "tee"
			- "caam"
			If not specified then it defaults to iterating through
			the trust source list starting with TPM and assigns the
			first trust source as a backend which is initialized
+11 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
 */

#ifndef __CAAM_TRUSTED_KEY_H
#define __CAAM_TRUSTED_KEY_H

extern struct trusted_key_ops trusted_key_caam_ops;

#endif
+10 −1
Original line number Diff line number Diff line
@@ -24,6 +24,15 @@ config TRUSTED_KEYS_TEE
	  Enable use of the Trusted Execution Environment (TEE) as trusted
	  key backend.

if !TRUSTED_KEYS_TPM && !TRUSTED_KEYS_TEE
config TRUSTED_KEYS_CAAM
	bool "CAAM-based trusted keys"
	depends on CRYPTO_DEV_FSL_CAAM_JR >= TRUSTED_KEYS
	select CRYPTO_DEV_FSL_CAAM_BLOB_GEN
	default y
	help
	  Enable use of NXP's Cryptographic Accelerator and Assurance Module
	  (CAAM) as trusted key backend.

if !TRUSTED_KEYS_TPM && !TRUSTED_KEYS_TEE && !TRUSTED_KEYS_CAAM
comment "No trust source selected!"
endif
+2 −0
Original line number Diff line number Diff line
@@ -12,3 +12,5 @@ trusted-$(CONFIG_TRUSTED_KEYS_TPM) += trusted_tpm2.o
trusted-$(CONFIG_TRUSTED_KEYS_TPM) += tpm2key.asn1.o

trusted-$(CONFIG_TRUSTED_KEYS_TEE) += trusted_tee.o

trusted-$(CONFIG_TRUSTED_KEYS_CAAM) += trusted_caam.o
+80 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
 */

#include <keys/trusted_caam.h>
#include <keys/trusted-type.h>
#include <linux/build_bug.h>
#include <linux/key-type.h>
#include <soc/fsl/caam-blob.h>

static struct caam_blob_priv *blobifier;

#define KEYMOD "SECURE_KEY"

static_assert(MAX_KEY_SIZE + CAAM_BLOB_OVERHEAD <= CAAM_BLOB_MAX_LEN);
static_assert(MAX_BLOB_SIZE <= CAAM_BLOB_MAX_LEN);

static int trusted_caam_seal(struct trusted_key_payload *p, char *datablob)
{
	int ret;
	struct caam_blob_info info = {
		.input  = p->key,  .input_len   = p->key_len,
		.output = p->blob, .output_len  = MAX_BLOB_SIZE,
		.key_mod = KEYMOD, .key_mod_len = sizeof(KEYMOD) - 1,
	};

	ret = caam_encap_blob(blobifier, &info);
	if (ret)
		return ret;

	p->blob_len = info.output_len;
	return 0;
}

static int trusted_caam_unseal(struct trusted_key_payload *p, char *datablob)
{
	int ret;
	struct caam_blob_info info = {
		.input   = p->blob,  .input_len  = p->blob_len,
		.output  = p->key,   .output_len = MAX_KEY_SIZE,
		.key_mod = KEYMOD,  .key_mod_len = sizeof(KEYMOD) - 1,
	};

	ret = caam_decap_blob(blobifier, &info);
	if (ret)
		return ret;

	p->key_len = info.output_len;
	return 0;
}

static int trusted_caam_init(void)
{
	int ret;

	blobifier = caam_blob_gen_init();
	if (IS_ERR(blobifier))
		return PTR_ERR(blobifier);

	ret = register_key_type(&key_type_trusted);
	if (ret)
		caam_blob_gen_exit(blobifier);

	return ret;
}

static void trusted_caam_exit(void)
{
	unregister_key_type(&key_type_trusted);
	caam_blob_gen_exit(blobifier);
}

struct trusted_key_ops trusted_key_caam_ops = {
	.migratable = 0, /* non-migratable */
	.init = trusted_caam_init,
	.seal = trusted_caam_seal,
	.unseal = trusted_caam_unseal,
	.exit = trusted_caam_exit,
};
Loading