From patchwork Thu Dec 20 10:16:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 154326 Delivered-To: patches@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp5976062ljp; Thu, 20 Dec 2018 02:16:58 -0800 (PST) X-Received: by 2002:a17:902:765:: with SMTP id 92mr23602736pli.242.1545301018215; Thu, 20 Dec 2018 02:16:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545301018; cv=none; d=google.com; s=arc-20160816; b=A2xwHfHEHwhtv6Lr7dido5D0wXpdeHIUQG1sHVGK+YJ2/LawPuXlJ+1vbhz7PJYbIS YhsmPzFHlDyGqm2dynoDG2M0lSIswaYuOyrMi5EHfhZxgitlli8X05PXJ+M6YQ7/67H7 N7tT4HdZJQqYHIeW8PWyT7WnOGNaC7a6BvjNEO45zHJ/mWi2DySxvKv0xEhVh4BWx9Kw tXJNgO3wIPnwiYcGv6ufZDH/qkDekbgv+6oESeUBeS1ec6R1B0HvSlj52YMpha3KyyXe Lb0dwKBeYlAr1CrVq2af/wV7ZOjOrjuBas5M1fynigdotyzStKXvtHkGSjY5RiWCHyZ7 qyTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=uuHGIoyqQtttS9xE06KahrWzGw46xmUc9M7qxbxCq40=; b=IFC28b43awviBwpFt0a9DS4u0iKv+aUY0ERh9E+qkKRSxXinHwNHFTU0zYQ+Hg5I0q 5w8iWkYShGlQciQ1S2Q5GPaLWbmYN7BpxwAd647MAHVMGRM4u6iYfEF3DcDbHcsxrZi6 sIEwlyUFdsergWzZqiazUwbQ1+4Li8+h+NdiJ7+fIWQUDGhvp9SclswUKYO1IB7LdGBv elSQ7z1pVwUCbLzUVgKmSVzsFjZHNGZbg/2RKR7NjZnnEUpss2Q6KBBIZJnUcuMDs/hy L7tWgTvW8bnwiPhXI+XSwGUperi8LxWfFWNd3m8mu9N9Pbqi5zRnhA3NpxSQG1kiHHQZ AAvg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ajGP46U6; spf=pass (google.com: domain of sumit.garg@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=sumit.garg@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id p22sor34546372pfi.50.2018.12.20.02.16.58 for (Google Transport Security); Thu, 20 Dec 2018 02:16:58 -0800 (PST) Received-SPF: pass (google.com: domain of sumit.garg@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ajGP46U6; spf=pass (google.com: domain of sumit.garg@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=sumit.garg@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=uuHGIoyqQtttS9xE06KahrWzGw46xmUc9M7qxbxCq40=; b=ajGP46U6NjpHHRC56S2lY2G8EiPjWcpkOTCPpfxZrSiKWMQkovY+oUtJbnRywHK4vh WtAxJ6U31J8hDVu3OiFtusnowPLR7rkKyV5nHaE34hsVx360F7UgzpeuQfgcBjCnM4f3 prTX3sqk9BM9xURso6fUBYW5uibh6gdxIos+8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=uuHGIoyqQtttS9xE06KahrWzGw46xmUc9M7qxbxCq40=; b=LsGoUye3NpuFBDra7tYfHStR4pGQ46I8oQ+jXrG8gImA3nte1sNLC+Q9yXcxuoS+bt mY33g07iteLmE4m6klubZxfdZ9tJjppVR2K3RJi99001gOCGZXy5+/ag72audRo/N+Au 5pIRAthXKKK7QsVmjmiVpZGzeR8Qdckh8Ns4MaUHWc8JMd3yCfb4p3IFnRSFrufSXN/1 03ZV0/6BUiv4v0mdG94ZBOQFH2TBEqy97350he1E93pZZyvuClsA1lJgiASjdPb9lcKg 764HX7Lw/Y2dfs/gg1xy3G5fcahxfHOBbjyS3Ti1/Mo1pit/VbezsiQTP0xy/YGb0ENl y9sg== X-Gm-Message-State: AA+aEWZ/201lLREjmtZKwkPhGYSGyDnoug6kCy/f3Vx2xco5nFSG5O0y 43ZM5RiIfDVi0U0f1enHefvu5EP3+27wQA== X-Google-Smtp-Source: AFSGD/ViCsqsUXha6hUL05d6/42Q9eFK0flslWvjDgXCwj64+YM2grad3zS2XsuuIJaJ6r4mMuAW+Q== X-Received: by 2002:a62:2a4b:: with SMTP id q72mr23444652pfq.61.1545301017731; Thu, 20 Dec 2018 02:16:57 -0800 (PST) Return-Path: Received: from localhost.localdomain ([117.196.232.175]) by smtp.gmail.com with ESMTPSA id f67sm44097089pff.29.2018.12.20.02.16.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 20 Dec 2018 02:16:57 -0800 (PST) From: Sumit Garg To: daniel.thompson@linaro.org Cc: patches@linaro.org, Sumit Garg Subject: [PATCH v2 1/2] dt/bindings: add bindings for optional optee rng-uuid property Date: Thu, 20 Dec 2018 15:46:37 +0530 Message-Id: <1545300998-10069-2-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1545300998-10069-1-git-send-email-sumit.garg@linaro.org> References: <1545300998-10069-1-git-send-email-sumit.garg@linaro.org> Add bindings for OP-TEE based optional hardware random number generator identifier property. It could be used on ARM based devices where entropy source is not accessible to normal world (linux in this case). Signed-off-by: Sumit Garg --- Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt | 4 ++++ 1 file changed, 4 insertions(+) -- 2.7.4 diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt index d38834c..e3a4c35 100644 --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.txt @@ -20,6 +20,9 @@ the reference implementation maintained by Linaro. "hvc" : HVC #0, with the register assignments specified in drivers/tee/optee/optee_smc.h +- rng-uuid : Optional OP-TEE based RNG service identifier in case + hardware entropy source is not accesible to normal world + (Linux). Example: @@ -27,5 +30,6 @@ Example: optee { compatible = "linaro,optee-tz"; method = "smc"; + rng-uuid = "ab7a617c-b8e7-4d8f-8301-d09b61036b64"; }; }; From patchwork Thu Dec 20 10:16:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 154327 Delivered-To: patches@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp5976119ljp; Thu, 20 Dec 2018 02:17:01 -0800 (PST) X-Received: by 2002:a62:2c4d:: with SMTP id s74mr23511771pfs.6.1545301020869; Thu, 20 Dec 2018 02:17:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545301020; cv=none; d=google.com; s=arc-20160816; b=I+EapYy6b+8VHA/EhbfzQnbIDT+3T+YndoTneDVp7qAy96IVHkTY1PaWpUARj8mnMX d5BRMYrg0X1EReF4JvstX3MQfsvCw1pIZaHuuU8AvvySNQYUYXqN9vcHv15pBdWEvBJ7 TauSogQ5ArvHI17eMIAbRZRfAz83opqwFhRIq2IqgJIO83rXPsm158a+6RTrvx2hawAd hUJ6axn7qZApEYh3JTkfl6aDyQ1CL2tpVyc47tVhNULG76Xxl9RGwx0WZCxQ6D/LSM4v mLdATYYi7lBUmGjGrNeMuc+1utg6SsInTwBkv4sy6fE8ZgZiRlGKVXCADyQkIMAZe51z 8XVQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=lmJ5zibTAVNRPPc6FEVhSaOZlC0eklES57rQGeEpEMs=; b=dqOvRQN70RXJFTju9ApPszGpIik4x2SRRl835Pj+FvbI5ldgfSowS2saH3hgf4g2y3 7sHydJJAUp5Qg//aAgvmbH7FPa7McXiIvhupIDEIbYe5RQHPs9R/7y0l08nj0E+sVWCF cb+9+hiV73+gC4o5zenkJ6cAKpIGdGcHhfm7vrh9nfC/v++bDOjCstRtACt5BG6K1dwr dLkI4HKzg+//hGJDBm68nBj1iM5zpDLZY6CumvKm23fGKNPZXVYldoI3FgwJ/19ZqOFa zZq4UQiVp6zS7R+BuWZWjtSoWE1trDCXhsNAuHbPQJEwsoJL2M9xYovwrK2LG3xs/jr2 VXPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JGq7F3Xo; spf=pass (google.com: domain of sumit.garg@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=sumit.garg@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id c10sor33393663pgq.28.2018.12.20.02.17.00 for (Google Transport Security); Thu, 20 Dec 2018 02:17:00 -0800 (PST) Received-SPF: pass (google.com: domain of sumit.garg@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JGq7F3Xo; spf=pass (google.com: domain of sumit.garg@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=sumit.garg@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=lmJ5zibTAVNRPPc6FEVhSaOZlC0eklES57rQGeEpEMs=; b=JGq7F3XosAyMbse4qmunxmQST+EUxN60RbAWSwxFGRQb55ZSsEEbCSbziK6lkZ71au Ib6yPrlaeFGHIKOyNNg2WJxU/WfeNSNiQSMG/uD7Ra6wPhWnIMIbpsSLcH+MRehxNjoN RX4/SBqn138EOYEA8X2quA0SfrUyrcJTZG2+c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=lmJ5zibTAVNRPPc6FEVhSaOZlC0eklES57rQGeEpEMs=; b=r6ybzhQq/TJlAy8ADApioSRH5acvd/xKvEHa0HT3y+J0w1OwX6Qnu2sNoE1tKB9Sus Jvw9kP2bNo/PK8GRB6vww7WUX1heSY3D10t6RN0uNfgvgAsRVdttKW+VlH8IM7qGNTmf s4625BXNxNLO+SR6i9WFmHUOaJ7U6656MjfrRP5lagkm5IxcWHX0zJXgOwDCvvNXmNCC Zo5wbr5UF6YMxPVo2Dkg7OZVY9rJa5Y+wRMRG1zQ7qMrD4b0cFrgvx7S08o10ZDEydx4 s4K8RL5PtALHs3WbFM9xhCfZF0DH/IfjjYswU53gVhh8dqGQlSEnJSGfYqtpH1HqPzZg 64Jw== X-Gm-Message-State: AA+aEWZ9tnskNlQdgpHs3Y54ufveo+1cuSPBYytxE5UDrg/b61dViRQu 7tACw5JK5yJTr6lVzRR/RfVnfF7c X-Google-Smtp-Source: AFSGD/WnutfzFF8Y6cT07zZfTzAZB9dFSdxuFLar2gCLSeuWu9l/bEfdJkxp8IzGPl3uZ/hA7jJWjw== X-Received: by 2002:a63:a452:: with SMTP id c18mr22859395pgp.204.1545301020299; Thu, 20 Dec 2018 02:17:00 -0800 (PST) Return-Path: Received: from localhost.localdomain ([117.196.232.175]) by smtp.gmail.com with ESMTPSA id f67sm44097089pff.29.2018.12.20.02.16.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 20 Dec 2018 02:16:59 -0800 (PST) From: Sumit Garg To: daniel.thompson@linaro.org Cc: patches@linaro.org, Sumit Garg Subject: [PATCH v2 2/2] hwrng: add OP-TEE based rng driver Date: Thu, 20 Dec 2018 15:46:38 +0530 Message-Id: <1545300998-10069-3-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1545300998-10069-1-git-send-email-sumit.garg@linaro.org> References: <1545300998-10069-1-git-send-email-sumit.garg@linaro.org> On ARM SoC's with TrustZone enabled, peripherals like entropy sources might not be accessible to normal world (linux in this case) and rather accessible to secure world (OP-TEE in this case) only. So this driver aims to provides a generic interface to OP-TEE based random number generator service. Signed-off-by: Sumit Garg --- MAINTAINERS | 5 + drivers/char/hw_random/Kconfig | 15 ++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/optee-rng.c | 280 +++++++++++++++++++++++++++++++++++++ 4 files changed, 301 insertions(+) create mode 100644 drivers/char/hw_random/optee-rng.c -- 2.7.4 diff --git a/MAINTAINERS b/MAINTAINERS index 0767f1d..fe0fb74 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11100,6 +11100,11 @@ M: Jens Wiklander S: Maintained F: drivers/tee/optee/ +OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER +M: Sumit Garg +S: Maintained +F: drivers/char/hw_random/optee-rng.c + OPA-VNIC DRIVER M: Dennis Dalessandro M: Niranjana Vishwanathapura diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index dac895d..25a7d8f 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -424,6 +424,21 @@ config HW_RANDOM_EXYNOS will be called exynos-trng. If unsure, say Y. + +config HW_RANDOM_OPTEE + tristate "OP-TEE based Random Number Generator support" + depends on OPTEE + default HW_RANDOM + help + This driver provides support for OP-TEE based Random Number + Generator on ARM SoCs where hardware entropy sources are not + accessible to normal world (Linux). + + To compile this driver as a module, choose M here: the module + will be called optee-rng. + + If unsure, say Y. + endif # HW_RANDOM config UML_RANDOM diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index e35ec3c..7c9ef4a 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -38,3 +38,4 @@ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o +obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c new file mode 100644 index 0000000..0dbe210 --- /dev/null +++ b/drivers/char/hw_random/optee-rng.c @@ -0,0 +1,280 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define PFX KBUILD_MODNAME ": " + +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 + +/* + * TA_CMD_GET_ENTROPY - Get Entropy from RNG + * + * param[0] (inout memref) - Entropy buffer memory reference + * param[1] unused + * param[2] unused + * param[3] unused + * + * Result: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool + * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed + */ +#define TA_CMD_GET_ENTROPY 0x0 + +/* + * PTA_CMD_GET_RNG_INFO - Get RNG information + * + * param[0] (out value) - value.a: RNG data-rate + * value.b: Quality/Entropy per 1024 bit of data + * param[1] unused + * param[2] unused + * param[3] unused + * + * Result: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + */ +#define TA_CMD_GET_RNG_INFO 0x1 + +#define MAX_ENTROPY_REQ_SZ (4 * 1024) + +static struct tee_context *ctx; +static struct tee_shm *entropy_shm_pool; +static u32 ta_rng_data_rate; +static u32 ta_rng_seesion_id; + +static size_t get_optee_rng_data(void *buf, size_t req_size) +{ + u32 ret = 0; + u8 *rng_data = NULL; + size_t rng_size = 0; + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct tee_param param[4] = {0}; + + /* Invoke TA_CMD_GET_RNG function of Trusted App */ + inv_arg.func = TA_CMD_GET_ENTROPY; + inv_arg.session = ta_rng_seesion_id; + inv_arg.num_params = 4; + + /* Fill invoke cmd params */ + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; + param[0].u.memref.shm = entropy_shm_pool; + param[0].u.memref.size = req_size; + param[0].u.memref.shm_offs = 0; + + ret = tee_client_invoke_func(ctx, &inv_arg, param); + if ((ret < 0) || (inv_arg.ret != 0)) { + pr_err(PFX "TA_CMD_GET_ENTROPY invoke function error: %x\n", + inv_arg.ret); + return 0; + } + + rng_data = tee_shm_get_va(entropy_shm_pool, 0); + if (IS_ERR(rng_data)) { + pr_err(PFX "tee_shm_get_va failed\n"); + return 0; + } + + rng_size = param[0].u.memref.size; + memcpy(buf, rng_data, rng_size); + + return rng_size; +} + +static int optee_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + u8 *data = buf; + size_t read = 0, rng_size = 0; + int timeout = max / MAX_ENTROPY_REQ_SZ + 1; + + /* New random numbers are generated approximately 1byte per 2ms */ + while (read < max) { + if ((max - read) < MAX_ENTROPY_REQ_SZ) + rng_size = get_optee_rng_data(data, (max - read)); + else + rng_size = get_optee_rng_data(data, MAX_ENTROPY_REQ_SZ); + + data += rng_size; + read += rng_size; + + if (wait) { + if (timeout-- == 0) + return read; + if ((max - read) < MAX_ENTROPY_REQ_SZ) + msleep((1000 * (max - read)) / + ta_rng_data_rate); + else + msleep((1000 * MAX_ENTROPY_REQ_SZ) / + ta_rng_data_rate); + } else { + return read; + } + } + + return read; +} + +static int optee_rng_init(struct hwrng *rng) +{ + entropy_shm_pool = tee_shm_alloc(ctx, MAX_ENTROPY_REQ_SZ, + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); + if (IS_ERR(entropy_shm_pool)) { + pr_err(PFX "tee_shm_alloc failed\n"); + return PTR_ERR(entropy_shm_pool); + } + + return 0; +} + +static void optee_rng_cleanup(struct hwrng *rng) +{ + tee_shm_free(entropy_shm_pool); +} + +static struct hwrng optee_rng = { + .name = "optee-rng", + .init = optee_rng_init, + .cleanup = optee_rng_cleanup, + .read = optee_rng_read, +}; + +static const struct of_device_id optee_match[] = { + { .compatible = "linaro,optee-tz" }, + {}, +}; + +static int get_optee_rng_uuid(uuid_t *ta_rng_uuid) +{ + struct device_node *fw_np; + struct device_node *np; + const char *uuid; + + /* Node is supposed to be below /firmware */ + fw_np = of_find_node_by_name(NULL, "firmware"); + if (!fw_np) + return -ENODEV; + + np = of_find_matching_node(fw_np, optee_match); + if (!np || !of_device_is_available(np)) + return -ENODEV; + + if (of_property_read_string(np, "rng-uuid", &uuid)) { + pr_warn(PFX "missing \"uuid\" property\n"); + return -ENXIO; + } + + if (uuid_parse(uuid, ta_rng_uuid)) { + pr_warn(PFX "incorrect rng ta uuid\n"); + return -EINVAL; + } + + return 0; +} + +static int get_optee_rng_info(void) +{ + u32 ret = 0; + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct tee_param param[4] = {0}; + + /* Invoke TA_CMD_GET_RNG function of Trusted App */ + inv_arg.func = TA_CMD_GET_RNG_INFO; + inv_arg.session = ta_rng_seesion_id; + inv_arg.num_params = 4; + + /* Fill invoke cmd params */ + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; + + ret = tee_client_invoke_func(ctx, &inv_arg, param); + if ((ret < 0) || (inv_arg.ret != 0)) { + pr_err(PFX "TA_CMD_GET_RNG_INFO invoke function error: %x\n", + inv_arg.ret); + return -EINVAL; + } + + ta_rng_data_rate = param[0].u.value.a; + optee_rng.quality = param[0].u.value.b; + + return 0; +} + +static int tee_match(struct tee_ioctl_version_data *ver, const void *data) +{ + if (ver->impl_id == TEE_IMPL_ID_OPTEE) + return 1; + else + return 0; +} + +static int __init mod_init(void) +{ + int ret = 0, err = -ENODEV; + struct tee_ioctl_open_session_arg sess_arg = {0}; + uuid_t ta_rng_uuid = {0}; + + err = get_optee_rng_uuid(&ta_rng_uuid); + if (err) + return err; + + /* Open context with TEE driver */ + ctx = tee_client_open_context(NULL, tee_match, NULL, NULL); + if (IS_ERR(ctx)) + return -ENODEV; + + /* Open session with hwrng Trusted App */ + memcpy(sess_arg.uuid, ta_rng_uuid.b, TEE_IOCTL_UUID_LEN); + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; + sess_arg.num_params = 0; + + ret = tee_client_open_session(ctx, &sess_arg, NULL); + if ((ret < 0) || (sess_arg.ret != 0)) { + pr_err(PFX "tee_client_open_session failed, error: %x\n", + sess_arg.ret); + err = -EINVAL; + goto out_ctx; + } + ta_rng_seesion_id = sess_arg.session; + + err = get_optee_rng_info(); + if (err) + goto out_sess; + + err = hwrng_register(&optee_rng); + if (err) { + pr_err(PFX " registering failed (%d)\n", err); + goto out_sess; + } + + return 0; + +out_sess: + tee_client_close_session(ctx, ta_rng_seesion_id); +out_ctx: + tee_client_close_context(ctx); + + return err; +} + +static void __exit mod_exit(void) +{ + tee_client_close_session(ctx, ta_rng_seesion_id); + tee_client_close_context(ctx); + hwrng_unregister(&optee_rng); +} + +module_init(mod_init); +module_exit(mod_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sumit Garg "); +MODULE_DESCRIPTION("OP-TEE based random number generator driver");