{"id":27298062,"url":"https://github.com/open-power/sb-signing-utils","last_synced_at":"2025-04-12T00:25:38.497Z","repository":{"id":43847330,"uuid":"66312097","full_name":"open-power/sb-signing-utils","owner":"open-power","description":"Secureboot Signing Utilities","archived":false,"fork":false,"pushed_at":"2024-05-15T16:05:15.000Z","size":393,"stargazers_count":3,"open_issues_count":3,"forks_count":12,"subscribers_count":20,"default_branch":"master","last_synced_at":"2024-05-17T04:02:14.743Z","etag":null,"topics":["openpower","ppc64","secure-boot"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/open-power.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-08-22T22:15:02.000Z","updated_at":"2024-05-29T21:28:29.644Z","dependencies_parsed_at":"2024-05-11T01:23:26.096Z","dependency_job_id":"c095fef3-1957-4a23-b438-1e5febcb9aca","html_url":"https://github.com/open-power/sb-signing-utils","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-power%2Fsb-signing-utils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-power%2Fsb-signing-utils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-power%2Fsb-signing-utils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-power%2Fsb-signing-utils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/open-power","download_url":"https://codeload.github.com/open-power/sb-signing-utils/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248498883,"owners_count":21114204,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["openpower","ppc64","secure-boot"],"created_at":"2025-04-12T00:25:37.791Z","updated_at":"2025-04-12T00:25:38.453Z","avatar_url":"https://github.com/open-power.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"sb-signing-utils\n================\n\nA simple utility for signing firmware components for OpenPOWER Secure\nand Trusted Boot.\n\nHow Firmware Signing works on OpenPOWER\n---------------------------------------\n\nThe core root of trust is in the CPU module (package). From the factory,\nthey come with \"imprint\" keys. The private key part is well known (i.e.\n**the private key is published on the internet**), and vendors, when\nputting modules into machines, will replace the imprint key with their\nown key.\n\nA hash of this key is stored in a SEEPROM inside the module (as there is\nnot enough space to store the full key). The full key is stored in the\nSecure/Trusted Boot Header (i.e the container header) of every bit of\nfirmware loaded from flash (PNOR).\n\nAll firmware loaded must be signed by this hardware key. In fact, there\nare three hardware keys, permitting a separation of duties for the root\nauthority. Signatures by all three hardware keys must be present in the\ncontainer.\n\nIn addition to the hardware key, there is also a software key (also\nreferred to as firmware key in some documentation.) In fact there are\nthree software keys, permitting a separation of duties for the firmware\nsigning operation.\n\nHaving separate hardware and software keys allows firmware to be\ndeveloped by a separate group to hardware (or multiple firmware loads\nfor the same hardware to be developed by separate entities).\n\nThe signing operations necessitate a two-step signing process since the\npart of the container header that must be signed needs to be created\nfirst, then the signatures must be returned to the container build\nprocess to complete the container. In the case of locally accessible keys\n(i.e. the private key is available to the build process), the entire\ncontainer can be completed at once (in a two-step process). In the case\nwhere signatures must be created externally, there may be some delay\nbetween the two steps.\n\nBy default, op-build will produce a signed firmware image but with the\npublished imprint keys. As such you **MUST NOT** use these to implement\nsecure boot. **The default product from op-build is only suitable for\ndevelopment use.**\n\nThe container build process\n---------------------------\n\nThe hardware and software keys form a two level hierarchy. The root keys\nare the hardware keys, and the signing keys are the software keys. In\nshort, the hardware keys sign the software keys, the and software keys\nsign the firmware components. The publc portion of the hardware and\nsoftware keys are added to the container during the build process.\n\nThere are two sections, or blobs, of the container header to be signed:\nthe software header and the prefix header. The software header, among\nother fields, contains a SHA512 hash of the payload (i.e. the firmware\nimage being signed). The software header will be signed by the software\nkeys. The prefix header contains a SHA512 hash of the software keys. The\nprefix header will be signed by the hardware keys.\n\nThe create-container program is run in a two-pass process. On each pass,\nthe program will create as much of the container as possible using all\navailable information. Normally, all information (i.e. all updatable\nfields) are provided on the first pass, except for the signatures. On the\nfirst pass, the program must have enough information to construct the\nsoftware and prefix headers. Namely, it must have the payload and the\npublic software keys. (Normally the hardware keys are also added on the\nfirst pass, although they don't have to be.) On the first pass, the\nprogram dumps the prefix and software header to the files specified.\n\nThe prefix header is then signed by the hardware keys, and the software\nheader is signed by the software keys. The signing operation (and keys)\nuse an ECDSA p521 signing algorithm. The signatures should be returned\nin DER format and can be performed by a simple \"openssl dgst\" command.\n\nOn the second pass, the program consumes the hardware and software key\nsignatures, adds these fields to the container header and completes the\ncontainer. The complete container consists of the container header (with\nall required public keys and signatures) added to the beginning of the\npayload.\n\nBuilding the project\n--------------------\n\nThe scripts \"build_all.sh\" and \"clean_all.sh\" are included in the project\nproject, and demonstrate how to build the project from source. The scripts\nsupport the GNU toolchain enabled method of building, and a\n\"lite\" method of building.\n\nTo build with full GNU toolchain support, run \"build_all.sh\" passing\n\"gnu\" on the command-line:\n\n$ build_all.sh gnu\n\nThis utilizes the included \"configure.ac\" and \"Makefile.am\", and is\nequivalent to running:\n\n$ libtoolize -f \u0026\u0026 aclocal \u0026\u0026 autoheader \u0026\u0026 automake -a \u0026\u0026 autoconf \u0026\u0026 \\\n  configure \u0026\u0026 make\n\nOr:\n\n$ autoreconf -i -Wno-unsupported \u0026\u0026 ./configure \u0026\u0026 make\n\nTo clean the project, including removing *all* GNU toolchain support\nfiles, run:\n\n$ clean_all.sh gnu\n\nTo build \"lite\" using a simple Makefile and config.h, run \"build_all.sh\"\npassing \"lite\" on the command-line (or no option at all, as \"lite\" is the\ndefault):\n\n$ build_all.sh lite\n\nThis utilizes the included \"configure.h.lite\" and \"Makefile.lite\". The\nscript simply copies these files into place and runs \"make\".\n\nTo clean the project, run the following, which is really just doing a\n\"make clean\":\n\n$ clean_all.sh lite\n\nBuilding the project with v2 container support\n--------------------\n\nTo support v2 containers you will need to build the mlca library with\ndilithium support.\n\nThis library can be found at : https://github.com/IBM/mlca/\n\nTo build with full GNU toolchain support, run \"build_all.sh\" passing\n\"gnu\" on the command-line:\n\n$ MLCA_PATH=\u003cPath to built mlca repo\u003e ./build_all.sh gnuv2\n\nBuilding the project with v3 container support\n--------------------\n\nTo support v3 containers you will need to build the mlca library with\nmldsa-87 support.\n\nThis library can be found at : https://github.com/IBM/mlca/\n\nTo build with full GNU toolchain support, run \"build_all.sh\" passing\n\"gnu\" on the command-line:\n\n$ MLCA_PATH=\u003cPath to built mlca repo\u003e ./build_all.sh gnuv3\n\nAIX: Building the project with v1 container support\n--------------------\n\n$ ./build_all.sh aixv3\n\nAIX: Building the project with v3 container support\n--------------------\n\nTo support v3 containers you will need to build the mlca library with\nmldsa-87 support.\n\nThis library can be found at : https://github.com/IBM/mlca/\n\n$ MLCA_PATH=\u003cPath to built mlca repo\u003e ./build_all.sh aixv3\n\n\nInstalling the project\n--------------------\nTo install the project (executable files) locally, after running the\npreferred build method above:\n\n$ make install\n\nTo uninstall:\n\n$ make uninstall\n\nThe files install to /usr/local/bin by default.  You must have write\npermission to this directory.  To install to a different directory:\n\n$ make install bindir=/preferred/install/path/\n$ make uninstall bindir=/preferred/install/path/\n\nSigning HOWTO\n-------------\n\nThis HOWTO signs a single payload (i.e. the contents of a single\nPNOR partition). You will need to repeat these steps for each signed bit\nof firmware. This may be several FFS partitions in a PNOR image, or\nseveral files (depending on platform).\n\nSigning with local keys\n-----------------------\n\nThe included shell script \"sign-with-local-keys.sh\" demonstrates the\ncontainer build operation. First, the program builds enough of the\ncontainer to create the prefix and software headers, and dumps them to\nthe specified files:\n\n$ ./create-container -a hw_key_a.key -b hw_key_b.key -c hw_key_c.key \\\n                     -p sw_key_a.key \\\n                      --payload image.bin --imagefile container.out \\\n                      --dumpPrefixHdr prefix_hdr --dumpSwHdr software_hdr\n\nwhere the *.key files contain the public keys in PEM format, the payload\nis the firmware image to be protected by this container, the output file\nis the completed container and the prefix_hdr and software_hdr files\ncontain the dump of the blobs to-be-signed.\n\n(Actually, the .key files may contain either the public key or the\nprivate key. Only the public key is required at this step, since this is\nnot a signing operation. The program only needs to extract the public key\nto add it to the container, and it can do so with either the public key\nor private key as input.)\n\nThe script reuses HW key A as SW key P, as a shortcut. Normally the\nhardware and firmware keys would be different. Also, the script only uses\none software key. The use of 1-3 software keys is supported by secure\nboot. However, for every software public key provided in the container\nheader, a corresponding signature must be present. In the case of the\nhardware keys, all three keys must be used (although the user may choose\nto use the same key thrice.)\n\nNext, the prefix and software headers are signed by the hardware and\nsoftware keys, respectively. These may be done with simple openssl\noperations:\n\n$ openssl dgst -SHA512 -sign hw_key_a.key prefix_hdr \u003e hw_key_a.sig\n$ openssl dgst -SHA512 -sign hw_key_b.key prefix_hdr \u003e hw_key_b.sig\n$ openssl dgst -SHA512 -sign hw_key_c.key prefix_hdr \u003e hw_key_c.sig\n\n$ openssl dgst -SHA512 -sign sw_key_a.key software_hdr \u003e sw_key_p.sig\n\nIn this case the .key files *must* be the private keys. The .sig files are\nthe resulting signatures in DER format. (The prefix_hdr and software_hdr\nfiles have now been consumed and may be discarded.)\n\nFinally, create-container is run one more time to add the signatures and\ncomplete the container:\n\n$ ./create-container -a hw_key_a.key -b hw_key_b.key -c hw_key_c.key \\\n                     -p sw_key_a.key \\\n                     -A hw_key_a.sig -B hw_key_b.sig -C hw_key_c.sig \\\n                     -P sw_key_p.sig \\\n                      --payload image.bin --imagefile container.out\n\nAll input files have the same meaning as on the first pass: the *.key\nfiles may be the public or private key in PEM format. The .sig files are\nthe signatures in DER format.\n\nYou now have a completed container that will secure boot on OpenPOWER\n(assuming the HW public keys match that stored in the CPU SEEPROM).\n\nSigning securely with protected private keys\n--------------------------------------------\n\nThe local signing method is secure only if the system on which the\ncontainer is built is secure. Bear in mind that the private keys will be\nexposed on the local system while the container header is built.\n\nIf the build system is not secure it may be desirable to perform the\nsigning operation in a separate environment. In this case the prefix and\nsoftware headers may be transferred to this environment (or environments,\nas separation of duties dictates), signed, and resulting signatures\nreturned to the build environment. It is not necessary to expose the\nprivate keys to the build environment.\n\nIn all cases, those doing the signing should **verify** the legitimacy of\nwhat they are about to sign, and perform the signing in a secure, trusted\nenvironment in which it safe to expose the unencrypted private keys.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopen-power%2Fsb-signing-utils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopen-power%2Fsb-signing-utils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopen-power%2Fsb-signing-utils/lists"}