Adds utility function in TEE subsystem for client UUID generation. This
function is also used in the optee driver. -----BEGIN PGP SIGNATURE----- iQJOBAABCgA4FiEEFV+gSSXZJY9ZyuB5LinzTIcAHJcFAl66eh4aHGplbnMud2lr bGFuZGVyQGxpbmFyby5vcmcACgkQLinzTIcAHJeZ5w/+O2C1ixl3tt40mVjCFkpT TCKy4lJXQWXegYZ7epJAImRM82ogVoOItEhOtrSmodnENJLVgH8TUBuPiTwh4kb6 sSQ2zEPoOvA+3HtnnPaxZKuttMvL9MMvAoNH8Mg6ZEaBxG0r6zqiff8vPtfGlM/r BSy/vH0rxYo1qX4twUHu6GSVWJLC2aSm/eO6BWri5kGHPgR1QOjeXXmotecx9h/b 6cxxRa6FG8nuXuqemMfdtk2j2PMsp639ziTD8cKKR7ncsiUqGtbvonRbeOOBTrHL aimLgGtIe7hgObspVrH9pvh9ZpTjH34ffQatfAnZROkWKxWhdab9RbrycoFsVRWq hc62KfuSA3zFHMx4/q0QIiE0TYXnrIjmHziIBKjQs1w3ZdjcQl2OB1guE20xuhWd LCDZEV2E954113DOQ4kCV9Yh5psDJ0jhjAZrrAdRMX6JZuZ3jzr5hA0BDtSOjKLs PqQ2TUI+95YZVLI7QdqBCf9Z3HXlI9a3TwOCVzDYy1m0InvzHXwHD6DhdobNhd+J rQEKvMog5hhe/C3W9agl8Hi2BXNLsepcwUBRx6CsyaZMXBBUxbPeWR6ZnqlRAkYS FyNbC82yoOYtOYdnOLHwIarr65uGhO5PFY/g5o6k2vuu2WeI7tr9wlGMgBbBb2wT EnGClHSHcOkmsYyJJ6TX2sw= =dx75 -----END PGP SIGNATURE----- Merge tag 'tee-login-for-5.8' of git://git.linaro.org/people/jens.wiklander/linux-tee into arm/drivers Adds utility function in TEE subsystem for client UUID generation. This function is also used in the optee driver. * tag 'tee-login-for-5.8' of git://git.linaro.org/people/jens.wiklander/linux-tee: tee: optee: Add support for session login client UUID generation tee: add support for session's client UUID generation Link: https://lore.kernel.org/r/20200512131243.GA10028@jade Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
be4ad166b4
|
@ -3,6 +3,7 @@
|
|||
config TEE
|
||||
tristate "Trusted Execution Environment support"
|
||||
depends on HAVE_ARM_SMCCC || COMPILE_TEST || CPU_SUP_AMD
|
||||
select CRYPTO_SHA1
|
||||
select DMA_SHARED_BUFFER
|
||||
select GENERIC_ALLOCATOR
|
||||
help
|
||||
|
|
|
@ -233,9 +233,13 @@ int optee_open_session(struct tee_context *ctx,
|
|||
msg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |
|
||||
OPTEE_MSG_ATTR_META;
|
||||
memcpy(&msg_arg->params[0].u.value, arg->uuid, sizeof(arg->uuid));
|
||||
memcpy(&msg_arg->params[1].u.value, arg->uuid, sizeof(arg->clnt_uuid));
|
||||
msg_arg->params[1].u.value.c = arg->clnt_login;
|
||||
|
||||
rc = tee_session_calc_client_uuid((uuid_t *)&msg_arg->params[1].u.value,
|
||||
arg->clnt_login, arg->clnt_uuid);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
rc = optee_to_msg_param(msg_arg->params + 2, arg->num_params, param);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
|
|
@ -6,18 +6,33 @@
|
|||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/tee_drv.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <crypto/sha.h>
|
||||
#include "tee_private.h"
|
||||
|
||||
#define TEE_NUM_DEVICES 32
|
||||
|
||||
#define TEE_IOCTL_PARAM_SIZE(x) (sizeof(struct tee_param) * (x))
|
||||
|
||||
#define TEE_UUID_NS_NAME_SIZE 128
|
||||
|
||||
/*
|
||||
* TEE Client UUID name space identifier (UUIDv4)
|
||||
*
|
||||
* Value here is random UUID that is allocated as name space identifier for
|
||||
* forming Client UUID's for TEE environment using UUIDv5 scheme.
|
||||
*/
|
||||
static const uuid_t tee_client_uuid_ns = UUID_INIT(0x58ac9ca0, 0x2086, 0x4683,
|
||||
0xa1, 0xb8, 0xec, 0x4b,
|
||||
0xc0, 0x8e, 0x01, 0xb6);
|
||||
|
||||
/*
|
||||
* Unprivileged devices in the lower half range and privileged devices in
|
||||
* the upper half range.
|
||||
|
@ -110,6 +125,143 @@ static int tee_release(struct inode *inode, struct file *filp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* uuid_v5() - Calculate UUIDv5
|
||||
* @uuid: Resulting UUID
|
||||
* @ns: Name space ID for UUIDv5 function
|
||||
* @name: Name for UUIDv5 function
|
||||
* @size: Size of name
|
||||
*
|
||||
* UUIDv5 is specific in RFC 4122.
|
||||
*
|
||||
* This implements section (for SHA-1):
|
||||
* 4.3. Algorithm for Creating a Name-Based UUID
|
||||
*/
|
||||
static int uuid_v5(uuid_t *uuid, const uuid_t *ns, const void *name,
|
||||
size_t size)
|
||||
{
|
||||
unsigned char hash[SHA1_DIGEST_SIZE];
|
||||
struct crypto_shash *shash = NULL;
|
||||
struct shash_desc *desc = NULL;
|
||||
int rc;
|
||||
|
||||
shash = crypto_alloc_shash("sha1", 0, 0);
|
||||
if (IS_ERR(shash)) {
|
||||
rc = PTR_ERR(shash);
|
||||
pr_err("shash(sha1) allocation failed\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(shash),
|
||||
GFP_KERNEL);
|
||||
if (!desc) {
|
||||
rc = -ENOMEM;
|
||||
goto out_free_shash;
|
||||
}
|
||||
|
||||
desc->tfm = shash;
|
||||
|
||||
rc = crypto_shash_init(desc);
|
||||
if (rc < 0)
|
||||
goto out_free_desc;
|
||||
|
||||
rc = crypto_shash_update(desc, (const u8 *)ns, sizeof(*ns));
|
||||
if (rc < 0)
|
||||
goto out_free_desc;
|
||||
|
||||
rc = crypto_shash_update(desc, (const u8 *)name, size);
|
||||
if (rc < 0)
|
||||
goto out_free_desc;
|
||||
|
||||
rc = crypto_shash_final(desc, hash);
|
||||
if (rc < 0)
|
||||
goto out_free_desc;
|
||||
|
||||
memcpy(uuid->b, hash, UUID_SIZE);
|
||||
|
||||
/* Tag for version 5 */
|
||||
uuid->b[6] = (hash[6] & 0x0F) | 0x50;
|
||||
uuid->b[8] = (hash[8] & 0x3F) | 0x80;
|
||||
|
||||
out_free_desc:
|
||||
kfree(desc);
|
||||
|
||||
out_free_shash:
|
||||
crypto_free_shash(shash);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
|
||||
const u8 connection_data[TEE_IOCTL_UUID_LEN])
|
||||
{
|
||||
gid_t ns_grp = (gid_t)-1;
|
||||
kgid_t grp = INVALID_GID;
|
||||
char *name = NULL;
|
||||
int name_len;
|
||||
int rc;
|
||||
|
||||
if (connection_method == TEE_IOCTL_LOGIN_PUBLIC) {
|
||||
/* Nil UUID to be passed to TEE environment */
|
||||
uuid_copy(uuid, &uuid_null);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* In Linux environment client UUID is based on UUIDv5.
|
||||
*
|
||||
* Determine client UUID with following semantics for 'name':
|
||||
*
|
||||
* For TEEC_LOGIN_USER:
|
||||
* uid=<uid>
|
||||
*
|
||||
* For TEEC_LOGIN_GROUP:
|
||||
* gid=<gid>
|
||||
*
|
||||
*/
|
||||
|
||||
name = kzalloc(TEE_UUID_NS_NAME_SIZE, GFP_KERNEL);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
switch (connection_method) {
|
||||
case TEE_IOCTL_LOGIN_USER:
|
||||
name_len = snprintf(name, TEE_UUID_NS_NAME_SIZE, "uid=%x",
|
||||
current_euid().val);
|
||||
if (name_len >= TEE_UUID_NS_NAME_SIZE) {
|
||||
rc = -E2BIG;
|
||||
goto out_free_name;
|
||||
}
|
||||
break;
|
||||
|
||||
case TEE_IOCTL_LOGIN_GROUP:
|
||||
memcpy(&ns_grp, connection_data, sizeof(gid_t));
|
||||
grp = make_kgid(current_user_ns(), ns_grp);
|
||||
if (!gid_valid(grp) || !in_egroup_p(grp)) {
|
||||
rc = -EPERM;
|
||||
goto out_free_name;
|
||||
}
|
||||
|
||||
name_len = snprintf(name, TEE_UUID_NS_NAME_SIZE, "gid=%x",
|
||||
grp.val);
|
||||
if (name_len >= TEE_UUID_NS_NAME_SIZE) {
|
||||
rc = -E2BIG;
|
||||
goto out_free_name;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
goto out_free_name;
|
||||
}
|
||||
|
||||
rc = uuid_v5(uuid, &tee_client_uuid_ns, name, name_len);
|
||||
out_free_name:
|
||||
kfree(name);
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tee_session_calc_client_uuid);
|
||||
|
||||
static int tee_ioctl_version(struct tee_context *ctx,
|
||||
struct tee_ioctl_version_data __user *uvers)
|
||||
{
|
||||
|
|
|
@ -166,6 +166,22 @@ int tee_device_register(struct tee_device *teedev);
|
|||
*/
|
||||
void tee_device_unregister(struct tee_device *teedev);
|
||||
|
||||
/**
|
||||
* tee_session_calc_client_uuid() - Calculates client UUID for session
|
||||
* @uuid: Resulting UUID
|
||||
* @connection_method: Connection method for session (TEE_IOCTL_LOGIN_*)
|
||||
* @connectuon_data: Connection data for opening session
|
||||
*
|
||||
* Based on connection method calculates UUIDv5 based client UUID.
|
||||
*
|
||||
* For group based logins verifies that calling process has specified
|
||||
* credentials.
|
||||
*
|
||||
* @return < 0 on failure
|
||||
*/
|
||||
int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
|
||||
const u8 connection_data[TEE_IOCTL_UUID_LEN]);
|
||||
|
||||
/**
|
||||
* struct tee_shm - shared memory object
|
||||
* @ctx: context using the object
|
||||
|
|
Loading…
Reference in New Issue