aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.14/817-platform-security-support-layerscape.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.14/817-platform-security-support-layerscape.patch')
-rw-r--r--target/linux/layerscape/patches-4.14/817-platform-security-support-layerscape.patch1443
1 files changed, 1443 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-4.14/817-platform-security-support-layerscape.patch b/target/linux/layerscape/patches-4.14/817-platform-security-support-layerscape.patch
new file mode 100644
index 0000000000..8f378d40ca
--- /dev/null
+++ b/target/linux/layerscape/patches-4.14/817-platform-security-support-layerscape.patch
@@ -0,0 +1,1443 @@
+From d2e808b0dcca1b5e850274f770775c355ae36c48 Mon Sep 17 00:00:00 2001
+From: Biwen Li <biwen.li@nxp.com>
+Date: Tue, 30 Oct 2018 18:27:03 +0800
+Subject: [PATCH 34/40] platfrom-security: support layerscape
+This is an integrated patch of platform-security for
+ layerscape
+
+Signed-off-by: Sahil Malhotra <sahil.malhotra@nxp.com>
+Signed-off-by: Udit Agarwal <udit.agarwal@nxp.com>
+Signed-off-by: Biwen Li <biwen.li@nxp.com>
+---
+ Documentation/security/keys/secure-key.rst | 67 ++
+ MAINTAINERS | 12 +
+ drivers/tee/optee/Kconfig | 8 +
+ drivers/tee/optee/core.c | 2 +-
+ include/keys/secure-type.h | 33 +
+ security/keys/Kconfig | 11 +
+ security/keys/Makefile | 5 +
+ security/keys/encrypted-keys/Makefile | 2 +
+ security/keys/encrypted-keys/encrypted.c | 13 +-
+ security/keys/encrypted-keys/encrypted.h | 13 +
+ .../keys/encrypted-keys/masterkey_secure.c | 37 ++
+ security/keys/secure_key.c | 339 ++++++++++
+ security/keys/securekey_desc.c | 608 ++++++++++++++++++
+ security/keys/securekey_desc.h | 141 ++++
+ 14 files changed, 1288 insertions(+), 3 deletions(-)
+ create mode 100644 Documentation/security/keys/secure-key.rst
+ create mode 100644 include/keys/secure-type.h
+ create mode 100644 security/keys/encrypted-keys/masterkey_secure.c
+ create mode 100644 security/keys/secure_key.c
+ create mode 100644 security/keys/securekey_desc.c
+ create mode 100644 security/keys/securekey_desc.h
+
+--- /dev/null
++++ b/Documentation/security/keys/secure-key.rst
+@@ -0,0 +1,67 @@
++==========
++Secure Key
++==========
++
++Secure key is the new type added to kernel key ring service.
++Secure key is a symmetric type key of minimum length 32 bytes
++and with maximum possible length to be 128 bytes. It is produced
++in kernel using the CAAM crypto engine. Userspace can only see
++the blob for the corresponding key. All the blobs are displayed
++or loaded in hex ascii.
++
++Secure key can be created on platforms which supports CAAM
++hardware block. Secure key can also be used as a master key to
++create the encrypted keys along with the existing key types in
++kernel.
++
++Secure key uses CAAM hardware to generate the key and blobify its
++content for userspace. Generated blobs are tied up with the hardware
++secret key stored in CAAM, hence the same blob will not be able to
++de-blobify with the different secret key on another machine.
++
++Usage::
++
++ keyctl add secure <name> "new <keylen>" <ring>
++ keyctl load secure <name> "load <hex_blob>" <ring>
++ keyctl print <key_id>
++
++"keyctl add secure" option will create the random data of the
++specified key len using CAAM and store it as a key in kernel.
++Key contents will be displayed as blobs to the user in hex ascii.
++User can input key len from 32 bytes to 128 bytes.
++
++"keyctl load secure" option will load the blob contents. In kernel,
++key will be deirved using input blob and CAAM, along with the secret
++key stored in CAAM.
++
++"keyctl print" will return the hex string of the blob corresponding to
++key_id. Returned blob will be of key_len + 48 bytes. Extra 48 bytes are
++the header bytes added by the CAAM.
++
++Example of secure key usage::
++
++1. Create the secure key with name kmk-master of length 32 bytes::
++
++ $ keyctl add secure kmk-master "new 32" @u
++ 46001928
++
++ $keyctl show
++ Session Keyring
++ 1030783626 --alswrv 0 65534 keyring: _uid_ses.0
++ 695927745 --alswrv 0 65534 \_ keyring: _uid.0
++ 46001928 --als-rv 0 0 \_ secure: kmk-master
++
++2. Print the blob contents for the kmk-master key::
++
++ $ keyctl print 46001928
++ d9743445b640f3d59c1670dddc0bc9c2
++ 34fc9aab7dd05c965e6120025012f029b
++ 07faa4776c4f6ed02899e35a135531e9a
++ 6e5c2b51132f9d5aef28f68738e658296
++ 3fe583177cfe50d2542b659a13039
++
++ $ keyctl pipe 46001928 > secure_key.blob
++
++3. Load the blob in the user key ring::
++
++ $ keyctl load secure kmk-master "load 'cat secure_key.blob'" @u
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -7645,6 +7645,18 @@ F: include/keys/trusted-type.h
+ F: security/keys/trusted.c
+ F: security/keys/trusted.h
+
++KEYS-SECURE
++M: Udit Agarwal <udit.agarwal@nxp.com>
++R: Sahil Malhotra <sahil.malhotra@nxp.com>
++L: linux-security-module@vger.kernel.org
++L: keyrings@vger.kernel.org
++S: Supported
++F: include/keys/secure-type.h
++F: security/keys/secure_key.c
++F: security/keys/securekey_desc.c
++F: security/keys/securekey_desc.h
++F: security/keys/encrypted-keys/masterkey_secure.c
++
+ KEYS/KEYRINGS:
+ M: David Howells <dhowells@redhat.com>
+ L: keyrings@vger.kernel.org
+--- a/drivers/tee/optee/Kconfig
++++ b/drivers/tee/optee/Kconfig
+@@ -5,3 +5,11 @@ config OPTEE
+ help
+ This implements the OP-TEE Trusted Execution Environment (TEE)
+ driver.
++
++config OPTEE_SHM_NUM_PRIV_PAGES
++ int "Private Shared Memory Pages"
++ default 1
++ depends on OPTEE
++ help
++ This sets the number of private shared memory pages to be
++ used by OP-TEE TEE driver.
+--- a/drivers/tee/optee/core.c
++++ b/drivers/tee/optee/core.c
+@@ -31,7 +31,7 @@
+
+ #define DRIVER_NAME "optee"
+
+-#define OPTEE_SHM_NUM_PRIV_PAGES 1
++#define OPTEE_SHM_NUM_PRIV_PAGES CONFIG_OPTEE_SHM_NUM_PRIV_PAGES
+
+ /**
+ * optee_from_msg_param() - convert from OPTEE_MSG parameters to
+--- /dev/null
++++ b/include/keys/secure-type.h
+@@ -0,0 +1,33 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2018 NXP.
++ *
++ */
++
++#ifndef _KEYS_SECURE_TYPE_H
++#define _KEYS_SECURE_TYPE_H
++
++#include <linux/key.h>
++#include <linux/rcupdate.h>
++
++/* Minimum key size to be used is 32 bytes and maximum key size fixed
++ * is 128 bytes.
++ * Blob size to be kept is Maximum key size + blob header added by CAAM.
++ */
++
++#define MIN_KEY_SIZE 32
++#define MAX_KEY_SIZE 128
++#define BLOB_HEADER_SIZE 48
++
++#define MAX_BLOB_SIZE (MAX_KEY_SIZE + BLOB_HEADER_SIZE)
++
++struct secure_key_payload {
++ struct rcu_head rcu;
++ unsigned int key_len;
++ unsigned int blob_len;
++ unsigned char key[MAX_KEY_SIZE + 1];
++ unsigned char blob[MAX_BLOB_SIZE];
++};
++
++extern struct key_type key_type_secure;
++#endif
+--- a/security/keys/Kconfig
++++ b/security/keys/Kconfig
+@@ -71,6 +71,17 @@ config TRUSTED_KEYS
+
+ If you are unsure as to whether this is required, answer N.
+
++config SECURE_KEYS
++ tristate "SECURE_KEYS"
++ depends on KEYS && CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
++ help
++ This option provide support for creating secure-type key and blobs
++ in kernel. Secure keys are random number symmetric keys generated
++ from CAAM. The CAAM creates the blobs for the random key.
++ Userspace will only be able to see the blob.
++
++ If you are unsure as to whether this is required, answer N.
++
+ config ENCRYPTED_KEYS
+ tristate "ENCRYPTED KEYS"
+ depends on KEYS
+--- a/security/keys/Makefile
++++ b/security/keys/Makefile
+@@ -28,4 +28,9 @@ obj-$(CONFIG_KEY_DH_OPERATIONS) += dh.o
+ #
+ obj-$(CONFIG_BIG_KEYS) += big_key.o
+ obj-$(CONFIG_TRUSTED_KEYS) += trusted.o
++CFLAGS_secure_key.o += -I$(obj)/../../drivers/crypto/caam/
++CFLAGS_securekey_desc.o += -I$(obj)/../../drivers/crypto/caam/
++obj-$(CONFIG_SECURE_KEYS) += securekey.o
++securekey-y := securekey_desc.o \
++ secure_key.o
+ obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted-keys/
+--- a/security/keys/encrypted-keys/Makefile
++++ b/security/keys/encrypted-keys/Makefile
+@@ -7,5 +7,7 @@ obj-$(CONFIG_ENCRYPTED_KEYS) += encrypte
+
+ encrypted-keys-y := encrypted.o ecryptfs_format.o
+ masterkey-$(CONFIG_TRUSTED_KEYS) := masterkey_trusted.o
++masterkey-$(CONFIG_SECURE_KEYS) := masterkey_secure.o
+ masterkey-$(CONFIG_TRUSTED_KEYS)-$(CONFIG_ENCRYPTED_KEYS) := masterkey_trusted.o
++masterkey-$(CONFIG_SECURE_KEYS)-$(CONFIG_ENCRYPTED_KEYS) := masterkey_secure.o
+ encrypted-keys-y += $(masterkey-y) $(masterkey-m-m)
+--- a/security/keys/encrypted-keys/encrypted.c
++++ b/security/keys/encrypted-keys/encrypted.c
+@@ -39,6 +39,7 @@
+ #include "ecryptfs_format.h"
+
+ static const char KEY_TRUSTED_PREFIX[] = "trusted:";
++static const char KEY_SECURE_PREFIX[] = "secure:";
+ static const char KEY_USER_PREFIX[] = "user:";
+ static const char hash_alg[] = "sha256";
+ static const char hmac_alg[] = "hmac(sha256)";
+@@ -49,6 +50,7 @@ static unsigned int ivsize;
+ static int blksize;
+
+ #define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1)
++#define KEY_SECURE_PREFIX_LEN (sizeof(KEY_SECURE_PREFIX) - 1)
+ #define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1)
+ #define KEY_ECRYPTFS_DESC_LEN 16
+ #define HASH_SIZE SHA256_DIGEST_SIZE
+@@ -125,7 +127,7 @@ static int valid_ecryptfs_desc(const cha
+ /*
+ * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key
+ *
+- * key-type:= "trusted:" | "user:"
++ * key-type:= "trusted:" | "user:" | "secure:"
+ * desc:= master-key description
+ *
+ * Verify that 'key-type' is valid and that 'desc' exists. On key update,
+@@ -140,6 +142,8 @@ static int valid_master_desc(const char
+
+ if (!strncmp(new_desc, KEY_TRUSTED_PREFIX, KEY_TRUSTED_PREFIX_LEN))
+ prefix_len = KEY_TRUSTED_PREFIX_LEN;
++ else if (!strncmp(new_desc, KEY_SECURE_PREFIX, KEY_SECURE_PREFIX_LEN))
++ prefix_len = KEY_SECURE_PREFIX_LEN;
+ else if (!strncmp(new_desc, KEY_USER_PREFIX, KEY_USER_PREFIX_LEN))
+ prefix_len = KEY_USER_PREFIX_LEN;
+ else
+@@ -358,7 +362,7 @@ static int calc_hmac(u8 *digest, const u
+
+ enum derived_key_type { ENC_KEY, AUTH_KEY };
+
+-/* Derive authentication/encryption key from trusted key */
++/* Derive authentication/encryption key from trusted/secure key */
+ static int get_derived_key(u8 *derived_key, enum derived_key_type key_type,
+ const u8 *master_key, size_t master_keylen)
+ {
+@@ -429,6 +433,11 @@ static struct key *request_master_key(st
+ mkey = request_trusted_key(epayload->master_desc +
+ KEY_TRUSTED_PREFIX_LEN,
+ master_key, master_keylen);
++ } else if (!strncmp(epayload->master_desc, KEY_SECURE_PREFIX,
++ KEY_SECURE_PREFIX_LEN)) {
++ mkey = request_secure_key(epayload->master_desc +
++ KEY_SECURE_PREFIX_LEN,
++ master_key, master_keylen);
+ } else if (!strncmp(epayload->master_desc, KEY_USER_PREFIX,
+ KEY_USER_PREFIX_LEN)) {
+ mkey = request_user_key(epayload->master_desc +
+--- a/security/keys/encrypted-keys/encrypted.h
++++ b/security/keys/encrypted-keys/encrypted.h
+@@ -16,6 +16,19 @@ static inline struct key *request_truste
+ }
+ #endif
+
++#if defined(CONFIG_SECURE_KEYS)
++extern struct key *request_secure_key(const char *secure_desc,
++ const u8 **master_key,
++ size_t *master_keylen);
++#else
++static inline struct key *request_secure_key(const char *secure_desc,
++ const u8 **master_key,
++ size_t *master_keylen)
++{
++ return ERR_PTR(-EOPNOTSUPP);
++}
++#endif
++
+ #if ENCRYPTED_DEBUG
+ static inline void dump_master_key(const u8 *master_key, size_t master_keylen)
+ {
+--- /dev/null
++++ b/security/keys/encrypted-keys/masterkey_secure.c
+@@ -0,0 +1,37 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2018 NXP.
++ *
++ */
++
++#include <linux/uaccess.h>
++#include <linux/module.h>
++#include <linux/err.h>
++#include <keys/secure-type.h>
++#include <keys/encrypted-type.h>
++#include "encrypted.h"
++
++/*
++ * request_secure_key - request the secure key
++ *
++ * Secure keys and their blobs are derived from CAAM hardware.
++ * Userspace manages secure key-type data, but key data is not
++ * visible in plain form. It is presented as blobs.
++ */
++struct key *request_secure_key(const char *secure_desc,
++ const u8 **master_key, size_t *master_keylen)
++{
++ struct secure_key_payload *spayload;
++ struct key *skey;
++
++ skey = request_key(&key_type_secure, secure_desc, NULL);
++ if (IS_ERR(skey))
++ goto error;
++
++ down_read(&skey->sem);
++ spayload = skey->payload.data[0];
++ *master_key = spayload->key;
++ *master_keylen = spayload->key_len;
++error:
++ return skey;
++}
+--- /dev/null
++++ b/security/keys/secure_key.c
+@@ -0,0 +1,339 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (C) 2018 NXP
++ * Secure key is generated using NXP CAAM hardware block. CAAM generates the
++ * random number (used as a key) and creates its blob for the user.
++ */
++
++#include <linux/slab.h>
++#include <linux/parser.h>
++#include <linux/string.h>
++#include <linux/key-type.h>
++#include <linux/rcupdate.h>
++#include <keys/secure-type.h>
++#include <linux/completion.h>
++
++#include "securekey_desc.h"
++
++static const char hmac_alg[] = "hmac(sha1)";
++static const char hash_alg[] = "sha1";
++
++static struct crypto_shash *hashalg;
++static struct crypto_shash *hmacalg;
++
++enum {
++ error = -1,
++ new_key,
++ load_blob,
++};
++
++static const match_table_t key_tokens = {
++ {new_key, "new"},
++ {load_blob, "load"},
++ {error, NULL}
++};
++
++static struct secure_key_payload *secure_payload_alloc(struct key *key)
++{
++ struct secure_key_payload *sec_key = NULL;
++ int ret = 0;
++
++ ret = key_payload_reserve(key, sizeof(*sec_key));
++ if (ret < 0)
++ goto out;
++
++ sec_key = kzalloc(sizeof(*sec_key), GFP_KERNEL);
++ if (!sec_key)
++ goto out;
++
++out:
++ return sec_key;
++}
++
++/*
++ * parse_inputdata - parse the keyctl input data and fill in the
++ * payload structure for key or its blob.
++ * param[in]: data pointer to the data to be parsed for creating key.
++ * param[in]: p pointer to secure key payload structure to fill parsed data
++ * On success returns 0, otherwise -EINVAL.
++ */
++static int parse_inputdata(char *data, struct secure_key_payload *p)
++{
++ substring_t args[MAX_OPT_ARGS];
++ long keylen = 0;
++ int ret = -EINVAL;
++ int key_cmd = -EINVAL;
++ char *c = NULL;
++
++ c = strsep(&data, " \t");
++ if (!c) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* Get the keyctl command i.e. new_key or load_blob etc */
++ key_cmd = match_token(c, key_tokens, args);
++
++ switch (key_cmd) {
++ case new_key:
++ /* first argument is key size */
++ c = strsep(&data, " \t");
++ if (!c) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ ret = kstrtol(c, 10, &keylen);
++ if (ret < 0 || keylen < MIN_KEY_SIZE ||
++ keylen > MAX_KEY_SIZE) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ p->key_len = keylen;
++ ret = new_key;
++
++ break;
++ case load_blob:
++ /* first argument is blob data for CAAM*/
++ c = strsep(&data, " \t");
++ if (!c) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* Blob_len = No of characters in blob/2 */
++ p->blob_len = strlen(c) / 2;
++ if (p->blob_len > MAX_BLOB_SIZE) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ ret = hex2bin(p->blob, c, p->blob_len);
++ if (ret < 0) {
++ ret = -EINVAL;
++ goto out;
++ }
++ ret = load_blob;
++
++ break;
++ case error:
++ ret = -EINVAL;
++ break;
++ }
++
++out:
++ return ret;
++}
++
++/*
++ * secure_instantiate - create a new secure type key.
++ * Supports the operation to generate a new key. A random number
++ * is generated from CAAM as key data and the corresponding red blob
++ * is formed and stored as key_blob.
++ * Also supports the operation to load the blob and key is derived using
++ * that blob from CAAM.
++ * On success, return 0. Otherwise return errno.
++ */
++static int secure_instantiate(struct key *key,
++ struct key_preparsed_payload *prep)
++{
++ struct secure_key_payload *payload = NULL;
++ size_t datalen = prep->datalen;
++ char *data = NULL;
++ int key_cmd = 0;
++ int ret = 0;
++ enum sk_req_type sk_op_type;
++ struct device *dev = NULL;
++
++ if (datalen <= 0 || datalen > 32767 || !prep->data) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ data = kmalloc(datalen + 1, GFP_KERNEL);
++ if (!data) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ memcpy(data, prep->data, datalen);
++ data[datalen] = '\0';
++
++ payload = secure_payload_alloc(key);
++ if (!payload) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ /* Allocate caam job ring for operation to be performed from CAAM */
++ dev = caam_jr_alloc();
++ if (!dev) {
++ pr_info("caam_jr_alloc failed\n");
++ ret = -ENODEV;
++ goto out;
++ }
++
++ key_cmd = parse_inputdata(data, payload);
++ if (key_cmd < 0) {
++ ret = key_cmd;
++ goto out;
++ }
++
++ switch (key_cmd) {
++ case load_blob:
++ /*
++ * Red blob decryption to be done for load operation
++ * to derive the key.
++ */
++ sk_op_type = sk_red_blob_dec;
++ ret = key_deblob(payload, sk_op_type, dev);
++ if (ret != 0) {
++ pr_info("secure_key: key_blob decap fail (%d)\n", ret);
++ goto out;
++ }
++ break;
++ case new_key:
++ /* Get Random number from caam of the specified length */
++ sk_op_type = sk_get_random;
++ ret = caam_get_random(payload, sk_op_type, dev);
++ if (ret != 0) {
++ pr_info("secure_key: get_random fail (%d)\n", ret);
++ goto out;
++ }
++
++ /* Generate red blob of key random bytes with CAAM */
++ sk_op_type = sk_red_blob_enc;
++ ret = key_blob(payload, sk_op_type, dev);
++ if (ret != 0) {
++ pr_info("secure_key: key_blob encap fail (%d)\n", ret);
++ goto out;
++ }
++ break;
++ default:
++ ret = -EINVAL;
++ goto out;
++ }
++out:
++ if (data)
++ kzfree(data);
++ if (dev)
++ caam_jr_free(dev);
++
++ if (!ret)
++ rcu_assign_keypointer(key, payload);
++ else
++ kzfree(payload);
++
++ return ret;
++}
++
++/*
++ * secure_read - copy the blob data to userspace in hex.
++ * param[in]: key pointer to key struct
++ * param[in]: buffer pointer to user data for creating key
++ * param[in]: buflen is the length of the buffer
++ * On success, return to userspace the secure key data size.
++ */
++static long secure_read(const struct key *key, char __user *buffer,
++ size_t buflen)
++{
++ const struct secure_key_payload *p = NULL;
++ char *ascii_buf;
++ char *bufp;
++ int i;
++
++ p = dereference_key_locked(key);
++ if (!p)
++ return -EINVAL;
++
++ if (buffer && buflen >= 2 * p->blob_len) {
++ ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
++ if (!ascii_buf)
++ return -ENOMEM;
++
++ bufp = ascii_buf;
++ for (i = 0; i < p->blob_len; i++)
++ bufp = hex_byte_pack(bufp, p->blob[i]);
++ if (copy_to_user(buffer, ascii_buf, 2 * p->blob_len) != 0) {
++ kzfree(ascii_buf);
++ return -EFAULT;
++ }
++ kzfree(ascii_buf);
++ }
++ return 2 * p->blob_len;
++}
++
++/*
++ * secure_destroy - clear and free the key's payload
++ */
++static void secure_destroy(struct key *key)
++{
++ kzfree(key->payload.data[0]);
++}
++
++struct key_type key_type_secure = {
++ .name = "secure",
++ .instantiate = secure_instantiate,
++ .destroy = secure_destroy,
++ .read = secure_read,
++};
++EXPORT_SYMBOL_GPL(key_type_secure);
++
++static void secure_shash_release(void)
++{
++ if (hashalg)
++ crypto_free_shash(hashalg);
++ if (hmacalg)
++ crypto_free_shash(hmacalg);
++}
++
++static int __init secure_shash_alloc(void)
++{
++ int ret;
++
++ hmacalg = crypto_alloc_shash(hmac_alg, 0, CRYPTO_ALG_ASYNC);
++ if (IS_ERR(hmacalg)) {
++ pr_info("secure_key: could not allocate crypto %s\n",
++ hmac_alg);
++ return PTR_ERR(hmacalg);
++ }
++
++ hashalg = crypto_alloc_shash(hash_alg, 0, CRYPTO_ALG_ASYNC);
++ if (IS_ERR(hashalg)) {
++ pr_info("secure_key: could not allocate crypto %s\n",
++ hash_alg);
++ ret = PTR_ERR(hashalg);
++ goto hashalg_fail;
++ }
++
++ return 0;
++
++hashalg_fail:
++ crypto_free_shash(hmacalg);
++ return ret;
++}
++
++static int __init init_secure_key(void)
++{
++ int ret;
++
++ ret = secure_shash_alloc();
++ if (ret < 0)
++ return ret;
++
++ ret = register_key_type(&key_type_secure);
++ if (ret < 0)
++ secure_shash_release();
++ return ret;
++}
++
++static void __exit cleanup_secure_key(void)
++{
++ secure_shash_release();
++ unregister_key_type(&key_type_secure);
++}
++
++late_initcall(init_secure_key);
++module_exit(cleanup_secure_key);
++
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/security/keys/securekey_desc.c
+@@ -0,0 +1,608 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2018 NXP
++ *
++ */
++
++#include <keys/secure-type.h>
++#include "securekey_desc.h"
++
++/* key modifier for blob encapsulation & decapsulation descriptor */
++u8 key_modifier[] = "SECURE_KEY";
++u32 key_modifier_len = 10;
++
++void caam_sk_rng_desc(struct sk_req *skreq, struct sk_desc *skdesc)
++{
++ struct sk_fetch_rnd_data *fetch_rnd_data = NULL;
++ struct random_desc *rnd_desc = NULL;
++ size_t len = 0;
++ u32 *desc = skreq->hwdesc;
++
++ init_job_desc(desc, 0);
++
++ fetch_rnd_data = &skreq->req_u.sk_fetch_rnd_data;
++ rnd_desc = &skdesc->dma_u.random_descp;
++ len = fetch_rnd_data->key_len;
++
++ /* command 0x82500000 */
++ append_cmd(desc, CMD_OPERATION | OP_TYPE_CLASS1_ALG |
++ OP_ALG_ALGSEL_RNG);
++ /* command 0x60340000 | len */
++ append_cmd(desc, CMD_FIFO_STORE | FIFOST_TYPE_RNGSTORE | len);
++ append_ptr(desc, rnd_desc->rnd_data);
++}
++
++void caam_sk_redblob_encap_desc(struct sk_req *skreq, struct sk_desc *skdesc)
++{
++ struct redblob_encap_desc *red_blob_desc =
++ &skdesc->dma_u.redblob_encapdesc;
++ struct sk_red_blob_encap *red_blob_req =
++ &skreq->req_u.sk_red_blob_encap;
++ u32 *desc = skreq->hwdesc;
++
++ init_job_desc(desc, 0);
++
++ /* Load class 2 key with key modifier. */
++ append_key_as_imm(desc, key_modifier, key_modifier_len,
++ key_modifier_len, CLASS_2 | KEY_DEST_CLASS_REG);
++
++ /* SEQ IN PTR Command. */
++ append_seq_in_ptr(desc, red_blob_desc->in_data, red_blob_req->data_sz,
++ 0);
++
++ /* SEQ OUT PTR Command. */
++ append_seq_out_ptr(desc, red_blob_desc->redblob,
++ red_blob_req->redblob_sz, 0);
++
++ /* RedBlob encapsulation PROTOCOL Command. */
++ append_operation(desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB);
++}
++
++/* void caam_sk_redblob_decap_desc(struct sk_req *skreq, struct sk_desc *skdesc)
++ * brief CAAM Descriptor creator from redblob to plaindata.
++ * param[in] skreq Pointer to secure key request structure
++ * param[in] skdesc Pointer to secure key descriptor structure
++ */
++void caam_sk_redblob_decap_desc(struct sk_req *skreq, struct sk_desc *skdesc)
++{
++ struct redblob_decap_desc *red_blob_desc =
++ &skdesc->dma_u.redblob_decapdesc;
++ struct sk_red_blob_decap *red_blob_req =
++ &skreq->req_u.sk_red_blob_decap;
++ u32 *desc = skreq->hwdesc;
++
++ init_job_desc(desc, 0);
++
++ /* Load class 2 key with key modifier. */
++ append_key_as_imm(desc, key_modifier, key_modifier_len,
++ key_modifier_len, CLASS_2 | KEY_DEST_CLASS_REG);
++
++ /* SEQ IN PTR Command. */
++ append_seq_in_ptr(desc, red_blob_desc->redblob,
++ red_blob_req->redblob_sz, 0);
++
++ /* SEQ OUT PTR Command. */
++ append_seq_out_ptr(desc, red_blob_desc->out_data,
++ red_blob_req->data_sz, 0);
++
++ /* RedBlob decapsulation PROTOCOL Command. */
++ append_operation(desc, OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB);
++}
++
++/* int caam_sk_get_random_map(struct device *dev, struct sk_req *req,
++ * struct sk_desc *skdesc)
++ * brief DMA map the buffer virtual pointers to physical address.
++ * param[in] dev Pointer to job ring device structure
++ * param[in] req Pointer to secure key request structure
++ * param[in] skdesc Pointer to secure key descriptor structure
++ * return 0 on success, error value otherwise.
++ */
++int caam_sk_get_random_map(struct device *dev, struct sk_req *req,
++ struct sk_desc *skdesc)
++{
++ struct sk_fetch_rnd_data *fetch_rnd_data;
++ struct random_desc *rnd_desc;
++
++ fetch_rnd_data = &req->req_u.sk_fetch_rnd_data;
++ rnd_desc = &skdesc->dma_u.random_descp;
++
++ rnd_desc->rnd_data = dma_map_single(dev, fetch_rnd_data->data,
++ fetch_rnd_data->key_len, DMA_FROM_DEVICE);
++
++ if (dma_mapping_error(dev, rnd_desc->rnd_data)) {
++ dev_err(dev, "Unable to map memory\n");
++ goto sk_random_map_fail;
++ }
++ return 0;
++
++sk_random_map_fail:
++ return -ENOMEM;
++}
++
++/* int caam_sk_redblob_encap_map(struct device *dev, struct sk_req *req,
++ * struct sk_desc *skdesc)
++ * brief DMA map the buffer virtual pointers to physical address.
++ * param[in] dev Pointer to job ring device structure
++ * param[in] req Pointer to secure key request structure
++ * param[in] skdesc Pointer to secure key descriptor structure
++ * return 0 on success, error value otherwise.
++ */
++int caam_sk_redblob_encap_map(struct device *dev, struct sk_req *req,
++ struct sk_desc *skdesc)
++{
++ struct sk_red_blob_encap *red_blob_encap;
++ struct redblob_encap_desc *red_blob_desc;
++
++ red_blob_encap = &req->req_u.sk_red_blob_encap;
++ red_blob_desc = &skdesc->dma_u.redblob_encapdesc;
++
++ red_blob_desc->in_data = dma_map_single(dev, red_blob_encap->data,
++ red_blob_encap->data_sz, DMA_TO_DEVICE);
++ if (dma_mapping_error(dev, red_blob_desc->in_data)) {
++ dev_err(dev, "Unable to map memory\n");
++ goto sk_data_fail;
++ }
++
++ red_blob_desc->redblob = dma_map_single(dev, red_blob_encap->redblob,
++ red_blob_encap->redblob_sz, DMA_FROM_DEVICE);
++ if (dma_mapping_error(dev, red_blob_desc->redblob)) {
++ dev_err(dev, "Unable to map memory\n");
++ goto sk_redblob_fail;
++ }
++
++ return 0;
++
++sk_redblob_fail:
++ dma_unmap_single(dev, red_blob_desc->in_data, red_blob_encap->data_sz,
++ DMA_TO_DEVICE);
++sk_data_fail:
++ return -ENOMEM;
++}
++
++/* static int caam_sk_redblob_decap_map(struct device *dev,
++ * struct sk_req *req,
++ * struct sk_desc *skdesc)
++ * brief DMA map the buffer virtual pointers to physical address.
++ * param[in] dev Pointer to job ring device structure
++ * param[in] req Pointer to secure key request structure
++ * param[in] skdesc Pointer to secure key descriptor structure
++ * return 0 on success, error value otherwise.
++ */
++int caam_sk_redblob_decap_map(struct device *dev, struct sk_req *req,
++ struct sk_desc *skdesc)
++{
++ struct sk_red_blob_decap *red_blob_decap;
++ struct redblob_decap_desc *red_blob_desc;
++
++ red_blob_decap = &req->req_u.sk_red_blob_decap;
++ red_blob_desc = &skdesc->dma_u.redblob_decapdesc;
++
++ red_blob_desc->redblob = dma_map_single(dev, red_blob_decap->redblob,
++ red_blob_decap->redblob_sz, DMA_TO_DEVICE);
++ if (dma_mapping_error(dev, red_blob_desc->redblob)) {
++ dev_err(dev, "Unable to map memory\n");
++ goto sk_redblob_fail;
++ }
++
++ red_blob_desc->out_data = dma_map_single(dev, red_blob_decap->data,
++ red_blob_decap->data_sz, DMA_FROM_DEVICE);
++ if (dma_mapping_error(dev, red_blob_desc->out_data)) {
++ dev_err(dev, "Unable to map memory\n");
++ goto sk_data_fail;
++ }
++
++ return 0;
++
++sk_data_fail:
++ dma_unmap_single(dev, red_blob_desc->redblob,
++ red_blob_decap->redblob_sz, DMA_TO_DEVICE);
++sk_redblob_fail:
++ return -ENOMEM;
++}
++
++/* @fn void securekey_unmap(struct device *dev,
++ * struct sk_desc *skdesc, struct sk_req *req)
++ * @brief DMA unmap the buffer pointers.
++ * @param[in] dev Pointer to job ring device structure
++ * @param[in] skdesc Pointer to secure key descriptor structure
++ * @param[in] req Pointer to secure key request structure
++ */
++void securekey_unmap(struct device *dev,
++ struct sk_desc *skdesc, struct sk_req *req)
++{
++
++ switch (req->type) {
++ case sk_get_random:
++ {
++ struct sk_fetch_rnd_data *fetch_rnd_data;
++ struct random_desc *rnd_desc;
++
++ fetch_rnd_data = &req->req_u.sk_fetch_rnd_data;
++ rnd_desc = &skdesc->dma_u.random_descp;
++
++ /* Unmap Descriptor buffer pointers. */
++ dma_unmap_single(dev, rnd_desc->rnd_data,
++ fetch_rnd_data->key_len,
++ DMA_FROM_DEVICE);
++ break;
++ }
++ case sk_red_blob_enc:
++ {
++ struct sk_red_blob_encap *red_blob_encap;
++ struct redblob_encap_desc *red_blob_desc;
++
++ red_blob_encap = &req->req_u.sk_red_blob_encap;
++ red_blob_desc = &skdesc->dma_u.redblob_encapdesc;
++
++ /* Unmap Descriptor buffer pointers. */
++ dma_unmap_single(dev, red_blob_desc->in_data,
++ red_blob_encap->data_sz,
++ DMA_TO_DEVICE);
++
++ dma_unmap_single(dev, red_blob_desc->redblob,
++ red_blob_encap->redblob_sz,
++ DMA_FROM_DEVICE);
++
++ break;
++ }
++ case sk_red_blob_dec:
++ {
++ struct sk_red_blob_decap *red_blob_decap;
++ struct redblob_decap_desc *red_blob_desc;
++
++ red_blob_decap = &req->req_u.sk_red_blob_decap;
++ red_blob_desc = &skdesc->dma_u.redblob_decapdesc;
++
++ /* Unmap Descriptor buffer pointers. */
++ dma_unmap_single(dev, red_blob_desc->redblob,
++ red_blob_decap->redblob_sz,
++ DMA_TO_DEVICE);
++
++ dma_unmap_single(dev, red_blob_desc->out_data,
++ red_blob_decap->data_sz,
++ DMA_FROM_DEVICE);
++
++ break;
++ }
++ default:
++ dev_err(dev, "Unable to find request type\n");
++ break;
++ }
++ kfree(skdesc);
++}
++
++/* int caam_securekey_desc_init(struct device *dev, struct sk_req *req)
++ * brief CAAM Descriptor creator for secure key operations.
++ * param[in] dev Pointer to job ring device structure
++ * param[in] req Pointer to secure key request structure
++ * return 0 on success, error value otherwise.
++ */
++int caam_securekey_desc_init(struct device *dev, struct sk_req *req)
++{
++ struct sk_desc *skdesc = NULL;
++ int ret = 0;
++
++ switch (req->type) {
++ case sk_get_random:
++ {
++ skdesc = kmalloc(sizeof(*skdesc), GFP_DMA);
++ if (!skdesc) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ skdesc->req_type = req->type;
++
++ if (caam_sk_get_random_map(dev, req, skdesc)) {
++ dev_err(dev, "caam get_random map fail\n");
++ ret = -ENOMEM;
++ goto out;
++ }
++ caam_sk_rng_desc(req, skdesc);
++ break;
++ }
++ case sk_red_blob_enc:
++ {
++ skdesc = kmalloc(sizeof(*skdesc), GFP_DMA);
++ if (!skdesc) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ skdesc->req_type = req->type;
++
++ if (caam_sk_redblob_encap_map(dev, req, skdesc)) {
++ dev_err(dev, "caam redblob_encap map fail\n");
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ /* Descriptor function to create redblob from data. */
++ caam_sk_redblob_encap_desc(req, skdesc);
++ break;
++ }
++
++ case sk_red_blob_dec:
++ {
++ skdesc = kmalloc(sizeof(*skdesc), GFP_DMA);
++ if (!skdesc) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ skdesc->req_type = req->type;
++
++ if (caam_sk_redblob_decap_map(dev, req, skdesc)) {
++ dev_err(dev, "caam redblob_decap map fail\n");
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ /* Descriptor function to decap data from redblob. */
++ caam_sk_redblob_decap_desc(req, skdesc);
++ break;
++ }
++ default:
++ pr_debug("Unknown request type\n");
++ ret = -EINVAL;
++ goto out;
++ }
++
++ req->desc_pointer = (void *)skdesc;
++
++out:
++ return ret;
++}
++
++/* static void caam_op_done (struct device *dev, u32 *desc, u32 ret,
++ * void *context)
++ * brief callback function to be called when descriptor executed.
++ * param[in] dev Pointer to device structure
++ * param[in] desc descriptor pointer
++ * param[in] ret return status of Job submitted
++ * param[in] context void pointer
++ */
++static void caam_op_done(struct device *dev, u32 *desc, u32 ret,
++ void *context)
++{
++ struct sk_req *req = context;
++
++ if (ret) {
++ dev_err(dev, "caam op done err: %x\n", ret);
++ /* print the error source name. */
++ caam_jr_strstatus(dev, ret);
++ }
++ /* Call securekey_unmap function for unmapping the buffer pointers. */
++ securekey_unmap(dev, req->desc_pointer, req);
++
++ req->ret = ret;
++ complete(&req->comp);
++}
++
++
++/* static int sk_job_submit(struct device *jrdev, struct sk_req *req)
++ * brief Enqueue a Job descriptor to Job ring and wait until SEC returns.
++ * param[in] jrdev Pointer to job ring device structure
++ * param[in] req Pointer to secure key request structure
++ * return 0 on success, error value otherwise.
++ */
++static int sk_job_submit(struct device *jrdev, struct sk_req *req)
++{
++ int ret;
++
++ init_completion(&req->comp);
++
++ /* caam_jr_enqueue function for Enqueue a job descriptor */
++ ret = caam_jr_enqueue(jrdev, req->hwdesc, caam_op_done, req);
++ if (!ret)
++ wait_for_completion_interruptible(&req->comp);
++
++ ret = req->ret;
++ return ret;
++}
++
++/* caam_get_random(struct secure_key_payload *p, enum sk_req_type fetch_rnd,
++ * struct device *dev)
++ * Create the random number of the specified length using CAAM block
++ * param[in]: out pointer to place the random bytes
++ * param[in]: length for the random data bytes.
++ * param[in]: dev Pointer to job ring device structure
++ * If operation is successful return 0, otherwise error.
++ */
++int caam_get_random(struct secure_key_payload *p, enum sk_req_type fetch_rnd,
++ struct device *dev)
++{
++ struct sk_fetch_rnd_data *fetch_rnd_data = NULL;
++ struct sk_req *req = NULL;
++ int ret = 0;
++ void *temp = NULL;
++
++ req = kmalloc(sizeof(struct sk_req), GFP_DMA);
++ if (!req) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ req->type = fetch_rnd;
++ fetch_rnd_data = &(req->req_u.sk_fetch_rnd_data);
++
++ /* initialise with key length */
++ fetch_rnd_data->key_len = p->key_len;
++
++ temp = kmalloc(fetch_rnd_data->key_len, GFP_DMA);
++ if (!temp) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ fetch_rnd_data->data = temp;
++
++ ret = caam_securekey_desc_init(dev, req);
++
++ if (ret) {
++ pr_info("caam_securekey_desc_init failed\n");
++ goto out;
++ }
++
++ ret = sk_job_submit(dev, req);
++ if (!ret) {
++ /*Copy output to key buffer. */
++ memcpy(p->key, fetch_rnd_data->data, p->key_len);
++ } else {
++ ret = -EINVAL;
++ }
++
++out:
++ if (req)
++ kfree(req);
++
++ if (temp)
++ kfree(temp);
++
++ return ret;
++}
++EXPORT_SYMBOL(caam_get_random);
++
++/* key_deblob(struct secure_key_payload *p, enum sk_req_type decap_type
++ * struct device *dev)
++ * Deblobify the blob to get the key data and fill in secure key payload struct
++ * param[in] p pointer to the secure key payload
++ * param[in] decap_type operation to be done.
++ * param[in] dev dev Pointer to job ring device structure
++ * If operation is successful return 0, otherwise error.
++ */
++int key_deblob(struct secure_key_payload *p, enum sk_req_type decap_type,
++ struct device *dev)
++{
++ unsigned int blob_len;
++ struct sk_red_blob_decap *d_blob;
++ struct sk_req *req = NULL;
++ int total_sz = 0, *temp = NULL, ret = 0;
++
++ req = kmalloc(sizeof(struct sk_req), GFP_DMA);
++ if (!req) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ d_blob = &(req->req_u.sk_red_blob_decap);
++ blob_len = p->blob_len;
++ req->type = decap_type;
++
++ /*
++ * Red blob size is the blob_len filled in payload struct
++ * Data_sz i.e. key is the blob_len - blob header size
++ */
++
++ d_blob->redblob_sz = blob_len;
++ d_blob->data_sz = blob_len - (SK_BLOB_KEY_SZ + SK_BLOB_MAC_SZ);
++ total_sz = d_blob->data_sz + d_blob->redblob_sz;
++
++ temp = kmalloc(total_sz, GFP_DMA);
++ if (!temp) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ req->mem_pointer = temp;
++ d_blob->redblob = temp;
++ d_blob->data = d_blob->redblob + d_blob->redblob_sz;
++ memcpy(d_blob->redblob, p->blob, blob_len);
++
++ ret = caam_securekey_desc_init(dev, req);
++
++ if (ret) {
++ pr_info("caam_securekey_desc_init: Failed\n");
++ goto out;
++ }
++
++ ret = sk_job_submit(dev, req);
++ if (!ret) {
++ /*Copy output to key buffer. */
++ p->key_len = d_blob->data_sz;
++ memcpy(p->key, d_blob->data, p->key_len);
++ } else {
++ ret = -EINVAL;
++ }
++
++out:
++ if (temp)
++ kfree(temp);
++ if (req)
++ kfree(req);
++ return ret;
++}
++EXPORT_SYMBOL(key_deblob);
++
++/* key_blob(struct secure_key_payload *p, enum sk_req_type encap_type,
++ * struct device *dev)
++ * To blobify the key data to get the blob. This blob can only be seen by
++ * userspace.
++ * param[in] p pointer to the secure key payload
++ * param[in] decap_type operation to be done.
++ * param[in] dev dev Pointer to job ring device structure
++ * If operation is successful return 0, otherwise error.
++ */
++int key_blob(struct secure_key_payload *p, enum sk_req_type encap_type,
++ struct device *dev)
++{
++ unsigned int key_len;
++ struct sk_red_blob_encap *k_blob;
++ struct sk_req *req = NULL;
++ int total_sz = 0, *temp = NULL, ret = 0;
++
++ req = kmalloc(sizeof(struct sk_req), GFP_DMA);
++ if (!req) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ key_len = p->key_len;
++
++ req->type = encap_type;
++ k_blob = &(req->req_u.sk_red_blob_encap);
++
++ /*
++ * Data_sz i.e. key len and the corresponding blob_len is
++ * key_len + BLOB header size.
++ */
++
++ k_blob->data_sz = key_len;
++ k_blob->redblob_sz = key_len + SK_BLOB_KEY_SZ + SK_BLOB_MAC_SZ;
++ total_sz = k_blob->data_sz + k_blob->redblob_sz;
++
++ temp = kmalloc(total_sz, GFP_DMA);
++ if (!temp) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ req->mem_pointer = temp;
++ k_blob->data = temp;
++
++ k_blob->redblob = k_blob->data + k_blob->data_sz;
++ memcpy(k_blob->data, p->key, key_len);
++
++ ret = caam_securekey_desc_init(dev, req);
++
++ if (ret) {
++ pr_info("caam_securekey_desc_init failed\n");
++ goto out;
++ }
++
++ ret = sk_job_submit(dev, req);
++ if (!ret) {
++ /*Copy output to key buffer. */
++ p->blob_len = k_blob->redblob_sz;
++ memcpy(p->blob, k_blob->redblob, p->blob_len);
++ } else {
++ ret = -EINVAL;
++ }
++
++out:
++ if (temp)
++ kfree(req->mem_pointer);
++ if (req)
++ kfree(req);
++ return ret;
++
++}
++EXPORT_SYMBOL(key_blob);
+--- /dev/null
++++ b/security/keys/securekey_desc.h
+@@ -0,0 +1,141 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright 2018 NXP
++ *
++ */
++#ifndef _SECUREKEY_DESC_H_
++#define _SECUREKEY_DESC_H_
++
++#include "compat.h"
++#include "regs.h"
++#include "intern.h"
++#include "desc.h"
++#include "desc_constr.h"
++#include "jr.h"
++#include "error.h"
++#include "pdb.h"
++
++#define SK_BLOB_KEY_SZ 32 /* Blob key size. */
++#define SK_BLOB_MAC_SZ 16 /* Blob MAC size. */
++
++/*
++ * brief defines different kinds of operations supported by this module.
++ */
++enum sk_req_type {
++ sk_get_random,
++ sk_red_blob_enc,
++ sk_red_blob_dec,
++};
++
++
++/*
++ * struct random_des
++ * param[out] rnd_data output buffer for random data.
++ */
++struct random_desc {
++ dma_addr_t rnd_data;
++};
++
++/* struct redblob_encap_desc
++ * details Structure containing dma address for redblob encapsulation.
++ * param[in] in_data input data to redblob encap descriptor.
++ * param[out] redblob output buffer for redblob.
++ */
++struct redblob_encap_desc {
++ dma_addr_t in_data;
++ dma_addr_t redblob;
++};
++
++/* struct redblob_decap_desc
++ * details Structure containing dma address for redblob decapsulation.
++ * param[in] redblob input buffer to redblob decap descriptor.
++ * param[out] out_data output data from redblob decap descriptor.
++ */
++struct redblob_decap_desc {
++ dma_addr_t redblob;
++ dma_addr_t out_data;
++};
++
++/* struct sk_desc
++ * details Structure for securekey descriptor creation.
++ * param[in] req_type operation supported.
++ * param[in] dma_u union of struct for supported operation.
++ */
++struct sk_desc {
++ u32 req_type;
++ union {
++ struct redblob_encap_desc redblob_encapdesc;
++ struct redblob_decap_desc redblob_decapdesc;
++ struct random_desc random_descp;
++ } dma_u;
++};
++
++/* struct sk_fetch_rnd_data
++ * decriptor structure containing key length.
++ */
++struct sk_fetch_rnd_data {
++ void *data;
++ size_t key_len;
++};
++
++/* struct sk_red_blob_encap
++ * details Structure containing buffer pointers for redblob encapsulation.
++ * param[in] data Input data.
++ * param[in] data_sz size of Input data.
++ * param[out] redblob output buffer for redblob.
++ * param[in] redblob_sz size of redblob.
++ */
++struct sk_red_blob_encap {
++ void *data;
++ uint32_t data_sz;
++ void *redblob;
++ uint32_t redblob_sz;
++};
++
++/* struct sk_red_blob_decap
++ * details Structure containing buffer pointers for redblob decapsulation.
++ * param[in] redblob Input redblob.
++ * param[in] redblob_sz size of redblob.
++ * param[out] data output buffer for data.
++ * param[in] data_sz size of output data.
++ */
++struct sk_red_blob_decap {
++ void *redblob;
++ uint32_t redblob_sz;
++ void *data;
++ uint32_t data_sz;
++};
++
++/* struct sk_req
++ * details Structure for securekey request creation.
++ * param[in] type operation supported.
++ * param[in] req_u union of struct for supported operation.
++ * param[out] ret return status of CAAM operation.
++ * param[in] mem_pointer memory pointer for allocated kernel memory.
++ * param[in] desc_pointer Pointer to securekey descriptor creation structure.
++ * param[in] comp struct completion object.
++ * param[in] hwdesc contains descriptor instructions.
++ */
++struct sk_req {
++ enum sk_req_type type;
++ void *arg;
++ union {
++ struct sk_red_blob_encap sk_red_blob_encap;
++ struct sk_red_blob_decap sk_red_blob_decap;
++ struct sk_fetch_rnd_data sk_fetch_rnd_data;
++ } req_u;
++ int ret;
++ void *mem_pointer;
++ void *desc_pointer;
++ struct completion comp;
++ u32 hwdesc[MAX_CAAM_DESCSIZE];
++};
++
++int caam_get_random(struct secure_key_payload *p, enum sk_req_type fetch_rnd,
++ struct device *dev);
++int key_blob(struct secure_key_payload *p, enum sk_req_type encap_type,
++ struct device *dev);
++int key_deblob(struct secure_key_payload *p, enum sk_req_type decap_type,
++ struct device *dev);
++
++#endif /*_SECUREKEY_DESC_H_*/