From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from EUR01-DB5-obe.outbound.protection.outlook.com (EUR01-DB5-obe.outbound.protection.outlook.com [40.107.15.51]) by mx.groups.io with SMTP id smtpd.web09.14615.1633017217059613269 for ; Thu, 30 Sep 2021 08:53:37 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@armh.onmicrosoft.com header.s=selector2-armh-onmicrosoft-com header.b=kiZivFmU; spf=pass (domain: arm.com, ip: 40.107.15.51, mailfrom: sami.mujawar@arm.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=058d/XHz/h3aTreXhyeBmpkCO1LUin0mjAmlv4r4qRU=; b=kiZivFmUkQLt3T/cMuiKAHu2ey+MwXuQK4/vnk2rlH0x5zu9CwehagFLF5j027xe9A8nklKP61VulDxnQZfLn0NzWJzZVVzg0jQcn/0gFvQS4U6+U77IpO2zSKYVzp0zzkIjNgNOK/fHI6zAtQnwk1pwbs8dTW7NN24bxj2N1Wk= Received: from DB8PR06CA0057.eurprd06.prod.outlook.com (2603:10a6:10:120::31) by PA4PR08MB5936.eurprd08.prod.outlook.com (2603:10a6:102:f1::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4566.14; Thu, 30 Sep 2021 15:53:33 +0000 Received: from DB5EUR03FT024.eop-EUR03.prod.protection.outlook.com (2603:10a6:10:120:cafe::ff) by DB8PR06CA0057.outlook.office365.com (2603:10a6:10:120::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4566.14 via Frontend Transport; Thu, 30 Sep 2021 15:53:33 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; edk2.groups.io; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;edk2.groups.io; dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by DB5EUR03FT024.mail.protection.outlook.com (10.152.20.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4566.14 via Frontend Transport; Thu, 30 Sep 2021 15:53:33 +0000 Received: ("Tessian outbound 71ebfb754289:v103"); Thu, 30 Sep 2021 15:53:33 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 94b32b2725f26c7f X-CR-MTA-TID: 64aa7808 Received: from 1985e89e2a7c.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 08279689-DE73-4F5A-96D7-33BBAEEE193F.1; Thu, 30 Sep 2021 15:40:53 +0000 Received: from EUR02-VE1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 1985e89e2a7c.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Thu, 30 Sep 2021 15:40:53 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OMDUlqnmV/lJ0aT354pwjSwfSUyRVSGQ0rPJSegHM8F0+vNFlMtvLpBvAvk4IGdhhRWgoeRwnj0rp2jZzSadUKyXaTc0UjSkaF/6JCb07zYZvcT7IDWlfiG8eYk/v8IMD2rc0l91sOSKHhvD3/eqp4knI5B01jquo60JZj0cGZf6PDISruHRsFYb75BUX2mJ7xx5ziiZ1Gp8PyTTmCXW10KewsdRLUINe2sfc9YD5sjUiXne9t1/MnJ4i/8QMnzioaNz2s9llmQs5thfNIJo9ceedBFgRi8pLXPNZGAqV/eNTFnhq9x3a3lRrA1oFkluRUvMfTnfr1miiwU0MririQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=058d/XHz/h3aTreXhyeBmpkCO1LUin0mjAmlv4r4qRU=; b=B/3FV8hvcGBBg60lVtNmfpz8ugX/0gpzJ5pXusPmo30n3LaamZqhKlA1uyhnFtFjfwrnElI5CJKu+SK0um7swQSf1LgOOn0NwkR5F3pFYfpCIWPRQ0/YyLOL++8TdssWviWMM4+r2Imte/CnPuWySj3z1vjam/JRtRJDzj3sdKNyj58gGsBsMPtB/OOXjBkQfwkVUbJXaNiiylFLk9DMRZ7YXG1HLtO2DFBYr7w1drFo7QS4Scra5fYbRiVloiHagZAPna1roRKEYvnIxKaeHQ2elzQkzk62ywYi8QWGu8VVW2rxpw+wDQq6gd5H42xWTZbdxBlHOmsQKn3bZ5hz3w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 40.67.248.234) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=058d/XHz/h3aTreXhyeBmpkCO1LUin0mjAmlv4r4qRU=; b=kiZivFmUkQLt3T/cMuiKAHu2ey+MwXuQK4/vnk2rlH0x5zu9CwehagFLF5j027xe9A8nklKP61VulDxnQZfLn0NzWJzZVVzg0jQcn/0gFvQS4U6+U77IpO2zSKYVzp0zzkIjNgNOK/fHI6zAtQnwk1pwbs8dTW7NN24bxj2N1Wk= Received: from DB6PR07CA0084.eurprd07.prod.outlook.com (2603:10a6:6:2b::22) by AM6PR08MB3173.eurprd08.prod.outlook.com (2603:10a6:209:4c::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4544.15; Thu, 30 Sep 2021 15:40:50 +0000 Received: from DB5EUR03FT050.eop-EUR03.prod.protection.outlook.com (2603:10a6:6:2b:cafe::eb) by DB6PR07CA0084.outlook.office365.com (2603:10a6:6:2b::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.7 via Frontend Transport; Thu, 30 Sep 2021 15:40:50 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 40.67.248.234) smtp.mailfrom=arm.com; edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 40.67.248.234 as permitted sender) receiver=protection.outlook.com; client-ip=40.67.248.234; helo=nebula.arm.com; Received: from nebula.arm.com (40.67.248.234) by DB5EUR03FT050.mail.protection.outlook.com (10.152.21.128) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.4566.14 via Frontend Transport; Thu, 30 Sep 2021 15:40:50 +0000 Received: from AZ-NEU-EX01.Emea.Arm.com (10.251.26.4) by AZ-NEU-EX04.Arm.com (10.251.24.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.2308.14; Thu, 30 Sep 2021 15:40:48 +0000 Received: from AZ-NEU-EX03.Arm.com (10.251.24.31) by AZ-NEU-EX01.Emea.Arm.com (10.251.26.4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2308.14; Thu, 30 Sep 2021 15:40:43 +0000 Received: from E114225.Arm.com (10.1.196.43) by mail.arm.com (10.251.24.31) with Microsoft SMTP Server id 15.1.2308.14 via Frontend Transport; Thu, 30 Sep 2021 15:40:47 +0000 From: "Sami Mujawar" To: CC: Sami Mujawar , , , , , , , , , , , , , Subject: [PATCH v1 3/9] ArmPkg: Add Arm Firmware TRNG library Date: Thu, 30 Sep 2021 16:40:38 +0100 Message-ID: <20210930154044.37336-4-sami.mujawar@arm.com> X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: <20210930154044.37336-1-sami.mujawar@arm.com> References: <20210930154044.37336-1-sami.mujawar@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 1 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: cc747753-879d-4759-615f-08d9842a74f7 X-MS-TrafficTypeDiagnostic: AM6PR08MB3173:|PA4PR08MB5936: X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Oob-TLC-OOBClassifiers: OLM:1303;OLM:1303; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: a9a8aJ0zyzb1iGF8Pza0WJc3AWc3sULqpxGfe5RSpHBrP4R76nYfa7jZnL+bo6kcp6UMpLSgMEn0/m5awlgpsXs9MLvhmpcpRvFWwqQ+twXa4d7qV/1di8pc+7sfjzi5K6C3QiXCk74rbYIKEKUCc6qsqqn2NXI5x6SLNY1XP/2ez+cp0JWuCUcLGi9O5hABi3Tte1V7gA3/yzIHreET9NKkyQnQWZuhtnS+VeAd6i6B1fbLbrnBnmv0OJ6x6W7UjwE5ee8JZfekisuqGCDMWMgENap0nO6huP5Nd9I0enoIxrRj3garOZ2si4CoWwdMmnIfnHUy9ztp0DMRsk7Ii5oSed9rsU/y+CMhL/jxyrSw2KSX019sD1bIpKDv5nn/I2qY2OejJTuJkniolCPO+SCAt+9iU8GwGQ46/IJoDqOxBPzEI8uXHiL48o+7IlYbj3a1kzXZwrVusS1EXkQ52mOl73Dek8Bx61zHR7f2BfUfKxKMQCF1btGXLSWShfj96QaYZhxat9iENQSW+LNnRZAG39V7lqVkvce35Lrgocfay4zBFE/Ul/sL4YKyYhrWLLaTxePAzRbXBmmDrtRkZD3P4IRZju80uJB8zDnLgeTce7owtupkqPAUzD/GbnMsY/u7aw8xyurg/grVjyNYlXjGKfYwB7Iq5C8W59RpXCrqok58CgdnqOqFkt/t//i50UEkoUAyC67qAM9yGivRuGj30BSaO/gxJ7XkrGHtTE9KBoM2WVSejrB8e7foHFhYFxmjjV+dp9fZ0ICar09y3FIsJ+pEhIC1SndfAqA6KqCnbzQ+WLMYv+JlBmDuCepqwFvwfJvZbU+uvc3O8VhXTk1ikmyET/l3TuKo0lldvo0= X-Forefront-Antispam-Report-Untrusted: CIP:40.67.248.234;CTRY:IE;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:nebula.arm.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(4636009)(36840700001)(46966006)(316002)(30864003)(1076003)(86362001)(7416002)(356005)(8676002)(508600001)(70206006)(81166007)(54906003)(8936002)(70586007)(82310400003)(44832011)(6666004)(36756003)(336012)(83380400001)(26005)(5660300002)(426003)(36860700001)(6916009)(2616005)(47076005)(4326008)(7696005)(2906002)(186003)(36900700001);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR08MB3173 Return-Path: Sami.Mujawar@arm.com X-MS-Exchange-Transport-CrossTenantHeadersStripped: DB5EUR03FT024.eop-EUR03.prod.protection.outlook.com X-MS-Office365-Filtering-Correlation-Id-Prvs: 5f37570f-6b28-4763-3745-08d98428ae40 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: fIFWSH4BWmda1Xjo/cRnueTg7QxPH4QiyifPxcvNjGSOuz1zrsgHCigLiaWbH50Kc79WcCyyqdU5Hptl/UdwQWzYaZVBRK4EvcyDvrUxah9rFNhTss0ImF/GlE4ZI7PTR/NV2O9yp0+4vKTcD3XMVHfwJUMPXtIGVM/+KTn9MUdQacTxU+dl4N+SzurAA/AfBDwt2bjqQZy/zp6vC6QYNPO029SSWfvGdlne33YayU0ULBZllBN2QvzILpWo2t6veMEeLCK4ls6MOWFD5awJwQyQ40HcvQET/phYAu2hh5Sj6duy1zHsnJSmXW9qpexwinehawWvmim6325oQWcI12y1C0dJIQjJcYgi6kCxMZFS51qTg1xZvqk1b35aziyAm8KLLH9HKnpYBcug4q3NF9CTt/6Yl17wsDQVQYmdx99Om365iJf6JE+Y27D9JJBOSLv0eIrgPhR8lZqZ6x2e8tqNjZJbDDvDCx94rrhL2F//TbcwvBgK4JezmpQeAMFJow8FvnILFrP/EsdjRgMbCSsgGtK3wkNPLec6sx0wVsX+W/8jl0NkcXeTbYi+GdTe5ABoT7nEOdVZEW4zcgkxa37w+P+ywvJMDQmpL6oJoUymKYbD/8Ng+vCZdJR4mneTp7H1qrHIc1q3op/VHs9+0/wstS21jjZ2nqHscyrK0EC8gJzUHRkBFut3jLLGFnQhCxMd7oCGn9Bm/nqBLJF85F7dGLA4a9fuesDvIf7QYEemaBKvf5sF3patzFPhKXvOFQ5qun9e75U5iErH7bncbsDISIhQU2Ewv2qv+o4WE5/0THV1WnK/RNGeN8d2aSqf X-Forefront-Antispam-Report: CIP:63.35.35.123;CTRY:IE;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:64aa7808-outbound-1.mta.getcheckrecipient.com;PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com;CAT:NONE;SFS:(4636009)(46966006)(36840700001)(7696005)(2616005)(1076003)(6916009)(426003)(83380400001)(508600001)(36756003)(47076005)(186003)(86362001)(36860700001)(82310400003)(54906003)(44832011)(5660300002)(4326008)(70206006)(26005)(336012)(6666004)(30864003)(81166007)(2906002)(8936002)(70586007)(8676002)(316002);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Sep 2021 15:53:33.5408 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: cc747753-879d-4759-615f-08d9842a74f7 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d;Ip=[63.35.35.123];Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: DB5EUR03FT024.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PA4PR08MB5936 Content-Type: text/plain Bugzilla: 3668 (https://bugzilla.tianocore.org/show_bug.cgi?id=3668) The Arm True Random Number Generator Firmware, Interface 1.0, Platform Design Document (https://developer.arm.com/documentation/den0098/latest/) defines an interface between an Operating System (OS) executing at EL1 and Firmware (FW) exposing a conditioned entropy source that is provided by a TRNG back end. The conditioned entropy, that is provided by the TRNG FW interface, is commonly used to seed deterministic random number generators. This patch adds a TrngLib library that implements the Arm TRNG firmware interface. Signed-off-by: Sami Mujawar --- ArmPkg/ArmPkg.dsc | 1 + ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h | 64 +++ ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c | 483 ++++++++++++++++++++ ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf | 34 ++ 4 files changed, 582 insertions(+) diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 8abe3713c829cbe81842c52de6982e7cbef5c323..2b78ee197d4c5fa30726d2cf3da11a7a4175a9b3 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -154,6 +154,7 @@ [Components.common] ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf + ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf diff --git a/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h new file mode 100644 index 0000000000000000000000000000000000000000..42236e743d972df0df205b1565496afeff5785f3 --- /dev/null +++ b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h @@ -0,0 +1,64 @@ +/** @file + Arm Firmware TRNG definitions. + + Copyright (c) 2021, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] Arm True Random Number Generator Firmware, Interface 1.0, + Platform Design Document. + (https://developer.arm.com/documentation/den0098/latest/) + + @par Glossary: + - TRNG - True Random Number Generator + - FID - Function ID +**/ + +#ifndef ARM_FW_TRNG_DEFS_H_ +#define ARM_FW_TRNG_DEFS_H_ + +// Firmware TRNG interface Function IDs +#define FID_TRNG_VERSION 0x84000050 +#define FID_TRNG_FEATURES 0x84000051 +#define FID_TRNG_GET_UUID 0x84000052 +#define FID_TRNG_RND_AARCH32 0x84000053 +#define FID_TRNG_RND_AARCH64 0xC4000053 + +// Firmware TRNG revision mask and shift +#define TRNG_REV_MAJOR_MASK 0x7FFF +#define TRNG_REV_MINOR_MASK 0xFFFF +#define TRNG_REV_MAJOR_SHIFT 16 +#define TRNG_REV_MINOR_SHIFT 0 + +// Firmware TRNG status codes +#define TRNG_STATUS_SUCCESS (INT32)(0) +#define TRNG_NOT_SUPPORTED (INT32)(-1) +#define TRNG_INVALID_PARAMETER (INT32)(-2) +#define TRNG_NO_ENTROPY (INT32)(-3) + +#if defined (MDE_CPU_ARM) +/** FID to use on AArch32 platform to request entropy. +*/ +#define FID_TRNG_RND FID_TRNG_RND_AARCH32 + +/** Maximum bits of entropy supported on AArch32. +*/ +#define MAX_ENTROPY_BITS 96 +#elif defined (MDE_CPU_AARCH64) +/** FID to use on AArch64 platform to request entropy. +*/ +#define FID_TRNG_RND FID_TRNG_RND_AARCH64 + +/** Maximum bits of entropy supported on AArch64. +*/ +#define MAX_ENTROPY_BITS 192 +#else +#error "Firmware TRNG not supported. Unknown chipset." +#endif + +/** Typedef for SMC or HVC arguments. +*/ +typedef ARM_SMC_ARGS ARM_MONITOR_ARGS; + +#endif // ARM_FW_TRNG_DEFS_H_ diff --git a/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c new file mode 100644 index 0000000000000000000000000000000000000000..442072fc088d4d53e71869284d0ebb1c6de285b5 --- /dev/null +++ b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c @@ -0,0 +1,483 @@ +/** @file + Arm Firmware TRNG interface library. + + Copyright (c) 2021, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] Arm True Random Number Generator Firmware, Interface 1.0, + Platform Design Document. + (https://developer.arm.com/documentation/den0098/latest/) + - [2] NIST Special Publication 800-90A Revision 1, June 2015, Recommendation + for Random Number Generation Using Deterministic Random Bit Generators. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final) + - [3] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [4] (Second Draft) NIST Special Publication 800-90C, Recommendation for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + + @par Glossary: + - TRNG - True Random Number Generator + - FID - Function ID +**/ + +#include +#include +#include +#include +#include +#include + +#include "ArmFwTrngDefs.h" + +/** Convert TRNG status codes to EFI status codes. + + @param [in] TrngStatus TRNG status code. + + @retval EFI_SUCCESS Success. + @retval EFI_UNSUPPORTED Function not implemented. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_READY No Entropy available. +**/ +STATIC +EFI_STATUS +TrngStatusToEfiStatus ( + IN INT32 TrngStatus + ) +{ + switch (TrngStatus) { + case TRNG_NOT_SUPPORTED: + return EFI_UNSUPPORTED; + + case TRNG_INVALID_PARAMETER: + return EFI_INVALID_PARAMETER; + + case TRNG_NO_ENTROPY: + return EFI_NOT_READY; + + case TRNG_STATUS_SUCCESS: + default: + return EFI_SUCCESS; + } +} + +/** Invoke the monitor call using the appropriate conduit. + If PcdMonitorConduitHvc is TRUE use the HVC conduit else use SMC conduit. + + @param [in, out] Args Arguments passed to and returned from the monitor. + + @return VOID +**/ +STATIC +VOID +ArmCallMonitor ( + IN OUT ARM_MONITOR_ARGS *Args + ) +{ + if (FeaturePcdGet (PcdMonitorConduitHvc)) { + ArmCallHvc ((ARM_HVC_ARGS*)Args); + } else { + ArmCallSmc ((ARM_SMC_ARGS*)Args); + } +} + +/** Get the version of the TRNG backend. + + A TRNG may be implemented by the system firmware, in which case this + function shall return the version of the TRNG backend. + The implementation must return NOT_SUPPORTED if a Back end is not present. + + @param [out] MajorRevision Major revision. + @param [out] MinorRevision Minor revision. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_UNSUPPORTED Backend not present. +**/ +EFI_STATUS +EFIAPI +GetTrngVersion ( + OUT UINT16 * CONST MajorRevision, + OUT UINT16 * CONST MinorRevision + ) +{ + EFI_STATUS Status; + ARM_MONITOR_ARGS Parameters; + INT32 Revision; + + if ((MajorRevision == NULL) || (MinorRevision == NULL)) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (&Parameters, sizeof (Parameters)); + + /* + Cf. [1], 2.1 TRNG_VERSION + Function ID (W0) 0x8400_0050 + Parameters + W1-W7 Reserved (MBZ) + Returns + Success (W0 > 0) W0[31] MBZ + W0[30:16] Major revision + W0[15:0] Minor revision + W1 - W3 Reserved (MBZ) + Error (W0 < 0) + NOT_SUPPORTED Function not implemented + */ + Parameters.Arg0 = FID_TRNG_VERSION; + ArmCallMonitor (&Parameters); + + Revision = (INT32)Parameters.Arg0; + // Convert status codes to EFI status codes. + Status = TrngStatusToEfiStatus (Revision); + if (EFI_ERROR (Status)) { + return Status; + } + + *MinorRevision = (Revision & TRNG_REV_MINOR_MASK); + *MajorRevision = ((Revision >> TRNG_REV_MAJOR_SHIFT) & TRNG_REV_MAJOR_MASK); + return EFI_SUCCESS; +} + +#ifndef MDEPKG_NDEBUG +/** Get the features supported by the TRNG backend. + + The caller can determine if functions defined in the TRNG ABI are + present in the ABI implementation. + + @param [in] FunctionId Function Id. + @param [out] Capability Function specific capability if present + otherwise Zero is returned. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_UNSUPPORTED Function not implemented. +**/ +STATIC +EFI_STATUS +EFIAPI +GetTrngFeatures ( + IN CONST UINT32 FunctionId, + OUT UINT32 * CONST Capability OPTIONAL + ) +{ + ARM_MONITOR_ARGS Parameters; + + ZeroMem (&Parameters, sizeof (Parameters)); + + /* + Cf. [1], Section 2.2 TRNG_FEATURES + Function ID (W0) 0x8400_0051 + Parameters + W1 trng_func_id + W2-W7 Reserved (MBZ) + Returns + Success (W0 >= 0) + SUCCESS Function is implemented. + > 0 Function is implemented and + has specific capabilities, + see function definition. + Error (W0 < 0) + NOT_SUPPORTED Function with FID=trng_func_id + is not implemented + */ + Parameters.Arg0 = FID_TRNG_FEATURES; + Parameters.Arg1 = FunctionId; + ArmCallMonitor (&Parameters); + if (Parameters.Arg0 < TRNG_STATUS_SUCCESS) { + return EFI_UNSUPPORTED; + } + + if (Capability != NULL) { + *Capability = Parameters.Arg0; + } + + return EFI_SUCCESS; +} +#endif //MDEPKG_NDEBUG + +/** Get the UUID of the TRNG backend. + + A TRNG may be implemented by the system firmware, in which case this + function shall return the UUID of the TRNG backend. + Returning the TRNG UUID is optional and if not implemented, EFI_UNSUPPORTED + shall be returned. + + Note: The caller must not rely on the returned UUID as a trustworthy TRNG + Back end identity + + @param [out] Guid UUID of the TRNG backend. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_UNSUPPORTED Function not implemented. +**/ +EFI_STATUS +EFIAPI +GetTrngUuid ( + OUT GUID * CONST Guid + ) +{ + EFI_STATUS Status; + ARM_MONITOR_ARGS Parameters; + + ZeroMem (&Parameters, sizeof (Parameters)); + + /* + Cf. [1], Section 2.3 TRNG_GET_UUID + Function ID (W0) 0x8400_0052 + Parameters + W1-W7 Reserved (MBZ) + Returns + Success (W0 != -1) + W0 UUID[31:0] + W1 UUID[63:32] + W2 UUID[95:64] + W3 UUID[127:96] + Error (W0 = -1) + W0 NOT_SUPPORTED + */ + Parameters.Arg0 = FID_TRNG_GET_UUID; + ArmCallMonitor (&Parameters); + + // Convert status codes to EFI status codes. + Status = TrngStatusToEfiStatus ((INT32)Parameters.Arg0); + if (EFI_ERROR (Status)) { + return Status; + } + + Guid->Data1 = (Parameters.Arg0 & MAX_UINT32); + Guid->Data2 = (Parameters.Arg1 & MAX_UINT16); + Guid->Data3 = ((Parameters.Arg1 >> 16) & MAX_UINT16); + + Guid->Data4[0] = (Parameters.Arg2 & MAX_UINT8); + Guid->Data4[1] = ((Parameters.Arg2 >> 8) & MAX_UINT8); + Guid->Data4[2] = ((Parameters.Arg2 >> 16) & MAX_UINT8); + Guid->Data4[3] = ((Parameters.Arg2 >> 24) & MAX_UINT8); + + Guid->Data4[4] = (Parameters.Arg3 & MAX_UINT8); + Guid->Data4[5] = ((Parameters.Arg3 >> 8) & MAX_UINT8); + Guid->Data4[6] = ((Parameters.Arg3 >> 16) & MAX_UINT8); + Guid->Data4[7] = ((Parameters.Arg3 >> 24) & MAX_UINT8); + + DEBUG ((DEBUG_INFO, "FW-TRNG: UUID %g\n", Guid)); + + return EFI_SUCCESS; +} + +/** Returns maximum number of entropy bits that can be returned in a single + call. + + @return Returns the maximum number of Entropy bits that can be returned + in a single call to GetEntropy(). +**/ +UINTN +EFIAPI +GetTrngMaxSupportedEntropyBits ( + VOID + ) +{ + return MAX_ENTROPY_BITS; +} + +/** Returns N bits of conditioned entropy. + + See [3] Section 2.3.1 GetEntropy: An Interface to the Entropy Source + GetEntropy + Input: + bits_of_entropy: the requested amount of entropy + Output: + entropy_bitstring: The string that provides the requested entropy. + status: A Boolean value that is TRUE if the request has been satisfied, + and is FALSE otherwise. + + Note: In this implementation this function returns a status code instead + of a boolean value. + This is also compatible with the definition of Get_Entropy, see [2] + Section 7.4 Entropy Source Calls. + (status, entropy_bitstring) = Get_Entropy ( + requested_entropy, + max_length + ) + + @param [in] EntropyBits Number of entropy bits requested. + @param [out] Buffer Buffer to return the entropy bits. + @param [in] BufferSize Size of the Buffer in bytes. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_UNSUPPORTED Function not implemented. + @retval EFI_BAD_BUFFER_SIZE Buffer size is too small. + @retval EFI_NOT_READY No Entropy available. +**/ +EFI_STATUS +EFIAPI +GetEntropy ( + IN CONST UINTN EntropyBits, + OUT UINT8 * CONST Buffer, + IN CONST UINTN BufferSize + ) +{ + EFI_STATUS Status; + ARM_MONITOR_ARGS Parameters; + UINTN EntropyBytes; + UINTN LastValidBits; + UINTN ArgSelector; + UINTN BytesToClear; + + // [1] Section 2.4.3 Caller responsibilities. + // The caller cannot request more than MAX_BITS bits of conditioned + // entropy per call. + if ((EntropyBits == 0) || (EntropyBits > MAX_ENTROPY_BITS)) { + return EFI_INVALID_PARAMETER; + } + + EntropyBytes = (EntropyBits + 7) >> 3; + if (EntropyBytes > BufferSize) { + return EFI_BAD_BUFFER_SIZE; + } + + ZeroMem (Buffer, BufferSize); + ZeroMem (&Parameters, sizeof (Parameters)); + + /* + Cf. [1], Section 2.4 TRNG_RND + Function ID (W0) 0x8400_0053 + 0xC400_0053 + SMC32 Parameters + W1 N bits of entropy (1 6 N 6 96) + W2-W7 Reserved (MBZ) + SMC64 Parameters + X1 N bits of entropy (1 6 N 6 192) + X2-X7 Reserved (MBZ) + SMC32 Returns + Success (W0 = 0): + W0 MBZ + W1 Entropy[95:64] + W2 Entropy[63:32] + W3 Entropy[31:0] + Error (W0 < 0) + W0 NOT_SUPPORTED + NO_ENTROPY + INVALID_PARAMETERS + W1 - W3 Reserved (MBZ) + SMC64 Returns + Success (X0 = 0): + X0 MBZ + X1 Entropy[191:128] + X2 Entropy[127:64] + X3 Entropy[63:0] + Error (X0 < 0) + X0 NOT_SUPPORTED + NO_ENTROPY + INVALID_PARAMETERS + X1 - X3 Reserved (MBZ) + */ + Parameters.Arg0 = FID_TRNG_RND; + Parameters.Arg1 = EntropyBits; + ArmCallMonitor (&Parameters); + + // Convert status codes to EFI status codes. + Status = TrngStatusToEfiStatus ((INT32)Parameters.Arg0); + if (EFI_ERROR (Status)) { + return Status; + } + + // Extract Data + // ArgSelector = ((EntropyBytes + 3) >> 2); for AArch32 + // ArgSelector = ((EntropyBytes + 7) >> 3); for AArch64 + // ((sizeof (UINTN) >> 2) + 1) is 3 or 2 depending on size of UINTN + ArgSelector = ((EntropyBytes + (sizeof (UINTN) - 1)) >> + ((sizeof (UINTN) >> 2) + 1)); + + switch (ArgSelector) { + case 3: + CopyMem (&Buffer[(sizeof (UINTN) * 2)], &Parameters.Arg1, sizeof (UINTN)); + + case 2: + CopyMem (&Buffer[sizeof (UINTN)], &Parameters.Arg2, sizeof (UINTN)); + + case 1: + CopyMem (&Buffer[0], &Parameters.Arg3, sizeof (UINTN)); + break; + + default: + ASSERT (0); + return EFI_INVALID_PARAMETER; + } // switch + + + // [1] Section 2.4.3 Caller responsibilities. + // The caller must ensure that only the value in Entropy[N-1:0] is consumed + // and that the remaining bits in Entropy[MAX_BITS-1:N] are ignored. + // Therefore, Clear the unused upper bytes. + BytesToClear = (sizeof (UINTN) * ArgSelector) - EntropyBytes; + if (BytesToClear != 0) { + ZeroMem (&Buffer[EntropyBytes], BytesToClear); + } + + // Clear the unused MSB bits of the last byte. + LastValidBits = EntropyBits & 0x7; + if (LastValidBits != 0) { + Buffer[EntropyBytes - 1] &= (0xFF >> (8 - LastValidBits)); + } + + return Status; +} + +/** The constructor checks that the FW-TRNG interface is supported + by the host firmware. + + It will ASSERT() if FW-TRNG is not supported. + It will always return EFI_SUCCESS. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. +**/ +EFI_STATUS +EFIAPI +ArmFwTrngLibConstructor ( + VOID + ) +{ + EFI_STATUS Status; + UINT16 MajorRev; + UINT16 MinorRev; + GUID Guid; + + Status = GetTrngVersion (&MajorRev, &MinorRev); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + +#ifndef MDEPKG_NDEBUG + // Check that the required features are present. + Status = GetTrngFeatures (FID_TRNG_RND, NULL); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + // Check if TRNG UUID is supported and if so trace the GUID. + Status = GetTrngFeatures (FID_TRNG_GET_UUID, NULL); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } +#endif + + Status = GetTrngUuid (&Guid); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + DEBUG (( + DEBUG_INFO, + "FW-TRNG: Version %d.%d, GUID {%g}\n", + MajorRev, + MinorRev, + Guid + )); + + return EFI_SUCCESS; +} diff --git a/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf new file mode 100644 index 0000000000000000000000000000000000000000..4b2c58251fbe8fbcb5af308736db014e8d954720 --- /dev/null +++ b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf @@ -0,0 +1,34 @@ +## @file +# Arm Firmware TRNG interface library. +# +# Copyright (c) 2021, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = ArmFwTrngLib + FILE_GUID = 10DE97C9-28E4-4C9B-A53E-8D7D1B0DD4E0 + VERSION_STRING = 1.0 + MODULE_TYPE = BASE + LIBRARY_CLASS = TrngLib + CONSTRUCTOR = ArmFwTrngLibConstructor + +[Sources] + ArmFwTrngDefs.h + ArmFwTrngLib.c + +[Packages] + ArmPkg/ArmPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + ArmSmcLib + ArmHvcLib + BaseLib + BaseMemoryLib + +[Pcd] + gArmTokenSpaceGuid.PcdMonitorConduitHvc + -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'