From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from EUR03-AM5-obe.outbound.protection.outlook.com (EUR03-AM5-obe.outbound.protection.outlook.com [40.107.3.78]) by mx.groups.io with SMTP id smtpd.web10.8752.1637062404430784394 for ; Tue, 16 Nov 2021 03:33:25 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@armh.onmicrosoft.com header.s=selector2-armh-onmicrosoft-com header.b=uw/cfDHl; spf=pass (domain: arm.com, ip: 40.107.3.78, 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=iFu8FUOfiojjENUiUGRxdQ0t2l0bUhtJJ3WZL/2zXHg=; b=uw/cfDHl2YkbSs968qqV2UJU2LYY1sch7s9UceLc1cvxZuq0H5WDMbF1s8tgvZE4URApbAXZCWgHBiUtlap10WTlp9vpJ7qQCfr8VO9qEoZ8BwzcJbzKsRRsjfNLXzkAfDzGmvzrfPF6GvndQmVvHpF5WcuJPqJJ5Fjm92N6R+A= Received: from DB6PR0201CA0032.eurprd02.prod.outlook.com (2603:10a6:4:3f::42) by DB6PR0802MB2325.eurprd08.prod.outlook.com (2603:10a6:4:85::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4690.27; Tue, 16 Nov 2021 11:33:19 +0000 Received: from DB5EUR03FT008.eop-EUR03.prod.protection.outlook.com (2603:10a6:4:3f:cafe::de) by DB6PR0201CA0032.outlook.office365.com (2603:10a6:4:3f::42) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4690.19 via Frontend Transport; Tue, 16 Nov 2021 11:33:19 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;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 DB5EUR03FT008.mail.protection.outlook.com (10.152.20.98) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4690.19 via Frontend Transport; Tue, 16 Nov 2021 11:33:19 +0000 Received: ("Tessian outbound de6049708a0a:v110"); Tue, 16 Nov 2021 11:33:19 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 2542778084ff1813 X-CR-MTA-TID: 64aa7808 Received: from 0a93b2d29aa1.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 692187F6-B125-480E-A173-5AEFB79DA606.1; Tue, 16 Nov 2021 11:33:10 +0000 Received: from EUR02-VE1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 0a93b2d29aa1.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Tue, 16 Nov 2021 11:33:10 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TEmwU5NXff0fmxax9kSM1YGOmJC6ttpAv4ASkVzpvDIIIZ8q83zpllYRf18iqho21Pbi1DRoe57zl6i3ey77/x5lAbxIdXZQJDMQ6VbID0geH5OEq9D0tEdWsV8KDq1/ixQS6/68LHugFL2xkoLXG28MFPPnpNp+pAT1G9vIOenSof/SgVg3ZXoNKvQB5Ln9U/1TWeveNDaBjsazSpgKkBfwfIusl2G+lzenZ+0HKW2o4nvOKejSXwTGizypZxdzbbKWkoRQpI23EdpT3sT3emJ0Lez5O5v1QzyccJKBzceR3jfyGhWQbU+oXmvNcQSXdi6sgXGkJk6GBS1DyMJnEg== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=iFu8FUOfiojjENUiUGRxdQ0t2l0bUhtJJ3WZL/2zXHg=; b=mmGN8bp6u8CvzyZMf8Hegv/Dr1t4T9JFMZTYowcLnPi1/14wvqMNt01cdgJ9K66xGIiJ/JqKqcSzqSxax00FeyHz/w/zL7e7TtSdhqSQxdARY8QLsG0V0lw66QwBPqQJ9u2yxIOtwumqGT6pwCxoHS23rJvJvxVGKeRP5PL2hIiUAL9cUtI0lxBouVdTpWuqa/cmGplX19R77jyAGwRyf0dGMwIDuZCrTkVuFQnLJzfEKZP9tfuMD2agLuW4ZqA8U8H6CfBhtcmJXA+7cHWEg2s+9sU0hXuewGxDqTMsNm4hzFbLqa9tyTz+fN+B4bhC4Is/9MyMmBdvXKKxZxVKWA== 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=iFu8FUOfiojjENUiUGRxdQ0t2l0bUhtJJ3WZL/2zXHg=; b=uw/cfDHl2YkbSs968qqV2UJU2LYY1sch7s9UceLc1cvxZuq0H5WDMbF1s8tgvZE4URApbAXZCWgHBiUtlap10WTlp9vpJ7qQCfr8VO9qEoZ8BwzcJbzKsRRsjfNLXzkAfDzGmvzrfPF6GvndQmVvHpF5WcuJPqJJ5Fjm92N6R+A= Received: from AS9PR06CA0328.eurprd06.prod.outlook.com (2603:10a6:20b:45b::31) by AM4PR0802MB2146.eurprd08.prod.outlook.com (2603:10a6:200:5b::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4690.27; Tue, 16 Nov 2021 11:33:07 +0000 Received: from VE1EUR03FT032.eop-EUR03.prod.protection.outlook.com (2603:10a6:20b:45b:cafe::98) by AS9PR06CA0328.outlook.office365.com (2603:10a6:20b:45b::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4690.26 via Frontend Transport; Tue, 16 Nov 2021 11:33:07 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 40.67.248.234) smtp.mailfrom=arm.com; dkim=none (message not signed) header.d=none;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 VE1EUR03FT032.mail.protection.outlook.com (10.152.18.121) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.4690.20 via Frontend Transport; Tue, 16 Nov 2021 11:33:07 +0000 Received: from AZ-NEU-EX03.Arm.com (10.251.24.31) by AZ-NEU-EX03.Arm.com (10.251.24.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.20; Tue, 16 Nov 2021 11:32:53 +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.20 via Frontend Transport; Tue, 16 Nov 2021 11:32:53 +0000 From: "Sami Mujawar" To: CC: Sami Mujawar , , , , , , , , , , , , , Subject: [PATCH v2 3/8] ArmPkg: Add Arm Firmware TRNG library Date: Tue, 16 Nov 2021 11:32:55 +0000 Message-ID: <20211116113301.31088-4-sami.mujawar@arm.com> X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: <20211116113301.31088-1-sami.mujawar@arm.com> References: <20211116113301.31088-1-sami.mujawar@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 1 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 63a6df21-6dc6-4230-58ff-08d9a8f4e368 X-MS-TrafficTypeDiagnostic: AM4PR0802MB2146:|DB6PR0802MB2325: 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: cEFXKqFbpw9F2fr4quqWjegUx4J+ttmtly2Xsptxh907akZUOFPXFw+j9yOzAyITVkd3ZgbiOloZKozpIHVMPnXXNCt4aD8q3BQi12EFM/UKKjMpVnVRjLKXTKWMafwQg9ixjTG+F9CZIBys78MSjsYLUKLNx8fCywdhN7JrcewfiX7FUpVwkIG9Rv2a8ntCTlM+GMJWNmYiAaXsbLs/noD6eEkdV+nNWc9WGdCu2+1lBQC3DIhUaGBIwSnFb0mnuB/BBIznDSTkaz+LBGZc24Fi6tslsMnVqM9gaOi3S6WJrtsxDRsLB2qaCTKkKzYZ8+xA1muB4jkbGREgJaUpM3YL/z1AFDN5/Gcs+CDmcTG5raVWaHLhipMsMcsf29YbNKDgvMRs4QFj7fu8xyi0c8KF2L5AIPG5Sc8OuD7euhR69tq9y6RQv/mn1qVpfsqtMlFS/FcMRFew6pBgVJvewhmqVVajrYB4eyOu2Mqu2ytiL3G3E0pPoi2upTd11lAw4GGJbd3equ6IqhfdYdlDLCD+obX1Ed49c7STrKf8U4qc3BD51mJpBsH+qkoeJSPjBqi5jEDfVq/gMHU/m4vimQSpCUndwU8VduvJv4mkuKfCglrRqkv+JoFJXYHO0SAGiePCv5qglE0YGvk//ou66Eeg5OgvuCcBtMZhemLKI/UdOtPa5WPU00l6uRYENLYSrrJ2jacrhPQZBG2rH9LCX7RUNyJLnQ65ILlL5yr25p/3eE+OCwAH+wrS1bU8LB8HEGEjq+iR3DLIARg+qdZAUg6623Ui/yMlZywlYDXCbz2WL38d3fDD40o7Th5yzXr2MEHmwzgDBSJd4UIPFVkAEpKInxPLcsQI89Kh4P7SoE8= 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)(356005)(30864003)(5660300002)(508600001)(44832011)(7416002)(6916009)(2906002)(83380400001)(8936002)(2616005)(86362001)(81166007)(82310400003)(1076003)(4326008)(47076005)(54906003)(316002)(36860700001)(7696005)(8676002)(426003)(70586007)(70206006)(36756003)(186003)(336012)(26005)(36900700001);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR0802MB2146 Return-Path: Sami.Mujawar@arm.com X-MS-Exchange-Transport-CrossTenantHeadersStripped: DB5EUR03FT008.eop-EUR03.prod.protection.outlook.com X-MS-Office365-Filtering-Correlation-Id-Prvs: c47a40f2-20e5-4d2b-45c6-08d9a8f4dc53 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: QJ+r3391VtJqUHPm5D+cJSxZj7i1g269UX0liGDJItPrVv0l9egDtGNUenWKCUoB7Rv/0JeqqaB9NH3NL0baO5yJTyFHtA1SuLuCaDp8iKeo9zhNUTaWaGEg/n+hdrADZW0+Pywnw8g27wuCNk6Yc7c4P1uegU/goD85mOnbEgOZCn80GDEKFQ1ZcUd0TuzR2/qEoL7hNUJgWtIqHi8OWZC2mvjYQoXleeANbBgfXsnLOLASw9ftnMw3Sye820bjulazFOG4VcPkDm8VFJNbbLUDmqy5EC1bgD1KmEqQpnWRM5Kbr3Q7m5nVH+zMqYjbbQnI8uzfE6PC6UeR4jlPO9wcIkdLLwN/svZoF9M5/Tq/007g00dj2QUQqehzeM8ymj6yIFZO+dGmb0fYa3zCCwvyfgl5bME0BQ2xLaz49VNlFdbi6QerUQol0h7ovqwNE30HsWswXE8p0XaZxjtfbyM2hrvPyuvKW7G8516EeSp735705P1jQEZF9U7q/Q+DZ3p4qKE8dTET/eCK9QxKFgNVM9wjbehpxrTGjwongZsX3qIPX4aFz/PeVklMsDcxyxevqlOvD+n3FV3ROVvTDrRZ6mDq03ovpzPihXIOtjMgjOK0FbTKejM//wuvFLuom+EziZtZ/TZYwS1Gg21TbrJzRZ1dR2Vf0Uw8x0Hx9tlL7f4m9L+H5E9pSVW3JxIU6tMcTJjyNzuKZaVBrL01e3Uc5UTlqvKqhXKwxsqUSRdKzYy9lDn9pJWRgsvbUOegkt4xtpUHT3ymHKrYwPjJ9Pg5IZqPn44mKtSXKXghxQDNX0sUHdqIMPNXQq/PMzmmHaUj3TmhnNXoDn53WzpRLg== 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)(508600001)(83380400001)(82310400003)(86362001)(70206006)(26005)(336012)(1076003)(54906003)(2616005)(81166007)(36860700001)(426003)(30864003)(2906002)(8676002)(70586007)(186003)(7696005)(44832011)(8936002)(5660300002)(36756003)(47076005)(4326008)(316002)(6916009);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Nov 2021 11:33:19.0279 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 63a6df21-6dc6-4230-58ff-08d9a8f4e368 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: DB5EUR03FT008.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0802MB2325 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 --- Notes: v2: - MdePkg\Include\Library\TrngLib.h is base type [LIMING] library. It can use RETURN_STATUS instead of EFI_STATUS. - Replaced EFI_STATUS with RETURN_STATUS. [SAMI] - MdePkg\Include\Library\TrngLib.h API parameter [LIMING] doesn't require CONST. CONST means the value specified by the input pointer will not be changed in API implementation. - Removed the use of constant pointers in the [SAMI] TRNG API. 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 59fd8f295d4f614cc68ee1021e691f94e279ab81..23df68c5eb53df11de5d96bde4949f3c833c9b2c 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -156,6 +156,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..314e7ffbc232ae90bbb77306f9c7113ce63012c8 --- /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 RETURN_SUCCESS Success. + @retval RETURN_UNSUPPORTED Function not implemented. + @retval RETURN_INVALID_PARAMETER A parameter is invalid. + @retval RETURN_NOT_READY No Entropy available. +**/ +STATIC +RETURN_STATUS +TrngStatusToEfiStatus ( + IN INT32 TrngStatus + ) +{ + switch (TrngStatus) { + case TRNG_NOT_SUPPORTED: + return RETURN_UNSUPPORTED; + + case TRNG_INVALID_PARAMETER: + return RETURN_INVALID_PARAMETER; + + case TRNG_NO_ENTROPY: + return RETURN_NOT_READY; + + case TRNG_STATUS_SUCCESS: + default: + return RETURN_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 RETURN_SUCCESS The function completed successfully. + @retval RETURN_INVALID_PARAMETER Invalid parameter. + @retval RETURN_UNSUPPORTED Backend not present. +**/ +RETURN_STATUS +EFIAPI +GetTrngVersion ( + OUT UINT16 *MajorRevision, + OUT UINT16 *MinorRevision + ) +{ + RETURN_STATUS Status; + ARM_MONITOR_ARGS Parameters; + INT32 Revision; + + if ((MajorRevision == NULL) || (MinorRevision == NULL)) { + return RETURN_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 RETURN_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 RETURN_SUCCESS The function completed successfully. + @retval RETURN_INVALID_PARAMETER Invalid parameter. + @retval RETURN_UNSUPPORTED Function not implemented. +**/ +STATIC +RETURN_STATUS +EFIAPI +GetTrngFeatures ( + IN CONST UINT32 FunctionId, + OUT UINT32 *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 RETURN_UNSUPPORTED; + } + + if (Capability != NULL) { + *Capability = Parameters.Arg0; + } + + return RETURN_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, RETURN_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 RETURN_SUCCESS The function completed successfully. + @retval RETURN_INVALID_PARAMETER Invalid parameter. + @retval RETURN_UNSUPPORTED Function not implemented. +**/ +RETURN_STATUS +EFIAPI +GetTrngUuid ( + OUT GUID *Guid + ) +{ + RETURN_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 RETURN_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 RETURN_SUCCESS The function completed successfully. + @retval RETURN_INVALID_PARAMETER Invalid parameter. + @retval RETURN_UNSUPPORTED Function not implemented. + @retval RETURN_BAD_BUFFER_SIZE Buffer size is too small. + @retval RETURN_NOT_READY No Entropy available. +**/ +RETURN_STATUS +EFIAPI +GetEntropy ( + IN CONST UINTN EntropyBits, + OUT UINT8 *Buffer, + IN CONST UINTN BufferSize + ) +{ + RETURN_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 RETURN_INVALID_PARAMETER; + } + + EntropyBytes = (EntropyBits + 7) >> 3; + if (EntropyBytes > BufferSize) { + return RETURN_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 RETURN_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 RETURN_SUCCESS. + + @retval RETURN_SUCCESS The constructor always returns RETURN_SUCCESS. +**/ +RETURN_STATUS +EFIAPI +ArmFwTrngLibConstructor ( + VOID + ) +{ + RETURN_STATUS Status; + UINT16 MajorRev; + UINT16 MinorRev; + GUID Guid; + + Status = GetTrngVersion (&MajorRev, &MinorRev); + if (EFI_ERROR (Status)) { + return RETURN_SUCCESS; + } + +#ifndef MDEPKG_NDEBUG + // Check that the required features are present. + Status = GetTrngFeatures (FID_TRNG_RND, NULL); + if (EFI_ERROR (Status)) { + return RETURN_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 RETURN_SUCCESS; + } +#endif + + Status = GetTrngUuid (&Guid); + if (EFI_ERROR (Status)) { + return RETURN_SUCCESS; + } + + DEBUG (( + DEBUG_INFO, + "FW-TRNG: Version %d.%d, GUID {%g}\n", + MajorRev, + MinorRev, + Guid + )); + + return RETURN_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)'