From patchwork Thu Nov 22 06:52:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 151729 Delivered-To: patches@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp370257ljp; Wed, 21 Nov 2018 22:53:19 -0800 (PST) X-Received: by 2002:a17:902:824:: with SMTP id 33-v6mr10300638plk.107.1542869598944; Wed, 21 Nov 2018 22:53:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542869598; cv=none; d=google.com; s=arc-20160816; b=zbJ80DqQRBcEAKGMUZAbQH1rRkazmaxLBe1/+bemr7eFg/nORaXmgPLGsDRoADUygs MiRod+f7dvf9wpIZqm+ekD3ipJsPyF5lZO9ZtqQffbc3KyCCw5YnG7I38/QNPzC901y9 Icqn73+C1mpejfuZXNrqYHkEdxhEp9mL+XWd8cnK3PHQcZE9EyhIGdYhvGf4vgg0BQ59 1L6vyRSDE/OC+ytVQdnfe26vi+sn7qubhNPFvAWwUTfNHw2n6+AQnNYdjJaqf/1RH6KM 3XLF6Tk+l+ft4hwKQQswbFMkddMRbaH/2rFtYOSFgLoseTz/1JQsRvPRS5JgsTc06Phx c2eQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:cc:to:from:dkim-signature; bh=9yoPR4aw/IK38P/e/Bw9RUCFkQAe7jN9kzfZ3SjmHyc=; b=Cobkgof8tUk9xvafr2ZqmdIfuaMeNSH0I89hXK+o8vlGVyZmcXA93YmR24Czie0NUf n+o/uAtn99FEWu0BiIDi5vdm8RE/QkFyAMwvHjm7VcMZbJGPrq0RHz4txkwOpY2p97lm OK/QDZJVMOy0zWyWKcd2CU635hTNgZTm6xWNgdvcDBcU6EIoxM7G16vbI7fMmi0FW4U2 xFK9/BhOP0LusMhHEtbBVjwbJG1u5U7LoWDTxry29bP2AH+PbSBZftl6siIQa97tjjwH +zpvQ6w/0aL1vajhnXekP7nnKxNQa+Ap16iN22AeX3/xqc/arHiFHQzWEchxgTHNuwYH wMMw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GbIjOVWY; 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 k6-v6sor56219930pls.18.2018.11.21.22.53.18 for (Google Transport Security); Wed, 21 Nov 2018 22:53:18 -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=GbIjOVWY; 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; bh=9yoPR4aw/IK38P/e/Bw9RUCFkQAe7jN9kzfZ3SjmHyc=; b=GbIjOVWY/ALgyIQeOU5agS/c3LvM7QcfJ5jzDMarzJyEnYPdj5l1tZpFaKojw14IK3 LtKbIa29BUAONB/5NfIVmCMo/69n6S1nQbhq63UbDf7tPQkwZGRBWY7Mixxyl3c2xJf1 jMTJlKfF5nlEjQKQB2SD/Dc9JVy40r1674B/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; bh=9yoPR4aw/IK38P/e/Bw9RUCFkQAe7jN9kzfZ3SjmHyc=; b=ABk2sS67/JDHmZR/PBRZluFB6KRACZDsj5v96HF6HcFxrdp6jqaWsuyJj3n+CUKg7u MwVSbIqkw8xCFXxgV8Attv58i8FYaldCTCE739Vqk8cTLhr+lIKQ9sdESrFjqwAGdcQf cASISKfsASjXzibQRKzvDC4dUhY/F0YtNA0wUTbORfWfVJ7evdTmV4ACYclhwbrkSGB1 wxI5l2jlcll62XMH+HHRfx+BT3ZX6E8YjuNRRLUsEFQJcgx6o2VvuSobKZunGiGVwH5i Vw8Ht7g/PlnIf0PJlC4h18nOF8w3H2WWv1Fricq7AbWOVyg/WE3FmN9EYvLINOE8kixO Zy2A== X-Gm-Message-State: AA+aEWaEwBq1duRXlb2hSgK2x5jqReBwbXB6Ef8QbQZHftxzUjjTbxAk Fp9Ox9SRzi5I7lbsHzpLAQfEmDtA X-Google-Smtp-Source: AFSGD/X6gnSH7cuj3xy0D/Fwo3bn3Nbwy/tocc90dz3niW0qPgeI062EYjg1vcpPXvTuDOMqTqE4/A== X-Received: by 2002:a17:902:8a95:: with SMTP id p21mr5082894plo.183.1542869598297; Wed, 21 Nov 2018 22:53:18 -0800 (PST) Return-Path: Received: from localhost.localdomain ([117.252.69.224]) by smtp.gmail.com with ESMTPSA id c4sm18745043pfm.151.2018.11.21.22.53.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 21 Nov 2018 22:53:17 -0800 (PST) From: Sumit Garg To: daniel.thompson@linaro.org Cc: patches@linaro.org, Sumit Garg Subject: [PATCH v4 1/3] libtomcrypt: Import SHA512/256 approved hash algorithm Date: Thu, 22 Nov 2018 12:22:55 +0530 Message-Id: <1542869577-32435-1-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 SHA-512/256 is an approved hash algorithm and a vetted conditioner as per NIST.SP.800-90B spec. We have used it to condition raw thermal sensor noise on Developerbox to condense entropy. It is imported from libtomcrypt: Git url: https://github.com/libtom/libtomcrypt.git, release tag: v1.18.0. Signed-off-by: Sumit Garg --- core/crypto.mk | 1 + core/include/crypto/crypto.h | 11 ++ core/lib/libtomcrypt/include/tomcrypt_custom.h | 3 + core/lib/libtomcrypt/include/tomcrypt_hash.h | 11 ++ core/lib/libtomcrypt/src/hashes/sha2/sha512_256.c | 158 ++++++++++++++++++++++ core/lib/libtomcrypt/src/hashes/sha2/sub.mk | 1 + core/lib/libtomcrypt/src/tee_ltc_provider.c | 17 +++ 7 files changed, 202 insertions(+) create mode 100644 core/lib/libtomcrypt/src/hashes/sha2/sha512_256.c -- 2.7.4 diff --git a/core/crypto.mk b/core/crypto.mk index b0a50d5..2fcde13 100644 --- a/core/crypto.mk +++ b/core/crypto.mk @@ -26,6 +26,7 @@ CFG_CRYPTO_SHA224 ?= y CFG_CRYPTO_SHA256 ?= y CFG_CRYPTO_SHA384 ?= y CFG_CRYPTO_SHA512 ?= y +CFG_CRYPTO_SHA512_256 ?= y # Asymmetric ciphers CFG_CRYPTO_DSA ?= y diff --git a/core/include/crypto/crypto.h b/core/include/crypto/crypto.h index 2018d3c..54a5f74 100644 --- a/core/include/crypto/crypto.h +++ b/core/include/crypto/crypto.h @@ -256,6 +256,17 @@ TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key, TEE_Result hash_sha256_check(const uint8_t *hash, const uint8_t *data, size_t data_size); +/* + * Computes a SHA-512/256 hash, vetted conditioner as per NIST.SP.800-90B. + * It doesn't require crypto_init() to be called in advance and has as few + * dependencies as possible. + * + * This function could be used inside interrupt context where the crypto + * library can't be used due to mutex handling. + */ +TEE_Result hash_sha512_256_compute(uint8_t *digest, const uint8_t *data, + size_t data_size); + #define CRYPTO_RNG_SRC_IS_QUICK(sid) (!!((sid) & 1)) /* diff --git a/core/lib/libtomcrypt/include/tomcrypt_custom.h b/core/lib/libtomcrypt/include/tomcrypt_custom.h index d4f8de1..1bb2f02 100644 --- a/core/lib/libtomcrypt/include/tomcrypt_custom.h +++ b/core/lib/libtomcrypt/include/tomcrypt_custom.h @@ -200,6 +200,9 @@ #ifdef CFG_CRYPTO_SHA512 #define LTC_SHA512 #endif +#ifdef CFG_CRYPTO_SHA512_256 +#define LTC_SHA512_256 +#endif #define LTC_NO_MACS diff --git a/core/lib/libtomcrypt/include/tomcrypt_hash.h b/core/lib/libtomcrypt/include/tomcrypt_hash.h index 8f67ad2..6678acc 100644 --- a/core/lib/libtomcrypt/include/tomcrypt_hash.h +++ b/core/lib/libtomcrypt/include/tomcrypt_hash.h @@ -255,6 +255,17 @@ int sha384_test(void); extern const struct ltc_hash_descriptor sha384_desc; #endif +#ifdef LTC_SHA512_256 +#ifndef LTC_SHA512 + #error LTC_SHA512 is required for LTC_SHA512_256 +#endif +int sha512_256_init(hash_state * md); +#define sha512_256_process sha512_process +int sha512_256_done(hash_state * md, unsigned char *hash); +int sha512_256_test(void); +extern const struct ltc_hash_descriptor sha512_256_desc; +#endif + #if defined(LTC_SHA256) || defined(LTC_SHA256_ARM32_CE) int sha256_init(hash_state * md); int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen); diff --git a/core/lib/libtomcrypt/src/hashes/sha2/sha512_256.c b/core/lib/libtomcrypt/src/hashes/sha2/sha512_256.c new file mode 100644 index 0000000..066f141 --- /dev/null +++ b/core/lib/libtomcrypt/src/hashes/sha2/sha512_256.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2001-2007, Tom St Denis + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +/** + @param sha512_256.c + SHA512/256 hash included in sha512.c +*/ + +#include "tomcrypt.h" + +#if defined(LTC_SHA512_256) && defined(LTC_SHA512) + +const struct ltc_hash_descriptor sha512_256_desc = +{ + "sha512-256", + 16, + 32, + 128, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 6, }, + 9, + + &sha512_256_init, + &sha512_process, + &sha512_256_done, + &sha512_256_test, + NULL +}; + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha512_256_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + + md->sha512.curlen = 0; + md->sha512.length = 0; + md->sha512.state[0] = CONST64(0x22312194FC2BF72C); + md->sha512.state[1] = CONST64(0x9F555FA3C84C64C2); + md->sha512.state[2] = CONST64(0x2393B86B6F53B151); + md->sha512.state[3] = CONST64(0x963877195940EABD); + md->sha512.state[4] = CONST64(0x96283EE2A88EFFE3); + md->sha512.state[5] = CONST64(0xBE5E1E2553863992); + md->sha512.state[6] = CONST64(0x2B0199FC2C85B8AA); + md->sha512.state[7] = CONST64(0x0EB72DDC81C52CA2); + return CRYPT_OK; +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (48 bytes) + @return CRYPT_OK if successful +*/ +int sha512_256_done(hash_state * md, unsigned char *out) +{ + unsigned char buf[64]; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha512.curlen >= sizeof(md->sha512.buf)) { + return CRYPT_INVALID_ARG; + } + + sha512_done(md, buf); + XMEMCPY(out, buf, 32); +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha512_256_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + const char *msg; + unsigned char hash[32]; + } tests[] = { + { "abc", + { 0x53, 0x04, 0x8E, 0x26, 0x81, 0x94, 0x1E, 0xF9, + 0x9B, 0x2E, 0x29, 0xB7, 0x6B, 0x4C, 0x7D, 0xAB, + 0xE4, 0xC2, 0xD0, 0xC6, 0x34, 0xFC, 0x6D, 0x46, + 0xE0, 0xE2, 0xF1, 0x31, 0x07, 0xE7, 0xAF, 0x23 } + }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x39, 0x28, 0xE1, 0x84, 0xFB, 0x86, 0x90, 0xF8, + 0x40, 0xDA, 0x39, 0x88, 0x12, 0x1D, 0x31, 0xBE, + 0x65, 0xCB, 0x9D, 0x3E, 0xF8, 0x3E, 0xE6, 0x14, + 0x6F, 0xEA, 0xC8, 0x61, 0xE1, 0x9B, 0x56, 0x3A } + }, + }; + + int i; + unsigned char tmp[32]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha512_256_init(&md); + sha512_256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha512_256_done(&md, tmp); + if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA512-265", i)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif /* defined(LTC_SHA384) && defined(LTC_SHA512) */ + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/core/lib/libtomcrypt/src/hashes/sha2/sub.mk b/core/lib/libtomcrypt/src/hashes/sha2/sub.mk index e6ff9bf..aa88b46 100644 --- a/core/lib/libtomcrypt/src/hashes/sha2/sub.mk +++ b/core/lib/libtomcrypt/src/hashes/sha2/sub.mk @@ -15,3 +15,4 @@ endif srcs-$(CFG_CRYPTO_SHA384) += sha384.c srcs-$(CFG_CRYPTO_SHA512) += sha512.c +srcs-$(CFG_CRYPTO_SHA512_256) += sha512_256.c diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c index 686f711..d9ebf0d 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -2726,6 +2726,23 @@ TEE_Result hash_sha256_check(const uint8_t *hash, const uint8_t *data, } #endif +#if defined(CFG_CRYPTO_SHA512_256) +TEE_Result hash_sha512_256_compute(uint8_t *digest, const uint8_t *data, + size_t data_size) +{ + hash_state hs; + + if (sha512_256_init(&hs) != CRYPT_OK) + return TEE_ERROR_GENERIC; + if (sha512_256_process(&hs, data, data_size) != CRYPT_OK) + return TEE_ERROR_GENERIC; + if (sha512_256_done(&hs, digest) != CRYPT_OK) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} +#endif + TEE_Result crypto_aes_expand_enc_key(const void *key, size_t key_len, void *enc_key, unsigned int *rounds) { From patchwork Thu Nov 22 06:52:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 151730 Delivered-To: patches@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp370295ljp; Wed, 21 Nov 2018 22:53:22 -0800 (PST) X-Received: by 2002:a62:6f88:: with SMTP id k130mr10092730pfc.234.1542869601956; Wed, 21 Nov 2018 22:53:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542869601; cv=none; d=google.com; s=arc-20160816; b=gf6wrwjwza3UNMWxpiqhC43wTf06ci552ZDK9806V9XEWt6b6MF9goi1WZcGht/hc4 g/Vi2YmeAtWRyFno99d1jBfnQr/5HP1aqep2/yDQqf32L7ktA14pKYjuS+DXBSrCLPHh 7Kel9M+0N04ifRAarbie4KiGJwqfn8uXgGx6oIe2TktaldkLEMete65ayyoe9rEQWnUh JHH7i+dXhEWFKBujxfr3Kgw1Z5EpNCkABYhNbBK7PxLXCml2s6Tb3MJG6ohxnfyuJO74 I3MBxkiiYOBtyrPc0By1FmxHfiNpKiBSUnk99z2bbYJlOip9rg9lH/FPkCwmVuVMeROW 03Rg== 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=ZRSf/PnOlFiPbqot3PWxBg57/D2oit07iiy9kH0bfxc=; b=Arn3m/A9wnSzoxIh0YmPuS5JPLNwv/h1LY906nQvzTIb/KnNY+0YW4KDTAc1tqAIsd 0/+wc5KUsj0h9j17lrIB5XblDv42kPkvp3zEPnd+YLWmCUUUF+P3/4ihK3WkQNKRGgfx UQIanJd0dQpcPXzZEqZ3+YVCVP9OsE/C13b0+rivmZISUxo5d6jLdXpKOigo8H6baRdc NZf53o+UVDlxXSwIIEQxs/lnxrU94Le0S+uAylVdRIOVKodgCC4ZANY+NWyxVXNYO5xr AjUO4GnDbA4UYwWj+TZdWz8YlwLB1s9CZqOFRCxqq8zllGwBuLFhyyqH4RfOMJ1DkXwi u6XA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=I6fTnqN0; 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 o10-v6sor45173872plk.56.2018.11.21.22.53.21 for (Google Transport Security); Wed, 21 Nov 2018 22:53:21 -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=I6fTnqN0; 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=ZRSf/PnOlFiPbqot3PWxBg57/D2oit07iiy9kH0bfxc=; b=I6fTnqN0ethq27A181OyjpTjmiPRuvsvofRNPbWODKFRpaC3ErqNvC3Ciq0dlUpjnf +tuHLmGdyZkvKEUAb6vV5ombmfR86oJk8YXd3si9uoQyAUgTdQcadJtjPAoK9T0nnCFu km4Z2JY12PFfR0te3VbE5r7r0hFLsvdaltKKM= 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=ZRSf/PnOlFiPbqot3PWxBg57/D2oit07iiy9kH0bfxc=; b=rzza5kUENwDUYwdhgg89ZWoufYnzbOMIfLdurxOZH09WFaiN9UMSoE45Mtx6YEryql KI1w54KjmfvJXWnt8YZxOohUoz60W5Lri9GUoooWxmdkKBR1WgbB6IK1ryg4KuuH9A3K ioyILkwuSj7tlH7IzI0Tdzxoza1er9RCWuhEqjDQoLkC5dEnS71LzBhe+i7gNg7cTNXU CswA2EDq1NtQEA3gbNBKab0gw7mJ87qQzNJNi22R+sA0WhIV8fxVRzsRHQZ/XWwcA9f2 UVrrpI/LJ6iG7g8dLhRTZXQmmdhO+WK4s8JBNw3qh0pZDAoiOzVTN278pAgADO6TncZ4 LTNA== X-Gm-Message-State: AA+aEWYiuzZHZd3BxAq/x+S8xi4lwhJ6TQ6MKYZ9srxzE7V+URApbqS+ oQxm9kYJBMWCBZUDcGvxZ4LZ4MTx X-Google-Smtp-Source: AFSGD/VBmHzEMEvfsm5svdNKKlXO4JqribQtcxfwSe1hltP9F4pbXm/AA6ituMgfiWHpjAETwmpecw== X-Received: by 2002:a17:902:2bc5:: with SMTP id l63-v6mr10133591plb.241.1542869601344; Wed, 21 Nov 2018 22:53:21 -0800 (PST) Return-Path: Received: from localhost.localdomain ([117.252.69.224]) by smtp.gmail.com with ESMTPSA id c4sm18745043pfm.151.2018.11.21.22.53.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 21 Nov 2018 22:53:20 -0800 (PST) From: Sumit Garg To: daniel.thompson@linaro.org Cc: patches@linaro.org, Sumit Garg Subject: [PATCH v4 2/3] synquacer: Add secure timer interrupt framework Date: Thu, 22 Nov 2018 12:22:56 +0530 Message-Id: <1542869577-32435-2-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1542869577-32435-1-git-send-email-sumit.garg@linaro.org> References: <1542869577-32435-1-git-send-email-sumit.garg@linaro.org> Currently there is no means to perform background housekeeping in secure world on Synquacer platforms. Provide an (optional) periodic timer to allow any housekeeping to be performed. Although it could be expanded, at present the code is fairly simple because we expect only a single PTA to exploit the timer interrupt. The secure timer interrupt is configured to fire every 2ms. Signed-off-by: Sumit Garg --- core/arch/arm/include/arm64.h | 4 ++ core/arch/arm/plat-synquacer/main.c | 30 ++++++++++-- core/arch/arm/plat-synquacer/platform_config.h | 2 + core/arch/arm/plat-synquacer/sub.mk | 1 + core/arch/arm/plat-synquacer/timer_fiq.c | 67 ++++++++++++++++++++++++++ core/arch/arm/plat-synquacer/timer_fiq.h | 13 +++++ 6 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 core/arch/arm/plat-synquacer/timer_fiq.c create mode 100644 core/arch/arm/plat-synquacer/timer_fiq.h -- 2.7.4 diff --git a/core/arch/arm/include/arm64.h b/core/arch/arm/include/arm64.h index 2c1fd8c..0cf14c0 100644 --- a/core/arch/arm/include/arm64.h +++ b/core/arch/arm/include/arm64.h @@ -305,6 +305,10 @@ DEFINE_REG_READ_FUNC_(cntfrq, uint32_t, cntfrq_el0) DEFINE_REG_READ_FUNC_(cntpct, uint64_t, cntpct_el0) DEFINE_REG_READ_FUNC_(cntkctl, uint32_t, cntkctl_el1) DEFINE_REG_WRITE_FUNC_(cntkctl, uint32_t, cntkctl_el1) +DEFINE_REG_READ_FUNC_(cntps_ctl, uint32_t, cntps_ctl_el1) +DEFINE_REG_WRITE_FUNC_(cntps_ctl, uint32_t, cntps_ctl_el1) +DEFINE_REG_READ_FUNC_(cntps_cval, uint32_t, cntps_cval_el1) +DEFINE_REG_WRITE_FUNC_(cntps_cval, uint32_t, cntps_cval_el1) DEFINE_REG_READ_FUNC_(pmccntr, uint64_t, pmccntr_el0) diff --git a/core/arch/arm/plat-synquacer/main.c b/core/arch/arm/plat-synquacer/main.c index c3aac4c..714becd 100644 --- a/core/arch/arm/plat-synquacer/main.c +++ b/core/arch/arm/plat-synquacer/main.c @@ -18,6 +18,7 @@ #include #include #include +#include static void main_fiq(void); @@ -46,7 +47,7 @@ const struct thread_handlers *generic_boot_get_handlers(void) static void main_fiq(void) { - panic(); + gic_it_handle(&gic_data); } void console_init(void) @@ -66,12 +67,31 @@ void main_init_gic(void) if (!gicd_base) panic(); - /* Initialize GIC */ - gic_init(&gic_data, 0, gicd_base); + /* On ARMv8-A, GIC configuration is initialized in TF-A */ + gic_init_base_addr(&gic_data, 0, gicd_base); + itr_init(&gic_data.chip); } -void main_secondary_init_gic(void) +static enum itr_return timer_itr_cb(struct itr_handler *h __unused) +{ + /* Reset timer for next FIQ */ + generic_timer_handler(); + + return ITRR_HANDLED; +} + +static struct itr_handler timer_itr = { + .it = IT_SEC_TIMER, + .flags = ITRF_TRIGGER_LEVEL, + .handler = timer_itr_cb, +}; + +static TEE_Result init_timer_itr(void) { - gic_cpu_init(&gic_data); + itr_add(&timer_itr); + itr_enable(IT_SEC_TIMER); + + return TEE_SUCCESS; } +driver_init(init_timer_itr); diff --git a/core/arch/arm/plat-synquacer/platform_config.h b/core/arch/arm/plat-synquacer/platform_config.h index 4d6d545..f9b1b40 100644 --- a/core/arch/arm/plat-synquacer/platform_config.h +++ b/core/arch/arm/plat-synquacer/platform_config.h @@ -19,6 +19,8 @@ #define CONSOLE_UART_CLK_IN_HZ 62500000 #define CONSOLE_BAUDRATE 115200 +#define IT_SEC_TIMER 29 + #define DRAM0_BASE 0x80000000 /* Platform specific defines */ diff --git a/core/arch/arm/plat-synquacer/sub.mk b/core/arch/arm/plat-synquacer/sub.mk index 8ddc2fd..cfa1dc3 100644 --- a/core/arch/arm/plat-synquacer/sub.mk +++ b/core/arch/arm/plat-synquacer/sub.mk @@ -1,2 +1,3 @@ global-incdirs-y += . srcs-y += main.c +srcs-y += timer_fiq.c diff --git a/core/arch/arm/plat-synquacer/timer_fiq.c b/core/arch/arm/plat-synquacer/timer_fiq.c new file mode 100644 index 0000000..c775bb9 --- /dev/null +++ b/core/arch/arm/plat-synquacer/timer_fiq.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2018, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned int timer_lock = SPINLOCK_UNLOCK; +static bool timer_fiq_running; + +void generic_timer_start(void) +{ + uint64_t cval; + uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); + + cpu_spin_lock(&timer_lock); + + if (timer_fiq_running == true) + goto exit; + + /* The timer will fire every 2 ms */ + cval = read_cntpct() + (read_cntfrq() / 500); + write_cntps_cval(cval); + + /* Enable the secure physical timer */ + write_cntps_ctl(1); + + timer_fiq_running = true; + +exit: + cpu_spin_unlock(&timer_lock); + thread_set_exceptions(exceptions); +} + +void generic_timer_stop(void) +{ + uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); + + cpu_spin_lock(&timer_lock); + + /* Disable the timer */ + write_cntps_ctl(0); + + timer_fiq_running = false; + + cpu_spin_unlock(&timer_lock); + thread_set_exceptions(exceptions); +} + +void generic_timer_handler(void) +{ + uint64_t cval; + + /* Ensure that the timer did assert the interrupt */ + assert((read_cntps_ctl() >> 2)); + + /* Reconfigure timer to fire every 2 ms */ + cval = read_cntpct() + (read_cntfrq() / 500); + write_cntps_cval(cval); +} diff --git a/core/arch/arm/plat-synquacer/timer_fiq.h b/core/arch/arm/plat-synquacer/timer_fiq.h new file mode 100644 index 0000000..4f2091a --- /dev/null +++ b/core/arch/arm/plat-synquacer/timer_fiq.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2018, Linaro Limited + */ + +#ifndef __TIMER_FIQ_H +#define __TIMER_FIQ_H + +void generic_timer_start(void); +void generic_timer_stop(void); +void generic_timer_handler(void); + +#endif /* __TIMER_FIQ_H */ From patchwork Thu Nov 22 06:52:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 151731 Delivered-To: patches@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp370333ljp; Wed, 21 Nov 2018 22:53:25 -0800 (PST) X-Received: by 2002:a63:165e:: with SMTP id 30mr8958738pgw.103.1542869605043; Wed, 21 Nov 2018 22:53:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542869605; cv=none; d=google.com; s=arc-20160816; b=LjuHaapUeCGJN/otAMe4wsRomFgL72uGWLf6sMiU9GlYY6Y2qDwDmpw3pRuRqZ1yBG vDERKE6jutt29gZXzaQWBulYNC3YjKS+zeOvuk8dBVxKDVDubr8oOzFNr7J4+LCwTXYy Kon9jSvQaLMiPPuv/92S8Zm/oNFXdtVGH8kUuAJdsgWU0JyJ/f4ZadUCCbXVUOz0SNtv JNRNSrXDypxS9NE86uY/rjXOpQfRKxjHt0Z1wj/UknaYF/o7gfyQpeud9C4G0zNu+j0t RYbaSyBTpKv4RWJDY+rXrv+d51HFkRXwf5PoytqmxJbrarvIPGh/hMHrSA5XHNAMNOKA c3DQ== 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=HyTX9LefFGBZndFARqBJ7dUeAIwGJu2QJY9neomzqwM=; b=v0bt4NjOuAj+2gSlp6CJpGIGanPvUvjEHPlLtfMIx8Ls1PLQFNOzom2fhN2HtUtsK9 mORdh+BmPbIzZ+ekYoXV9ir/aBij3Jzpwp2wehpk6xjJ6xYHwdlkPhpACq6YwrkZV+zE G6ssPo9HimBSw/4toPXyEkoYtCHHKIv3qMXWDIrNjAmo9hY8B/YSwMMt45JCF4gQDH/Z YJ6a8vAoU+Up8cCRKI/S3nKlu6pmBm9ze/OdgmgsPrKA00RNZM7bItmEePCsfeV1HQyy 6b/6Sv7irgMpaXc8yCboESMWGUFOqxvGpQFW1Os5TYI6FrS9d23yftj2Ps1pb7p07Hjn 8hAA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=YGWlxbFO; 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 q2sor5807465plh.10.2018.11.21.22.53.24 for (Google Transport Security); Wed, 21 Nov 2018 22:53:25 -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=YGWlxbFO; 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=HyTX9LefFGBZndFARqBJ7dUeAIwGJu2QJY9neomzqwM=; b=YGWlxbFO4CcyuPpsKvijATZf2OZQNJ2Bf8loLEReudsd9mUmyDFAX1+9n2vn0hBU5b +MCSOAMgFxkKe/EQqPQv/21HeQvIoPNh+y1ZpdJh1sWT+VfW0Fbbeba+Hi0/KzxCpYqr EJGBzWQF7CrsCKN+zjaEwGhgx4TJXK46HabJU= 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=HyTX9LefFGBZndFARqBJ7dUeAIwGJu2QJY9neomzqwM=; b=meIOnyI4mCwRNxpg8JxHq1U86TqDyGBBAXTW/970K9h7YGC70eLUvE121nDLrm0yDx ACddgeLbgkkxQwgZA8vyMmInMwk3z+GN8NAPYzn6QZ6cbONy2iLThAADN6zaqzhiTX+j hFICqNx8iGbAxwosK08vuTAwVyfNVnMQuggEyG5k1Q5DJceQjg8wPZ8AOAr+FHuA7gwk cadNCQi2WD9qttcQHAPev8AemG7cKQknVcUxrkUGyFtzbmTD5EkaUNP2DlWle+XgWTwG 0aAEdWJJ0dsVBHSUL2cHpdsoYESM3MXVwc6+Z1Ir4gHNDSuFv82iO+zjVI9BQrWqNVI4 gLDw== X-Gm-Message-State: AA+aEWYLW60222u+jCs8opGWq2U+vBRKk1MHrBqaaUY9fe85wF5v3K4Y QrNjXFLFhdC8KzTZsqi5hYr0d8/E X-Google-Smtp-Source: AFSGD/Wn86vNC9JhvtJdSqT6hLp1Hw8NdjiVwj3G06qEFbGJicdpVTN6+Rb0G89v9PZFcnDxTJEefQ== X-Received: by 2002:a17:902:8bca:: with SMTP id r10-v6mr9811090plo.199.1542869604339; Wed, 21 Nov 2018 22:53:24 -0800 (PST) Return-Path: Received: from localhost.localdomain ([117.252.69.224]) by smtp.gmail.com with ESMTPSA id c4sm18745043pfm.151.2018.11.21.22.53.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 21 Nov 2018 22:53:23 -0800 (PST) From: Sumit Garg To: daniel.thompson@linaro.org Cc: patches@linaro.org, Sumit Garg Subject: [PATCH v4 3/3] synquacer: Add RNG pseudo TA Date: Thu, 22 Nov 2018 12:22:57 +0530 Message-Id: <1542869577-32435-3-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1542869577-32435-1-git-send-email-sumit.garg@linaro.org> References: <1542869577-32435-1-git-send-email-sumit.garg@linaro.org> This platform provides 7 on-chip thermal sensors accessible from secure world only. So, using thermal noise from these sensors we have tried to create an entropy source as a pseudo TA. Signed-off-by: Sumit Garg --- core/arch/arm/plat-synquacer/main.c | 8 + core/arch/arm/plat-synquacer/platform_config.h | 1 + core/arch/arm/plat-synquacer/rng_pta.c | 347 +++++++++++++++++++++++++ core/arch/arm/plat-synquacer/rng_pta.h | 11 + core/arch/arm/plat-synquacer/rng_pta_client.h | 30 +++ core/arch/arm/plat-synquacer/sub.mk | 1 + 6 files changed, 398 insertions(+) create mode 100644 core/arch/arm/plat-synquacer/rng_pta.c create mode 100644 core/arch/arm/plat-synquacer/rng_pta.h create mode 100644 core/arch/arm/plat-synquacer/rng_pta_client.h -- 2.7.4 diff --git a/core/arch/arm/plat-synquacer/main.c b/core/arch/arm/plat-synquacer/main.c index 714becd..c5af85d 100644 --- a/core/arch/arm/plat-synquacer/main.c +++ b/core/arch/arm/plat-synquacer/main.c @@ -18,6 +18,7 @@ #include #include #include +#include #include static void main_fiq(void); @@ -39,6 +40,7 @@ static struct pl011_data console_data; register_phys_mem(MEM_AREA_IO_NSEC, CONSOLE_UART_BASE, CORE_MMU_DEVICE_SIZE); register_phys_mem(MEM_AREA_IO_SEC, GIC_BASE, CORE_MMU_DEVICE_SIZE); +register_phys_mem(MEM_AREA_IO_SEC, THERMAL_SENSOR_BASE, CORE_MMU_DEVICE_SIZE); const struct thread_handlers *generic_boot_get_handlers(void) { @@ -78,6 +80,9 @@ static enum itr_return timer_itr_cb(struct itr_handler *h __unused) /* Reset timer for next FIQ */ generic_timer_handler(); + /* Collect entropy on each timer FIQ */ + rng_collect_entropy(); + return ITRR_HANDLED; } @@ -92,6 +97,9 @@ static TEE_Result init_timer_itr(void) itr_add(&timer_itr); itr_enable(IT_SEC_TIMER); + /* Enable timer FIQ to fetch entropy required during boot */ + generic_timer_start(); + return TEE_SUCCESS; } driver_init(init_timer_itr); diff --git a/core/arch/arm/plat-synquacer/platform_config.h b/core/arch/arm/plat-synquacer/platform_config.h index f9b1b40..8a91ddb 100644 --- a/core/arch/arm/plat-synquacer/platform_config.h +++ b/core/arch/arm/plat-synquacer/platform_config.h @@ -19,6 +19,7 @@ #define CONSOLE_UART_CLK_IN_HZ 62500000 #define CONSOLE_BAUDRATE 115200 +#define THERMAL_SENSOR_BASE 0x54190000 #define IT_SEC_TIMER 29 #define DRAM0_BASE 0x80000000 diff --git a/core/arch/arm/plat-synquacer/rng_pta.c b/core/arch/arm/plat-synquacer/rng_pta.c new file mode 100644 index 0000000..0329264 --- /dev/null +++ b/core/arch/arm/plat-synquacer/rng_pta.c @@ -0,0 +1,347 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (C) 2018, Linaro Limited + */ + +/* + * Developerbox doesn't provide a hardware based true random number + * generator. So this pseudo TA provides a good source of entropy using + * noise from 7 thermal sensors. Its suitable for entropy required + * during boot, seeding kernel entropy pool, cryptographic use etc. + * + * Assumption + * ========== + * + * We have assumed the entropy of the sensor is better than 8 bits per + * 14 sensor readings. This entropy estimate is based on our simple + * minimal entropy estimates done on 2.1G bytes of raw samples collected + * from thermal sensors. + * + * We believe our estimate to be conservative and have designed to + * health tests to trigger if a sensor does not achieve at least + * 8 bits in 16 sensor reading (we use 16 rather than 14 to prevent + * spurious failures on edge cases). + * + * Theory of operation + * =================== + * + * This routine uses secure timer interrupt to sample raw thermal sensor + * readings. As thermal sensor refresh rate is every 2ms, so interrupt + * fires every 2ms. It implements continuous health test counting rising + * and falling edges to report if sensors fail to provide entropy. + * + * It uses vetted conditioner as SHA512/256 (approved hash algorithm) + * to condense entropy. As per NIST.SP.800-90B spec, to get full entropy + * from vetted conditioner, we need to supply double of input entropy. + * According to assumption above and requirement for vetted conditioner, + * we need to supply 28 raw sensor readings to get 1 byte of full + * entropy as output. So for 32 bytes of conditioner output, we need to + * supply 896 bytes of raw sensor readings. + * + * Interfaces -> Input + * ------------------- + * + * void rng_collect_entropy(void); + * + * Called as part of secure timer interrupt handler to sample raw + * thermal sensor readings and add entropy to the pool. + * + * Interfaces -> Output + * -------------------- + * + * TEE_Result rng_get_entropy(uint32_t types, + * TEE_Param params[TEE_NUM_PARAMS]); + * + * Invoke command to expose an entropy interface to normal world. + * + * Testing + * ======= + * + * Passes FIPS 140-2 rngtest. + * + * Limitations + * =========== + * + * Output rate is limited to approx. 128 bytes per second. + * + * Our entropy estimation was not reached using any approved or + * published estimation framework such as NIST.SP.800-90B and was tests + * on a very small set of physical samples (instead we have adopted what + * we believe to be a conservative estimate and partnered it with a + * fairly agressive health check). + * + * Generating the SHA512/256 hash takes 24uS and will be run by an + * interrupt handler that pre-empts the normal world. The interrupt + * handler runs on core X. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PTA_NAME "rng.pta" + +#define THERMAL_SENSOR_BASE0 0x54190800 +#define THERMAL_SENSOR_OFFSET 0x80 +#define NUM_SENSORS 7 +#define NUM_SLOTS 13 + +#define TEMP_DATA_REG_OFFSET 0x34 + +#define ENTROPY_POOL_SIZE 4096 + +#define SENSOR_DATA_SIZE 128 +#define CONDITIONER_PAYLOAD (SENSOR_DATA_SIZE * NUM_SENSORS) + +/* + * Used in heatlh test to check if count of either bit flips 1-0 or 0-1 lies + * in 12.5% to 37.5% of 128 bytes raw data from particular sensor reading. In + * ideal scenario (1 bit of entropy per LSB) either of bit flips should be + * around 25%. + */ +#define MAX_BIT_FLIP_EDGE_COUNT 48 +#define MIN_BIT_FLIP_EDGE_COUNT 16 + +static uint8_t entropy_pool[ENTROPY_POOL_SIZE] = {0}; +static uint32_t entropy_size; + +static uint8_t sensors_data[NUM_SLOTS][SENSOR_DATA_SIZE] = {0}; +static uint8_t slot_idx; +static uint8_t sensor_idx; + +static uint32_t health_test_fail_cnt; +static uint32_t health_test_pass_cnt; + +static unsigned int entropy_lock = SPINLOCK_UNLOCK; + +static void pool_add_entropy(uint8_t *entropy, uint32_t size) +{ + uint32_t copy_size; + + if (entropy_size >= ENTROPY_POOL_SIZE) + return; + + if ((ENTROPY_POOL_SIZE - entropy_size) >= size) + copy_size = size; + else + copy_size = ENTROPY_POOL_SIZE - entropy_size; + + memcpy((entropy_pool + entropy_size), entropy, copy_size); + + entropy_size += copy_size; +} + +static void pool_get_entropy(uint8_t *buf, uint32_t size) +{ + uint32_t off; + + if (size > entropy_size) + return; + + off = entropy_size - size; + + memcpy(buf, &entropy_pool[off], size); + entropy_size -= size; +} + +static bool health_test(uint8_t sensor_id) +{ + bool result = true; + uint8_t bit_flip_falling = 0, bit_flip_rising = 0; + uint8_t i; + + for (i = 0; i < (SENSOR_DATA_SIZE - 1); i++) { + if ((sensors_data[sensor_id][i] ^ + sensors_data[sensor_id][i + 1]) & 0x1) { + bit_flip_falling += sensors_data[sensor_id][i] & 0x1; + bit_flip_rising += sensors_data[sensor_id][i + 1] & 0x1; + } + } + + if (bit_flip_falling > bit_flip_rising) { + if (bit_flip_rising < MIN_BIT_FLIP_EDGE_COUNT) + result = false; + if (bit_flip_falling > MAX_BIT_FLIP_EDGE_COUNT) + result = false; + } else { + if (bit_flip_falling < MIN_BIT_FLIP_EDGE_COUNT) + result = false; + if (bit_flip_rising > MAX_BIT_FLIP_EDGE_COUNT) + result = false; + } + + return result; +} + +static uint8_t pool_check_add_entropy(void) +{ + uint32_t i; + uint8_t entropy_sha512_256[TEE_SHA256_HASH_SIZE]; + uint8_t pool_status = 0; + TEE_Result res; + + for (i = 0; i < NUM_SENSORS; i++) { + /* Check if particular sensor data passes health test */ + if (health_test(slot_idx) == true) { + health_test_pass_cnt++; + slot_idx++; + } else { + health_test_fail_cnt++; + memmove(sensors_data[slot_idx], + sensors_data[slot_idx + 1], + (SENSOR_DATA_SIZE * (NUM_SENSORS - i - 1))); + } + } + + /* Check if sensors_data have enough pass data for entropy */ + if (slot_idx >= NUM_SENSORS) { + /* + * Use vetted conditioner SHA512/256 as per + * NIST.SP.800-90B to condition raw data from entropy + * source. + */ + res = hash_sha512_256_compute(entropy_sha512_256, + (uint8_t *)sensors_data, + CONDITIONER_PAYLOAD); + if (res == TEE_SUCCESS) + pool_add_entropy(entropy_sha512_256, + TEE_SHA256_HASH_SIZE); + + slot_idx -= NUM_SENSORS; + memmove(sensors_data[0], + sensors_data[NUM_SENSORS], + (SENSOR_DATA_SIZE * slot_idx)); + } + + if (entropy_size >= ENTROPY_POOL_SIZE) + pool_status = 1; + + return pool_status; +} + +void rng_collect_entropy(void) +{ + uint8_t i, pool_full = 0; + void *vaddr; + uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); + + cpu_spin_lock(&entropy_lock); + + for (i = 0; i < NUM_SENSORS; i++) { + vaddr = phys_to_virt_io(THERMAL_SENSOR_BASE0 + + (THERMAL_SENSOR_OFFSET * i) + + TEMP_DATA_REG_OFFSET); + sensors_data[slot_idx + i][sensor_idx] = + (uint8_t)read32((vaddr_t)vaddr); + } + + sensor_idx++; + + if (sensor_idx >= SENSOR_DATA_SIZE) { + pool_full = pool_check_add_entropy(); + sensor_idx = 0; + } + + if (pool_full) + generic_timer_stop(); + + cpu_spin_unlock(&entropy_lock); + thread_set_exceptions(exceptions); +} + +static TEE_Result rng_get_entropy(uint32_t types, + TEE_Param params[TEE_NUM_PARAMS]) +{ + uint8_t *e = NULL; + uint32_t pool_size = 0, rq_size = 0; + uint32_t exceptions; + TEE_Result res = TEE_SUCCESS; + + if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE)) { + EMSG("bad parameters types: 0x%" PRIx32, types); + return TEE_ERROR_BAD_PARAMETERS; + } + + rq_size = params[0].memref.size; + + if ((rq_size == 0) || (rq_size > ENTROPY_POOL_SIZE)) + return TEE_ERROR_NOT_SUPPORTED; + + e = (uint8_t *)params[0].memref.buffer; + if (!e) + return TEE_ERROR_BAD_PARAMETERS; + + exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); + cpu_spin_lock(&entropy_lock); + + /* + * Report health test failure to normal world in case fail count + * exceeds 1% of pass count. + */ + if (health_test_pass_cnt > 100) { + if (health_test_fail_cnt > (health_test_pass_cnt / 100)) { + res = TEE_ERROR_HEALTH_TEST_FAIL; + params[0].memref.size = 0; + health_test_pass_cnt = 0; + health_test_fail_cnt = 0; + goto exit; + } + } else { + if (health_test_fail_cnt > 1) { + res = TEE_ERROR_HEALTH_TEST_FAIL; + params[0].memref.size = 0; + health_test_pass_cnt = 0; + health_test_fail_cnt = 0; + goto exit; + } + } + + pool_size = entropy_size; + + if (pool_size < rq_size) { + params[0].memref.size = pool_size; + pool_get_entropy(e, pool_size); + } else { + params[0].memref.size = rq_size; + pool_get_entropy(e, rq_size); + } + +exit: + /* Enable timer FIQ to fetch entropy */ + generic_timer_start(); + + cpu_spin_unlock(&entropy_lock); + thread_set_exceptions(exceptions); + + return res; +} + +static TEE_Result invoke_command(void *pSessionContext __unused, + uint32_t nCommandID, uint32_t nParamTypes, + TEE_Param pParams[TEE_NUM_PARAMS]) +{ + FMSG("command entry point for pseudo-TA \"%s\"", PTA_NAME); + + switch (nCommandID) { + case PTA_CMD_GET_ENTROPY: + return rng_get_entropy(nParamTypes, pParams); + default: + break; + } + + return TEE_ERROR_NOT_IMPLEMENTED; +} + +pseudo_ta_register(.uuid = PTA_RNG_UUID, .name = PTA_NAME, + .flags = PTA_DEFAULT_FLAGS, + .invoke_command_entry_point = invoke_command); diff --git a/core/arch/arm/plat-synquacer/rng_pta.h b/core/arch/arm/plat-synquacer/rng_pta.h new file mode 100644 index 0000000..8ce2afa --- /dev/null +++ b/core/arch/arm/plat-synquacer/rng_pta.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2018, Linaro Limited + */ + +#ifndef __RNG_PTA_H +#define __RNG_PTA_H + +void rng_collect_entropy(void); + +#endif /* __RNG_PTA_H */ diff --git a/core/arch/arm/plat-synquacer/rng_pta_client.h b/core/arch/arm/plat-synquacer/rng_pta_client.h new file mode 100644 index 0000000..b7986d3 --- /dev/null +++ b/core/arch/arm/plat-synquacer/rng_pta_client.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2018, Linaro Limited + */ + +#ifndef __RNG_PTA_CLIENT_H +#define __RNG_PTA_CLIENT_H + +#define PTA_RNG_UUID { 0xab7a617c, 0xb8e7, 0x4d8f, \ + { 0x83, 0x01, 0xd0, 0x9b, 0x61, 0x03, 0x6b, 0x64 } } + +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 + +/* + * PTA_CMD_GET_ENTROPY - Get Entropy from RNG using Thermal Sensor + * + * 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 PTA_CMD_GET_ENTROPY 0x0 + +#endif /* __RNG_PTA_CLIENT_H */ diff --git a/core/arch/arm/plat-synquacer/sub.mk b/core/arch/arm/plat-synquacer/sub.mk index cfa1dc3..013e57d 100644 --- a/core/arch/arm/plat-synquacer/sub.mk +++ b/core/arch/arm/plat-synquacer/sub.mk @@ -1,3 +1,4 @@ global-incdirs-y += . srcs-y += main.c +srcs-y += rng_pta.c srcs-y += timer_fiq.c