From patchwork Tue Jul 18 11:53:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Funke X-Patchwork-Id: 1809196 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=weidmueller.onmicrosoft.com header.i=@weidmueller.onmicrosoft.com header.a=rsa-sha256 header.s=selector1-weidmueller-onmicrosoft-com header.b=Gb6QndmU; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R4y7v2T6pz20Cs for ; Tue, 18 Jul 2023 21:55:39 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 072028670E; Tue, 18 Jul 2023 13:53:59 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=weidmueller.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=weidmueller.onmicrosoft.com header.i=@weidmueller.onmicrosoft.com header.b="Gb6QndmU"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 7E9A68668C; Tue, 18 Jul 2023 13:53:38 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FORGED_SPF_HELO,SPF_HELO_PASS,T_SCC_BODY_TEXT_LINE, T_SPF_PERMERROR autolearn=no autolearn_force=no version=3.4.2 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-he1eur04on0627.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe0d::627]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 7A4C1866C6 for ; Tue, 18 Jul 2023 13:53:32 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=weidmueller.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=Lukas.Funke-oss@weidmueller.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Lx8TW9J0p7rUpLuOmVxma4zqqcsWT5oQGf4orpnMi9H4JbPTAWmjaIRoerv+Par25CzjJspb2YJF4/Zf9zJNj6/e81+r0ioNZM6TO/LBZZqqmvsSO+VqKmuhhbZNRQVioNHmvio10G0tQgLMM9Vur3Fluwui+d54sfTu0qng5gskjGVuQ7cH1tLmrrnenaPtKTA2+ow5Xcw9EmLNmVzIiNF/TIK4bJrZwiX11CceKf4s+QJhddBhvwUa3fksJx8yrhAEXtnzblO3wxMdmNh2Y8P1W7f47Jkg4PIEskZjP5wfQxPbdIMF95zdG/+f0vhY6vOa6CHolnS9WFhpPbov4A== 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=YaxPhgqfubJboKCYn8jO9NA1ZaPiVzEME3WVtQ9g3zA=; b=JrANQEDzbOEsjWo8AH250w+uefuAS74yB7v2jzW4r+OFLmlrMJMJdTUgDPiYN7CC1lmmhUMtBncPqE6rFYEWjyPggmLw8oZ0xSGkhB3bJep3kdhsYu7PTnk96a4yeXZWop0QLlEVfoVn04M1kgWyy5hFsZWU4ky12T8bSdPxceqp3X8zgWH1ktPojaV6wzKONlEaMd1Kpwgvhcye2Z+C8CFOyt0hiC3/ZeQkWKNxySuCGGd7L/1qk88+MZ1AxqdHCkeM9i+DhEu8UYMkggC1INP0Yk9Xjv8nuvI33CqeOi4S1glv4DDCa63zcRFfAyatTawqKIB/MhkHiKOiCAJfDA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=weidmueller.com; dmarc=pass action=none header.from=weidmueller.com; dkim=pass header.d=weidmueller.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=weidmueller.onmicrosoft.com; s=selector1-weidmueller-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=YaxPhgqfubJboKCYn8jO9NA1ZaPiVzEME3WVtQ9g3zA=; b=Gb6QndmUo/c3ZxslB7g9lBn/6BQrgKXfQNDiOZ2RPxW9ijoPO1RbE10tnmufM4JevGaU452phlVyA9Qd0xDwNMlEJEB1GdE5UgKvapf8f8QuhwXesKbgDDBZ5hSISaXSbb+rGVVn9NIhgSBHa7p/2NhfJTf58lwREcxQObfFNiM= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=weidmueller.com; Received: from AS2PR08MB8431.eurprd08.prod.outlook.com (2603:10a6:20b:55a::18) by DB5PR08MB10288.eurprd08.prod.outlook.com (2603:10a6:10:4a5::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6588.31; Tue, 18 Jul 2023 11:53:31 +0000 Received: from AS2PR08MB8431.eurprd08.prod.outlook.com ([fe80::9d3c:b418:152b:34d9]) by AS2PR08MB8431.eurprd08.prod.outlook.com ([fe80::9d3c:b418:152b:34d9%7]) with mapi id 15.20.6588.031; Tue, 18 Jul 2023 11:53:31 +0000 From: lukas.funke-oss@weidmueller.com To: u-boot@lists.denx.de Cc: Simon Glass , Quentin Schulz , Lukas Funke , Alper Nebi Yasak , Michal Simek Subject: [PATCH v3 11/11] binman: etype: Add xilinx_fsbl_auth etype Date: Tue, 18 Jul 2023 13:53:19 +0200 Message-Id: <20230718115319.868130-12-lukas.funke-oss@weidmueller.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230718115319.868130-1-lukas.funke-oss@weidmueller.com> References: <20230718115319.868130-1-lukas.funke-oss@weidmueller.com> X-ClientProxiedBy: FR3P281CA0179.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:a0::16) To AS2PR08MB8431.eurprd08.prod.outlook.com (2603:10a6:20b:55a::18) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AS2PR08MB8431:EE_|DB5PR08MB10288:EE_ X-MS-Office365-Filtering-Correlation-Id: 28490fee-2299-4240-0f24-08db87859b77 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: XDMdl2y9HlXOi62s6mYJE0G3tV5Zl6N1VZ2zpQZcpil353yOdfPRlt5YVMrvGgMQ2XxBf2JMozmWqhN2whqy26gvATetlc4+6PBCD6esEOKh3sXiinaNyOupq4Y/h5bAzGnBOrpLHvLr++w9I9NZsHNbq44valeCnKTzrmbbYfcteGECifW1gJCLUcOW8kX+2TViBNIoWOxyhySDL9hIa6YUT0RHC9RcycegVaBzCdKPGxyITO9ApqRPyhgKZUzIwbCHsywqbhhZ57MAXJgkWkB6+CHjK0KNdzoDM+D9lMIt1Qq6MUZTv2ejehXSOYO+1BoLFfWxZKgRQm0jHZLzLG17KI6lMBs4/BuccuGHO+iqJ3KC9eDs8Xu/1GfiMCFTRNyXuZnP+z79nfBaOETOJvuLGzn7dc0twKYkSTX0/BMo9y3S39nKSrPg5dXe6M22ydqcCQaAXNjGxL9TBJosjd5PiVeLS6LHtHety98loxeF3srVWOO1Ggejt3tqX1MikqeL6DigRwnCvHINxjs4vATiV56QgbkqaGCNhrF1yxChAg4xu/ygmn1TDeTBulML8LwG2anV8r1hpisiElo0S7282mOcdKVu3WKNqLYcUVM= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AS2PR08MB8431.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230028)(4636009)(39860400002)(366004)(376002)(396003)(346002)(136003)(451199021)(83380400001)(86362001)(52116002)(6486002)(6666004)(36756003)(38350700002)(38100700002)(2906002)(2616005)(30864003)(186003)(5660300002)(1076003)(6506007)(26005)(41300700001)(8676002)(8936002)(478600001)(66556008)(6512007)(9686003)(66476007)(966005)(66946007)(6916009)(4326008)(316002)(54906003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: +mmmZrmHQQW5pch8/ot97EuAWrj3Jh1R0OKm4i9NJ1alyjS1MZ3lbfu3J35ODQX0Pd9S7SH8k5rNtq9J7j6sD94qAcAY3g4RgXco+0iZCaCGSujsmoi1W6TJhJ0uorXkGQWhUUZnsy0P7dQa7u0Rs7mcTQ5MVzdOSUfIbTGOKpAwS+1+qwomZ4Ish+2R9oI6JbPhFuKjTgQS+ibZ9ZSPdZxYaGiWM53R2ShDjd5C5Mfzd7p7H2TolTC25g2aMYY/LOPg+1mw5VaRzvXL122Ed2N6tHQT/kbiPgYmSJqGi+wATbx9vN/0H3En4P7oEf5FFeDgm+r//qql0Z1bdGMDyapTgicqdbmXmtxZq450RhqK15bZ5MubZB300qFcayHMWCf+V5zcUqOt0vR2VMF3Uf4vB8pX0ZrreI+N8rgxzy6g2pFoa7nP2ZsQyj9Ojp/re3NnsaiFJt/9TDB7085PfEQFr2j2Vm2tBfhNNfbFSehFrrom7xpbxSUR70grLTbqlwm6cfSRmqbvGtH+5Xy2n/5dnj7tVpxinwBZf5OvBn56ClRpbV2Rb8jNb6pqReQuoJ4CB9XDeGUuGQbKvEwOhesOYb/aDaQaNeas3O0GxjJ5TFKFIZtR3JAaPhS8EDEFee9pQ5Lmw0l9Cf6vP05KjPUzIu2/jTbF21zfSLZHWOZ29UE7lw490dPihZp5wzPgPsGHgKn7eUzD6JyRBeP67nQh+qmdQ0LVYZ6aHaCKw82WLUErmtmCFFPlTnz44YsbQaApKPGEif+6WGMPAdKv5KE4Dws5etT54Xhl6aDzof2+KHguajLCrZnLjGqNNVf5IgS+YEoSqU5MsQ4qSSP0icQeRmTSXTr5NSK/QwHcndisMyiteMFfyr+l63rrp+hKlKse1TCXshlDY+cubtdZcZVLj4n9gNA3/BKmLFdEZSRB/rzi8Jyn3ve2GpU7FHuwDT3FTiAu27LgKCfHMB6sJCwOytHhAMkxCmE4+7xdCnM59PiQv323nxjDlEhS/aQdW1VWAvpNx+BWFXMkr9JlUjhcUp9WdcCSGSmI67SV+AQb+m+bN+QSE3h1mXSeht3P8/VEXIPJ08tJQMKBDhBeWv3lEethobzZKVLe1o67YxealEviy+vHajmCCFXGGB+jm9Y2HvbZkwe8ayHlS9vhoeUcdnvKsyiYL57AJpoRfyriicoDAR6JfAgPHzhw7teweotb+HcHpTeHJGLhKVC+t+z3F10l8tXpr78PkInGcn1DAGnp5wPqEGs1JrKL3bvF1E8ikuK+xHxY0WuA/ywuUcsgnJukFzd1fizFjrMecdwv4kHu9agvJFV8N2wdHLoo6kM13l2a+PslJ/E8svxKw2FsxPTNP1cPjgsGB/3JQUUzRR2SMWiGeqSZewEWdcinVyUtZuuzvsNkwYm4DEBwHmi8EB+05wXce9Xzd5cKk8DZ312D38+j+ZiCzvFvo0pR5G57ZOrY2JTcdRMzhPeRif9gD0nYkxsmeQHTjR/4H59w+bd5OldOc/xhR9tY/FB7MIHrX98/budY4eH3Ox3e8w9fFeNZMtCpU01xB/OjvYYa1RsJCYpSGtr6PcM1CI3hDMCl8eVAfyQyXqC/lR18MQ== X-OriginatorOrg: weidmueller.com X-MS-Exchange-CrossTenant-Network-Message-Id: 28490fee-2299-4240-0f24-08db87859b77 X-MS-Exchange-CrossTenant-AuthSource: AS2PR08MB8431.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Jul 2023 11:53:31.2821 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e4289438-1c5f-4c95-a51a-ee553b8b18ec X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: DbfrJKi8u4mWzsC1ptMAoQSVuuaTkdyAlQTAipn2qTEv+HEzXufW0T8r3/VAIoVgX0gAzUBQ5G19MDQLvJdrkQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB5PR08MB10288 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean From: Lukas Funke This adds a new etype 'xilinx-fsbl-auth'. By using this etype it is possible to created an authenticated SPL (FSBL in Xilinx terms) for ZynqMP boards. The etype uses Xilinx Bootgen tools in order to transform the SPL into a bootable image and sign the image with a given primary and secondary public key. For more information to signing the FSBL please refer to the Xilinx Bootgen documentation. Here is an example of the etype in use: spl { filename = "boot.signed.bin"; xilinx-fsbl-auth { psk-key-name-hint = "psk0"; ssk-key-name-hint = "ssk0"; auth-params = "ppk_select=0", "spk_id=0x00000000"; u-boot-spl-nodtb { }; u-boot-spl-dtb { }; }; }; For this to work the hash of the primary public key has to be fused into the ZynqMP device and authentication (RSA_EN) has to be set. For testing purposes: if ppk hash check should be skipped one can add the property 'fsbl_config = "bh_auth_enable";' to the etype. However, this should only be used for testing(!). Signed-off-by: Lukas Funke Reviewed-by: Simon Glass --- Changes in v3: - Changed etype from entry to section - Changed property name "psk-filename" to "psk-key-name-hint" - Changed property name "ssk-filename" to "ssk-key-name-hint" - Decode spl elf file instead of reading start symbol - Improved test coverage - Improved documentation Changes in v2: - Add 'keysrc-enc' property to pass down to Bootgen - Improved documentation - Use predictable output names for intermediated results tools/binman/entries.rst | 71 ++++++++ tools/binman/etype/xilinx_fsbl_auth.py | 221 +++++++++++++++++++++++++ 2 files changed, 292 insertions(+) create mode 100644 tools/binman/etype/xilinx_fsbl_auth.py diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst index c368ea8053..47af8c7226 100644 --- a/tools/binman/entries.rst +++ b/tools/binman/entries.rst @@ -2462,3 +2462,74 @@ may be used instead. +.. _etype_xilinx_fsbl_auth: + +Entry: xilinx-fsbl-auth: Authenticated SPL for booting Xilinx ZynqMP devices +---------------------------------------------------------------------------- + +Properties / Entry arguments: + - auth-params: (Optional) Authentication parameters passed to bootgen + - fsbl-config: (Optional) FSBL parameters passed to bootgen + - keysrc-enc: (Optional) Key source when using decryption engine + - pmufw-filename: Filename of PMU firmware. Default: pmu-firmware.elf + - psk-key-name-hint: Name of primary secret key to use for signing the + secondardy public key. Format: .pem file + - ssk-key-name-hint: Name of secondardy secret key to use for signing + the boot image. Format: .pem file + +The etype is used to create an authenticated boot image for Xilinx ZynqMP +devices. In AMD/Xilinx SoCs, two pairs of public and secret keys are used +- primary and secondary. The function of the primary public/secret key pair +is to authenticate the secondary public/secret key pair. +The function of the secondary key is to sign/verify the boot image. [1] + +AMD/Xilinx uses the following terms for private/public keys [1]: + + PSK = Primary Secret Key (Used to sign Secondary Public Key) + PPK = Primary Public Key (Used to verify Secondary Public Key) + SSK = Secondary Secret Key (Used to sign the boot image/partitions) + SPK = Used to verify the actual boot image + +The following example builds an authenticated boot image. The fuses of +the primary public key (ppk) should be fused together with the RSA_EN flag. + +Example node:: + + spl { + filename = "boot.signed.bin"; + + xilinx-fsbl-auth { + psk-key-name-hint = "psk0"; + ssk-key-name-hint = "ssk0"; + auth-params = "ppk_select=0", "spk_id=0x00000000"; + + u-boot-spl-nodtb { + }; + u-boot-spl-pubkey-dtb { + algo = "sha384,rsa4096"; + required = "conf"; + key-name-hint = "dev"; + }; + }; + }; + +For testing purposes, e.g. if no RSA_EN should be fused, one could add +the "bh_auth_enable" flag in the fsbl-config field. This will skip the +verification of the ppk fuses and boot the image, even if ppk hash is +invalid. + +Example node:: + + xilinx-fsbl-auth { + psk-key-name-hint = "psk0"; + psk-key-name-hint = "ssk0"; + ... + fsbl-config = "bh_auth_enable"; + ... + }; + +[1] https://docs.xilinx.com/r/en-US/ug1283-bootgen-user-guide/Using-Authentication + + + + diff --git a/tools/binman/etype/xilinx_fsbl_auth.py b/tools/binman/etype/xilinx_fsbl_auth.py new file mode 100644 index 0000000000..1f85784024 --- /dev/null +++ b/tools/binman/etype/xilinx_fsbl_auth.py @@ -0,0 +1,221 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2023 Weidmueller GmbH +# Written by Lukas Funke +# +# Entry-type module for signed ZynqMP boot images (boot.bin) +# + +import tempfile + +from collections import OrderedDict + +from binman import elf +from binman.etype.section import Entry_section + +from dtoc import fdt_util + +from u_boot_pylib import tools +from u_boot_pylib import command + +# pylint: disable=C0103 +class Entry_xilinx_fsbl_auth(Entry_section): + """Authenticated SPL for booting Xilinx ZynqMP devices + + Properties / Entry arguments: + - auth-params: (Optional) Authentication parameters passed to bootgen + - fsbl-config: (Optional) FSBL parameters passed to bootgen + - keysrc-enc: (Optional) Key source when using decryption engine + - pmufw-filename: Filename of PMU firmware. Default: pmu-firmware.elf + - psk-key-name-hint: Name of primary secret key to use for signing the + secondardy public key. Format: .pem file + - ssk-key-name-hint: Name of secondardy secret key to use for signing + the boot image. Format: .pem file + + The etype is used to create an authenticated boot image for Xilinx ZynqMP + devices. In AMD/Xilinx SoCs, two pairs of public and secret keys are used + - primary and secondary. The function of the primary public/secret key pair + is to authenticate the secondary public/secret key pair. + The function of the secondary key is to sign/verify the boot image. [1] + + AMD/Xilinx uses the following terms for private/public keys [1]: + + PSK = Primary Secret Key (Used to sign Secondary Public Key) + PPK = Primary Public Key (Used to verify Secondary Public Key) + SSK = Secondary Secret Key (Used to sign the boot image/partitions) + SPK = Used to verify the actual boot image + + The following example builds an authenticated boot image. The fuses of + the primary public key (ppk) should be fused together with the RSA_EN flag. + + Example node:: + + spl { + filename = "boot.signed.bin"; + + xilinx-fsbl-auth { + psk-key-name-hint = "psk0"; + ssk-key-name-hint = "ssk0"; + auth-params = "ppk_select=0", "spk_id=0x00000000"; + + u-boot-spl-nodtb { + }; + u-boot-spl-pubkey-dtb { + algo = "sha384,rsa4096"; + required = "conf"; + key-name-hint = "dev"; + }; + }; + }; + + For testing purposes, e.g. if no RSA_EN should be fused, one could add + the "bh_auth_enable" flag in the fsbl-config field. This will skip the + verification of the ppk fuses and boot the image, even if ppk hash is + invalid. + + Example node:: + + xilinx-fsbl-auth { + psk-key-name-hint = "psk0"; + psk-key-name-hint = "ssk0"; + ... + fsbl-config = "bh_auth_enable"; + ... + }; + + [1] https://docs.xilinx.com/r/en-US/ug1283-bootgen-user-guide/Using-Authentication + + """ + def __init__(self, section, etype, node): + super().__init__(section, etype, node) + self._auth_params = None + self._entries = OrderedDict() + self._filename = None + self._fsbl_config = None + self._keysrc_enc = None + self._pmufw_filename = None + self._psk_key_name_hint = None + self._ssk_key_name_hint = None + self.align_default = None + self.bootgen = None + self.required_props = ['psk-key-name-hint', 'ssk-key-name-hint'] + + def ReadNode(self): + """Read properties from the xilinx_fsbl_auth node""" + super().ReadNode() + self._auth_params = fdt_util.GetStringList(self._node, + 'auth-params') + self._filename = fdt_util.GetString(self._node, 'filename') + self._fsbl_config = fdt_util.GetStringList(self._node, + 'fsbl-config') + self._keysrc_enc = fdt_util.GetString(self._node, + 'keysrc-enc') + self._pmufw_filename = fdt_util.GetString(self._node, + 'pmufw-filename', + 'pmu-firmware.elf') + self._psk_key_name_hint = fdt_util.GetString(self._node, + 'psk-key-name-hint', + 'psk.pem') + self._ssk_key_name_hint = fdt_util.GetString(self._node, + 'psk-key-name-hint', + 'ssk.pem') + self.ReadEntries() + + @classmethod + def _ToElf(cls, data, output_fname): + """Convert SPL object file to bootable ELF file. + + Args: + data (bytearray): u-boot-spl-nodtb + u-boot-spl-pubkey-dtb obj file + data + output_fname (str): Filename of converted FSBL ELF file + """ + platform_elfflags = {"aarch64": + ["-B", "aarch64", "-O", "elf64-littleaarch64"], + # amd64 support makes no sense for the target + # platform, but we include it here to enable + # testing on hosts + "x86_64": + ["-B", "i386", "-O", "elf64-x86-64"] + } + + gcc, args = tools.get_target_compile_tool('cc') + args += ['-dumpmachine'] + stdout = command.output(gcc, *args) + # split target machine triplet (arch, vendor, os) + arch, _, _ = stdout.split('-') + + spl_elf = elf.DecodeElf(tools.read_file( + tools.get_input_filename('spl/u-boot-spl')), 0) + + # Obj file to swap data and text section (rename-section) + with tempfile.NamedTemporaryFile(prefix="u-boot-spl-pubkey-", + suffix=".o.tmp", + dir=tools.get_output_dir())\ + as tmp_obj: + input_objcopy_fname = tmp_obj.name + # Align packed content to 4 byte boundary + pad = bytearray(tools.align(len(data), 4) - len(data)) + tools.write_file(input_objcopy_fname, data + pad) + # Final output elf file which contains a valid start address + with tempfile.NamedTemporaryFile(prefix="u-boot-spl-pubkey-elf-", + suffix=".o.tmp", + dir=tools.get_output_dir())\ + as tmp_elf_obj: + input_ld_fname = tmp_elf_obj.name + objcopy, args = tools.get_target_compile_tool('objcopy') + args += ["--rename-section", ".data=.text", + "-I", "binary"] + args += platform_elfflags[arch] + args += [input_objcopy_fname, input_ld_fname] + command.run(objcopy, *args) + + ld, args = tools.get_target_compile_tool('ld') + args += [input_ld_fname, '-o', output_fname, + "--defsym", f"_start={hex(spl_elf.entry)}", + "-Ttext", hex(spl_elf.entry)] + command.run(ld, *args) + + def BuildSectionData(self, required): + """Pack node content, and create bootable, signed ZynqMP boot image + + The method collects the content of this node (usually SPL + dtb) and + converts them to an ELF file. The ELF file is passed to the + Xilinx bootgen tool which packs the SPL ELF file together with + Platform Management Unit (PMU) firmware into a bootable image + for ZynqMP devices. The image is signed within this step. + + The result is a bootable, authenticated SPL image for Xilinx ZynqMP + devices. + + """ + data = super().BuildSectionData(required) + bootbin_fname = self._filename if self._filename else \ + tools.get_output_filename( + f'boot.{self.GetUniqueName()}.bin') + + pmufw_elf_fname = tools.get_input_filename(self._pmufw_filename) + psk_fname = tools.get_input_filename(self._psk_key_name_hint + ".pem") + ssk_fname = tools.get_input_filename(self._ssk_key_name_hint + ".pem") + fsbl_config = ";".join(self._fsbl_config) if self._fsbl_config else None + auth_params = ";".join(self._auth_params) if self._auth_params else None + + spl_elf_fname = tools.get_output_filename('u-boot-spl-pubkey.dtb.elf') + + # We need to convert to node content (see above) into an ELF + # file in order to be processed by bootgen. + self._ToElf(bytearray(data), spl_elf_fname) + + # Call Bootgen in order to sign the SPL + self.bootgen.sign('zynqmp', spl_elf_fname, pmufw_elf_fname, + psk_fname, ssk_fname, fsbl_config, + auth_params, self._keysrc_enc, bootbin_fname) + + data = tools.read_file(bootbin_fname) + self.SetContents(data) + + return data + + # pylint: disable=C0116 + def AddBintools(self, btools): + super().AddBintools(btools) + self.bootgen = self.AddBintool(btools, 'bootgen')