From patchwork Tue Nov 20 06:42:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 151557 Delivered-To: patches@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp237517ljp; Mon, 19 Nov 2018 22:42:38 -0800 (PST) X-Received: by 2002:a62:1d14:: with SMTP id d20mr912091pfd.221.1542696157874; Mon, 19 Nov 2018 22:42:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542696157; cv=none; d=google.com; s=arc-20160816; b=RLp2FHMbNtFMR5uX/76DBxNkHSvTvG1K44v7wTctk6npV4LRMxleYBHSZYnHRbCl15 G016F5tpXCOCMV0rnUm76wroKIF1iVltU1GdWBHbKd7K+IL8RZK4/Qai1srsuYAjkBFI 6iZCjBk1vBBhRifYtfPMOyNu6rd1f3M9/w7sk/LoAiELMneDQEUGjX1kMLsq++2dnWV0 Zhdve8FR4xxzO5LifjOnG5Zhfq61DLNWiUKAjA6iXoU/YqOmfOBsgr7qrv6v31SCnFhn 3+Pp7sBIqubBeaYmGpF4Ke64kVbCyzlF+/hVHUx6gaO/XFVX1LvnmEwlAHpn6csGd7KL wmDw== 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=0VWay4NXm3P+TdsKGV3jEDn6Pm7/f3eazZO6aCrFbfo=; b=dzFIhvGipc+i8WnA8VYPbFYCO+TKuv8JRgdMpin7LLXzLrx0Alh+tG7xz4evZLdcMf 5qHbs9vvvbQyLfecfoLMe8CQOOKQFzrrE6QDrn48F55wv+IBIzQ0vVGWz9PaY7o5P8XJ x4WwWyz4MwT0aICSwNanuq/9rE86TKJLwcgOGYYzTyXlz0CqIBgJAnBef71TUNMs6mmr JO5iR4eYNHzin22DPVb8Qy2BwTyPZt17MxNyFBOT74Smd7yQs1h9tpT8G37b+S5fWadw nwtPmnbnHiVSqMgVe0Dqewi0ECU7+04+xYV8uFpxTAdXXHfvb0vS2Q19hBAzQf1qGZ0z j03w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JyJ1xK5a; 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 g61sor547036plb.5.2018.11.19.22.42.37 for (Google Transport Security); Mon, 19 Nov 2018 22:42:37 -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=JyJ1xK5a; 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=0VWay4NXm3P+TdsKGV3jEDn6Pm7/f3eazZO6aCrFbfo=; b=JyJ1xK5afFDd4YjglM5zcee8vt0LYbe5gL/eyWSR6Swgf31sYDxYps5wLhW4NAa3D0 uNs1SoIAXRuaBVpDBIY0WCjixBu6AWZusxB6C4jASjF3a1KiX2E5pWWkbroq3tiqp4Mb 20Rx/4Pz/czjapcG2gLMLw0VCu5MgZ09SDjYo= 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=0VWay4NXm3P+TdsKGV3jEDn6Pm7/f3eazZO6aCrFbfo=; b=XZRJtjoaKqJSkL+VJoy8artzp7C22ge3n7EEU0W6XX/m37rdewFGzgOylysIcNurlI yVvCXLVwLFOn44WknGEM2FCcoh07YdJLPNBIro4w7RKvrThEF/LfoqCei8EeNxdsvuCb 0tG3OtQpOF5oA96YPUqhDQYeFP/ywpWp+BZJ4DzUWDSi/NwCHde8cQMlUPxhJytvc8XA WEzV+C1O4XMOoGBaEHPO9L1TLQ++qm0091B0S9SLIvXje4iRPzw3k42UqP2t9KHuk/b8 2MVkcK0dhHlairiL2HqVy3J6ZcSToW9WFMa5qtcq3R/wtt37tNjxoCxuj4R1EcUIxYct BsJA== X-Gm-Message-State: AA+aEWZJ846GOzRjEMXUQ6qEbIJM55AogDbJpXkoRI4D4YOmVzhKnSX5 OJPCMoMnr8iDlYH721vr+r75I4o6SI1M/g== X-Google-Smtp-Source: AFSGD/XwxMJeAlIuNKi7JlXQLjrnZueoI/JalptgfRzItXb6PuNJlTYp8VUxfyv606HGm7SQRpptuA== X-Received: by 2002:a17:902:e002:: with SMTP id ca2mr956515plb.103.1542696157279; Mon, 19 Nov 2018 22:42:37 -0800 (PST) Return-Path: Received: from localhost.localdomain ([117.252.69.224]) by smtp.gmail.com with ESMTPSA id p83sm51534173pfi.85.2018.11.19.22.42.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 19 Nov 2018 22:42:36 -0800 (PST) From: Sumit Garg To: daniel.thompson@linaro.org Cc: patches@linaro.org, Sumit Garg Subject: [PATCH v3 1/3] libtomcrypt: Import SHA512/256 approved hash algorithm Date: Tue, 20 Nov 2018 12:12:14 +0530 Message-Id: <1542696136-5240-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 2fbb7a1..030f86c 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 0c35a34..2f849fd 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -2825,6 +2825,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 Tue Nov 20 06:42:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 151558 Delivered-To: patches@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp237555ljp; Mon, 19 Nov 2018 22:42:40 -0800 (PST) X-Received: by 2002:a62:5793:: with SMTP id i19mr950053pfj.49.1542696160684; Mon, 19 Nov 2018 22:42:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542696160; cv=none; d=google.com; s=arc-20160816; b=HWga5CdipIldYTbkUE7owFg8rNtuIevRzuzLldCNKNziwmHBZde2VnF43AkE6n7THg xEJC+sb+mMAv3nz7FV0v1QpfKhZ6xGWXDW9MmxG+YxPjmqE2na6THrZ5ctlWE0YI++UC jp+39rPwaHroLkEYF72Sf98AB6PDN3gziegXfoEFKy1PO6FLNFoedOuNm1I5E7XEEM1r w9zGUUj+m4AwFB067/o/FrBOQFVj3S6dfkeHBfCP23RVNmn5JyDsNe9dGdNnh0xG4Rud i+juKc9nLE0y6DtamMAUKCulf7CMRvZsCrOQrCTGiex1KCCgwd9Mm6unA9tJqi9Rpyj8 YlNA== 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=Xx2xszJZxCyI/9/nb2k+6U6ofOWCBfJybDLdeYmZJdI=; b=KmIxrzA9NtHILUL0VyC3fmIuW89v1C6TWnEEi1fGbIQXL3XyLi5F5CyUWTOD5sOKwM Y8zHDegtVxraSjv0cvr4rLYYLTG0rHtFQQnp9Y1AZULxhABgx2pYidUrOgBKudB6lIJL 1CuxD7XvBdL7Ou9gFU1uOZt724XO8l/rP8Rf+vcyFuAg8DGdVOMAwPiogiTyASRoEO51 QXWbyQ3ES/FOJyqyIiIVzlgWI3eVdJLQFcqwGI5k23nQ063/KKJqvvS47YfhW41ZFm3C AnBudQr/PDwXwNqEm2ocUK41CgiaF8E092zbYzKxWySZ/N3Qo91PLfJ1jPtqtYf2Oo7y IJTw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=G0QEzcJu; 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 d6sor4318697pfe.71.2018.11.19.22.42.40 for (Google Transport Security); Mon, 19 Nov 2018 22:42:40 -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=G0QEzcJu; 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=Xx2xszJZxCyI/9/nb2k+6U6ofOWCBfJybDLdeYmZJdI=; b=G0QEzcJuuVRNklfiLtfZUyrl/vVf98WkUn2R4g8GUhaHDDknxDTaIo4bYCybUd/gQu 0tfIpP3Jt59oBmCjXh4oh4/36SZY1TQpV5RSing8pfJe5Q0JxKRtA38YvvrNrRsw7Dob hi0Lvz9iQXbcmGHWNZRjeLjbw0sOnAyQXklWY= 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=Xx2xszJZxCyI/9/nb2k+6U6ofOWCBfJybDLdeYmZJdI=; b=YSZdYqMC3ykw49lHPseYs4sKc8sa9B9tn326UI9kUJARopxoEtYbyLbWqlNeFvPxup rFVa+Mlidod1+QdqB9alPOrMydgG+OFiGf3Lis5C1eWqCtKH3pmYLjAjS07DqvDZmMzm bBG/BnGd3Krg/Ax8+XMUzfKVuIxtYAkNP6NR7FHIfkowPruFX+UaZp7xTYU8yYFiNelA hnTp7M+PYhlOMaZHO5GobLbinrSpg1j9RQhsF50a3mujrDWDEwLwX02/SHwvWVTpweYQ v2MqrrJSzVNPX8i9lW+PPxyWEduNDOJeCGgaPHMVJFbxYY+jH1P7EK5+Pz6X4AgANTXG izgQ== X-Gm-Message-State: AGRZ1gJtr/qvvIOFfIykOnJN8dhEounRD73Car462oHtVm5A+2ySa95A CUxVcxWkpmqozMRlocCjG7uY0U2f X-Google-Smtp-Source: AJdET5eq2TtWigKSmX+9Kc6wpSsGRn1KB1IH3NU8ecYlhxNuGdKAwnucfps+O7Z85JvI6x09dEONzw== X-Received: by 2002:a62:9a09:: with SMTP id o9-v6mr945952pfe.229.1542696160095; Mon, 19 Nov 2018 22:42:40 -0800 (PST) Return-Path: Received: from localhost.localdomain ([117.252.69.224]) by smtp.gmail.com with ESMTPSA id p83sm51534173pfi.85.2018.11.19.22.42.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 19 Nov 2018 22:42:39 -0800 (PST) From: Sumit Garg To: daniel.thompson@linaro.org Cc: patches@linaro.org, Sumit Garg Subject: [PATCH v3 2/3] synquacer: Add secure timer interrupt framework Date: Tue, 20 Nov 2018 12:12:15 +0530 Message-Id: <1542696136-5240-2-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1542696136-5240-1-git-send-email-sumit.garg@linaro.org> References: <1542696136-5240-1-git-send-email-sumit.garg@linaro.org> 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 | 43 ++++++++++++++++++++++++++ core/arch/arm/plat-synquacer/timer_fiq.h | 15 +++++++++ 6 files changed, 90 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..e8395d9 --- /dev/null +++ b/core/arch/arm/plat-synquacer/timer_fiq.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2018, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include + +bool timer_fiq_running = false; + +void generic_timer_start(void) +{ + uint64_t cval; + uint32_t ctl = 1; + + /* 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(ctl); +} + +void generic_timer_stop(void) +{ + /* Disable the timer */ + write_cntps_ctl(0); +} + +void generic_timer_handler(void) +{ + /* Ensure that the timer did assert the interrupt */ + assert((read_cntps_ctl() >> 2)); + + /* Disable the timer and reprogram it */ + write_cntps_ctl(0); + generic_timer_start(); +} 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..ebbe5ba --- /dev/null +++ b/core/arch/arm/plat-synquacer/timer_fiq.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2018, Linaro Limited + */ + +#ifndef __TIMER_FIQ_H +#define __TIMER_FIQ_H + +extern bool timer_fiq_running; + +void generic_timer_start(void); +void generic_timer_stop(void); +void generic_timer_handler(void); + +#endif /* __TIMER_FIQ_H */ From patchwork Tue Nov 20 06:42:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 151559 Delivered-To: patches@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp237593ljp; Mon, 19 Nov 2018 22:42:44 -0800 (PST) X-Received: by 2002:a65:5c4b:: with SMTP id v11mr787567pgr.333.1542696164139; Mon, 19 Nov 2018 22:42:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542696164; cv=none; d=google.com; s=arc-20160816; b=PRam3Oqgyr5ceGf2ucGQLohyS414mSgvcmHTpksVx2SUwFaXBgcS4Lm0fJSfUFJV0d VWJwdCT1emElNWL7CUEUMGHAy6E/Vzok3OPvHYaFjNCpnS4bOFd0MoxgrfGUh0zhqbiU Z7jghEb6fI5VITC0dKBTSVuZ4YVjz/5uWHRpc4NRA8aBelqHqqzm2jCuuMdikHSS6edP GzT8qeKINAbZ/zYgO/IWW/CKaMPnNdbfA0RHCHHwSDZ48eH9XBOf2ncnBOF7b1t7M/FF 5bNOhVEcs3p6Q9UPD3VZgOnXEXmgamFrVv5axHaytnbDI4K/XotAUf6ARs5oNdRyWfBC Vcww== 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=4auhsqQtwbHSJ9K728CEGtEpOiBaawV/fzOJeqkj2tI=; b=gaW12oDI+I2IbLr8vUSPXuwuWeR9aQcZ62e7RfyTs/JM0E+27Qr0KG0YbODWnGljrx RBmCJD5dBbUFzB/tkjeqzTd6Nb+ec4Zu/WPd7Z6AMzcNdooI3em9qb6HClfpuCscjOIq NKfr9jDN3a7qlpVAAHt4W/2VeyQcqabf0NW/s0iBi4D1dGiJ0zSX6EAo302ZjUUnmUFD GgswlL3Iq8WoFwc8b7cg3qDSY0ACD+OCzyfiq1OpKh+Q8mu71EImsLc7XXIJ/EhYzYJI PrkWzzW0LJ9O2VAIHC1sNFs/HXC2tUPELVuVOwB3K9arxCAyL2nf46iaVc8+mYq+x9me IzsA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Rkvu6ZPT; 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 l14sor13759579pfj.27.2018.11.19.22.42.43 for (Google Transport Security); Mon, 19 Nov 2018 22:42:44 -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=Rkvu6ZPT; 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=4auhsqQtwbHSJ9K728CEGtEpOiBaawV/fzOJeqkj2tI=; b=Rkvu6ZPTOGNTlvQ0wJrEw1fVWaPdjY6xbG6LP0b/8ZXSdO8KGbIHP4omJ7/YZTRjdX 8t/DCLZUwver2ZmWfjmGWBZjwIkKzrIeGjAHNVabzwAW1u6p7uXd31IE91xH7nQo4Gxk lXEEagGHuqrQ6YrZq+PKrHYtPOCO2sbqzCqdM= 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=4auhsqQtwbHSJ9K728CEGtEpOiBaawV/fzOJeqkj2tI=; b=D7VfkZ+N/4yPx8AzjlrVDuz1JXm0Q4b0+BWvHmRs7o+HkiRDBand+TRpC5X/m0hwyp k2LOFTMfC413NKAGJtSlhkHgd7vkrylIaklhsPwcLvPD6K4pE7Z22u8LQ6Br7QZxc56Q F4DO7v1nbv1x32nfTX7gINvMKtdLESzKWKJcZs+r1P+SnUcfUag2ZZEnqLcbS5UncxwY hSIbF7HAd2WtGDYNvji3utT5fF5xrd8/vfwWc6q3tNQbWtICVRAFhk6biESXl+tqrJRa YHoOdKfkYqnan6iTVHzjUHU8nOaPnMyguoBA2mRxF8vN3ueQlEx+CwfDeFCrkp6e58WV wfRw== X-Gm-Message-State: AGRZ1gJA88bIkwLsOt8EsSpN9mOf0vkRfMTN/f8B34+PlBTwqRwhbZS6 NxQVHu7eMszdLiYH2YODgGdeg0+N X-Google-Smtp-Source: AJdET5fdLSKFwtZAD2ddyU+VysBm9dt3NpGbr5l8T5EOuYLtXFNHg/rNPQ62sUZCYsIQ+Nuu5a9rTA== X-Received: by 2002:aa7:8354:: with SMTP id z20mr926412pfm.81.1542696163438; Mon, 19 Nov 2018 22:42:43 -0800 (PST) Return-Path: Received: from localhost.localdomain ([117.252.69.224]) by smtp.gmail.com with ESMTPSA id p83sm51534173pfi.85.2018.11.19.22.42.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 19 Nov 2018 22:42:42 -0800 (PST) From: Sumit Garg To: daniel.thompson@linaro.org Cc: patches@linaro.org, Sumit Garg Subject: [PATCH v3 3/3] synquacer: Add RNG pseudo TA Date: Tue, 20 Nov 2018 12:12:16 +0530 Message-Id: <1542696136-5240-3-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1542696136-5240-1-git-send-email-sumit.garg@linaro.org> References: <1542696136-5240-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 | 9 + core/arch/arm/plat-synquacer/platform_config.h | 1 + core/arch/arm/plat-synquacer/rng_pta.c | 363 +++++++++++++++++++++++++ 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, 415 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..c91ba9b 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,10 @@ 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(); + timer_fiq_running = true; + 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..f9a40aa --- /dev/null +++ b/core/arch/arm/plat-synquacer/rng_pta.c @@ -0,0 +1,363 @@ +// 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 is an effort to provide 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 + * ========== + * + * Here we have assumed a conservative entropy estimate as 4 bits per 7 + * 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. + * + * 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. + * + * Limitation + * ========== + * + * Output rate is limited to approx. 128 bytes per second. + * + */ + +#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_OF_SENSORS 7 + +#define TEMP_DATA_REG_OFFSET 0x34 + +#define ENTROPY_POOL_SIZE 4096 + +#define SENSOR_DATA_SIZE 128 + +/* + * As per NIST.SP.800-90B, to get full entropy from vetted conditioner, we need + * to supply double of input entropy. So with full entropy (8 bits per byte) we + * will get yield as one byte of output data for every 28 sensor readings. + * For 32 bytes of SHA512/256 output data, we need to supply 896 bytes of raw + * input data. + */ +#define CONDITIONER_PAYLOAD (SENSOR_DATA_SIZE * NUM_OF_SENSORS) + +/* + * Used in heatlh test to check if count of bit flips 1-0 or 0-1 lies in 12.5% + * to 50.0% of 128 bytes raw data from particular sensor reading. In ideal + * scenario either of bit flips should be around 25%. + */ +#define MAX_BIT_FLIP_EDGE_COUNT 64 +#define MIN_BIT_FLIP_EDGE_COUNT 16 + +static uint8_t entropy_pool[ENTROPY_POOL_SIZE] = {0}; +static uint32_t entropy_size; + +/* Current sensor data */ +static uint8_t sensor_data[NUM_OF_SENSORS][SENSOR_DATA_SIZE] = {0}; +static uint8_t sensor_idx; + +/* Sensor data that passed health test */ +static uint8_t sensor_data_pass[NUM_OF_SENSORS][SENSOR_DATA_SIZE] = {0}; +static uint8_t num_sensors_pass; + +static uint8_t rest_data_pass[NUM_OF_SENSORS][SENSOR_DATA_SIZE] = {0}; + +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 ((sensor_data[sensor_id][i] ^ + sensor_data[sensor_id][i + 1]) & 0x1) { + bit_flip_falling += sensor_data[sensor_id][i] & 0x1; + bit_flip_rising += sensor_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 void pool_check_add_entropy(void) +{ + uint32_t i; + uint8_t entropy_sha512_256[TEE_SHA256_HASH_SIZE]; + uint8_t rest_sensors_pass = 0; + TEE_Result res; + + for (i = 0; i < NUM_OF_SENSORS; i++) { + /* Check if particular sensor data passes health test */ + if (health_test(i) == true) { + health_test_pass_cnt++; + if (num_sensors_pass < NUM_OF_SENSORS) { + memcpy(sensor_data_pass[num_sensors_pass], + sensor_data[i], SENSOR_DATA_SIZE); + num_sensors_pass++; + } else { + memcpy(rest_data_pass[rest_sensors_pass], + sensor_data[i], SENSOR_DATA_SIZE); + rest_sensors_pass++; + } + } else { + health_test_fail_cnt++; + } + } + + /* Check if sensor_data_pass is full */ + if (num_sensors_pass == NUM_OF_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 *)sensor_data_pass, + CONDITIONER_PAYLOAD); + if (res == TEE_SUCCESS) + pool_add_entropy(entropy_sha512_256, + TEE_SHA256_HASH_SIZE); + } + + if (rest_sensors_pass) + memcpy((uint8_t *)sensor_data_pass, (uint8_t *)rest_data_pass, + (rest_sensors_pass * SENSOR_DATA_SIZE)); + + num_sensors_pass = rest_sensors_pass; +} + +void rng_collect_entropy(void) +{ + uint8_t i; + void *vaddr; + uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); + + cpu_spin_lock(&entropy_lock); + + for (i = 0; i < NUM_OF_SENSORS; i++) { + vaddr = phys_to_virt_io(THERMAL_SENSOR_BASE0 + + (THERMAL_SENSOR_OFFSET * i) + + TEMP_DATA_REG_OFFSET); + sensor_data[i][sensor_idx] = (uint8_t)read32((vaddr_t)vaddr); + } + + sensor_idx++; + + if (sensor_idx >= SENSOR_DATA_SIZE) { + pool_check_add_entropy(); + sensor_idx = 0; + } + + if (entropy_size >= ENTROPY_POOL_SIZE) { + generic_timer_stop(); + timer_fiq_running = false; + } + + 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: + if (timer_fiq_running == false) { + /* Enable timer FIQ to fetch entropy */ + generic_timer_start(); + timer_fiq_running = true; + } + + cpu_spin_unlock(&entropy_lock); + thread_set_exceptions(exceptions); + + return res; +} + +/* + * Trusted Application Entry Points + */ +static TEE_Result open_session(uint32_t param_types __unused, + TEE_Param params[TEE_NUM_PARAMS] __unused, + void **session_context __unused) +{ + DMSG("open entry point for pseudo-TA \"%s\"", PTA_NAME); + return TEE_SUCCESS; +} + +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, + .open_session_entry_point = open_session, + .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