summaryrefslogtreecommitdiff
path: root/security/keys
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/big_key.c2
-rw-r--r--security/keys/encrypted-keys/ecryptfs_format.c3
-rw-r--r--security/keys/encrypted-keys/encrypted.c4
-rw-r--r--security/keys/process_keys.c2
-rw-r--r--security/keys/trusted-keys/trusted_caam.c108
-rw-r--r--security/keys/trusted-keys/trusted_core.c4
-rw-r--r--security/keys/trusted-keys/trusted_tpm2.c29
-rw-r--r--security/keys/user_defined.c2
8 files changed, 124 insertions, 30 deletions
diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index c3367622c683..d46862ab90d6 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -66,7 +66,7 @@ int big_key_preparse(struct key_preparsed_payload *prep)
BUILD_BUG_ON(sizeof(*payload) != sizeof(prep->payload.data));
- if (datalen <= 0 || datalen > 1024 * 1024 || !prep->data)
+ if (datalen == 0 || datalen > 1024 * 1024 || !prep->data)
return -EINVAL;
/* Set an arbitrary quota */
diff --git a/security/keys/encrypted-keys/ecryptfs_format.c b/security/keys/encrypted-keys/ecryptfs_format.c
index 8fdd76105ce3..2fc6f3a66135 100644
--- a/security/keys/encrypted-keys/ecryptfs_format.c
+++ b/security/keys/encrypted-keys/ecryptfs_format.c
@@ -54,8 +54,7 @@ int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
auth_tok->version = (((uint16_t)(major << 8) & 0xFF00)
| ((uint16_t)minor & 0x00FF));
auth_tok->token_type = ECRYPTFS_PASSWORD;
- strncpy((char *)auth_tok->token.password.signature, key_desc,
- ECRYPTFS_PASSWORD_SIG_SIZE);
+ strscpy_pad(auth_tok->token.password.signature, key_desc);
auth_tok->token.password.session_key_encryption_key_bytes =
ECRYPTFS_MAX_KEY_BYTES;
/*
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 513c09e2b01c..596e7a30bd3c 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -795,7 +795,7 @@ static int encrypted_instantiate(struct key *key,
size_t datalen = prep->datalen;
int ret;
- if (datalen <= 0 || datalen > 32767 || !prep->data)
+ if (datalen == 0 || datalen > 32767 || !prep->data)
return -EINVAL;
datablob = kmalloc(datalen + 1, GFP_KERNEL);
@@ -856,7 +856,7 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
if (key_is_negative(key))
return -ENOKEY;
- if (datalen <= 0 || datalen > 32767 || !prep->data)
+ if (datalen == 0 || datalen > 32767 || !prep->data)
return -EINVAL;
buf = kmalloc(datalen + 1, GFP_KERNEL);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index b5d5333ab330..a63c46bb2d14 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -51,7 +51,7 @@ static struct key *get_user_register(struct user_namespace *user_ns)
if (!reg_keyring) {
reg_keyring = keyring_alloc(".user_reg",
user_ns->owner, INVALID_GID,
- &init_cred,
+ kernel_cred(),
KEY_POS_WRITE | KEY_POS_SEARCH |
KEY_USR_VIEW | KEY_USR_READ,
0,
diff --git a/security/keys/trusted-keys/trusted_caam.c b/security/keys/trusted-keys/trusted_caam.c
index e3415c520c0a..601943ce0d60 100644
--- a/security/keys/trusted-keys/trusted_caam.c
+++ b/security/keys/trusted-keys/trusted_caam.c
@@ -1,12 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
+ * Copyright 2025 NXP
*/
#include <keys/trusted_caam.h>
#include <keys/trusted-type.h>
#include <linux/build_bug.h>
#include <linux/key-type.h>
+#include <linux/parser.h>
#include <soc/fsl/caam-blob.h>
static struct caam_blob_priv *blobifier;
@@ -16,6 +18,77 @@ static struct caam_blob_priv *blobifier;
static_assert(MAX_KEY_SIZE + CAAM_BLOB_OVERHEAD <= CAAM_BLOB_MAX_LEN);
static_assert(MAX_BLOB_SIZE <= CAAM_BLOB_MAX_LEN);
+enum {
+ opt_err,
+ opt_key_enc_algo,
+};
+
+static const match_table_t key_tokens = {
+ {opt_key_enc_algo, "key_enc_algo=%s"},
+ {opt_err, NULL}
+};
+
+#ifdef CAAM_DEBUG
+static inline void dump_options(const struct caam_pkey_info *pkey_info)
+{
+ pr_info("key encryption algo %d\n", pkey_info->key_enc_algo);
+}
+#else
+static inline void dump_options(const struct caam_pkey_info *pkey_info)
+{
+}
+#endif
+
+static int get_pkey_options(char *c,
+ struct caam_pkey_info *pkey_info)
+{
+ substring_t args[MAX_OPT_ARGS];
+ unsigned long token_mask = 0;
+ u16 key_enc_algo;
+ char *p = c;
+ int token;
+ int res;
+
+ if (!c)
+ return 0;
+
+ while ((p = strsep(&c, " \t"))) {
+ if (*p == '\0' || *p == ' ' || *p == '\t')
+ continue;
+ token = match_token(p, key_tokens, args);
+ if (test_and_set_bit(token, &token_mask))
+ return -EINVAL;
+
+ switch (token) {
+ case opt_key_enc_algo:
+ res = kstrtou16(args[0].from, 16, &key_enc_algo);
+ if (res < 0)
+ return -EINVAL;
+ pkey_info->key_enc_algo = key_enc_algo;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static bool is_key_pkey(char **datablob)
+{
+ char *c = NULL;
+
+ do {
+ /* Second argument onwards,
+ * determine if tied to HW
+ */
+ c = strsep(datablob, " \t");
+ if (c && (strcmp(c, "pk") == 0))
+ return true;
+ } while (c);
+
+ return false;
+}
+
static int trusted_caam_seal(struct trusted_key_payload *p, char *datablob)
{
int ret;
@@ -25,11 +98,30 @@ static int trusted_caam_seal(struct trusted_key_payload *p, char *datablob)
.key_mod = KEYMOD, .key_mod_len = sizeof(KEYMOD) - 1,
};
+ /*
+ * If it is to be treated as protected key,
+ * read next arguments too.
+ */
+ if (is_key_pkey(&datablob)) {
+ info.pkey_info.plain_key_sz = p->key_len;
+ info.pkey_info.is_pkey = 1;
+ ret = get_pkey_options(datablob, &info.pkey_info);
+ if (ret < 0)
+ return 0;
+ dump_options(&info.pkey_info);
+ }
+
ret = caam_encap_blob(blobifier, &info);
if (ret)
return ret;
p->blob_len = info.output_len;
+ if (info.pkey_info.is_pkey) {
+ p->key_len = p->blob_len + sizeof(struct caam_pkey_info);
+ memcpy(p->key, &info.pkey_info, sizeof(struct caam_pkey_info));
+ memcpy(p->key + sizeof(struct caam_pkey_info), p->blob, p->blob_len);
+ }
+
return 0;
}
@@ -42,11 +134,27 @@ static int trusted_caam_unseal(struct trusted_key_payload *p, char *datablob)
.key_mod = KEYMOD, .key_mod_len = sizeof(KEYMOD) - 1,
};
+ if (is_key_pkey(&datablob)) {
+ info.pkey_info.plain_key_sz = p->blob_len - CAAM_BLOB_OVERHEAD;
+ info.pkey_info.is_pkey = 1;
+ ret = get_pkey_options(datablob, &info.pkey_info);
+ if (ret < 0)
+ return 0;
+ dump_options(&info.pkey_info);
+
+ p->key_len = p->blob_len + sizeof(struct caam_pkey_info);
+ memcpy(p->key, &info.pkey_info, sizeof(struct caam_pkey_info));
+ memcpy(p->key + sizeof(struct caam_pkey_info), p->blob, p->blob_len);
+
+ return 0;
+ }
+
ret = caam_decap_blob(blobifier, &info);
if (ret)
return ret;
p->key_len = info.output_len;
+
return 0;
}
diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
index e2d9644efde1..b1680ee53f86 100644
--- a/security/keys/trusted-keys/trusted_core.c
+++ b/security/keys/trusted-keys/trusted_core.c
@@ -157,7 +157,7 @@ static int trusted_instantiate(struct key *key,
int key_cmd;
size_t key_len;
- if (datalen <= 0 || datalen > 32767 || !prep->data)
+ if (datalen == 0 || datalen > 32767 || !prep->data)
return -EINVAL;
orig_datablob = datablob = kmalloc(datalen + 1, GFP_KERNEL);
@@ -240,7 +240,7 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
p = key->payload.data[0];
if (!p->migratable)
return -EPERM;
- if (datalen <= 0 || datalen > 32767 || !prep->data)
+ if (datalen == 0 || datalen > 32767 || !prep->data)
return -EINVAL;
orig_datablob = datablob = kmalloc(datalen + 1, GFP_KERNEL);
diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
index 024be262702f..91656e44b326 100644
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -18,14 +18,6 @@
#include "tpm2key.asn1.h"
-static struct tpm2_hash tpm2_hash_map[] = {
- {HASH_ALGO_SHA1, TPM_ALG_SHA1},
- {HASH_ALGO_SHA256, TPM_ALG_SHA256},
- {HASH_ALGO_SHA384, TPM_ALG_SHA384},
- {HASH_ALGO_SHA512, TPM_ALG_SHA512},
- {HASH_ALGO_SM3_256, TPM_ALG_SM3_256},
-};
-
static u32 tpm2key_oid[] = { 2, 23, 133, 10, 1, 5 };
static int tpm2_key_encode(struct trusted_key_payload *payload,
@@ -244,20 +236,13 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
off_t offset = TPM_HEADER_SIZE;
struct tpm_buf buf, sized;
int blob_len = 0;
- u32 hash;
+ int hash;
u32 flags;
- int i;
int rc;
- for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) {
- if (options->hash == tpm2_hash_map[i].crypto_id) {
- hash = tpm2_hash_map[i].tpm_id;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(tpm2_hash_map))
- return -EINVAL;
+ hash = tpm2_find_hash_alg(options->hash);
+ if (hash < 0)
+ return hash;
if (!options->keyhandle)
return -EINVAL;
@@ -387,6 +372,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
struct trusted_key_options *options,
u32 *blob_handle)
{
+ u8 *blob_ref __free(kfree) = NULL;
struct tpm_buf buf;
unsigned int private_len;
unsigned int public_len;
@@ -400,6 +386,9 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
/* old form */
blob = payload->blob;
payload->old_format = 1;
+ } else {
+ /* Bind for cleanup: */
+ blob_ref = blob;
}
/* new format carries keyhandle but old format doesn't */
@@ -464,8 +453,6 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
(__be32 *) &buf.data[TPM_HEADER_SIZE]);
out:
- if (blob != payload->blob)
- kfree(blob);
tpm_buf_destroy(&buf);
if (rc > 0)
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 749e2a4dcb13..686d56e4cc85 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -61,7 +61,7 @@ int user_preparse(struct key_preparsed_payload *prep)
struct user_key_payload *upayload;
size_t datalen = prep->datalen;
- if (datalen <= 0 || datalen > 32767 || !prep->data)
+ if (datalen == 0 || datalen > 32767 || !prep->data)
return -EINVAL;
upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);