Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp1791046ybz; Thu, 30 Apr 2020 05:40:40 -0700 (PDT) X-Google-Smtp-Source: APiQypIrawEQbMipQlEUyYsjHCY4rIqCx3DnkKBBX91udhe5lW8mn/Sd8URa0HFmy9oKF399tT0r X-Received: by 2002:aa7:c40c:: with SMTP id j12mr2348984edq.169.1588250440780; Thu, 30 Apr 2020 05:40:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588250440; cv=none; d=google.com; s=arc-20160816; b=zo5SVuLrE0U93EsmrKlXoH91KkvSd/xKblo4A1YXhj1+Axgd2mON0qzPJUlyy90NAW 9i4tm/OgJqZYmTaNoeAFJ2e5TEVKrdtsY2//wUd4B+jAesTar62uoY0GtFd3rfPD0VjN LDXF8k9Uci30O2GGeOUB9QWch2bLK0ipId9D+e3Sftm8YqPI52IPDcEdc4cx2YWQ9Sjw xOJ/aSddIchSwCCHyfKIgxIceyCgNDgaNMFflYhtrxrhn9lS3rpJIFtqM+d0kegm9ezC neniEnkAfmhG2L47ijk4mdFFJYioqdoBTA5Nt7NqSzbZkGJ9VRTyrCGdxZyxPhbUVxMg La+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :ironport-sdr; bh=wpU560d8wEzFWZmVSYzNt5nkU7oLKYcypnYn+Csuu1o=; b=b1fb8EaSuTUB39IaWpiboOu/MjjTv27NwHei3uKyGWOGSs1YkfvTQP57yBtIH36GWu abwd21dsdbndws/tT8Ytc/h3gZcioJjRvXFkmP+BakDdOqbmvO7vAxVAaAihGtCNS+HC AG3Bg2eiqflljbPDVrYMuLQG6vzjXzSn/wg9vETB6PdW9p88OMMoXzUGLy+JUh7CaTcJ GSM+hGAbNDxKyw2rSfJP9l/RIIwtaOmsQsRU6hecLaL6gwGqaCmEh1/Ep7LTnhcXnGhG 3MAMypLC15bxPnhj/LCFeVY9U9DFmpKXQKpXkd6K4a34bDnLy4RQFDdk4HRKCzQfUMqE fiYw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id x25si6106535ejs.434.2020.04.30.05.40.17; Thu, 30 Apr 2020 05:40:40 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726906AbgD3Mhh (ORCPT + 99 others); Thu, 30 Apr 2020 08:37:37 -0400 Received: from hel-mailgw-01.vaisala.com ([193.143.230.17]:46718 "EHLO hel-mailgw-01.vaisala.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726053AbgD3Mha (ORCPT ); Thu, 30 Apr 2020 08:37:30 -0400 IronPort-SDR: zRXC6M2FUn1WZaDz1avibpNtAnAhZij38kZyoSNXxrHQ7AESSKILAU4bHzgEB3TEQTh/ZoQgqf Tb7UZ98nhGLoeKthwEjCkXSz40v12uYj0PPrzuG5zvaNqXQ7j1Qpv9XWLUcf92n27FXpexMpzF roi0JtnAM8++rAdzUCwSs1Ux6qttU5vHGQy1CK4O52aAJ/PT13GOsAuK1/Cn+p6o4SG5dbrH71 Fm/HbJpGOqL2S1SwEBWblfJIZlfojV8RN61siXt1/HNZx7+FR3/1RoAwEitIUqD7eIIAkQD/fj IpM= X-IronPort-AV: E=Sophos;i="5.73,334,1583186400"; d="scan'208";a="278151911" From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?= To: op-tee@lists.trustedfirmware.org, Jens Wiklander Cc: Rijo Thomas , Herbert Xu , Dan Carpenter , Devaraj Rangasamy , Hongbo Yao , Colin Ian King , linux-kernel@vger.kernel.org, =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?= Subject: [PATCH v2 1/3] tee: add support for session's client UUID generation Date: Thu, 30 Apr 2020 15:37:09 +0300 Message-Id: <20200430123711.20083-2-vesa.jaaskelainen@vaisala.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200430123711.20083-1-vesa.jaaskelainen@vaisala.com> References: <20200430123711.20083-1-vesa.jaaskelainen@vaisala.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-OriginalArrivalTime: 30 Apr 2020 12:37:21.0286 (UTC) FILETIME=[17B4FA60:01D61EEC] Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org TEE Client API defines that from user space only information needed for specified login operations is group identifier for group based logins. REE kernel is expected to formulate trustworthy client UUID and pass that to TEE environment. REE kernel is required to verify that provided group identifier for group based logins matches calling processes group memberships. TEE specification only defines that the information passed from REE environment to TEE environment is encoded into on UUID. In order to guarantee trustworthiness of client UUID user space is not allowed to freely pass client UUID. UUIDv5 form is used encode variable amount of information needed for different login types. Signed-off-by: Vesa Jääskeläinen --- drivers/tee/Kconfig | 1 + drivers/tee/tee_core.c | 153 ++++++++++++++++++++++++++++++++++++++++ include/linux/tee_drv.h | 16 +++++ 3 files changed, 170 insertions(+) diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig index 8da63f38e6bd..806eb87d4da0 100644 --- a/drivers/tee/Kconfig +++ b/drivers/tee/Kconfig @@ -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 diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 6aec502c495c..d5db206d6af2 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -6,18 +6,33 @@ #define pr_fmt(fmt) "%s: " fmt, __func__ #include +#include #include #include #include #include #include #include +#include +#include #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,144 @@ 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]) +{ + const char *application_id = NULL; + 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= + * + * For TEEC_LOGIN_GROUP: + * 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) { diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index 1412e9cc79ce..8471b790e858 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -165,6 +165,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 -- 2.17.1