commit 1b3e5944491c315ca99b832bc3afdb6a19d81430 Author: Lans Zhang Date: Thu Jun 22 15:22:01 2017 +0800 meta-secure-core: initial commit Signed-off-by: Lans Zhang diff --git a/COPYING.MIT b/COPYING.MIT new file mode 100644 index 0000000..89de354 --- /dev/null +++ b/COPYING.MIT @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/MAINTAINERS b/MAINTAINERS new file mode 100644 index 0000000..db348c9 --- /dev/null +++ b/MAINTAINERS @@ -0,0 +1 @@ +Jia Zhang diff --git a/README b/README new file mode 100644 index 0000000..afbf854 --- /dev/null +++ b/README @@ -0,0 +1,60 @@ +This README file contains information on the contents of the +meta-secure-core layer. + +Please see the corresponding sections below for details. + + +Dependencies +============ + +This layer depends on: + + URI: git://git.openembedded.org/bitbake + branch: master + + URI: git://git.openembedded.org/openembedded-core + layers: meta + branch: master + + +Patches +======= + +Please submit any patches against the meta-secure-core layer to the +maintainer: + +Maintainer: Jia Zhang + + +Table of Contents +================= + + I. Adding the meta-secure-core layer to your build + II. Misc + + +I. Adding the meta-secure-core layer to your build +================================================= + +--- replace with specific instructions for the meta-secure-core layer --- + +In order to use this layer, you need to make the build system aware of +it. + +Assuming the meta-secure-core layer exists at the top-level of your +yocto build tree, you can add it to the build system by adding the +location of the meta-secure-core layer to bblayers.conf, along with any +other layers needed. e.g.: + + BBLAYERS ?= " \ + /path/to/yocto/meta \ + /path/to/yocto/meta-poky \ + /path/to/yocto/meta-yocto-bsp \ + /path/to/yocto/meta-meta-secure-core \ + " + + +II. Misc +======== + +--- replace with specific information about the meta-secure-core layer --- diff --git a/README.md b/README.md new file mode 100644 index 0000000..8cc9f32 --- /dev/null +++ b/README.md @@ -0,0 +1,95 @@ +### meta-secure-env +This layer provides the following common and platform-specific security +features: + +#### UEFI Secure Boot +For x86 platform, UEFI secure boot is the industry standard defined in the +UEFI spec, allowing images loaded by UEFI BIOS to be verified with the trusted +key. Whenever this feature is enabled, the bootloader and kernel will be +signed automatically during the build, implying the signed binaries are +contained by the resulting RPM and rootfs image. + +Refer to [meta-efi-secure-boot](https://github.com/jiazhang0/meta-efi-secure-boot/blob/master/README.md) for more details. + +#### MOK Secure Boot +For x86 platform, MOK secure boot is based on the UEFI secure boot, adding +the shim loader to chainloader the second-stage bootloader. Meanwhile, +the shim will also install a protocol which permits the second-stage bootloader +to perform similar binary validation, e.g, for linux kernel. + +Refer to [meta-efi-secure-boot](https://github.com/jiazhang0/meta-efi-secure-boot/blob/master/README.md) for more details. + +#### User key store +By default, the signing key used by UEFI/MOK secure boot is the sample key for +the purposes of development and demonstration. It is not recommended that +this sample key be used for a production device and should be replaced by +a secret key owned by the user. + +Refer to [meta-signing-key](https://github.com/jiazhang0/meta-signing-key/blob/master/README.md) +for more details about how to construct an user key store. + +#### TPM 1.x +This feature enables Trusted Platform Module 1.x support, including +kernel option changes to enable tpm drivers, and picking up TPM 1.x packages. + +Refer to [meta-tpm](https://github.com/jiazhang0/meta-tpm/blob/master/README.md) +for more details. + +#### TPM 2.0 +This feature enables Trusted Platform Module 2.0 support, including +kernel option changes to enable tpm drivers, and picking up TPM 2.0 packages. + +Trusted Platform Module (TPM 2.0) is a microcontroller that stores keys, +passwords, and digital certificates. A discrete TPM 2.0 offers the +capabilities as part of the overall platform security requirements. + +Refer to [meta-tpm2](https://github.com/jiazhang0/meta-tpm2/blob/master/README.md) +for more details. + +#### Encrypted storage +This feature gives 2 types of granularity for storage encryption. Data volume +encryption allows the user to create encryption partition with a passphrase +typed by the end user. Root filesystem encryption enables the data encryption on +the entire rootfs except the boot partition. + +Both types of storage encryption are based on device-mapper crypt target, +which provides transparent encryption of block devices using the kernel crypto +API. Additionally, the utility cryptsetup is used to conveniently setup disk +encryption based on device-mapper crypt target. + +Refer to [meta-encrypted-storage](https://github.com/jiazhang0/meta-encrypted-storage/blob/master/README.md) for more details. + +#### Integrity +The Linux IMA subsystem introduces hooks within the Linux kernel to support +measuring the integrity of files that are loaded (including application code) +before it is executed or mmap()ed to memory. The measured value (hash) is then +registered in a log that can be consulted by administrators. + +To support proven integrity of the files, the IMA subsystem can interact with +the TPM chip within the system to protect the registered hashes from tampering +by a rogue administrator or application. The IMA subsystem, as already +supported by the Linux kernel, supports reporting on the hashes of files and +commands ran by privileged accounts (and more if you create your own +measurement policies). + +In addition, IMA appraisal can even register the measured value as an extended +attribute, and after subsequent measurement(s) validate this extended attribute +against the measured value and refuse to load the file (or execute the +application) if the hash does not match. In that case, the IMA subsystem allows +files and applications to be loaded if the hashes match (and will save the +updated hash if the file is modified) but refuse to load it if it doesn't. This +provides some protection against offline tampering of the files. + +Refer to [meta-integrity](https://github.com/jiazhang0/meta-efi-secure-boot/blob/master/README.md) +for more details. + +#### RPM signing +This feature provides the integrity verification for the RPM5 package. + +Refer to [meta-rpm-signing](https://github.com/jiazhang0/meta-rpm-signing/blob/master/README.md) +for more details. + + +### Building the meta-secure-env layer +This layer should be added to the bblayers.conf file. To enable certain +feature provided by this layer, add the feature to the local.conf file. diff --git a/meta-efi-secure-boot/README.md b/meta-efi-secure-boot/README.md new file mode 100644 index 0000000..6f32e7c --- /dev/null +++ b/meta-efi-secure-boot/README.md @@ -0,0 +1,463 @@ +### EFI secure boot feature +This feature consists of two widely used secure boot technologies: UEFI Secure +Boot and MOK Secure Boot. + +- UEFI Secure Boot is the industry standard defined in the UEFI spec, allowing the +images loaded by UEFI BIOS to be verified with the certificates corresponding to +the trusted keys. +- MOK (Machine Owner Key) Secure Boot is based on UEFI Secure Boot, adding +the shim bootloader to chainloader the next stage bootloader with the integrity +check using the shim-managed certificates corresponding to another set of +trusted keys which may be different than the trusted keys used by UEFI Secure +Boot. + +In addition, this feature introduces the SELoader as the second-stage bootloader +and eventually chainliader to the third-stage bootloader "grub". With the +extension provided by SELoader, grub configuration files, kernel (even without +EFI stub support) and initrd can be authenticated. This capability is not +available in the shim bootloader. + +Grub bootloader is enhanced to support lockdown mode. In this mode, the +edit, rescue and command line are protected in order to prevent from +tampering the kernel commandline or loading an unsigned boot component. Hence, +this lockdown protection can effectively defeat the attempts to disable the +kernel security mechanisms. The flexibility is also provided if the user +authentication is enabled. The user authenticated by a password check can enter +into edit and command line. + +Therefore, using UEFI Secure Boot, SELoader, and grub lockdown together, the +boot process is completely trustworthy. + +A complete boot flow with this feature is: + +- UEFI BIOS boot manager (UEFI Secure Boot enabled) -> + - shim (verified by a DB certificate) -> + - SELoader (verified by a shim-managed certificate) -> + - grub (verified by a shim-managed certificate) -> + - grub.cfg (verified by a shim-managed certificate) + - kernel (verified by a shim-managed certificate) + - initramfs (verified by a shim-managed certificate) + +### Quick start for the first boot +- Deploy the rootfs + +- Boot up the target board + +- Enter to BIOS setup and remove the enrolled certificates + * It is recommended to still turn on UEFI Secure Boot option if allowed. + +- Exit BIOS setup and automatically reboot + +- Manually launch a reboot via ctrl + alt + del again + * Otherwise, a misleading error message about the verification failure + will be displayed. + +- Automatically boot to the boot option "Automatic Certificate Provision" in + grub boot menu. + +- (Optional) Enter into BIOS setup to turn on UEFI Secure Boot option + +- Boot to the system with the protection provided by UEFI and MOK Secure Boot + +### Key Management +Refer to meta-signing-key/README.md for the initial cognition about key +management for UEFI Secure Boot. + +Note that the sample key and user key are the concepts in the key signing +model according to the ownership and secrecy. In UEFI Secure Boot, a policy +object such as PK, KEK, DB and DBX is mapped to a key managed by the key +signing model. + +#### Sample Keys +This feature, by default, use **the sample keys** to sign and verify images for +the purpose of development and demonstration. **Please ensure you know what your +risk is to use the sample keys in your product, because they are completely +public.** + +The sample keys used for UEFI Secure Boot are centrally placed under +meta-signing-key/files/uefi_sb_keys/. + +- PK.pem + The X509 certificate enrolled to UEFI BIOS, used to update/delete PK/KEK. + +- PK.key + The private key corresponding to PK.pem, used to sign the EFI signature + list for PK/KEK enrollment. + +- KEK.pem + The X509 certificate enrolled to UEFI BIOS, used to update/delete + DB/DBX. + +- KEK.key + The private key corresponding to KEK.pem, used to sign the EFI signature + list for DB/DBX enrollment. + +- DB.pem + The X509 certificate enrolled to UEFI BIOS, used to verify the images + directly loaded by UEFI BIOS. + +- DB.key + The private key corresponding to DB.pem, used to sign the images directly + loaded by UEFI BIOS. + +- DBX + This directory contains any number of X509 certificate enrolled to UEFI + BIOS, used to blacklist the revoked certificates. The revoked certificates + must be PEM-formatted. + +The sample keys used for MOK Secure Boot are centrally placed under +`meta-signing-key/files/mok_sb_keys/`. + +- shim_cert.pem + The X509 certificate embedded in shim, used to verify the images either + directly or indirectly loaded by shim. + +- shim_cert.key + The private key corresponding to shim_cert.pem, used to sign the images + either directly or indirectly loaded by shim. + +- vendor_cert.pem + Used in the same way as shim_cert.pem. In addition, vendor certificate + is the switch to enable shim verification protocol, which facilitates + the verification for the SELoader. + +- vendor_cert.key + The private key corresponding to vendor_cert.pem, Same fuction as + shim_cert.key. + +- vendor_dbx + This directory contains any number of X509 certificate embedded in shim, + used to blacklist the revoked certificates. + +#### User Keys +Refer to meta-signing-key/README.md for the details about how to generate/use +the keys owned by the end user. + +#### Automatic Certificate Provision +The certificate provision is required to enable UEFI Secure Boot. By default, +the target may be provisioned with the default certificates enrolled during the +manufacture. + +In order to use the bootloader and kernel signed by the sample or self-owned +key to boot up the system, this feature provides a process of autmatic +certificate provison for the convenience. Refer to the instructions listed in +the section "Work Flow For The First Boot". The detailed descriptions are +given below. + +##### Remove the enrolled certificates in BIOS setup +The LockDown.efi application is used to run the provision. However, +LockDown.efi cannot be launched if UEFI Secure Boot is already enabled. In +addition, the enrolled certificates may be not the ones the user hopes to use. + +The provisioned certificates can be removed in BIOS setup. The detailed steps +may vary between the boards. Refer to BIOS manual for the details. + +##### Launch the automatic provision +Lockdown.efi will automatically provision UEFI Secure Boot after removing the +the provisioned certificates in BIOS setup. More specifically, the PK, KEK, +DB and DBX (if any) will be enrolled and begin to take affect after a reboot. + +##### Turn on UEFI Secure Boot option +If UEFI Secure Boot option is turned off, the user has to enter into BIOS setup +after provision to manually turn on the option. + +If the option is already enabled when removing the enrolled certificates in +BIOS setup, this step can be ignored. + +##### Re-trigger automatic provision +By default, the "Automatic Certificate Provision" option is hidden in boot +menu for the first boot. If the user would like to clear the certificates +provisioned by the "Automatic Certificate Provision" option in BIOS setup, this +hidden boot option will be shown in boot menu, allowing to re-trigger it when +necessary. + +### Signing +By default, the build system uses DB.key to sign shim, and uses vendor_cert.key +to sign SELoader, grub, grub configuration file, kernel and initramfs image +during the build. + +### Verficiation + +#### UEFI Secure Boot Verification +UEFI BIOS will validate the integrity of shim bootloader with a certificate in +DB before running it. + +#### Bootloader Verification +When the shim loads SELoader and SELoader loads grub, if both UEFI Secure Boot +and MOK Secure Boot are already enabled, the upper bootloader uses a list of +certificate to check the integrity of lower bootloader. + +- Blacklist check + If the lower bootloader is signed with a key corresponding to a certificate + within any of a policy object below, the boot failure will occur. + + * Vendor DBX + * DBX + * MokListX (MOK certificate blacklist) + +- Whitelist check + If the lower bootloader is signed with a key corresponding to a certificate + within any of a policy object below, the boot success will occur. + + * DB + * MokList (MOK certificate whitelist) + * Shim certificate (only for PE image) + * Vendor certificate + +If the lower bootloader is not signed or signed by a key not corresponding to +any policy objects mentioned above, the boot failure will occur. + +The benefit of these behaviors allow the end user to regulate the secure boot +even without the ownership of DB on Microsoft certificated hardware. + +##### SELoader Verification +The SELoader is designed to authenticate the non-PE files, such as grub.cfg, +kernel (without EFI stub support) and initrd, which cannot be verified by +the verification protocol registered by the shim loader. + +In order to conveniently authenticate the PE file with gBS->LoadImage() +and gBS->StartImage(), the SELoader hooks EFI Security2 Architectural +Protocol and employs verification protocol provided by the shim loader to +verify the PE file. If only UEFI Secure Boot is enabled, the SELoader just +simplily calls gBS->LoadImage() and gBS->StartImage() to allow UEFI BIOS +to verify the PE file. + +The SELoader publishes MOK2 verification protocol which provides a flexible +interface to allow the bootloader to verify the file, file buffer or +memory buffer without knowing the file format. + +In order to establish the chain of trust, the SELoader is required to be +signed by a private key corresponding to a DB certificate, the shim +certificate, the vendor certificate or a MOK certificate. The specific +key is determined by the secure boot scheme you will use. + +See more details about the SELoader in its README file. + +#### Grub Configuration File Verification +Grub can call the MOK2 verification protocol registered by the SELoader +to validate the integrity of grub configuration file before parsing it. + +This protection prevents from tampering the grub configuration file from +disabling certains kernel security mechanism such as selinux, IMA and so on. + +#### Kernel Verification +When SELoader loads the kernel image with the linux command, if both UEFI +Secure Boot and MOK Secure Boot are already enabled, grub will call the +verification protocol installed by SELoader to validate the kernel image. + +Alternately, if grub loads the kernel image with the chainloader command, +if both UEFI Secure Boot and MOK Secure Boot are already enabled, grub will +call the verification protocol installed by shim to validate the kernel image. + +By default, the kernel image is signed by vendor certificate and then signed +again to generate the .p7b signature file. + +#### Initramfs Verification +When SELoader loads the kernel image with the initrd command, if both UEFI +Secure Boot and MOK Secure Boot are already enabled, grub will call the +verification protocol installed by SELoader to validate the initramfs image. + +#### Verification Failure +Either situation will cause a failure of verification. +- A boot component is not signed. +- A boot component is signed by a key which doesn't correspond to any + certificate in whitelists such as DB and shim-managed certificates. +- A boot component is signed by a key which corresponds to a certificate in + blacklist such as DBX and shim-managed certificates in MOKX. + +Each boot component may have different verification failure phenomenon. +- If SELoader fails signature check, UEFI BIOS boot manager will print an error + message about the image authentication failure. +- If grub fails signature check, an image authentication failure message is + printed and the system hangs. +- If a grub configuration file fails the signature check, an authentication + failure message is printed and grub hangs. +- If kernel image fails signature check, grub returns back to the boot menu. +- If initrd fails signature check, grub returns back to the boot menu. + +### MOK Secure Boot and the shim bootloader +MOK (Machine Owner Key) Secure Boot is based on UEFI Secure Boot, adding +the shim bootloader to chainloader the second-stage bootloader +"SELoader" and eventually chainliader to the third-stage bootloader "grub". + +[ Quoting: https://github.com/rhinstaller/shim ] +shim is a trivial EFI application that, when run, attempts to open and +execute another application. It will initially attempt to do this via the +standard EFI LoadImage() and StartImage() calls. If these fail (because secure +boot is enabled and the binary is not signed with an appropriate key, for +instance) it will then validate the binary against a built-in certificate. If +this succeeds and if the binary or signing key are not blacklisted then shim +will relocate and execute the binary. + +shim will also install a protocol which permits the second-stage bootloader +to perform similar binary validation. This protocol has a GUID as described +in the shim.h header file and provides a single entry point. On 64-bit systems +this entry point expects to be called with SysV ABI rather than MSABI, and +so calls to it should not be wrapped. +[ End of Quote ] + +In most cases, the hardware coming out of the factory is already provisioned +with a default certificate used to verify the bootloader and issued by +Microsoft Corporation UEFI CA 2011. This kind of hardware is so-called +Microsoft certificated hardware. + +Obviously, this requirement needs a bootloader loaded by BIOS must be signed +by Microsoft. Microsoft provides the signing service (not free), but only +accept shim bootloader for Linux world. Refer to [Microsoft's signing policy](http://blogs.msdn.com/b/windows_hardware_certification/archive/2013/12/03/microsoft-uefi-ca-signing-policy-updates.aspx). + +It is allowed to remove all default certificates and use the self-owned keys to +provision UEFI Secure Boot, but this is not practical for ODM/OEM devices +during the manufacture phrase. See the section "Out-of-box Experience". + +For a good user experience, shim + SELoader + grub is an excellent combination +to handle Microsoft certificated hardware. With this model, SELoader and grub +are signed by a shim-managed certificate without being subject to the limit from +Microsoft's signing policy, and the manual provision is thus unnecessary. + +#### mokutil and MOK Manager +mokutil is a tool to import or delete the machines owner keys stored in the +database of shim. mokutil creates the requests and MOK manager will be +automatically launched by shim as long as it detects the pending requests. +The physical present user will be prompted to run the operations corresponding +to the requests. Note the operation is required to be authenticated by MOK +management password set by mokutil. + +Refer to mokutil man page for the detailed usages. + +##### MOK Management Password +MOK management password is the authentication information to allow MOK manager +to grant the request regarding of MOK management. To set the password, run +mokutil with the option --password. In addition, there are 4 input methods to +provide the password. By default, mokutil prompts the user to input the +password and then wraps the password to sha256 password hash. For other 3 +methods, refer to the uses of option --hash-file, --root-pw and --simple-hash. + +##### Enroll the MOK certificate +Here is an example showing how to enroll a DER formatted X509 certificate to +the database of shim. +``` +# mokutil --import +``` +where `` is the MOK certificate corresponding to the private key used +to sign either grub or kernel. + +To convert a PEM, for exmaple, the shim_cert.pem, to a DER formatted X509 +certificate, type the command: +``` +$ openssl x509 -in shim_cert.pem -inform PEM -out shim_cert.cer -outform DER +``` + +##### List the enrollment requests +The several enrollment requests can be submitted before system reboot. Run the +following command to check all enrollment requests. +``` +# mokutil --list-new +``` + +##### Revoke the enrollment requests +Note the revocation operation will remove all enrollment requests. +``` +# mokutil --revoke-import +``` + +##### Test the MOK certificate +If you cannot confirm whether a certificate has been enrolled or not, type the +following command for a check: +``` +# mokutil --test-key +``` + +##### Delete the MOK certificate +Removing an useless MOK certificate is also supported. +``` +# mokutil --delete +``` +Refer to the options --list-delete and --revoke-delete to list and revoke the +MOKs. + +##### Reset MOK certificates +This request will clear all enrolled MOK certificates. +``` +# mokutil --reset +``` + +##### Disable/Enable MOK Secure Boot +MOK Secure Boot can be enabled or disabled regardless of the setting of UEFI +Secure Boot. +``` +# mokutil --disable-validation // disable MOK Secure Boot +# mokutil --enable-validation // enable MOK Secure Boot +``` + +Note that MOK Secure Boot is based on UEFI Secure Boot. If UEFI Secure Boot +is disabled, MOK Secure Boot will be automatically inactive. Type the +following command to check the status of UEFI Secure Boot. +``` +# mokutil --sb-state +``` + +##### Other options +Refer to the options --import-hash and --delete-hash to manage hash-based +signature. The options --pk, --kek, --db and --dbx are useful to check +the content of the policy objects used in UEFI Secure Boot. + +##### Manage blacklist +All above mentioned are talking MOK which is acting as whitelist to +authenticate the verified image to launch. Actually, there is a contrary +policy object called MOKX, acting as blacklist to deny the untrusted +image to launch. Also, MOKX as blacklist is handled by shim prior to MOK +as whitelist. + +For the management of blacklist, add the option --mokx with the following +options to change the operation target from MOK to the following options. + +--list-enrolled +--test-key +--list-new +--list-delete +--import +--delete +--import-hash +--delete-hash +--reset +--revoke-import +--revoke-delete + +##### Handle MOK Secure Boot Failure with MOK Manager +If either grub or SELoader is not signed or signed with an unauthorized +certificate, the shim will prompt the end user a UI called MOK manager to +guide the user to enroll the certificate or hash of the image. + +The policy of the selection between digest and certificate for next step is +decided by whether the unauthorized grub or SELoader is signed or not. + +If the grub or SELoader is not signed at all, you have to always select +the calculation of the digest based on the file. Note that once grub or SELoader +is updated and its digest is changed, you have to relaunch the MOK manager +to enroll the new digests. + +If the grub or SELoader is signed by an unauthorized certificate, enrolling the +signing certificate is the preferred way. Copy the certificate to the boot +drive and then select the certificate in MOK manager. Note that the +certificate for the selection must be **DER formatted**. + +If doing so, the unauthorized grub or SELoader will be verified successfully +after exiting MOK Manager. + +### Grub Lockdown +In order to prevent from tampering the kernel command line or loading an +unsigned boot component, grub is locked if UEFI Secure Boot is enabled. In this +situation, the end user cannot enter into command or edit line via pressing 'c' +and 'e'. + +If the user authentication is enabled, the access to command or edit line is +protected by a password. In this situation, grub is unlockable. + +Rescue mode is always disabled as long as UEFI Secure Boot is enabled. + +### Known Issues +- The 32-bit MOK Secure Boot is not validated. In other words, loading 32-bit +shim, MOK manager, grub and kernel is not supported. + +### Reference +[OpenEmbedded layer for EFI secure boot features](https://github.com/jiazhang0/meta-efi-secure-boot) diff --git a/meta-efi-secure-boot/conf/layer.conf b/meta-efi-secure-boot/conf/layer.conf new file mode 100644 index 0000000..f453a5c --- /dev/null +++ b/meta-efi-secure-boot/conf/layer.conf @@ -0,0 +1,16 @@ +# We have a conf and classes directory, add to BBPATH +BBPATH .= ":${LAYERDIR}" + +# We have recipes-* directories, add to BBFILES +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ + ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "efi-secure-boot" +BBFILE_PATTERN_efi-secure-boot = "^${LAYERDIR}/" +BBFILE_PRIORITY_efi-secure-boot = "10" + +LAYERDEPENDS_efi-secure-boot = "\ + core \ + openembedded-layer \ + signing-key \ +" diff --git a/meta-efi-secure-boot/recipes-base/packagegroups/packagegroup-efi-secure-boot.bb b/meta-efi-secure-boot/recipes-base/packagegroups/packagegroup-efi-secure-boot.bb new file mode 100644 index 0000000..a2b35b1 --- /dev/null +++ b/meta-efi-secure-boot/recipes-base/packagegroups/packagegroup-efi-secure-boot.bb @@ -0,0 +1,28 @@ +DESCRIPTION = "EFI Secure Boot packages for secure-environment." +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \ + file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +S = "${WORKDIR}" + +ALLOW_EMPTY_${PN} = "1" + +pkgs = " \ + grub-efi \ + efitools \ + efibootmgr \ + mokutil \ + seloader \ + shim \ +" + +RDEPENDS_${PN}_x86 = "${pkgs}" +RDEPENDS_${PN}_x86-64 = "${pkgs}" + +kmods = " \ + kernel-module-efivarfs \ + kernel-module-efivars \ +" + +RRECOMMENDS_${PN}_x86 += "${kmods}" +RRECOMMENDS_${PN}_x86-64 += "${kmods}" diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools-native_git.bb b/meta-efi-secure-boot/recipes-bsp/efitools/efitools-native_git.bb new file mode 100644 index 0000000..890abcf --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools-native_git.bb @@ -0,0 +1,11 @@ +require efitools.inc + +inherit native + +DEPENDS_append = " gnu-efi-native" + +EXTRA_OEMAKE_append = " \ + INCDIR_PREFIX='${STAGING_DIR_NATIVE}' \ + CRTPATH_PREFIX='${STAGING_DIR_NATIVE}' \ + EXTRA_LDFLAGS='-Wl,-rpath,${libdir}' \ +" diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools.inc b/meta-efi-secure-boot/recipes-bsp/efitools/efitools.inc new file mode 100644 index 0000000..9a9888c --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools.inc @@ -0,0 +1,63 @@ +SUMMARY = "Tools to support reading and manipulating the UEFI signature database" +DESCRIPTION = "\ +From the EFI Tools package in the Linux user-space, it's now possible \ +to read and manipulate the UEFI signatures database via the new \ +efi-readvar and efi-updatevar commands. Aside from needing efitools \ +1.4, the EFIVARFS file-system is also needed, which was only introduced \ +in the Linux 3.8 kernel. \ +" + +LICENSE = "GPLv2" +LIC_FILES_CHKSUM = "file://COPYING;md5=e28f66b16cb46be47b20a4cdfe6e99a1" + +SRC_URI = " \ + git://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git \ + file://Fix-for-the-cross-compilation.patch \ + file://Kill-all-the-build-warning-caused-by-implicit-declar.patch \ + file://Fix-the-wrong-dependency-for-blacklist.esl.patch \ + file://LockDown-run-system-warm-reset-after-the-key-provisi.patch \ + file://Allow-to-override-tools-for-target-build.patch \ + file://Fix-help2man-failure.patch \ + file://Don-t-build-PreLoader.efi.patch \ + file://Reuse-xxdi.pl.patch \ + file://Add-static-keyword-for-IsValidVariableHeader.patch \ +" + +SRCREV = "0649468475d20d8ca5634433c4912467cef3ce93" +PV = "1.7.0+git${SRCPV}" + +PARALLEL_MAKE = "" + +inherit perlnative + +DEPENDS_append += "\ + help2man-native openssl-native sbsigntool-native \ + libfile-slurp-perl-native \ +" + +S = "${WORKDIR}/git" + +EXTRA_OEMAKE = " \ + HELP2MAN='${STAGING_BINDIR_NATIVE}/help2man' \ + OPENSSL='${STAGING_BINDIR_NATIVE}/openssl' \ + SBSIGN='${STAGING_BINDIR_NATIVE}/sbsign' \ + OPENSSL_LIB='${STAGING_LIBDIR}' \ + NM='${NM}' AR='${AR}' \ +" +EXTRA_OEMAKE_append_x86 += " ARCH=ia32" +EXTRA_OEMAKE_append_x86-64 += " ARCH=x86_64" + +# LDFLAGS is used by LD not CC, so remove '-Wl,' +LDFLAGS := "${@oe_filter_out('-Wl,', '${LDFLAGS}', d)}" +BUILD_LDFLAGS := "${@oe_filter_out('-Wl,', '${BUILD_LDFLAGS}', d)}" + +do_compile_prepend() { + sed -i -e "1s:#!.*:#!/usr/bin/env nativeperl:" xxdi.pl +} + +EFI_BOOT_PATH = "/boot/efi/EFI/BOOT" +FILES_${PN} += "${EFI_BOOT_PATH}" + +do_install() { + oe_runmake install DESTDIR='${D}${base_prefix}' +} diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Add-static-keyword-for-IsValidVariableHeader.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Add-static-keyword-for-IsValidVariableHeader.patch new file mode 100644 index 0000000..f0b8246 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Add-static-keyword-for-IsValidVariableHeader.patch @@ -0,0 +1,38 @@ +From 960a5fc7c58c875827797b6f4afed2684acc2cde Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Sun, 12 Jun 2016 13:45:54 +0800 +Subject: [PATCH] Add static keyword for IsValidVariableHeader() + +Upstream-Status: Pending + +GCC does not inline any functions when not optimizing (-O0 specified) unless +you specify "always_inline" attribute for the function. + +By default, GCC complies with C89 standard for c code, which means +"inline" equals to "extern inline" and thus the definition is used only for +inlining with the assembly code actually generated. + +Therefore, "static inline" is used for both purposes. If -O0 is specified, +GCC will generate the assembly code as long as the function is referred. + +Signed-off-by: Lans Zhang +--- + include/variableformat.h | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/include/variableformat.h b/include/variableformat.h +index 32cde05..45d0ebb 100644 +--- a/include/variableformat.h ++++ b/include/variableformat.h +@@ -109,7 +109,7 @@ typedef struct { + + #pragma pack() + +-inline BOOLEAN ++static inline BOOLEAN + IsValidVariableHeader (VARIABLE_HEADER *vh) { + if (vh == NULL || vh->StartId != VARIABLE_DATA) + return FALSE; +-- +1.7.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Allow-to-override-tools-for-target-build.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Allow-to-override-tools-for-target-build.patch new file mode 100644 index 0000000..e326c3c --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Allow-to-override-tools-for-target-build.patch @@ -0,0 +1,94 @@ +From 1613bae3a9760b3cdcbf8f43e750c475d69ad8bb Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Wed, 23 Mar 2016 19:05:29 +0800 +Subject: [PATCH] Allow to override tools for target build + +Upstream-Status: Pending + +These tools should use the ones from native build. + +Signed-off-by: Lans Zhang +--- + Make.rules | 22 +++++++++++++--------- + Makefile | 4 ++-- + 2 files changed, 15 insertions(+), 11 deletions(-) + +diff --git a/Make.rules b/Make.rules +index 5e8cb82..4aa7650 100644 +--- a/Make.rules ++++ b/Make.rules +@@ -34,6 +34,10 @@ AR = ar + OPENSSL = openssl + SBSIGN = sbsign + XXD = xxd ++SIGN_EFI_SIG_LIST ?= ./sign-efi-sig-list ++CERT_TO_EFI_SIG_LIST ?= ./cert-to-efi-sig-list ++CERT_TO_EFI_HASH_LIST ?= ./cert-to-efi-hash-list ++HASH_TO_EFI_SIG_LIST ?= ./hash-to-efi-sig-list + MYGUID = 11111111-2222-3333-4444-123456789abc + INSTALL = install + BINDIR = $(DESTDIR)/usr/bin +@@ -75,34 +79,34 @@ endif + $(XXD) -i $< > $@ + + %.hash: %.efi hash-to-efi-sig-list +- ./hash-to-efi-sig-list $< $@ ++ $(HASH_TO_EFI_SIG_LIST) $< $@ + + %-blacklist.esl: %.crt cert-to-efi-sig-list +- ./cert-to-efi-sig-list $< $@ ++ $(CERT_TO_EFI_SIG_LIST) $< $@ + + %-hash-blacklist.esl: %.crt cert-to-efi-hash-list +- ./cert-to-efi-hash-list $< $@ ++ $(CERT_TO_EFI_HASH_LIST) $< $@ + + %.esl: %.crt cert-to-efi-sig-list +- ./cert-to-efi-sig-list -g $(MYGUID) $< $@ ++ $(CERT_TO_EFI_SIG_LIST) -g $(MYGUID) $< $@ + + getcert = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo "-c PK.crt -k PK.key"; else echo "-c KEK.crt -k KEK.key"; fi) + getvar = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo $(1); else echo db; fi) + + %.auth: %.esl PK.crt KEK.crt sign-efi-sig-list +- ./sign-efi-sig-list $(call getcert,$*) $(call getvar,$*) $< $@ ++ $(SIGN_EFI_SIG_LIST) $(call getcert,$*) $(call getvar,$*) $< $@ + + %-update.auth: %.esl PK.crt KEK.crt sign-efi-sig-list +- ./sign-efi-sig-list -a $(call getcert,$*) $(call getvar,$*) $< $@ ++ $(SIGN_EFI_SIG_LIST) -a $(call getcert,$*) $(call getvar,$*) $< $@ + + %-pkupdate.auth: %.esl PK.crt sign-efi-sig-list +- ./sign-efi-sig-list -a -c PK.crt -k PK.key $(call getvar,$*) $< $@ ++ $(SIGN_EFI_SIG_LIST) -a -c PK.crt -k PK.key $(call getvar,$*) $< $@ + + %-blacklist.auth: %-blacklist.esl KEK.crt sign-efi-sig-list +- ./sign-efi-sig-list -a -c KEK.crt -k KEK.key dbx $< $@ ++ $(SIGN_EFI_SIG_LIST) -a -c KEK.crt -k KEK.key dbx $< $@ + + %-pkblacklist.auth: %-blacklist.esl PK.crt sign-efi-sig-list +- ./sign-efi-sig-list -a -c PK.crt -k PK.key dbx $< $@ ++ $(SIGN_EFI_SIG_LIST) -a -c PK.crt -k PK.key dbx $< $@ + + %.o: %.c + $(CC) $(INCDIR) $(cflags) $(cppflags) -c $< -o $@ +diff --git a/Makefile b/Makefile +index 15fc944..c4e0081 100644 +--- a/Makefile ++++ b/Makefile +@@ -66,10 +66,10 @@ noPK.esl: + > noPK.esl + + noPK.auth: noPK.esl PK.crt sign-efi-sig-list +- ./sign-efi-sig-list -t "$(shell date --date='1 second' +'%Y-%m-%d %H:%M:%S')" -c PK.crt -k PK.key PK $< $@ ++ $(SIGN_EFI_SIG_LIST) -t "$(shell date --date='1 second' +'%Y-%m-%d %H:%M:%S')" -c PK.crt -k PK.key PK $< $@ + + ms-%.esl: ms-%.crt cert-to-efi-sig-list +- ./cert-to-efi-sig-list -g $(MSGUID) $< $@ ++ $(CERT_TO_EFI_SIG_LIST) -g $(MSGUID) $< $@ + + hashlist.h: HashTool.hash + cat $^ > /tmp/tmp.hash +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Build-DBX-by-default.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Build-DBX-by-default.patch new file mode 100644 index 0000000..9c20c7a --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Build-DBX-by-default.patch @@ -0,0 +1,44 @@ +From e909a2d4777a6fd2644ff89361539db141c0a67f Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Sat, 28 Jan 2017 13:42:28 +0800 +Subject: [PATCH] Build DBX by default + +Signed-off-by: Lans Zhang +--- + Makefile | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Makefile b/Makefile +index a1fc538..7f767c8 100644 +--- a/Makefile ++++ b/Makefile +@@ -26,7 +26,7 @@ include Make.rules + + EFISIGNED = $(patsubst %.efi,%-signed.efi,$(EFIFILES)) + +-all: $(EFIFILES) $(BINARIES) $(MANPAGES) noPK.auth $(KEYAUTH) \ ++all: $(EFIFILES) $(BINARIES) $(MANPAGES) noPK.auth $(KEYAUTH) DBX.auth \ + $(KEYUPDATEAUTH) $(KEYBLACKLISTAUTH) $(KEYHASHBLACKLISTAUTH) + + +@@ -49,7 +49,7 @@ lib/asn1/libasn1.a lib/asn1/libasn1-efi.a: FORCE + + .SUFFIXES: .crt + +-.KEEP: PK.crt KEK.crt DB.crt PK.key KEK.key DB.key PK.esl DB.esl KEK.esl \ ++.KEEP: PK.crt KEK.crt DB.crt DBX.crt PK.key KEK.key DB.key PK.esl DB.esl KEK.esl DBX.esl \ + $(EFIFILES) + + LockDown.o: PK.h KEK.h DB.h DBX.h +@@ -116,7 +116,7 @@ flash-var: flash-var.o lib/lib.a + $(CC) $(ARCH3264) -o $@ $< lib/lib.a + + clean: +- rm -f PK.* KEK.* DB.* $(EFIFILES) $(EFISIGNED) $(BINARIES) *.o *.so ++ rm -f PK.* KEK.* DB.* DBX.* $(EFIFILES) $(EFISIGNED) $(BINARIES) *.o *.so + rm -f noPK.* + rm -f doc/*.1 + $(MAKE) -C lib clean +-- +2.7.4 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Don-t-build-PreLoader.efi.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Don-t-build-PreLoader.efi.patch new file mode 100644 index 0000000..9874d71 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Don-t-build-PreLoader.efi.patch @@ -0,0 +1,40 @@ +From 95e167f432f1a6d8c96aeca73871122806007c9f Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Thu, 28 Apr 2016 11:21:33 +0800 +Subject: [PATCH] Don't build PreLoader.efi + +Upstream-Status: Pending + +The upstream has an obvious build failure: +| PreLoader.c:45:2: error: too few arguments to function 'security_policy_install' +| status = security_policy_install(); +| ^ +| In file included from PreLoader.c:14:0: +| /buildarea3/jzhang0/projects/wrl8/intel-x86-64-gwp-scp/bitbake_build/tmp/work/x86_64-linux/efitools-native/1.7.0+gitAUTOINC+20a8fdc4ec-r0/git/include/security_policy.h:4:1: note: declared here +| security_policy_install(BOOLEAN (*override)(void), POLICY_FUNCTION allow, POLICY_FUNCTION deny); +| ^ + +We are waiting for the upstream fix and remove this workaround in next +refresh. + +Signed-off-by: Lans Zhang +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index b3bb73a..da363a6 100644 +--- a/Makefile ++++ b/Makefile +@@ -5,7 +5,7 @@ BINARIES = cert-to-efi-sig-list sig-list-to-certs sign-efi-sig-list \ + flash-var + + ifeq ($(ARCH),x86_64) +-EFIFILES += PreLoader.efi ++#EFIFILES += PreLoader.efi + endif + + MSGUID = 77FA9ABD-0359-4D32-BD60-28F4E78F784B +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Fix-for-the-cross-compilation.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Fix-for-the-cross-compilation.patch new file mode 100644 index 0000000..75c64ae --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Fix-for-the-cross-compilation.patch @@ -0,0 +1,193 @@ +From ab2eb06c1271e46e07add5a0b0a444353d45e055 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Tue, 15 Mar 2016 21:28:33 +0800 +Subject: [PATCH] Fix for the cross compilation + +Upstream-Status: Pending + +Signed-off-by: Lans Zhang +--- + Make.rules | 52 +++++++++++++++++++++++++++++----------------------- + Makefile | 14 +++++++------- + 2 files changed, 36 insertions(+), 30 deletions(-) + +diff --git a/Make.rules b/Make.rules +index 88d5481..7e89332 100644 +--- a/Make.rules ++++ b/Make.rules +@@ -13,21 +13,27 @@ ARCH3264 = + else + $(error unknown architecture $(ARCH)) + endif +-INCDIR = -I$(TOPDIR)include/ -I/usr/include/efi -I/usr/include/efi/$(ARCH) -I/usr/include/efi/protocol +-CPPFLAGS = -DCONFIG_$(ARCH) +-CFLAGS = -O2 $(ARCH3264) -fpic -Wall -fshort-wchar -fno-strict-aliasing -fno-merge-constants -fno-stack-protector -ffreestanding -fno-stack-check +-LDFLAGS = -nostdlib ++INCDIR = -I$(TOPDIR)include/ -I$(INCDIR_PREFIX)/usr/include/efi -I$(INCDIR_PREFIX)/usr/include/efi/$(ARCH) -I$(INCDIR_PREFIX)/usr/include/efi/protocol ++cppflags = -DCONFIG_$(ARCH) ++cflags = -O2 $(ARCH3264) -fpic -Wall -fshort-wchar -fno-strict-aliasing -fno-merge-constants -fno-stack-protector -ffreestanding -fno-stack-check $(CFLAGS) ++ldflags = -nostdlib $(LDFLAGS) + CRTOBJ = crt0-efi-$(ARCH).o + CRTPATHS = /lib /lib64 /lib/efi /lib64/efi /usr/lib /usr/lib64 /usr/lib/efi /usr/lib64/efi +-CRTPATH = $(shell for f in $(CRTPATHS); do if [ -e $$f/$(CRTOBJ) ]; then echo $$f; break; fi; done) ++CRTPATH = $(shell for f in $(CRTPATHS); do if [ -e $(CRTPATH_PREFIX)/$$f/$(CRTOBJ) ]; then echo $(CRTPATH_PREFIX)/$$f; break; fi; done) + CRTOBJS = $(CRTPATH)/$(CRTOBJ) + # there's a bug in the gnu tools ... the .reloc section has to be + # aligned otherwise the file alignment gets screwed up + LDSCRIPT = elf_$(ARCH)_efi.lds +-LDFLAGS += -shared -Bsymbolic $(CRTOBJS) -L $(CRTPATH) -T $(LDSCRIPT) ++ldflags += -shared -Bsymbolic $(CRTOBJS) -L $(CRTPATH) -T $(LDSCRIPT) ++ldflags_openssl = $(addprefix -L$(CRTPATH_PREFIX),$(CRTPATHS)) + LOADLIBES = -lefi -lgnuefi $(shell $(CC) $(ARCH3264) -print-libgcc-file-name) + FORMAT = --target=efi-app-$(ARCH) + OBJCOPY = objcopy ++NM = nm ++AR = ar ++OPENSSL = openssl ++SBSIGN = sbsign ++XXD = xxd + MYGUID = 11111111-2222-3333-4444-123456789abc + INSTALL = install + BINDIR = $(DESTDIR)/usr/bin +@@ -36,23 +42,23 @@ EFIDIR = $(DESTDIR)/usr/share/efitools/efi + DOCDIR = $(DESTDIR)/usr/share/efitools + + # globally use EFI calling conventions (requires gcc >= 4.7) +-CFLAGS += -DGNU_EFI_USE_MS_ABI ++cflags += -DGNU_EFI_USE_MS_ABI + + ifeq ($(ARCH),x86_64) +- CFLAGS += -DEFI_FUNCTION_WRAPPER -mno-red-zone ++ cflags += -DEFI_FUNCTION_WRAPPER -mno-red-zone + endif + + ifeq ($(ARCH),ia32) +- CFLAGS += -mno-red-zone ++ cflags += -mno-red-zone + endif + + ifeq ($(ARCH),arm) +- LDFLAGS += --defsym=EFI_SUBSYSTEM=0x0a ++ ldflags += --defsym=EFI_SUBSYSTEM=0x0a + FORMAT = -O binary + endif + + ifeq ($(ARCH),aarch64) +- LDFLAGS += --defsym=EFI_SUBSYSTEM=0x0a ++ ldflags += --defsym=EFI_SUBSYSTEM=0x0a + FORMAT = -O binary + endif + +@@ -61,12 +67,12 @@ endif + -j .rel -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \ + -j .reloc $(FORMAT) $*.so $@ + %.so: %.o +- $(LD) $(LDFLAGS) $^ -o $@ $(LOADLIBES) ++ $(LD) $(ldflags) $^ -o $@ $(LOADLIBES) + # check we have no undefined symbols +- nm -D $@ | grep ' U ' && exit 1 || exit 0 ++ ${NM} -D $@ | grep ' U ' && exit 1 || exit 0 + + %.h: %.auth +- ./xxdi.pl $< > $@ ++ $(XXD) -i $< > $@ + + %.hash: %.efi hash-to-efi-sig-list + ./hash-to-efi-sig-list $< $@ +@@ -99,28 +105,28 @@ getvar = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo $(1); else ec + ./sign-efi-sig-list -a -c PK.crt -k PK.key dbx $< $@ + + %.o: %.c +- $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ ++ $(CC) $(INCDIR) $(cflags) $(cppflags) -c $< -o $@ + + %.efi.o: %.c +- $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -fno-toplevel-reorder -DBUILD_EFI -c $< -o $@ ++ $(CC) $(INCDIR) $(cflags) $(cppflags) -fno-toplevel-reorder -DBUILD_EFI -c $< -o $@ + + %.efi.s: %.c +- $(CC) -S $(INCDIR) $(CFLAGS) $(CPPFLAGS) -fno-toplevel-reorder -DBUILD_EFI -c $< -o $@ ++ $(CC) -S $(INCDIR) $(cflags) $(cppflags) -fno-toplevel-reorder -DBUILD_EFI -c $< -o $@ + + %.crt: +- openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$*/" -keyout $*.key -out $@ -days 3650 -nodes -sha256 ++ $(OPENSSL) req -new -x509 -newkey rsa:2048 -subj "/CN=$*/" -keyout $*.key -out $@ -days 3650 -nodes -sha256 + + %.cer: %.crt +- openssl x509 -in $< -out $@ -outform DER ++ $(OPENSSL) x509 -in $< -out $@ -outform DER + + %-subkey.csr: +- openssl req -new -newkey rsa:2048 -keyout $*-subkey.key -subj "/CN=Subkey $* of KEK/" -out $@ -nodes ++ $(OPENSSL) req -new -newkey rsa:2048 -keyout $*-subkey.key -subj "/CN=Subkey $* of KEK/" -out $@ -nodes + + %-subkey.crt: %-subkey.csr KEK.crt +- openssl x509 -req -in $< -CA DB.crt -CAkey DB.key -set_serial 1 -out $@ -days 365 ++ $(OPENSSL) x509 -req -in $< -CA DB.crt -CAkey DB.key -set_serial 1 -out $@ -days 365 + + %-signed.efi: %.efi DB.crt +- sbsign --key DB.key --cert DB.crt --output $@ $< ++ $(SBSIGN) --key DB.key --cert DB.crt --output $@ $< + + ## + # No need for KEK signing +@@ -129,7 +135,7 @@ getvar = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo $(1); else ec + # sbsign --key KEK.key --cert KEK.crt --output $@ $< + + %.a: +- ar rcv $@ $^ ++ $(AR) rcv $@ $^ + + doc/%.1: doc/%.1.in % + $(HELP2MAN) --no-info -i $< -o $@ ./$* +diff --git a/Makefile b/Makefile +index 774ee0a..46e4620 100644 +--- a/Makefile ++++ b/Makefile +@@ -73,7 +73,7 @@ ms-%.esl: ms-%.crt cert-to-efi-sig-list + + hashlist.h: HashTool.hash + cat $^ > /tmp/tmp.hash +- ./xxdi.pl /tmp/tmp.hash > $@ ++ $(XXD) -i /tmp/tmp.hash > $@ + rm -f /tmp/tmp.hash + + +@@ -88,28 +88,28 @@ HelloWorld.so: lib/lib-efi.a + ShimReplace.so: lib/lib-efi.a + + cert-to-efi-sig-list: cert-to-efi-sig-list.o lib/lib.a +- $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a ++ $(CC) $(ARCH3264) -o $@ $< $(ldflags_openssl) $(EXTRA_LDFLAGS) -lcrypto lib/lib.a + + sig-list-to-certs: sig-list-to-certs.o lib/lib.a +- $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a ++ $(CC) $(ARCH3264) -o $@ $< $(ldflags_openssl) $(EXTRA_LDFLAGS) -lcrypto lib/lib.a + + sign-efi-sig-list: sign-efi-sig-list.o lib/lib.a +- $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a ++ $(CC) $(ARCH3264) -o $@ $< $(ldflags_openssl) $(EXTRA_LDFLAGS) -lcrypto lib/lib.a + + hash-to-efi-sig-list: hash-to-efi-sig-list.o lib/lib.a + $(CC) $(ARCH3264) -o $@ $< lib/lib.a + + cert-to-efi-hash-list: cert-to-efi-hash-list.o lib/lib.a +- $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a ++ $(CC) $(ARCH3264) -o $@ $< $(ldflags_openssl) $(EXTRA_LDFLAGS) -lcrypto lib/lib.a + + efi-keytool: efi-keytool.o lib/lib.a + $(CC) $(ARCH3264) -o $@ $< lib/lib.a + + efi-readvar: efi-readvar.o lib/lib.a +- $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a ++ $(CC) $(ARCH3264) -o $@ $< $(ldflags_openssl) $(EXTRA_LDFLAGS) -lcrypto lib/lib.a + + efi-updatevar: efi-updatevar.o lib/lib.a +- $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a ++ $(CC) $(ARCH3264) -o $@ $< $(ldflags_openssl) $(EXTRA_LDFLAGS) -lcrypto lib/lib.a + + flash-var: flash-var.o lib/lib.a + $(CC) $(ARCH3264) -o $@ $< lib/lib.a +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Fix-help2man-error.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Fix-help2man-error.patch new file mode 100644 index 0000000..eb61493 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Fix-help2man-error.patch @@ -0,0 +1,28 @@ +From f2e4ff4e63f4a5f8a4452c970ca271091eeaec7d Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Sun, 18 Jun 2017 23:35:09 +0800 +Subject: [PATCH] Fix help2man error + +This issue may be caused by the poky compiler. + +Signed-off-by: Lans Zhang +--- + Make.rules | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/Make.rules b/Make.rules +index 38c7a22..bda5518 100644 +--- a/Make.rules ++++ b/Make.rules +@@ -140,5 +140,7 @@ getvar = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo $(1); else ec + %.a: + $(AR) rcv $@ $^ + ++HELP2MAN_PROG_PREFIX ?= . ++ + doc/%.1: doc/%.1.in % +- $(HELP2MAN) --no-discard-stderr --no-info -i $< -o $@ ./$* ++ $(HELP2MAN) --no-discard-stderr --no-info -i $< -o $@ $(HELP2MAN_PROG_PREFIX)/$* +-- +2.7.5 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Fix-help2man-failure.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Fix-help2man-failure.patch new file mode 100644 index 0000000..d5079da --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Fix-help2man-failure.patch @@ -0,0 +1,25 @@ +From 546b8c36301bdcf540b3b027fd25baa9cff2abdc Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Wed, 23 Mar 2016 19:44:51 +0800 +Subject: [PATCH] Fix help2man failure + +Add --no-discard-stderr to work around the error. + +Signed-off-by: Lans Zhang +--- + Make.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Make.rules b/Make.rules +index 4aa7650..21926b0 100644 +--- a/Make.rules ++++ b/Make.rules +@@ -142,4 +142,4 @@ getvar = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo $(1); else ec + $(AR) rcv $@ $^ + + doc/%.1: doc/%.1.in % +- $(HELP2MAN) --no-info -i $< -o $@ ./$* ++ $(HELP2MAN) --no-discard-stderr --no-info -i $< -o $@ ./$* +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Fix-the-wrong-dependency-for-blacklist.esl.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Fix-the-wrong-dependency-for-blacklist.esl.patch new file mode 100644 index 0000000..d5f863e --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Fix-the-wrong-dependency-for-blacklist.esl.patch @@ -0,0 +1,28 @@ +From 52228c24af681463d73d5bd8454872b3e811855b Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Tue, 15 Mar 2016 21:07:31 +0800 +Subject: [PATCH] Fix the wrong dependency for %-blacklist.esl + +Upstream-Status: Pending + +Signed-off-by: Lans Zhang +--- + Make.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Make.rules b/Make.rules +index 48b02e4..08a2489 100644 +--- a/Make.rules ++++ b/Make.rules +@@ -77,7 +77,7 @@ endif + %.hash: %.efi hash-to-efi-sig-list + ./hash-to-efi-sig-list $< $@ + +-%-blacklist.esl: %.crt cert-to-efi-hash-list ++%-blacklist.esl: %.crt cert-to-efi-sig-list + ./cert-to-efi-sig-list $< $@ + + %-hash-blacklist.esl: %.crt cert-to-efi-hash-list +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Kill-all-the-build-warning-caused-by-implicit-declar.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Kill-all-the-build-warning-caused-by-implicit-declar.patch new file mode 100644 index 0000000..f7f32c3 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Kill-all-the-build-warning-caused-by-implicit-declar.patch @@ -0,0 +1,80 @@ +From 872a9d96386b819d2c5fd7581d2bdaf7ea61a5f8 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Tue, 15 Mar 2016 17:12:24 +0800 +Subject: [PATCH] Kill all the build warning caused by implicit declaration of + function + +Upstream-Status: Pending + +Signed-off-by: Lans Zhang +--- + Loader.c | 1 + + cert-to-efi-hash-list.c | 2 +- + flash-var.c | 2 ++ + lib/pecoff.c | 1 + + sign-efi-sig-list.c | 2 ++ + 5 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/Loader.c b/Loader.c +index 1f9201a..044469a 100644 +--- a/Loader.c ++++ b/Loader.c +@@ -9,6 +9,7 @@ + #include + #include + ++#include + #include + #include + #include +diff --git a/cert-to-efi-hash-list.c b/cert-to-efi-hash-list.c +index d4484f9..3792553 100644 +--- a/cert-to-efi-hash-list.c ++++ b/cert-to-efi-hash-list.c +@@ -3,7 +3,7 @@ + * + * see COPYING file + */ +- ++#define _GNU_SOURCE + + #include + #define __STDC_VERSION__ 199901L +diff --git a/flash-var.c b/flash-var.c +index aa10ae6..10429bc 100644 +--- a/flash-var.c ++++ b/flash-var.c +@@ -1,3 +1,5 @@ ++#define _GNU_SOURCE ++ + #include + #include + #include +diff --git a/lib/pecoff.c b/lib/pecoff.c +index 26d9dcf..10b898a 100644 +--- a/lib/pecoff.c ++++ b/lib/pecoff.c +@@ -59,6 +59,7 @@ + #endif + #endif + ++#include + #include + #include + #include +diff --git a/sign-efi-sig-list.c b/sign-efi-sig-list.c +index e19ef97..5abcf27 100644 +--- a/sign-efi-sig-list.c ++++ b/sign-efi-sig-list.c +@@ -3,6 +3,8 @@ + * + * see COPYING file + */ ++#define _GNU_SOURCE ++ + #include + #define __STDC_VERSION__ 199901L + #include +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/LockDown-disable-the-entrance-into-BIOS-setup-to-re-.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/LockDown-disable-the-entrance-into-BIOS-setup-to-re-.patch new file mode 100644 index 0000000..ec9849a --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/LockDown-disable-the-entrance-into-BIOS-setup-to-re-.patch @@ -0,0 +1,47 @@ +From e259aecc645c6dd4c194a64d607124cd5a714f9a Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Wed, 15 Feb 2017 14:52:07 +0800 +Subject: [PATCH] LockDown: disable the entrance into BIOS setup to re-enable + secure boot + +In most cases, this step is not necessary. + +Signed-off-by: Lans Zhang +--- + LockDown.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/LockDown.c b/LockDown.c +index 13c626f..fbde3f2 100644 +--- a/LockDown.c ++++ b/LockDown.c +@@ -20,6 +20,11 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + EFI_STATUS efi_status; + UINT8 SecureBoot, SetupMode; + UINTN DataSize = sizeof(SetupMode); ++ /* This controls whether it is required to enter into BIOS setup in ++ * order to re-enable UEFI secure boot. This operation is unnecessary ++ * in most cases. ++ */ ++ UINTN NeedSetAttempt = 0; + + InitializeLib(image, systab); + +@@ -110,12 +115,12 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + * UEFI secure boot in BIOS setup. + */ + Print(L"Prepare to execute system warm reset after 3 seconds ...\n"); +- if (!SecureBoot) ++ if (NeedSetAttempt && !SecureBoot) + Print(L"After warm reset, enter to BIOS setup to enable UEFI Secure Boot.\n"); + + BS->Stall(3000000); + +- if (!SecureBoot) ++ if (NeedSetAttempt && !SecureBoot) + SETOSIndicationsAndReboot(EFI_OS_INDICATIONS_BOOT_TO_FW_UI); + else + RT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL); +-- +2.7.4 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/LockDown-enable-the-enrollment-for-DBX.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/LockDown-enable-the-enrollment-for-DBX.patch new file mode 100644 index 0000000..e0cb9b8 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/LockDown-enable-the-enrollment-for-DBX.patch @@ -0,0 +1,85 @@ +From 49b6a0bf2b9c69d1fd682fbc9d2ad7a7f6abee77 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Fri, 22 Apr 2016 16:28:05 +0800 +Subject: [PATCH] LockDown: enable the enrollment for DBX + +Upstream-Status: Pending + +DBX acting as blacklist now is able to be enrolled. + +Signed-off-by: Lans Zhang +--- + LockDown.c | 16 +++++++++++----- + Makefile | 4 +++- + 2 files changed, 14 insertions(+), 6 deletions(-) + +diff --git a/LockDown.c b/LockDown.c +index 821985c..fec2e79 100644 +--- a/LockDown.c ++++ b/LockDown.c +@@ -12,6 +12,7 @@ + #include "PK.h" + #include "KEK.h" + #include "DB.h" ++#include "DBX.h" + + EFI_STATUS + efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) +@@ -47,6 +48,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + return efi_status; + } + Print(L"Created KEK Cert\n"); ++ + efi_status = RT->SetVariable(L"db", &SIG_DB, + EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_RUNTIME_ACCESS +@@ -58,15 +60,19 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + return efi_status; + } + Print(L"Created db Cert\n"); +-#if 0 +- /* testing revocation ... this will revoke the certificate +- * we just enrolled in db */ +- efi_status = SetSecureVariable(L"dbx", DB_cer, DB_cer_len, SIG_DB, 0); ++ ++ efi_status = RT->SetVariable(L"dbx", &SIG_DB, ++ EFI_VARIABLE_NON_VOLATILE ++ | EFI_VARIABLE_RUNTIME_ACCESS ++ | EFI_VARIABLE_BOOTSERVICE_ACCESS ++ | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, ++ DBX_auth_len, DBX_auth); + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to enroll dbx: %d\n", efi_status); + return efi_status; + } +-#endif ++ Print(L"Created dbx Cert\n"); ++ + /* PK must be updated with a signed copy of itself */ + efi_status = RT->SetVariable(L"PK", &GV_GUID, + EFI_VARIABLE_NON_VOLATILE +diff --git a/Makefile b/Makefile +index b3bb73a..e189866 100644 +--- a/Makefile ++++ b/Makefile +@@ -53,7 +53,7 @@ lib/asn1/libasn1.a lib/asn1/libasn1-efi.a: FORCE + .KEEP: PK.crt KEK.crt DB.crt PK.key KEK.key DB.key PK.esl DB.esl KEK.esl \ + $(EFIFILES) + +-LockDown.o: PK.h KEK.h DB.h ++LockDown.o: PK.h KEK.h DB.h DBX.h + PreLoader.o: hashlist.h + + PK.h: PK.auth +@@ -62,6 +62,8 @@ KEK.h: KEK.auth + + DB.h: DB.auth + ++DBX.h: DBX.auth ++ + noPK.esl: + > noPK.esl + +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/LockDown-run-system-warm-reset-after-the-key-provisi.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/LockDown-run-system-warm-reset-after-the-key-provisi.patch new file mode 100644 index 0000000..4134bda --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/LockDown-run-system-warm-reset-after-the-key-provisi.patch @@ -0,0 +1,44 @@ +From b2897e78c7910f0e55f4861542155d2817c15bf4 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Fri, 25 Mar 2016 10:52:34 +0800 +Subject: [PATCH] LockDown: run system warm reset after the key provision + success + +Upstream-Status: Pending + +In addition, BIOS would stop at its setup screen. The end user can thus +enable UEFI secure boot immediately. + +Signed-off-by: Lans Zhang +--- + LockDown.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/LockDown.c b/LockDown.c +index 29df9de..821985c 100644 +--- a/LockDown.c ++++ b/LockDown.c +@@ -99,5 +99,20 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + } + Print(L"Platform %s set to boot securely\n", SecureBoot ? L"is" : L"is not"); + ++ /* Reset system to go back the real UEFI secure boot flow. ++ * If SecureBoot is still false, the user needs to turn on ++ * UEFI secure boot in BIOS setup. ++ */ ++ Print(L"Prepare to execute system warm reset after 3 seconds ...\n"); ++ if (!SecureBoot) ++ Print(L"After warm reset, enter to BIOS setup to enable UEFI Secure Boot.\n"); ++ ++ BS->Stall(3000000); ++ ++ if (!SecureBoot) ++ SETOSIndicationsAndReboot(EFI_OS_INDICATIONS_BOOT_TO_FW_UI); ++ else ++ RT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL); ++ + return EFI_SUCCESS; + } +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/LockDown-show-the-error-message-with-3-sec-timeout.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/LockDown-show-the-error-message-with-3-sec-timeout.patch new file mode 100644 index 0000000..8dc681f --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/LockDown-show-the-error-message-with-3-sec-timeout.patch @@ -0,0 +1,94 @@ +From 28eb6a3118c3c843b41732ec3cf5167fe027daba Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Tue, 17 Jan 2017 12:48:27 +0800 +Subject: [PATCH] LockDown: show the error message with 3-sec timeout + +Signed-off-by: Lans Zhang +--- + LockDown.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/LockDown.c b/LockDown.c +index fec2e79..13c626f 100644 +--- a/LockDown.c ++++ b/LockDown.c +@@ -27,12 +27,12 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + + if (efi_status != EFI_SUCCESS) { + Print(L"No SetupMode variable ... is platform secure boot enabled?\n"); +- return EFI_SUCCESS; ++ goto out; + } + + if (!SetupMode) { + Print(L"Platform is not in Setup Mode, cannot install Keys\n"); +- return EFI_SUCCESS; ++ goto out; + } + + Print(L"Platform is in Setup Mode\n"); +@@ -45,7 +45,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + KEK_auth_len, KEK_auth); + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to enroll KEK: %d\n", efi_status); +- return efi_status; ++ goto out; + } + Print(L"Created KEK Cert\n"); + +@@ -57,7 +57,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + DB_auth_len, DB_auth); + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to enroll db: %d\n", efi_status); +- return efi_status; ++ goto out; + } + Print(L"Created db Cert\n"); + +@@ -69,7 +69,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + DBX_auth_len, DBX_auth); + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to enroll dbx: %d\n", efi_status); +- return efi_status; ++ goto out; + } + Print(L"Created dbx Cert\n"); + +@@ -84,14 +84,14 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to enroll PK: %d\n", efi_status); +- return efi_status; ++ goto out; + } + Print(L"Created PK Cert\n"); + /* enrolling the PK should put us in SetupMode; check this */ + efi_status = RT->GetVariable(L"SetupMode", &GV_GUID, NULL, &DataSize, &SetupMode); + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to get SetupMode variable: %d\n", efi_status); +- return efi_status; ++ goto out; + } + Print(L"Platform is in %s Mode\n", SetupMode ? L"Setup" : L"User"); + +@@ -101,7 +101,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to get SecureBoot variable: %d\n", efi_status); +- return efi_status; ++ goto out; + } + Print(L"Platform %s set to boot securely\n", SecureBoot ? L"is" : L"is not"); + +@@ -121,4 +121,8 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + RT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL); + + return EFI_SUCCESS; ++ ++out: ++ BS->Stall(3000000); ++ return efi_status; + } +-- +2.7.4 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Makefile-do-not-build-signed-efi-image.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Makefile-do-not-build-signed-efi-image.patch new file mode 100644 index 0000000..43daeab --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Makefile-do-not-build-signed-efi-image.patch @@ -0,0 +1,33 @@ +From 923b9cb2bfe81ff29a29d46bfc4e3fe172e0e5ae Mon Sep 17 00:00:00 2001 +From: Yunguo Wei +Date: Tue, 17 Jan 2017 17:24:51 +0800 +Subject: [PATCH] Makefile: do not build signed efi image + +Signed-off-by: Yunguo Wei +--- + Makefile | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/Makefile b/Makefile +index addb593..a1fc538 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,5 +1,4 @@ +-EFIFILES = HelloWorld.efi LockDown.efi Loader.efi ReadVars.efi UpdateVars.efi \ +- KeyTool.efi HashTool.efi SetNull.efi ShimReplace.efi ++EFIFILES = LockDown.efi + BINARIES = cert-to-efi-sig-list sig-list-to-certs sign-efi-sig-list \ + hash-to-efi-sig-list efi-readvar efi-updatevar cert-to-efi-hash-list \ + flash-var +@@ -27,7 +26,7 @@ include Make.rules + + EFISIGNED = $(patsubst %.efi,%-signed.efi,$(EFIFILES)) + +-all: $(EFISIGNED) $(BINARIES) $(MANPAGES) noPK.auth $(KEYAUTH) \ ++all: $(EFIFILES) $(BINARIES) $(MANPAGES) noPK.auth $(KEYAUTH) \ + $(KEYUPDATEAUTH) $(KEYBLACKLISTAUTH) $(KEYHASHBLACKLISTAUTH) + + +-- +2.7.4 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Reuse-xxdi.pl.patch b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Reuse-xxdi.pl.patch new file mode 100644 index 0000000..c382a99 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools/Reuse-xxdi.pl.patch @@ -0,0 +1,51 @@ +From 959e4395b5524babb27c2bf95fa37b990d79b663 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Thu, 28 Apr 2016 12:52:22 +0800 +Subject: [PATCH] Reuse xxdi.pl + +The missing File::Slurp required by xxdi.pl is added. To avoid introducing +an extra xxd package, remove the support of using xxd. + +Signed-off-by: Lans Zhang +--- + Make.rules | 3 +-- + Makefile | 2 +- + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/Make.rules b/Make.rules +index 21926b0..38c7a22 100644 +--- a/Make.rules ++++ b/Make.rules +@@ -33,7 +33,6 @@ NM = nm + AR = ar + OPENSSL = openssl + SBSIGN = sbsign +-XXD = xxd + SIGN_EFI_SIG_LIST ?= ./sign-efi-sig-list + CERT_TO_EFI_SIG_LIST ?= ./cert-to-efi-sig-list + CERT_TO_EFI_HASH_LIST ?= ./cert-to-efi-hash-list +@@ -76,7 +75,7 @@ endif + ${NM} -D $@ | grep ' U ' && exit 1 || exit 0 + + %.h: %.auth +- $(XXD) -i $< > $@ ++ ./xxdi.pl $< > $@ + + %.hash: %.efi hash-to-efi-sig-list + $(HASH_TO_EFI_SIG_LIST) $< $@ +diff --git a/Makefile b/Makefile +index da363a6..2534b47 100644 +--- a/Makefile ++++ b/Makefile +@@ -73,7 +73,7 @@ ms-%.esl: ms-%.crt cert-to-efi-sig-list + + hashlist.h: HashTool.hash + cat $^ > /tmp/tmp.hash +- $(XXD) -i /tmp/tmp.hash > $@ ++ ./xxdi.pl /tmp/tmp.hash > $@ + rm -f /tmp/tmp.hash + + +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/efitools/efitools_git.bb b/meta-efi-secure-boot/recipes-bsp/efitools/efitools_git.bb new file mode 100644 index 0000000..79b86a6 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/efitools/efitools_git.bb @@ -0,0 +1,83 @@ +require efitools.inc + +SRC_URI_append += " \ + file://LockDown-enable-the-enrollment-for-DBX.patch \ + file://LockDown-show-the-error-message-with-3-sec-timeout.patch \ + file://Makefile-do-not-build-signed-efi-image.patch \ + file://Build-DBX-by-default.patch \ + file://LockDown-disable-the-entrance-into-BIOS-setup-to-re-.patch \ + file://Fix-help2man-error.patch \ +" + +COMPATIBLE_HOST = '(i.86|x86_64).*-linux' + +inherit user-key-store deploy + +# The generated native binaries are used during native and target build +DEPENDS += "${BPN}-native gnu-efi openssl" + +RDEPENDS_${PN}_append += " \ + parted mtools coreutils util-linux openssl libcrypto \ +" + +EXTRA_OEMAKE_append += " \ + INCDIR_PREFIX='${STAGING_DIR_TARGET}' \ + CRTPATH_PREFIX='${STAGING_DIR_TARGET}' \ + SIGN_EFI_SIG_LIST='${STAGING_BINDIR_NATIVE}/sign-efi-sig-list' \ + CERT_TO_EFI_SIG_LIST='${STAGING_BINDIR_NATIVE}/cert-to-efi-sig-list' \ + CERT_TO_EFI_HASH_LIST='${STAGING_BINDIR_NATIVE}/cert-to-efi-hash-list' \ + HASH_TO_EFI_SIG_LIST='${STAGING_BINDIR_NATIVE}/hash-to-efi-sig-list' \ + MYGUID='${UEFI_SIG_OWNER_GUID}' \ + HELP2MAN_PROG_PREFIX='${STAGING_BINDIR_NATIVE}' \ +" + +python do_prepare_signing_keys() { + if d.expand('${UEFI_SB}') != '1': + return + + # Prepare PK, KEK and DB for LockDown.efi. + if uks_signing_model(d) in ('sample', 'user'): + dir = uefi_sb_keys_dir(d) + else: + dir = d.expand('${SAMPLE_UEFI_SB_KEYS_DIR}/') + + import shutil + + for _ in ('PK', 'KEK', 'DB'): + shutil.copyfile(dir + _ + '.pem', d.expand('${S}/') + _ + '.crt') + shutil.copyfile(dir + _ + '.key', d.expand('${S}/') + _ + '.key') + + # Make sure LockDown.efi contains the DB and KEK from Microsoft. + if "${@bb.utils.contains('DISTRO_FEATURES', 'msft', '1', '0', d)}" == '1': + shutil.copyfile(d.expand('${MSFT_DB_CERT}'), d.expand('${S}/DB.crt')) + shutil.copyfile(d.expand('${MSFT_KEK_CERT}'), d.expand('${S}/KEK.crt')) + + path = create_uefi_dbx(d) + if path: + with open(d.expand('${S}/DBX.crt'), 'w') as f: + pass + + shutil.copyfile(path, d.expand('${S}/DBX.esl')) + + # Cheat the Makefile to avoid running this rule: + # %.esl: %.crt cert-to-efi-sig-list + # $(CERT_TO_EFI_SIG_LIST) -g $(MYGUID) $< $@ + import time, os + tm = time.strptime('2038-01-01 00:00:00', \ + '%Y-%m-%d %H:%M:%S') + time_stamp = time.mktime(tm) + os.utime(d.expand('${S}/DBX.esl'), (time_stamp, time_stamp)) +} +addtask prepare_signing_keys after do_configure before do_compile + +do_install_append() { + install -d ${D}${EFI_BOOT_PATH} + install -m 0755 ${D}${datadir}/efitools/efi/LockDown.efi ${D}${EFI_BOOT_PATH} +} + +do_deploy() { + install -d ${DEPLOYDIR} + + install -m 0600 ${D}${EFI_BOOT_PATH}/LockDown.efi "${DEPLOYDIR}" +} +addtask deploy after do_install before do_build diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0001-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0001-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch new file mode 100644 index 0000000..249f66a --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0001-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch @@ -0,0 +1,67 @@ +From aecadf65c4d3dea68e55605ff5f0c3eb90206488 Mon Sep 17 00:00:00 2001 +From: Ricardo Neri +Date: Fri, 27 Mar 2015 08:01:41 -0700 +Subject: [PATCH 1/7] pe32.h: add header structures for TE and DOS executables + +Upstream-Status: Inappropriate [embedded specific] + +Add header structures to describe the Terse Executable format and +the DOS header format for executable images. + +These definitions are needed in subsequent commits to parse and +verify the identity of the executable image when utilizing a shim +to boot LUV. + +Signed-off-by: Ricardo Neri +--- + include/grub/efi/pe32.h | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h +index c3efa9b..c1c3483 100644 +--- a/include/grub/efi/pe32.h ++++ b/include/grub/efi/pe32.h +@@ -313,4 +313,40 @@ struct grub_pe32_reloc + #define GRUB_PE32_REL_I386_DIR32 0x6 + #define GRUB_PE32_REL_I386_REL32 0x14 + ++struct grub_te_header ++{ ++ grub_uint16_t signature; ++ grub_uint16_t machine; ++ grub_uint8_t num_sections; ++ grub_uint8_t subsystem; ++ grub_uint16_t stripped_size; ++ grub_uint32_t entry_point; ++ grub_uint32_t code_base; ++ grub_uint64_t image_base; ++ struct grub_pe32_data_directory data_directory[2]; ++}; ++ ++struct grub_dos_header ++{ ++ grub_uint16_t magic; ++ grub_uint16_t cblp; ++ grub_uint16_t cp; ++ grub_uint16_t crlc; ++ grub_uint16_t cparhdr; ++ grub_uint16_t minalloc; ++ grub_uint16_t maxalloc; ++ grub_uint16_t ss; ++ grub_uint16_t sp; ++ grub_uint16_t csum; ++ grub_uint16_t ip; ++ grub_uint16_t cs; ++ grub_uint16_t lfarlc; ++ grub_uint16_t ovno; ++ grub_uint16_t res[4]; ++ grub_uint16_t oemid; ++ grub_uint16_t oeminfo; ++ grub_uint16_t res2[10]; ++ grub_uint32_t lfanew; ++}; ++ + #endif /* ! GRUB_EFI_PE32_HEADER */ +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0002-shim-add-needed-data-structures.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0002-shim-add-needed-data-structures.patch new file mode 100644 index 0000000..d09550e --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0002-shim-add-needed-data-structures.patch @@ -0,0 +1,161 @@ +From 2341c2d2cf2ee67b036d21aa9b12b71bea84495f Mon Sep 17 00:00:00 2001 +From: Ricardo Neri +Date: Fri, 27 Mar 2015 08:09:58 -0700 +Subject: [PATCH 2/7] shim: add needed data structures + +Upstream-Status: Inappropriate [embedded specific] + +Add the needed data structures for shim to load, parse, relocate and +execute a binary. This includes file-parsing structures, an identifier for +the UEFI protocol for image verification under secure boot provided by shim. + +Shim is thin loader developed by Matthew Garret +(https://github.com/rhinstaller/shim). This code was ported from such project. + +Signed-off-by: Ricardo Neri +--- + include/grub/efi/shim.h | 132 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 132 insertions(+) + create mode 100644 include/grub/efi/shim.h + +diff --git a/include/grub/efi/shim.h b/include/grub/efi/shim.h +new file mode 100644 +index 0000000..4b92a00 +--- /dev/null ++++ b/include/grub/efi/shim.h +@@ -0,0 +1,132 @@ ++/* ++ * shim.h - interface to shim: UEFI first-stage bootloader ++ * ++ * Copyright 2015 Intel Corporation. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * Significant portions of this code are derived from Red Hat shim: UEFI ++ * first-stage bootloader. ++ * (https://github.com/rhinstaller/shim) and are Copyright 2012 Red Hat, Inc ++ */ ++ ++#ifndef GRUB_SHIM_HEADER ++#define GRUB_SHIM_HEADER 1 ++ ++#include ++ ++struct grub_nt_headers32 ++{ ++ grub_efi_uint32_t signature; ++ struct grub_pe32_coff_header file_hdr; ++ struct grub_pe32_optional_header opt_hdr; ++}; ++ ++struct grub_nt_headers64 ++{ ++ grub_efi_uint32_t signature; ++ struct grub_pe32_coff_header file_hdr; ++ struct grub_pe64_optional_header opt_hdr; ++}; ++ ++struct grub_image_base_relocation ++{ ++ grub_efi_uint32_t virtual_address; ++ grub_efi_uint32_t block_size; ++}; ++ ++struct grub_shim_pe_coff_loader_image_context { ++ grub_efi_uint64_t image_address; ++ grub_efi_uint64_t image_size; ++ grub_efi_uint64_t entry_point; ++ grub_efi_uintn_t header_size; ++ grub_efi_uint16_t image_type; ++ grub_efi_uint16_t num_sections; ++ struct grub_pe32_section_table *first_section; ++ struct grub_pe32_data_directory *reloc_dir; ++ struct grub_pe32_data_directory *sec_dir; ++ grub_efi_uint64_t number_of_rva_and_sizes; ++ union grub_shim_optional_header_union *pe_hdr; ++}; ++ ++struct grub_shim_lock ++{ ++ grub_efi_status_t ++ (*verify) (void *buffer, ++ grub_uint32_t size); ++ ++ grub_efi_status_t ++ (*hash) (grub_int8_t *data, ++ grub_int32_t datasize, ++ struct grub_shim_pe_coff_loader_image_context *context, ++ grub_uint8_t sha256hash, ++ grub_uint8_t sha1hash); ++ ++ grub_efi_status_t ++ (*context) (void *data, ++ grub_uint32_t datasize, ++ struct grub_shim_pe_coff_loader_image_context *context); ++}; ++ ++union grub_shim_optional_header_union ++{ ++ struct grub_nt_headers32 pe32; ++ struct grub_nt_headers64 pe32plus; ++ struct grub_te_header te; ++}; ++ ++#define GRUB_EFI_SHIM_PROTOCOL_GUID \ ++ { 0x605dab50, 0xe046, 0x4300, \ ++ { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \ ++ } ++ ++#define SIGNATURE_16(A, B) ((A) | (B << 8)) ++#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16)) ++ ++#define EFI_IMAGE_DOS_SIGNATURE SIGNATURE_16('M', 'Z') ++#define EFI_IMAGE_NT_SIGNATURE SIGNATURE_32('P', 'E', '\0', '\0') ++ ++#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5 ++ ++#define ALIGN_VALUE(Value, Alignment) ((Value) + (((Alignment) - (Value)) & ((Alignment) - 1))) ++#define ALIGN_POINTER(Pointer, Alignment) ((void *) (ALIGN_VALUE ((grub_efi_uintn_t)(Pointer), (Alignment)))) ++ ++/* Based relocation types. */ ++ ++#define EFI_IMAGE_REL_BASED_ABSOLUTE 0 ++#define EFI_IMAGE_REL_BASED_HIGH 1 ++#define EFI_IMAGE_REL_BASED_LOW 2 ++#define EFI_IMAGE_REL_BASED_HIGHLOW 3 ++#define EFI_IMAGE_REL_BASED_HIGHADJ 4 ++#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5 ++#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5 ++#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7 ++#define EFI_IMAGE_REL_BASED_IA64_IMM64 9 ++#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR16 9 ++#define EFI_IMAGE_REL_BASED_DIR64 10 ++ ++ ++#endif /* ! GRUB_SHIM_HEADER */ +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0003-efi-chainloader-implement-an-UEFI-Exit-service-for-s.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0003-efi-chainloader-implement-an-UEFI-Exit-service-for-s.patch new file mode 100644 index 0000000..cf13fc1 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0003-efi-chainloader-implement-an-UEFI-Exit-service-for-s.patch @@ -0,0 +1,81 @@ +From 3b75fa5071e4b1a40510669119791928859b46e7 Mon Sep 17 00:00:00 2001 +From: Matt Fleming +Date: Fri, 27 Mar 2015 08:11:19 -0700 +Subject: [PATCH 3/7] efi: chainloader: implement an UEFI Exit service for shim + in grub + +Upstream-Status: Inappropriate [embedded specific] + +When exiting, grub will call the UEFI boot-time service Exit. The +effect of this is that UEFI will jump to the entry point of the +UEFI started image. If we execute an image using shim within grub, +shim takes care of loading/parsing/relocating/executing the image. +Under this scenario, we also need to take care of the Exit call. Thus, +we need to reimplement the function to make sure we perform a jump +to the instruction after which shim executed the image. + +Once we have taken care of the exit of the shim-executed image +the system Exit call is restored. + +Signed-off-by: Ricardo Neri +--- + grub-core/kern/x86_64/efi/callwrap.S | 23 +++++++++++++++++++++++ + include/grub/efi/api.h | 4 ++++ + 2 files changed, 27 insertions(+) + +diff --git a/grub-core/kern/x86_64/efi/callwrap.S b/grub-core/kern/x86_64/efi/callwrap.S +index 2df95dd..f0f1dd8 100644 +--- a/grub-core/kern/x86_64/efi/callwrap.S ++++ b/grub-core/kern/x86_64/efi/callwrap.S +@@ -48,6 +48,26 @@ FUNCTION(efi_wrap_1) + addq $48, %rsp + ret + ++FUNCTION(efi_call_foo) ++ pushq %rbp ++ pushq %r12 ++ pushq %r13 ++ pushq %r14 ++ pushq %r15 ++ movq %rsp, saved_sp(%rip) ++ subq $48, %rsp ++ mov %rsi, %rcx ++ call *%rdi ++ ++FUNCTION(efi_shim_exit) ++ movq saved_sp(%rip), %rsp ++ popq %r15 ++ popq %r14 ++ popq %r13 ++ popq %r12 ++ popq %rbp ++ ret ++ + FUNCTION(efi_wrap_2) + subq $48, %rsp + mov %rsi, %rcx +@@ -127,3 +147,6 @@ FUNCTION(efi_wrap_10) + call *%rdi + addq $96, %rsp + ret ++ ++ .data ++saved_sp: .quad 0 +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h +index 26127de..374d88b 100644 +--- a/include/grub/efi/api.h ++++ b/include/grub/efi/api.h +@@ -1437,6 +1437,10 @@ typedef struct grub_efi_block_io grub_efi_block_io_t; + + grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func); + grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1); ++grub_efi_status_t EXPORT_FUNC(efi_shim_exit) (grub_efi_handle_t handle, grub_efi_status_t exit_status, ++ grub_efi_uintn_t exit_data_size, grub_efi_char16_t *exit_data) __attribute__((noreturn)); ++grub_uint64_t EXPORT_FUNC(efi_call_foo) (void *func, grub_uint64_t arg1, ++ grub_uint64_t arg2); + grub_uint64_t EXPORT_FUNC(efi_wrap_2) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2); + grub_uint64_t EXPORT_FUNC(efi_wrap_3) (void *func, grub_uint64_t arg1, +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0004-efi-chainloader-port-shim-to-grub.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0004-efi-chainloader-port-shim-to-grub.patch new file mode 100644 index 0000000..baa0986 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0004-efi-chainloader-port-shim-to-grub.patch @@ -0,0 +1,582 @@ +From e097b4e25469aabdceac79c45cca27029824c1b5 Mon Sep 17 00:00:00 2001 +From: Ricardo Neri +Date: Fri, 27 Mar 2015 08:19:21 -0700 +Subject: [PATCH 4/7] efi: chainloader: port shim to grub + +Upstream-Status: Inappropriate [embedded specific] + +Shim is a thin loader to execute signed binaries under the +chain of trust of UEFI secure boot. Before executing the image, +shim verifies that such image is signed with any of the Machine +Owner Keys (MOKs). If the verification is successful, shim will +load, parse, relocate and execute the image. + +Shim is useful in case the user does not want to modify the UEFI +database of valid certificates (DB). + +This commit ports Matthew Garret's code from shim to grub in order +to provide to grub the capability of load and execute trusted +binaries. This is useful in case we need to chainload two bootloaders. + +Shim can be found here: https://github.com/rhinstaller/shim + +Signed-off-by: Ricardo Neri +--- + grub-core/loader/efi/chainloader.c | 534 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 534 insertions(+) + +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index 3f3e6e3..bd83859 100644 +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -45,6 +46,539 @@ static grub_efi_uintn_t pages; + static grub_efi_device_path_t *file_path; + static grub_efi_handle_t image_handle; + static grub_efi_char16_t *cmdline; ++static grub_int32_t shim_used; ++static grub_efi_physical_address_t shim_buffer; ++static grub_efi_uintn_t shim_pages; ++static grub_efi_loaded_image_t shim_li_bak; ++static grub_efi_status_t (*shim_entry_point) (grub_efi_handle_t image_handle, ++ grub_efi_system_table_t *systab); ++ ++static const grub_uint16_t ++grub_shim_machine_type = ++#if defined(__x86_64__) ++ GRUB_PE32_MACHINE_X86_64; ++#elif defined(__aarch64__) ++ IMAGE_FILE_MACHINE_ARM64; ++#elif defined(__arm__) ++ IMAGE_FILE_MACHINE_ARMTHUMB_MIXED; ++#elif defined(__i386__) || defined(__i486__) || defined(__i686__) ++ GRUB_PE32_MACHINE_I386; ++#elif defined(__ia64__) ++ GRUB_PE32_MACHINE_IA64; ++#else ++#error this architecture is not supported by shim chainloader ++#endif ++ ++static grub_efi_guid_t grub_shim_protocol_guid = GRUB_EFI_SHIM_PROTOCOL_GUID; ++ ++static grub_int32_t ++grub_shim_allow_64_bit (void) ++{ ++/* TODO: what is the definition for aarch64? */ ++#if defined(__x86_64__) ++ return 1; ++#elif defined(__i386__) || defined(__i686__) ++/* TODO: find out what to do with in_protocol */ ++ return 0; ++#else /* assuming everything else is 32-bit... */ ++ return 0; ++#endif ++} ++ ++static grub_int32_t ++grub_shim_allow_32_bit (void) ++{ ++/* TODO: what is the definition for aarch64? */ ++#if defined(__x86_64__) ++/* TODO: find out what to do with in_protocol */ ++ return 0; ++#elif defined(__i386__) || defined(__i686__) ++ return 1; ++#else /* assuming everything else is 32-bit... */ ++ return 1; ++#endif ++} ++ ++static grub_int32_t ++grub_shim_image_is_64_bit (union grub_shim_optional_header_union *pe_hdr) ++{ ++ /* .Magic is the same offset in all cases */ ++ if (pe_hdr->pe32plus.opt_hdr.magic == GRUB_PE32_PE64_MAGIC) ++ return 1; ++ return 0; ++} ++ ++static grub_int32_t ++grub_shim_image_is_loadable (union grub_shim_optional_header_union *pe_hdr) ++{ ++ /* If the machine type doesn't match the binary, bail, unless ++ * we're in an allowed 64-on-32 scenario ++ */ ++ if (pe_hdr->pe32.file_hdr.machine != grub_shim_machine_type) ++ { ++ if (!(grub_shim_machine_type == GRUB_PE32_MACHINE_I386 ++ && pe_hdr->pe32.file_hdr.machine == GRUB_PE32_MACHINE_X86_64 ++ && grub_shim_allow_64_bit ())) ++ return 0; ++ } ++ ++ /* If it's not a header type we recognize at all, bail */ ++ switch (pe_hdr->pe32plus.opt_hdr.magic) ++ { ++ case GRUB_PE32_PE64_MAGIC: ++ case GRUB_PE32_PE32_MAGIC: ++ break; ++ default: ++ return 0; ++ } ++ ++ /* and now just check for general 64-vs-32 compatibility */ ++ if (grub_shim_image_is_64_bit(pe_hdr)) ++ { ++ if (grub_shim_allow_64_bit ()) ++ return 1; ++ } ++ else ++ { ++ if (grub_shim_allow_32_bit ()) ++ return 1; ++ } ++ return 0; ++} ++ ++/* ++ * Perform basic bounds checking of the intra-image pointers ++ */ ++static grub_efi_uint64_t ++grub_shim_image_address (grub_addr_t image, grub_uint32_t size, grub_uint32_t addr) ++{ ++ if (addr > size) ++ return 0; ++ return image + addr; ++} ++ ++/* ++ * Perform the actual relocation ++ */ ++static grub_err_t ++grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, ++ void *orig, void *data) ++{ ++ struct grub_image_base_relocation *reloc_base, *reloc_base_end; ++ grub_efi_uint64_t adjust; ++ grub_efi_uint16_t *reloc, *reloc_end; ++ grub_uint8_t *fixup, *fixup_base, *fixup_data = NULL; ++ grub_efi_uint16_t *fixup16; ++ grub_efi_uint32_t *fixup32; ++ grub_efi_uint64_t *fixup64; ++ grub_int32_t size = context->image_size; ++ void *image_end = (char *)orig + size; ++ ++ if (grub_shim_image_is_64_bit(context->pe_hdr)) ++ context->pe_hdr->pe32plus.opt_hdr.image_base = (grub_efi_uint64_t)(unsigned long)data; ++ else ++ context->pe_hdr->pe32.opt_hdr.image_base = (grub_efi_uint32_t)(unsigned long)data; ++ ++ reloc_base = (struct grub_image_base_relocation *) ++ grub_shim_image_address ((grub_efi_uint64_t)orig, size, ++ context->reloc_dir->rva); ++ reloc_base_end = (struct grub_image_base_relocation *) ++ grub_shim_image_address ((grub_efi_uint64_t)orig, size, ++ context->reloc_dir->rva ++ + context->reloc_dir->size - 1); ++ ++ if (!reloc_base || !reloc_base_end) ++ { ++ grub_printf("Reloc table overflows binary\n"); ++ return GRUB_ERR_BAD_FILE_TYPE; ++ } ++ ++ adjust = (grub_efi_uintn_t)data - context->image_address; ++ ++ if (adjust == 0) ++ return GRUB_EFI_SUCCESS; ++ ++ while (reloc_base < reloc_base_end) ++ { ++ reloc = (grub_efi_uint16_t *) ((grub_int8_t *) reloc_base ++ + sizeof (struct grub_image_base_relocation)); ++ ++ if ((reloc_base->block_size == 0) ++ || (reloc_base->block_size > context->reloc_dir->size)) ++ { ++ grub_printf("Reloc block size %d is invalid\n", reloc_base->block_size); ++ return GRUB_ERR_FILE_READ_ERROR; ++ } ++ ++ reloc_end = (grub_efi_uint16_t *) ++ ((grub_uint8_t *) reloc_base + reloc_base->block_size); ++ if ((void *)reloc_end < orig || (void *)reloc_end > image_end) ++ { ++ grub_printf("Reloc entry overflows binary\n"); ++ return GRUB_ERR_FILE_READ_ERROR; ++ } ++ ++ fixup_base = (grub_uint8_t *) ++ grub_shim_image_address ((grub_efi_uint64_t)data, ++ size, ++ reloc_base->virtual_address); ++ if (!fixup_base) ++ { ++ grub_printf("Invalid fixup_base\n"); ++ return GRUB_ERR_FILE_READ_ERROR; ++ } ++ ++ while (reloc < reloc_end) ++ { ++ fixup = fixup_base + (*reloc & 0xFFF); ++ switch ((*reloc) >> 12) ++ { ++ case EFI_IMAGE_REL_BASED_ABSOLUTE: ++ break; ++ ++ case EFI_IMAGE_REL_BASED_HIGH: ++ fixup16 = (grub_efi_uint16_t *) fixup; ++ *fixup16 = (grub_efi_uint16_t) ++ (*fixup16 ++ + ((grub_efi_uint16_t) ((grub_efi_uint32_t) adjust >> 16))); ++ if (fixup_data != NULL) ++ { ++ *(grub_efi_uint16_t *) fixup_data = *fixup16; ++ fixup_data = fixup_data + sizeof (grub_efi_uint16_t); ++ } ++ break; ++ ++ case EFI_IMAGE_REL_BASED_LOW: ++ fixup16 = (grub_efi_uint16_t *) fixup; ++ *fixup16 = (grub_efi_uint16_t) ++ (*fixup16 + (grub_efi_uint16_t) adjust); ++ if (fixup_data != NULL) ++ { ++ *(grub_efi_uint16_t *) fixup_data = *fixup16; ++ fixup_data = fixup_data + sizeof (grub_efi_uint16_t); ++ } ++ break; ++ ++ case EFI_IMAGE_REL_BASED_HIGHLOW: ++ fixup32 = (grub_efi_uint32_t *) fixup; ++ *fixup32 = *fixup32 + (grub_efi_uint32_t) adjust; ++ if (fixup_data != NULL) ++ { ++ fixup_data = ALIGN_POINTER (fixup_data, sizeof (grub_efi_uint32_t)); ++ *(grub_efi_uint32_t *)fixup_data = *fixup32; ++ fixup_data = fixup_data + sizeof (grub_efi_uint32_t); ++ } ++ break; ++ ++ case EFI_IMAGE_REL_BASED_DIR64: ++ fixup64 = (grub_efi_uint64_t *) fixup; ++ *fixup64 = *fixup64 + (grub_efi_uint64_t) adjust; ++ if (fixup_data != NULL) ++ { ++ fixup_data = ALIGN_POINTER (fixup_data, sizeof(grub_efi_uint64_t)); ++ *(grub_efi_uint64_t *)(fixup_data) = *fixup64; ++ fixup_data = fixup_data + sizeof(grub_efi_uint64_t); ++ } ++ break; ++ ++ default: ++ grub_printf("Unknown relocation\n"); ++ return GRUB_ERR_FILE_READ_ERROR; ++ } ++ reloc += 1; ++ } ++ reloc_base = (struct grub_image_base_relocation *) reloc_end; ++ } ++ ++ return GRUB_EFI_SUCCESS; ++} ++ ++/* ++ * Read the binary header and grab appropriate information from it ++ */ ++static grub_err_t ++grub_shim_read_header(grub_efi_physical_address_t data, grub_uint32_t datasize, ++ struct grub_shim_pe_coff_loader_image_context *context) ++{ ++ struct grub_dos_header *dos_hdr = (struct grub_dos_header *)data; ++ union grub_shim_optional_header_union *pe_hdr = (union grub_shim_optional_header_union *)data; ++ grub_uint64_t header_without_data_dir, section_header_offset, opt_hdr_size; ++ ++ if (datasize < sizeof (pe_hdr->pe32)) ++ { ++ grub_printf("Invalid image\n"); ++ return GRUB_ERR_BAD_FILE_TYPE; ++ } ++ ++ if (dos_hdr->magic == EFI_IMAGE_DOS_SIGNATURE) ++ pe_hdr = (union grub_shim_optional_header_union *)((grub_uint8_t *)data ++ + dos_hdr->lfanew); ++ ++ if (!grub_shim_image_is_loadable(pe_hdr)) ++ { ++ grub_printf("Platform does not support this image\n"); ++ return GRUB_ERR_BAD_FILE_TYPE; ++ } ++ ++ if (grub_shim_image_is_64_bit(pe_hdr)) ++ { ++ context->number_of_rva_and_sizes = pe_hdr->pe32plus.opt_hdr.num_data_directories; ++ context->header_size = pe_hdr->pe32plus.opt_hdr.header_size; ++ context->image_size = pe_hdr->pe32plus.opt_hdr.image_size; ++ opt_hdr_size = sizeof(struct grub_pe64_optional_header); ++ } else ++ { ++ context->number_of_rva_and_sizes = pe_hdr->pe32.opt_hdr.num_data_directories; ++ context->header_size = pe_hdr->pe32.opt_hdr.header_size; ++ context->image_size = (grub_efi_uint64_t)pe_hdr->pe32.opt_hdr.header_size; ++ opt_hdr_size = sizeof(struct grub_pe32_optional_header); ++ } ++ ++ context->num_sections = pe_hdr->pe32.file_hdr.num_sections; ++ ++ if (GRUB_PE32_NUM_DATA_DIRECTORIES < context->number_of_rva_and_sizes) ++ { ++ grub_printf("Image header too small\n"); ++ return GRUB_ERR_FILE_READ_ERROR; ++ } ++ ++ header_without_data_dir = opt_hdr_size ++ - sizeof (struct grub_pe32_data_directory) ++ * GRUB_PE32_NUM_DATA_DIRECTORIES; ++ if (((grub_efi_uint32_t)pe_hdr->pe32.file_hdr.optional_header_size ++ - header_without_data_dir) != ++ context->number_of_rva_and_sizes * sizeof (struct grub_pe32_data_directory)) ++ { ++ grub_printf("Image header overflows data directory\n"); ++ return GRUB_ERR_FILE_READ_ERROR; ++ } ++ ++ section_header_offset = dos_hdr->lfanew ++ + sizeof (grub_efi_uint32_t) ++ + sizeof (struct grub_pe32_coff_header) ++ + pe_hdr->pe32.file_hdr.optional_header_size; ++ if (((grub_efi_uint32_t)context->image_size - section_header_offset) ++ / sizeof (struct grub_pe32_section_table) ++ <= context->num_sections) ++ { ++ grub_printf("Image sections overflow image size\n"); ++ return GRUB_ERR_FILE_READ_ERROR; ++ } ++ ++ if ((context->header_size - section_header_offset) ++ / sizeof (struct grub_pe32_section_table) ++ < (grub_efi_uint32_t)context->num_sections) ++ { ++ grub_printf("Image sections overflow section headers\n"); ++ return GRUB_ERR_FILE_READ_ERROR; ++ } ++ ++ if ((((grub_efi_uint8_t *)pe_hdr ++ - (grub_efi_uint8_t *)data) ++ + sizeof(union grub_shim_optional_header_union )) > datasize) ++ { ++ grub_printf("Invalid image\n"); ++ return GRUB_ERR_BAD_FILE_TYPE; ++ } ++ ++ if (pe_hdr->te.signature != EFI_IMAGE_NT_SIGNATURE) ++ { ++ grub_printf("Unsupported image type\n"); ++ return GRUB_ERR_BAD_FILE_TYPE; ++ } ++ ++ if (pe_hdr->pe32.file_hdr.characteristics & GRUB_PE32_RELOCS_STRIPPED) ++ { ++ grub_printf("Unsupported image - Relocations have been stripped\n"); ++ return GRUB_ERR_BAD_FILE_TYPE; ++ } ++ ++ context->pe_hdr = pe_hdr; ++ ++ if (grub_shim_image_is_64_bit(pe_hdr)) ++ { ++ context->image_address = pe_hdr->pe32plus.opt_hdr.image_base; ++ context->entry_point = pe_hdr->pe32plus.opt_hdr.entry_addr; ++ context->reloc_dir = &pe_hdr->pe32plus.opt_hdr.base_relocation_table; ++ context->sec_dir = &pe_hdr->pe32plus.opt_hdr.certificate_table; ++ } else ++ { ++ context->image_address = pe_hdr->pe32.opt_hdr.image_base; ++ context->entry_point = pe_hdr->pe32.opt_hdr.entry_addr; ++ context->reloc_dir = &pe_hdr->pe32.opt_hdr.base_relocation_table; ++ context->sec_dir = &pe_hdr->pe32.opt_hdr.certificate_table; ++ } ++ ++ context->first_section = (struct grub_pe32_section_table *) ++ ((char *)pe_hdr ++ + pe_hdr->pe32.file_hdr.optional_header_size ++ + sizeof(grub_efi_uint32_t) ++ + sizeof(struct grub_pe32_coff_header)); ++ ++ if (context->image_size < context->header_size) ++ { ++ grub_printf("Invalid image\n"); ++ return GRUB_ERR_BAD_FILE_TYPE; ++ } ++ ++ if ((unsigned long)((grub_efi_uint8_t *)context->sec_dir - (grub_efi_uint8_t *)data) > ++ (datasize - sizeof(struct grub_pe32_data_directory))) ++ { ++ grub_printf("Invalid image\n"); ++ return GRUB_ERR_BAD_FILE_TYPE; ++ } ++ ++ if (context->sec_dir->rva >= datasize) ++ { ++ grub_printf("Malformed security header\n"); ++ return GRUB_ERR_BAD_FILE_TYPE; ++ } ++ return GRUB_ERR_NONE; ++} ++ ++static grub_efi_status_t ++grub_shim_verify (grub_addr_t addr, grub_ssize_t size) ++{ ++ struct grub_shim_lock *shim_lock; ++ shim_lock = grub_efi_locate_protocol (&grub_shim_protocol_guid, 0); ++ if (!shim_lock) ++ { ++ grub_error (GRUB_ERR_BAD_OS, "could not load shim protocol"); ++ return GRUB_EFI_UNSUPPORTED; ++ } ++ ++ return shim_lock->verify((void *) addr, size); ++} ++ ++static grub_err_t ++grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, ++ struct grub_shim_pe_coff_loader_image_context *context) ++{ ++ grub_err_t status; ++ grub_efi_status_t efi_status; ++ grub_uint32_t sect_size; ++ /* TODO: can they be unsigned? */ ++ grub_int8_t *base, *end; ++ grub_int32_t i; ++ struct grub_pe32_section_table *section; ++ grub_efi_boot_services_t *b; ++ ++ shim_used = 0; ++ shim_buffer = 0; ++ ++ status = grub_shim_verify (addr, size); ++ if (status != GRUB_ERR_NONE) ++ { ++ grub_error (GRUB_ERR_BAD_OS, "shim verification failed"); ++ return GRUB_ERR_BAD_OS; ++ } ++ ++ grub_memset(context, 0, sizeof(*context)); ++ status = grub_shim_read_header (addr, size, context); ++ if (status != GRUB_ERR_NONE) ++ { ++ grub_error (GRUB_ERR_BAD_OS, "read header failed"); ++ return GRUB_ERR_BAD_OS; ++ } ++ ++ /* TODO: do we need to do this with efi_allocate? */ ++ shim_pages = (((grub_efi_uintn_t) context->image_size + ((1 << 12) - 1)) >> 12); ++ ++ b = grub_efi_system_table->boot_services; ++ efi_status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, ++ GRUB_EFI_LOADER_CODE, shim_pages, &shim_buffer); ++ if (efi_status != GRUB_EFI_SUCCESS) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory for shim buffer")); ++ return GRUB_ERR_OUT_OF_MEMORY; ++ } ++ ++ /* TODO: do we need the double cast? */ ++ grub_memcpy ((void *) ((grub_efi_physical_address_t) shim_buffer), ++ (void *) ((grub_addr_t) addr), context->header_size); ++ /* ++ * Copy the executable's sections to their desired offsets ++ */ ++ section = context->first_section; ++ for (i = 0; i < context->num_sections; i++, section++) ++ { ++ if (section->characteristics & 0x02000000) ++ /* section has EFI_IMAGE_SCN_MEM_DISCARDABLE attr set */ ++ continue; ++ ++ sect_size = section->virtual_size; ++ ++ if (sect_size > section->raw_data_size) ++ sect_size = section->raw_data_size; ++ ++ base = (grub_int8_t *) ++ grub_shim_image_address (shim_buffer, context->image_size, ++ section->virtual_address); ++ end = (grub_int8_t *) ++ grub_shim_image_address (shim_buffer, context->image_size, ++ section->virtual_address ++ + sect_size - 1); ++ if (!base || !end) ++ { ++ grub_printf("Invalid section base\n"); ++ status = GRUB_ERR_BAD_FILE_TYPE; ++ goto fail; ++ } ++ ++ if (section->virtual_address < context->header_size ++ || section->raw_data_offset < context->header_size) ++ { ++ grub_printf("Section is inside image headers\n"); ++ status = GRUB_ERR_BAD_FILE_TYPE; ++ goto fail; ++ } ++ ++ if (section->raw_data_size > 0) ++ /* TODO: do we need the double cast? */ ++ grub_memcpy ((void *)base, ++ (void *) (((grub_addr_t) addr) ++ + section->raw_data_offset), sect_size); ++ ++ if (sect_size < section->virtual_size) ++ grub_memset ((void *)(base + sect_size), 0, ++ section->virtual_size - sect_size); ++ } ++ ++ if (context->number_of_rva_and_sizes <= EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) ++ { ++ grub_printf("Image has no relocation entry\n"); ++ status = GRUB_ERR_BAD_FILE_TYPE; ++ goto fail; ++ } ++ ++ if (context->reloc_dir->size) ++ { ++ status = grub_shim_relocate_coff (context, (void *) addr, ++ (void *) shim_buffer); ++ if (status != GRUB_ERR_NONE) ++ { ++ grub_printf("Relocation failed: [%u]\n", status); ++ status = GRUB_ERR_BAD_FILE_TYPE; ++ goto fail; ++ } ++ } ++ shim_entry_point = (void *)grub_shim_image_address (shim_buffer, ++ context->image_size, ++ context->entry_point); ++ if (!shim_entry_point) ++ { ++ grub_printf("Invalid entry point\n"); ++ status = GRUB_ERR_BAD_FILE_TYPE; ++ goto fail; ++ } ++ ++ shim_used = 1; ++ return GRUB_ERR_NONE; ++fail: ++ efi_call_2 (b->free_pages, shim_buffer, shim_pages); ++ shim_buffer = 0; ++ return status; ++} + + static grub_err_t + grub_chainloader_unload (void) +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0005-efi-chainloader-use-shim-to-load-and-verify-an-image.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0005-efi-chainloader-use-shim-to-load-and-verify-an-image.patch new file mode 100644 index 0000000..143a140 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0005-efi-chainloader-use-shim-to-load-and-verify-an-image.patch @@ -0,0 +1,98 @@ +From f922ac74714d01972a3c291e15f0c316b67e40eb Mon Sep 17 00:00:00 2001 +From: Ricardo Neri +Date: Fri, 27 Mar 2015 08:26:08 -0700 +Subject: [PATCH 5/7] efi: chainloader: use shim to load and verify an image + +Upstream-Status: Inappropriate [embedded specific] + +The grub chainloader module uses the UEFI LoadImage service +to load a chainloaded binary. However, if such binary is not +signed by the UEFI certification authority, LoadImage will fail. +Under shim, we can use Machine-Owned Keys (MOKs) to verify an +image. Thus, in case LoadImage fails due to a security violation +we rely on the shim verification service. If successful, the +image is parsed and loaded. + +Signed-off-by: Ricardo Neri +--- + grub-core/loader/efi/chainloader.c | 49 +++++++++++++++++++++++++++++++------- + 1 file changed, 40 insertions(+), 9 deletions(-) + +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index bd83859..01d2ebe 100644 +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -733,6 +733,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), + grub_efi_loaded_image_t *loaded_image; + char *filename; + grub_efi_handle_t dev_handle = 0; ++ struct grub_shim_pe_coff_loader_image_context context; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); +@@ -827,23 +828,53 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), + if (status != GRUB_EFI_SUCCESS) + { + if (status == GRUB_EFI_OUT_OF_RESOURCES) +- grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); ++ goto fail; ++ } ++ /* try with shim */ ++ else if (status == GRUB_EFI_SECURITY_VIOLATION) ++ { ++ status = grub_shim_load_image (address, size, &context); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ grub_error (GRUB_ERR_BAD_OS, "shim cannot load image"); ++ goto fail; ++ } ++ } + else +- grub_error (GRUB_ERR_BAD_OS, "cannot load image"); +- +- goto fail; ++ { ++ grub_error (GRUB_ERR_BAD_OS, "cannot load image"); ++ goto fail; ++ } + } + +- /* LoadImage does not set a device handler when the image is +- loaded from memory, so it is necessary to set it explicitly here. +- This is a mess. */ +- loaded_image = grub_efi_get_loaded_image (image_handle); ++ /* if we use shim, the UEFI load_image failed, thus, we borrow ++ * grub_efi_image_handle and restore it later ++ */ ++ if (shim_used) ++ /* if we use shim, the UEFI load_image failed, thus, we borrow ++ grub_efi_image_handle and restore it later */ ++ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); ++ else ++ /* LoadImage does not set a device handler when the image is ++ loaded from memory, so it is necessary to set it explicitly here. ++ This is a mess. */ ++ loaded_image = grub_efi_get_loaded_image (image_handle); ++ + if (! loaded_image) + { + grub_error (GRUB_ERR_BAD_OS, "no loaded image available"); + goto fail; + } +- loaded_image->device_handle = dev_handle; ++ if (shim_used) ++ { ++ grub_memcpy(&shim_li_bak, loaded_image, sizeof(shim_li_bak)); ++ loaded_image->image_base = (void *)shim_buffer; ++ loaded_image->image_size = context.image_size; ++ } ++ else ++ loaded_image->device_handle = dev_handle; + + grub_file_close (file); + +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0006-efi-chainloader-boot-the-image-using-shim.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0006-efi-chainloader-boot-the-image-using-shim.patch new file mode 100644 index 0000000..46ded18 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0006-efi-chainloader-boot-the-image-using-shim.patch @@ -0,0 +1,63 @@ +From f25778620360ccff55f3d9c1bccba14249978502 Mon Sep 17 00:00:00 2001 +From: Ricardo Neri +Date: Fri, 27 Mar 2015 08:29:13 -0700 +Subject: [PATCH 6/7] efi: chainloader: boot the image using shim + +Upstream-Status: Inappropriate [embedded specific] + +If the image was loaded using shim, boot the image. Given that +shim loaded the image, the UEFI firmware will not know where to +jump after the execution completes. Thus, replace the UEFI boot +service Exit with our own implementation to make sure we jump +to the instruction after the call to the entry point. + +Replace the system Exit service when done. + +Signed-off-by: Ricardo Neri +--- + grub-core/loader/efi/chainloader.c | 27 ++++++++++++++++++++++++++- + 1 file changed, 26 insertions(+), 1 deletion(-) + +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index 01d2ebe..1c9795c 100644 +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -605,9 +605,34 @@ grub_chainloader_boot (void) + grub_efi_status_t status; + grub_efi_uintn_t exit_data_size; + grub_efi_char16_t *exit_data = NULL; ++ grub_efi_loaded_image_t *loaded_image = NULL; ++ grub_efi_status_t ++ (*saved_exit) (grub_efi_handle_t image_handle, ++ grub_efi_status_t exit_status, ++ grub_efi_uintn_t exit_data_size, ++ grub_efi_char16_t *exit_data) __attribute__((noreturn)); + + b = grub_efi_system_table->boot_services; +- status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data); ++ ++ if (!shim_used) ++ status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data); ++ else ++ { ++ saved_exit = grub_efi_system_table->boot_services->exit; ++ grub_efi_system_table->boot_services->exit = efi_shim_exit; ++ status = efi_call_foo(shim_entry_point, ++ (grub_efi_uint64_t)grub_efi_image_handle, ++ (grub_efi_uint64_t)grub_efi_system_table); ++ grub_efi_system_table->boot_services->exit = saved_exit; ++ ++ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); ++ if (!loaded_image) ++ /* TODO: this is serious, what to do? */ ++ grub_error (GRUB_ERR_BAD_OS, "GRUB loaded image not found"); ++ else ++ /* restore loaded image */ ++ grub_memcpy(loaded_image, &shim_li_bak, sizeof(shim_li_bak)); ++ } + if (status != GRUB_EFI_SUCCESS) + { + if (exit_data) +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0007-efi-chainloader-take-care-of-unload-undershim.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0007-efi-chainloader-take-care-of-unload-undershim.patch new file mode 100644 index 0000000..6917b2f --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/0007-efi-chainloader-take-care-of-unload-undershim.patch @@ -0,0 +1,43 @@ +From 70a30826d1cfb7a90c34760896dfd92b9c396f52 Mon Sep 17 00:00:00 2001 +From: Ricardo Neri +Date: Fri, 27 Mar 2015 08:31:27 -0700 +Subject: [PATCH 7/7] efi: chainloader: take care of unload undershim + +Upstream-Status: Inappropriate [embedded specific] + +Under shim, we use a custom buffer to put the relocated image, make +sure we free that memory when unloading. + +Signed-off-by: Ricardo Neri +--- + grub-core/loader/efi/chainloader.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index 1c9795c..d0ceb6e 100644 +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -586,8 +586,18 @@ grub_chainloader_unload (void) + grub_efi_boot_services_t *b; + + b = grub_efi_system_table->boot_services; +- efi_call_1 (b->unload_image, image_handle); +- efi_call_2 (b->free_pages, address, pages); ++ if (!shim_used) ++ { ++ efi_call_1 (b->unload_image, image_handle); ++ efi_call_2 (b->free_pages, address, pages); ++ } ++ else ++ { ++ if (shim_buffer) ++ { ++ efi_call_2 (b->free_pages, shim_buffer, shim_pages); ++ } ++ } + + grub_free (file_path); + grub_free (cmdline); +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/Fix-32-bit-build-failures.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/Fix-32-bit-build-failures.patch new file mode 100644 index 0000000..6ba5352 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/Fix-32-bit-build-failures.patch @@ -0,0 +1,252 @@ +From e7b2efacc2d3acb48761aa2d62f943310fd70100 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Mon, 25 Apr 2016 11:35:14 +0800 +Subject: [PATCH] Fix 32-bit build failures + +Upstream-Status: Pending + +For 32-bit build, the 64-bit pointer should be replaced by grub_addr_t +which is compatible between 32-bit and 64-bit build. + +In addition, the functions efi_shim_exit and efi_call_foo should be available +for 32-bit build. + +Signed-off-by: Lans Zhang +--- + grub-core/Makefile.core.def | 1 + + grub-core/kern/i386/efi/callwrap.S | 50 ++++++++++++++++++++++++++++++++++++++ + grub-core/loader/efi/chainloader.c | 30 +++++++++++------------ + include/grub/efi/api.h | 8 +++--- + include/grub/efi/shim.h | 2 +- + 5 files changed, 71 insertions(+), 20 deletions(-) + create mode 100644 grub-core/kern/i386/efi/callwrap.S + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 39e77a4..0a78137 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -135,6 +135,7 @@ kernel = { + efi = term/efi/console.c; + + i386_efi = kern/i386/tsc.c; ++ i386_efi = kern/i386/efi/callwrap.S; + i386_efi = kern/i386/efi/init.c; + i386_efi = bus/pci.c; + +diff --git a/grub-core/kern/i386/efi/callwrap.S b/grub-core/kern/i386/efi/callwrap.S +new file mode 100644 +index 0000000..c683444 +--- /dev/null ++++ b/grub-core/kern/i386/efi/callwrap.S +@@ -0,0 +1,50 @@ ++/* callwrap.S - wrapper for i386 efi calls */ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2006,2007,2009 Free Software Foundation, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++ ++ .file "callwrap.S" ++ .text ++ ++FUNCTION(efi_call_foo) ++ movl 12(%esp), %eax ++ movl 8(%esp), %edx ++ movl 4(%esp), %ecx ++ pushl %ebx ++ pushl %esi ++ pushl %edi ++ pushl %ebp ++ movl %esp, saved_sp ++ subl $40, %esp ++ pushl %eax ++ pushl %edx ++ call *%ecx ++ ++FUNCTION(efi_shim_exit) ++ addl $48, %esp ++ movl saved_sp, %esp ++ popl %ebp ++ popl %edi ++ popl %esi ++ popl %ebx ++ ret ++ ++ .data ++saved_sp: .long 0 +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index 83769a2..e3d1138 100644 +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -149,7 +149,7 @@ grub_shim_image_is_loadable (union grub_shim_optional_header_union *pe_hdr) + /* + * Perform basic bounds checking of the intra-image pointers + */ +-static grub_efi_uint64_t ++static grub_addr_t + grub_shim_image_address (grub_addr_t image, grub_uint32_t size, grub_uint32_t addr) + { + if (addr > size) +@@ -208,12 +208,12 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, + * yield the next entry in the array. + */ + reloc_base = (struct grub_image_base_relocation *) +- grub_shim_image_address ((grub_efi_uint64_t)orig, size, ++ grub_shim_image_address ((grub_addr_t)orig, size, + section->raw_data_offset); + /* reloc_base_end is the address of the first entry /past/ the + * table. */ + reloc_base_end = (struct grub_image_base_relocation *) +- grub_shim_image_address ((grub_efi_uint64_t)orig, size, ++ grub_shim_image_address ((grub_addr_t)orig, size, + section->raw_data_offset + + section->virtual_size - 1); + +@@ -254,7 +254,7 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, + } + + fixup_base = (grub_uint8_t *) +- grub_shim_image_address ((grub_efi_uint64_t)data, ++ grub_shim_image_address ((grub_addr_t)data, + size, + reloc_base->virtual_address); + if (!fixup_base) +@@ -333,12 +333,12 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, + * Read the binary header and grab appropriate information from it + */ + static grub_err_t +-grub_shim_read_header(grub_efi_physical_address_t data, grub_uint32_t datasize, ++grub_shim_read_header(grub_addr_t data, grub_uint32_t datasize, + struct grub_shim_pe_coff_loader_image_context *context) + { + struct grub_dos_header *dos_hdr = (struct grub_dos_header *)data; + union grub_shim_optional_header_union *pe_hdr = (union grub_shim_optional_header_union *)data; +- grub_uint64_t header_without_data_dir, section_header_offset, opt_hdr_size; ++ grub_efi_uintn_t header_without_data_dir, section_header_offset, opt_hdr_size; + + if (datasize < sizeof (pe_hdr->pe32)) + { +@@ -393,7 +393,7 @@ grub_shim_read_header(grub_efi_physical_address_t data, grub_uint32_t datasize, + + sizeof (grub_efi_uint32_t) + + sizeof (struct grub_pe32_coff_header) + + pe_hdr->pe32.file_hdr.optional_header_size; +- if (((grub_efi_uint32_t)context->image_size - section_header_offset) ++ if ((context->image_size - section_header_offset) + / sizeof (struct grub_pe32_section_table) + <= context->num_sections) + { +@@ -530,7 +530,7 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, + } + + /* TODO: do we need the double cast? */ +- grub_memcpy ((void *) ((grub_efi_physical_address_t) shim_buffer), ++ grub_memcpy ((void *) ((grub_addr_t) shim_buffer), + (void *) ((grub_addr_t) addr), context->header_size); + + reloc_base = (grub_int8_t *) grub_shim_image_address (shim_buffer, size, +@@ -553,10 +553,10 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, + sect_size = section->raw_data_size; + + base = (grub_int8_t *) +- grub_shim_image_address (shim_buffer, context->image_size, ++ grub_shim_image_address ((grub_addr_t) shim_buffer, context->image_size, + section->virtual_address); + end = (grub_int8_t *) +- grub_shim_image_address (shim_buffer, context->image_size, ++ grub_shim_image_address ((grub_addr_t) shim_buffer, context->image_size, + section->virtual_address + + sect_size - 1); + +@@ -619,7 +619,7 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, + if (context->reloc_dir->size && reloc_section) + { + status = grub_shim_relocate_coff (context, reloc_section, +- (void *) addr, (void *) shim_buffer); ++ (void *) addr, (void *) ((grub_addr_t) shim_buffer)); + if (status != GRUB_ERR_NONE) + { + grub_printf("Relocation failed: [%u]\n", status); +@@ -627,7 +627,7 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, + goto fail; + } + } +- shim_entry_point = (void *)grub_shim_image_address (shim_buffer, ++ shim_entry_point = (void *)grub_shim_image_address ((grub_addr_t) shim_buffer, + context->image_size, + context->entry_point); + if (!shim_entry_point) +@@ -696,8 +696,8 @@ grub_chainloader_boot (void) + saved_exit = grub_efi_system_table->boot_services->exit; + grub_efi_system_table->boot_services->exit = efi_shim_exit; + status = efi_call_foo(shim_entry_point, +- (grub_efi_uint64_t)grub_efi_image_handle, +- (grub_efi_uint64_t)grub_efi_system_table); ++ grub_efi_image_handle, ++ grub_efi_system_table); + grub_efi_system_table->boot_services->exit = saved_exit; + + loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); +@@ -970,7 +970,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), + if (shim_used) + { + grub_memcpy(&shim_li_bak, loaded_image, sizeof(shim_li_bak)); +- loaded_image->image_base = (void *)shim_buffer; ++ loaded_image->image_base = (void *)(grub_addr_t) shim_buffer; + loaded_image->image_size = context.image_size; + } + else +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h +index 374d88b..22b3543 100644 +--- a/include/grub/efi/api.h ++++ b/include/grub/efi/api.h +@@ -1437,10 +1437,6 @@ typedef struct grub_efi_block_io grub_efi_block_io_t; + + grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func); + grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1); +-grub_efi_status_t EXPORT_FUNC(efi_shim_exit) (grub_efi_handle_t handle, grub_efi_status_t exit_status, +- grub_efi_uintn_t exit_data_size, grub_efi_char16_t *exit_data) __attribute__((noreturn)); +-grub_uint64_t EXPORT_FUNC(efi_call_foo) (void *func, grub_uint64_t arg1, +- grub_uint64_t arg2); + grub_uint64_t EXPORT_FUNC(efi_wrap_2) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2); + grub_uint64_t EXPORT_FUNC(efi_wrap_3) (void *func, grub_uint64_t arg1, +@@ -1467,4 +1463,8 @@ grub_uint64_t EXPORT_FUNC(efi_wrap_10) (void *func, grub_uint64_t arg1, + grub_uint64_t arg10); + #endif + ++grub_efi_status_t EXPORT_FUNC(efi_shim_exit) (grub_efi_handle_t handle, grub_efi_status_t exit_status, ++ grub_efi_uintn_t exit_data_size, grub_efi_char16_t *exit_data) __attribute__((noreturn)); ++grub_efi_status_t EXPORT_FUNC(efi_call_foo) (void *func, void *arg1, void *arg2); ++ + #endif /* ! GRUB_EFI_API_HEADER */ +diff --git a/include/grub/efi/shim.h b/include/grub/efi/shim.h +index 4b92a00..9fac90b 100644 +--- a/include/grub/efi/shim.h ++++ b/include/grub/efi/shim.h +@@ -60,7 +60,7 @@ struct grub_image_base_relocation + + struct grub_shim_pe_coff_loader_image_context { + grub_efi_uint64_t image_address; +- grub_efi_uint64_t image_size; ++ grub_efi_uintn_t image_size; + grub_efi_uint64_t entry_point; + grub_efi_uintn_t header_size; + grub_efi_uint16_t image_type; +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/Grub-get-and-set-efi-variables.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/Grub-get-and-set-efi-variables.patch new file mode 100644 index 0000000..7c30632 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/Grub-get-and-set-efi-variables.patch @@ -0,0 +1,263 @@ +--- + grub-core/Makefile.core.def | 8 + + grub-core/commands/efi/efivar.c | 238 ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 246 insertions(+) + +--- /dev/null ++++ b/grub-core/commands/efi/efivar.c +@@ -0,0 +1,238 @@ ++/* efivar.c - Read EFI global variables. */ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2015 Free Software Foundation, Inc. ++ * Copyright (C) 2015 CloudFlare, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static const struct grub_arg_option options[] = { ++ {"format", 'f', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR in specific format (hex, uint8, ascii, dump). Default: hex."), N_("FORMAT"), ARG_TYPE_STRING}, ++ {"set", 's', GRUB_ARG_OPTION_OPTIONAL, N_("Save parsed result to environment variable (does not work with dump)."), N_("ENV_VAR"), ARG_TYPE_STRING}, ++ {0, 0, 0, 0, 0, 0} ++}; ++ ++enum efi_var_type ++ { ++ EFI_VAR_ASCII = 0, ++ EFI_VAR_UINT8, ++ EFI_VAR_HEX, ++ EFI_VAR_DUMP, ++ EFI_VAR_INVALID = -1 ++ }; ++ ++static enum efi_var_type ++parse_efi_var_type (const char *type) ++{ ++ if (!grub_strncmp (type, "ascii", sizeof("ascii"))) ++ return EFI_VAR_ASCII; ++ ++ if (!grub_strncmp (type, "uint8", sizeof("uint8"))) ++ return EFI_VAR_UINT8; ++ ++ if (!grub_strncmp (type, "hex", sizeof("hex"))) ++ return EFI_VAR_HEX; ++ ++ if (!grub_strncmp (type, "dump", sizeof("dump"))) ++ return EFI_VAR_DUMP; ++ ++ return EFI_VAR_INVALID; ++} ++ ++static int ++grub_print_ascii (char *str, char c) ++{ ++ if (grub_iscntrl (c)) ++ { ++ switch (c) ++ { ++ case '\0': ++ str[0] = '\\'; ++ str[1] = '0'; ++ return 2; ++ ++ case '\a': ++ str[0] = '\\'; ++ str[1] = 'a'; ++ return 2; ++ ++ case '\b': ++ str[0] = '\\'; ++ str[1] = 'b'; ++ return 2; ++ ++ case '\f': ++ str[0] = '\\'; ++ str[1] = 'f'; ++ return 2; ++ ++ case '\n': ++ str[0] = '\\'; ++ str[1] = 'n'; ++ return 2; ++ ++ case '\r': ++ str[0] = '\\'; ++ str[1] = 'r'; ++ return 2; ++ ++ case '\t': ++ str[0] = '\\'; ++ str[1] = 't'; ++ return 2; ++ ++ case '\v': ++ str[0] = '\\'; ++ str[1] = 'v'; ++ return 2; ++ ++ default: ++ str[0] = '.'; /* as in hexdump -C */ ++ return 1; ++ } ++ } ++ ++ str[0] = c; ++ return 1; ++} ++ ++static grub_err_t ++grub_cmd_get_efi_var (struct grub_extcmd_context *ctxt, ++ int argc, char **args) ++{ ++ struct grub_arg_list *state = ctxt->state; ++ grub_err_t status; ++ void *efi_var = NULL; ++ grub_size_t efi_var_size = 0; ++ enum efi_var_type efi_type = EFI_VAR_HEX; ++ grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; ++ char *env_var = NULL; ++ grub_size_t i; ++ char *ptr; ++ ++ if (1 != argc) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); ++ ++ if (state[0].set) ++ efi_type = parse_efi_var_type (state[0].arg); ++ ++ if (EFI_VAR_INVALID == efi_type) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format specifier")); ++ ++ efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size); ++ if (!efi_var || !efi_var_size) ++ { ++ status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable")); ++ goto err; ++ } ++ ++ switch (efi_type) ++ { ++ case EFI_VAR_ASCII: ++ env_var = grub_malloc (efi_var_size * 2 + 1); ++ if (!env_var) ++ { ++ status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ break; ++ } ++ ++ ptr = env_var; ++ ++ for (i = 0; i < efi_var_size; i++) ++ ptr += grub_print_ascii (ptr, ((const char *)efi_var)[i]); ++ *ptr = '\0'; ++ break; ++ ++ case EFI_VAR_UINT8: ++ env_var = grub_malloc (4); ++ if (!env_var) ++ { ++ status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ break; ++ } ++ grub_snprintf (env_var, 4, "%u", *((grub_uint8_t *)efi_var)); ++ break; ++ ++ case EFI_VAR_HEX: ++ env_var = grub_malloc (efi_var_size * 2 + 1); ++ if (!env_var) ++ { ++ status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ break; ++ } ++ for (i = 0; i < efi_var_size; i++) ++ grub_snprintf (env_var + (i * 2), 3, "%02x", ((grub_uint8_t *)efi_var)[i]); ++ break; ++ ++ case EFI_VAR_DUMP: ++ if (state[1].set) ++ status = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set variable with dump format specifier")); ++ else ++ { ++ hexdump (0, (char *)efi_var, efi_var_size); ++ status = GRUB_ERR_NONE; ++ } ++ break; ++ ++ default: ++ status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug in module?)")); ++ } ++ ++ if (efi_type != EFI_VAR_DUMP) ++ { ++ if (state[1].set) ++ status = grub_env_set (state[1].arg, env_var); ++ else ++ { ++ grub_printf ("%s\n", (const char *)env_var); ++ status = GRUB_ERR_NONE; ++ } ++ } ++ ++err: ++ ++ if (env_var) ++ grub_free (env_var); ++ ++ if (efi_var) ++ grub_free (efi_var); ++ ++ return status; ++} ++ ++static grub_extcmd_t cmd = NULL; ++ ++GRUB_MOD_INIT (efivar) ++{ ++ cmd = grub_register_extcmd ("get_efivar", grub_cmd_get_efi_var, 0, N_("[-f FORMAT] [-s ENV_VAR] EFI_VAR"), ++ N_("Read EFI variable and print it or save its contents to environment variable."), options); ++} ++ ++GRUB_MOD_FINI (efivar) ++{ ++ if (cmd) ++ grub_unregister_extcmd (cmd); ++} +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -539,6 +539,14 @@ module = { + }; + + module = { ++ name = efivar; ++ ++ common = commands/efi/efivar.c; ++ ++ enable = efi; ++}; ++ ++module = { + name = lsacpi; + + common = commands/lsacpi.c; diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/Work-around-the-failure-of-ExitBootServices.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/Work-around-the-failure-of-ExitBootServices.patch new file mode 100644 index 0000000..ca4ad75 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/Work-around-the-failure-of-ExitBootServices.patch @@ -0,0 +1,62 @@ +From 9517b3173af961ea66721cfc48cd47e50a704388 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Wed, 4 Nov 2015 17:17:06 +0800 +Subject: [PATCH] Work around the failure of ExitBootServices() + +ExitBootServices() will fail if any of the event handlers change +the memory map. In which case, we must be prepared to retry, but +only once so that we're guaranteed to exit on repeated failures +instead of spinning forever. This fix refers to the workaround +made by Linux kernel. + +Signed-off-by: Lans Zhang +--- + grub-core/kern/efi/mm.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index 461deb0..7620a47 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -158,6 +158,7 @@ grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf, + { + grub_efi_boot_services_t *b; + grub_efi_status_t status; ++ int called_exit = 0; + + #if defined (__i386__) || defined (__x86_64__) + const grub_uint16_t apple[] = { 'A', 'p', 'p', 'l', 'e' }; +@@ -167,6 +168,7 @@ grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf, + apple, sizeof (apple)) == 0); + #endif + ++get_mem_map: + if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key, + &finish_desc_size, &finish_desc_version) < 0) + return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map"); +@@ -186,7 +188,21 @@ grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf, + status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, + finish_key); + if (status != GRUB_EFI_SUCCESS) +- return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services"); ++ { ++ /* ++ * ExitBootServices() will fail if any of the event ++ * handlers change the memory map. In which case, we ++ * must be prepared to retry, but only once so that ++ * we're guaranteed to exit on repeated failures instead ++ * of spinning forever. ++ */ ++ if (called_exit) ++ return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services"); ++ ++ called_exit = 1; ++ grub_free (finish_mmap_buf); ++ goto get_mem_map; ++ } + + grub_efi_is_finished = 1; + if (outbuf_size) +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/boot-menu.inc b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/boot-menu.inc new file mode 100644 index 0000000..9cc8726 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/boot-menu.inc @@ -0,0 +1,13 @@ +# Note the initrd command becomes not working if the command for +# loading image is changed to the chainloader command instead of +# the linux command. + +menuentry "Sample EFI boot" --unrestricted { + savedefault + set fallback=1 + chainloader /bzImage root=/dev/sda2 ro rootwait initrd=/initrd +} + +menuentry "Sample EFI boot (Recovery)" --unrestricted { + chainloader /bzImage_bakup root=/dev/sda2 ro rootwait initrd=/initrd_bakup +} diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/chainloader-Actually-find-the-relocations-correctly-.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/chainloader-Actually-find-the-relocations-correctly-.patch new file mode 100644 index 0000000..e5a0ebb --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/chainloader-Actually-find-the-relocations-correctly-.patch @@ -0,0 +1,219 @@ +From f6c412a240312a2be28b85905a0866288db9ffc8 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Sun, 24 Apr 2016 19:02:28 +0800 +Subject: [PATCH] chainloader: Actually find the relocations correctly and + process them that way. + +Upstream-Status: Pending + +Refer to a846aedd0e9dfe26ca6afaf6a1db8a54c20363c1 in shim. + +Find the relocations based on the *file* address in the old binary, +because it's only the same as the virtual address some of the time. + +Also perform some extra validation before processing it, and don't bail +out in /error/ if both ReloceBase and RelocEnd are null - that condition +is fine. + +Signed-off-by: Lans Zhang +--- + grub-core/loader/efi/chainloader.c | 97 +++++++++++++++++++++++++++++++------- + 1 file changed, 81 insertions(+), 16 deletions(-) + +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index 0e84100..83769a2 100644 +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -162,6 +162,7 @@ grub_shim_image_address (grub_addr_t image, grub_uint32_t size, grub_uint32_t ad + */ + static grub_err_t + grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, ++ struct grub_pe32_section_table *section, + void *orig, void *data) + { + struct grub_image_base_relocation *reloc_base, *reloc_base_end; +@@ -173,19 +174,53 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, + grub_efi_uint64_t *fixup64; + grub_int32_t size = context->image_size; + void *image_end = (char *)orig + size; ++ int n = 0; + + if (grub_shim_image_is_64_bit(context->pe_hdr)) + context->pe_hdr->pe32plus.opt_hdr.image_base = (grub_efi_uint64_t)(unsigned long)data; + else + context->pe_hdr->pe32.opt_hdr.image_base = (grub_efi_uint32_t)(unsigned long)data; + ++ ++ /* Alright, so here's how this works: ++ * ++ * context->RelocDir gives us two things: ++ * - the VA the table of base relocation blocks are (maybe) to be ++ * mapped at (RelocDir->VirtualAddress) ++ * - the virtual size (RelocDir->Size) ++ * ++ * The .reloc section (Section here) gives us some other things: ++ * - the name! kind of. (Section->Name) ++ * - the virtual size (Section->VirtualSize), which should be the same ++ * as RelocDir->Size ++ * - the virtual address (Section->VirtualAddress) ++ * - the file section size (Section->SizeOfRawData), which is ++ * a multiple of OptHdr->FileAlignment. Only useful for image ++ * validation, not really useful for iteration bounds. ++ * - the file address (Section->PointerToRawData) ++ * - a bunch of stuff we don't use that's 0 in our binaries usually ++ * - Flags (Section->Characteristics) ++ * ++ * and then the thing that's actually at the file address is an array ++ * of EFI_IMAGE_BASE_RELOCATION structs with some values packed behind ++ * them. The SizeOfBlock field of this structure includes the ++ * structure itself, and adding it to that structure's address will ++ * yield the next entry in the array. ++ */ + reloc_base = (struct grub_image_base_relocation *) + grub_shim_image_address ((grub_efi_uint64_t)orig, size, +- context->reloc_dir->rva); ++ section->raw_data_offset); ++ /* reloc_base_end is the address of the first entry /past/ the ++ * table. */ + reloc_base_end = (struct grub_image_base_relocation *) + grub_shim_image_address ((grub_efi_uint64_t)orig, size, +- context->reloc_dir->rva +- + context->reloc_dir->size - 1); ++ section->raw_data_offset ++ + section->virtual_size - 1); ++ ++ if (!reloc_base && !reloc_base_end) ++ { ++ return GRUB_EFI_SUCCESS; ++ } + + if (!reloc_base || !reloc_base_end) + { +@@ -206,7 +241,7 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, + if ((reloc_base->block_size == 0) + || (reloc_base->block_size > context->reloc_dir->size)) + { +- grub_printf("Reloc block size %d is invalid\n", reloc_base->block_size); ++ grub_printf("Reloc %d block size %d is invalid\n", n, reloc_base->block_size); + return GRUB_ERR_FILE_READ_ERROR; + } + +@@ -214,7 +249,7 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, + ((grub_uint8_t *) reloc_base + reloc_base->block_size); + if ((void *)reloc_end < orig || (void *)reloc_end > image_end) + { +- grub_printf("Reloc entry overflows binary\n"); ++ grub_printf("Reloc %d entry overflows binary\n", n); + return GRUB_ERR_FILE_READ_ERROR; + } + +@@ -224,7 +259,7 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, + reloc_base->virtual_address); + if (!fixup_base) + { +- grub_printf("Invalid fixup_base\n"); ++ grub_printf("Reloc %d invalid fixup_base\n", n); + return GRUB_ERR_FILE_READ_ERROR; + } + +@@ -282,12 +317,13 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context, + break; + + default: +- grub_printf("Unknown relocation\n"); ++ grub_printf("Reloc %d unknown relocation\n", n); + return GRUB_ERR_FILE_READ_ERROR; + } + reloc += 1; + } + reloc_base = (struct grub_image_base_relocation *) reloc_end; ++ n++; + } + + return GRUB_EFI_SUCCESS; +@@ -458,9 +494,9 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, + grub_efi_status_t efi_status; + grub_uint32_t sect_size; + /* TODO: can they be unsigned? */ +- grub_int8_t *base, *end; ++ grub_int8_t *base, *end, *reloc_base, *reloc_base_end; + grub_int32_t i; +- struct grub_pe32_section_table *section; ++ struct grub_pe32_section_table *section, *reloc_section; + grub_efi_boot_services_t *b; + + shim_used = 0; +@@ -496,16 +532,21 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, + /* TODO: do we need the double cast? */ + grub_memcpy ((void *) ((grub_efi_physical_address_t) shim_buffer), + (void *) ((grub_addr_t) addr), context->header_size); ++ ++ reloc_base = (grub_int8_t *) grub_shim_image_address (shim_buffer, size, ++ context->reloc_dir->rva); ++ /* reloc_base_end here is the address of the last byte of the table */ ++ reloc_base_end = (grub_int8_t *) grub_shim_image_address (shim_buffer, size, ++ context->reloc_dir->rva + ++ context->reloc_dir->size - 1); ++ reloc_section = NULL; ++ + /* + * Copy the executable's sections to their desired offsets + */ + section = context->first_section; + for (i = 0; i < context->num_sections; i++, section++) + { +- if (section->characteristics & 0x02000000) +- /* section has EFI_IMAGE_SCN_MEM_DISCARDABLE attr set */ +- continue; +- + sect_size = section->virtual_size; + + if (sect_size > section->raw_data_size) +@@ -518,6 +559,30 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, + grub_shim_image_address (shim_buffer, context->image_size, + section->virtual_address + + sect_size - 1); ++ ++ /* We do want to process .reloc, but it's often marked ++ * discardable, so we don't want to memcpy it. */ ++ if (grub_memcmp (section->name, ".reloc\0\0", 8) == 0) { ++ if (reloc_section) { ++ grub_printf("Image has multiple relocation sections\n"); ++ status = GRUB_ERR_BAD_FILE_TYPE; ++ goto fail; ++ } ++ /* If it has nonzero sizes, and our bounds check ++ * made sense, and the VA and size match RelocDir's ++ * versions, then we believe in this section table. */ ++ if (section->raw_data_size && section->virtual_size && ++ base && end && ++ reloc_base == base && ++ reloc_base_end == end) { ++ reloc_section = section; ++ } ++ } ++ ++ if (section->characteristics & 0x02000000) ++ /* section has EFI_IMAGE_SCN_MEM_DISCARDABLE attr set */ ++ continue; ++ + if (!base || !end) + { + grub_printf("Invalid section base\n"); +@@ -551,10 +616,10 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, + goto fail; + } + +- if (context->reloc_dir->size) ++ if (context->reloc_dir->size && reloc_section) + { +- status = grub_shim_relocate_coff (context, (void *) addr, +- (void *) shim_buffer); ++ status = grub_shim_relocate_coff (context, reloc_section, ++ (void *) addr, (void *) shim_buffer); + if (status != GRUB_ERR_NONE) + { + grub_printf("Relocation failed: [%u]\n", status); +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/chainloader-Don-t-check-empty-section-in-file-like-..patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/chainloader-Don-t-check-empty-section-in-file-like-..patch new file mode 100644 index 0000000..482ca5c --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/chainloader-Don-t-check-empty-section-in-file-like-..patch @@ -0,0 +1,32 @@ +From d3a1198bfc671530ed77ad2b81b0ae4582f9378e Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Sun, 24 Apr 2016 15:56:38 +0800 +Subject: [PATCH] chainloader: Don't check empty section in file like .bss + +Upstream-Status: Pending + +Because this kind of section always has a zeroed PointerToRawData denoting +the offset to file and a valid VirtualSize denoting the real size in the +memory. + +Signed-off-by: Lans Zhang +--- + grub-core/loader/efi/chainloader.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index 2d8edc0..0e84100 100644 +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -526,7 +526,7 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size, + } + + if (section->virtual_address < context->header_size +- || section->raw_data_offset < context->header_size) ++ || (section->raw_data_offset && section->raw_data_offset < context->header_size)) + { + grub_printf("Section is inside image headers\n"); + status = GRUB_ERR_BAD_FILE_TYPE; +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/chainloader-handle-the-unauthenticated-image-by-shim.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/chainloader-handle-the-unauthenticated-image-by-shim.patch new file mode 100644 index 0000000..3a3a7a8 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/chainloader-handle-the-unauthenticated-image-by-shim.patch @@ -0,0 +1,32 @@ +From b945262cdbad67e59f0d13725181862aa8a29561 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Sun, 24 Apr 2016 12:58:10 +0800 +Subject: [PATCH] chainloader: handle the unauthenticated image by shim + +Upstream-Status: Pending + +EFI_ACCESS_DENIED is another case whenever an unauthenticated image is loaded +by UEFI LoadImage() boot service. Shim verification protocol should handle +this case as EFI_SECURITY_VIOLATION. + +Signed-off-by: Lans Zhang +--- + grub-core/loader/efi/chainloader.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index 9f908c3..2850627 100644 +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -868,7 +868,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + /* try with shim */ +- else if (status == GRUB_EFI_SECURITY_VIOLATION) ++ else if ((status == GRUB_EFI_ACCESS_DENIED) || (status == GRUB_EFI_SECURITY_VIOLATION)) + { + status = grub_shim_load_image (address, size, &context); + if (status != GRUB_EFI_SUCCESS) +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/efi-secure-boot.inc b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/efi-secure-boot.inc new file mode 100644 index 0000000..a1518e1 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/efi-secure-boot.inc @@ -0,0 +1,38 @@ +get_efivar -f uint8 -s secured SecureBoot + +if [ "${secured}" = "1" ]; then + if [ -s "${prefix}/password.inc" ]; then + source "${prefix}/password.inc" + fi +fi + +get_efivar -f uint8 -s unprovisioned SetupMode + +if [ "${unprovisioned}" = "1" ]; then + # Create a boot entry for Automatic Certificate Provision. + # This is especially useful for certain hardware, e.g, + # Intel NUC5i3MYHE, doedn't support to display a customized + # BIOS boot option used to launch LockDown.efi. + + if [ ! "${provision_failed}" ]; then + # Secure boot was disabled in BIOS setup. Overwrite the + # behavior of normal boot. + set timeout=0 + set default="Automatic Certificate Provision" + elif [ "${provision_failed}" = "0" ]; then + # The auto provision was reset in BIOS setup. + set default="Automatic Certificate Provision" + fi + + # This menu will be hidden as long as the provision succeeds. + menuentry "Automatic Certificate Provision" --unrestricted { + set provision_failed="0" + save_env provision_failed + + chainloader "${prefix}/LockDown.efi" + + # Refuse to unlimitedly run into auto provision if failed. + set provision_failed="1" + save_env provision_failed + } +fi diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/grub-efi.cfg b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/grub-efi.cfg new file mode 100644 index 0000000..4093f59 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/grub-efi.cfg @@ -0,0 +1,36 @@ +set timeout=3 +set color_normal="light-gray/black" +set color_highlight="light-green/blue" + +# The first boot entry in normal boot. +set first_boot="0" + +# The default boot entry after the first boot. +set default_boot="0" + +function savedefault { + if [ "${chosen}" ]; then + next_boot="${chosen}" + save_env next_boot + fi +} + +if [ -s "${prefix}/grubenv" ]; then + load_env +fi + +if [ "${next_boot}" ]; then + set default="${next_boot}" +else + set default="${first_boot}" + set next_boot="${default_boot}" + save_env next_boot +fi + +if [ -s "${prefix}/efi-secure-boot.inc" ]; then + source "${prefix}/efi-secure-boot.inc" +fi + +if [ -s "${prefix}/boot-menu.inc" ]; then + source "${prefix}/boot-menu.inc" +fi diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/grub-enable-serial-console-by-default.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/grub-enable-serial-console-by-default.patch new file mode 100644 index 0000000..6d00e4d --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/grub-enable-serial-console-by-default.patch @@ -0,0 +1,30 @@ +From cd9fbf5dc00733f8e46966e67be85ff6f9d36e6e Mon Sep 17 00:00:00 2001 +From: Paul Gortmaker +Date: Fri, 10 Apr 2015 18:38:23 -0400 +Subject: [PATCH] grub: enable serial console by default + +Have grub go to the serial console and the default VGA console. + +Signed-off-by: Paul Gortmaker +--- + util/grub.d/00_header.in | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in +index 765bfdcd30e3..86b260a2c380 100644 +--- a/util/grub.d/00_header.in ++++ b/util/grub.d/00_header.in +@@ -27,6 +27,10 @@ grub_lang=`echo $LANG | cut -d . -f 1` + export TEXTDOMAIN=@PACKAGE@ + export TEXTDOMAINDIR="@localedir@" + ++export GRUB_TERMINAL_INPUT="console serial" ++export GRUB_TERMINAL_OUTPUT="console serial" ++export GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1" ++ + . "@datadir@/@PACKAGE@/grub-mkconfig_lib" + + # Do this as early as possible, since other commands might depend on it. +-- +2.3.1 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/mok2verify-support-to-verify-non-PE-file-with-PKCS-7.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/mok2verify-support-to-verify-non-PE-file-with-PKCS-7.patch new file mode 100644 index 0000000..b5a0a52 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/mok2verify-support-to-verify-non-PE-file-with-PKCS-7.patch @@ -0,0 +1,709 @@ +From 46873e2c5514bf6460a2f0f39ad8f8feb8f18f68 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Thu, 16 Mar 2017 14:49:41 +0800 +Subject: [PATCH] mok2verify: support to verify non-PE file with PKCS#7 + signature + +MOK2 Verify Protocol is designed to verify non-PE file which cannot be +verified by the MOK verify protocol supplied by shim loader, such as grub +configuration, initrd, grub modules and so on. + +Each signed file has a .p7b PKCS#7 signature file for verification. For +more details about signature format and singing tool, refer to +https://github.com/jiazhang0/SELoader and https://github.com/jiazhang0/libsign + +If either kernel or initrd is not authenticated, just go to the failover +boot to avoid a much worse failure. + +If any of grub config files is not authenticated, the boot process just +stops there. + +In addition, the editor, rescue and cmdline modes are protected by the +combination of settings of secure boot and user authentication in order +to prevent from tampering the kernel commandline or booting unsigned +kernel. + +Signed-off-by: Lans Zhang +--- + grub-core/Makefile.core.def | 6 ++ + grub-core/commands/boot.c | 14 +++- + grub-core/gfxmenu/gui_label.c | 39 ++++++++-- + grub-core/lib/efi/mok2verify.c | 172 +++++++++++++++++++++++++++++++++++++++++ + grub-core/loader/i386/linux.c | 80 +++++++++++++++++++ + grub-core/normal/main.c | 55 ++++++++++++- + grub-core/normal/menu.c | 29 +++++-- + grub-core/normal/menu_text.c | 32 ++++++-- + include/grub/efi/mok2verify.h | 48 ++++++++++++ + 9 files changed, 447 insertions(+), 28 deletions(-) + create mode 100644 grub-core/lib/efi/mok2verify.c + create mode 100644 include/grub/efi/mok2verify.h + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index e9e1483..8e72251 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1434,6 +1434,12 @@ module = { + }; + + module = { ++ name = mok2verify; ++ efi = lib/efi/mok2verify.c; ++ enable = efi; ++}; ++ ++module = { + name = mmap; + common = mmap/mmap.c; + x86 = mmap/i386/uppermem.c; +diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c +index 91ec87d..5cddbb6 100644 +--- a/grub-core/commands/boot.c ++++ b/grub-core/commands/boot.c +@@ -24,6 +24,9 @@ + #include + #include + #include ++#ifdef GRUB_MACHINE_EFI ++#include ++#endif + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -143,8 +146,15 @@ grub_loader_boot (void) + struct grub_preboot *cur; + + if (! grub_loader_loaded) +- return grub_error (GRUB_ERR_NO_KERNEL, +- N_("you need to load the kernel first")); ++ { ++#ifdef GRUB_MACHINE_EFI ++ if (grub_is_secured () == 1) ++ return grub_error (GRUB_ERR_BAD_OS, ++ N_("you need to load the authenticated boot components")); ++#endif ++ return grub_error (GRUB_ERR_NO_KERNEL, ++ N_("you need to load the kernel first")); ++ } + + if (grub_loader_flags & GRUB_LOADER_FLAG_NORETURN) + grub_machine_fini (); +diff --git a/grub-core/gfxmenu/gui_label.c b/grub-core/gfxmenu/gui_label.c +index 637578f..84bf7d4 100644 +--- a/grub-core/gfxmenu/gui_label.c ++++ b/grub-core/gfxmenu/gui_label.c +@@ -23,6 +23,9 @@ + #include + #include + #include ++#ifdef GRUB_MACHINE_EFI ++#include ++#endif + + static const char *align_options[] = + { +@@ -180,15 +183,37 @@ label_set_property (void *vself, const char *name, const char *value) + else + { + if (grub_strcmp (value, "@KEYMAP_LONG@") == 0) +- value = _("Press enter to boot the selected OS, " +- "`e' to edit the commands before booting " +- "or `c' for a command-line. ESC to return previous menu."); ++ { ++#ifdef GRUB_MACHINE_EFI ++ if (grub_is_locked () == 1) ++ value = _("Press enter to boot the selected OS. " ++ "ESC to return previous menu."); ++ else ++#endif ++ value = _("Press enter to boot the selected OS, " ++ "`e' to edit the commands before booting " ++ "or `c' for a command-line. ESC to return previous menu."); ++ } + else if (grub_strcmp (value, "@KEYMAP_MIDDLE@") == 0) +- value = _("Press enter to boot the selected OS, " +- "`e' to edit the commands before booting " +- "or `c' for a command-line."); ++ { ++#ifdef GRUB_MACHINE_EFI ++ if (grub_is_locked () == 1) ++ value = _("Press enter to boot the selected OS."); ++ else ++#endif ++ value = _("Press enter to boot the selected OS, " ++ "`e' to edit the commands before booting " ++ "or `c' for a command-line."); ++ } + else if (grub_strcmp (value, "@KEYMAP_SHORT@") == 0) +- value = _("enter: boot, `e': options, `c': cmd-line"); ++ { ++#ifdef GRUB_MACHINE_EFI ++ if (grub_is_locked () == 1) ++ value = _("enter: boot"); ++ else ++#endif ++ value = _("enter: boot, `e': options, `c': cmd-line"); ++ } + /* FIXME: Add more templates here if needed. */ + self->template = grub_strdup (value); + self->text = grub_xasprintf (value, self->value); +diff --git a/grub-core/lib/efi/mok2verify.c b/grub-core/lib/efi/mok2verify.c +new file mode 100644 +index 0000000..2e48ef9 +--- /dev/null ++++ b/grub-core/lib/efi/mok2verify.c +@@ -0,0 +1,172 @@ ++/* mok2verify.c - MOK2 Verify Protocol support ++ * ++ * BSD 2-clause "Simplified" License ++ * ++ * Copyright (c) 2017, Lans Zhang ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * * Redistributions of source code must retain the above copyright notice, this ++ * list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ++ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ++ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv2+"); ++ ++#define EFI_MOK2_VERIFY_PROTOCOL_GUID \ ++ { 0x4eda73ad, 0x07aa, 0x4b7a, \ ++ { 0xa1, 0x91, 0xd4, 0xd4, 0x10, 0xfb, 0x8c, 0xb4 } \ ++ } ++ ++typedef struct efi_mok2_verify_protocol efi_mok2_verify_protocol_t; ++ ++typedef grub_efi_status_t ++(*grub_efi_mok2_verify_signature) (efi_mok2_verify_protocol_t *this, ++ void *signature, ++ grub_efi_uintn_t signature_size, ++ void *data, grub_efi_uintn_t data_size); ++ ++typedef grub_efi_status_t ++(*grub_efi_mok2_verify_file_buffer) (efi_mok2_verify_protocol_t *this, ++ void **data, grub_efi_uintn_t *data_size, ++ const grub_efi_char16_t *path); ++ ++typedef grub_efi_status_t ++(*grub_efi_mok2_verify_file) (efi_mok2_verify_protocol_t *this, ++ const grub_efi_char16_t *path); ++ ++struct efi_mok2_verify_protocol { ++ grub_efi_uint8_t revision; ++ grub_efi_mok2_verify_signature verify_signature; ++ grub_efi_mok2_verify_file_buffer verify_file_buffer; ++ grub_efi_mok2_verify_file verify_file; ++}; ++ ++static grub_efi_guid_t grub_efi_mok2_verify_protoco_guid = EFI_MOK2_VERIFY_PROTOCOL_GUID; ++ ++int ++grub_is_secured (void) ++{ ++ grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; ++ void *efi_var; ++ grub_size_t efi_var_size = 0; ++ int secured = 0; ++ ++ efi_var = grub_efi_get_variable ("SecureBoot", &global, &efi_var_size); ++ if (!efi_var) ++ return grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable")); ++ ++ if (efi_var_size == 1 && *(grub_uint8_t *) efi_var == 1) ++ secured = 1; ++ ++ grub_free (efi_var); ++ ++ return secured; ++} ++ ++int ++grub_is_unlockable (void) ++{ ++ return !! grub_env_get ("superusers"); ++} ++ ++int ++grub_is_locked (void) ++{ ++ return ! grub_is_unlockable () && grub_is_secured (); ++} ++ ++grub_err_t ++grub_verify_file (const char *path) ++{ ++ efi_mok2_verify_protocol_t *mok2; ++ grub_efi_char16_t *p; ++ grub_size_t len = grub_strlen (path); ++ grub_efi_char16_t file_path[(len + 1) * GRUB_MAX_UTF16_PER_UTF8]; ++ const char *root; ++ const char *real_path; ++ grub_efi_status_t status; ++ ++ mok2 = grub_efi_locate_protocol (&grub_efi_mok2_verify_protoco_guid, 0); ++ if (!mok2) ++ { ++ grub_dprintf ("mok2verify", "unable to load mok2 verify protocol\n"); ++ return GRUB_ERR_NONE; ++ } ++ ++ grub_dprintf ("mok2verify", "attempting to verify the file %s ...\n", path); ++ ++ real_path = path; ++ root = grub_env_get ("root"); ++ if (root) ++ { ++ char *pattern; ++ ++ pattern = grub_xasprintf ("(%s)", root); ++ if (!pattern) ++ return grub_errno; ++ ++ if (grub_strstr (path, pattern) == path) ++ { ++ real_path = path + grub_strlen (pattern); ++ len -= grub_strlen (pattern); ++ } ++ ++ grub_free (pattern); ++ } ++ ++ len = grub_utf8_to_utf16 (file_path, len * GRUB_MAX_UTF16_PER_UTF8, ++ (const grub_uint8_t *) real_path, len, 0); ++ file_path[len] = 0; ++ for (p = file_path; p < file_path + len; ++p) ++ if (*p == '/') ++ *p = '\\'; ++ ++ status = efi_call_2 (mok2->verify_file, mok2, file_path); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ if (status == GRUB_EFI_NOT_FOUND) ++ return grub_error (GRUB_ERR_FILE_NOT_FOUND, "the specified file %s is not found", ++ path); ++ else ++ { ++ grub_printf ("failed to verify file %s (err: 0x%lx)\n", ++ path, status); ++ ++ return grub_error (GRUB_ERR_ACCESS_DENIED, "the file %s is not verified", ++ path); ++ } ++ } ++ ++ grub_dprintf ("mok2verify", "succeeded to verify file %s\n", path); ++ ++ return GRUB_ERR_NONE; ++} +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index e2425c8..5a12444 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -34,6 +34,9 @@ + #include + #include + #include ++#ifdef GRUB_MACHINE_EFI ++#include ++#endif + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -664,6 +667,55 @@ grub_linux_unload (void) + return GRUB_ERR_NONE; + } + ++#ifdef GRUB_MACHINE_EFI ++static grub_err_t ++grub_verify_linux (const char *path) ++{ ++ grub_file_t file; ++ grub_ssize_t size; ++ grub_uint8_t *buf = NULL; ++ ++ grub_dprintf ("linux", "Verifying kernel %s\n", path); ++ ++ file = grub_file_open (path); ++ if (!file) ++ return grub_errno; ++ ++ size = grub_file_size (file); ++ ++ buf = grub_malloc (size); ++ if (!buf) ++ goto fail; ++ ++ if (grub_file_read (file, buf, size) != size) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of kernel file %s"), ++ path); ++ goto fail; ++ } ++ ++ if (grub_verify_file (path) == GRUB_ERR_NONE) ++ grub_dprintf ("linux", "kernel %s verified\n", path); ++ else ++ grub_error (grub_errno, N_("failed to verify kernel %s"), path); ++ ++fail: ++ if (buf) ++ grub_free (buf); ++ ++ grub_file_close (file); ++ ++ return grub_errno; ++} ++#else ++static grub_err_t ++grub_verify_linux (const char *path) ++{ ++ return GRUB_ERR_NONE; ++} ++#endif ++ + static grub_err_t + grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +@@ -687,6 +739,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + ++ if (grub_verify_linux (argv[0])) ++ goto fail; ++ + file = grub_file_open (argv[0]); + if (! file) + goto fail; +@@ -1132,6 +1187,26 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + argv[i]); + goto fail; + } ++ ++#ifdef GRUB_MACHINE_EFI ++ grub_dprintf ("linux", "Verifying initrd %s, addr=0x%lx, size=0x%lx\n", ++ argv[i], (unsigned long) ptr, (unsigned long) cursize); ++ ++ /* ++ * XXX: use grub_verify_file_buffer (argv[i], ptr, cursize) in future ++ */ ++ err = grub_verify_file (argv[i]); ++ if (err == GRUB_ERR_NONE) ++ { ++ grub_dprintf ("linux", "initrd %s verified\n", argv[i]); ++ } ++ else ++ { ++ grub_error (err, N_("failed to verify initrd %s"), argv[i]); ++ goto fail; ++ } ++#endif ++ + ptr += cursize; + grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); + ptr += ALIGN_UP_OVERHEAD (cursize, 4); +@@ -1149,6 +1224,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + grub_file_close (files[i]); + grub_free (files); + ++#ifdef GRUB_MACHINE_EFI ++ /* An unauthenticated initrd always causes a complete boot failure. */ ++ if (grub_is_secured () == 1 && grub_errno != GRUB_ERR_NONE) ++ grub_loader_unset(); ++#endif + return grub_errno; + } + +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 13473ec..f11ce2a 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -32,6 +32,9 @@ + #include + #include + #include ++#ifdef GRUB_MACHINE_EFI ++#include ++#endif + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -233,6 +236,16 @@ grub_normal_init_page (struct grub_term_output *term) + + grub_term_cls (term); + ++#ifdef GRUB_MACHINE_EFI ++ if (grub_is_secured () == 1) ++ { ++ if (grub_is_unlockable () == 1) ++ msg = _("GNU GRUB version %s (UNLOCKABLE)"); ++ else ++ msg = _("GNU GRUB version %s (LOCKED)"); ++ } ++#endif ++ + msg_formatted = grub_xasprintf (msg, PACKAGE_VERSION); + if (!msg_formatted) + return; +@@ -294,6 +307,24 @@ grub_normal_execute (const char *config, int nested, int batch) + + if (config) + { ++#ifdef GRUB_MACHINE_EFI ++ grub_err_t err; ++ ++ err = grub_verify_file (config); ++ if (err != GRUB_ERR_NONE) ++ { ++ grub_error (err, "Security Violation: grub.cfg failed to load"); ++ grub_print_error (); ++ ++ /* System halt. */ ++ asm volatile ("cli"); ++ while (1) ++ { ++ asm volatile ("hlt"); ++ } ++ } ++#endif ++ + menu = read_config_file (config); + + /* Ignore any error. */ +@@ -317,7 +348,10 @@ grub_enter_normal_mode (const char *config) + { + nested_level++; + grub_normal_execute (config, 0, 0); +- grub_cmdline_run (0); ++#ifdef GRUB_MACHINE_EFI ++ if (grub_is_locked () == 0) ++#endif ++ grub_cmdline_run (0); + nested_level--; + if (grub_normal_exit_level) + grub_normal_exit_level--; +@@ -352,6 +386,18 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + grub_enter_normal_mode (argv[0]); + + quit: ++#ifdef GRUB_MACHINE_EFI ++ if (grub_is_secured () == 1) ++ { ++ /* Never return back to the rescue mode */ ++ asm volatile ("cli"); ++ ++ while (1) ++ { ++ asm volatile ("hlt"); ++ } ++ } ++#endif + return 0; + } + +@@ -527,8 +573,11 @@ GRUB_MOD_INIT(normal) + /* Register a command "normal" for the rescue mode. */ + grub_register_command ("normal", grub_cmd_normal, + 0, N_("Enter normal mode.")); +- grub_register_command ("normal_exit", grub_cmd_normal_exit, +- 0, N_("Exit from normal mode.")); ++#ifdef GRUB_MACHINE_EFI ++ if (grub_is_secured () == 0) ++#endif ++ grub_register_command ("normal_exit", grub_cmd_normal_exit, ++ 0, N_("Exit from normal mode.")); + + /* Reload terminal colors when these variables are written to. */ + grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal); +diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c +index 7e0a158..5ed9670 100644 +--- a/grub-core/normal/menu.c ++++ b/grub-core/normal/menu.c +@@ -32,6 +32,9 @@ + #include + #include + #include ++#ifdef GRUB_MACHINE_EFI ++#include ++#endif + + /* Time to delay after displaying an error message about a default/fallback + entry failing to boot. */ +@@ -633,18 +636,28 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) + break; + + case 'c': +- menu_fini (); +- grub_cmdline_run (1); +- goto refresh; ++#ifdef GRUB_MACHINE_EFI ++ if (grub_is_locked () == 0) ++#endif ++ { ++ menu_fini (); ++ grub_cmdline_run (1); ++ goto refresh; ++ } + + case 'e': +- menu_fini (); ++#ifdef GRUB_MACHINE_EFI ++ if (grub_is_locked () == 0) ++#endif + { +- grub_menu_entry_t e = grub_menu_get_entry (menu, current_entry); +- if (e) +- grub_menu_entry_run (e); ++ menu_fini (); ++ { ++ grub_menu_entry_t e = grub_menu_get_entry (menu, current_entry); ++ if (e) ++ grub_menu_entry_run (e); ++ } ++ goto refresh; + } +- goto refresh; + + default: + { +diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c +index 1687c28..6e4fbfb 100644 +--- a/grub-core/normal/menu_text.c ++++ b/grub-core/normal/menu_text.c +@@ -27,6 +27,9 @@ + #include + #include + #include ++#ifdef GRUB_MACHINE_EFI ++#include ++#endif + + static grub_uint8_t grub_color_menu_normal; + static grub_uint8_t grub_color_menu_highlight; +@@ -179,19 +182,32 @@ command-line or ESC to discard edits and return to the GRUB menu."), + + if (nested) + { ++#ifdef GRUB_MACHINE_EFI ++ if (grub_is_locked () == 1) ++ msg = _("Press enter to boot the selected OS. " ++ "ESC to return previous menu."); ++ else ++#endif ++ msg = _("Press enter to boot the selected OS, " ++ "`e' to edit the commands before booting " ++ "or `c' for a command-line. ESC to return previous menu."); ++ + ret += grub_print_message_indented_real +- (_("Press enter to boot the selected OS, " +- "`e' to edit the commands before booting " +- "or `c' for a command-line. ESC to return previous menu."), +- STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); ++ (msg, STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); + } + else + { ++#ifdef GRUB_MACHINE_EFI ++ if (grub_is_locked () == 1) ++ msg = _("Press enter to boot the selected OS."); ++ else ++#endif ++ msg = _("Press enter to boot the selected OS, " ++ "`e' to edit the commands before booting " ++ "or `c' for a command-line."); ++ + ret += grub_print_message_indented_real +- (_("Press enter to boot the selected OS, " +- "`e' to edit the commands before booting " +- "or `c' for a command-line."), +- STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); ++ (msg, STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); + } + } + return ret; +diff --git a/include/grub/efi/mok2verify.h b/include/grub/efi/mok2verify.h +new file mode 100644 +index 0000000..98ef2d4 +--- /dev/null ++++ b/include/grub/efi/mok2verify.h +@@ -0,0 +1,48 @@ ++/* ++ * mok2verify.h - interface to MOK2 Verify Protocol ++ * ++ * BSD 2-clause "Simplified" License ++ * ++ * Copyright (c) 2017, Lans Zhang ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * * Redistributions of source code must retain the above copyright notice, this ++ * list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ++ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ++ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifndef GRUB_EFI_MOK2_VERIFY_HEADER ++#define GRUB_EFI_MOK2_VERIFY_HEADER 1 ++ ++#include ++ ++int ++EXPORT_FUNC (grub_is_secured) (void); ++ ++int ++EXPORT_FUNC (grub_is_locked) (void); ++ ++int ++EXPORT_FUNC (grub_is_unlockable) (void); ++ ++grub_err_t ++EXPORT_FUNC (grub_verify_file) (const char *path); ++ ++#endif /* ! GRUB_EFI_MOK2_VERIFY_HEADER */ +-- +2.7.4 + diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/password.inc b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/password.inc new file mode 100644 index 0000000..c0f4b39 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/password.inc @@ -0,0 +1,2 @@ +set superusers="root" +password_pbkdf2 root grub.pbkdf2.sha512.10000.4039B6F2AC3D0E349479D2573BC4B206E022E9308DBCBA8F42FBBBF64B699B79A5426CE58503ACBB37CA4116CA1B95C89BEC5F804CB91C8ED5A7381C9E03EDE8.69E763E475CF993A6B4954F9BA863E45E8DFAF2BCEBEAAB21319DC766287FA1A621807F6E2AAD9277A6BA3B9B56A14C0918C441EE47BE304D23ADA562CA018E9 diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/serial-redirect-control-x-fix.patch b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/serial-redirect-control-x-fix.patch new file mode 100644 index 0000000..3ada2b0 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi/serial-redirect-control-x-fix.patch @@ -0,0 +1,22 @@ +--- + grub-core/term/efi/console.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/grub-core/term/efi/console.c ++++ b/grub-core/term/efi/console.c +@@ -124,9 +124,12 @@ grub_console_getkey (struct grub_term_in + if (status != GRUB_EFI_SUCCESS) + return GRUB_TERM_NO_KEY; + +- if (key.scan_code == 0) +- return key.unicode_char; +- else if (key.scan_code < ARRAY_SIZE (efi_codes)) ++ if (key.scan_code == 0) { ++ if (key.unicode_char < 0x20 && key.unicode_char != 0 && key.unicode_char != '\t' && key.unicode_char != '\b' && key.unicode_char != '\n' && key.unicode_char != '\r') ++ return GRUB_TERM_CTRL | (key.unicode_char - 1 + 'a'); ++ else ++ return key.unicode_char; ++ } else if (key.scan_code < ARRAY_SIZE (efi_codes)) + return efi_codes[key.scan_code]; + + return GRUB_TERM_NO_KEY; diff --git a/meta-efi-secure-boot/recipes-bsp/grub/grub-efi_2.02.bbappend b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi_2.02.bbappend new file mode 100644 index 0000000..dd98968 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/grub/grub-efi_2.02.bbappend @@ -0,0 +1,146 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/grub-efi:" + +EXTRA_SRC_URI = " \ + ${@'file://efi-secure-boot.inc file://password.inc' if d.getVar('UEFI_SB', True) == '1' else ''} \ +" + +SRC_URI += " \ + file://0001-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch \ + file://0002-shim-add-needed-data-structures.patch \ + file://0003-efi-chainloader-implement-an-UEFI-Exit-service-for-s.patch \ + file://0004-efi-chainloader-port-shim-to-grub.patch \ + file://0005-efi-chainloader-use-shim-to-load-and-verify-an-image.patch \ + file://0006-efi-chainloader-boot-the-image-using-shim.patch \ + file://0007-efi-chainloader-take-care-of-unload-undershim.patch \ + file://chainloader-handle-the-unauthenticated-image-by-shim.patch \ + file://chainloader-Don-t-check-empty-section-in-file-like-..patch \ + file://chainloader-Actually-find-the-relocations-correctly-.patch \ + file://Grub-get-and-set-efi-variables.patch \ + file://Fix-32-bit-build-failures.patch;apply=0 \ + file://Work-around-the-failure-of-ExitBootServices.patch;apply=0 \ + file://serial-redirect-control-x-fix.patch;apply=0 \ + file://mok2verify-support-to-verify-non-PE-file-with-PKCS-7.patch;apply=0 \ + file://grub-efi.cfg \ + file://boot-menu.inc \ + ${EXTRA_SRC_URI} \ +" + +EFI_BOOT_PATH = "/boot/efi/EFI/BOOT" + +#GRUB_BUILDIN_append = " chain ${@'efivar mok2verify password_pbkdf2' if d.getVar('UEFI_SB', True) == '1' else ''}" +GRUB_BUILDIN_append += " chain ${@'efivar password_pbkdf2' if d.getVar('UEFI_SB', True) == '1' else ''}" + +# For efi_call_foo and efi_shim_exit +CFLAGS_append = " -fno-toplevel-reorder" + +# Set a default root specifier. +inherit user-key-store + +python __anonymous () { + if d.getVar('UEFI_SB', True) != "1": + return + + # Override the default filename if efi-secure-boot enabled. + # grub-efi must be renamed as grub${arch}.efi for working with shim + # or SELoader. + import re + + target = d.getVar('TARGET_ARCH', True) + if target == "x86_64": + grubimage = "grubx64.efi" + elif re.match('i.86', target): + grubimage = "grubia32.efi" + else: + raise bb.parse.SkipPackage("grub-efi is incompatible with target %s" % target) + + d.setVar("GRUB_IMAGE", grubimage) +} + +do_compile_append_class-native() { + make grub-editenv +} + +do_install_append_class-native() { + install -m 0755 grub-editenv "${D}${bindir}" +} + +do_install_append_class-target() { + local menu="${WORKDIR}/boot-menu.inc" + + # Enable the default IMA rules if IMA is enabled and encrypted-storage is + # disabled. This is because unseal operation will fail when any PCR is + # extended due to updating the aggregate integrity value by the default + # IMA rules. + [ x"${IMA}" = x"1" -a x"${@bb.utils.contains('DISTRO_FEATURES', 'encrypted-storage', '1', '0', d)}" != x"1" ] && { + ! grep -q "ima_policy=tcb" "$menu" && + sed -i 's/^\s*chainloader\s\+.*bzImage.*/& ima_policy=tcb/g' "$menu" + } + + [ x"${UEFI_SB}" = x"1" ] && { + # Don't allow to load the detached initramfs if the bundled kernel used. + [ x"${INITRAMFS_IMAGE_BUNDLE}" = x"1" ] && + sed -i 's/\(^\s*chainloader\s\+.*bzImage.*\)\s\+initrd=[^[:space:]]*\(.*\)/\1\2/g' "$menu" + } + + # Install the stacked grub configs. + install -d "${D}${EFI_BOOT_PATH}" + install -m 0600 "${WORKDIR}/grub-efi.cfg" "${D}${EFI_BOOT_PATH}/grub.cfg" + install -m 0600 "$menu" "${D}${EFI_BOOT_PATH}" + [ x"${UEFI_SB}" = x"1" ] && { + install -m 0600 "${WORKDIR}/efi-secure-boot.inc" "${D}${EFI_BOOT_PATH}" + install -m 0600 "${WORKDIR}/password.inc" "${D}${EFI_BOOT_PATH}" + } + + # Create the initial environment block with empty item. + grub-editenv "${D}${EFI_BOOT_PATH}/grubenv" create + + install -d "${D}${EFI_BOOT_PATH}/${GRUB_TARGET}-efi" + grub-mkimage -p /EFI/BOOT -d "./grub-core" \ + -O "${GRUB_TARGET}-efi" -o "${B}/${GRUB_IMAGE}" \ + ${GRUB_BUILDIN} + + install -m 0644 "${B}/${GRUB_IMAGE}" "${D}${EFI_BOOT_PATH}/${GRUB_IMAGE}" + + # Install the modules to grub-efi's search path + make -C grub-core install DESTDIR="${D}${EFI_BOOT_PATH}" pkglibdir="" + + # Remove .module + rm -f ${D}${EFI_BOOT_PATH}/${GRUB_TARGET}-efi/*.module +} + +fakeroot python do_sign_class-target() { + image_dir = d.getVar('D', True) + efi_boot_path = d.getVar('EFI_BOOT_PATH', True) + grub_image = d.getVar('GRUB_IMAGE', True) + dir = image_dir + efi_boot_path + '/' + + sb_sign(dir + grub_image, dir + grub_image, d) + uks_sel_sign(dir + 'grub.cfg', d) + uks_sel_sign(dir + 'boot-menu.inc', d) + + if d.getVar('UEFI_SB', True) == "1": + uks_sel_sign(dir + 'efi-secure-boot.inc', d) + uks_sel_sign(dir + 'password.inc', d) +} + +fakeroot python do_sign() { +} +addtask sign after do_install before do_deploy do_package + +# Override the do_deploy() in oe-core. +do_deploy_class-target() { + install -m 0644 "${D}${EFI_BOOT_PATH}/${GRUB_IMAGE}" "${DEPLOYDIR}" + + install -d "${DEPLOYDIR}/efi-unsigned" + install -m 0644 "${B}/${GRUB_IMAGE}" "${DEPLOYDIR}/efi-unsigned" + cp -af "${D}${EFI_BOOT_PATH}/${GRUB_TARGET}-efi" "${DEPLOYDIR}/efi-unsigned" +} + +FILES_${PN} += "/boot/efi" + +CONFFILES_${PN} += " \ + ${EFI_BOOT_PATH}/grub.cfg \ + ${EFI_BOOT_PATH}/grubenv \ + ${EFI_BOOT_PATH}/boot-menu.inc \ + ${EFI_BOOT_PATH}/efi-secure-boot.inc \ +" diff --git a/meta-efi-secure-boot/recipes-bsp/seloader/seloader_git.bb b/meta-efi-secure-boot/recipes-bsp/seloader/seloader_git.bb new file mode 100644 index 0000000..76f2669 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/seloader/seloader_git.bb @@ -0,0 +1,94 @@ +SUMMARY = "The bootloader capable of authenticating the PE and non-PE files." +DESCRIPTION = "The SELoader is designed to authenticate the non-PE files, \ +such as grub configuration, initrd, grub modules, which cannot be verified \ +by the MOK Verify Protocol registered by shim loader. \ +\ +In order to conveniently authenticate the PE file with gBS->LoadImage() \ +and gBS->StartImage(), the SELoader hooks EFI Security2 Architectural \ +Protocol and employs MOK Verify Protocol to verify the PE file. If only \ +UEFI Secure Boot is enabled, the SELoader just simplily calls \ +gBS->LoadImage() and gBS->StartImage() to allow BIOS to verify PE file. \ +\ +The SELoader publishes MOK2 Verify Protocol which provides a flexible \ +interface to allow the bootloader to verify the file, file buffer or \ +memory buffer without knowing the file format. \ +" +HOMEPAGE = "https://github.com/jiazhang0/SELoader.git" +SECTION = "bootloaders" + +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://LICENSE;md5=d9bf404642f21afb4ad89f95d7bc91ee" +PR = "r0" +SRC_URI = " \ + git://github.com/jiazhang0/SELoader.git \ +" +SRCREV = "32e3292c33603f319354aac273938fe63897a8da" +PV = "0.4.5+git${SRCPV}" + +COMPATIBLE_HOST = '(i.86|x86_64).*-linux' + +inherit deploy user-key-store + +S = "${WORKDIR}/git" +DEPENDS += " \ + gnu-efi sbsigntool-native \ +" + +EFI_ARCH_x86 = "ia32" +EFI_ARCH_x86-64 = "x64" + +EXTRA_OEMAKE = " \ + CROSS_COMPILE="${TARGET_PREFIX}" \ + SBSIGN=${STAGING_BINDIR_NATIVE}/sbsign \ + gnuefi_libdir=${STAGING_LIBDIR} \ + LIB_GCC="`${CC} -print-libgcc-file-name`" \ +" + +PARALLEL_MAKE = "" + +EFI_TARGET = "/boot/efi/EFI/BOOT" +FILES_${PN} += "${EFI_TARGET}" + +python do_sign() { + sb_sign(d.expand('${B}/Src/Efi/SELoader.efi'), d.expand('${B}/Src/Efi/SELoader.efi.signed'), d) + sb_sign(d.expand('${B}/Bin/Hash2DxeCrypto.efi'), d.expand('${B}/Bin/Hash2DxeCrypto.efi.signed'), d) + sb_sign(d.expand('${B}/Bin/Pkcs7VerifyDxe.efi'), d.expand('${B}/Bin/Pkcs7VerifyDxe.efi.signed'), d) +} +addtask sign after do_compile before do_install + +do_install() { + install -d ${D}${EFI_TARGET} + + oe_runmake install EFI_DESTDIR=${D}${EFI_TARGET} + + if [ x"${UEFI_SB}" = x"1" ]; then + if [ x"${MOK_SB}" != x"1" ]; then + mv ${D}${EFI_TARGET}/SELoader${EFI_ARCH}.efi \ + ${D}${EFI_TARGET}/boot${EFI_ARCH}.efi + fi + fi +} + +do_deploy() { + # Deploy the unsigned images for manual signing + install -d ${DEPLOYDIR}/efi-unsigned + + install -m 0600 ${B}/Src/Efi/SELoader.efi \ + ${DEPLOYDIR}/efi-unsigned/SELoader${EFI_ARCH}.efi + install -m 0600 ${B}/Bin/Hash2DxeCrypto.efi ${DEPLOYDIR}/efi-unsigned/ + install -m 0600 ${B}/Bin/Pkcs7VerifyDxe.efi ${DEPLOYDIR}/efi-unsigned/ + + # Deploy the signed images + if [ x"${UEFI_SB}" = x"1" -a x"${MOK_SB}" != x"1" ]; then + SEL_NAME=boot + else + SEL_NAME=SELoader + fi + install -m 0600 ${D}${EFI_TARGET}/${SEL_NAME}${EFI_ARCH}.efi \ + ${DEPLOYDIR}/${SEL_NAME}${EFI_ARCH}.efi + install -m 0600 ${D}${EFI_TARGET}/Hash2DxeCrypto.efi \ + ${DEPLOYDIR}/Hash2DxeCrypto.efi + install -m 0600 ${D}${EFI_TARGET}/Pkcs7VerifyDxe.efi \ + ${DEPLOYDIR}/Pkcs7VerifyDxe.efi +} +addtask deploy after do_install before do_build diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/0001-shim-allow-to-verify-sha1-digest-for-Authenticode.patch b/meta-efi-secure-boot/recipes-bsp/shim/shim/0001-shim-allow-to-verify-sha1-digest-for-Authenticode.patch new file mode 100644 index 0000000..f458515 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/0001-shim-allow-to-verify-sha1-digest-for-Authenticode.patch @@ -0,0 +1,156 @@ +From 88806eaf9f1726d06eb4e88f12ca86537dbaab75 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Fri, 16 Jun 2017 15:16:35 +0800 +Subject: [PATCH] shim: allow to verify sha1 digest for Authenticode + +Upstream-Status: Pending + +The EV code signing cert sometimes doesn't comply the Authenticode spec to +employ a sha256 digest. + +Signed-off-by: Lans Zhang +--- + shim.c | 48 +++++++++++++++++++++++++++++++++++------------- + 1 file changed, 35 insertions(+), 13 deletions(-) + +diff --git a/shim.c b/shim.c +index 6e040c4..384ccd7 100644 +--- a/shim.c ++++ b/shim.c +@@ -428,7 +428,8 @@ static BOOLEAN verify_eku(UINT8 *Cert, UINTN CertSize) + static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList, + UINTN dbsize, + WIN_CERTIFICATE_EFI_PKCS *data, +- UINT8 *hash) ++ UINT8 *hash, ++ UINTN hashsize) + { + EFI_SIGNATURE_DATA *Cert; + UINTN CertSize; +@@ -445,7 +446,7 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList, + data->Hdr.dwLength - sizeof(data->Hdr), + Cert->SignatureData, + CertSize, +- hash, SHA256_DIGEST_SIZE); ++ hash, hashsize); + if (IsFound) + return DATA_FOUND; + } +@@ -462,7 +463,7 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList, + } + + static CHECK_STATUS check_db_cert(CHAR16 *dbname, EFI_GUID guid, +- WIN_CERTIFICATE_EFI_PKCS *data, UINT8 *hash) ++ WIN_CERTIFICATE_EFI_PKCS *data, UINT8 *hash, UINTN hashsize) + { + CHECK_STATUS rc; + EFI_STATUS efi_status; +@@ -477,7 +478,7 @@ static CHECK_STATUS check_db_cert(CHAR16 *dbname, EFI_GUID guid, + + CertList = (EFI_SIGNATURE_LIST *)db; + +- rc = check_db_cert_in_ram(CertList, dbsize, data, hash); ++ rc = check_db_cert_in_ram(CertList, dbsize, data, hash, hashsize); + + FreePool(db); + +@@ -571,7 +572,8 @@ static EFI_STATUS check_blacklist (WIN_CERTIFICATE_EFI_PKCS *cert, + DATA_FOUND) + return EFI_SECURITY_VIOLATION; + if (cert && check_db_cert_in_ram(dbx, vendor_dbx_size, cert, +- sha256hash) == DATA_FOUND) ++ sha256hash, SHA256_DIGEST_SIZE) == ++ DATA_FOUND) + return EFI_SECURITY_VIOLATION; + + if (check_db_hash(L"dbx", secure_var, sha256hash, SHA256_DIGEST_SIZE, +@@ -580,14 +582,14 @@ static EFI_STATUS check_blacklist (WIN_CERTIFICATE_EFI_PKCS *cert, + if (check_db_hash(L"dbx", secure_var, sha1hash, SHA1_DIGEST_SIZE, + EFI_CERT_SHA1_GUID) == DATA_FOUND) + return EFI_SECURITY_VIOLATION; +- if (cert && check_db_cert(L"dbx", secure_var, cert, sha256hash) == ++ if (cert && check_db_cert(L"dbx", secure_var, cert, sha256hash, SHA256_DIGEST_SIZE) == + DATA_FOUND) + return EFI_SECURITY_VIOLATION; + if (check_db_hash(L"MokListX", shim_var, sha256hash, SHA256_DIGEST_SIZE, + EFI_CERT_SHA256_GUID) == DATA_FOUND) { + return EFI_SECURITY_VIOLATION; + } +- if (cert && check_db_cert(L"MokListX", shim_var, cert, sha256hash) == ++ if (cert && check_db_cert(L"MokListX", shim_var, cert, sha256hash, SHA256_DIGEST_SIZE) == + DATA_FOUND) { + return EFI_SECURITY_VIOLATION; + } +@@ -622,7 +624,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert, + update_verification_method(VERIFIED_BY_HASH); + return EFI_SUCCESS; + } +- if (cert && check_db_cert(L"db", secure_var, cert, sha256hash) ++ if (cert && check_db_cert(L"db", secure_var, cert, sha256hash, SHA256_DIGEST_SIZE) + == DATA_FOUND) { + verification_method = VERIFIED_BY_CERT; + update_verification_method(VERIFIED_BY_CERT); +@@ -636,7 +638,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert, + update_verification_method(VERIFIED_BY_HASH); + return EFI_SUCCESS; + } +- if (cert && check_db_cert(L"MokList", shim_var, cert, sha256hash) == ++ if (cert && check_db_cert(L"MokList", shim_var, cert, sha256hash, SHA256_DIGEST_SIZE) == + DATA_FOUND) { + verification_method = VERIFIED_BY_CERT; + update_verification_method(VERIFIED_BY_CERT); +@@ -1020,27 +1022,47 @@ static EFI_STATUS verify_buffer (char *data, int datasize, + /* + * Check against the shim build key + */ +- if (sizeof(shim_cert) && +- AuthenticodeVerify(cert->CertData, ++ if (sizeof(shim_cert)) { ++ if (AuthenticodeVerify(cert->CertData, + cert->Hdr.dwLength - sizeof(cert->Hdr), + shim_cert, sizeof(shim_cert), sha256hash, + SHA256_DIGEST_SIZE)) { + update_verification_method(VERIFIED_BY_CERT); + status = EFI_SUCCESS; + return status; ++ } ++ ++ if (AuthenticodeVerify(cert->CertData, ++ cert->Hdr.dwLength - sizeof(cert->Hdr), ++ shim_cert, sizeof(shim_cert), sha1hash, ++ SHA1_DIGEST_SIZE)) { ++ update_verification_method(VERIFIED_BY_CERT); ++ status = EFI_SUCCESS; ++ return status; ++ } + } + + /* + * And finally, check against shim's built-in key + */ +- if (vendor_cert_size && +- AuthenticodeVerify(cert->CertData, ++ if (vendor_cert_size) { ++ if (AuthenticodeVerify(cert->CertData, + cert->Hdr.dwLength - sizeof(cert->Hdr), + vendor_cert, vendor_cert_size, + sha256hash, SHA256_DIGEST_SIZE)) { + update_verification_method(VERIFIED_BY_CERT); + status = EFI_SUCCESS; + return status; ++ } ++ ++ if (AuthenticodeVerify(cert->CertData, ++ cert->Hdr.dwLength - sizeof(cert->Hdr), ++ vendor_cert, vendor_cert_size, ++ sha1hash, SHA1_DIGEST_SIZE)) { ++ update_verification_method(VERIFIED_BY_CERT); ++ status = EFI_SUCCESS; ++ return status; ++ } + } + } + +-- +2.7.5 + diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/0005-Fix-signing-failure-due-to-not-finding-certificate.patch b/meta-efi-secure-boot/recipes-bsp/shim/shim/0005-Fix-signing-failure-due-to-not-finding-certificate.patch new file mode 100644 index 0000000..f56aced --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/0005-Fix-signing-failure-due-to-not-finding-certificate.patch @@ -0,0 +1,36 @@ +From 85e74fa95094175753e39acdd694f9c639069abf Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Fri, 18 Mar 2016 12:30:08 +0800 +Subject: [PATCH 05/11] Fix signing failure due to not finding certificate + +Upstream-Status: Pending + +The shim.p12 containing private sample key should be imported after +importing the corresponding certificate shim.crt. Otherwise, the +nick name of shim certificate cannot be used. + +Signed-off-by: Lans Zhang +--- + Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index dcfa357..efab050 100644 +--- a/Makefile ++++ b/Makefile +@@ -124,10 +124,10 @@ version.c : version.c.in + -e "s,@@COMMIT@@,$(shell if [ -d .git ] ; then git log -1 --pretty=format:%H ; elif [ -f commit ]; then cat commit ; else echo commit id not available; fi)," \ + < version.c.in > version.c + +-certdb/secmod.db: shim.crt ++certdb/secmod.db: shim.crt shim.p12 + -mkdir certdb +- $(PK12UTIL) -d certdb/ -i shim.p12 -W "" -K "" + $(CERTUTIL) -d certdb/ -A -i shim.crt -n shim -t u ++ $(PK12UTIL) -d certdb/ -i shim.p12 -W "" -K "" + + shim.o: $(SOURCES) shim_cert.h + shim.o: $(wildcard *.h) +-- +2.11.0 + diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/0006-Prevent-from-removing-intermediate-.efi.patch b/meta-efi-secure-boot/recipes-bsp/shim/shim/0006-Prevent-from-removing-intermediate-.efi.patch new file mode 100644 index 0000000..fbbf94b --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/0006-Prevent-from-removing-intermediate-.efi.patch @@ -0,0 +1,33 @@ +From 1f03018aa0b7df2eab576d410ec88e8cf66b06e0 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Wed, 21 Sep 2016 11:25:14 +0800 +Subject: [PATCH 06/11] Prevent from removing intermediate .efi + +Upstream-Status: Pending + +Otherwise Make will delete the .efi during the build: +sysroots/x86_64-linux/usr/bin/pesign -n certdb -i MokManager.efi -c "shim" -s -o MokManager.efi.signed -f +rm fallback.efi MokManager.efi +DEBUG: Shell function do_compile finished + +Signed-off-by: Lans Zhang +--- + Makefile | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Makefile b/Makefile +index efab050..7c71993 100644 +--- a/Makefile ++++ b/Makefile +@@ -100,6 +100,8 @@ MOK_SOURCES = MokManager.c shim.h include/console.h PasswordCrypt.c PasswordCryp + FALLBACK_OBJS = fallback.o + FALLBACK_SRCS = fallback.c + ++.PRECIOUS: $(MMNAME).efi $(FBNAME).efi ++ + ifneq ($(origin ENABLE_HTTPBOOT), undefined) + OBJS += httpboot.o + SOURCES += httpboot.c httpboot.h +-- +2.11.0 + diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/0007-Use-sbsign-to-sign-MokManager-and-fallback.patch b/meta-efi-secure-boot/recipes-bsp/shim/shim/0007-Use-sbsign-to-sign-MokManager-and-fallback.patch new file mode 100644 index 0000000..14fae76 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/0007-Use-sbsign-to-sign-MokManager-and-fallback.patch @@ -0,0 +1,44 @@ +From 04da6c928d5f15b7adb6c51e55b9aa0a8126063d Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Wed, 21 Sep 2016 11:31:02 +0800 +Subject: [PATCH 07/11] Use sbsign to sign MokManager and fallback + +Upstream-Status: Pending + +pesign is written with -std=gnu11 and thus the host gcc version lower +than 4.7 cannot build out pesign. + +sbsign is another alternate used to sign efi binary and it works well. +Therefore, drop to use sbsign to sign efi binary. + +Signed-off-by: Lans Zhang +--- + Makefile | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index 7c71993..58b4b4c 100644 +--- a/Makefile ++++ b/Makefile +@@ -12,6 +12,7 @@ HEXDUMP ?= hexdump + PK12UTIL ?= pk12util + CERTUTIL ?= certutil + PESIGN ?= pesign ++SBSIGN ?= sbsign + + ARCH = $(shell $(CC) -dumpmachine | cut -f1 -d- | sed s,i[3456789]86,ia32,) + OBJCOPY_GTE224 = $(shell expr `$(OBJCOPY) --version |grep ^"GNU objcopy" | sed 's/^.*\((.*)\|version\) //g' | cut -f1-2 -d.` \>= 2.24) +@@ -190,8 +191,8 @@ endif + -j .note.gnu.build-id \ + $(FORMAT) $^ $@.debug + +-%.efi.signed: %.efi certdb/secmod.db +- $(PESIGN) -n certdb -i $< -c "shim" -s -o $@ -f ++%.efi.signed: %.efi shim.key shim.crt ++ $(SBSIGN) --key shim.key --cert shim.crt --output $@ $< + + clean: + $(MAKE) -C Cryptlib clean +-- +2.11.0 + diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/0008-Fix-the-world-build-failure-due-to-the-missing-rule-.patch b/meta-efi-secure-boot/recipes-bsp/shim/shim/0008-Fix-the-world-build-failure-due-to-the-missing-rule-.patch new file mode 100644 index 0000000..ddaa9f9 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/0008-Fix-the-world-build-failure-due-to-the-missing-rule-.patch @@ -0,0 +1,35 @@ +From 508a31905aff2d271f1b82a5a36a614113b7fe85 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Mon, 6 Jun 2016 16:28:09 +0800 +Subject: [PATCH 08/11] Fix the world build failure due to the missing rule of + generating shim.key + +Upstream-Status: Pending + +shim.key is not given without feature/mok-secure-boot, the script +make-certs already integrated in shim is able to generate it and shim.crt +for signing. However, the commit 79c0d3ab3964ff03483277a515aaf50016bbe786 +forgets to add the rule of generating shim.key, causing the world build +failure. + +Signed-off-by: Lans Zhang +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 58b4b4c..0da5e6c 100644 +--- a/Makefile ++++ b/Makefile +@@ -110,7 +110,7 @@ endif + + all: $(TARGET) + +-shim.crt: ++shim.crt shim.key: + ./make-certs shim shim@xn--u4h.net all codesign 1.3.6.1.4.1.311.10.3.1 +Date: Wed, 28 Dec 2016 11:08:37 +0800 +Subject: [PATCH 10/11] Makefile: do not sign the efi file + +Shim tries to sign all the efi binaries at build time, but is not +suitable for us. Because the private key has to be supplied, and this +doesn't make sense to EDSS key. + +We will use a seperated function in bitbake file to +sign these efi binaries, so that we can freely use EDSS key, Wind +River sample key or user key. + +Signed-off-by: Yunguo Wei +Signed-off-by: Lans Zhang +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 24e21a8..0912cd0 100644 +--- a/Makefile ++++ b/Makefile +@@ -92,7 +92,7 @@ endif + + LDFLAGS = --hash-style=sysv -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH) -L$(LIB_PATH) -LCryptlib -LCryptlib/OpenSSL $(EFI_CRT_OBJS) --build-id=sha1 + +-TARGET = $(SHIMNAME).efi $(MMNAME).efi.signed $(FBNAME).efi.signed ++TARGET = $(SHIMNAME).efi $(MMNAME).efi $(FBNAME).efi + OBJS = shim.o netboot.o cert.o replacements.o tpm.o version.o + KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer + SOURCES = shim.c shim.h netboot.c include/PeImage.h include/wincert.h include/console.h replacements.c replacements.h tpm.c tpm.h version.c version.h +-- +2.11.0 + diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/0011-Update-verification_method-if-the-loaded-image-is-si.patch b/meta-efi-secure-boot/recipes-bsp/shim/shim/0011-Update-verification_method-if-the-loaded-image-is-si.patch new file mode 100644 index 0000000..12cbecd --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/0011-Update-verification_method-if-the-loaded-image-is-si.patch @@ -0,0 +1,69 @@ +From 62489adc36c5177f90ed16af936a4c0a992cea7e Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Wed, 21 Sep 2016 11:17:29 +0800 +Subject: [PATCH 11/11] Update verification_method if the loaded image is + signed by shim/vendor cert + +Upstream-Status: Pending + +Also, if the loaded image is not verfied by cert, the validation process +should be allowed as well. + +Signed-off-by: Lans Zhang +--- + replacements.c | 2 +- + shim.c | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/replacements.c b/replacements.c +index 01eda0e..9ed5a5d 100644 +--- a/replacements.c ++++ b/replacements.c +@@ -144,7 +144,7 @@ start_image(EFI_HANDLE image_handle, UINTN *exit_data_size, CHAR16 **exit_data) + static EFI_STATUS EFIAPI + exit_boot_services(EFI_HANDLE image_key, UINTN map_key) + { +- if (loader_is_participating || verification_method == VERIFIED_BY_HASH) { ++ if (loader_is_participating || verification_method != VERIFIED_BY_NOTHING) { + unhook_system_services(); + EFI_STATUS status; + status = systab->BootServices->ExitBootServices(image_key, map_key); +diff --git a/shim.c b/shim.c +index 364784b..ef62145 100644 +--- a/shim.c ++++ b/shim.c +@@ -1029,6 +1029,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize, + cert->Hdr.dwLength - sizeof(cert->Hdr), + shim_cert, sizeof(shim_cert), sha256hash, + SHA256_DIGEST_SIZE)) { ++ update_verification_method(VERIFIED_BY_CERT); + status = EFI_SUCCESS; + return status; + } +@@ -1037,6 +1038,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize, + cert->Hdr.dwLength - sizeof(cert->Hdr), + shim_cert, sizeof(shim_cert), sha1hash, + SHA1_DIGEST_SIZE)) { ++ update_verification_method(VERIFIED_BY_CERT); + status = EFI_SUCCESS; + return status; + } +@@ -1050,6 +1052,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize, + cert->Hdr.dwLength - sizeof(cert->Hdr), + vendor_cert, vendor_cert_size, + sha256hash, SHA256_DIGEST_SIZE)) { ++ update_verification_method(VERIFIED_BY_CERT); + status = EFI_SUCCESS; + return status; + } +@@ -1058,6 +1061,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize, + cert->Hdr.dwLength - sizeof(cert->Hdr), + vendor_cert, vendor_cert_size, + sha1hash, SHA1_DIGEST_SIZE)) { ++ update_verification_method(VERIFIED_BY_CERT); + status = EFI_SUCCESS; + return status; + } +-- +2.11.0 + diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/0012-netboot-replace-the-depreciated-EFI_PXE_BASE_CODE.patch b/meta-efi-secure-boot/recipes-bsp/shim/shim/0012-netboot-replace-the-depreciated-EFI_PXE_BASE_CODE.patch new file mode 100644 index 0000000..19f6c2d --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/0012-netboot-replace-the-depreciated-EFI_PXE_BASE_CODE.patch @@ -0,0 +1,28 @@ +From 1f22dc6be768b7032b73ea963901de270e3c99d9 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Sun, 18 Jun 2017 21:50:26 +0800 +Subject: [PATCH] netboot: replace the depreciated EFI_PXE_BASE_CODE + +The newer gnu-efi already uses EFI_PXE_BASE_CODE_PROTOCOL instead. + +Signed-off-by: Lans Zhang +--- + netboot.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/netboot.c b/netboot.c +index 1cc1a2b..32c9b0a 100644 +--- a/netboot.c ++++ b/netboot.c +@@ -43,7 +43,7 @@ + #define ntohs(x) __builtin_bswap16(x) /* supported both by GCC and clang */ + #define htons(x) ntohs(x) + +-static EFI_PXE_BASE_CODE *pxe; ++static EFI_PXE_BASE_CODE_PROTOCOL *pxe; + static EFI_IP_ADDRESS tftp_addr; + static CHAR8 *full_path; + +-- +2.7.5 + diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/LICENSE b/meta-efi-secure-boot/recipes-bsp/shim/shim/LICENSE new file mode 100644 index 0000000..3b5a464 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/LICENSE @@ -0,0 +1,30 @@ +Copyright 2012 Red Hat, Inc + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + +Significant portions of this code are derived from Tianocore +(http://tianocore.sf.net) and are Copyright 2009-2012 Intel +Corporation. diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim_git.bb b/meta-efi-secure-boot/recipes-bsp/shim/shim_git.bb new file mode 100644 index 0000000..83ba5b7 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim_git.bb @@ -0,0 +1,137 @@ +SUMMARY = "shim is a trivial EFI application." +DESCRIPTION = "shim is a trivial EFI application that, when run, attempts to open and \ +execute another application. It will initially attempt to do this via the \ +standard EFI LoadImage() and StartImage() calls. If these fail (because secure \ +boot is enabled and the binary is not signed with an appropriate key, for \ +instance) it will then validate the binary against a built-in certificate. If \ +this succeeds and if the binary or signing key are not blacklisted then shim \ +will relocate and execute the binary." +HOMEPAGE = "https://github.com/rhinstaller/shim.git" +SECTION = "bootloaders" + +LICENSE = "BSD-2-Clause" +LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=b92e63892681ee4e8d27e7a7e87ef2bc" +PR = "r0" + +COMPATIBLE_HOST = '(i.86|x86_64).*-linux' + +inherit deploy user-key-store + +SRC_URI = " \ + git://github.com/rhinstaller/shim.git \ + file://0001-shim-allow-to-verify-sha1-digest-for-Authenticode.patch \ + file://0005-Fix-signing-failure-due-to-not-finding-certificate.patch;apply=0 \ + file://0006-Prevent-from-removing-intermediate-.efi.patch \ + file://0007-Use-sbsign-to-sign-MokManager-and-fallback.patch \ + file://0008-Fix-the-world-build-failure-due-to-the-missing-rule-.patch \ + file://0010-Makefile-do-not-sign-the-efi-file.patch \ + file://0011-Update-verification_method-if-the-loaded-image-is-si.patch;apply=0 \ + file://0012-netboot-replace-the-depreciated-EFI_PXE_BASE_CODE.patch \ +" +SRC_URI_append_x86-64 = " \ + ${@bb.utils.contains('DISTRO_FEATURES', 'msft', 'file://shim${EFI_ARCH}.efi.signed file://LICENSE' if uks_signing_model(d) == 'sample' else '', '', d)} \ +" + +SRCREV = "55c65546e46a78edbe41e88cb4ccbd2522e09625" +PV = "12+git${SRCPV}" + +S = "${WORKDIR}/git" +DEPENDS += "\ + gnu-efi nss openssl util-linux-native openssl-native nss-native \ +" + +EFI_ARCH_x86 = "ia32" +EFI_ARCH_x86-64 = "x64" + +EXTRA_OEMAKE = " \ + CROSS_COMPILE="${TARGET_PREFIX}" \ + LIB_GCC="`${CC} -print-libgcc-file-name`" \ + LIB_PATH="${STAGING_LIBDIR}" \ + EFI_PATH="${STAGING_LIBDIR}" \ + EFI_INCLUDE="${STAGING_INCDIR}/efi" \ + RELEASE="_${DISTRO}_${DISTRO_VERSION}" \ + DEFAULT_LOADER=\\\\\\SELoader${EFI_ARCH}.efi \ + OPENSSL=${STAGING_BINDIR_NATIVE}/openssl \ + HEXDUMP=${STAGING_BINDIR_NATIVE}/hexdump \ + PK12UTIL=${STAGING_BINDIR_NATIVE}/pk12util \ + CERTUTIL=${STAGING_BINDIR_NATIVE}/certutil \ + SBSIGN=${STAGING_BINDIR_NATIVE}/sbsign \ + AR=${AR} \ + ${@'VENDOR_CERT_FILE=${WORKDIR}/vendor_cert.cer' if d.getVar('MOK_SB', True) == '1' else ''} \ + ${@'VENDOR_DBX_FILE=${WORKDIR}/vendor_dbx.esl' if uks_signing_model(d) == 'user' else ''} \ +" + +PARALLEL_MAKE = "" + +EFI_TARGET = "/boot/efi/EFI/BOOT" +FILES_${PN} += "${EFI_TARGET}" + +MSFT = "${@bb.utils.contains('DISTRO_FEATURES', 'msft', '1', '0', d)}" + +# Prepare the signing certificate and keys +python do_prepare_signing_keys() { + # For UEFI_SB, shim is not built + if d.getVar('MOK_SB', True) != '1': + return + + path = create_mok_vendor_dbx(d) + + # Prepare shim_cert and vendor_cert. + dir = mok_sb_keys_dir(d) + + import shutil + + shutil.copyfile(dir + 'shim_cert.pem', d.getVar('S', True) + '/shim.crt') + pem2der(dir + 'vendor_cert.pem', d.getVar('WORKDIR', True) + '/vendor_cert.cer', d) + + # Replace the shim certificate with EV certificate for speeding up + # the progress of MSFT signing. + if d.expand('${MSFT}') == "1" and uks_signing_model(d) == "sample": + shutil.copyfile(d.expand('${EV_CERT}'), d.expand('${S}/shim.crt')) +} +addtask prepare_signing_keys after do_configure before do_compile + +python do_sign() { + # The pre-signed shim binary will override the one built from the + # scratch. + pre_signed = d.expand('${WORKDIR}/shim${EFI_ARCH}.efi.signed') + dst = d.expand('${B}/shim${EFI_ARCH}.efi.signed') + if d.expand('${MSFT}') == "1" and os.path.exists(pre_signed): + import shutil + shutil.copyfile(pre_signed, dst) + else: + if uks_signing_model(d) in ('sample', 'user'): + uefi_sb_sign(d.expand('${S}/shim${EFI_ARCH}.efi'), dst, d) + elif uks_signing_model(d) == 'edss': + edss_sign_efi_image(d.expand('${S}/shim${EFI_ARCH}.efi'), dst, d) + + sb_sign(d.expand('${S}/mm${EFI_ARCH}.efi'), d.expand('${B}/mm${EFI_ARCH}.efi.signed'), d) + sb_sign(d.expand('${S}/fb${EFI_ARCH}.efi'), d.expand('${B}/fb${EFI_ARCH}.efi.signed'), d) +} +addtask sign after do_compile before do_install + +do_install() { + install -d ${D}${EFI_TARGET} + + local shim_dst="${D}${EFI_TARGET}/boot${EFI_ARCH}.efi" + local mm_dst="${D}${EFI_TARGET}/mm${EFI_ARCH}.efi" + if [ x"${UEFI_SB}" = x"1" ]; then + install -m 0600 ${B}/shim${EFI_ARCH}.efi.signed $shim_dst + install -m 0600 ${B}/mm${EFI_ARCH}.efi.signed $mm_dst + else + install -m 0600 ${B}/shim${EFI_ARCH}.efi $shim_dst + install -m 0600 ${B}/mm${EFI_ARCH}.efi $mm_dst + fi +} + +# Install the unsigned images for manual signing +do_deploy() { + install -d ${DEPLOYDIR}/efi-unsigned + + install -m 0600 ${B}/shim${EFI_ARCH}.efi ${DEPLOYDIR}/efi-unsigned/boot${EFI_ARCH}.efi + install -m 0600 ${B}/mm${EFI_ARCH}.efi ${DEPLOYDIR}/efi-unsigned/mm${EFI_ARCH}.efi + + install -m 0600 "${D}${EFI_TARGET}/boot${EFI_ARCH}.efi" "${DEPLOYDIR}" + install -m 0600 "${D}${EFI_TARGET}/mm${EFI_ARCH}.efi" "${DEPLOYDIR}" +} +addtask deploy after do_install before do_build diff --git a/meta-efi-secure-boot/recipes-core/systemd/systemd_%.bbappend b/meta-efi-secure-boot/recipes-core/systemd/systemd_%.bbappend new file mode 100644 index 0000000..7b935b5 --- /dev/null +++ b/meta-efi-secure-boot/recipes-core/systemd/systemd_%.bbappend @@ -0,0 +1,7 @@ +DEPENDS += " \ + ${@bb.utils.contains('MACHINE_FEATURES', 'efi', 'gnu-efi', '', d)} \ +" + +EXTRA_OECONF += " \ + ${@bb.utils.contains('MACHINE_FEATURES', 'efi', '--enable-efi --enable-gnuefi --with-efi-libdir=${STAGING_LIBDIR} --with-efi-ldsdir=${STAGING_LIBDIR} --with-efi-includedir=${STAGING_INCDIR}', '', d)} \ +" diff --git a/meta-efi-secure-boot/recipes-devtools/libsign/libsign_git.bb b/meta-efi-secure-boot/recipes-devtools/libsign/libsign_git.bb new file mode 100644 index 0000000..0984ec5 --- /dev/null +++ b/meta-efi-secure-boot/recipes-devtools/libsign/libsign_git.bb @@ -0,0 +1,48 @@ +SUMMARY = "A generic signing tool framework" +DESCRIPTION = " \ +This project targets to provide a generic signing framework. This framework \ +separates the signing request and signing process and correspondingly forms \ +the so-called signlet and signaturelet. \ +Each signaturelet only concerns about the details about how to construct the \ +layout of a signature format, and signlet only cares how to construct the \ +signing request. \ +" +SECTION = "devel" +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=d9bf404642f21afb4ad89f95d7bc91ee" + +SRC_URI = " \ + git://github.com/jiazhang0/libsign.git \ +" +SRCREV = "dfab84b4235a36bb395bc6663e50578bb2f9edca" +PV = "0.3.2+git${SRCPV}" + +DEPENDS += "openssl" +RDEPENDS_${PN}_class-target += "libcrypto" +RDEPENDS_${PN}_class-native += "openssl" + +PARALLEL_MAKE = "" + +S = "${WORKDIR}/git" + +EXTRA_OEMAKE = " \ + CC="${CC}" \ + bindir="${STAGING_BINDIR}" \ + libdir="${STAGING_LIBDIR}" \ + includedir="${STAGING_INCDIR}" \ + EXTRA_CFLAGS="${CFLAGS}" \ + EXTRA_LDFLAGS="${LDFLAGS}" \ + SIGNATURELET_DIR="${libdir}/signaturelet" \ + BINDIR="${bindir}" \ + LIBDIR="${libdir}" \ +" + +do_install() { + oe_runmake install DESTDIR="${D}" +} + +FILES_${PN} += " \ + ${libdir}/signaturelet \ +" + +BBCLASSEXTEND = "native" diff --git a/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool-native_git.bb b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool-native_git.bb new file mode 100644 index 0000000..2d09a97 --- /dev/null +++ b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool-native_git.bb @@ -0,0 +1,50 @@ +SUMMARY = "Signing utility for UEFI secure boot" + +LICENSE = "GPLv3" +LIC_FILES_CHKSUM = "file://LICENSE.GPLv3;md5=9eef91148a9b14ec7f9df333daebc746" + +SRC_URI = "git://kernel.ubuntu.com/jk/sbsigntool \ + file://ccan.git.tar.bz2 \ + file://disable-man-page-creation.patch \ + file://Fix-for-multi-sign.patch \ + file://sbsign-add-x-option-to-avoid-overwrite-existing-sign.patch \ + file://fix-mixed-implicit-and-normal-rules.patch;apply=0 \ + file://image-fix-the-segment-fault-caused-by-the-uninitiali.patch \ +" + +SRCREV="951ee95a301674c046f55330cd7460e1314deff2" +PV = "0.6+git${SRCPV}" + +inherit autotools-brokensep pkgconfig native + +DEPENDS_append = " binutils-native openssl-native gnu-efi-native util-linux-native" + +S = "${WORKDIR}/git" + +do_configure() { + cd ${S} + rm -rf lib/ccan.git + git clone ${WORKDIR}/ccan.git lib/ccan.git + cd lib/ccan.git && git apply ${WORKDIR}/fix-mixed-implicit-and-normal-rules.patch && cd - + + OLD_CC="${CC}" + + if [ ! -e lib/ccan ]; then + export CC="${BUILD_CC}" + export TMPDIR=${B} + lib/ccan.git/tools/create-ccan-tree \ + --build-type=automake lib/ccan \ + talloc read_write_all build_assert array_size || exit 2 + fi + + export CC="${OLD_CC}" + ./autogen.sh --noconfigure + oe_runconf +} + +EXTRA_OEMAKE += " \ + INCLUDES='-I../lib/ccan.git/' \ + EFI_CPPFLAGS='-DEFI_FUNCTION_WRAPPER \ + -I${STAGING_INCDIR}/efi \ + -I${STAGING_INCDIR}/efi/${BUILD_ARCH}' \ +" diff --git a/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/Fix-for-multi-sign.patch b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/Fix-for-multi-sign.patch new file mode 100644 index 0000000..873ade0 --- /dev/null +++ b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/Fix-for-multi-sign.patch @@ -0,0 +1,41 @@ +From e58a528ef57e53008222f238cce7c326a14572e2 Mon Sep 17 00:00:00 2001 +From: James Bottomley +Date: Mon, 30 Sep 2013 19:25:37 -0700 +Subject: [PATCH] Fix for multi-sign + +Upstream-Status: Inappropriate [embedded specific] + +The new Tianocore multi-sign code fails now for images signed with +sbsigntools. The reason is that we don't actually align the signature table, +we just slap it straight after the binary data. Unfortunately, the new +multi-signature code checks that our alignment offsets are correct and fails +the signature for this reason. Fix by adding junk to the end of the image to +align the signature section. + +Signed-off-by: James Bottomley +--- + src/image.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/image.c b/src/image.c +index 10eba0e..519e288 100644 +--- a/src/image.c ++++ b/src/image.c +@@ -385,7 +385,13 @@ static int image_find_regions(struct image *image) + + /* record the size of non-signature data */ + r = &image->checksum_regions[image->n_checksum_regions - 1]; +- image->data_size = (r->data - (void *)image->buf) + r->size; ++ /* ++ * The new Tianocore multisign does a stricter check of the signatures ++ * in particular, the signature table must start at an aligned offset ++ * fix this by adding bytes to the end of the text section (which must ++ * be included in the hash) ++ */ ++ image->data_size = align_up((r->data - (void *)image->buf) + r->size, 8); + + return 0; + } +-- +1.8.4 + diff --git a/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/ccan.git.tar.bz2 b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/ccan.git.tar.bz2 new file mode 100644 index 0000000..9a2994f Binary files /dev/null and b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/ccan.git.tar.bz2 differ diff --git a/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/disable-man-page-creation.patch b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/disable-man-page-creation.patch new file mode 100644 index 0000000..9310628 --- /dev/null +++ b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/disable-man-page-creation.patch @@ -0,0 +1,15 @@ +Upstream-Status: Inappropriate [embedded specific] + +diff --git a/docs/Makefile.am b/docs/Makefile.am +index 1b5a588..6918dd8 100644 +--- a/docs/Makefile.am ++++ b/docs/Makefile.am +@@ -1,8 +1,4 @@ + +-man1_MANS = sbsign.1 sbverify.1 sbattach.1 sbvarsign.1 sbsiglist.1 +- +-EXTRA_DIST = sbsign.1.in sbverify.1.in sbattach.1.in \ +- sbvarsign.1.in sbsiglist.1.in + CLEANFILES = $(man1_MANS) + + $(builddir)/%.1: $(srcdir)/%.1.in $(top_builddir)/src/% diff --git a/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/fix-mixed-implicit-and-normal-rules.patch b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/fix-mixed-implicit-and-normal-rules.patch new file mode 100644 index 0000000..3031e4a --- /dev/null +++ b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/fix-mixed-implicit-and-normal-rules.patch @@ -0,0 +1,33 @@ +From 05e73dbe1f25600ad0dbb36b2d690560c5a36281 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Tue, 31 Mar 2015 15:34:38 +0800 +Subject: [PATCH] Fix mixed implicit and normal rules + +Upstream-Status: Inappropriate [embedded specific] + +This patch comes from upstream: +http://git.yoctoproject.org/cgit/cgit.cgi/meta-luv/plain/recipes-devtools/sbsigntool/sbsigntool/fix-mixed-implicit-and-normal-rules.patch + +Signed-off-by: Lans Zhang +--- + Makefile | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/Makefile b/Makefile +index 65d0d8f..a83185d 100644 +--- a/Makefile ++++ b/Makefile +@@ -39,10 +39,6 @@ $(SCOREDIR)/SUMMARY: $(MODS:%=$(SCOREDIR)/%.score) + $(CC) -v >> $@ + cat $^ | grep 'Total score:' >> $@ + +-$(SCOREDIR)/%.score: ccan/%/_info tools/ccanlint/ccanlint $(OBJFILES) +- mkdir -p `dirname $@` +- $(CCANLINT) -v -s ccan/$* > $@ || true +- + $(ALL_DEPENDS): %/.depends: %/_info tools/ccan_depends + tools/ccan_depends $* > $@ || ( rm -f $@; exit 1 ) + +-- +1.8.3.1 + diff --git a/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/image-fix-the-segment-fault-caused-by-the-uninitiali.patch b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/image-fix-the-segment-fault-caused-by-the-uninitiali.patch new file mode 100644 index 0000000..6fef038 --- /dev/null +++ b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/image-fix-the-segment-fault-caused-by-the-uninitiali.patch @@ -0,0 +1,30 @@ +From a6862cb3bb3b00a1d6704b2bd1fedbd1374be861 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Thu, 6 Apr 2017 11:11:14 +0800 +Subject: [PATCH] image: fix the segment fault caused by the uninitialized + sigbuf + +The uninitialized struct image might contain a non-zeroed sigbuf and then +it is wrongly freed by image_add_signature(). + +Signed-off-by: Lans Zhang +--- + src/image.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/image.c b/src/image.c +index cc55791..644e8f1 100644 +--- a/src/image.c ++++ b/src/image.c +@@ -395,7 +395,7 @@ struct image *image_load(const char *filename) + struct image *image; + int rc; + +- image = talloc(NULL, struct image); ++ image = talloc_zero(NULL, struct image); + if (!image) { + perror("talloc(image)"); + return NULL; +-- +2.11.0 + diff --git a/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/sbsign-add-x-option-to-avoid-overwrite-existing-sign.patch b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/sbsign-add-x-option-to-avoid-overwrite-existing-sign.patch new file mode 100644 index 0000000..b67f56a --- /dev/null +++ b/meta-efi-secure-boot/recipes-devtools/sbsigntool/sbsigntool/sbsign-add-x-option-to-avoid-overwrite-existing-sign.patch @@ -0,0 +1,75 @@ +From 0016a571a5ea1ab65817973f179800947e1aa8de Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Fri, 15 Jan 2016 09:40:56 +0800 +Subject: [PATCH] sbsign: add -x option to avoid overwrite existing signature + +Upstream-Status: Pending + +Signed-off-by: Lans Zhang +--- + src/sbsign.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/src/sbsign.c b/src/sbsign.c +index dcf6eed..7dc101f 100644 +--- a/src/sbsign.c ++++ b/src/sbsign.c +@@ -66,6 +66,7 @@ struct sign_context { + }; + + static struct option options[] = { ++ { "noresign", no_argument, NULL, 'x' }, + { "output", required_argument, NULL, 'o' }, + { "cert", required_argument, NULL, 'c' }, + { "key", required_argument, NULL, 'k' }, +@@ -87,6 +88,7 @@ static void usage(void) + "\t--cert certificate (x509 certificate)\n" + "\t--detached write a detached signature, instead of\n" + "\t a signed binary\n" ++ "\t--noresign don't re-sign the binary if signed\n" + "\t--output write signed data to \n" + "\t (default .signed,\n" + "\t or .pk7 for detached\n" +@@ -114,7 +116,7 @@ int main(int argc, char **argv) + const char *keyfilename, *certfilename; + struct sign_context *ctx; + uint8_t *buf, *tmp; +- int rc, c, sigsize; ++ int rc, c, sigsize, no_resign = 0; + + ctx = talloc_zero(NULL, struct sign_context); + +@@ -123,11 +125,14 @@ int main(int argc, char **argv) + + for (;;) { + int idx; +- c = getopt_long(argc, argv, "o:c:k:dvVh", options, &idx); ++ c = getopt_long(argc, argv, "xo:c:k:dvVh", options, &idx); + if (c == -1) + break; + + switch (c) { ++ case 'x': ++ no_resign = 1; ++ break; + case 'o': + ctx->outfilename = talloc_strdup(ctx, optarg); + break; +@@ -178,6 +183,14 @@ int main(int argc, char **argv) + if (!ctx->image) + return EXIT_FAILURE; + ++ if (ctx->image->cert_table) { ++ if (no_resign) { ++ fprintf(stderr, ++ "Don't overwrite existing signature\n"); ++ return EXIT_SUCCESS; ++ } ++ } ++ + talloc_steal(ctx, ctx->image); + + ERR_load_crypto_strings(); +-- +1.9.1 + diff --git a/meta-efi-secure-boot/recipes-extended/mokutil/mokutil_git.bb b/meta-efi-secure-boot/recipes-extended/mokutil/mokutil_git.bb new file mode 100644 index 0000000..0ea4c96 --- /dev/null +++ b/meta-efi-secure-boot/recipes-extended/mokutil/mokutil_git.bb @@ -0,0 +1,24 @@ +SUMMARY = "The utility to manipulate machines owner keys which managed in shim" + +LICENSE = "GPLv3" +LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504" + +SRC_URI = "\ + git://github.com/lcp/mokutil.git \ +" + +S = "${WORKDIR}/git" +SRCREV = "e19adc575c1f9d8f08b7fbc594a0887ace63f83f" +PV = "0.3.0+git${SRCPV}" + +inherit autotools pkgconfig + +DEPENDS += "openssl efivar" +RDEPENDS_${PN} += "openssl efivar" + +EXTRA_OEMAKE += "\ + EFIVAR_LIBS='-L${STAGING_LIBDIR} -lefivar' \ + OPENSSL_LIBS='-L${STAGING_LIBDIR} -lssl -lcrypto' \ +" + +FILES_${PN} += "${datadir}/bash-completion/*" diff --git a/meta-efi-secure-boot/recipes-kernel/linux/linux-yocto-efi-secure-boot.inc b/meta-efi-secure-boot/recipes-kernel/linux/linux-yocto-efi-secure-boot.inc new file mode 100644 index 0000000..8c570a1 --- /dev/null +++ b/meta-efi-secure-boot/recipes-kernel/linux/linux-yocto-efi-secure-boot.inc @@ -0,0 +1,101 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/linux-yocto:" + +sccs = " \ + ${@bb.utils.contains('DISTRO_FEATURES', 'efi-secure-boot', \ + 'cfg/efi-ext.scc', '', d)} \ +" +KERNEL_FEATURES_append_x86 += "${sccs}" +KERNEL_FEATURES_append_x86-64 += "${sccs}" + +inherit user-key-store + +fakeroot python do_sign() { + import re + + if (d.expand('${TARGET_ARCH}') != 'x86_64') and (not re.match('i.86', d.expand('${TARGET_ARCH}'))): + return + + if d.expand('${UEFI_SB}') != '1': + return + + import shutil + + for type in d.expand('${KERNEL_IMAGETYPES}').split(): + kernel = d.expand('${B}/${KERNEL_OUTPUT_DIR}/') + type + + # Prepare the unsigned kernel image for manual signing. + shutil.copy(kernel, d.expand('${B}/') + type + '.unsigned') + + # SELoader signature is always based on the unsigned kernel image, + # disallowing chainloader to kernel efi-stub. + uks_sel_sign(kernel, d) + + shutil.copyfile(kernel, d.expand('${D}/boot/') + type + d.expand('-${KERNEL_RELEASE}')) + shutil.copyfile(kernel + '.p7b', d.expand('${D}/boot/') + type + d.expand('-${KERNEL_RELEASE}.p7b')) +} + +# Make sure the kernel image has been signed before kernel_do_deploy() +# which prepares the kernel image for creating usb/iso. +addtask sign after do_install before do_package do_populate_sysroot do_deploy + +fakeroot python do_sign_bundled_kernel() { + import re + + if (d.expand('${TARGET_ARCH}') != 'x86_64') and (not re.match('i.86', d.expand('${TARGET_ARCH}'))): + return + + if d.expand('${UEFI_SB}') != '1': + return + + if (d.expand('${INITRAMFS_IMAGE}') == '') or (d.expand('${INITRAMFS_IMAGE_BUNDLE}') != '1'): + return + + import shutil + + for type in d.expand('${KERNEL_IMAGETYPES}').split(): + kernel = d.expand('${B}/${KERNEL_OUTPUT_DIR}/') + type + '.initramfs' + + # Prepare the unsigned kernel image for manual signing. + shutil.copy(kernel, d.expand('${B}/') + type + '.initramfs.unsigned') + + # SELoader signature is always based on the unsigned kernel image, + # disallowing chainloader to kernel efi-stub. + uks_sel_sign(kernel, d) + + shutil.copyfile(kernel, d.expand('${D}/boot/') + type + d.expand('-initramfs-${MACHINE}.bin')) + shutil.copyfile(kernel + '.p7b', d.expand('${D}/boot/') + type + d.expand('-initramfs-${MACHINE}.bin.p7b')) +} +addtask sign_bundled_kernel after do_bundle_initramfs before do_deploy + +do_deploy_append() { + install -d "${DEPLOYDIR}/efi-unsigned" + + for type in ${KERNEL_IMAGETYPES}; do + if [ -f "${B}/$type.unsigned" ]; then + install -m 0644 "${B}/$type.unsigned" "${DEPLOYDIR}/efi-unsigned/$type" + fi + + if [ -f "${B}/$type.initramfs.unsigned" ]; then + install -m 0644 "${B}/$type.initramfs.unsigned" "${DEPLOYDIR}/efi-unsigned/type.initramfs" + fi + + if [ -f "${D}/boot/$type-initramfs-${MACHINE}.bin.p7b" ]; then + install -m 0644 "${D}/boot/$type-initramfs-${MACHINE}.bin.p7b" "${DEPLOYDIR}" + fi + + if [ -f "${B}/${KERNEL_OUTPUT_DIR}/$type.p7b" ]; then + base_name="${type}-${KERNEL_IMAGE_BASE_NAME}.bin.p7b" + + install -m 0644 "${B}/${KERNEL_OUTPUT_DIR}/$type.p7b" "${DEPLOYDIR}/$base_name" + ln -sf "$base_name" "${DEPLOYDIR}/$type-${KERNEL_IMAGE_SYMLINK_NAME}.bin.p7b" + ln -sf "$base_name" "${DEPLOYDIR}/$type.p7b" + fi + done +} + +# Ship *.p7b files to related packages +python do_package_prepend() { + for type in d.expand('${KERNEL_IMAGETYPES}').split(): + typelower = type.lower() + d.appendVar('FILES_kernel-image-' + typelower, ' /boot/' + type + d.expand('-${KERNEL_VERSION_NAME}.p7b')) +} diff --git a/meta-efi-secure-boot/recipes-kernel/linux/linux-yocto-rt_%.bbappend b/meta-efi-secure-boot/recipes-kernel/linux/linux-yocto-rt_%.bbappend new file mode 100644 index 0000000..956a35c --- /dev/null +++ b/meta-efi-secure-boot/recipes-kernel/linux/linux-yocto-rt_%.bbappend @@ -0,0 +1 @@ +require linux-yocto-efi-secure-boot.inc diff --git a/meta-efi-secure-boot/recipes-kernel/linux/linux-yocto_%.bbappend b/meta-efi-secure-boot/recipes-kernel/linux/linux-yocto_%.bbappend new file mode 100644 index 0000000..956a35c --- /dev/null +++ b/meta-efi-secure-boot/recipes-kernel/linux/linux-yocto_%.bbappend @@ -0,0 +1 @@ +require linux-yocto-efi-secure-boot.inc diff --git a/meta-efi-secure-boot/recipes-perl/libfile-slurp/libfile-slurp-perl_9999.19.bb b/meta-efi-secure-boot/recipes-perl/libfile-slurp/libfile-slurp-perl_9999.19.bb new file mode 100644 index 0000000..142a2f7 --- /dev/null +++ b/meta-efi-secure-boot/recipes-perl/libfile-slurp/libfile-slurp-perl_9999.19.bb @@ -0,0 +1,15 @@ +DESCRIPTION = "Slurp entire files into variables." +SECTION = "libs" +LICENSE = "Artistic-1.0 | GPL-1.0+" + +LIC_FILES_CHKSUM = "file://README;beginline=37;endline=41;md5=255fbd5f98a90d51d9908d31271ae4d4" +SRC_URI = "http://search.cpan.org/CPAN/authors/id/U/UR/URI/File-Slurp-9999.19.tar.gz" + +S = "${WORKDIR}/File-Slurp-${PV}" + +inherit cpan +BBCLASSEXTEND="native" +PACKAGE_ARCH = "all" + +SRC_URI[md5sum] = "7d584cd15c4f8b9547765eff8c4ef078" +SRC_URI[sha256sum] = "ce29ebe995097ebd6e9bc03284714cdfa0c46dc94f6b14a56980747ea3253643" diff --git a/meta-efi-secure-boot/recipes-support/efivar/efivar/Remove-use-of-deprecated-readdir_r.patch b/meta-efi-secure-boot/recipes-support/efivar/efivar/Remove-use-of-deprecated-readdir_r.patch new file mode 100644 index 0000000..af58c22 --- /dev/null +++ b/meta-efi-secure-boot/recipes-support/efivar/efivar/Remove-use-of-deprecated-readdir_r.patch @@ -0,0 +1,44 @@ +From 7078852e4a89f5ba27e7a70bc69641e01a6bff7a Mon Sep 17 00:00:00 2001 +From: Yunguo Wei +Date: Thu, 19 Jan 2017 15:11:25 +0800 +Subject: [PATCH] Remove use of deprecated readdir_r + +Backport 1dc6d576fa4(Remove use of deprecated readdir_r) from +https://github.com/rhinstaller/efivar.git + +Signed-off-by: Yunguo Wei +--- + src/vars.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/src/vars.c b/src/vars.c +index 2a276de..ec0d6bf 100644 +--- a/src/vars.c ++++ b/src/vars.c +@@ -126,19 +126,15 @@ is_64bit(void) + if (dfd < 0) + goto err; + +- struct dirent entry; +- struct dirent *result = NULL; + while (1) { +- int rc = readdir_r(dir, &entry, &result); +- if (rc != 0) +- break; +- if (result == NULL) ++ struct dirent *entry = readdir(dir); ++ if (entry == NULL) + break; + +- if (!strcmp(entry.d_name, "..") || !strcmp(entry.d_name, ".")) ++ if (!strcmp(entry->d_name, "..") || !strcmp(entry->d_name, ".")) + continue; + +- ssize_t size = get_file_data_size(dfd, entry.d_name); ++ ssize_t size = get_file_data_size(dfd, entry->d_name); + if (size < 0) { + continue; + } else if (size == 2084) { +-- +2.7.4 + diff --git a/meta-efi-secure-boot/recipes-support/efivar/efivar_0.24.bbappend b/meta-efi-secure-boot/recipes-support/efivar/efivar_0.24.bbappend new file mode 100644 index 0000000..6d415bb --- /dev/null +++ b/meta-efi-secure-boot/recipes-support/efivar/efivar_0.24.bbappend @@ -0,0 +1,13 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/efivar:" + +SRC_URI += "\ + file://Remove-use-of-deprecated-readdir_r.patch \ +" + +# In dp.h, 'for' loop initial declarations are used +CFLAGS_append = " -std=gnu99" + +# In order to install headers and libraries to sysroot +do_install_append() { + oe_runmake DESTDIR=${D} install +} diff --git a/meta-encrypted-storage/README.md b/meta-encrypted-storage/README.md new file mode 100644 index 0000000..989c8be --- /dev/null +++ b/meta-encrypted-storage/README.md @@ -0,0 +1,179 @@ +### Storage Encryption +This feature provides secure storage for application data. Some applications +need secure storage for sensitive data which must not be accessible to another +device. For example, only an application with the right signature can update +the data on an encrypted SD card. If you move that SD card to another device, +the data cannot be either read or updated. One application of this capability +is a POS application. The application keeps tax information in secure storage +that cannot be modified by another device. + +This feature gives 2 types of granularity for storage encryption. Data volume +encryption allows the user to create encryption partition with a passphrase +typed by the end user. Root filesystem encryption enables the data encryption +on the entire rootfs except the boot partition. + +Both types of storage encryption are based on device-mapper crypt target, +which provides transparent encryption of block devices using the kernel crypto +API. Additionally, the utility cryptsetup is used to conveniently set up disk +encryption, aka LUKS partition, based on device-mapper crypt target. + +Due to the use of TPM state to seal the passphrase used to encrypt the storage, +the encrypted storage cannot be accessed on another machine, preventing from +the so-called offline attack. + +### Dependency +This feature depends on meta-tpm2. + +Note: +Even though the hardware doesn't have a TPM 2.0 device, this feature can still +run on it, although without the guarantee of compromise detection. + +### Limit +- TPM 2.0 is validated and officially supported. But TPM 1.2 device is not + supported by this feature. + +### Data Volume Encryption +#### Use case 1: manual operation +##### Create the LUKS partition +``` +# cryptsetup --type luks --cipher aes-xts-plain --hash sha256 \ + --use-random luksFormat /dev/$dev +``` +where $dev is the device node of the partition to be encrypted. + +This command initializes a LUKS partition and prompts to input an initial +passphrase used to encrypt the data. Don't disclose the passphrase used for +product. + +##### Open the LUKS partition +``` +# cryptsetup luksOpen /dev/$dev $name +``` +This command opens the LUKS device $dev and sets up a mapping $name after +successful verification of the supplied passphrase typed interactively. From +now on, the data written to /dev/mapper/$name is encrypted and the data +read back from /dev/mapper/$name is decrypted transparently and automatically. + +##### Create the filesystem on top of the LUKS partition +The user can run any available filesytem formatting program on +/dev/mapper/$name to create the filesytem with the data encryption. + +##### Close the LUKS partition +``` +# cryptsetup luksClose $name +``` +This command removes the existing mapping $name and wipes the key from kernel +memory. + +To access the encryped partition, follow the instruction "Open the LUKS partition" +and then manually mount /dev/mapper/$name to a mount point. + +#### Use case 2: luks-setup.sh +This script provides a semi automatic method to set up LUKS partition. The user +still needs to manually create the filesystem on top of the newly created LUKS +partition. + +##### LUKS partition creation +In runtime, for example, create LUKS partition on /dev/sdb1 with the +name "my_luks_part": +``` +# luks-setup.sh -d /dev/sdb1 -n my_luks_name -e +``` +Note: if TPM is detected, the passphrase will be generated automatically. + +For more uses about luks-setup.sh, run it with -h option. + +##### Retrieve the passphrase +``` +# cryptfs-tpm2 -q unseal passphrase -P sha1 -o /tmp/passphrase +``` +This command will unseal the passphrase from TPM device and save the content +of passphrase to the file /tmp/passphrase. + +The passphrase should not be disclosed and needs to be backed up to a off-line +storage. + +##### Open the LUKS partition +``` +# cryptsetup luksOpen --key-file /tmp/passphrase /dev/$dev $name +``` +##### Mount the LUKS partition +``` +# mount /dev/mapper/$name $mount_point +``` +The remaining operations are left to the user. Don't forget to close the LUKS +partition if not used. + +Note: +If TPM device exists in the system, the passphrase will be bound to PCR 7, +gating the unseal operation. If the value of PCR 7 when unsealing the +passphrase doesn't match up the value when creating the passphrase, the +passphrase cannot be unsealed. The value of PCR 7 is usually affected by the +status of UEFI secure boot. + +### Root Filesystem Encryption +This enables the data encryption on the rootfs without the need of a human +entering an user passphrase. Therefore, it is required to employ an initramfs +where the unique identity from the platform is collected from the devices on +the platform and used to unlock the root filesystem encryption. Meanwhile, use +TPM to protect the user passphrase for volume decryption to avoid disclosing +the user passphrase. If the TPM device is not detected, the end user will be +prompted to type the user passphrase. + +#### Operations +Note: +The instructions below with the prefix "[TPM]" indicate the operation +requires TPM device. Oppositely, the prefix "[Non-TPM]" indicates this +operation is required if the target board doesn't have a TPM device. + +- Ensure a hard drive is attached on target board + WARNNING: the following instructions will wipe all data in the hard drive. + +- Create overc installer on a USB device + Refer to layers/meta-overc/README.install for the details about how to + run cubeit to install overc installer to a USB device. + +- Attach the USB device to the board + +- Power on + +- [TPM] Clear TPM + Refer to meta-tpm2/README.md for the details. + +- Boot to Linux + +- Install overc runtime on the hard drive + Refer to layers/meta-overc/README.install for the details about how to + run cubeit-installer to install overc runtime to a hard drive. In + addition, beware of specifying "--encrypt" option to set up an + encrypted rootfs. + +- Reboot + After reboot to initramfs, it employs a init script to transparently + unseal the passphrase and mount the rootfs without any interaction. + +### Best Practice +- The benefit of anchoring the TPM is that the machine status cannot be + compromised by any attack. If compromised, the system cannot boot up + due to the failure when mouting the rootfs, or access the encrypted partition + when mounting the LUKS partition. This is caused by the fact that the content + of PCR 7 is different with the value when creating the encrypted storage. + Usually, the content of PCR 7 is calculated based on the status of UEFI + secure boot. + + Based on the above conclusion, it is recommended to provision UEFI secure + boot and turn on it prior to setting up the encrypted storage. + +- The non-default seal secret is supported to provide extra protection, and it + is user configurable. Modify the values of CRYPTFS_TPM2_PRIMARY_KEY_SECRET + and CRYPTFS_TPM2_PASSPHRASE_SECRET in cryptfs-tpm2 with your preference. + +### Known Issues +- The default IMA rules provides the ability of measuring the boot components + and calculating the aggregate integrity value for attesting. However, this + function conflicts with this feature which employs PCR policy session to + retrieve the passphrase in a safe way. If the installer enables both of + them, the default IMA rules will be not used. + +### Reference +- [OpenEmbedded layer for TPM 2.0 enablement](https://github.com/jiazhang0/meta-tpm2) diff --git a/meta-encrypted-storage/conf/layer.conf b/meta-encrypted-storage/conf/layer.conf new file mode 100644 index 0000000..b24954c --- /dev/null +++ b/meta-encrypted-storage/conf/layer.conf @@ -0,0 +1,15 @@ +# We have a conf and classes directory, add to BBPATH +BBPATH .= ":${LAYERDIR}" + +# We have recipes-* directories, add to BBFILES +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ + ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "encrypted-storage" +BBFILE_PATTERN_encrypted-storage = "^${LAYERDIR}/" +BBFILE_PRIORITY_encrypted-storage = "10" + +LAYERDEPENDS_encrypted-storage = "\ + core \ + tpm2 \ +" diff --git a/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage-initramfs.bb b/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage-initramfs.bb new file mode 100644 index 0000000..88e8f7f --- /dev/null +++ b/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage-initramfs.bb @@ -0,0 +1,8 @@ +include packagegroup-encrypted-storage.inc + +DESCRIPTION = "The packages used for encrypted storage in initramfs." + +RDEPENDS_${PN} += " \ + cryptfs-tpm2-initramfs \ + packagegroup-tpm2-initramfs \ +" diff --git a/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage.bb b/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage.bb new file mode 100644 index 0000000..225eb6a --- /dev/null +++ b/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage.bb @@ -0,0 +1,14 @@ +include packagegroup-encrypted-storage.inc + +DESCRIPTION = "The packages used for encrypted storage." + +# Install the minimal stuffs only for the linux rootfs. +# The common packages shared between initramfs and rootfs +# are listed in the .inc. +# @util-linux: fdisk +# @parted: parted +RDEPENDS_${PN} += " \ + util-linux-fdisk \ + parted \ + packagegroup-tpm2 \ +" diff --git a/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage.inc b/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage.inc new file mode 100644 index 0000000..ab4b778 --- /dev/null +++ b/meta-encrypted-storage/recipes-base/packagegroups/packagegroup-encrypted-storage.inc @@ -0,0 +1,25 @@ +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \ + file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +ALLOW_EMPTY_${PN} = "1" + +S = "${WORKDIR}" + +# Install the minimal stuffs for the common uses between initramfs +# and linux rootfs. +# @util-linux: mount, umount +# @cryptsetup: cryptsetup +# @cryptfs-tpm: tpm_gen_dmcrypt_key, tpm_unwrap_dmcrypt_key +# @kmod: modprobe +# @coreutils: cat, mkdir, mknod, cp, rm +# @trousers: tcsd +RDEPENDS_${PN} = " \ + util-linux-mount \ + util-linux-umount \ + cryptsetup \ + kmod \ + coreutils \ + cryptfs-tpm2 \ + procps \ +" diff --git a/meta-encrypted-storage/recipes-kernel/linux/linux-yocto-encrypted-storage.inc b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto-encrypted-storage.inc new file mode 100644 index 0000000..198c972 --- /dev/null +++ b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto-encrypted-storage.inc @@ -0,0 +1,6 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/linux-yocto:" + +SRC_URI += " \ + ${@bb.utils.contains('DISTRO_FEATURES', 'encrypted-storage', \ + 'file://dmcrypt.scc file://dmcrypt.cfg', '', d)} \ +" diff --git a/meta-encrypted-storage/recipes-kernel/linux/linux-yocto-rt_%.bbappend b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto-rt_%.bbappend new file mode 100644 index 0000000..fc85431 --- /dev/null +++ b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto-rt_%.bbappend @@ -0,0 +1 @@ +include linux-yocto-encrypted-storage.inc diff --git a/meta-encrypted-storage/recipes-kernel/linux/linux-yocto/dmcrypt.cfg b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto/dmcrypt.cfg new file mode 100644 index 0000000..cedfcea --- /dev/null +++ b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto/dmcrypt.cfg @@ -0,0 +1,11 @@ +# Enable device-mapper crypt target +CONFIG_DM_CRYPT=y + +# Enable the default cipher-spec for LUKS +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_AES_NI_INTEL=y +CONFIG_CRYPTO_XTS=y + +# Use entropy-strong source for RNG +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_TPM=m diff --git a/meta-encrypted-storage/recipes-kernel/linux/linux-yocto/dmcrypt.scc b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto/dmcrypt.scc new file mode 100644 index 0000000..c549edd --- /dev/null +++ b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto/dmcrypt.scc @@ -0,0 +1 @@ +kconf non-hardware dmcrypt.cfg diff --git a/meta-encrypted-storage/recipes-kernel/linux/linux-yocto_%.bbappend b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto_%.bbappend new file mode 100644 index 0000000..fc85431 --- /dev/null +++ b/meta-encrypted-storage/recipes-kernel/linux/linux-yocto_%.bbappend @@ -0,0 +1 @@ +include linux-yocto-encrypted-storage.inc diff --git a/meta-encrypted-storage/recipes-tpm/cryptfs-tpm2/cryptfs-tpm2_git.bb b/meta-encrypted-storage/recipes-tpm/cryptfs-tpm2/cryptfs-tpm2_git.bb new file mode 100644 index 0000000..2ad7ed1 --- /dev/null +++ b/meta-encrypted-storage/recipes-tpm/cryptfs-tpm2/cryptfs-tpm2_git.bb @@ -0,0 +1,55 @@ +SUMMARY = "A tool used to create, persist, evict a passphrase \ +for full-disk-encryption with TPM 2.0" +DESCRIPTION = " \ +This project provides with an implementation for \ +creating, persisting and evicting a passphrase with TPM 2.0. \ +The passphrase and its associated primary key are automatically \ +created by RNG engine in TPM. In order to avoid saving the \ +context file, the created passphrase and primary key are always \ +persistent in TPM. \ +" +SECTION = "devel" +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=89c8ce1346a3dfe75379e84f3ba9d641" + +SRC_URI = " \ + git://github.com/WindRiver-OpenSourceLabs/cryptfs-tpm2.git \ +" +SRCREV = "32b49092d54b3d59c482d77d5eb1e36993912e89" +PV = "0.6.0+git${SRCPV}" + +DEPENDS += "tpm2.0-tss tpm2-abrmd pkgconfig-native" +RDEPENDS_${PN} += "libtss2 libtctidevice libtctisocket" + +PACKAGES =+ " \ + ${PN}-initramfs \ +" + +PARALLEL_MAKE = "" + +S = "${WORKDIR}/git" + +EXTRA_OEMAKE = " \ + sbindir="${sbindir}" \ + libdir="${libdir}" \ + includedir="${includedir}" \ + tpm2_tss_includedir="${STAGING_INCDIR}/sapi" \ + tpm2_tss_libdir="${STAGING_LIBDIR}" \ + tpm2_tabrmd_includedir="${STAGING_INCDIR}" \ + CC="${CC}" \ + PKG_CONFIG="${STAGING_BINDIR_NATIVE}/pkg-config" \ + EXTRA_CFLAGS="${CFLAGS}" \ + EXTRA_LDFLAGS="${LDFLAGS}" \ +" + +do_install() { + oe_runmake install DESTDIR="${D}" + + if [ x"${@bb.utils.contains('DISTRO_FEATURES', 'encrypted-storage', '1', '0', d)}" = x"1" ]; then + install -m 0500 ${S}/script/init.cryptfs ${D} + fi +} + +FILES_${PN}-initramfs = "\ + /init.cryptfs \ +" diff --git a/meta-integrity/COPYING.MIT b/meta-integrity/COPYING.MIT new file mode 100644 index 0000000..fb950dc --- /dev/null +++ b/meta-integrity/COPYING.MIT @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/meta-integrity/README.md b/meta-integrity/README.md new file mode 100644 index 0000000..2efb494 --- /dev/null +++ b/meta-integrity/README.md @@ -0,0 +1,166 @@ +### meta-integrity +OpenEmbedded layer for Linux integrity support + +#### Integrity Measurement Architecture (IMA) +The Linux IMA subsystem introduces hooks within the Linux kernel to support +measuring the integrity of files that are loaded (including application code) +before it is executed or mmap()ed to memory. The measured value (hash) is then +registered in a log that can be consulted by administrators. + +To support proven integrity of the files, the IMA subsystem can interact with +the TPM chip within the system to protect the registered hashes from tampering +by a rogue administrator or application. The IMA subsystem, as already +supported by the Linux kernel, supports reporting on the hashes of files and +commands ran by privileged accounts (and more if you create your own +measurement policies). + +In addition, IMA appraisal can even register the measured value as an extended +attribute, and after subsequent measurement(s) validate this extended attribute +against the measured value and refuse to load the file (or execute the +application) if the hash does not match. In that case, the IMA subsystem allows +files and applications to be loaded if the hashes match (and will save the +updated hash if the file is modified) but refuse to load it if it doesn't. This +provides some protection against offline tampering of the files. + +NOTE: Extended file system attribute is required for IMA appraisal, but not +all file systems can support it. Typically, the pseudo file systems, such as +sysfs, proc, tmpfs and ramfs, certain disk-based file systems, such as FAT, +and network file systems, such as NFS, don't support extended attribute, +meaning IMA appraisal is not available with them. + +##### Dependency +- meta-tpm + This layer provides the kernel configurations for TPM 1.x enablement. + +- meta-tpm2 + This layer provides the kernel configurations for TPM 2.0 enablement. + +##### Use The External IMA Policy +initramfs is a good place to run some IMA initializations, such as loading +the IMA policy, as well as the public keys used to verify IMA signatures. + +###### The default external IMA policy +The default external IMA policy enforces appraising all the executable, shared +library, kernel modules and firmwares with the digital signature in the +effective root identity (euid=0). Hence, the opportunity of loading the default +external IMA policy occurs at the end of initramfs initializations, just before +switch_root. + +Instead of running switch_root directly from initramfs, a statically linked +switch_root from the real rootfs is called and it must be already signed +properly. Otherwise, switch_root will fail to mount the real rootfs and kernel +panic will happen due to this failure. + +The default external IMA policy is located at `/etc/ima_policy.default` in +initramfs. If a custom external IMA policy file exists, the default external +IMA policy file won't be used any more. + +The default external IMA policy enables the following constraint conditions: +- Appraise the files for exec'd (the executables), files mmap'd for exec + (shared libraries), kernel modules and firmwares in effective root identity + (euid=0). +- Enforce verifying the IMA signature when running the executables, shared + libraries, kernel modules and firmwares. +- Deny to run the newly created executables, shared libraries, kernel modules + and firmwares. +- Deny to run the tampered executables, shared libraries, kernel modules and + firmwares. +- Deny to run any executables, shared libraries, kernel modules and firmwares + in the filesystems without file extended attribute supported. +- Allow to run the manually signed executables, shared libraries, kernel + modules and firmwares. +- Allow to run the updated executables, shared libraries, kernel modules and + firmwares during RPM installation. +- Note the different behaviors when executing a script. + e.g, launching a python script with "./test.py" is allowed only when test.py + is signed, and launching a python script with "python test.py" is always + allowed as long as the python interpreter is signed. + +###### The custom external IMA policy +If the default external IMA policy cannot meet the protection requirement, it +is allowed to define the custom external IMA policy. + +- Deploy the custom policy file to installer image + +- Create `/opt/installer/sbin/config-installer.sh` in installer image + Define the IMA_POLICY variable, pointing to the path of policy file. + +The custom external IMA policy file is eventually installed to `/etc/ima_policy` +in initramfs. + +##### IMA certificate & private Key +The private key come in two flavors; one used by an installer to sign all +regular files in rootfs and one used by RPM to re-sign the executable, shared +library, kernel module and firmware during RPM installation. Correspondingly, +the IMA certificate is used to verify the IMA signature signed by the private +key. + +In addition, initramfs is a good place to import the IMA certificate likewise. + +###### The default IMA certificate & private key +The default IMA certificate & private key are generated by the build system. By +default, the sample keys are used for the purpose of development and +demonstration. Please ensure you know what your risk is to use the sample keys +in your product, because they are completely public. + +### Best practice +The following best practices should be applied with using IMA. + +- Enable UEFI/MOK secure boot + UEFI/MOK secure boot can verify the integrity of initramfs, providing the + protection against tampering of the external IMA policy files and IMA public + keys stored in initramfs. + +- Moderate measuring + Measuring the files owned by non-root user may introduce malicious attack. + Malicious user may create lots of files with different names or trigger + violation conditions to generate a mass of event logs recorded in the runtime + measurement list, and thus exhaust the persistent kernel memory. + +- Performance influence + Moderate policy can make a good balance between the performance and security. + Tune the default external policy (`/etc/ima_policy.default`) and modulate the + custom policy for the product requirement. + +- Use IMA digital signature to protect the executable + Using the digital signature scheme DIGSIG is safer than digest-based scheme. + Meanwhile, use `appraise_type=imasig` in your IMA policy to enforce running + this. + +- Use the measurement and audit rules together + The runtime measurement list is unable to track down the order of changes for + a file, e.g, a file content varies in order of X -> Y -> X. However, audit log + can record these changes in the right order. + +##### Known Issues +- The following operations may break the behavior of appraisal and cause the + failure of launching the executables, shared libraries, kernel modules and + firmwares: + - the syscalls used to set file last access and modification times. + - the syscalls used to set ownership of a file. + - the syscalls used to set permissions of a file. + + To fix the failure, manually re-sign the affected file. + + Note: RPM installation violates the IMA appraisal but its post_install + operation will always re-sign the affected files. + +- Overwriting an existing file with the same content is deemed as tampering of + the file. + +- The default IMA rules provides the ability of measuring the boot components + and calculating the aggregate integrity value for attesting. However, this + function conflicts with encrypted-storage feature which employs PCR policy + session to retrieve the passphrase in a safe way. If the installer enables + both of them, the default IMA rules will be not used. + +### Reference +[IMA wiki page](https://sourceforge.net/p/linux-ima/wiki/Home/) + +[OpenEmbedded layer for EFI Secure Boot](https://github.com/jiazhang0/meta-efi-secure-boot) + +[OpenEmbedded layer for signing key management](https://github.com/jiazhang0/meta-signing-key) + +[OpenEmbedded layer for TPM 1.x](https://github.com/jiazhang0/meta-tpm) + +[OpenEmbedded layer for TPM 2.0](https://github.com/jiazhang0/meta-tpm2) diff --git a/meta-integrity/classes/rpm5-ima.bbclass b/meta-integrity/classes/rpm5-ima.bbclass new file mode 100644 index 0000000..fbdefeb --- /dev/null +++ b/meta-integrity/classes/rpm5-ima.bbclass @@ -0,0 +1,156 @@ +inherit package + +PACKAGEFUNCS =+ "package_ima_hook" + +# security.ima is generated during the RPM build, and the base64-encoded +# value is written during RPM installation. In addition, if the private +# key is deployed on board, re-sign the updated files during RPM +# installation in higher priority. +python package_ima_hook() { + packages = d.getVar('PACKAGES', True) + pkgdest = d.getVar('PKGDEST', True) + ima_signing_blacklist = d.getVar('IMA_SIGNING_BLACKLIST', True) + ima_keys_dir = d.getVar('IMA_KEYS_DIR', True) + + pkg_suffix_blacklist = ('dbg', 'dev', 'doc', 'locale', 'staticdev') + + pkg_blacklist = () + with open(ima_signing_blacklist, 'r') as f: + pkg_blacklist = [ _.strip() for _ in f.readlines() ] + pkg_blacklist = tuple(pkg_blacklist) + + import base64, pipes, stat + + for pkg in packages.split(): + if (pkg.split('-')[-1] in pkg_suffix_blacklist) is True: + continue + + if pkg.startswith(pkg_blacklist) is True: + continue + + bb.note("Writing IMA %%post hook for %s ..." % pkg) + + pkgdestpkg = os.path.join(pkgdest, pkg) + + cmd = 'evmctl ima_sign --hashalgo sha256 -n --sigfile --key %s/x509_ima.key ' % (ima_keys_dir) + sig_list = [] + pkg_sig_list = [] + + for _ in pkgfiles[pkg]: + # Ignore the symbol links. + if os.path.islink(_): + continue + + # IMA appraisal is only applied to the regular file. + if not stat.S_ISREG(os.stat(_)[stat.ST_MODE]): + continue + + bb.note("Preparing to sign %s ..." % _) + + sh_name = pipes.quote(_) + print("Signing command: %s" % cmd + sh_name) + rc, res = oe.utils.getstatusoutput(cmd + sh_name + " >/dev/null") + if rc: + bb.fatal('Calculate IMA signature for %s failed with exit code %s:\n%s' % \ + (_, rc, res if res else "")) + + with open(_ + '.sig', 'rb') as f: + s = str(base64.b64encode(f.read()).decode('ascii')) + '|' + sig_list.append(s + os.sep + os.path.relpath(_, pkgdestpkg)) + + os.remove(_ + '.sig') + + ima_sig_list = '&'.join(sig_list) + + # When the statically linked binary is updated, use the + # dynamically linked one to resign or set. This situation + # occurs in runtime only. + setfattr_bin = 'setfattr.static' + evmctl_bin = 'evmctl.static' + # We don't want to create a statically linked echo program + # any more. + safe_echo = '1' + if pkg == 'attr-setfattr.static': + setfattr_bin = 'setfattr' + elif pkg == 'ima-evm-utils-evmctl.static': + evmctl_bin = 'evmctil' + elif pkg == 'coreutils': + safe_echo = '0' + + # The %post is dynamically constructed according to the currently + # installed package and enviroment. + postinst = r'''#!/bin/sh + +# %post hook for IMA appraisal +ima_resign=0 +sig_list="''' + ima_sig_list + r'''" + +if [ -z "$D" ]; then + evmctl_bin="${sbindir}/''' + evmctl_bin + r'''" + setfattr_bin="${bindir}/''' + setfattr_bin + r'''" + + [ -f "/etc/keys/privkey_evm.pem" -a -x "$evmctl_bin" ] && \ + ima_resign=1 + + safe_echo="''' + safe_echo + r'''" + + cond_print() + { + [ $safe_echo = "1" ] && echo $1 + } + + saved_IFS="$IFS" + IFS="&" + for entry in $sig_list; do + IFS="|" + + tokens="" + for token in $entry; do + tokens="$tokens$token|" + done + + for sig in $tokens; do + break + done + + IFS="$saved_IFS" + + f="$token" + + # If the filesystem doesn't support xattr, skip the following steps. + res=`"$setfattr_bin" -x security.ima "$f" 2>&1 | grep "Operation not supported$"` + [ x"$res" != x"" ] && { + cond_print "Current file system doesn't support to set xattr" + break + } + + if [ $ima_resign -eq 0 ]; then + cond_print "Setting up security.ima for $f ..." + + "$setfattr_bin" -n security.ima -v "0s$sig" "$f" || { + err=$? + cond_print "Unable to set up security.ima for $f (err: $err)" + exit 1 + } + else + cond_print "IMA signing for $f ..." + + "$evmctl_bin" ima_sign --hashalgo sha256 "$f" || { + err=$? + cond_print "Unable to sign $f (err: $err)" + exit 1 + } + fi + + IFS="&" + done + + IFS="$saved_IFS" +fi + +''' + postinst = postinst + (d.getVar('pkg_postinst_%s' % pkg, True) or '') + d.setVar('pkg_postinst_%s' % pkg, postinst) +} + +do_package[depends] += "ima-evm-utils-native:do_populate_sysroot" diff --git a/meta-integrity/conf/layer.conf b/meta-integrity/conf/layer.conf new file mode 100644 index 0000000..f3c00e0 --- /dev/null +++ b/meta-integrity/conf/layer.conf @@ -0,0 +1,19 @@ +# We have a conf and classes directory, add to BBPATH +BBPATH .= ":${LAYERDIR}" + +# We have recipes-* directories, add to BBFILES +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ + ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "integrity" +BBFILE_PATTERN_integrity = "^${LAYERDIR}/" +BBFILE_PRIORITY_integrity = "10" + +IMA_SIGNING_BLACKLIST ??= "${LAYERDIR}/files/ima_signing_blacklist" + +LAYERDEPENDS_integrity = "\ + core \ + signing-key \ + tpm2 \ + tpm \ +" diff --git a/meta-integrity/files/ima_signing_blacklist b/meta-integrity/files/ima_signing_blacklist new file mode 100644 index 0000000..276a7bc --- /dev/null +++ b/meta-integrity/files/ima_signing_blacklist @@ -0,0 +1 @@ +kernel-devsrc diff --git a/meta-integrity/recipes-base/packagegroups/packagegroup-ima-initramfs.bb b/meta-integrity/recipes-base/packagegroups/packagegroup-ima-initramfs.bb new file mode 100644 index 0000000..89cb120 --- /dev/null +++ b/meta-integrity/recipes-base/packagegroups/packagegroup-ima-initramfs.bb @@ -0,0 +1,12 @@ +DESCRIPTION = "Linux Integrity Measurement Architecture (IMA) subsystem for initramfs" + +include packagegroup-ima.inc + +RDEPENDS_${PN} += " \ + util-linux-mount \ + util-linux-umount \ + gawk \ + ima-policy \ + key-store-ima-cert \ + initrdscripts-ima \ +" diff --git a/meta-integrity/recipes-base/packagegroups/packagegroup-ima.bb b/meta-integrity/recipes-base/packagegroups/packagegroup-ima.bb new file mode 100644 index 0000000..e10300e --- /dev/null +++ b/meta-integrity/recipes-base/packagegroups/packagegroup-ima.bb @@ -0,0 +1,21 @@ +DESCRIPTION = "Linux Integrity Measurement Architecture (IMA) subsystem" + +include packagegroup-ima.inc + +DEPENDS += " \ + ima-evm-utils-native \ + attr-native \ +" + +RDEPENDS_${PN} += " \ + attr \ + util-linux-switch_root.static \ + attr-setfattr.static \ + ima-evm-utils-evmctl.static \ +" + +# Note any private key is not available if user key signing model used. +RRECOMMENDS_${PN} += " \ + key-store-ima-privkey \ + key-store-system-trusted-privkey \ +" diff --git a/meta-integrity/recipes-base/packagegroups/packagegroup-ima.inc b/meta-integrity/recipes-base/packagegroups/packagegroup-ima.inc new file mode 100644 index 0000000..64829dc --- /dev/null +++ b/meta-integrity/recipes-base/packagegroups/packagegroup-ima.inc @@ -0,0 +1,13 @@ +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \ + file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +S = "${WORKDIR}" + +ALLOW_EMPTY_${PN} = "1" + +RDEPENDS_${PN} = " \ + ima-evm-utils \ + coreutils \ + grep \ +" diff --git a/meta-integrity/recipes-core/base-files/base-files_%.bbappend b/meta-integrity/recipes-core/base-files/base-files_%.bbappend new file mode 100644 index 0000000..2636dad --- /dev/null +++ b/meta-integrity/recipes-core/base-files/base-files_%.bbappend @@ -0,0 +1,4 @@ +# Append iversion option for auto types +do_install_append() { + sed -i 's/\s*auto\s*defaults/&,iversion/' ${D}${sysconfdir}/fstab +} diff --git a/meta-integrity/recipes-core/initrdscripts/files/init.ima b/meta-integrity/recipes-core/initrdscripts/files/init.ima new file mode 100755 index 0000000..1e92ba2 --- /dev/null +++ b/meta-integrity/recipes-core/initrdscripts/files/init.ima @@ -0,0 +1,129 @@ +#!/bin/sh + +# Initramfs script for IMA initialzation +# +# This script is a halper used to load the external +# IMA policy and public keys used to verify the IMA +# signature. +# +# Copyright (c) 2017, Jia Zhang +# All rights reserved. +# +# See "LICENSE" for license terms. + +# Exit code: +# 0 - IMA initialiazation complete +# 1 - Kernel doesn't support securityfs +# 2 - Kernel doesn't support IMA +# 3 - There is no public key to load +# 4 - There is no IMA policy file defined +# 5 - Unable to load IMA policy file + +# If root directory is not specified, the root of +# initramfs assumed. +ROOT_DIR="${1}" + +SECURITYFS_DIR="${ROOT_DIR}/sys/kernel/security" + +# The policy files are always placed in initramfs +IMA_POLICY=/etc/ima_policy + +SECURITYFS_MOUNTED=0 + +function print_critical +{ + printf "\033[1;35m" + echo "$@" + printf "\033[0m" +} + +function print_error +{ + printf "\033[1;31m" + echo "$@" + printf "\033[0m" +} + +function print_warning +{ + printf "\033[1;33m" + echo "$@" + printf "\033[0m" +} + +function print_info +{ + printf "\033[1;32m" + echo "$@" + printf "\033[0m" +} + +function print_verbose +{ + printf "\033[1;36m" + echo "$@" + printf "\033[0m" +} + +function trap_handler +{ + local err=$? + + print_verbose "Cleaning up with exit code $err ..." + + [ $SECURITYFS_MOUNTED -eq 1 ] && + umount "$SECURITYFS_DIR" 2>"${ROOT_DIR}/dev/null" +} + +trap "trap_handler $?" SIGINT EXIT + +if grep -q "ima_appraise=off" "${ROOT_DIR}/proc/cmdline"; then + print_info "Skip to load the public key and IMA policy" + exit 0 +fi + +if ! grep -q securityfs "${ROOT_DIR}/proc/mounts"; then + ! mount -t securityfs none "$SECURITYFS_DIR" 2>"${ROOT_DIR}/dev/null" && { + print_error "Unable to mount securityfs filesystem" + exit 1 + } + SECURITYFS_MOUNTED=1 + securityfs_dir="$SECURITYFS_DIR" +else + securityfs_dirs="$(grep securityfs ${ROOT_DIR}/proc/mounts | awk '{print $2}')" + + # Use the first one. + for securityfs_dir in "$securityfs_dirs"; do + break + done +fi + +[ ! -d "$securityfs_dir/ima" ] && + print_info "IMA is not enabled. Exiting ..." && exit 2 + +keyring_id=0x`grep '\skeyring\s*\.ima: ' "${ROOT_DIR}/proc/keys" | awk '{ print $1 }'` + +for key in ${ROOT_DIR}/etc/keys/x509_evm*.pem; do + [ ! -s "$key" ] && continue + + if ! evmctl import "$key" "$keyring_id" >"${ROOT_DIR}/dev/null"; then + print_critical "Unable to load the public key $key for IMA appraisal" + else + print_verbose "The external public key $key loaded for IMA appraisal" + fi +done + +# Attempt to load the default policy. +[ ! -f "${IMA_POLICY}" ] && IMA_POLICY="${IMA_POLICY}.default" + +[ ! -f "${IMA_POLICY}" ] && { + print_warning "No IMA policy file defined" + exit 4 +} + +cat "${IMA_POLICY}" > "$securityfs_dir/ima/policy" && { + exit 0 +} || { + print_critical "Unable to load the IMA policy ${IMA_POLICY}" + exit 5 +} diff --git a/meta-integrity/recipes-core/initrdscripts/initrdscripts-ima.bb b/meta-integrity/recipes-core/initrdscripts/initrdscripts-ima.bb new file mode 100644 index 0000000..3860be2 --- /dev/null +++ b/meta-integrity/recipes-core/initrdscripts/initrdscripts-ima.bb @@ -0,0 +1,47 @@ +DESCRIPTION = "The initrd script for Linux Integrity Measurement Architecture (IMA)" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \ + file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +S = "${WORKDIR}" + +ALLOW_EMPTY_${PN} = "1" + +SRC_URI = "\ + file://init.ima \ +" + +do_install() { + if [ x"${@bb.utils.contains('DISTRO_FEATURES', 'ima', '1', '0', d)}" = x"1" ]; then + install -m 0500 ${WORKDIR}/init.ima ${D} + fi +} + +FILES_${PN} += " \ + ${@bb.utils.contains('DISTRO_FEATURES', 'ima', '/init.ima', '', d)} \ +" + +# Install the minimal stuffs only, and don't care how the external +# environment is configured. +# @bash: sh +# @coreutils: echo, mkdir, mknod, dirname, basename, cp, rm, sleep +# seq, printf, cut +# @grep: grep +# @gawk: awk +# @kmod: modprobe, depmod +# @net-tools: ifconfig +# @trousers: tcsd +# @procps: pkill +# @util-linux: blkid, mount, umount +RDEPENDS_${PN} += "\ + bash \ + coreutils \ + grep \ + gawk \ + kmod \ + net-tools \ + procps \ + util-linux-blkid \ + util-linux-mount \ + util-linux-umount \ +" diff --git a/meta-integrity/recipes-core/util-linux/util-linux_%.bbappend b/meta-integrity/recipes-core/util-linux/util-linux_%.bbappend new file mode 100644 index 0000000..1728f2e --- /dev/null +++ b/meta-integrity/recipes-core/util-linux/util-linux_%.bbappend @@ -0,0 +1,16 @@ +PACKAGES =+ "${PN}-switch_root.static" + +CFLAGS_remove += "-pie -fpie" + +do_compile_append_class-target() { + ${CC} ${CFLAGS} ${LDFLAGS} -static \ + sys-utils/switch_root.o \ + -o switch_root.static +} + +do_install_append_class-target() { + install -d ${D}${sbindir} + install -m 0700 ${B}/switch_root.static ${D}${sbindir}/switch_root.static +} + +FILES_${PN}-switch_root.static = "${sbindir}/switch_root.static" diff --git a/meta-integrity/recipes-kernel/linux/linux-yocto-integrity.inc b/meta-integrity/recipes-kernel/linux/linux-yocto-integrity.inc new file mode 100644 index 0000000..8c08a45 --- /dev/null +++ b/meta-integrity/recipes-kernel/linux/linux-yocto-integrity.inc @@ -0,0 +1,18 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/linux-yocto:" + +IMA_ENABLED = "${@bb.utils.contains('DISTRO_FEATURES', 'ima', '1', '0', d)}" + +DEPENDS += "${@'key-store openssl-native' if d.getVar('IMA_ENABLED', True) == '1' else ''}" +# key-store-ima-cert is required in runtime but we hope it is available +# in initramfs only. So we don't add it to RDEPENDS_${PN} here. + +SRC_URI += " \ + ${@'file://ima.scc file://ima.cfg' if d.getVar('IMA_ENABLED', True) == '1' else ''} \ +" + +do_configure_append() { + [ -f "${STAGING_DIR_TARGET}${sysconfdir}/keys/system_trusted_key.pem" ] && + openssl x509 -in "${STAGING_DIR_TARGET}${sysconfdir}/keys/system_trusted_key.pem" \ + -outform DER -out "${B}/system_trusted_cert.x509" || + true +} diff --git a/meta-integrity/recipes-kernel/linux/linux-yocto-rt_4.%.bbappend b/meta-integrity/recipes-kernel/linux/linux-yocto-rt_4.%.bbappend new file mode 100644 index 0000000..685d15c --- /dev/null +++ b/meta-integrity/recipes-kernel/linux/linux-yocto-rt_4.%.bbappend @@ -0,0 +1 @@ +include linux-yocto-integrity.inc diff --git a/meta-integrity/recipes-kernel/linux/linux-yocto/ima.cfg b/meta-integrity/recipes-kernel/linux/linux-yocto/ima.cfg new file mode 100644 index 0000000..073197a --- /dev/null +++ b/meta-integrity/recipes-kernel/linux/linux-yocto/ima.cfg @@ -0,0 +1,35 @@ +.......................................................................... +. WARNING +. +. This file is a kernel configuration fragment, and not a full kernel +. configuration file. The final kernel configuration is made up of +. an assembly of processed fragments, each of which is designed to +. capture a specific part of the final configuration (e.g. platform +. configuration, feature configuration, and board specific hardware +. configuration). For more information on kernel configuration, please +. consult the product documentation. +. +.......................................................................... + +CONFIG_IMA=y +CONFIG_IMA_MEASURE_PCR_IDX=10 +# CONFIG_IMA_TEMPLATE is not set +# CONFIG_IMA_NG_TEMPLATE=y is not set +CONFIG_IMA_SIG_TEMPLATE=y +CONFIG_IMA_DEFAULT_TEMPLATE="ima-sig" +# CONFIG_IMA_DEFAULT_HASH_SHA1 is not set +CONFIG_IMA_DEFAULT_HASH_SHA256=y +# CONFIG_IMA_DEFAULT_HASH_SHA512 is not set +# CONFIG_IMA_DEFAULT_HASH_WP512 is not set +CONFIG_IMA_DEFAULT_HASH="sha256" +CONFIG_IMA_APPRAISE=y +CONFIG_INTEGRITY_SIGNATURE=y +CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y +CONFIG_INTEGRITY_TRUSTED_KEYRING=y +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_IMA_LOAD_X509=y +CONFIG_IMA_TRUSTED_KEYRING=y +CONFIG_IMA_X509_PATH="/etc/keys/x509_evm.der" +# CONFIG_IMA_APPRAISE_SIGNED_INIT is not set +CONFIG_AUDIT=y +CONFIG_INTEGRITY_AUDIT=y diff --git a/meta-integrity/recipes-kernel/linux/linux-yocto/ima.scc b/meta-integrity/recipes-kernel/linux/linux-yocto/ima.scc new file mode 100644 index 0000000..c43e1c4 --- /dev/null +++ b/meta-integrity/recipes-kernel/linux/linux-yocto/ima.scc @@ -0,0 +1,4 @@ +define KFEATURE_DESCRIPTION "Integrity Measurement Architecture (IMA) enablement" +define KFEATURE_COMPATIBILITY board + +kconf non-hardware ima.cfg diff --git a/meta-integrity/recipes-kernel/linux/linux-yocto_4.%.bbappend b/meta-integrity/recipes-kernel/linux/linux-yocto_4.%.bbappend new file mode 100644 index 0000000..685d15c --- /dev/null +++ b/meta-integrity/recipes-kernel/linux/linux-yocto_4.%.bbappend @@ -0,0 +1 @@ +include linux-yocto-integrity.inc diff --git a/meta-integrity/recipes-support/ima-evm-utils/ima-evm-utils/0001-Don-t-build-man-pages.patch b/meta-integrity/recipes-support/ima-evm-utils/ima-evm-utils/0001-Don-t-build-man-pages.patch new file mode 100644 index 0000000..db006c0 --- /dev/null +++ b/meta-integrity/recipes-support/ima-evm-utils/ima-evm-utils/0001-Don-t-build-man-pages.patch @@ -0,0 +1,27 @@ +From b5bc04d9062a69e116ed60ad540b56cd057d47d1 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Tue, 27 Dec 2016 14:25:58 +0800 +Subject: [PATCH] Don't build man pages + +Too many external tools are required to build the man pages. We don't +need them anyway. + +Signed-off-by: George McCollister +Signed-off-by: Lans Zhang +--- + Makefile.am | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/Makefile.am b/Makefile.am +index 06ebf59..e527f34 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1,5 +1,4 @@ + SUBDIRS = src +-dist_man_MANS = evmctl.1 + + doc_DATA = examples/ima-genkey-self.sh examples/ima-genkey.sh examples/ima-gen-local-ca.sh + EXTRA_DIST = autogen.sh $(doc_DATA) +-- +2.7.4 + diff --git a/meta-integrity/recipes-support/ima-evm-utils/ima-evm-utils/0001-Install-evmctl-to-sbindir-rather-than-bindir.patch b/meta-integrity/recipes-support/ima-evm-utils/ima-evm-utils/0001-Install-evmctl-to-sbindir-rather-than-bindir.patch new file mode 100644 index 0000000..545be42 --- /dev/null +++ b/meta-integrity/recipes-support/ima-evm-utils/ima-evm-utils/0001-Install-evmctl-to-sbindir-rather-than-bindir.patch @@ -0,0 +1,28 @@ +From 412f60bbd5a7ed1eac7051bd2947d5fc0c95e86b Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Thu, 12 Jan 2017 16:55:03 +0800 +Subject: [PATCH] Install evmctl to $sbindir rather than $bindir + +Setting security.ima requires sys_admin capability. + +Signed-off-by: Lans Zhang +--- + src/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/Makefile.am b/src/Makefile.am +index deb18fb..aa8f666 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -9,7 +9,7 @@ libimaevm_la_LIBADD = $(OPENSSL_LIBS) + + include_HEADERS = imaevm.h + +-bin_PROGRAMS = evmctl ++sbin_PROGRAMS = evmctl + + evmctl_SOURCES = evmctl.c + evmctl_CPPFLAGS = $(OPENSSL_CFLAGS) +-- +2.7.4 + diff --git a/meta-integrity/recipes-support/ima-evm-utils/ima-evm-utils_git.bb b/meta-integrity/recipes-support/ima-evm-utils/ima-evm-utils_git.bb new file mode 100644 index 0000000..c1278a9 --- /dev/null +++ b/meta-integrity/recipes-support/ima-evm-utils/ima-evm-utils_git.bb @@ -0,0 +1,41 @@ +LICENSE = "GPLv2" +LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263" + +SRC_URI = " \ + git://git.code.sf.net/p/linux-ima/ima-evm-utils \ + file://0001-Don-t-build-man-pages.patch \ + file://0001-Install-evmctl-to-sbindir-rather-than-bindir.patch \ +" +SRCREV = "3e2a67bdb0673581a97506262e62db098efef6d7" +PV = "1.0+git${SRCPV}" + +S = "${WORKDIR}/git" + +PACKAGES =+ "${PN}-evmctl.static" + +DEPENDS += "openssl attr keyutils" +RDEPENDS_${PN}_class-target += "libcrypto libattr keyutils" + +inherit pkgconfig autotools + +# Specify any options you want to pass to the configure script using EXTRA_OECONF: +EXTRA_OECONF = "" + +CFLAGS_remove += "-pie -fpie" + +do_compile_append_class-target() { + ${CC} ${CFLAGS} ${LDFLAGS} -static \ + -include config.h -L=${libdir} \ + -Wl,--start-group -lcrypto -lkeyutils -ldl \ + ${S}/src/evmctl.c ${S}/src/libimaevm.c \ + -Wl,--end-group -o ${B}/src/evmctl.static +} + +do_install_append_class-target() { + install -m 0700 ${B}/src/evmctl.static ${D}${sbindir}/evmctl.static +} + +FILES_${PN}-dev += "${includedir}" +FILES_${PN}-evmctl.static = "${sbindir}/evmctl.static" + +BBCLASSEXTEND = "native nativesdk" diff --git a/meta-integrity/recipes-support/ima-policy/files/ima_policy.default b/meta-integrity/recipes-support/ima-policy/files/ima_policy.default new file mode 100644 index 0000000..5d4ae47 --- /dev/null +++ b/meta-integrity/recipes-support/ima-policy/files/ima_policy.default @@ -0,0 +1,24 @@ +# The default external IMA policy + +# Don't appraise any file opened. +# However, we cannot write down such a rule, +# dont_appraise func=FILE_CHECK +# +# because this rule will accidently cause the security.ima +# being deleted in post_setattr() path. In fact, this is a +# real bug in policy engine when handling post_setattr() +# hook. The failure can be triggered in such a way: +# touch /bin/ls +# /bin/ls <- permission denied + +# Reduce performance loss +# audit func=FILE_CHECK fowner=0 mask=^MAY_READ +# measure func=FILE_CHECK fowner=0 mask=^MAY_READ + +appraise func=MMAP_CHECK euid=0 appraise_type=imasig + +appraise func=BPRM_CHECK euid=0 appraise_type=imasig + +appraise func=MODULE_CHECK euid=0 appraise_type=imasig + +appraise func=FIRMWARE_CHECK euid=0 appraise_type=imasig diff --git a/meta-integrity/recipes-support/ima-policy/ima-policy_0.1.bb b/meta-integrity/recipes-support/ima-policy/ima-policy_0.1.bb new file mode 100644 index 0000000..982717a --- /dev/null +++ b/meta-integrity/recipes-support/ima-policy/ima-policy_0.1.bb @@ -0,0 +1,18 @@ +DESCRIPTION = "The default external IMA policy" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \ + file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +SRC_URI = " \ + file://ima_policy.default \ + " + +S = "${WORKDIR}" + +do_install() { + install -d "${D}${sysconfdir}" + install -m 0400 "${WORKDIR}/ima_policy.default" \ + "${D}${sysconfdir}" +} + +FILES_${PN} = "${sysconfdir}" diff --git a/meta-integrity/recipes-support/keyutils/keyutils/keyutils-fix-powerpc-cflags.patch b/meta-integrity/recipes-support/keyutils/keyutils/keyutils-fix-powerpc-cflags.patch new file mode 100644 index 0000000..11be1e1 --- /dev/null +++ b/meta-integrity/recipes-support/keyutils/keyutils/keyutils-fix-powerpc-cflags.patch @@ -0,0 +1,28 @@ +From 1cc17e3c8b1f73db43011775292396338f932a20 Mon Sep 17 00:00:00 2001 +From: Lei Maohui +Date: Mon, 17 Aug 2015 15:30:40 +0900 +Subject: [PATCH] keyutils fix powerpc cflags + +--- + Makefile | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/Makefile b/Makefile +index 82e1a0f..0746c82 100644 +--- a/Makefile ++++ b/Makefile +@@ -65,12 +65,10 @@ BUILDFOR := $(shell file /usr/bin/make | sed -e 's!.*ELF \(32\|64\)-bit.*!\1!')- + LNS := ln -sf + + ifeq ($(BUILDFOR),32-bit) +-CFLAGS += -m32 + LIBDIR := /usr/lib + USRLIBDIR := /usr/lib + else + ifeq ($(BUILDFOR),64-bit) +-CFLAGS += -m64 + LIBDIR := /usr/lib + USRLIBDIR := /usr/lib + endif +-- +1.8.4.2 diff --git a/meta-integrity/recipes-support/keyutils/keyutils/keyutils-fix-the-cflags-for-all-of-targets.patch b/meta-integrity/recipes-support/keyutils/keyutils/keyutils-fix-the-cflags-for-all-of-targets.patch new file mode 100644 index 0000000..77cf528 --- /dev/null +++ b/meta-integrity/recipes-support/keyutils/keyutils/keyutils-fix-the-cflags-for-all-of-targets.patch @@ -0,0 +1,32 @@ +From 8a1331d4abf9a96ee65e5fb31a00c7a2e0eed7c8 Mon Sep 17 00:00:00 2001 +From: Lei Maohui +Date: Mon, 17 Aug 2015 13:53:28 +0900 +Subject: [PATCH] fix the cflags for all of targets. + +Signed-off-by: Lei Maohui +--- + Makefile | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/Makefile b/Makefile +index e2d7e2d..82e1a0f 100644 +--- a/Makefile ++++ b/Makefile +@@ -64,7 +64,6 @@ BUILDFOR := $(shell file /usr/bin/make | sed -e 's!.*ELF \(32\|64\)-bit.*!\1!')- + + LNS := ln -sf + +-ifeq ($(origin CFLAGS),undefined) + ifeq ($(BUILDFOR),32-bit) + CFLAGS += -m32 + LIBDIR := /usr/lib +@@ -76,7 +75,6 @@ LIBDIR := /usr/lib + USRLIBDIR := /usr/lib + endif + endif +-endif + + ############################################################################### + # +-- +1.8.4.2 diff --git a/meta-integrity/recipes-support/keyutils/keyutils/keyutils-remove-m32-m64.patch b/meta-integrity/recipes-support/keyutils/keyutils/keyutils-remove-m32-m64.patch new file mode 100644 index 0000000..a049fd2 --- /dev/null +++ b/meta-integrity/recipes-support/keyutils/keyutils/keyutils-remove-m32-m64.patch @@ -0,0 +1,19 @@ +Index: keyutils-1.5.5/Makefile +=================================================================== +--- keyutils-1.5.5.orig/Makefile 2011-12-20 11:05:10.000000000 +0200 ++++ keyutils-1.5.5/Makefile 2011-12-20 11:06:27.000000000 +0200 +@@ -58,12 +58,12 @@ + LNS := ln -sf + + ifeq ($(BUILDFOR),32-bit) +-CFLAGS += -m32 ++#CFLAGS += -m32 + LIBDIR := /usr/lib + USRLIBDIR := /usr/lib + else + ifeq ($(BUILDFOR),64-bit) +-CFLAGS += -m64 ++#CFLAGS += -m64 + LIBDIR := /usr/lib + USRLIBDIR := /usr/lib + endif diff --git a/meta-integrity/recipes-support/keyutils/keyutils/keyutils_fix_library_install.patch b/meta-integrity/recipes-support/keyutils/keyutils/keyutils_fix_library_install.patch new file mode 100644 index 0000000..adf0643 --- /dev/null +++ b/meta-integrity/recipes-support/keyutils/keyutils/keyutils_fix_library_install.patch @@ -0,0 +1,30 @@ +Index: keyutils-1.5.5/Makefile +=================================================================== +--- keyutils-1.5.5.orig/Makefile 2011-11-30 17:27:43.000000000 +0200 ++++ keyutils-1.5.5/Makefile 2011-12-21 16:05:53.000000000 +0200 +@@ -59,13 +59,13 @@ + + ifeq ($(BUILDFOR),32-bit) + CFLAGS += -m32 +-LIBDIR := /lib ++LIBDIR := /usr/lib + USRLIBDIR := /usr/lib + else + ifeq ($(BUILDFOR),64-bit) + CFLAGS += -m64 +-LIBDIR := /lib64 +-USRLIBDIR := /usr/lib64 ++LIBDIR := /usr/lib ++USRLIBDIR := /usr/lib + endif + endif + +@@ -152,7 +152,7 @@ + $(INSTALL) -D $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(LIBNAME) + $(LNS) $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SONAME) + mkdir -p $(DESTDIR)$(USRLIBDIR) +- $(LNS) $(LIBDIR)/$(SONAME) $(DESTDIR)$(USRLIBDIR)/$(DEVELLIB) ++ $(LNS) $(SONAME) $(DESTDIR)$(USRLIBDIR)/$(DEVELLIB) + $(INSTALL) -D keyctl $(DESTDIR)$(BINDIR)/keyctl + $(INSTALL) -D request-key $(DESTDIR)$(SBINDIR)/request-key + $(INSTALL) -D request-key-debug.sh $(DESTDIR)$(SHAREDIR)/request-key-debug.sh diff --git a/meta-integrity/recipes-support/keyutils/keyutils/keyutils_fix_x86-64_cflags.patch b/meta-integrity/recipes-support/keyutils/keyutils/keyutils_fix_x86-64_cflags.patch new file mode 100644 index 0000000..b0c2d92 --- /dev/null +++ b/meta-integrity/recipes-support/keyutils/keyutils/keyutils_fix_x86-64_cflags.patch @@ -0,0 +1,24 @@ +From d3b6b98984a28e782cb22dc6c7bd0ea9a0e74f15 Mon Sep 17 00:00:00 2001 +From: Lei Maohui +Date: Mon, 17 Aug 2015 15:53:02 +0900 +Subject: [PATCH] keyutils fix x86-64 cflags + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 82e1a0f..23aa466 100644 +--- a/Makefile ++++ b/Makefile +@@ -60,7 +60,7 @@ endif + ifeq ($(origin USRLIBDIR),undefined) + USRLIBDIR := $(patsubst /lib/%,/usr/lib/%,$(LIBDIR)) + endif +-BUILDFOR := $(shell file /usr/bin/make | sed -e 's!.*ELF \(32\|64\)-bit.*!\1!')-bit ++BUILDFOR := 64-bit + + LNS := ln -sf + +-- +1.8.4.2 diff --git a/meta-integrity/recipes-support/keyutils/keyutils/keyutils_fix_x86_cflags.patch b/meta-integrity/recipes-support/keyutils/keyutils/keyutils_fix_x86_cflags.patch new file mode 100644 index 0000000..f5d5f70 --- /dev/null +++ b/meta-integrity/recipes-support/keyutils/keyutils/keyutils_fix_x86_cflags.patch @@ -0,0 +1,24 @@ +From 3263917382af02e61f12f3774c32d3324a57059f Mon Sep 17 00:00:00 2001 +From: Lei Maohui +Date: Mon, 17 Aug 2015 11:48:22 +0900 +Subject: [PATCH] keyutils fix x86 cflags + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index e2d7e2d..f05bada 100644 +--- a/Makefile ++++ b/Makefile +@@ -60,7 +60,7 @@ endif + ifeq ($(origin USRLIBDIR),undefined) + USRLIBDIR := $(patsubst /lib/%,/usr/lib/%,$(LIBDIR)) + endif +-BUILDFOR := $(shell file /usr/bin/make | sed -e 's!.*ELF \(32\|64\)-bit.*!\1!')-bit ++BUILDFOR := 32-bit + + LNS := ln -sf + +-- +1.8.4.2 diff --git a/meta-integrity/recipes-support/keyutils/keyutils_1.5.9.bb b/meta-integrity/recipes-support/keyutils/keyutils_1.5.9.bb new file mode 100644 index 0000000..64e0365 --- /dev/null +++ b/meta-integrity/recipes-support/keyutils/keyutils_1.5.9.bb @@ -0,0 +1,48 @@ +SUMMARY = "Linux Key Management Utilities" +DESCRIPTION = "Keyutils is a set of utilities for managing the key retention \ +facility in the kernel, which can be used by filesystems, block devices and \ +more to gain and retain the authorization and encryption keys required to \ +perform secure operations." +SECTION = "base" +LICENSE = "GPLv2" +LIC_FILES_CHKSUM = "file://LICENCE.GPL;md5=5f6e72824f5da505c1f4a7197f004b45" + +PR = "r1" + +SRCREV = "9209a0c8fd63afc59f644e078b40cec531409c30" + +SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/keyutils.git;protocol=git \ + file://keyutils_fix_library_install.patch \ + file://keyutils-fix-the-cflags-for-all-of-targets.patch \ + " +SRC_URI_append_arm = " file://keyutils-remove-m32-m64.patch" +SRC_URI_append_aarch64 = " file://keyutils-remove-m32-m64.patch" +SRC_URI_append_mips = " file://keyutils-remove-m32-m64.patch" +SRC_URI_append_mips64 = " file://keyutils-remove-m32-m64.patch" +SRC_URI_append_x86 = " file://keyutils_fix_x86_cflags.patch" +SRC_URI_append_x86-64 = " file://keyutils_fix_x86-64_cflags.patch" +SRC_URI_append_powerpc = "file://keyutils-fix-powerpc-cflags.patch" + +S = "${WORKDIR}/git" + +inherit autotools-brokensep + +INSTALL_FLAGS = " \ + LIBDIR=${libdir} \ + USRLIBDIR=${libdir} \ + BINDIR=${bindir} \ + SBINDIR=${sbindir} \ + ETCDIR=${sysconfdir} \ + SHAREDIR=${datadir} \ + MANDIR=${mandir} \ + INCLUDEDIR=${includedir} \ + DESTDIR=${D} \ +" + +do_install() { + cd ${S} && oe_runmake ${INSTALL_FLAGS} install +} + +FILES_${PN} += "${datadir}/request-key-debug.sh" + +BBCLASSEXTEND = "native nativesdk" diff --git a/meta-signing-key/README.md b/meta-signing-key/README.md new file mode 100644 index 0000000..2b26599 --- /dev/null +++ b/meta-signing-key/README.md @@ -0,0 +1,73 @@ +### User Key Store +The sample keys, by default, are used by build system to sign bootloader, +kernel, IMA signature, RPM and so on. It is used for development and +demonstration. The user must know what te risk is to use the sample +keys in the product. + +The user key in a general sense is able to be used in the product with +contrary of the sample key. This document defines the definitions for +the uses of various keys. + +In addition, the scripts/create-user-key-store.sh provides a reference +to the creation of user key store, stored in such a layout: +``` +user-keys +├── ima_keys +│   ├── x509_ima.der +│   └── x509_ima.key +├── mok_sb_keys +│   ├── shim_cert.key +│   ├── shim_cert.pem +│   ├── vendor_cert.key +│   └── vendor_cert.pem +└── uefi_sb_keys + ├── DB.key + ├── KEK.key + ├── KEK.pem + ├── PK.key + └── PK.pem +``` +If the user plans to create the user keys by self, please consider to +define the necessary variables mentioned below in local.conf, or construct +a layer for the user key store. Eventually, the build system will copy the +user key store to `$project/tmp/deploy/images/*/user-keys/` for further use. + +The vital definitions include: + +- `SIGNING_MODEL := "user"` + Prohibit using the sample keys for signing the images. + +- `UEFI_SB_KEYS_DIR := ""` + Point to the location of user keys used for UEFI secure boot. If not defined, + the user keys for UEFI secure boot will be automatically generated. + +- `MOK_SB_KEYS_DIR := ""` + Point to the location of user keys used for MOK secure boot. Note that + MOK secure boot is on top of UEFI secure boot so creating the user keys + for MOK secure boot only will still introduce the security risk in your + product. If not defined, the user keys for MOK secure boot will be + automatically generated. + +- `IMA_KEYS_DIR := ""` + Point to the location of user keys used for IMA appraisal. If not defined, + the user keys for IMA appraisal will be automatically generated. + +- `USER_KEY_SHOW_VERBOSE = "1"` + Optional. Used to enable the verbose output for debugging purpose. + +To ensure a image signed by the untrustworthy sample key cannot be loaded, e.g, +preventing the shim signed by the user key from loading the grub signed by the +sample key, certain sample keys are added to the blacklists during the build, +meaning the following precautions: + +- Blacklist the sample DB and DBX in DBX database for UEFI secure boot. +- Blacklist the sample DB, shim_cert and vendor_cert in vendor_dbx database + for MOK secure boot. +- Cascade the default blacklist mentioned above and the user specified + blacklist if any. + +For the details about UEFI secure boot and MOK secure boot, please refer +to meta-efi-secure-boot/README.md. + +### Reference +[meta-efi-secure-boot](https://github.com/jiazhang0/meta-efi-secure-boot) diff --git a/meta-signing-key/classes/user-key-store.bbclass b/meta-signing-key/classes/user-key-store.bbclass new file mode 100644 index 0000000..da99064 --- /dev/null +++ b/meta-signing-key/classes/user-key-store.bbclass @@ -0,0 +1,440 @@ +DEPENDS_append_class-target += " \ + sbsigntool-native \ + libsign-native \ + openssl-native \ + efitools-native \ +" + +USER_KEY_SHOW_VERBOSE = "1" + +UEFI_SB = '${@bb.utils.contains("DISTRO_FEATURES", "efi-secure-boot", "1", "0", d)}' +MOK_SB = '${@bb.utils.contains("DISTRO_FEATURES", "efi-secure-boot", "1", "0", d)}' +IMA = '${@bb.utils.contains("DISTRO_FEATURES", "ima", "1", "0", d)}' +SYSTEM_TRUSTED = '1' + +def vprint(str, d): + if d.getVar('USER_KEY_SHOW_VERBOSE', True) == '1': + bb.note(str) + +def uks_signing_model(d): + return d.getVar('SIGNING_MODEL', True) + +def uks_system_trusted_keys_dir(d): + set_keys_dir('SYSTEM_TRUSTED', d) + return d.getVar('SYSTEM_TRUSTED_KEYS_DIR', True) + '/' + +def uks_ima_keys_dir(d): + set_keys_dir('IMA', d) + return d.getVar('IMA_KEYS_DIR', True) + '/' + +def uks_rpm_keys_dir(d): + # XXX: currently the user rpm pubkey is not supported. + if uks_signing_model(d) != 'sample': + return '' + + return d.getVar('RPM_KEYS_DIR', True) + '/' + +def sign_efi_image(key, cert, input, output, d): + import bb.process + + cmd = (' '.join((d.getVar('STAGING_BINDIR_NATIVE', True) + '/sbsign', + '--key', key, '--cert', cert, + '--output', output, input))) + vprint("Signing %s with the key %s ..." % (input, key), d) + vprint("Running: %s" % cmd, d) + try: + result, _ = bb.process.run(cmd) + except bb.process.ExecutionError: + raise bb.build.FuncFailed('ERROR: Unable to sign %s' % input) + +def edss_sign_efi_image(input, output, d): + # This function will be overloaded in pulsar-binary-release + pass + +def uefi_sb_keys_dir(d): + set_keys_dir('UEFI_SB', d) + return d.getVar('UEFI_SB_KEYS_DIR', True) + '/' + +def check_uefi_sb_user_keys(d): + dir = uefi_sb_keys_dir(d) + + for _ in ('PK', 'KEK', 'DB'): + if not os.path.exists(dir + _ + '.key'): + vprint("%s.key is unavailable" % _, d) + return False + + if not os.path.exists(dir + _ + '.pem'): + vprint("%s.pem is unavailable" % _, d) + return False + +def uefi_sb_sign(input, output, d): + if d.getVar('UEFI_SB', True) != '1': + return + + _ = uefi_sb_keys_dir(d) + sign_efi_image(_ + 'DB.key', _ + 'DB.pem', input, output, d) + +def mok_sb_keys_dir(d): + if d.getVar('MOK_SB', True) != '1': + return + + set_keys_dir('MOK_SB', d) + return d.getVar('MOK_SB_KEYS_DIR', True) + '/' + +def sb_sign(input, output, d): + if d.getVar('UEFI_SB', True) != '1': + return + + if uks_signing_model(d) in ('sample', 'user'): + # Deal with MOK_SB firstly, as MOK_SB implies UEFI_SB == 1. + # On this scenario, bootloader is verified by shim_cert.pem + if d.getVar('MOK_SB', True) == '1': + mok_sb_sign(input, output, d) + # UEFI_SB is defined, but MOK_SB is not defined + # On this scenario, shim is not used, and DB.pem is used to + # verify bootloader directly. + else: + uefi_sb_sign(input, output, d) + elif uks_signing_model(d) == 'edss': + edss_sign_efi_image(input, output, d) + +def check_mok_sb_user_keys(d): + dir = mok_sb_keys_dir(d) + + for _ in ('shim_cert', 'vendor_cert'): + if not os.path.exists(dir + _ + '.key'): + vprint("%s.key is unavailable" % _, d) + return False + + if not os.path.exists(dir + _ + '.pem'): + vprint("%s.pem is unavailable" % _, d) + return False + +def mok_sb_sign(input, output, d): + if d.getVar('MOK_SB', True) != '1': + return + + _ = mok_sb_keys_dir(d) + sign_efi_image(_ + 'vendor_cert.key', _ + 'vendor_cert.pem', input, output, d) + +def sel_sign(key, cert, input, d): + import bb.process + + cmd = (' '.join(('LD_LIBRARY_PATH=' + d.getVar('STAGING_LIBDIR_NATIVE', True) + + ':$LD_LIBRARY_PATH', d.getVar('STAGING_BINDIR_NATIVE', True) + '/selsign', + '--key', key, '--cert', cert, input))) + vprint("Signing %s with the key %s ..." % (input, key), d) + vprint("Running cmd: %s" % cmd, d) + try: + result, _ = bb.process.run(cmd) + except bb.process.ExecutionError: + raise bb.build.FuncFailed('ERROR: Unable to sign %s' % input) + +def uks_sel_sign(input, d): + if d.getVar('UEFI_SB', True) != '1': + return + + if d.getVar('MOK_SB', True) == '1': + _ = mok_sb_keys_dir(d) + key = _ + 'vendor_cert.key' + cert = _ + 'vendor_cert.pem' + else: + _ = uefi_sb_keys_dir(d) + key = _ + 'DB.key' + cert = _ + 'DB.pem' + + sel_sign(key, cert, input, d) + +def check_ima_user_keys(d): + dir = uks_ima_keys_dir(d) + + for _ in ('key', 'der'): + if not os.path.exists(dir + 'x509_ima.' + _): + vprint("%s.pem is unavailable" % _, d) + return False + +def check_system_trusted_keys(d): + dir = uks_system_trusted_keys_dir(d) + + _ = 'system_trusted_key' + if not os.path.exists(dir + _ + '.key'): + vprint("%s.key is unavailable" % _, d) + return False + + if not os.path.exists(dir + _ + '.pem'): + vprint("%s.pem is unavailable" % _, d) + return False + +# Convert the PEM to DER format. +def pem2der(input, output, d): + import bb.process + + cmd = (' '.join((d.getVar('STAGING_BINDIR_NATIVE', True) + '/openssl', + 'x509', '-inform', 'PEM', '-outform', 'DER', + '-in', input, '-out', output))) + try: + result, _ = bb.process.run(cmd) + except bb.process.ExecutionError: + raise bb.build.FuncFailed('ERROR: Unable to convert %s to %s' % (input, output)) + +# Convert the certificate (PEM formatted) to ESL. +__pem2esl() { + "${STAGING_BINDIR_NATIVE}/cert-to-efi-sig-list" \ + -g ${UEFI_SIG_OWNER_GUID} "$1" "$2" +} + +# Blacklist the sample DB, shim_cert, vendor_cert by default. +__create_default_mok_sb_blacklist() { + __pem2esl "${SAMPLE_MOK_SB_KEYS_DIR}/shim_cert.pem" \ + "${TMPDIR}/sample_shim_cert.esl" + + __pem2esl "${SAMPLE_MOK_SB_KEYS_DIR}/vendor_cert.pem" \ + "${TMPDIR}/sample_vendor_cert.esl" + + # Cascade the sample DB, shim_cert and vendor_cert to + # the default vendor_dbx. + cat "${TMPDIR}/sample_shim_cert.esl" \ + "${TMPDIR}/sample_vendor_cert.esl" >> "${TMPDIR}/blacklist.esl" +} + +__create_default_uefi_sb_blacklist() { + __pem2esl "${SAMPLE_UEFI_SB_KEYS_DIR}/DB.pem" \ + "${TMPDIR}/sample_DB.esl" + + cat "${TMPDIR}/sample_DB.esl" > "${TMPDIR}/blacklist.esl" +} + +# Cascade the default blacklist and user specified blacklist if any. +def __create_blacklist(d): + tmp_dir = d.getVar('TMPDIR', True) + + vprint('Preparing to create the default blacklist %s' % tmp_dir + '/blacklist.esl', d) + + bb.build.exec_func('__create_default_uefi_sb_blacklist', d) + if d.getVar('MOK_SB', True) == '1': + bb.build.exec_func('__create_default_mok_sb_blacklist', d) + + def __pem2esl_dir (dir): + if not os.path.isdir(dir): + return + + dst = open(tmp_dir + '/blacklist.esl', 'wb+') + + for _ in os.listdir(dir): + fn = os.path.join(dir, _) + if not os.path.isfile(fn): + continue + + cmd = (' '.join((d.getVar('STAGING_BINDIR_NATIVE', True) + '/cert-to-efi-sig-list', + '-g', d.getVar('UEFI_SIG_OWNER_GUID', True), fn, + tmp_dir + '/' + _ + '.esl'))) + try: + result, _ = bb.process.run(cmd) + except bb.process.ExecutionError: + vprint('Unable to convert %s' % fn) + continue + + with open(fn) as src: + shutil.copyfileobj(src, dst) + src.close() + + dst.close() + + # Cascade the user specified blacklists. + __pem2esl_dir(uefi_sb_keys_dir(d) + 'DBX') + + if d.getVar('MOK_SB', True) == '1': + __pem2esl_dir(mok_sb_keys_dir(d) + 'vendor_dbx') + +# To ensure a image signed by the sample key cannot be loaded by a image +# signed by the user key, e.g, preventing the shim signed by the user key +# from loading the grub signed by the sample key, certain sample keys are +# added to the blacklist. +def create_mok_vendor_dbx(d): + if d.getVar('MOK_SB', True) != '1' or d.getVar('SIGNING_MODEL', True) != 'user': + return None + + src = d.getVar('TMPDIR', True) + '/blacklist.esl' + import os + if os.path.exists(src): + os.remove(src) + + __create_blacklist(d) + + dst = d.getVar('WORKDIR', True) + '/vendor_dbx.esl' + import shutil + shutil.copyfile(src, dst) + + return dst + +def create_uefi_dbx(d): + if d.getVar('UEFI_SB', True) != '1' or d.getVar('SIGNING_MODEL', True) != 'user': + return None + + src = d.getVar('TMPDIR', True) + '/blacklist.esl' + import os + if os.path.exists(src): + os.remove(src) + + __create_blacklist(d) + + dst = d.getVar('WORKDIR', True) + '/DBX.esl' + import shutil + shutil.copyfile(src, dst) + + return dst + +create_uefi_sb_user_keys() { + local deploy_dir="${DEPLOY_DIR_IMAGE}/user-keys/uefi_sb_keys" + + install -d "$deploy_dir" + + # PK is self-signed. + "${STAGING_BINDIR_NATIVE}/openssl" req -new -x509 -newkey rsa:2048 \ + -sha256 -nodes -days 3650 \ + -subj "/CN=PK Certificate for $USER@`hostname`/" \ + -keyout "$deploy_dir/PK.key" \ + -out "$deploy_dir/PK.pem" + + # KEK is signed by PK. + "${STAGING_BINDIR_NATIVE}/openssl" req -new -newkey rsa:2048 \ + -sha256 -nodes \ + -subj "/CN=KEK Certificate for $USER@`hostname`" \ + -keyout "$deploy_dir/KEK.key" \ + -out "${TMPDIR}/KEK.csr" + + "${STAGING_BINDIR_NATIVE}/openssl" x509 -req -in "${TMPDIR}/KEK.csr" \ + -CA "$deploy_dir/PK.pem" -CAkey "$deploy_dir/PK.key" \ + -set_serial 1 -days 3650 -out "$deploy_dir/KEK.pem" + + # DB is signed by KEK. + "${STAGING_BINDIR_NATIVE}/openssl" req -new -newkey rsa:2048 \ + -sha256 -nodes \ + -subj "/CN=DB Certificate for $USER@`hostname`" \ + -keyout "$deploy_dir/DB.key" \ + -out "${TMPDIR}/DB.csr" + + "${STAGING_BINDIR_NATIVE}/openssl" x509 -req -in "${TMPDIR}/DB.csr" \ + -CA "$deploy_dir/KEK.pem" -CAkey "$deploy_dir/KEK.key" \ + -set_serial 1 -days 3650 -out "$deploy_dir/DB.pem" +} + +create_mok_sb_user_keys() { + local deploy_dir="${DEPLOY_DIR_IMAGE}/user-keys/mok_sb_keys" + + install -d "$deploy_dir" + + "${STAGING_BINDIR_NATIVE}/openssl" req -new -x509 -newkey rsa:2048 \ + -sha256 -nodes -days 3650 -subj "/CN=Shim Certificate for $USER@`hostname`/" \ + -keyout "$deploy_dir/shim_cert.key" -out "$deploy_dir/shim_cert.pem" + + "${STAGING_BINDIR_NATIVE}/openssl" req -new -x509 -newkey rsa:2048 \ + -sha256 -nodes -days 3650 -subj "/CN=Vendor Certificate for $USER@`hostname`/" \ + -keyout "$deploy_dir/vendor_cert.key" -out "$deploy_dir/vendor_cert.pem" \ +} + +create_ima_user_keys() { + local deploy_dir="${DEPLOY_DIR_IMAGE}/user-keys/ima_keys" + + install -d "$deploy_dir" + + "${STAGING_BINDIR_NATIVE}/openssl" genrsa -out "$deploy_dir/ima_privkey.pem" 2048 + + "${STAGING_BINDIR_NATIVE}/openssl" rsa -in "$deploy_dir/ima_privkey.pem" -pubout \ + -out "$deploy_dir/ima_pubkey.pem" +} + +def create_user_keys(name, d): + vprint('Creating the user keys for %s ...' % name, d) + bb.build.exec_func('create_' + name.lower() + '_user_keys', d) + +deploy_uefi_sb_keys() { + local deploy_dir="${DEPLOY_KEYS_DIR}/uefi_sb_keys" + + if [ x"${UEFI_SB_KEYS_DIR}" != x"$deploy_dir" ]; then + install -d "$deploy_dir" + + cp -af "${UEFI_SB_KEYS_DIR}"/* "$deploy_dir" + fi +} + +deploy_mok_sb_keys() { + local deploy_dir="${DEPLOY_KEYS_DIR}/mok_sb_keys" + + if [ x"${MOK_SB_KEYS_DIR}" != x"$deploy_dir" ]; then + install -d "$deploy_dir" + + cp -af "${MOK_SB_KEYS_DIR}"/* "$deploy_dir" + fi +} + +deploy_ima_keys() { + local deploy_dir="${DEPLOY_KEYS_DIR}/ima_keys" + + if [ x"${IMA_KEYS_DIR}" != x"$deploy_dir" ]; then + install -d "$deploy_dir" + + cp -af "${IMA_KEYS_DIR}"/* "$deploy_dir" + fi +} + +deploy_system_trusted_keys() { + local deploy_dir="${DEPLOY_KEYS_DIR}/system_trusted_keys" + + if [ x"${SYSTEM_TRUSTED_KEYS_DIR}" != x"$deploy_dir" ]; then + install -d "$deploy_dir" + + cp -af "${SYSTEM_TRUSTED_KEYS_DIR}"/* "$deploy_dir" + fi +} + +def deploy_keys(name, d): + d.setVar('DEPLOY_KEYS_DIR', d.getVar('DEPLOY_DIR_IMAGE', True) + '/' + \ + d.getVar('SIGNING_MODEL', True) + '-keys') + bb.build.exec_func('deploy_' + name.lower() + '_keys', d) + +def sanity_check_user_keys(name, may_exit, d): + if name == 'UEFI_SB': + _ = check_uefi_sb_user_keys(d) + elif name == 'MOK_SB': + _ = check_mok_sb_user_keys(d) + elif name == 'IMA': + _ = check_ima_user_keys(d) + elif name == 'SYSTEM_TRUSTED': + _ = check_system_trusted_keys(d) + else: + _ = False + may_exit = True + + if _ == False: + if may_exit: + raise bb.build.FuncFailed('ERROR: Unable to find user key for %s ...' % name) + + vprint('Failed to check the user keys for %s ...' % name, d) + + return _ + +# *_KEYS_DIR need to be updated whenever reading them. +def set_keys_dir(name, d): + if (d.getVar(name, True) != "1") or (d.getVar('SIGNING_MODEL', True) != "user"): + return + + if d.getVar(name + '_KEYS_DIR', True) == d.getVar('SAMPLE_' + name + '_KEYS_DIR', True): + d.setVar(name + '_KEYS_DIR', d.getVar('DEPLOY_DIR_IMAGE', True) + '/user-keys/' + name.lower() + '_keys') + +python () { + # XXX: the user key for rpm signing is necessary but not required. + for _ in ('UEFI_SB', 'MOK_SB', 'IMA', 'SYSTEM_TRUSTED'): + if d.getVar(_, True) != "1": + continue + + # Intend to use user key? + if not d.getVar('SIGNING_MODEL', True) in ("sample", "user"): + continue + + # Raise error if not specifying the location of the + # user keys. + sanity_check_user_keys(_, True, d) + + deploy_keys(_, d) +} diff --git a/meta-signing-key/conf/layer.conf b/meta-signing-key/conf/layer.conf new file mode 100644 index 0000000..ed83abd --- /dev/null +++ b/meta-signing-key/conf/layer.conf @@ -0,0 +1,40 @@ +# We have a conf and classes directory, add to BBPATH +BBPATH .= ":${LAYERDIR}" + +# We have recipes-* directories, add to BBFILES +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ + ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "signing-key" +BBFILE_PATTERN_signing-key = "^${LAYERDIR}/" +BBFILE_PRIORITY_signing-key = "10" + +SIGNING_MODEL ??= "sample" +SAMPLE_MOK_SB_KEYS_DIR = "${LAYERDIR}/files/mok_sb_keys" +SAMPLE_UEFI_SB_KEYS_DIR = "${LAYERDIR}/files/uefi_sb_keys" +SAMPLE_SYSTEM_TRUSTED_KEYS_DIR = "${LAYERDIR}/files/system_trusted_keys" +SAMPLE_IMA_KEYS_DIR = "${LAYERDIR}/files/ima_keys" +SAMPLE_RPM_KEYS_DIR = "${LAYERDIR}/files/rpm_keys" + +# Microsoft certificates +MSFT_DB_CERT = "${LAYERDIR}/files/uefi_sb_keys/ms-DB.pem" +MSFT_KEK_CERT = "${LAYERDIR}/files/uefi_sb_keys/ms-KEK.pem" + +# EV certificate +EV_CERT ??= "${LAYERDIR}/files/mok_sb_keys/wosign_ev_cert.pem" + +# By default the sample keys are used +MOK_SB_KEYS_DIR ??= "${SAMPLE_MOK_SB_KEYS_DIR}" +UEFI_SB_KEYS_DIR ??= "${SAMPLE_UEFI_SB_KEYS_DIR}" +SYSTEM_TRUSTED_KEYS_DIR ??= "${SAMPLE_SYSTEM_TRUSTED_KEYS_DIR}" +IMA_KEYS_DIR ??= "${SAMPLE_IMA_KEYS_DIR}" +RPM_KEYS_DIR ??= "${SAMPLE_RPM_KEYS_DIR}" + +# Define the identification of vendor +VENDOR_UUID = "1f7b9654-2107-4697-8f1c-0cbc38874588" + +# User configurable identification of signature owner +UEFI_SIG_OWNER_GUID ??= "${VENDOR_UUID}" + +SAMPLE_RPM_KEYNAME ??= "SecureCoreSample" +RPM_GPG_NAME ??= "${SAMPLE_RPM_KEYNAME}" diff --git a/meta-signing-key/files/ima_keys/x509_ima.der b/meta-signing-key/files/ima_keys/x509_ima.der new file mode 100644 index 0000000..ae0e098 Binary files /dev/null and b/meta-signing-key/files/ima_keys/x509_ima.der differ diff --git a/meta-signing-key/files/ima_keys/x509_ima.key b/meta-signing-key/files/ima_keys/x509_ima.key new file mode 100644 index 0000000..2f5bf14 --- /dev/null +++ b/meta-signing-key/files/ima_keys/x509_ima.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDYwkDsMkB4HUdT +uHsrmvzeuHbxrgdUa7WVjFL3cC7+KzJFnVgXP4U7BZQpeufbAjOMTJIPik0mDNMe +UtYLSVxHFyL17ccAfyZ2JckuV2pJrYr7O9MQCLtb/ttUO3ANPM9UqUG+KCsAAPPW +RYz7BjsWV1oj5ctMDtCjV58uhDYz6CQdqxbE2Zbe8dtRSlUBuyx3OxXV9p/LDg1t +4421dhhKpAM2t+OGaC0ZGquHtBfoAIx6nzufhHp7q561T9l/xtrq/kOKiDCawS38 +MTqlNjG7adN1rB0TK52bvMfMABZPyGeS0YhFrDExOVvynOqwcPS6yTKKcC7EsqM3 +3GO6Mk3tAgMBAAECggEBANO+p5dU27+6slPpsoD9barQvnkHTWe9tGw74UyQjYeD +gR+aPlSvm6H1qDABPX+nnd2fa0u9CfJyssY7m5b4+ikERAXEWxN0IolmDiq0AEOr +QUp9vYg7T3Pl+jJFwgdccRk+Itf0+1SMmaam2Lrb8lq3yHmq4LcS/eOjFABn7V8z +yXsxTQNH2K9YAoeLnsF66IprHR+dyj1TXpiTaLyS/DF/OmReLtHDd9zQUN2wWQuA +VHLDSKCueY0to7mMt/EGJ934hC51bydJYLifZPDKVleqB8NsHA30I5FF3RVlV2/a +/FSKSjuy3xntb5GtwhPMKXaFZJBJzfAnkQ3X+ogyfe0CgYEA9X6R/NymqpPuR2F7 +u8l3cxrZt82BDkXV2LX0FlvfzQPSxZL/ogKkAXeHxa/fCpdOx7yJwz3aTY1luWKR +WgDwVkMB4r7TTL3Cbvg6jFsm1mh4ImDMt9wN56ThIMdOaLimm8bvTijxum+x6RQA +Xq0iV1Zfxb0D3le3UwM+nZDD1JsCgYEA4gjhVa1VtS6uNNZ1cEXXaFN+HZ+N1Dzv +1HpxjeUFvxSo/YzYTwO2DnrGGjCdP1TW7K5YmkdNDZo4R9icRXOX4AuzGPitaPwV +MNWJ0oEyYHA1gfy3kg5rruGG/Jz7fZPLoKsgwmdOt06+nuDxAhiQKxMz+mvWcD1L +miTE9a9/3BcCgYBCaiWQpRkp2K+D/Cl/WjfImiEAisY5WEdMQ51vVxeq3TfuX6Bs +8g3wn6fJoZTTxq93ddhHS7p9dJ1qk/ICyXI7xBEEiN+dSVEKuHkOc7KEGus1Ub7Q +luXkH0UQmxrpVdstFZq0KHuNFp6pEdIvyuMZgbKTSll7k3tzJ9OOyRVRtQKBgQCr +PbMI56KQ+uZ7nSWngyHoJajb5G7cpbXEMWcp6qHp20sTm8qcQeGBIr5GRSI8Qpf5 +AzSY3P+hGH8e3xm0/BfJYtOyTWOCr8eWEZCya7KwoRHIgp7IBijKeo17f6p/vqJ7 +/Gl7HizibsO3Ng8gWV+PYqL0SxJQQf+urcCRqP2izQKBgQCA+I/VOmyfTiGGz8Q9 +dj4EnFw2CmPawNmqFuASvEcB4VqWMaYswiM3DOP31K4hDnuQUdS/BY8++OVesQ1t +VrNG+cbkVXpRDgsRdr9/S2ZBKBT1+gCzoHyfrbpV+1U9ZTkng8EBuO1clsc7crjz +Z5OTFNej0ldJ9zquU8ZjvRNV2Q== +-----END PRIVATE KEY----- diff --git a/meta-signing-key/files/mok_sb_keys/shim_cert.key b/meta-signing-key/files/mok_sb_keys/shim_cert.key new file mode 100644 index 0000000..77e8f4b --- /dev/null +++ b/meta-signing-key/files/mok_sb_keys/shim_cert.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC9o6BF9wUJxJRb +4eAbc6lyIaSkhAs/XTR9nIwIlSAgKLJs6btBdi76AmOHB5qa4nS609dZtJl5rz11 +S/RUEh3uUoqdlPATFSlyZehpER54u6AVS8ZaJpJhYHNztzMdwn8IOYiR3+dwveH8 +HeSGZYyOoujTNcmPx9MCcsSrvHYIRZBC6kFRosVVKgU5FZfskd3/ITv9BXaLSgzr +jeCTaawI7gzIvAnNwqR5xb7qIfwG5Gnity1Zy0wKEgiA3MhkdEn72Amn5hKn37gG +vQcqhyMvS7Dr/J4H9Fwx5+1//tufti7DWDRfJhIFcIA45z1GUPxFQdZ4RMlqyeoW +cC5TG84VAgMBAAECggEAZe786H6lw6FZyaW5C6h5DTMOR6v+S7nyzA4Iq1hVI1Qc +zDQ6hi5bg+Ei1GL+9IADFKVn3P0ZffH3DASeuU3frsnJXni/LtKyK56hdVBRW74m +hyvq22xeRF9Oz4VKwZVZKPeb9CUxR0WZoiYDP0Z4bfcdROJljJZxUqCUHGe53ilv +4BSl1sOF1l3ZWvAL60KPcsZ+DX7UGD79c+vdPe1fXfsPORZ6hT9wpedQej7av4q0 +4Hoe2Gp2bbDzyBJJF6S8iESlw8VuDVuDthpXyXahB9lD7uvVrrSguodAqQsB52WY +zrknbeCZOeRsATjCmSiC96wYhrnI/Uo+khUQZKIeJQKBgQD1wso5a0btnpqoTuux +a0I2THAL9+u0wipig1qi09FN7fKWShwFFJdjZKeIlh5KSnVtskCjBnnHQtnuotJZ +ND32kGu5+U5USqMsYilj33/rhxSxgBE+uu45Ys6PDAXpb0XCpIdGoiFiOt5OhBei +uVzUtr50ySW0P6UhfYjRVvqASwKBgQDFikJNp3zs9LBuNkqcZHi7K+p7qe9e4uvl +il418BAInosw7q/OOL5+qW8BcsRAiGIEePerBDhyt9xi2ee/PI2Wq3l27clX3NCE +zMzNVcBhgVGiKSwcZx45Mqx73Gz3buOxQ9exepio4klOLKBPda76QlpdRFXqWZQ/ +iVGA+VmvHwKBgG56O1gmjoMBOnsQx0lBc0lfgTsQHyhp5I3WiKcL21pR7ix7ci8i +e4+Vzu5KtaEl6bX/XKksnw/hUIDDNxYcswIlGBhJJ1ojF0k7c2nPLf0eA0Jr1NTD +SZYIgdyyRfITMGP4fEtXVPSIjCj1nn5rH30MDYAIcGef+MaeXSPmGsQTAoGBALfs +z2c2Nx75hPxZGIcdFTxQ23Zg9ztF1ZZXivh1mLgtxjO9SXudYeDVKUIT9Z6QXZME +frWArH5DqrNvaFOqsbpD1khhhkKEmrHLbjURTpp6qeNuql+Xs5BWGjsJNXv8h4wZ +Os9I8rLsXoynCGxzioQBG9oTMluNJHc0B+sqP9LJAoGBAKKSOPYMj8vyRAiOV8d2 +4sWG0Jq3bVENK0NmB8q5hV8+bzY9gh9MZC/NwZYkC//LwBSxo0RvjTyfVZ/2LuQT +A1KkhKT3/mp5YWWkCX9jBCCg+vpSBoTeLG7E+MNEyLKsTs/ib/1QguFoHmQoa6G+ +gwfYmI1EgW07xbXpw00AsDYN +-----END PRIVATE KEY----- diff --git a/meta-signing-key/files/mok_sb_keys/shim_cert.pem b/meta-signing-key/files/mok_sb_keys/shim_cert.pem new file mode 100644 index 0000000..f6c0e23 --- /dev/null +++ b/meta-signing-key/files/mok_sb_keys/shim_cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCTCCAfGgAwIBAgIJAMsUVTZv3GSuMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV +BAMMEFNoaW0gQ2VydGlmaWNhdGUwHhcNMTcwNTE4MDE1MTIyWhcNMjcwNTE2MDE1 +MTIyWjAbMRkwFwYDVQQDDBBTaGltIENlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAvaOgRfcFCcSUW+HgG3OpciGkpIQLP100fZyMCJUg +ICiybOm7QXYu+gJjhweamuJ0utPXWbSZea89dUv0VBId7lKKnZTwExUpcmXoaREe +eLugFUvGWiaSYWBzc7czHcJ/CDmIkd/ncL3h/B3khmWMjqLo0zXJj8fTAnLEq7x2 +CEWQQupBUaLFVSoFORWX7JHd/yE7/QV2i0oM643gk2msCO4MyLwJzcKkecW+6iH8 +BuRp4rctWctMChIIgNzIZHRJ+9gJp+YSp9+4Br0HKocjL0uw6/yeB/RcMeftf/7b +n7Yuw1g0XyYSBXCAOOc9RlD8RUHWeETJasnqFnAuUxvOFQIDAQABo1AwTjAdBgNV +HQ4EFgQULvuvKMYuVLG+sHbjUrMqnfxzLZwwHwYDVR0jBBgwFoAULvuvKMYuVLG+ +sHbjUrMqnfxzLZwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAGSHY +2iKYUO7Xnvn82lgcBdkI4s8ZmpqF8ETQox9C8Nz7Kz43vstAKacw2CRTZYKhElGA +GjCLaPGMRXZWLHaqaxkYR957lvmxKCv7geDk8bzLo5r4ppgjMwDGvcBMW8syNR9A +bIrIc2G1j5SmPbBOgwrnqxgoiV2IojO+B/OKUsbMNTqjmpOBHJmFspOLMxYbbuHa +JLB8QRvLVZf92+Kc0QKYlBbyPwtHuDCImtsWndo5zNbu0ZBmZdoc3c/fLBA2Umig +0OWmJqSY7B9zVbXCY/FjZRZMcqPVAFp0UjF1eQ7PKmtAXUuomXWt3ygmIYa1biQO +KEVY96hZLWVtfYKgMw== +-----END CERTIFICATE----- diff --git a/meta-signing-key/files/mok_sb_keys/vendor_cert.key b/meta-signing-key/files/mok_sb_keys/vendor_cert.key new file mode 100644 index 0000000..5187666 --- /dev/null +++ b/meta-signing-key/files/mok_sb_keys/vendor_cert.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCvQVgl3kSAZUkR +4jfomHUZqkngdoxStDCbsldW0itmGBLqFF3ZcH26igNvA4U/nk6a8oKbFJIhAlNK +5BONOXxBs5HO49PIe92bMKkiaYaabxpwNBX4Lz8b7SC1SoDHWeebEvkcoclqkOUK +GAf/ZP4gr2T0Hh3baxst0kO0nE6ftAQvWONfgZFmjtIANW1//4CQyC9v5+IK2Igp +2Aum6EIPmlv3Ui+7e0MGAk6oMvr2C43puKX0VVfOE+2o3ABYV+cFXToUHSjWznIm +EeFbY354dgah01e3iXvgigDeiINXvkODOAbkCuXvRbIfdQNd0f6u5B9R1E3j3q18 +jWqj9b9xAgMBAAECggEAM9Mq8efMcfuBpBw1VD7hQfmtZwcnb72BMkmGslHsK4Cq +9zWWmxo809DEOyvbV3jE3eUg4iMvIzvAzcCsV3LMX9FuKLQOiJa4bY/yNA7okvqP +4uZEKOQv0V5J8dJaSpk3eBAgQmtFWJIIaPe6Rbfjvl6fh+DwC1ac7uviwaIHTgo8 +XUQHghkNOIDJs9PaIXBXwaZMaiiMkQwqTFNxm+PVv/RgpwlXGUayS1VlUOMaswlg +NB3Lv6Idm9wdvJTExhnLwG1qRYslM+MVJlrXzUUhKE7TkkI4/iep8x6ZH31Tlf29 +8QRUIg1Xenn6mITaUWxxFHceTrtcF5STaORS4H0NkQKBgQDdYSsYz6Zcv2pUVWuf +WYrXHdRhb7qFpAHduK8Ip6+fYWMSG5d2pPJsWy4dC92h6xMqFV7YIwr+zE9pWhTL +pRkZePPgkh9pq+L3ezxEBIL4L7LuUEWhgiyMuOroep1+e1OHwrx9Z859ekvOwoEC +uce4hw2h2g3crIjBhCJbCBmxawKBgQDKqZwbUrcgV7NV7MMstpCmdrrD5xEA+I5W +2IqGae9T2VtDXfLcj4KA7/Hu2J2wQATDmuO2f0LhkSWqLu/EfLxExkDyHhvT/6RK +74YeKCft7vAPzB0tP1c578O1czVtVKibiYBG+9H43ZN5Vk2GgIylJXUgPLutyFBw +oI1bGoNdkwKBgEYEjZTzWDLNd9vkiH2F3JvdG2cV53CNRunRl8qs/qbyLltzzpv/ +34zV6efV8OtdZlpRGAZUTw33oMY5b4pZVW7xCnFkxfquGsMbfxwkMSg+LeGiEePb +QCvh8KpG3bk7WFgAB43CX1TgcUmbyyIJkFmUnYMrbGb3Sump2RPho/6xAoGAFWPD +Yyrewx4egnIjw2NdbwRW//gyVjzloQrny/oAVYQ6WqjeyiKnbn5ktYXNVt3a4t5F +LGzQHUiZhhXAHqffow6dqjA9VanEqFgRertYQ4eVdMVhSvZFeYrxyAPp3qkxxoDD +tjo71h1kxEi0k/6bWY7ThtyCHnxm6Qw4/yWUOdsCgYA8pAPJ43T2f0rRN5iYoJOz +xK94z7+xtfU8iM+he0KoOwBMvg+FPLyq4lHt44qqgk6pL13scbMcwabyg2bUimSq +jkt0LzOM+xB9AF1myK4hJv0/DCt++EC+xNupbTUR91F/TR11yurIO0aXWOsb58JN +490nl5BP5yqcfN+cZu6kFQ== +-----END PRIVATE KEY----- diff --git a/meta-signing-key/files/mok_sb_keys/vendor_cert.pem b/meta-signing-key/files/mok_sb_keys/vendor_cert.pem new file mode 100644 index 0000000..0200779 --- /dev/null +++ b/meta-signing-key/files/mok_sb_keys/vendor_cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDTCCAfWgAwIBAgIJAOxbh118EZp9MA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV +BAMMElZlbmRvciBDZXJ0aWZpY2F0ZTAeFw0xNzA1MTgwMTUxMjhaFw0yNzA1MTYw +MTUxMjhaMB0xGzAZBgNVBAMMElZlbmRvciBDZXJ0aWZpY2F0ZTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAK9BWCXeRIBlSRHiN+iYdRmqSeB2jFK0MJuy +V1bSK2YYEuoUXdlwfbqKA28DhT+eTprygpsUkiECU0rkE405fEGzkc7j08h73Zsw +qSJphppvGnA0FfgvPxvtILVKgMdZ55sS+RyhyWqQ5QoYB/9k/iCvZPQeHdtrGy3S +Q7ScTp+0BC9Y41+BkWaO0gA1bX//gJDIL2/n4grYiCnYC6boQg+aW/dSL7t7QwYC +Tqgy+vYLjem4pfRVV84T7ajcAFhX5wVdOhQdKNbOciYR4Vtjfnh2BqHTV7eJe+CK +AN6Ig1e+Q4M4BuQK5e9Fsh91A13R/q7kH1HUTePerXyNaqP1v3ECAwEAAaNQME4w +HQYDVR0OBBYEFCNxnVlIojl6HEQLYUZtzDi4aJaZMB8GA1UdIwQYMBaAFCNxnVlI +ojl6HEQLYUZtzDi4aJaZMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +ABozA60FTXVJ48baYLR8NNuEoT/oZPhWyd5rWfRVAAYNOLAb0Csu1NtzadmMap0j +3rVK4Rvv4Cf0cjrZsGWUXWJIY4Gp3qbgxk085WPFVq3fmKp5i10c4WR1x39cSeWF +QuzyQdt/+XFim1RsuLzAWUSaHuIYfZTQe42r0ar/xYKg0/7VdRNiqVYhWeWzYtKj +QZnHVSytF9xqHBUBl/f/EDejQjnsbYZ2tOSRe4f7SDyoUlBTEf/uFcquaGC7aLN5 +aejyVSlksmelP3fuUKugWGEIPMTzYOZMEfzYzdL2gdQtMFO7H4a36h0mWGCmnhcY +/datDO9Rtg9/wkuSG8DoVO8= +-----END CERTIFICATE----- diff --git a/meta-signing-key/files/mok_sb_keys/wosign_ev_cert.pem b/meta-signing-key/files/mok_sb_keys/wosign_ev_cert.pem new file mode 100644 index 0000000..a1fd851 --- /dev/null +++ b/meta-signing-key/files/mok_sb_keys/wosign_ev_cert.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGHDCCBQSgAwIBAgIQLbtRUsXGAdcMmhrabBAVBDANBgkqhkiG9w0BAQsFADBT +MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKDAmBgNV +BAMMH0NBIOayg+mAmiBFViDku6PnoIHnrb7lkI3or4HkuaYwHhcNMTUwOTMwMDgx +MzI4WhcNMTcxMTMwMDgxMzI4WjCCAaIxEzARBgsrBgEEAYI3PAIBAwwCQ04xGDAW +BgsrBgEEAYI3PAIBAgwHQmVpamluZzEYMBYGCysGAQQBgjc8AgEBDAdCZWlqaW5n +MR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjEYMBYGA1UEBRMPMTEwMDAw +NDUwMDM0MTI2MQswCQYDVQQGEwJDTjESMBAGA1UECAwJ5YyX5Lqs5biCMRIwEAYD +VQQHDAnljJfkuqzluIIxDzANBgNVBBEMBjEwMDEwMjFGMEQGA1UECQw95YyX5Lqs +5biC5pyd6Ziz5Yy65pyb5Lqs5Lit546v5Y2X6LevOeWPt+acm+S6rOWkp+WOpkLl +uqcxNeWxgjEzMDEGA1UECgwq6aOO5rKz6L2v5Lu256CU5Y+R77yI5YyX5Lqs77yJ +5pyJ6ZmQ5YWs5Y+4MSYwJAYJKoZIhvcNAQkBFhdqaWEuemhhbmdAd2luZHJpdmVy +LmNvbTEzMDEGA1UEAwwq6aOO5rKz6L2v5Lu256CU5Y+R77yI5YyX5Lqs77yJ5pyJ +6ZmQ5YWs5Y+4MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqvi3zCGT +4JfzNi3f8GsiAeDcnNxDtq3WUeC19YMOuDJe6i7E4EZhF29gBlsAVowmQUU+AWFA +RehMpBtIe3ZV55luI9SOU9cXd89hB3uYuK8fwU0tEnJrzoT0H0oXGLp8Zk6jIA6c +35s7PEgknj34nqo1zJ96xJYL3a8RCASqtdAGZsNoQRkaDIgAFMrPd6nqzOKTaiMg +hRKpF732AsXoVoknVzsbPVc+3WhRjxksfgdcyKmeggvnisyV8kBQGFsjlCLFLENF +6chSLLXXwLDGs7tI9AoeD8BjOcIdMX2wOadDYu4fSQq4fuoMW5v13feH5AyoRY35 +8ZaLPIzRB5lRVwIDAQABo4IBmTCCAZUwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM +MAoGCCsGAQUFBwMDMAkGA1UdEwQCMAAwHQYDVR0OBBYEFBVbHhL0x538UGntIcgw +HcJrYpySMB8GA1UdIwQYMBaAFBVBV5kt2EOSOn0PsmjUIQU3X2GjMGkGCCsGAQUF +BwEBBF0wWzAqBggrBgEFBQcwAYYeaHR0cDovL29jc3AyLndvc2lnbi5jbi9jYTIv +Y3M0MC0GCCsGAQUFBzAChiFodHRwOi8vYWlhMi53b3NpZ24uY24vY2EyLmNzNC5j +ZXIwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybHMyLndvc2lnbi5jbi9jYTIt +Y3M0LmNybDA1BgNVHREELjAsoCoGCCsGAQUFBwgDoB4wHAwaQ04tQmVpamluZy0x +MTAwMDA0NTAwMzQxMjYwTAYDVR0gBEUwQzALBgkrBgEEAYKbUQIwNAYFZ4EMAQMw +KzApBggrBgEFBQcCARYdaHR0cDovL3d3dy53b3NpZ24uY29tL3BvbGljeS8wDQYJ +KoZIhvcNAQELBQADggEBABo0pAyUNJIlRgkL2gMrUkLcOcq+7rr5UsOLiabLBg+M +P7K+AB6+/wSz2J0jqQiaWFl9cZasq3KgTPMo2zs3QH3Qgyd6/B30GgLLSvU5xXxU +1yRkJpZSIsSo5g7SoXA3FNQz63fN0BLF+WnKqCU11kKTAegCtK57lErx5vRlBNIH +/MJ7BI25T37w+ZERKa2Ugt0FukWvCWLLN2x2PwNaSY9ztmKdeLzTrtSy0X49jXVn +juzT0NhmYwJaKhYADgvMUP+pGn3Aj/Ie64vkEjFS+m7HpnL/vbmgffH6lwa6oXxL +01mxv7R9SkyuWq9gtdGJ+prDT0dPrHeXb3M6uQeE0x0= +-----END CERTIFICATE----- diff --git a/meta-signing-key/files/system_trusted_keys/system_trusted_key.key b/meta-signing-key/files/system_trusted_keys/system_trusted_key.key new file mode 100644 index 0000000..e63900a --- /dev/null +++ b/meta-signing-key/files/system_trusted_keys/system_trusted_key.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7aRl34d6FNFwN +/J9OuDG0vh7aOM4Acs46/4lDKzxeSGxfNCmxXWhEG6M3rDU6nfy09vqMhuLyLgMP +kMum47yFqufP4XRIb3aJYkjRYRUtzHo8CoZR80SoG778RlnvMekIE51yps/wR9/9 +AjY21PejZvXppkVXNtaiB4BP0tIu+a/5D8+jmiBus5ZtzkmFghUfTRuT+QdoQuC4 +gtqDBbz7WQTzryqESbIL9kkPLQFbOwETJwfur40hmkH+yDxlBURuod8A4Ne0jJt7 +gfFZBk3cgwlP/EOsJndlIAsnC8lgNfvji1lx9XOQGCj5X24wqRFstvkmpi/Ha7uJ +UEjn59KjAgMBAAECggEACGJnVUmxntv80lNe/TKYZrGqx7CK5tI8D7+m8G5awQ0U +bB31T44SQBnMb40wxHKU/7Oc+fR+6r7MPEIKGmlN4d0HifFYNnVmJDdVcqiZPfdL +8Ku33qq3g53aKYcsNttQxZ+7B4oW+3T7vGIA8usMOS8+CTn7GC/H4m/bebbA2IEX +cF9RfypsDoI1vHJ5w6S9g+Y+/DaiOWUoYHu5N6aNJbWmuGskpoRiPWrNY2t9mm9G +7HHLxz6/6g2OCbHH7zXXYdkMoF9sCiTrc9IaMttQ1hrPdVf/OVAK9QkO9+Si+iFv +hNTrfoSB3QQG0pbxlI/g2lNj15mr/gPiZpshAVXWIQKBgQD4wX4kIuVvF5+2TAoh +qURtyllNpjinHl1CGHoHLvJbhVksNnRAjmrtWNHUOEE5Z8ClRdouo1+RYVTMfMRl +10m+Il8fZxmeIKnKDfVSuN/qfNBDrHP24VBIfN2T6RDHXQG/VLjAKEmWiBaMsq3z +BtCOsAAXAPacCGyV7FOxnacobwKBgQDA3kUFZGx3SI99D++ea5BTG1jVvyjwLU/8 +bhU//+0+KffGvym1FCoj4z9z8m9b3WX7yFkNlzpnP/fq69p8AuzkRe/CnqnaGIRh +mnd9A43K+hj3OALWSEgD2vydk5TGv2nggdyy1QWWWZDRIjeUANsuYCRbxjVgFZ8R +I6naTjILDQKBgD0dJIVyQVXiwu1Bjzen41Tp4rjN/psoPZcwdkJviUFs6HSRSExX +8PMw4BQ4YeXdlJnGKI1Ou/r2o6O9f27Zzpc00JPhe4y6z5wBg+T34KM2WOBXbQIZ +ZuT4MGPXXbTtJ7G++cjT3QhrlMaqW0wav4BewxbjuLKq6yqGLiWz6s5nAoGBAJJt +LcG2SJMXR7kPTEDeMSinbn55Lz+JZ1yixwdb6mZzvmXp5GRR9txgP2BsAxefsznB +Fbs3wWN6MWLtxWa5Ydi9MBZ2F0Y5rufbOjRzakdcMXAf2ieNoP8sVvXbgeySjnOg +pEoxaJiJT2U3sTJwo/dFjtUOWp+kSqvcg6v2ChBRAoGBANVyxieM/eG9qkOjVRi+ +KxZTR0VuouL6elwGnZp3WzdCv1Q3AJSe3EhDI0eJzQJzF11Ultl0qGRyIQfjmWwj +vwN97ImedeD9L8K+9O4NCbBjpb68i1zQN8Nt/g6DJYOU7ygoUSZEVNfZFpt7Ni9O +n/XCHesfBriZhlv7n6gkmFZy +-----END PRIVATE KEY----- diff --git a/meta-signing-key/files/system_trusted_keys/system_trusted_key.pem b/meta-signing-key/files/system_trusted_keys/system_trusted_key.pem new file mode 100644 index 0000000..b730c97 --- /dev/null +++ b/meta-signing-key/files/system_trusted_keys/system_trusted_key.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHTCCAgWgAwIBAgIJALu1KPLxuKZTMA0GCSqGSIb3DQEBCwUAMCUxIzAhBgNV +BAMMGlN5c3RlbSBUcnVzdGVkIENlcnRpZmljYXRlMB4XDTE3MDYxMjAzNDU1OVoX +DTI3MDYxMDAzNDU1OVowJTEjMCEGA1UEAwwaU3lzdGVtIFRydXN0ZWQgQ2VydGlm +aWNhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7aRl34d6FNFwN +/J9OuDG0vh7aOM4Acs46/4lDKzxeSGxfNCmxXWhEG6M3rDU6nfy09vqMhuLyLgMP +kMum47yFqufP4XRIb3aJYkjRYRUtzHo8CoZR80SoG778RlnvMekIE51yps/wR9/9 +AjY21PejZvXppkVXNtaiB4BP0tIu+a/5D8+jmiBus5ZtzkmFghUfTRuT+QdoQuC4 +gtqDBbz7WQTzryqESbIL9kkPLQFbOwETJwfur40hmkH+yDxlBURuod8A4Ne0jJt7 +gfFZBk3cgwlP/EOsJndlIAsnC8lgNfvji1lx9XOQGCj5X24wqRFstvkmpi/Ha7uJ +UEjn59KjAgMBAAGjUDBOMB0GA1UdDgQWBBQ+XtkvfIaRyIHPnU2eTlTgClRKZjAf +BgNVHSMEGDAWgBQ+XtkvfIaRyIHPnU2eTlTgClRKZjAMBgNVHRMEBTADAQH/MA0G +CSqGSIb3DQEBCwUAA4IBAQBtUkdB4iPnBXvJY9O68canmzryOby/RE5PLQiMvCy4 +1zY9vH+VBZunAyijLkfP9jzuIIxBBU2QPVzAocOxoS2ie2lvfmbxRzX1d72mKdib +Oq7BJ8wyscbsSFhAb4UcTsfwYyzM2IIa5uh8nG7caiMPv93XVWdu7KWA4xM0BqIU +p1fV9+iUxdWrXDMQJPy+2qWdMTMo6hinyOx0CE7Hh9aTaH33C8/Tq6lDoSmVINog +83+/bcbGObfkkFukhu2uynnkt7txxBQqdBkYGpvUpvF2CxZPhjwVjDx9W4Gujfqm +QpBhMoXL0b1JhwsJE9EWsaLRXmP+RTKdt0F8PYOqOT0g +-----END CERTIFICATE----- diff --git a/meta-signing-key/files/uefi_sb_keys/DB.key b/meta-signing-key/files/uefi_sb_keys/DB.key new file mode 100644 index 0000000..499fba1 --- /dev/null +++ b/meta-signing-key/files/uefi_sb_keys/DB.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDCEEXcSeC4C6Zd +0fVak+6IooUG9OKF0iEJAc+5juFi7Ly7k5v0LnvMPleCASSYbiHc4wSRaIxcr60v +1pDyf1XQW+gqQ4AI4YyinAt0CLZxTiXsykeyqsBYq54ABFnEfj2I6ztBucGCjIJc +OY07IMZhCESN4IRNs13hUFHN0cMfSgE1fYboCDy6fbyaeOLhZwOOfiWp4A2f7a2O +NLa1v9iJmO3Ps7BVYqa7N5OrOJr2voekq3ziCWqNibPaIeyLPSQuWShotgoUFEeP +ejGp7fUC0dVkWPf4OefCftC4zmvRiyIeIzo4JXF8K5NaPeHakWgvRko+xD5A0sCy +AFq3JJaxAgMBAAECggEAWqDa30upJIpcQYhh+tEHHsw3L86BU1mUj+5GojO10ksY +wMjolhp3OiULHO2Ht6AHNG7YnUej9U0dpi+gNX9+BfZF8CbhzkP3N6GEP8Yp3bRP +RcwZu7i+ZyqOeRePDJKgDic83y7uzhbsckF2UVy3CG2iBlgJsXfIqgamjWYep6dJ +T1CgizWH4pJmruFw5MPGSsVnbo5OCNnJ51z1y8aozVfA9X+KTPPR5eG0DXb7ok+m +aC4s5OSHrEuYhKDKb5axdVMOqim2VM+8ghRKsqe8ccyIOS7/5Oahp5vzHFB4ZRcH +lV+Yew8Q1xdAAQ+0BVwQqvZv12QkZbCe75887mLBIQKBgQDuRQsN+/heoHE9SkG/ ++oSxKKPFWa5HSnolOFw3PjC7c0eD4RgcOHJbjII3EvvPrxDCjGV0yGhQeT6UGS2t +iDrN42E+r1atzOin3JtxX0sEorOtp4B/BXPHYswv//VJOnsIzlMOuqgbmPjPRM+o +CQgCg+e3U+xYBS8I15dnRv4ZPQKBgQDQgR4taPECuFm9e74Wyd7vDtlwDisUC770 +xzWM3E/9wRSV5sZFomZKiFPiQ6o9teTNLRzaa/TOywLMgnYV9MwG3VczNAqO7aM5 +K3YBhpazeFDtQaDOkR+0SZGmQc9XxkJuFvWCeWUUZKUDnexATOTNg0t6y8Lwo8Av +bZ8Y5ZsChQKBgQDLnkkyLDA2fZoILJs/upEG7Jn4HwmmduknQaDcvNLcfkmRVB1M +kJh5z/u/oQN8mjkSaPSS9mjezJ5D5bh5YcAPDs+dyC2k3UW9nfNg0XTEg15Vep1+ +72Pf8nhYVL6DU+ysu9WS8sSSwQlv53gmO4GS1LKCor+JAPUO8165rZucaQKBgH69 +jbdyq9XIc5xPhKvbh+zurNOFeUAVJ70o/m8iWGlaHYZFIk6fuegiWEMYeHpMf8kM +XBaVOtkc5BWmU9ti00Z08xWH08cvwmD0/yVMR3zObPrbQsFty8TOV3+lT0D+ndDH +mfL2ka/Ewd2h+ELZutcFsTLyewvFrgPmcagzoXb1AoGBAJcp2UyWWxwkn2TI5A95 +vhcH1lNLYG+KCZd4iR8Ynj6tRjNFFsZwiTaxuRdWI7PSm41GMnJVdrx7qlsPUnDb +1FYUVCB3aR93+TEgsVXrMSKGZ97f4MP8nJE5Ml2vFkKAXWHX5FtIxtS/Vd/LPAZa +JtMPM2x3OiIj3MeQfCK6q9tD +-----END PRIVATE KEY----- diff --git a/meta-signing-key/files/uefi_sb_keys/DB.pem b/meta-signing-key/files/uefi_sb_keys/DB.pem new file mode 100644 index 0000000..3517ddc --- /dev/null +++ b/meta-signing-key/files/uefi_sb_keys/DB.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpzCCAY8CAQEwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAwwPS0VLIENlcnRp +ZmljYXRlMB4XDTE3MDUxODAxNTM1N1oXDTI3MDUxNjAxNTM1N1owGTEXMBUGA1UE +AwwOREIgQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDCEEXcSeC4C6Zd0fVak+6IooUG9OKF0iEJAc+5juFi7Ly7k5v0LnvMPleCASSY +biHc4wSRaIxcr60v1pDyf1XQW+gqQ4AI4YyinAt0CLZxTiXsykeyqsBYq54ABFnE +fj2I6ztBucGCjIJcOY07IMZhCESN4IRNs13hUFHN0cMfSgE1fYboCDy6fbyaeOLh +ZwOOfiWp4A2f7a2ONLa1v9iJmO3Ps7BVYqa7N5OrOJr2voekq3ziCWqNibPaIeyL +PSQuWShotgoUFEePejGp7fUC0dVkWPf4OefCftC4zmvRiyIeIzo4JXF8K5NaPeHa +kWgvRko+xD5A0sCyAFq3JJaxAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAF24d314 +tT5RC22vouFCwfaqQgMlejs/nAg1NIZU/PL2r7HtXsB18K+vT3zdslvtzDlSnI7L +UTg+z7VBg3lCnH6wfJbnuLEUKJH3rdb5x83M+C6lPIc4lrxgjl+n1RrlaUOwUlBp +4rd8OcqLFmnuX36gfQ1Z5yYjfcAI/vStptrQjQ0kKmTRdqS2//0aKURkouvZeJOx +ddbdAyzANordmdWorqhSrHt+nj4pm5btlPGw5lSw1G0nm+3weYC7YNbs0SvRXomW +RwsEy5BpFbtGTH1pe9MBMpJXYL9lJ7Kd76DIFBEGy7wyR63ggKyEq7cd3o0cT6VR +yFY0sjzcS3llwfs= +-----END CERTIFICATE----- diff --git a/meta-signing-key/files/uefi_sb_keys/DBX/DBX.key b/meta-signing-key/files/uefi_sb_keys/DBX/DBX.key new file mode 100644 index 0000000..9001f0b --- /dev/null +++ b/meta-signing-key/files/uefi_sb_keys/DBX/DBX.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCcmAgStdSkmQrg +bxa2bNmIP5hWQcbMGB5XNuZ3AnlCR9jjU/OatFTaTonfgiRq1UyTgeVnshHEbciF +/Auz7QCJiKArM5qCWnnfQXj3DHOW0uznMmkFGkovpzYMDHxr6Gx6TZfYCyQt8R+N +u5mg/6hl9JWIXRM3fCTyGIp/zo3Yj9Q6JXLUuyRcHKFEpUSErrGtC0yizUNiTu38 +GPTxS5I8zvs6gFW9KKQa8X4d+f+1WuXXrEj4WqybGNdf4SzoPlkau8haXEDuAabE +/sQwj+bQNTvWDiMGEEY6l/WpFXEEdSnbBDOhoJnlWNaU8hbu7eRH/BE8WBVSs8Kw +TLlqJ+8XAgMBAAECggEAFjxYWR/MtBqvOrNLjFfkg75UCVuJuQ1rsYKwMxH82faN +y6nuG3ej3OPuG/jE5w6mswNs6c6VS0kzgiMKHmB3BRCLfdb0B7KFP7hyTtJLz4zf +6uxzkS/sfNvHhup2+HOmg69k8l6SoptsmZmb9QqYhPG4Egb1ZZmRPXdSo1dXOPrq +jeofrH6ZrVXxKmHhZYPZ0VE8jjVKaNzQuAb15KyEb/vYf6fUFKBDm/b1myOCy06c +WUs78nqgX3iW9P+4mL2CuuI6Dq1/Ja97qA+iepzF8SJte8HMVHfom8iI1dWrg5mr +UiTyGlVpwvwGdqnhXwXGLyFK0VUNLuB5RIFpaNvnoQKBgQDMjjp4OTvDdoSgcIY+ +VRlpCe9VuageHbyMUybQfrCBgubNnWZcU8VI+n8f8Rj6xfIZlVNBNROmdUqWWGPE +tkh2n5bsfSgV452uR48QelsH5TDcgTjJRtJry+9zOOgFPKrH6mNidl6PWiPPM7ga +skch43tbqog40IAb39tNRmFYOQKBgQDD+epGZ9Pv1gi4zP68CbI94F7exeHzhvH1 +sOCX/wBEtGW3crp4RXOiiL7o+9O06odz2PG6FbvqFe8WkQRSq5pZT0SiLhfIlJQ9 +Yql00a5kEJWahqUKydqEAcz4ON7DR5DAy+x128UXknm08YerjigvI4pk1zGPQ9IL +lKyt7yRhzwKBgA+EytLMJMiTeURixQx9kEvzwQCT8Tk3sFJFDLDMq79nmvMGefmP +MWxz9KkLtYVw9wkR1xsfV7pNM7dsRUVrPtwhB2YxqJTgi9no++WYIsfaj3ZrJ0+9 +28Dp2+S18IRVMe+wzJFvwYTGpejWV6VO2S6s/3LY4TTOPKngtdaK/F+hAoGASbPI +dpf/rbgZ6Z42wvMGlJy4MSHMezCp+JN/s8oUCMKralV8aVT9SwgQfECQ+v4k2N2i +8y/PTxbWpu786DZfQu07y554FVhDc96SCjv9UOanzMiMc0U8p96hfkytAlX8y3Ul +xaFUOyw8F1+qfUtmM2wzVP9VRSLlcLOGSZehYCMCgYA1saH1W+X4VFVUZMPBKirP +UldaTtUtyNfarAJwEq4rqLkhJfQoVsxjNcuUEqzpJXUihhny6XYvmb7QDv48P5Fn +83a2UEdasMfTN+zqvT273vn6zrSbNzJ1f/e1Z4T0h4ntwaQ/W0f197nWEWz6Mq+U +P9YtEC1cRbX6RPM5BereZA== +-----END PRIVATE KEY----- diff --git a/meta-signing-key/files/uefi_sb_keys/DBX/DBX.pem b/meta-signing-key/files/uefi_sb_keys/DBX/DBX.pem new file mode 100644 index 0000000..b62663e --- /dev/null +++ b/meta-signing-key/files/uefi_sb_keys/DBX/DBX.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBzCCAe+gAwIBAgIJAKJQcC+EJo1hMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV +BAMMD0RCWCBDZXJ0aWZpY2F0ZTAeFw0xNzA1MTgwMTU0MzNaFw0yNzA1MTYwMTU0 +MzNaMBoxGDAWBgNVBAMMD0RCWCBDZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAJyYCBK11KSZCuBvFrZs2Yg/mFZBxswYHlc25ncCeUJH +2ONT85q0VNpOid+CJGrVTJOB5WeyEcRtyIX8C7PtAImIoCszmoJaed9BePcMc5bS +7OcyaQUaSi+nNgwMfGvobHpNl9gLJC3xH427maD/qGX0lYhdEzd8JPIYin/OjdiP +1DolctS7JFwcoUSlRISusa0LTKLNQ2JO7fwY9PFLkjzO+zqAVb0opBrxfh35/7Va +5desSPharJsY11/hLOg+WRq7yFpcQO4BpsT+xDCP5tA1O9YOIwYQRjqX9akVcQR1 +KdsEM6GgmeVY1pTyFu7t5Ef8ETxYFVKzwrBMuWon7xcCAwEAAaNQME4wHQYDVR0O +BBYEFOtvhQzmM47hXRy34LGHwxCepaMMMB8GA1UdIwQYMBaAFOtvhQzmM47hXRy3 +4LGHwxCepaMMMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAGcaSshH +NmzvPVRPUsQPXnnnAfFT2/SUACChxQvV6Cdv2ZTsnfSeq5Qic1XBI4w0qGfevv69 +pE6tMjg3t9H3+WFUsGugjkRB2i6oyDI3d7okFXRKPYP0Zagm64HAGG+p76j694Rj +cnKL85wXmkY1X5sE/pxCBOiAsLH8yhC8jJCUCRKPxpLC3iD6bOLO57DNSYaucIke +BNqf2NQaQFTEeE8ELqArPVpi9iTRQotfmpoUrt/zt0l7kKe38qOZD1WwwoFJB7eY +OpPS/8sxxx5ym8YKd9I5HF2MwzDHNZZNOIRXPFkVVgDLTWsrQjHI2ppxXcZHVPhp +3FQb+KhWL0nkb5M= +-----END CERTIFICATE----- diff --git a/meta-signing-key/files/uefi_sb_keys/KEK.key b/meta-signing-key/files/uefi_sb_keys/KEK.key new file mode 100644 index 0000000..3759464 --- /dev/null +++ b/meta-signing-key/files/uefi_sb_keys/KEK.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDTGE3U05B+weQu +7XQ4aX4y99pn/kjs4+Kq6BYOX2+gaaisxW7ZO4okeXwRGD0h/LGjN6hfqXhTl0Il +4ztx/ofIuB4nklVhTolsFrqvILBleoNo/gSK3oUXJvqbrfHNLWBLaaIpznQk+Rmf +5mqUJ2EdXuakF5jfNFLICRMi3Mt8+SQfSbZf1EVb16h79GvyHd/Lx3rKU0cAmGJK +2Idg3lFdfZ4IuX96PTf1oH/MpYvgJnJU7+OpfgT1Oeq7d/lXAm/wevERfkQ77kyb +cYQPg+upfQKXprM3oq+HAqcbwZg3F2q++QeO62Z8DtYDpzWdCOz142bSHojUnzaV +1ZdjNz9LAgMBAAECggEBAKuk4nyAfsijDdCeodbQ6J227W+L025TqlZ/mpebQF/2 +KgI6E3UttZkM8zXPOL4vA54MvqryWPXXUyENkKOTbINoOpTApw4VVyZ9oNSPxv7s +zHeNvNHSN/PobPQzTx8fm2IWhZZq2gPKTOy45caL8qp4JSAeU96CZCFlR5scX5XA +YQHOEctofv4r+TZRWoNFKylUZ9y+bPc8VXPi4dEdbnv/IkT3TOJE+vthsYLOh0eN +ankKDtBviK7/0PNXCQ4mthss67e+SquSd+JBGIgcTL231s+18LkyiIWETuO07fip +dpk1lBg2QybjhaarIRhvdD4vuwTKnUqlJthBcqUCgbECgYEA9ARigUFQIHsQxLLT +TCkmSFeEcCqsvp91g7xcUnasDAnk4Ju6gwZYu3r+nKozXClLUUJkwMjdePYSSfj7 +LVnWskE0jjw1uWGIwcivexBo7G1JqJiuj+7MOhYxagUnfEpYU/Zp5auBGn9+/531 +0L1NWFz7c0usyEYrLK/xHVPF4AMCgYEA3XYLTUQ+z5brpK8OLs3atnYm5NvVZGxV +N3o5omcUbO70brd2/Zkei81R/NzCVfaaBAe1O/2H9Z6aC3+3g57l/s7ilWgJJGE5 +kHgj7B5jzpqwAzuz20lSWuc3pfCvWCKcjUVMevXO2PMNMLdY9CLMdCD6s0Tt4w/y +lUY5vkyBdRkCgYEAnn7anKoXqYFF+v1MUYPI4eQ2mcSeP5LDebW3IbkDNy6WA24j +T0eoCt5w0sGaappH2ZgOaUoO0KrEZlfajjJ0SYQg5uIk4yx+75+ym3SlMiwqU+AY +QlURQgl4Pyzp4MlJZf//+LXVPajijJXFPLg4rNR4XwMgT1WEZZpCOpJXTJECgYEA +oxGltspWucK2VvgzqFEaCBqt/vzEf4KpqQUN5UCjsKavQ8tCCfAyptyTz266hlPk +Cq2mTLsd3sVfRrJPbdKWJm8uNrd5a9lPasqcIOQrt9j9XBQdFo5B3v+8YSr94hby +Ua/CZhQTsHofr0yCapopFCWolFJgHD8E79fa8v4goRkCgYEAnxS6k4NfnzjQholq +Sbb19bJUdUW6Go01mAqZ66DBQYV4run6elB7sGLkwgyo3GrriNFK1miIzS+J9jXb +j79yhiDjMUPj0L6dzHVdeqgienFbOhRY4s5ArpPgNGPO77A4H/02qe4vbcCY1OK3 +FeovKglic0lRsV0YObbujiatznk= +-----END PRIVATE KEY----- diff --git a/meta-signing-key/files/uefi_sb_keys/KEK.pem b/meta-signing-key/files/uefi_sb_keys/KEK.pem new file mode 100644 index 0000000..c27b01a --- /dev/null +++ b/meta-signing-key/files/uefi_sb_keys/KEK.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpzCCAY8CAQEwDQYJKoZIhvcNAQELBQAwGTEXMBUGA1UEAwwOUEsgQ2VydGlm +aWNhdGUwHhcNMTcwNTE4MDE1MzQ4WhcNMjcwNTE2MDE1MzQ4WjAaMRgwFgYDVQQD +DA9LRUsgQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDTGE3U05B+weQu7XQ4aX4y99pn/kjs4+Kq6BYOX2+gaaisxW7ZO4okeXwRGD0h +/LGjN6hfqXhTl0Il4ztx/ofIuB4nklVhTolsFrqvILBleoNo/gSK3oUXJvqbrfHN +LWBLaaIpznQk+Rmf5mqUJ2EdXuakF5jfNFLICRMi3Mt8+SQfSbZf1EVb16h79Gvy +Hd/Lx3rKU0cAmGJK2Idg3lFdfZ4IuX96PTf1oH/MpYvgJnJU7+OpfgT1Oeq7d/lX +Am/wevERfkQ77kybcYQPg+upfQKXprM3oq+HAqcbwZg3F2q++QeO62Z8DtYDpzWd +COz142bSHojUnzaV1ZdjNz9LAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAGDBZKxx +yMoEi5tkX11o0SYGOZu/ESsb5Py1PB7owbDBZpcjXqr6PdC3MKcSz1TkLRVGNiAn +SOVeToT4GU662fhbqI1M+n/gIrcxSjs/U2ijbGyJZH9wRJFxuHZAaow3x6kPapFA +sF3EWr6obp3PQaLmOvRcJXgvCy7Zq31pwoCdSLuSRaRbtb7ltMgf7OqYb47QKrdg +U6opykf3h8rK9iopuuj1tfBzWqG0FYlctkHg9W4ehOy3da1kwoeFIikuACYZrqMN +L8ABjseUtQut/yrTEcMRm0t/6Z13599xM6eORdGgv/zCE0OxtMiJoRceE9cBHABa +y2K1leYM/Bz9ciY= +-----END CERTIFICATE----- diff --git a/meta-signing-key/files/uefi_sb_keys/PK.key b/meta-signing-key/files/uefi_sb_keys/PK.key new file mode 100644 index 0000000..80288a3 --- /dev/null +++ b/meta-signing-key/files/uefi_sb_keys/PK.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC3/v2TZgaYSy+s +mDAkkfRgdsjasqx8q5jPUqjlxci35s8Mcj0uKnNSfoF3lKZnk7nN4mQshEEyFrP0 +dZt0NZhxsNBl7kutFDa88ETkwJIEhGSFzNFvw4bCAa+Ut9M+3coxt5mqFz06T1vU +TQdY4BN7tZwEmXc2RftrNxEIb+y+P0XgXC9mfLLi0Au0fSUbOMQU/yYyLMrTuwvL +7+i8kxuK8iItoezge6P7RBmt56gVZT9QawY4urNcdxXHpLfBLmF9XmoOpr77/l/g +KXWOQdX3XNym31xnlRucbmAziUnQd+ok8YKBGhe4O3Y8jrUY9s8YGDbdxfHxmjTP +4fyGHD6bAgMBAAECggEAZFzurIwmZMP+SULqX8hNaKDihoiXlZl0TQJlpo/wIIAB +yGQ4AwqcxQ7ESBoJes4Vt7wZsD6j4VKI7nuIRCdH9BviUPdeyBYSlZTpv21bOKOO +wX0rcK9Svlh1EcYDsHMCa4Qeia0LdNb83Bz4OP5hIkW5yLh9Ullx/tWWsOd8V3j2 +f7nrLQLmfxdcDMT/nnkgQH1IMDwaaVuKxnul0PY1UV6keiBcKW702WxTOx/ZrF09 +gbqEdu6nifQJAZ2+luC7EOw2QD4PHmSVPZrEwM5dcMn0Lg9yS6Ep7Nd4vRKPc1iB +IqePP16ufZ4doj79i3Cd7H7RY2dQda6yoihb2hrsIQKBgQDqzjfZ3QMjQ751WyyU +N7w929GOkV1liIOqCpgNx9lcmIE45JJzobBblOKwaTpctX3jIswnByfPgl5wCM5R +89P1yFXG56JeuEdhNGKTYw76kRoXkwP0vMXkrd6Biq/CD/uLnl8BqhDSlIngK0Q3 +2stDpbS8TqtdxeNF3prJTDKxhwKBgQDImrCAdG9AmrONUyYGgjPrIML4jUWuL01a +AbDpC3+F46kZdfDr9JwlP/WO6WRb0LcjH/TvKsqO4vqxOGMSU4fzyZsiMIZma4E7 +GKCuz7aFldDXhlqHWuwp2vzLlABP0sL5wjwYsdAGLPhm4v8KN0eiuirkNt9QN8Bi +SiRaexafTQKBgDRczpm4LtXzaorTTUq0bzdASShJBJH68pm+CRCxq6h5nf+pAXvl +5+VUe4UpwkkgdDVt8icV8mvVP+guHoyqGm+qQG6+AziqUci8nOsPYSzBpRbywyQV +4O/RUliDLBTT6Z3GMJu3aE79rw2duHXYRhIM5xRDWvXrhnZzYQNZCckLAoGAGwTS +vwpvrZjolCFd3sSMr5+jAw0sFHDkjznpFQpqa6MlNHuxLmas3UuHDG+dB8zNzdpR +CCGQVLx3nYUFuwMrLYe68Fju0T6rkkUX51OstsNd9Jlw+ggiBOUs5VKS1C2D+1XQ ++FaCuUI3Vsw+I6cca+t9OW22mDxaGiL4UIOBoYUCgYA58IXBablXY8Va1o9b+RqJ +sKMK/22hpunTbbfjDO2z6v8VR/ScLLGkeXnTquPoU5nVgh38Y61etAVLLBf0dw0r +iDH9OQ4g+el6+mnRa9IqzznDhNF6XERkJ/pQC0EIz4lMejNl4vnDsxb25RVejY7f +Ez0iGfy8zAgiaAhZM45JUQ== +-----END PRIVATE KEY----- diff --git a/meta-signing-key/files/uefi_sb_keys/PK.pem b/meta-signing-key/files/uefi_sb_keys/PK.pem new file mode 100644 index 0000000..db659a5 --- /dev/null +++ b/meta-signing-key/files/uefi_sb_keys/PK.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBTCCAe2gAwIBAgIJANpjqQyCduqsMA0GCSqGSIb3DQEBCwUAMBkxFzAVBgNV +BAMMDlBLIENlcnRpZmljYXRlMB4XDTE3MDUxODAxNTMzOVoXDTI3MDUxNjAxNTMz +OVowGTEXMBUGA1UEAwwOUEsgQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC3/v2TZgaYSy+smDAkkfRgdsjasqx8q5jPUqjlxci35s8M +cj0uKnNSfoF3lKZnk7nN4mQshEEyFrP0dZt0NZhxsNBl7kutFDa88ETkwJIEhGSF +zNFvw4bCAa+Ut9M+3coxt5mqFz06T1vUTQdY4BN7tZwEmXc2RftrNxEIb+y+P0Xg +XC9mfLLi0Au0fSUbOMQU/yYyLMrTuwvL7+i8kxuK8iItoezge6P7RBmt56gVZT9Q +awY4urNcdxXHpLfBLmF9XmoOpr77/l/gKXWOQdX3XNym31xnlRucbmAziUnQd+ok +8YKBGhe4O3Y8jrUY9s8YGDbdxfHxmjTP4fyGHD6bAgMBAAGjUDBOMB0GA1UdDgQW +BBRAjBvvXvZI0+DrDAhBXG9PgvzocDAfBgNVHSMEGDAWgBRAjBvvXvZI0+DrDAhB +XG9PgvzocDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCUiNwz1BGg +KR82WfqIMB95uGOSo2aw91NM8lcBZgie/tH4BCjxGaJsoJJUs5+2Xj/COZRL6Z4K +Jz6M3UdL5Gpdidx5wzHmhP0tlaD/Qq0e20Jlx2VBDniBdXP3EOmdxgPnjQIZxufB +Vtft2woSYeu+1oz6Ahss8fiMlGYEV/EhCnd9Zxo9ErwiW8Jr49Ks9JcqvKj48uNJ +JKyFxZkmIcWhhCIIoXVsfUEh/mKs/vuy0NIF3gStuwg2tJSIc58ut/bUtFKD5zoT +AFglbbWY1fDa5IPtFPGKfMXnIXiEl+GXebuX+s36RLUffrnltfgVmqjLSwhTqymD +8mY8m0zY7h5V +-----END CERTIFICATE----- diff --git a/meta-signing-key/files/uefi_sb_keys/ms-DB.pem b/meta-signing-key/files/uefi_sb_keys/ms-DB.pem new file mode 100644 index 0000000..d7c29ef --- /dev/null +++ b/meta-signing-key/files/uefi_sb_keys/ms-DB.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGEDCCA/igAwIBAgIKYQjTxAAAAAAABDANBgkqhkiG9w0BAQsFADCBkTELMAkG +A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx +HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjE7MDkGA1UEAxMyTWljcm9z +b2Z0IENvcnBvcmF0aW9uIFRoaXJkIFBhcnR5IE1hcmtldHBsYWNlIFJvb3QwHhcN +MTEwNjI3MjEyMjQ1WhcNMjYwNjI3MjEzMjQ1WjCBgTELMAkGA1UEBhMCVVMxEzAR +BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p +Y3Jvc29mdCBDb3Jwb3JhdGlvbjErMCkGA1UEAxMiTWljcm9zb2Z0IENvcnBvcmF0 +aW9uIFVFRkkgQ0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKUIbEzHRQlqSwykwId/BnUMQwFUZOAWfwftkn0LsnO/DArGSkVhoMUWLZbT9Sug ++01Jm0GAkDy5VP3mvNGdxKQYin9BilxZg2gyu4xHye5xvCFPmop8/0Q/jY8ysiZI +rnW17slMHkoZfuSCmh14d00MsL32D9MW07z6K6VROF31+7rbeALb/+wKG5bVg7gZ +E+m2wHtAe+EfKCfJ+u9WXhzmfpR+wPBEsnk55dqyYotNvzhw4mgkFMkzpAg31Vhp +XtN87cEEUwjnTrAqh2MIYW9jFVnqsit51wxhZ4pb/V6th3+6hmdPcVgSIgQiIs6L +71RxAM5QNVh2lQjuarGiAdUCAwEAAaOCAXYwggFyMBIGCSsGAQQBgjcVAQQFAgMB +AAEwIwYJKwYBBAGCNxUCBBYEFPjBa7d/d1NK8yU3HU6hJnsPIHCAMB0GA1UdDgQW +BBQTrb9DCb2CcJyM1U8xbtUimIob1DAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMA +QTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRFZlJD +4X5YEb/WTp4jVQg7OiJqqDBcBgNVHR8EVTBTMFGgT6BNhktodHRwOi8vY3JsLm1p +Y3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNDb3JUaGlQYXJNYXJSb29f +MjAxMC0xMC0wNS5jcmwwYAYIKwYBBQUHAQEEVDBSMFAGCCsGAQUFBzAChkRodHRw +Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY0NvclRoaVBhck1hclJv +b18yMDEwLTEwLTA1LmNydDANBgkqhkiG9w0BAQsFAAOCAgEANQhC/zDMzvd2DK0Q +aFg1KUYydid87xJBJ0IbSqptgThIWRNV8+lYNKYWC4KqXa2C2oCDQQaPtB3yA7nz +Gl0b8VCQ+bNVhEIoHCC9sq5RFMXArJeVIRyQ2w/8d56Vc5GIyr29UrkFUA3fV56g +Ye0N5W0l2UAPF0DIzqNKwk2vmhIdCFSPvce8uSs9SSsfMvxqIWlPm8h+QjT8NgYX +i48gQMCzmiV1J83JA6P2XdHnNlR6uVC10xLRB7+7dN/cHo+A1e0Y9C8UFmsv3maM +sCPlx4TY7erBM4KtVksYLfFolQfNz/By8K673YaFmCwhTDMr8A9K8GiHtZJVMnWh +aoJqPKMlEaTtrdcErsvYQFmghNGVTGKRIhp0HYw9Rw5EpuSwmzQ1sfq2U6gsgeyk +BXHInbi66BtEZuRHVA6OVn+znxaYsobQaD6QI7UvXo9QhY3GjYJfQaH0Lg3gmdJs +deS2abUhhvoH0fbiTdHarSx3Ux4lMjfHbFJylYaw8TVhahn1sjuBUFamMi3+oon5 +QoYnGFWhgspam/gwmFQUpkeWJS/IJuRBlBpcAj/lluOFWzw+P7tHFnJV4iUisdl7 +5wMGKqP3HpBGwwAN1hmJ4w41J2IDcRWm79AnoKBZN2D4OJS44Hhw+LpMhoeU9uCu +AkXuZcK2o35pFnUHkpv1prxZg1g= +-----END CERTIFICATE----- diff --git a/meta-signing-key/files/uefi_sb_keys/ms-KEK.pem b/meta-signing-key/files/uefi_sb_keys/ms-KEK.pem new file mode 100644 index 0000000..37c814a --- /dev/null +++ b/meta-signing-key/files/uefi_sb_keys/ms-KEK.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF6DCCA9CgAwIBAgIKYQrRiAAAAAAAAzANBgkqhkiG9w0BAQsFADCBkTELMAkG +A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx +HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjE7MDkGA1UEAxMyTWljcm9z +b2Z0IENvcnBvcmF0aW9uIFRoaXJkIFBhcnR5IE1hcmtldHBsYWNlIFJvb3QwHhcN +MTEwNjI0MjA0MTI5WhcNMjYwNjI0MjA1MTI5WjCBgDELMAkGA1UEBhMCVVMxEzAR +BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p +Y3Jvc29mdCBDb3Jwb3JhdGlvbjEqMCgGA1UEAxMhTWljcm9zb2Z0IENvcnBvcmF0 +aW9uIEtFSyBDQSAyMDExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +xOi1ir+tVyawJsPq5/tXekQCXQcN2krldCrmsA/sbevsf7njWmMyfBEXTw7jC6c4 +FZOOxvXghLGamyzn9beR1gnh4sAEqKwwHN9I8wZQmmSnUX/IhU+PIIbO/i/hn/+C +wO3pzc70U2piOgtDueIl/f4F+dTEFKsR4iOJjXC3pB1N7K7lnPoWwtfBy9ToxC/l +me4kiwPsjfKL6sNK+0MREgt+tUeSbNzmBInr9TME6xABKnHl+YMTPP8lCS9odkb/ +uk++3K1xKliq+w7SeT3km2U7zCkqn/xyWaLrrpLv9jUTgMYC7ORfzJ12ze9jksGv +eUCEeYd/41Ko6J17B2mPFQIDAQABo4IBTzCCAUswEAYJKwYBBAGCNxUBBAMCAQAw +HQYDVR0OBBYEFGL8Q82gPqTLZxLSW9lVrHvMtopfMBkGCSsGAQQBgjcUAgQMHgoA +UwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQY +MBaAFEVmUkPhflgRv9ZOniNVCDs6ImqoMFwGA1UdHwRVMFMwUaBPoE2GS2h0dHA6 +Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY0NvclRoaVBh +ck1hclJvb18yMDEwLTEwLTA1LmNybDBgBggrBgEFBQcBAQRUMFIwUAYIKwYBBQUH +MAKGRGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljQ29yVGhp +UGFyTWFyUm9vXzIwMTAtMTAtMDUuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQDUhIj1 +FJQYAsoqPPsqkhwM16DR8ehSZqjuorV1epAAqi2kdlrqebe5N2pRexBk9uFk8gJn +vveoG3i9us6IWGQM1lfIGaNfBdbbxtBpzkhLMrfrXdIw9cD1uLp4B6Mr/pvbNFaE +7ILKrkElcJxr6f6QD9eWH+XnlB+yKgyNS/8oKRB799d8pdF2uQXIee0PkJKcwv7f +b35sD3vUwUXdNFGWOQ/lXlbYGAWW9AemQrOgd/0IGfJxVsyfhiOkh8um/Vh+1Gln +FZF+gfJ/E+UNi4o8h4Tr4869Q+WtLYSTjmorWnxE+lKqgcgtHLvgUt8AEfiaPcFg +sOEztaOI0WUZChrnrHykwYKHTjixLw3FFIdv/Y0uvDm25+bD4OTNJ4TvlELvKYuQ +RkE7gRtn2PlDWWXLDbz9AJJP9HU7p6kk/FBBQHngLU8Kaid2blLtlml7rw/3hwXQ +RcKtUxSBH/swBKo3NmHaSmkbNNho7dYCz2yUDNPPbCJ5rbHwvAOiRmCpxAfCIYLx +/fLoeTJgv9ispSIUS8rB2EvrfT9XNbLmT3W0sGADIlOukXkd1ptBHxWGVHCy3g01 +D3ywNHK6l2A78HnrorIcXaIWuIfF6Rv2tZclbzif45H6inmYw2kOt6McIAWX+MoU +rgDXxPPAFBB1azSgG7WZYPNcsMVXTjbSMoS/ng== +-----END CERTIFICATE----- diff --git a/meta-signing-key/recipes-support/key-store/key-store_0.1.bb b/meta-signing-key/recipes-support/key-store/key-store_0.1.bb new file mode 100644 index 0000000..7b9572e --- /dev/null +++ b/meta-signing-key/recipes-support/key-store/key-store_0.1.bb @@ -0,0 +1,122 @@ +DESCRIPTION = "Key store for key installation" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \ + file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +inherit user-key-store + +S = "${WORKDIR}" + +ALLOW_EMPTY_${PN} = "1" + +PACKAGES =+ " \ + ${PN}-system-trusted-cert \ + ${PN}-ima-cert \ + " + +# Note any private key is not available if user key signing model used. +PACKAGES_DYNAMIC += " \ + ${PN}-ima-privkey \ + ${PN}-system-trusted-privkey \ + ${PN}-rpm-pubkey \ + " + +KEY_DIR = "${sysconfdir}/keys" +# For RPM verification +RPM_KEY_DIR = "${sysconfdir}/pki/rpm-gpg" + +# For ${PN}-system-trusted-privkey +SYSTEM_PRIV_KEY = "${KEY_DIR}/system_trusted_key.key" + +# For ${PN}-ima-privkey +IMA_PRIV_KEY = "${KEY_DIR}/privkey_evm.pem" + +# For ${PN}-system-trusted-cert +SYSTEM_CERT = "${KEY_DIR}/system_trusted_key.pem" +FILES_${PN}-system-trusted-cert = "${SYSTEM_CERT}" +CONFFILES_${PN}-system-trusted-cert = "${SYSTEM_CERT}" + +# For ${PN}-ima-cert +IMA_CERT = "${KEY_DIR}/x509_evm.der" +FILES_${PN}-ima-cert = "${IMA_CERT}" +CONFFILES_${PN}-ima-cert = "${IMA_CERT}" + +python () { + if uks_signing_model(d) != "sample": + return + + pn = d.getVar('PN', True) + '-system-trusted-privkey' + d.setVar('PACKAGES_prepend', pn + ' ') + d.setVar('FILES_' + pn, d.getVar('SYSTEM_PRIV_KEY', True)) + d.setVar('CONFFILES_' + pn, d.getVar('SYSTEM_PRIV_KEY', True)) + + pn = d.getVar('PN', True) + '-ima-privkey' + d.setVar('PACKAGES_prepend', pn + ' ') + d.setVar('FILES_' + pn, d.getVar('IMA_PRIV_KEY', True)) + d.setVar('CONFFILES_' + pn, d.getVar('IMA_PRIV_KEY', True)) + + pn = d.getVar('PN', True) + '-rpm-pubkey' + d.setVar('PACKAGES_prepend', pn + ' ') + d.setVar('FILES_' + pn, d.getVar(d.getVar('RPM_KEY_DIR', True) + '/RPM-GPG-KEY-*', True)) + d.setVar('CONFFILES_' + pn, d.getVar(d.getVar('RPM_KEY_DIR', True) + 'RPM-GPG-KEY-*', True)) + d.appendVar('RDEPENDS_' + pn, ' rpm') +} + +do_install() { + install -d "${D}${RPM_KEY_DIR}" + + for f in `ls ${WORKDIR}/RPM-GPG-KEY-* 2>/dev/null`; do + [ ! -f "$f" ] && continue + + install -m 0644 "$f" "${D}${RPM_KEY_DIR}" + done + + key_dir="${@uks_rpm_keys_dir(d)}" + if [ -n "$key_dir" ]; then + for f in `ls $key_dir/RPM-GPG-KEY-* 2>/dev/null`; do + [ ! -s "$f" ] && continue + + install -m 0644 "$f" "${D}${RPM_KEY_DIR}" + done + fi + + install -d "${D}${KEY_DIR}" + + key_dir="${@uks_system_trusted_keys_dir(d)}" + install -m 0644 "$key_dir/system_trusted_key.pem" "${D}${SYSTEM_CERT}" + + if [ "${@uks_signing_model(d)}" = "sample" ]; then + install -m 0400 "$key_dir/system_trusted_key.key" "${D}${SYSTEM_PRIV_KEY}" + fi + + key_dir="${@uks_ima_keys_dir(d)}" + install -m 0644 "$key_dir/x509_ima.der" "${D}${IMA_CERT}" + + if [ "${@uks_signing_model(d)}" = "sample" ]; then + install -m 0400 "$key_dir/x509_ima.key" "${D}${IMA_PRIV_KEY}" + fi +} + +SYSROOT_PREPROCESS_FUNCS += "key_store_sysroot_preprocess" + +key_store_sysroot_preprocess() { + sysroot_stage_dir "${D}${sysconfdir}" "${SYSROOT_DESTDIR}${sysconfdir}" +} + +pkg_postinst_${PN}-rpm-pubkey() { + if [ -z "$D" ]; then + keydir="${RPM_KEY_DIR}" + + [ ! -d "$keydir" ] && mkdir -p "$keydir" + + # XXX: only import the new key + for keyfile in `ls $keydir/RPM-GPG-KEY-*`; do + [ ! -f "$keyfile" ] && continue + + ! rpm --import "$keyfile" && { + echo "Unable to import the public key $keyfile" + exit 1 + } + done + fi +} diff --git a/meta-signing-key/scripts/create-user-key-store.sh b/meta-signing-key/scripts/create-user-key-store.sh new file mode 100755 index 0000000..1d0803c --- /dev/null +++ b/meta-signing-key/scripts/create-user-key-store.sh @@ -0,0 +1,144 @@ +#!/bin/bash + +KEYS_DIR="`pwd`/user-keys" + +function show_help() +{ + cat < + +Usage: $1 options... + +Options: + -d + Set the path to save the generated user keys. + Default: `pwd`/user-keys + + -h|--help + Show this help information. + +EOF +} + +while [ $# -gt 0 ]; do + opt=$1 + case $opt in + -d) + shift && KEYS_DIR="$1" + ;; + -h|--help) + show_help `basename $0` + exit 0 + ;; + *) + echo "Unsupported option $opt" + exit 1 + ;; + esac + shift +done + +echo "KEYS_DIR: $KEYS_DIR" + +UEFI_SB_KEYS_DIR="$KEYS_DIR/uefi_sb_keys" +MOK_SB_KEYS_DIR="$KEYS_DIR/mok_sb_keys" +SYSTEM_KEYS_DIR="$KEYS_DIR/system_trusted_keys" +IMA_KEYS_DIR="$KEYS_DIR/ima_keys" + +create_uefi_sb_user_keys() { + local key_dir="$UEFI_SB_KEYS_DIR" + + [ ! -d "$key_dir" ] && mkdir -p "$key_dir" + + # PK is self-signed. + openssl req -new -x509 -newkey rsa:2048 \ + -sha256 -nodes -days 3650 \ + -subj "/CN=PK Certificate for $USER@`hostname`/" \ + -keyout "$key_dir/PK.key" \ + -out "$key_dir/PK.pem" + + # KEK is signed by PK. + openssl req -new -newkey rsa:2048 \ + -sha256 -nodes \ + -subj "/CN=KEK Certificate for $USER@`hostname`" \ + -keyout "$key_dir/KEK.key" \ + -out "$key_dir/KEK.csr" + + openssl x509 -req -in "$key_dir/KEK.csr" \ + -CA "$key_dir/PK.pem" -CAkey "$key_dir/PK.key" \ + -set_serial 1 -days 3650 -out "$key_dir/KEK.pem" + + rm -f "$key_dir/KEK.csr" + + # DB is signed by KEK. + openssl req -new -newkey rsa:2048 \ + -sha256 -nodes \ + -subj "/CN=DB Certificate for $USER@`hostname`" \ + -keyout "$key_dir/DB.key" \ + -out "$key_dir/DB.csr" + + openssl x509 -req -in "key_dir/DB.csr" \ + -CA "$key_dir/KEK.pem" -CAkey "$key_dir/KEK.key" \ + -set_serial 1 -days 3650 -out "$key_dir/DB.pem" + + rm -f "$key_dir/DB.csr" +} + +create_mok_sb_user_keys() { + local key_dir="$MOK_SB_KEYS_DIR" + + [ ! -d "$key_dir" ] && mkdir -p "$key_dir" + + openssl req -new -x509 -newkey rsa:2048 \ + -sha256 -nodes -days 3650 \ + -subj "/CN=Shim Certificate for $USER@`hostname`/" \ + -keyout "$key_dir/shim_cert.key" -out "$key_dir/shim_cert.pem" + + openssl req -new -x509 -newkey rsa:2048 \ + -sha256 -nodes -days 3650 \ + -subj "/CN=Vendor Certificate for $USER@`hostname`/" \ + -keyout "$key_dir/vendor_cert.key" -out "$key_dir/vendor_cert.pem" +} + +create_system_trusted_keys() { + local key_dir="$SYSTEM_KEYS_DIR" + + [ ! -d "$key_dir" ] && mkdir -p "$key_dir" + + openssl req -new -x509 -newkey rsa:2048 \ + -sha256 -nodes -days 3650 \ + -subj "/CN=System Trusted Certificate/" \ + -keyout "$key_dir/system_trusted_key.key" \ + -out "$key_dir/system_trusted_key.pem" +} + +create_ima_user_keys() { + local key_dir="$IMA_KEYS_DIR" + + [ ! -d "$key_dir" ] && mkdir -p "$key_dir" + + openssl req -new -x509 -newkey rsa:2048 \ + -sha256 -nodes -days 3650 \ + -subj "/CN=IMA Trusted Certificate/" \ + -keyout "$key_dir/x509_ima.key" \ + -outform DER -out "$key_dir/x509_ima.der" +} + +create_user_keys() { + echo "Creating the user keys for UEFI Secure Boot" + create_uefi_sb_user_keys + + echo "Creating the user keys for MOK Secure Boot" + create_mok_sb_user_keys + + echo "Creating the system trusted keys" + create_system_trusted_keys + + echo "Creating the user keys for IMA appraisal" + create_ima_user_keys +} + +create_user_keys + diff --git a/meta-tpm/README.md b/meta-tpm/README.md new file mode 100644 index 0000000..11cff2a --- /dev/null +++ b/meta-tpm/README.md @@ -0,0 +1,59 @@ +### TPM 1.2 +This feature enables tpm 1.2 support, including kernel option changes to +enable tpm drivers, and picking up packages trousers, tpm-tools, +openssl-tpm-engine, tpm-quote-tools. + +### How to use TPM 1.2 +For TPM 1.2, the following typical steps can be performed to get the TPM +ready for use: + +- Clear and enable TPM from the BIOS. +- Take TPM ownership. + ``` + # tpm_takeownership -y -z + ``` +- Change owner and SRK passwords. These password are used for the + access permission to other functions including generate keys. + ``` + # tpm_changeownerauth -z -s -o + ``` +Then, you can use the TPM for a specific need, such as key generation, +sealing encrypted data, etc. + +### openssl tpm engine for TPM 1.2 +openssl-tpm-engine package provides tpm engine lib for openssl applications. +It is an interface between openssl applications and TPM hardware. + +- Wrap software key using the TPM engine + - If tpm is not owned, run "tpm_takeownership -y -z". + This also set tpm SRK and Owner password to well-known key. + You can then run tpm_changeownerauth to set new SRK and Owner password. + To reset SRK and Owner password to well-known key, run "tpm_changeownerauth -r -s -o". + - Generate tpm hardware key: (add -z for using well-known key) + ``` + $ create_tpm_key rootkey.pem [-z] + ``` + - Wrap software key into TPM storage: + $ openssl genrsa -out softkey.pem 1024 + $ create_tpm_key -w softkey.pem -s 1024 rootkey.pem [-z] +- Create a self-signed cert using the TPM engine + - Generate a TPM key and write it to a file: + ``` + $ create_tpm_key + ``` +- Make the openssl certificate request: + ``` + $ openssl req -keyform engine -engine tpm -key -new -x509 -days 365 -out + ``` +- How to use tpm engine lib +The name of tpm engine library is libtpm.so. +There is an enhencement to the original opensource code. +Add an additional way to pass SRK passwork to libtpm.so, +that is using environment variable "TPM_SRK_PW". +For example: +``` + env TPM_SRK_PW=xxx openssl s_server ... +``` +Note: +- "env TPM_SRK_PW=#WELLKNOWN#" is used to pass well-known key. +- Detail description about openssl-tpm-engine, please refer to the README in source code. diff --git a/meta-tpm/conf/layer.conf b/meta-tpm/conf/layer.conf new file mode 100644 index 0000000..e425b92 --- /dev/null +++ b/meta-tpm/conf/layer.conf @@ -0,0 +1,12 @@ +# We have a conf and classes directory, add to BBPATH +BBPATH .= ":${LAYERDIR}" + +# We have recipes-* directories, add to BBFILES +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ + ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "tpm" +BBFILE_PATTERN_tpm = "^${LAYERDIR}/" +BBFILE_PRIORITY_tpm = "10" + +LAYERDEPENDS_tpm = "core" diff --git a/meta-tpm/recipes-base/packagegroups/packagegroup-tpm.bb b/meta-tpm/recipes-base/packagegroups/packagegroup-tpm.bb new file mode 100644 index 0000000..684a392 --- /dev/null +++ b/meta-tpm/recipes-base/packagegroups/packagegroup-tpm.bb @@ -0,0 +1,19 @@ +DESCRIPTION = "Basic packagegroup for TCG TSS and utilities that use it." +LICENSE = "MIT" +PR = "r0" + +inherit packagegroup + +RDEPENDS_${PN} = "\ + trousers \ + tpm-tools \ + openssl-tpm-engine \ + rng-tools \ +" + +RRECOMMENDS_${PN} = "\ + kernel-module-tpm-rng \ + kernel-module-tpm-tis \ + kernel-module-tpm-atmel \ + kernel-module-tpm-infineon \ +" diff --git a/meta-tpm/recipes-kernel/linux/linux-yocto-rt_4.%.bbappend b/meta-tpm/recipes-kernel/linux/linux-yocto-rt_4.%.bbappend new file mode 100644 index 0000000..8fbd7ba --- /dev/null +++ b/meta-tpm/recipes-kernel/linux/linux-yocto-rt_4.%.bbappend @@ -0,0 +1 @@ +include linux-yocto-tpm.inc diff --git a/meta-tpm/recipes-kernel/linux/linux-yocto-tpm.inc b/meta-tpm/recipes-kernel/linux/linux-yocto-tpm.inc new file mode 100644 index 0000000..276e154 --- /dev/null +++ b/meta-tpm/recipes-kernel/linux/linux-yocto-tpm.inc @@ -0,0 +1,6 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/linux-yocto:" + +SRC_URI += " \ + ${@bb.utils.contains('DISTRO_FEATURES', 'tpm', \ + 'file://tpm.scc file://tpm.cfg', '', d)} \ +" diff --git a/meta-tpm/recipes-kernel/linux/linux-yocto/tpm.cfg b/meta-tpm/recipes-kernel/linux/linux-yocto/tpm.cfg new file mode 100644 index 0000000..ac18405 --- /dev/null +++ b/meta-tpm/recipes-kernel/linux/linux-yocto/tpm.cfg @@ -0,0 +1,17 @@ +.......................................................................... +. WARNING +. +. This file is a kernel configuration fragment, and not a full kernel +. configuration file. The final kernel configuration is made up of +. an assembly of processed fragments, each of which is designed to +. capture a specific part of the final configuration (e.g. platform +. configuration, feature configuration, and board specific hardware +. configuration). For more information on kernel configuration, please +. consult the product documentation. +. +.......................................................................... + +CONFIG_TCG_TPM=y +CONFIG_TCG_TIS=y +CONFIG_TCG_ATMEL=y +CONFIG_TCG_INFINEON=y diff --git a/meta-tpm/recipes-kernel/linux/linux-yocto/tpm.scc b/meta-tpm/recipes-kernel/linux/linux-yocto/tpm.scc new file mode 100644 index 0000000..90cfe56 --- /dev/null +++ b/meta-tpm/recipes-kernel/linux/linux-yocto/tpm.scc @@ -0,0 +1,4 @@ +define KFEATURE_DESCRIPTION "TPM 1.x enablement" + +kconf hardware tpm.cfg + diff --git a/meta-tpm/recipes-kernel/linux/linux-yocto_4.%.bbappend b/meta-tpm/recipes-kernel/linux/linux-yocto_4.%.bbappend new file mode 100644 index 0000000..8fbd7ba --- /dev/null +++ b/meta-tpm/recipes-kernel/linux/linux-yocto_4.%.bbappend @@ -0,0 +1 @@ +include linux-yocto-tpm.inc diff --git a/meta-tpm/recipes-tpm/openssl-tpm-engine/files/0001-create-tpm-key-support-well-known-key-option.patch b/meta-tpm/recipes-tpm/openssl-tpm-engine/files/0001-create-tpm-key-support-well-known-key-option.patch new file mode 100644 index 0000000..67071b6 --- /dev/null +++ b/meta-tpm/recipes-tpm/openssl-tpm-engine/files/0001-create-tpm-key-support-well-known-key-option.patch @@ -0,0 +1,99 @@ +commit 16dac0cb7b73b8a7088300e45b98ac20819b03ed +Author: Junxian.Xiao +Date: Wed Jun 19 18:57:13 2013 +0800 + +support well-known password in openssl-tpm-engine. + +Add "-z" option to select well known password in create_tpm_key tool. + +Signed-off-by: Junxian.Xiao + +diff --git a/create_tpm_key.c b/create_tpm_key.c +index fee917f..7b94d62 100644 +--- a/create_tpm_key.c ++++ b/create_tpm_key.c +@@ -46,6 +46,8 @@ + #include + #include + ++#define TPM_WELL_KNOWN_KEY_LEN 20 /*well know key length is 20 bytes zero*/ ++ + #define print_error(a,b) \ + fprintf(stderr, "%s:%d %s result: 0x%x (%s)\n", __FILE__, __LINE__, \ + a, b, Trspi_Error_String(b)) +@@ -70,6 +72,7 @@ usage(char *argv0) + "\t\t-e|--enc-scheme encryption scheme to use [PKCSV15] or OAEP\n" + "\t\t-q|--sig-scheme signature scheme to use [DER] or SHA1\n" + "\t\t-s|--key-size key size in bits [2048]\n" ++ "\t\t-z|--zerokey use well known 20 bytes zero as SRK password.\n" + "\t\t-a|--auth require a password for the key [NO]\n" + "\t\t-p|--popup use TSS GUI popup dialogs to get the password " + "for the\n\t\t\t\t key [NO] (implies --auth)\n" +@@ -147,6 +150,7 @@ int main(int argc, char **argv) + int asn1_len; + char *filename, c, *openssl_key = NULL; + int option_index, auth = 0, popup = 0, wrap = 0; ++ int wellknownkey = 0; + UINT32 enc_scheme = TSS_ES_RSAESPKCSV15; + UINT32 sig_scheme = TSS_SS_RSASSAPKCS1V15_DER; + UINT32 key_size = 2048; +@@ -154,12 +158,15 @@ int main(int argc, char **argv) + + while (1) { + option_index = 0; +- c = getopt_long(argc, argv, "pe:q:s:ahw:", ++ c = getopt_long(argc, argv, "pe:q:s:zahw:", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { ++ case 'z': ++ wellknownkey = 1; ++ break; + case 'a': + initFlags |= TSS_KEY_AUTHORIZATION; + auth = 1; +@@ -293,6 +300,8 @@ int main(int argc, char **argv) + + if (srk_authusage) { + char *authdata = calloc(1, 128); ++ TSS_FLAG secretMode = TSS_SECRET_MODE_PLAIN; ++ int authlen = 0; + + if (!authdata) { + fprintf(stderr, "malloc failed.\n"); +@@ -309,17 +318,26 @@ int main(int argc, char **argv) + exit(result); + } + +- if (EVP_read_pw_string(authdata, 128, "SRK Password: ", 0)) { +- Tspi_Context_CloseObject(hContext, hKey); +- Tspi_Context_Close(hContext); +- free(authdata); +- exit(result); ++ if (wellknownkey) { ++ memset(authdata, 0, TPM_WELL_KNOWN_KEY_LEN); ++ secretMode = TSS_SECRET_MODE_SHA1; ++ authlen = TPM_WELL_KNOWN_KEY_LEN; ++ } ++ else { ++ if (EVP_read_pw_string(authdata, 128, "SRK Password: ", 0)) { ++ Tspi_Context_CloseObject(hContext, hKey); ++ Tspi_Context_Close(hContext); ++ free(authdata); ++ exit(result); ++ } ++ secretMode = TSS_SECRET_MODE_PLAIN; ++ authlen = strlen(authdata); + } + + //Set Secret + if ((result = Tspi_Policy_SetSecret(srkUsagePolicy, +- TSS_SECRET_MODE_PLAIN, +- strlen(authdata), ++ secretMode, ++ authlen, + (BYTE *)authdata))) { + print_error("Tspi_Policy_SetSecret", result); + free(authdata); diff --git a/meta-tpm/recipes-tpm/openssl-tpm-engine/files/0002-libtpm-support-env-TPM_SRK_PW.patch b/meta-tpm/recipes-tpm/openssl-tpm-engine/files/0002-libtpm-support-env-TPM_SRK_PW.patch new file mode 100644 index 0000000..f718f2e --- /dev/null +++ b/meta-tpm/recipes-tpm/openssl-tpm-engine/files/0002-libtpm-support-env-TPM_SRK_PW.patch @@ -0,0 +1,80 @@ +commit 16dac0cb7b73b8a7088300e45b98ac20819b03ed +Author: Junxian.Xiao +Date: Wed Jun 19 18:57:13 2013 +0800 + +support reading SRK password from env TPM_SRK_PW + +Add "env TPM_SRK_PW=xxxx" to set password for libtpm.so. Specially, +use "env TPM_SRK_PW=#WELLKNOWN#" to set well known password. + +Signed-off-by: Junxian.Xiao + +diff --git a/e_tpm.c b/e_tpm.c +index f3e8bcf..7dcb75a 100644 +--- a/e_tpm.c ++++ b/e_tpm.c +@@ -38,6 +38,8 @@ + + #include "e_tpm.h" + ++#define TPM_WELL_KNOWN_KEY_LEN 20 /*well know key length is 20 bytes zero*/ ++ + //#define DLOPEN_TSPI + + #ifndef OPENSSL_NO_HW +@@ -248,6 +250,10 @@ int tpm_load_srk(UI_METHOD *ui, void *cb_data) + TSS_RESULT result; + UINT32 authusage; + BYTE *auth; ++ char *srkPasswd = NULL; ++ TSS_FLAG secretMode = secret_mode; ++ int authlen = 0; ++ + + if (hSRK != NULL_HKEY) { + DBGFN("SRK is already loaded."); +@@ -299,18 +305,36 @@ int tpm_load_srk(UI_METHOD *ui, void *cb_data) + return 0; + } + +- if (!tpm_engine_get_auth(ui, (char *)auth, 128, "SRK authorization: ", +- cb_data)) { +- Tspi_Context_CloseObject(hContext, hSRK); +- free(auth); +- TSSerr(TPM_F_TPM_LOAD_SRK, TPM_R_REQUEST_FAILED); +- return 0; ++ srkPasswd = getenv("TPM_SRK_PW"); ++ if (NULL != srkPasswd) { ++ if (0 == strcmp(srkPasswd, "#WELLKNOWN#")) { ++ memset(auth, 0, TPM_WELL_KNOWN_KEY_LEN); ++ secretMode = TSS_SECRET_MODE_SHA1; ++ authlen = TPM_WELL_KNOWN_KEY_LEN; ++ } else { ++ int authbuflen = 128; ++ memset(auth, 0, authbuflen); ++ strncpy(auth, srkPasswd, authbuflen-1); ++ secretMode = TSS_SECRET_MODE_PLAIN; ++ authlen = strlen(auth); ++ } ++ } ++ else { ++ if (!tpm_engine_get_auth(ui, (char *)auth, 128, ++ "SRK authorization: ", cb_data)) { ++ Tspi_Context_CloseObject(hContext, hSRK); ++ free(auth); ++ TSSerr(TPM_F_TPM_LOAD_SRK, TPM_R_REQUEST_FAILED); ++ return 0; ++ } ++ secretMode = secret_mode; ++ authlen = strlen(auth); + } + + /* secret_mode is a global that may be set by engine ctrl + * commands. By default, its set to TSS_SECRET_MODE_PLAIN */ +- if ((result = Tspi_Policy_SetSecret(hSRKPolicy, secret_mode, +- strlen((char *)auth), auth))) { ++ if ((result = Tspi_Policy_SetSecret(hSRKPolicy, secretMode, ++ authlen, auth))) { + Tspi_Context_CloseObject(hContext, hSRK); + free(auth); + TSSerr(TPM_F_TPM_LOAD_SRK, TPM_R_REQUEST_FAILED); diff --git a/meta-tpm/recipes-tpm/openssl-tpm-engine/files/0003-Fix-not-building-libtpm.la.patch b/meta-tpm/recipes-tpm/openssl-tpm-engine/files/0003-Fix-not-building-libtpm.la.patch new file mode 100644 index 0000000..d24a150 --- /dev/null +++ b/meta-tpm/recipes-tpm/openssl-tpm-engine/files/0003-Fix-not-building-libtpm.la.patch @@ -0,0 +1,25 @@ +From 7848445a1f4c750ef73bf96f5e89d402f87a1756 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Mon, 19 Jun 2017 14:54:28 +0800 +Subject: [PATCH] Fix not building libtpm.la + +Signed-off-by: Lans Zhang +--- + Makefile.am | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/Makefile.am b/Makefile.am +index 6695656..634a7e6 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -10,4 +10,6 @@ libtpm_la_LIBADD=-lcrypto -lc -ltspi + libtpm_la_SOURCES=e_tpm.c e_tpm.h e_tpm_err.c + + create_tpm_key_SOURCES=create_tpm_key.c +-create_tpm_key_LDADD=-ltspi ++create_tpm_key_LDFLAGS=-ltspi ++ ++LDADD=libtpm.la +-- +2.7.5 + diff --git a/meta-tpm/recipes-tpm/openssl-tpm-engine/openssl-tpm-engine_0.4.2.bb b/meta-tpm/recipes-tpm/openssl-tpm-engine/openssl-tpm-engine_0.4.2.bb new file mode 100644 index 0000000..acb79bd --- /dev/null +++ b/meta-tpm/recipes-tpm/openssl-tpm-engine/openssl-tpm-engine_0.4.2.bb @@ -0,0 +1,54 @@ +DESCRIPTION = " OpenSSL secure engine based on TPM hardware" +HOMEPAGE = "http://www.openssl.org/" +SECTION = "libs/network" +LICENSE = "openssl" + +DEPENDS += "openssl trousers" +RDEPENDS_${PN} += "libcrypto libtspi" + +SRC_URI = "\ + http://sourceforge.net/projects/trousers/files/OpenSSL%20TPM%20Engine/0.4.2/openssl_tpm_engine-0.4.2.tar.gz \ + file://0001-create-tpm-key-support-well-known-key-option.patch \ + file://0002-libtpm-support-env-TPM_SRK_PW.patch \ + file://0003-Fix-not-building-libtpm.la.patch \ +" +SRC_URI[md5sum] = "5bc8d66399e517dde25ff55ce4c6560f" +SRC_URI[sha256sum] = "2df697e583053f7047a89daa4585e21fc67cf4397ee34ece94cf2d4b4f7ab49c" +LIC_FILES_CHKSUM = "file://LICENSE;md5=11f0ee3af475c85b907426e285c9bb52" + +inherit autotools-brokensep + +S = "${WORKDIR}/openssl_tpm_engine-${PV}" + +do_configure_prepend() { + cd "${S}" + cp LICENSE COPYING + touch NEWS AUTHORS ChangeLog +} + +FILES_${PN}-staticdev += "${libdir}/ssl/engines/libtpm.la" +FILES_${PN}-dbg += "${libdir}/ssl/engines/.debug \ + ${libdir}/engines/.debug \ + ${prefix}/local/ssl/lib/engines/.debug \ +" +FILES_${PN} += "${libdir}/ssl/engines/libtpm.so* \ + ${libdir}/engines/libtpm.so* \ + ${libdir}/libtpm.so* \ + ${prefix}/local/ssl/lib/engines/libtpm.so* \ +" + +do_install_append() { + install -m 0755 -d "${D}${libdir}/engines" + install -m 0755 -d "${D}${prefix}/local/ssl/lib/engines" + install -m 0755 -d "${D}${libdir}/ssl/engines" + + cp -f "${D}${libdir}/openssl/engines/libtpm.so.0.0.0" "${D}${libdir}/libtpm.so.0" + cp -f "${D}${libdir}/openssl/engines/libtpm.so.0.0.0" "${D}${libdir}/engines/libtpm.so" + cp -f "${D}${libdir}/openssl/engines/libtpm.so.0.0.0" "${D}${prefix}/local/ssl/lib/engines/libtpm.so" + mv -f "${D}${libdir}/openssl/engines/libtpm.so.0.0.0" "${D}${libdir}/ssl/engines/libtpm.so" + mv -f "${D}${libdir}/openssl/engines/libtpm.la" "${D}${libdir}/ssl/engines/libtpm.la" + rm -rf "${D}${libdir}/openssl" +} + +INSANE_SKIP_${PN} = "libdir" +INSANE_SKIP_${PN}-dbg = "libdir" diff --git a/meta-tpm/recipes-tpm/pcr-extend/pcr-extend_0.1.bb b/meta-tpm/recipes-tpm/pcr-extend/pcr-extend_0.1.bb new file mode 100644 index 0000000..6f4611a --- /dev/null +++ b/meta-tpm/recipes-tpm/pcr-extend/pcr-extend_0.1.bb @@ -0,0 +1,21 @@ +SUMMARY = " \ + " +DESCRIPTION = " \ + " +SECTION = "tpm" +PR = "r0" +LICENSE = "PD" +LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263" +DEPENDS = "libtspi" + +S = "${WORKDIR}/${BPN}_${PV}" + +SRC_URI += " \ + http://twobit.us/${BPN}/${BPN}_${PV}.tar.bz2 \ +" + +SRC_URI[md5sum] = "98d2a3b816e54bdb17fe97a4294928bc" +SRC_URI[sha256sum] = "0ee784b252537bde4e195bfdedb20efd01ccf106a2b86beae6c8c02b3f7b1470" + +inherit autotools +B = "${WORKDIR}/${BPN}_${PV}" diff --git a/meta-tpm/recipes-tpm/tpm-quote-tools/tpm-quote-tools_1.0.1.bb b/meta-tpm/recipes-tpm/tpm-quote-tools/tpm-quote-tools_1.0.1.bb new file mode 100644 index 0000000..f20d17d --- /dev/null +++ b/meta-tpm/recipes-tpm/tpm-quote-tools/tpm-quote-tools_1.0.1.bb @@ -0,0 +1,26 @@ +SUMMARY = " \ + The TPM Quote Tools is a collection of programs that provide support \ + for TPM based attestation using the TPM quote mechanism. \ + " +DESCRIPTION = " \ + The TPM Quote Tools is a collection of programs that provide support \ + for TPM based attestation using the TPM quote mechanism. The manual \ + page for tpm_quote_tools provides a usage overview. \ + \ + TPM Quote Tools has been tested with TrouSerS on Linux and NTRU on \ + Windows XP. It was ported to Windows using MinGW and MSYS. \ + " +SECTION = "tpm" +PR = "r0" +LICENSE = "PD" +LIC_FILES_CHKSUM = "file://COPYING;md5=8ec30b01163d242ecf07d9cd84e3611f" +DEPENDS = "libtspi tpm-tools" + +SRC_URI += " \ + http://downloads.sourceforge.net/project/tpmquotetools/1.0.1/tpm-quote-tools-1.0.1.tar.gz \ +" + +SRC_URI[md5sum] = "bea00c7d5c9bd78bfa42e4e69428de80" +SRC_URI[sha256sum] = "40a6987c009cc24677a7e13a6c4121c0a165e37a588c019ae417d66a3bdfa0b5" + +inherit autotools diff --git a/meta-tpm/recipes-tpm/tpm-tools/tpm-tools-1.3.8/03-fix-bool-error-parseStringWithValues.patch b/meta-tpm/recipes-tpm/tpm-tools/tpm-tools-1.3.8/03-fix-bool-error-parseStringWithValues.patch new file mode 100644 index 0000000..9497e89 --- /dev/null +++ b/meta-tpm/recipes-tpm/tpm-tools/tpm-tools-1.3.8/03-fix-bool-error-parseStringWithValues.patch @@ -0,0 +1,30 @@ +Title: Fix boolean comparison error (and FTBFS with gcc-5) +Date: 2015-06-28 +Author: Pierre Chifflier +Bug-Debian: http://bugs.debian.org/778147 +Index: tpm-tools/src/tpm_mgmt/tpm_nvcommon.c +=================================================================== +--- tpm-tools.orig/src/tpm_mgmt/tpm_nvcommon.c ++++ tpm-tools/src/tpm_mgmt/tpm_nvcommon.c +@@ -140,8 +140,8 @@ int parseStringWithValues(const char *aA + aArg); + return -1; + } +- if (!aArg[offset+numbytes] == '|' && +- !aArg[offset+numbytes] == 0) { ++ if (!(aArg[offset+numbytes] == '|' || ++ aArg[offset+numbytes] == 0)) { + logError(_("Illegal character following " + "hexadecimal number in %s\n"), + aArg + offset); +@@ -164,8 +164,8 @@ int parseStringWithValues(const char *aA + return -1; + } + +- if (!aArg[offset+numbytes] == '|' && +- !aArg[offset+numbytes] == 0) { ++ if (!(aArg[offset+numbytes] == '|' || ++ aArg[offset+numbytes] == 0)) { + logError(_("Illegal character following decimal " + "number in %s\n"), + aArg + offset); diff --git a/meta-tpm/recipes-tpm/tpm-tools/tpm-tools-1.3.8/tpm-tools-extendpcr.patch b/meta-tpm/recipes-tpm/tpm-tools/tpm-tools-1.3.8/tpm-tools-extendpcr.patch new file mode 100644 index 0000000..ab5e683 --- /dev/null +++ b/meta-tpm/recipes-tpm/tpm-tools/tpm-tools-1.3.8/tpm-tools-extendpcr.patch @@ -0,0 +1,244 @@ +Index: tpm-tools-1.3.8/include/tpm_tspi.h +=================================================================== +--- tpm-tools-1.3.8.orig/include/tpm_tspi.h 2011-08-17 08:20:35.000000000 -0400 ++++ tpm-tools-1.3.8/include/tpm_tspi.h 2013-01-05 23:26:31.571598217 -0500 +@@ -117,6 +117,10 @@ + UINT32 *a_PcrSize, BYTE **a_PcrValue); + TSS_RESULT pcrcompositeSetPcrValue(TSS_HPCRS a_hPcrs, UINT32 a_Idx, + UINT32 a_PcrSize, BYTE *a_PcrValue); ++TSS_RESULT tpmPcrExtend(TSS_HTPM a_hTpm, UINT32 a_Idx, ++ UINT32 a_DataSize, BYTE *a_Data, ++ TSS_PCR_EVENT *a_Event, ++ UINT32 *a_PcrSize, BYTE **a_PcrValue); + #ifdef TSS_LIB_IS_12 + TSS_RESULT unloadVersionInfo(UINT64 *offset, BYTE *blob, TPM_CAP_VERSION_INFO *v); + TSS_RESULT pcrcompositeSetPcrLocality(TSS_HPCRS a_hPcrs, UINT32 localityValue); +Index: tpm-tools-1.3.8/lib/tpm_tspi.c +=================================================================== +--- tpm-tools-1.3.8.orig/lib/tpm_tspi.c 2011-08-17 08:20:35.000000000 -0400 ++++ tpm-tools-1.3.8/lib/tpm_tspi.c 2013-01-05 23:27:37.731593490 -0500 +@@ -594,6 +594,20 @@ + return result; + } + ++TSS_RESULT ++tpmPcrExtend(TSS_HTPM a_hTpm, UINT32 a_Idx, ++ UINT32 a_DataSize, BYTE *a_Data, ++ TSS_PCR_EVENT *a_Event, ++ UINT32 *a_PcrSize, BYTE **a_PcrValue) ++{ ++ TSS_RESULT result = ++ Tspi_TPM_PcrExtend(a_hTpm, a_Idx, a_DataSize, a_Data, a_Event, ++ a_PcrSize, a_PcrValue); ++ tspiResult("Tspi_TPM_PcrExtend", result); ++ ++ return result; ++} ++ + #ifdef TSS_LIB_IS_12 + /* + * These getPasswd functions will wrap calls to the other functions and check to see if the TSS +Index: tpm-tools-1.3.8/src/cmds/Makefile.am +=================================================================== +--- tpm-tools-1.3.8.orig/src/cmds/Makefile.am 2011-08-15 13:52:08.000000000 -0400 ++++ tpm-tools-1.3.8/src/cmds/Makefile.am 2013-01-05 23:30:46.223593698 -0500 +@@ -22,6 +22,7 @@ + # + + bin_PROGRAMS = tpm_sealdata \ ++ tpm_extendpcr \ + tpm_unsealdata + + if TSS_LIB_IS_12 +@@ -33,4 +34,5 @@ + LDADD = $(top_builddir)/lib/libtpm_tspi.la -ltspi $(top_builddir)/lib/libtpm_unseal.la -ltpm_unseal -lcrypto + + tpm_sealdata_SOURCES = tpm_sealdata.c ++tpm_extendpcr_SOURCES = tpm_extendpcr.c + tpm_unsealdata_SOURCES = tpm_unsealdata.c +Index: tpm-tools-1.3.8/src/cmds/tpm_extendpcr.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ tpm-tools-1.3.8/src/cmds/tpm_extendpcr.c 2013-01-05 23:37:43.403585514 -0500 +@@ -0,0 +1,181 @@ ++/* ++ * The Initial Developer of the Original Code is International ++ * Business Machines Corporation. Portions created by IBM ++ * Corporation are Copyright (C) 2005, 2006 International Business ++ * Machines Corporation. All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the Common Public License as published by ++ * IBM Corporation; either version 1 of the License, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * Common Public License for more details. ++ * ++ * You should have received a copy of the Common Public License ++ * along with this program; if not, a copy can be viewed at ++ * http://www.opensource.org/licenses/cpl1.0.php. ++ */ ++#include ++#include ++#include ++#include "tpm_tspi.h" ++#include "tpm_utils.h" ++#include "tpm_seal.h" ++ ++// #define TPM_EXTENDPCR_DEBUG ++ ++static void help(const char *aCmd) ++{ ++ logCmdHelp(aCmd); ++ logCmdOption("-i, --infile FILE", ++ _ ++ ("Filename containing data to extend PCRs with. Default is STDIN.")); ++ logCmdOption("-p, --pcr NUMBER", ++ _("PCR to extend.")); ++ ++} ++ ++static char in_filename[PATH_MAX] = ""; ++static TSS_HPCRS hPcrs = NULL_HPCRS; ++static TSS_HTPM hTpm; ++static UINT32 selectedPcrs[24]; ++static UINT32 selectedPcrsLen = 0; ++TSS_HCONTEXT hContext = 0; ++ ++static int parse(const int aOpt, const char *aArg) ++{ ++ int rc = -1; ++ ++ switch (aOpt) { ++ case 'i': ++ if (aArg) { ++ strncpy(in_filename, aArg, PATH_MAX); ++ rc = 0; ++ } ++ break; ++ case 'p': ++ if (aArg) { ++ selectedPcrs[selectedPcrsLen++] = atoi(aArg); ++ rc = 0; ++ } ++ break; ++ default: ++ break; ++ } ++ return rc; ++ ++} ++ ++int main(int argc, char **argv) ++{ ++ ++ int iRc = -1; ++ struct option opts[] = { ++ {"infile", required_argument, NULL, 'i'}, ++ {"pcr", required_argument, NULL, 'p'}, ++ }; ++ unsigned char line[EVP_MD_block_size(EVP_sha1()) * 16]; ++ int lineLen; ++ UINT32 i; ++ ++ BIO *bin = NULL; ++ ++ initIntlSys(); ++ ++ if (genericOptHandler(argc, argv, "i:p:", opts, ++ sizeof(opts) / sizeof(struct option), parse, ++ help) != 0) ++ goto out; ++ ++ if (contextCreate(&hContext) != TSS_SUCCESS) ++ goto out; ++ ++ if (contextConnect(hContext) != TSS_SUCCESS) ++ goto out_close; ++ ++ if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) ++ goto out_close; ++ ++ /* Create a BIO for the input file */ ++ if ((bin = BIO_new(BIO_s_file())) == NULL) { ++ logError(_("Unable to open input BIO\n")); ++ goto out_close; ++ } ++ ++ /* Assign the input file to the BIO */ ++ if (strlen(in_filename) == 0) ++ BIO_set_fp(bin, stdin, BIO_NOCLOSE); ++ else if (!BIO_read_filename(bin, in_filename)) { ++ logError(_("Unable to open input file: %s\n"), ++ in_filename); ++ goto out_close; ++ } ++ ++ /* Create the PCRs object. If any PCRs above 15 are selected, this will need to be ++ * a 1.2 TSS/TPM */ ++ if (selectedPcrsLen) { ++ TSS_FLAG initFlag = 0; ++ UINT32 pcrSize; ++ BYTE *pcrValue; ++ ++ for (i = 0; i < selectedPcrsLen; i++) { ++ if (selectedPcrs[i] > 15) { ++#ifdef TSS_LIB_IS_12 ++ initFlag |= TSS_PCRS_STRUCT_INFO_LONG; ++#else ++ logError(_("This version of %s was compiled for a v1.1 TSS, which " ++ "can only seal\n data to PCRs 0-15. PCR %u is out of range" ++ "\n"), argv[0], selectedPcrs[i]); ++ goto out_close; ++#endif ++ } ++ } ++ ++ unsigned char msg[EVP_MAX_MD_SIZE]; ++ unsigned int msglen; ++ EVP_MD_CTX ctx; ++ EVP_DigestInit(&ctx, EVP_sha1()); ++ while ((lineLen = BIO_read(bin, line, sizeof(line))) > 0) ++ EVP_DigestUpdate(&ctx, line, lineLen); ++ EVP_DigestFinal(&ctx, msg, &msglen); ++ ++ if (contextCreateObject(hContext, TSS_OBJECT_TYPE_PCRS, initFlag, ++ &hPcrs) != TSS_SUCCESS) ++ goto out_close; ++ ++ for (i = 0; i < selectedPcrsLen; i++) { ++#ifdef TPM_EXTENDPCR_DEBUG ++ if (tpmPcrRead(hTpm, selectedPcrs[i], &pcrSize, &pcrValue) != TSS_SUCCESS) ++ goto out_close; ++ ++ unsigned int j; ++ for (j = 0; j < pcrSize; j++) ++ printf("%02X ", pcrValue[j]); ++ printf("\n"); ++#endif ++ ++ if (tpmPcrExtend(hTpm, selectedPcrs[i], msglen, msg, NULL, &pcrSize, &pcrValue) != TSS_SUCCESS) ++ goto out_close; ++ ++#ifdef TPM_EXTENDPCR_DEBUG ++ for (j = 0; j < pcrSize; j++) ++ printf("%02X ", pcrValue[j]); ++ printf("\n"); ++#endif ++ } ++ } ++ ++ iRc = 0; ++ logSuccess(argv[0]); ++ ++out_close: ++ contextClose(hContext); ++ ++out: ++ if (bin) ++ BIO_free(bin); ++ return iRc; ++} diff --git a/meta-tpm/recipes-tpm/tpm-tools/tpm-tools-1.3.8/tpm-tools-gcc-6.patch b/meta-tpm/recipes-tpm/tpm-tools/tpm-tools-1.3.8/tpm-tools-gcc-6.patch new file mode 100644 index 0000000..eb4373d --- /dev/null +++ b/meta-tpm/recipes-tpm/tpm-tools/tpm-tools-1.3.8/tpm-tools-gcc-6.patch @@ -0,0 +1,21 @@ +--- a/src/tpm_mgmt/tpm_present.c ++++ b/src/tpm_mgmt/tpm_present.c +@@ -349,13 +349,13 @@ + } + } while (flags[++i].name); + +- out_success: ++out_success: + logSuccess(argv[0]); + iRc = 0; +- out_close: ++out_close: + contextClose(hContext); +- out: +- if (szTpmPasswd && !isWellKnown) +- shredPasswd( szTpmPasswd ); ++out: ++ if (szTpmPasswd && !isWellKnown) ++ shredPasswd( szTpmPasswd ); + return iRc; + } diff --git a/meta-tpm/recipes-tpm/tpm-tools/tpm-tools_1.3.8.bb b/meta-tpm/recipes-tpm/tpm-tools/tpm-tools_1.3.8.bb new file mode 100644 index 0000000..5b5bbd8 --- /dev/null +++ b/meta-tpm/recipes-tpm/tpm-tools/tpm-tools_1.3.8.bb @@ -0,0 +1,24 @@ +SUMMARY = "The tpm-tools package contains commands to allow the platform administrator the ability to manage and diagnose the platform's TPM." +DESCRIPTION = " \ + The tpm-tools package contains commands to allow the platform administrator \ + the ability to manage and diagnose the platform's TPM. Additionally, the \ + package contains commands to utilize some of the capabilities available \ + in the TPM PKCS#11 interface implemented in the openCryptoki project. \ + " +SECTION = "tpm" +PR = "r0" +LICENSE = "CPL-1.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=059e8cd6165cb4c31e351f2b69388fd9" +DEPENDS = "libtspi openssl" + +SRC_URI += " \ + http://downloads.sourceforge.net/project/trousers/tpm-tools/1.3.8/tpm-tools-1.3.8.tar.gz \ + file://tpm-tools-extendpcr.patch \ + file://03-fix-bool-error-parseStringWithValues.patch \ + file://tpm-tools-gcc-6.patch \ +" + +SRC_URI[md5sum] = "85a978c4e03fefd4b73cbeadde7c4d0b" +SRC_URI[sha256sum] = "66eb4ff095542403db6b4bd4b574e8a5c08084fe4e9e5aa9a829ee84e20bea83" + +inherit autotools gettext diff --git a/meta-tpm/recipes-tpm/trousers/files/Fix-segment-fault-if-client-hostname-cannot-be-retri.patch b/meta-tpm/recipes-tpm/trousers/files/Fix-segment-fault-if-client-hostname-cannot-be-retri.patch new file mode 100644 index 0000000..ea6d609 --- /dev/null +++ b/meta-tpm/recipes-tpm/trousers/files/Fix-segment-fault-if-client-hostname-cannot-be-retri.patch @@ -0,0 +1,33 @@ +From cdc4828ea44e8cb6f8c62f9021ce37b0c1636aa4 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Thu, 12 May 2016 23:55:44 +0800 +Subject: [PATCH] Fix segment fault if client hostname cannot be retrieve + +Upstream-Status: Pending + +When tcsd cannot resolve the hostname of client, the constant C string +INVALID_ADDR_STR is used to identify the client. The host name eventually +be freed by calling free(), which will violate the memory protection for +sure. To fix this issue, always create a freeable INVALID_ADDR_STR. + +Signed-off-by: Lans Zhang +--- + src/tcsd/svrside.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/tcsd/svrside.c b/src/tcsd/svrside.c +index 1ae1636..692211c 100644 +--- a/src/tcsd/svrside.c ++++ b/src/tcsd/svrside.c +@@ -557,7 +557,7 @@ main(int argc, char **argv) + + hostname = fetch_hostname(&client_addr, client_len); + if (hostname == NULL) +- hostname=INVALID_ADDR_STR; ++ hostname=strdup(INVALID_ADDR_STR); + + tcsd_thread_create(newsd, hostname); + hostname = NULL; +-- +1.9.1 + diff --git a/meta-tpm/recipes-tpm/trousers/files/fix-deadlock-and-potential-hung.patch b/meta-tpm/recipes-tpm/trousers/files/fix-deadlock-and-potential-hung.patch new file mode 100644 index 0000000..1bf1a7e --- /dev/null +++ b/meta-tpm/recipes-tpm/trousers/files/fix-deadlock-and-potential-hung.patch @@ -0,0 +1,82 @@ +commit dbd71905ba3183e53bcc699813f6061779001c62 +Author: Genli Pan +Date: Mon Dec 15 10:54:04 2014 +0800 + +obj_list_get_obj() uses a mutex lock to exclusively access to list. +And the lock is released in function obj_list_put(). Usage of this +couple of functions in the following code path cause deadlock. + -------- + obj_context_transport_close + obj_list_get_obj + secret_PerformAuth_OIAP + obj_context_get_tcs_api + obj_list_get_obj + ... + obj_list_put + Transport_OIAP + obj_context_transport_init + obj_list_get_obj + ... + obj_list_put + RPC_ReleaseTransportSigned + obj_list_put + -------- + +Also fix a potential hung situation, that authorization session didn't been +released even if establish transport session failed. And retrying will +takes up more authorization sessions, until the thread being forced waiting. + +Signed-off-by: Genli Pan + +diff --git a/src/tspi/obj_context.c b/src/tspi/obj_context.c +index cb2091e..bcbc4da 100644 +--- a/src/tspi/obj_context.c ++++ b/src/tspi/obj_context.c +@@ -1330,6 +1334,7 @@ obj_context_transport_close(TSS_HCONTEXT tspContext, + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; ++ obj_list_put(&context_list); + + /* return immediately if we're not in a transport session */ + if (!(context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED)) { +@@ -1431,7 +1436,7 @@ obj_context_transport_close(TSS_HCONTEXT tspContext, + done_disabled: + context->flags &= ~TSS_CONTEXT_FLAGS_TRANSPORT_ESTABLISHED; + done: +- obj_list_put(&context_list); ++ //obj_list_put(&context_list); + + return result; + } +diff --git a/src/tcs/tcsi_transport.c b/src/tcs/tcsi_transport.c +index ce47e09..98a9d40 100644 +--- a/src/tcs/tcsi_transport.c ++++ b/src/tcs/tcsi_transport.c +@@ -77,11 +77,16 @@ TCSP_EstablishTransport_Internal(TCS_CONTEXT_HANDLE hContext, + } else + LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_EstablishTransport, txBlob); + +- if ((result = req_mgr_submit_req(txBlob))) ++ if ((result = req_mgr_submit_req(txBlob))) { ++ if (pEncKeyAuth) ++ pEncKeyAuth->fContinueAuthSession = FALSE; + goto done; ++ } + + if ((result = UnloadBlob_Header(txBlob, ¶mSize))) { + LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result); ++ if (pEncKeyAuth) ++ pEncKeyAuth->fContinueAuthSession = FALSE; + goto done; + } + +@@ -97,6 +102,8 @@ TCSP_EstablishTransport_Internal(TCS_CONTEXT_HANDLE hContext, + *prgbCurrentTicks = malloc(*ulCurrentTicks); + if (*prgbCurrentTicks == NULL) { + result = TCSERR(TSS_E_OUTOFMEMORY); ++ if (pEncKeyAuth) ++ pEncKeyAuth->fContinueAuthSession = FALSE; + goto done; + } + diff --git a/meta-tpm/recipes-tpm/trousers/files/fix-event-log-parsing-problem.patch b/meta-tpm/recipes-tpm/trousers/files/fix-event-log-parsing-problem.patch new file mode 100644 index 0000000..578e0bf --- /dev/null +++ b/meta-tpm/recipes-tpm/trousers/files/fix-event-log-parsing-problem.patch @@ -0,0 +1,38 @@ +commit 3545a0675ee3cfee6297f968276b5a9b64799057 +Author: Genli Pan +Date: Tue Aug 25 15:12:36 2015 +0800 + +trousers: fix event log parsing problem + +Due to the change of format of kernel ima event log, trousers +failed to parse the log to extract information. this commit adjust +trousers to adapt the change. + +Signed-off-by: Genli Pan + +--- a/src/tcs/tcs_evlog_imaem.c 2014-04-25 02:05:44.000000000 +0800 ++++ b/src/tcs/tcs_evlog_imaem.c 2015-08-24 14:16:46.000000000 +0800 +@@ -145,11 +145,6 @@ + result = TCSERR(TSS_E_INTERNAL_ERROR); + goto free_list; + } +- if (fread(digest, 1, sizeof digest, fp) != (sizeof(digest))) { +- LogError("Failed to read event log file"); +- result = TCSERR(TSS_E_INTERNAL_ERROR); +- goto free_list; +- } + } + /* Get the template data namelen and data */ + if (fread(&cur->event.ulEventLength, 1, sizeof(int), fp) != sizeof(int)) { +@@ -286,11 +281,6 @@ + LogError("Failed to read event log file"); + result = TCSERR(TSS_E_INTERNAL_ERROR); + goto done; +- } +- if (fread(digest, 1, sizeof(digest), fp) != sizeof(digest)) { +- LogError("Failed to read event log file"); +- result = TCSERR(TSS_E_INTERNAL_ERROR); +- goto done; + } + } + /* Get the template data namelen and data */ diff --git a/meta-tpm/recipes-tpm/trousers/files/fix-incorrect-report-of-insufficient-buffer.patch b/meta-tpm/recipes-tpm/trousers/files/fix-incorrect-report-of-insufficient-buffer.patch new file mode 100644 index 0000000..d9a3e31 --- /dev/null +++ b/meta-tpm/recipes-tpm/trousers/files/fix-incorrect-report-of-insufficient-buffer.patch @@ -0,0 +1,22 @@ +commit 3452971ba08ced886db7a9adcfc2d977b07d1410 +Author: Genli Pan +Date: Thu Jul 30 10:43:25 2015 +0800 + +trousers: fix incorrect report of insufficient buffer + +"size" as the size of buffer, is also used as returned size of result, +and so would be modified after "Tddli_TransmitData" function call. +So has to set it back in every loop. + +Signed-off-by: Genli Pan + +--- a/src/tcs/tcs_req_mgr.c 2014-04-25 02:05:44.000000000 +0800 ++++ b/src/tcs/tcs_req_mgr.c 2015-07-22 16:38:49.000000000 +0800 +@@ -45,6 +45,7 @@ + #endif + + do { ++ size = TSS_TPM_TXBLOB_SIZE; + result = Tddli_TransmitData(blob, Decode_UINT32(&blob[2]), loc_buf, &size); + } while (!result && (Decode_UINT32(&loc_buf[6]) == TCPA_E_RETRY) && --retry); + diff --git a/meta-tpm/recipes-tpm/trousers/files/tcsd.conf b/meta-tpm/recipes-tpm/trousers/files/tcsd.conf new file mode 100755 index 0000000..1adf7aa --- /dev/null +++ b/meta-tpm/recipes-tpm/trousers/files/tcsd.conf @@ -0,0 +1,170 @@ + +# +# This is the configuration file for the trousers tcsd. (The Trusted Computing +# Software Stack Core Services Daemon). +# +# Defaults are listed below, commented out +# +# Send questions to: trousers-users@lists.sourceforge.net +# + +# Option: port +# Values: 1 - 65535 +# Description: The port that the tcsd will listen on. +# +port = 30003 +# + +# Option: num_threads +# Values: 1 - 65535 +# Description: The number of threads that the tcsd will spawn internally. +# +num_threads = 10 +# + +# Option: system_ps_file +# Values: Any absolute directory path +# Description: Path where the tcsd creates its persistent storage file. +# +system_ps_file = /var/lib/tpm/system.data +# + +# Option: firmware_log_file +# Values: Any absolute directory path +# Description: Path to the file containing the current firmware PCR event +# log data. The interface to this log is usually provided by the TPM +# device driver. +# +firmware_log_file = /sys/kernel/security/tpm0/binary_bios_measurements +# + +# Option: kernel_log_file +# Values: Any absolute directory path +# Description: Path to the file containing the current kernel PCR event +# log data. By default, this data will be parsed in the format provided +# by the Integrity Measurement Architecture LSM. See +# http://sf.net/projects/linux-ima for more info on getting IMA. +# +# +kernel_log_file = /sys/kernel/security/ima/binary_runtime_measurements +# + +# Option: firmware_pcrs +# Values: PCR indices, separated by commas +# Description: A list of PCR indices that are manipulated only by the system +# firmware and therefore are not extended or logged by the TCSD. +# +firmware_pcrs = 0, 1, 2, 3, 4, 5, 6, 7 +# + +# Option: kernel_pcrs +# Values: PCR indices, separated by commas +# Description: A list of PCR indices that are manipulated only by the kernel +# and therefore are not extended or logged by the TCSD. +# +kernel_pcrs = 10 +# + +# Option: platform_cred +# Values: Any absolute directory path (example: /path/to/platform.cert) +# Description: Path to the file containing your TPM's platform credential. +# The platform credential may have been provided to you by your TPM +# manufacturer. If so, set platform_cred to the path to the file on disk. +# Whenever a new TPM identity is created, the credential will be used. See +# Tspi_TPM_CollateIdentityRequest(3) for more information. +# +# platform_cred = +# + +# Option: conformance_cred +# Values: Any absolute directory path (example: /path/to/conformance.cert) +# Description: Path to the file containing your TPM's conformance credential. +# The conformance credential may have been provided to you by your TPM +# manufacturer. If so, set conformance_cred to the path to the file on disk. +# Whenever a new TPM identity is created, the credential will be used. See +# Tspi_TPM_CollateIdentityRequest(3) for more information. +# +# conformance_cred = +# + +# Option: endorsement_cred +# Values: Any absolute directory path (example: /path/to/endorsement.cert) +# Description: Path to the file containing your TPM's endorsement credential. +# The endorsement credential may have been provided to you by your TPM +# manufacturer. If so, set endorsement_cred to the path to the file on disk. +# Whenever a new TPM identity is created, the credential will be used. See +# Tspi_TPM_CollateIdentityRequest(3) for more information. +# +# endorsement_cred = +# + +# Option: remote_ops +# Values: TCS operation names, separated by commas (no whitespace) +# Description: A list of TCS commands which will be allowed to be executed +# on this machine's TCSD by TSP's on non-local hosts (over the internet). +# By default, access to all operations is denied. +# +# possible values: seal - encrypt data bound to PCR values +# unseal - decrypt data bound to PCR values +# registerkey - store keys in system persistent storage [Disk write access!] +# unregisterkey - remove keys from system persistent storage [Disk write access!] +# loadkey - load a key into the TPM +# createkey - create a key using the TPM +# sign - encrypt data using a private key +# random - generate random numbers +# getcapability - query the TCS/TPM for its capabilities +# unbind - decrypt data +# quote - request a signed blob containing all PCR values +# readpubek - access the TPM's Public EndorsementKey +# getregisteredkeybypublicinfo - Search system persistent storage for a public key +# getpubkey - Retrieve a loaded key's public data from inside the TPM +# selftest - execute selftest and test results ordinals +# +# remote_ops = +# + +# Option: enforce_exclusive_transport +# Values: 0 or 1 +# Description: When an application opens a transport session with the TPM, one +# of the options available is an "exclusive" session, meaning that the TPM +# will not execute any commands other than those coming through the transport +# session for the lifetime of the session. The TCSD can choose to enforce this +# option or not. By default, exclusive sessions are not enforced, since this +# could allow for a denial of service to the TPM. +# +# enforce_exclusive_transport = 0 +# + +# Option: host_platform_class +# Values: One of the TCG platform class specifications +# PC_11 - PC Client System, version 1.1 +# PC_12 - PC Client System, version 1.2 +# PDA_12 - PDA System, version 1.2 +# SERVER_12 - Server System, version 1.2 +# MOBILE_12 - Mobile Phone System, version 1.2 +# +# Description: This option determines the host platform (host the TCS system +# is running on) class, among those specified by the Trusted Computing group +# on https://www.trustedcomputinggroup.org/specs/. This class will be reported +# by the TCS daemon when an application queries it using the +# TSS_TCSCAP_PROP_HOST_PLATFORM sub-capability. The default is PC_12. +# +host_platform_class = PC_12 +# + +# Option: all_platform_classes +# Values: TCG Platform class names, separated by commas (no whitespaces) +# PC_11 - PC Client System, version 1.1 +# PC_12 - PC Client System, version 1.2 +# PDA_12 - PDA System, version 1.2 +# SERVER_12 - Server System, version 1.2 +# MOBILE_12 - Mobile Phone System, version 1.2 +# +# Description: This option determines all the platform classes supported by the +# TCS daemon. This list must not include the value set as "host_platform_class" +# specified above. Since by default TrouSerS supports all TPM 1.2 functionality, +# the default is all 1.2 and 1.1 platform classes. +# +# all_platform_classes = PC_11,PDA_12,SERVER_12,MOBILE_12 +# + diff --git a/meta-tpm/recipes-tpm/trousers/files/tcsd.service b/meta-tpm/recipes-tpm/trousers/files/tcsd.service new file mode 100644 index 0000000..59f573b --- /dev/null +++ b/meta-tpm/recipes-tpm/trousers/files/tcsd.service @@ -0,0 +1,21 @@ +[Unit] +Description=TrouSerS TCG Core Services daemon +After=syslog.target network.target +ConditionPathExists=|/dev/tpm0 +ConditionPathExists=|/udev/tpm0 +ConditionPathExists=|/dev/tpm +ConditionPathExistsGlob=/sys/class/*/tpm0/@TPM_CAPS@ + +[Service] +Type=forking +ExecStartPre=/bin/sh -c "fgrep '@FAMILY_MAJOR@' /sys/class/*/tpm0/@TPM_CAPS@" +ExecStart=/usr/sbin/tcsd + +TimeoutSec=30s +Restart=on-failure +RestartSec=4 +StartLimitInterval=25 +StartLimitBurst=5 + +[Install] +WantedBy=multi-user.target diff --git a/meta-tpm/recipes-tpm/trousers/files/trousers-conditional-compile-DES-related-code.patch b/meta-tpm/recipes-tpm/trousers/files/trousers-conditional-compile-DES-related-code.patch new file mode 100644 index 0000000..6e54586 --- /dev/null +++ b/meta-tpm/recipes-tpm/trousers/files/trousers-conditional-compile-DES-related-code.patch @@ -0,0 +1,38 @@ +From 8140d73d63383f22c9d88e5f3207b201cddebff2 Mon Sep 17 00:00:00 2001 +From: Haiqing Bai +Date: Wed, 6 Apr 2016 18:38:25 +0800 +Subject: [PATCH] trousers: Conditional compile DES related code. + +Added "OPENSSL_NO_DES" checking for DES related +code in trousers. + +Upstream-Status: Pending + +Signed-off-by: Haiqing Bai +--- + src/trspi/crypto/openssl/symmetric.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/trspi/crypto/openssl/symmetric.c b/src/trspi/crypto/openssl/symmetric.c +index f5c3836..8ba183d 100644 +--- a/src/trspi/crypto/openssl/symmetric.c ++++ b/src/trspi/crypto/openssl/symmetric.c +@@ -162,6 +162,7 @@ get_openssl_cipher(UINT16 alg, UINT16 mode) + break; + } + break; ++#ifndef OPENSSL_NO_DES + case TSS_ALG_DES: + case TCPA_ALG_DES: + switch (mode) { +@@ -202,6 +203,7 @@ get_openssl_cipher(UINT16 alg, UINT16 mode) + break; + } + break; ++#endif /* OPENSSL_NO_DES */ + case TPM_ALG_AES192: + case TSS_ALG_AES192: + switch (mode) { +-- +1.9.1 + diff --git a/meta-tpm/recipes-tpm/trousers/files/trousers-udev.rules b/meta-tpm/recipes-tpm/trousers/files/trousers-udev.rules new file mode 100644 index 0000000..256babd --- /dev/null +++ b/meta-tpm/recipes-tpm/trousers/files/trousers-udev.rules @@ -0,0 +1,2 @@ +# trousers daemon expects tpm device to be owned by tss user & group +KERNEL=="tpm[0-9]*", MODE="0600", OWNER="tss", GROUP="tss" diff --git a/meta-tpm/recipes-tpm/trousers/files/trousers.init.sh b/meta-tpm/recipes-tpm/trousers/files/trousers.init.sh new file mode 100644 index 0000000..0ecf7cc --- /dev/null +++ b/meta-tpm/recipes-tpm/trousers/files/trousers.init.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +### BEGIN INIT INFO +# Provides: tcsd trousers +# Required-Start: $local_fs $remote_fs $network +# Required-Stop: $local_fs $remote_fs $network +# Should-Start: +# Should-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: starts tcsd +# Description: tcsd belongs to the TrouSerS TCG Software Stack +### END INIT INFO + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +DAEMON=/usr/sbin/tcsd +NAME=tcsd +DESC="Trusted Computing daemon" +USER="tss" + +test -x "${DAEMON}" || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +case "${1}" in + start) + echo "Starting $DESC: " + + if [ ! -e /dev/tpm* ] + then + echo "device driver not loaded, skipping." + exit 0 + fi + + start-stop-daemon --start --quiet --oknodo --pidfile /var/run/${NAME}.pid --user ${USER} --chuid ${USER} --exec ${DAEMON} -- ${DAEMON_OPTS} + RETVAL="$?" + echo "$NAME." + [ "$RETVAL" = 0 ] && pidof $DAEMON > /var/run/${NAME}.pid + exit $RETVAL + ;; + + stop) + echo "Stopping $DESC: " + + start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/${NAME}.pid --user ${USER} --exec ${DAEMON} + RETVAL="$?" + echo "$NAME." + rm -f /var/run/${NAME}.pid + exit $RETVAL + ;; + + restart|force-reload) + "${0}" stop + sleep 1 + "${0}" start + exit $? + ;; + *) + echo "Usage: ${NAME} {start|stop|restart|force-reload|status}" >&2 + exit 3 + ;; +esac + +exit 0 diff --git a/meta-tpm/recipes-tpm/trousers/trousers_0.3.14.bb b/meta-tpm/recipes-tpm/trousers/trousers_0.3.14.bb new file mode 100644 index 0000000..e12543f --- /dev/null +++ b/meta-tpm/recipes-tpm/trousers/trousers_0.3.14.bb @@ -0,0 +1,114 @@ +SUMMARY = "TrouSerS - An open-source TCG Software Stack implementation." +DESCRIPTION = " \ +Trousers is an open-source TCG Software Stack (TSS), released under the \ +Common Public License. Trousers aims to be compliant with the current (1.1b) \ +and upcoming (1.2) TSS specifications available from the Trusted Computing \ +Group website: http://www.trustedcomputinggroup.org. \ +" +HOMEPAGE = "https://sourceforge.net/projects/trousers" +SECTION = "security/tpm" + +LICENSE = "BSD" +LIC_FILES_CHKSUM = "file://LICENSE;md5=8031b2ae48ededc9b982c08620573426" + +SRC_URI = " \ + http://sourceforge.net/projects/trousers/files/trousers/0.3.14/trousers-0.3.14.tar.gz;subdir=${PN}-${PV} \ + file://fix-deadlock-and-potential-hung.patch \ + file://trousers.init.sh \ + file://fix-event-log-parsing-problem.patch \ + file://fix-incorrect-report-of-insufficient-buffer.patch \ + file://trousers-conditional-compile-DES-related-code.patch \ + file://Fix-segment-fault-if-client-hostname-cannot-be-retri.patch \ + file://trousers-udev.rules \ + file://tcsd.service \ + file://tcsd.conf \ + " + +SRC_URI[md5sum] = "4a476b4f036dd20a764fb54fc24edbec" +SRC_URI[sha256sum] = "ce50713a261d14b735ec9ccd97609f0ad5ce69540af560e8c3ce9eb5f2d28f47" + +S = "${WORKDIR}/${PN}-${PV}" + +DEPENDS = "openssl" + +inherit autotools pkgconfig useradd update-rc.d +inherit ${@bb.utils.contains('VIRTUAL-RUNTIME_init_manager', 'systemd', 'systemd', '', d)} + +PACKAGECONFIG ?= "gmp " +PACKAGECONFIG[gmp] = "--with-gmp, --with-gmp=no, gmp" +PACKAGECONFIG[gtk] = "--with-gui=gtk, --with-gui=none, gtk+" + +PROVIDES = "${PACKAGES}" +PACKAGES =+ " \ + libtspi \ + libtspi-dbg \ + libtspi-dev \ + libtspi-doc \ + libtspi-staticdev \ + " + +FILES_libtspi = " \ + ${libdir}/libtspi.so.* \ + " +FILES_libtspi-dbg = " \ + ${prefix}/src/debug/${PN}/${PV}-${PR}/${PN}-${PV}/src/tspi \ + ${prefix}/src/debug/${PN}/${PV}-${PR}/${PN}-${PV}/src/trspi \ + ${prefix}/src/debug/${PN}/${PV}-${PR}/${PN}-${PV}/src/include/*.h \ + ${prefix}/src/debug/${PN}/${PV}-${PR}/${PN}-${PV}/src/include/tss \ + " +FILES_libtspi-dev = " \ + ${includedir} \ + ${libdir}/*.so \ + ${libdir}/*.so.1 \ + " +FILES_libtspi-doc = " \ + ${mandir}/man3 \ + " +FILES_libtspi-staticdev = " \ + ${libdir}/*.la \ + ${libdir}/*.a \ + " +FILES_${PN}-dbg = " \ + ${prefix}/src/debug/${PN}/${PV}-${PR}/${PN}-${PV}/src/tcs \ + ${prefix}/src/debug/${PN}/${PV}-${PR}/${PN}-${PV}/src/tcsd \ + ${prefix}/src/debug/${PN}/${PV}-${PR}/${PN}-${PV}/src/tddl \ + ${prefix}/src/debug/${PN}/${PV}-${PR}/${PN}-${PV}/src/trousers \ + ${prefix}/src/debug/${PN}/${PV}-${PR}/${PN}-${PV}/src/include/trousers \ + " +FILES_${PN}-dev += "${libdir}/trousers" +FILES_${PN} += "${systemd_unitdir}/system/tcsd.service" +CONFFILES_${PN} += "${sysconfig}/tcsd.conf" + +INITSCRIPT_NAME = "trousers" +INITSCRIPT_PARAMS = "start 99 2 3 4 5 . stop 19 0 1 6 ." + +USERADD_PACKAGES = "${PN}" +GROUPADD_PARAM_${PN} = "tss" +USERADD_PARAM_${PN} = "-M -d /var/lib/tpm -s /bin/false -g tss tss" + +SYSTEMD_PACKAGES = "${PN}" +SYSTEMD_SERVICE_${PN} = "tcsd.service" +SYSTEMD_AUTO_ENABLE = "enable" + +TPM_CAPS_x86 = 'device/caps' +FAMILY_MAJOR_x86 = 'TCG version: 1.2' +TPM_CAPS_x86-64 = 'device/caps' +FAMILY_MAJOR_x86-64 = 'TCG version: 1.2' + +do_install_append() { + install -d "${D}${sysconfdir}/init.d" + install -m 0600 "${WORKDIR}/tcsd.conf" "${D}${sysconfdir}" + chown tss:tss "${D}${sysconfdir}/tcsd.conf" + install -m 0755 "${WORKDIR}/trousers.init.sh" "${D}${sysconfdir}/init.d/trousers" + + install -d "${D}${sysconfdir}/udev/rules.d" + install -m 0644 "${WORKDIR}/trousers-udev.rules" \ + "${D}${sysconfdir}/udev/rules.d/45-trousers.rules" + + install -d "${D}${systemd_unitdir}/system" + install -m 0644 "${WORKDIR}/tcsd.service" "${D}${systemd_unitdir}/system" + sed -i 's:@TPM_CAPS@:${TPM_CAPS}:' "${D}${systemd_unitdir}/system/tcsd.service" + sed -i 's/@FAMILY_MAJOR@/${FAMILY_MAJOR}/' "${D}${systemd_unitdir}/system/tcsd.service" +} + +BBCLASSEXTEND = "native" diff --git a/meta-tpm/recipes-tpm/tss-testsuite/files/Tspi_TPM_CreateIdentityWithCallbacks_no_des.patch b/meta-tpm/recipes-tpm/tss-testsuite/files/Tspi_TPM_CreateIdentityWithCallbacks_no_des.patch new file mode 100644 index 0000000..6d43068 --- /dev/null +++ b/meta-tpm/recipes-tpm/tss-testsuite/files/Tspi_TPM_CreateIdentityWithCallbacks_no_des.patch @@ -0,0 +1,79 @@ +diff --git a/tcg/highlevel/tpm/Tspi_TPM_CreateIdentityWithCallbacks.c b/tcg/highlevel/tpm/Tspi_TPM_CreateIdentityWithCallbacks.c +index b5704f3..12fbd56 100644 +--- a/tcg/highlevel/tpm/Tspi_TPM_CreateIdentityWithCallbacks.c ++++ b/tcg/highlevel/tpm/Tspi_TPM_CreateIdentityWithCallbacks.c +@@ -66,8 +66,8 @@ + + #define CERT_VERIFY_BYTE 0x5a + +-TCPA_ALGORITHM_ID symAlg = TCPA_ALG_3DES; +-TSS_ALGORITHM_ID tssSymAlg = TSS_ALG_3DES; ++TCPA_ALGORITHM_ID symAlg = TCPA_ALG_AES; ++TSS_ALGORITHM_ID tssSymAlg = TSS_ALG_AES; + + /* globals to make callbacks easier */ + TSS_HTPM hTPM = 0; +@@ -114,6 +114,7 @@ collate_cb(PVOID myArgs, UINT32 proofSize, BYTE *proof, TSS_ALGORITHM_ID algID, + symKey.size = 128/8; + memcpy(iv, "&%@)*%%$&#)%&#*$", 16); + break; ++#ifndef OPENSSL_NO_DES + case TSS_ALG_DES: + symKey.algId = TCPA_ALG_DES; + symKey.size = 64/8; +@@ -124,6 +125,7 @@ collate_cb(PVOID myArgs, UINT32 proofSize, BYTE *proof, TSS_ALGORITHM_ID algID, + symKey.size = 192/8; + memcpy(iv, "&%@)*%%)", 8); + break; ++#endif /* OPENSSL_NO_DES */ + default: + return TSS_E_BAD_PARAMETER; + break; +@@ -194,6 +196,7 @@ activate_cb(PVOID myArgs, UINT32 symBlobLen, BYTE *symBlob, UINT32 symAttestBlob + case TCPA_ALG_AES: + memcpy(iv, "&%@)*%%$&#)%&#*$", 16); + break; ++#ifndef OPENSSL_NO_DES + case TSS_ALG_DES: + case TCPA_ALG_DES: + memcpy(iv, "&*$#%)$&", 8); +@@ -202,6 +205,7 @@ activate_cb(PVOID myArgs, UINT32 symBlobLen, BYTE *symBlob, UINT32 symAttestBlob + case TCPA_ALG_3DES: + memcpy(iv, "&%@)*%%)", 8); + break; ++#endif /* OPENSSL_NO_DES */ + default: + fprintf(stderr, "Bad algorithm ID: 0x%x\n", symKey.algId); + free(symKey.data); +@@ -438,6 +442,7 @@ ca_create_credential(TSS_HCONTEXT hContext, TSS_HTPM hTPM, + asymContents.sessionKey.size = 128/8; + memcpy(iv, "&%@)*%%$&#)%&#*$", 16); + break; ++#ifndef OPENSSL_NO_DES + case TCPA_ALG_DES: + asymContents.sessionKey.size = 64/8; + memcpy(iv, "&*$#%)$&", 8); +@@ -446,6 +451,7 @@ ca_create_credential(TSS_HCONTEXT hContext, TSS_HTPM hTPM, + asymContents.sessionKey.size = 192/8; + memcpy(iv, "&%@)*%%)", 8); + break; ++#endif /* OPENSSL_NO_DES */ + default: + print_error("Invalid symmetric algorithm!", -1); + return TSS_E_INTERNAL_ERROR; +@@ -727,6 +733,7 @@ main_v1_1(void){ + } + + switch (symKey.algId) { ++#ifndef OPENSSL_NO_DES + case TCPA_ALG_DES: + algID = TSS_ALG_DES; + iv = "&*$#%)$&"; +@@ -735,6 +742,7 @@ main_v1_1(void){ + algID = TSS_ALG_3DES; + iv = "&%@)*%%)"; + break; ++#endif /* OPENSSL_NO_DES */ + case TCPA_ALG_AES: + algID = TSS_ALG_AES; + iv = "&%@)*%%$&#)%&#*$"; diff --git a/meta-tpm/recipes-tpm/tss-testsuite/files/Tspi_TPM_CreateIdentity_no_des.patch b/meta-tpm/recipes-tpm/tss-testsuite/files/Tspi_TPM_CreateIdentity_no_des.patch new file mode 100644 index 0000000..98b5fad --- /dev/null +++ b/meta-tpm/recipes-tpm/tss-testsuite/files/Tspi_TPM_CreateIdentity_no_des.patch @@ -0,0 +1,45 @@ +diff --git a/tcg/highlevel/tpm/Tspi_TPM_CreateIdentity.c b/tcg/highlevel/tpm/Tspi_TPM_CreateIdentity.c +index 01a8aca..128f238 100644 +--- a/tcg/highlevel/tpm/Tspi_TPM_CreateIdentity.c ++++ b/tcg/highlevel/tpm/Tspi_TPM_CreateIdentity.c +@@ -66,8 +66,8 @@ + + #define CERT_VERIFY_BYTE 0x5a + +-TCPA_ALGORITHM_ID symAlg = TCPA_ALG_3DES; +-TSS_ALGORITHM_ID tssSymAlg = TSS_ALG_3DES; ++TCPA_ALGORITHM_ID symAlg = TCPA_ALG_AES; ++TSS_ALGORITHM_ID tssSymAlg = TSS_ALG_AES; + + /* substitute this for TPM_IDENTITY_CREDENTIAL in the TPM docs */ + struct trousers_ca_tpm_identity_credential +@@ -299,12 +299,14 @@ ca_create_credential(TSS_HCONTEXT hContext, TSS_HTPM hTPM, + case TCPA_ALG_AES: + asymContents.sessionKey.size = 128/8; + break; ++#ifndef OPENSSL_NO_DES + case TCPA_ALG_DES: + asymContents.sessionKey.size = 64/8; + break; + case TCPA_ALG_3DES: + asymContents.sessionKey.size = 192/8; + break; ++#endif /* OPENSSL_NO_DES */ + default: + print_error("Invalid symmetric algorithm!", -1); + return TSS_E_INTERNAL_ERROR; +@@ -569,12 +571,14 @@ main_v1_1(void){ + } + + switch (symKey.algId) { ++#ifndef OPENSSL_NO_DES + case TCPA_ALG_DES: + algID = TSS_ALG_DES; + break; + case TCPA_ALG_3DES: + algID = TSS_ALG_3DES; + break; ++#endif /* OPENSSL_NO_DES */ + case TCPA_ALG_AES: + algID = TSS_ALG_AES; + break; diff --git a/meta-tpm/recipes-tpm/tss-testsuite/files/Tspi_TPM_LoadMaintenancePubKey01.patch b/meta-tpm/recipes-tpm/tss-testsuite/files/Tspi_TPM_LoadMaintenancePubKey01.patch new file mode 100644 index 0000000..213797e --- /dev/null +++ b/meta-tpm/recipes-tpm/tss-testsuite/files/Tspi_TPM_LoadMaintenancePubKey01.patch @@ -0,0 +1,21 @@ +commit e9f5c326e6b2020300d897dd5a75301b54991ca1 +Author: Genli Pan +Date: Tue May 12 15:27:48 2015 +0800 + +fix bug in Tspi_TPM_LoadMaintenancePubKey01.c, assign to the right variable. + +Signed-off-by: Genli Pan + +diff --git a/tcg/tpm/Tspi_TPM_LoadMaintenancePubKey01.c b/tcg/tpm/Tspi_TPM_LoadMaintenancePubKey01.c +index b141d34..e8b18a5 100644 +--- a/tcg/tpm/Tspi_TPM_LoadMaintenancePubKey01.c ++++ b/tcg/tpm/Tspi_TPM_LoadMaintenancePubKey01.c +@@ -194,7 +194,7 @@ main_v1_1( void ) + exit( result ); + } + +- ValidationData.ulDataLength = 20; ++ ValidationData.ulExternalDataLength = 20; + ValidationData.rgbExternalData = data; + + //Load Key Blob diff --git a/meta-tpm/recipes-tpm/tss-testsuite/files/common_c_no_des.patch b/meta-tpm/recipes-tpm/tss-testsuite/files/common_c_no_des.patch new file mode 100644 index 0000000..e2ffb7d --- /dev/null +++ b/meta-tpm/recipes-tpm/tss-testsuite/files/common_c_no_des.patch @@ -0,0 +1,36 @@ +diff --git a/tcg/common/common.c b/tcg/common/common.c +index bafe54c..eda1be5 100644 +--- a/tcg/common/common.c ++++ b/tcg/common/common.c +@@ -1729,6 +1729,7 @@ TestSuite_SymEncrypt(UINT16 alg, BYTE mode, BYTE *key, BYTE *iv, BYTE *in, UINT3 + case TCPA_ALG_AES: + cipher = (EVP_CIPHER *)EVP_aes_128_cbc(); + break; ++#ifndef OPENSSL_NO_DES + case TSS_ALG_DES: + case TCPA_ALG_DES: + cipher = (EVP_CIPHER *)EVP_des_cbc(); +@@ -1737,6 +1738,7 @@ TestSuite_SymEncrypt(UINT16 alg, BYTE mode, BYTE *key, BYTE *iv, BYTE *in, UINT3 + case TCPA_ALG_3DES: + cipher = (EVP_CIPHER *)EVP_des_ede3_cbc(); + break; ++#endif /* OPENSSL_NO_DES */ + default: + return TSS_E_INTERNAL_ERROR; + break; +@@ -1826,6 +1828,7 @@ TestSuite_SymDecrypt(UINT16 alg, BYTE mode, BYTE *key, BYTE *iv, BYTE *in, UINT3 + case TCPA_ALG_AES: + cipher = (EVP_CIPHER *)EVP_aes_128_cbc(); + break; ++#ifndef OPENSSL_NO_DES + case TSS_ALG_DES: + case TCPA_ALG_DES: + cipher = (EVP_CIPHER *)EVP_des_cbc(); +@@ -1834,6 +1837,7 @@ TestSuite_SymDecrypt(UINT16 alg, BYTE mode, BYTE *key, BYTE *iv, BYTE *in, UINT3 + case TCPA_ALG_3DES: + cipher = (EVP_CIPHER *)EVP_des_ede3_cbc(); + break; ++#endif /* OPENSSL_NO_DES */ + default: + return TSS_E_INTERNAL_ERROR; + break; diff --git a/meta-tpm/recipes-tpm/tss-testsuite/files/fix-failure-of-.so-LD-with-cortexa8t-neon-wrswrap-linux.patch b/meta-tpm/recipes-tpm/tss-testsuite/files/fix-failure-of-.so-LD-with-cortexa8t-neon-wrswrap-linux.patch new file mode 100644 index 0000000..3aa8bd0 --- /dev/null +++ b/meta-tpm/recipes-tpm/tss-testsuite/files/fix-failure-of-.so-LD-with-cortexa8t-neon-wrswrap-linux.patch @@ -0,0 +1,33 @@ +commit 545f6773fcaf7aeff6de84f9e7594bd4c28eaa61 +Author: Yang, Xiao +Date: Wed Mar 27 19:58:26 2013 +0800 + +Fix package testsuite's compilation failure with ARM cross CC + +missing -fPIC flags in ${CFLAGS}, will cause compilation errors +when compile with cortexa8t-neon-wrswrap-linux-gnueabi-gcc. +While it appears didn't cause problem when cross compiled for ATOM. + +Signed-off-by: Yang, Xiao +Signed-off-by: Genli Pan + +--- + tcg/common/Makefile | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/tcg/common/Makefile b/tcg/common/Makefile +index f389ac0..c6c12db 100644 +--- a/tcg/common/Makefile ++++ b/tcg/common/Makefile +@@ -24,7 +24,7 @@ CC = gcc + CFLAGS += -g -I../include + + .c.o: +- $(CC) $(CFLAGS) -c -o $@ $< ++ $(CC) $(CFLAGS) -fPIC -c -o $@ $< + + all: common.o + +-- +1.7.0.4 + diff --git a/meta-tpm/recipes-tpm/tss-testsuite/files/fix-hardcode-path-in-tsstests.sh.patch b/meta-tpm/recipes-tpm/tss-testsuite/files/fix-hardcode-path-in-tsstests.sh.patch new file mode 100644 index 0000000..a9e6680 --- /dev/null +++ b/meta-tpm/recipes-tpm/tss-testsuite/files/fix-hardcode-path-in-tsstests.sh.patch @@ -0,0 +1,16 @@ +diff --git a/tsstests.sh b/tsstests.sh +index 6a1a5e5..ebaf6c3 100755 +--- a/tsstests.sh ++++ b/tsstests.sh +@@ -54,9 +54,9 @@ TEST_OUTPUT= + OUTPUT_FORMAT="standard" + + # this variable needs to be changed to testcases/tcg/ for ltp compatibility +-TESTCASEDIR=testsuite/tcg/ ++TESTCASEDIR=tcg/ + +-cd .. ++cd `dirname $0` + + export LTPTSSROOT=$PWD + diff --git a/meta-tpm/recipes-tpm/tss-testsuite/files/fix-missing-LDFLAGS-in-compile-command-line.patch b/meta-tpm/recipes-tpm/tss-testsuite/files/fix-missing-LDFLAGS-in-compile-command-line.patch new file mode 100644 index 0000000..3c11371 --- /dev/null +++ b/meta-tpm/recipes-tpm/tss-testsuite/files/fix-missing-LDFLAGS-in-compile-command-line.patch @@ -0,0 +1,25 @@ +From 93f3d150cc1147997be4401b5a14c5bb3120bf0a Mon Sep 17 00:00:00 2001 +From: Yang, Xiao +Date: Thu, 21 Mar 2013 14:24:24 +0800 +Subject: [PATCH] fix missing LDFLAGS in compile command line to locate libs + +--- + tcg/transport/Makefile | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/tcg/transport/Makefile b/tcg/transport/Makefile +index 7b511a0..21568dc 100644 +--- a/tcg/transport/Makefile ++++ b/tcg/transport/Makefile +@@ -27,7 +27,7 @@ else + OPTS = + endif + ALL = $(shell ls *.c | sed "s/\.c//g") +-LIBS = ../common/common.o -ltspi ++LIBS = ../common/common.o -ltspi $(LDFLAGS) + CFLAGS += -g -I../include + + .c: +-- +1.7.0.4 + diff --git a/meta-tpm/recipes-tpm/tss-testsuite/files/testsuite-transport-init.patch b/meta-tpm/recipes-tpm/tss-testsuite/files/testsuite-transport-init.patch new file mode 100644 index 0000000..d25fabb --- /dev/null +++ b/meta-tpm/recipes-tpm/tss-testsuite/files/testsuite-transport-init.patch @@ -0,0 +1,38 @@ +commit 6110b3e5c9cb0e56319d5000e9785171ec9b9559 +Author: Genli Pan +Date: Mon Dec 15 11:18:49 2014 +0800 + +testsuite: fix transport session not released problem + +According to TPM Spec v1.2, TPM_ReleaseTransportSigned command uses two +authorization sessions, but testsuite use one authorization session when +release transport session, this causes transport session actually not be +released in TPM unit, even though TPM return success, in haswell. Fix +testsuite_transport_init() in testsuite. After this fix, transport testcases +works both on haswell and crosshill. + +Signed-off-by: Genli Pan + +--- testsuite-0.3.orig/tcg/common/common.c 2014-10-15 19:04:50.000000000 +0800 ++++ testsuite-0.3/tcg/common/common.c 2014-12-11 15:59:01.000000000 +0800 +@@ -2124,12 +2124,19 @@ + // Create the key used to sign the transport session + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY, + TSS_KEY_SIZE_512 | TSS_KEY_TYPE_SIGNING | +- TSS_KEY_NO_AUTHORIZATION, hSigningKey); ++ TSS_KEY_AUTHORIZATION, hSigningKey); + if (result != TSS_SUCCESS) { + print_error("Tspi_Context_CreateObject", result); + return result; + } + ++ result = Tspi_Policy_AssignToObject(hPolicy, *hSigningKey); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error("Tspi_Policy_AssignToObject", result); ++ return result; ++ } ++ + result = Tspi_Key_CreateKey(*hSigningKey, hSRK, 0); + if (result != TSS_SUCCESS) { + print_error("Tspi_Key_CreateKey", result); diff --git a/meta-tpm/recipes-tpm/tss-testsuite/files/transport-Tspi_TPM_Delegate.patch b/meta-tpm/recipes-tpm/tss-testsuite/files/transport-Tspi_TPM_Delegate.patch new file mode 100644 index 0000000..61235ed --- /dev/null +++ b/meta-tpm/recipes-tpm/tss-testsuite/files/transport-Tspi_TPM_Delegate.patch @@ -0,0 +1,2284 @@ +commit ed7a8f0a0c31c20d35e567e1625c0edfe77b8276 +Author: Genli Pan +Date: Mon Jul 6 18:03:15 2015 +0800 + +fix logical errors in transport delegate testcases + +There are obvious logical errors and redundant code in these testcases. +Resouces are not been released properly. they didn't cause errors in some +TPM chips because these TPMs have enough resouces to be abused. +But in Atmel TPM resource is so limited that allows no abusing. + +Signed-off-by: Genli Pan + +diff --git a/tcg/transport/Tspi_TPM_Delegate_AddFamily-trans01.c b/tcg/transport/Tspi_TPM_Delegate_AddFamily-trans01.c +index fd59e47..12ebd69 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_AddFamily-trans01.c ++++ b/tcg/transport/Tspi_TPM_Delegate_AddFamily-trans01.c +@@ -86,8 +86,6 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error("connect_load_all", result); +- Tspi_Context_FreeMemory( hContext, NULL ); +- Tspi_Context_Close( hContext ); + exit( result ); + } + +@@ -99,33 +97,20 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_AddFamily", result ); +- goto done; +- } ++ } else { + ++ /* Invalidate the family to avoid resource exhaustion */ ++ if (hFamily != NULL_HDELFAMILY) ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++ } + result = Testsuite_Transport_Final(hContext, hSigningKey); + if ( result != TSS_SUCCESS ) + { + print_error("Testsuite_Transport_Final", result); +- goto done; + } + else + { +@@ -133,11 +118,6 @@ main_v1_2( char version ) + } + + print_end_test( function ); +-done: +- /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); +- exit( 0 ); ++ exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_AddFamily-trans02.c b/tcg/transport/Tspi_TPM_Delegate_AddFamily-trans02.c +index 3dd3299..3fe8cff 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_AddFamily-trans02.c ++++ b/tcg/transport/Tspi_TPM_Delegate_AddFamily-trans02.c +@@ -86,8 +86,6 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error("connect_load_all", result); +- Tspi_Context_FreeMemory( hContext, NULL ); +- Tspi_Context_Close( hContext ); + exit( result ); + } + +@@ -99,33 +97,20 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_AddFamily", result ); +- goto done; +- } ++ } else { + ++ /* Invalidate the family to avoid resource exhaustion */ ++ if (hFamily != NULL_HDELFAMILY) ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++ } + result = Testsuite_Transport_Final(hContext, hSigningKey); + if ( result != TSS_SUCCESS ) + { + print_error("Testsuite_Transport_Final", result); +- goto done; + } + else + { +@@ -133,11 +118,6 @@ main_v1_2( char version ) + } + + print_end_test( function ); +-done: +- /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); +- exit( 0 ); ++ exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_AddFamily-trans03.c b/tcg/transport/Tspi_TPM_Delegate_AddFamily-trans03.c +index 8b149d2..98c6127 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_AddFamily-trans03.c ++++ b/tcg/transport/Tspi_TPM_Delegate_AddFamily-trans03.c +@@ -86,8 +86,6 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error("connect_load_all", result); +- Tspi_Context_FreeMemory( hContext, NULL ); +- Tspi_Context_Close( hContext ); + exit( result ); + } + +@@ -99,33 +97,20 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_AddFamily", result ); +- goto done; +- } ++ } else { + ++ /* Invalidate the family to avoid resource exhaustion */ ++ if (hFamily != NULL_HDELFAMILY) ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++ } + result = Testsuite_Transport_Final(hContext, 0); + if ( result != TSS_SUCCESS ) + { + print_error("Testsuite_Transport_Final", result); +- goto done; + } + else + { +@@ -133,11 +118,6 @@ main_v1_2( char version ) + } + + print_end_test( function ); +-done: +- /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); +- exit( 0 ); ++ exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_CacheOwnerDelegation-trans01.c b/tcg/transport/Tspi_TPM_Delegate_CacheOwnerDelegation-trans01.c +index 663c6eb..ef9cac1 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_CacheOwnerDelegation-trans01.c ++++ b/tcg/transport/Tspi_TPM_Delegate_CacheOwnerDelegation-trans01.c +@@ -89,7 +89,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error("connect_load_all", result); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, FALSE, &hWrappingKey, +@@ -100,21 +100,20 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); ++ result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; ++ print_error( "Tspi_TPM_Delegate_AddFamily", result ); ++ goto done_trans; + } + +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); ++ result = Tspi_SetAttribUint32(hFamily, TSS_TSPATTRIB_DELFAMILY_STATE, ++ TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED, TRUE); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_Policy_SetSecret", result ); ++ print_error( "Tspi_SetAttribUint32", result ); + goto done; + } +- + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hDelegation); + if ( result != TSS_SUCCESS ) + { +@@ -154,21 +153,6 @@ main_v1_2( char version ) + goto done; + } + +- result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_TPM_Delegate_AddFamily", result ); +- goto done; +- } +- +- result = Tspi_SetAttribUint32(hFamily, TSS_TSPATTRIB_DELFAMILY_STATE, +- TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED, TRUE); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_SetAttribUint32", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_CreateDelegation(hTPM, 'b', 0, NULL_HPCRS, hFamily, hDelegation); + if ( result != TSS_SUCCESS ) + { +@@ -182,27 +166,22 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_CacheOwnerDelegation", result ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, hSigningKey); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Testsuite_Transport_Final", result ); +- goto done; + } + else + { + print_success( function, result ); + } +- +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ + if (hFamily != NULL_HDELFAMILY) + Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, hSigningKey); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", result); ++ } + Tspi_Context_Close( hContext ); +- ++ print_end_test( function ); + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_CacheOwnerDelegation-trans02.c b/tcg/transport/Tspi_TPM_Delegate_CacheOwnerDelegation-trans02.c +index eaed650..d3c19e8 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_CacheOwnerDelegation-trans02.c ++++ b/tcg/transport/Tspi_TPM_Delegate_CacheOwnerDelegation-trans02.c +@@ -88,8 +88,8 @@ main_v1_2( char version ) + result = connect_load_all(&hContext, &hSRK, &hTPM); + if ( result != TSS_SUCCESS ) + { +- print_error( "connect_load_all", result ); +- goto done; ++ print_error( "connect_load_all", result); ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -100,21 +100,20 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); ++ result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; ++ print_error( "Tspi_TPM_Delegate_AddFamily", result ); ++ goto done_trans; + } + +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); ++ result = Tspi_SetAttribUint32(hFamily, TSS_TSPATTRIB_DELFAMILY_STATE, ++ TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED, TRUE); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_Policy_SetSecret", result ); ++ print_error( "Tspi_SetAttribUint32", result ); + goto done; + } +- + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hDelegation); + if ( result != TSS_SUCCESS ) + { +@@ -154,21 +153,6 @@ main_v1_2( char version ) + goto done; + } + +- result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_TPM_Delegate_AddFamily", result ); +- goto done; +- } +- +- result = Tspi_SetAttribUint32(hFamily, TSS_TSPATTRIB_DELFAMILY_STATE, +- TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED, TRUE); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_SetAttribUint32", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_CreateDelegation(hTPM, 'b', 0, NULL_HPCRS, hFamily, hDelegation); + if ( result != TSS_SUCCESS ) + { +@@ -182,27 +166,22 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_CacheOwnerDelegation", result ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, hSigningKey); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Testsuite_Transport_Final", result ); +- goto done; + } + else + { + print_success( function, result ); + } +- +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ + if (hFamily != NULL_HDELFAMILY) + Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, hSigningKey); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", result); ++ } + Tspi_Context_Close( hContext ); +- ++ print_end_test( function ); + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_CacheOwnerDelegation-trans03.c b/tcg/transport/Tspi_TPM_Delegate_CacheOwnerDelegation-trans03.c +index 0585386..b84fd55 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_CacheOwnerDelegation-trans03.c ++++ b/tcg/transport/Tspi_TPM_Delegate_CacheOwnerDelegation-trans03.c +@@ -89,7 +89,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", result ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -100,18 +100,18 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); ++ result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; ++ print_error( "Tspi_TPM_Delegate_AddFamily", result ); ++ goto done_trans; + } + +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); ++ result = Tspi_SetAttribUint32(hFamily, TSS_TSPATTRIB_DELFAMILY_STATE, ++ TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED, TRUE); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_Policy_SetSecret", result ); ++ print_error( "Tspi_SetAttribUint32", result ); + goto done; + } + +@@ -154,21 +154,6 @@ main_v1_2( char version ) + goto done; + } + +- result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_TPM_Delegate_AddFamily", result ); +- goto done; +- } +- +- result = Tspi_SetAttribUint32(hFamily, TSS_TSPATTRIB_DELFAMILY_STATE, +- TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED, TRUE); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_SetAttribUint32", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_CreateDelegation(hTPM, 'b', 0, NULL_HPCRS, hFamily, hDelegation); + if ( result != TSS_SUCCESS ) + { +@@ -182,27 +167,23 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_CacheOwnerDelegation", result ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, 0); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Testsuite_Transport_Final", result ); +- goto done; + } + else + { + print_success( function, result ); + } +- +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ + if (hFamily != NULL_HDELFAMILY) + Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); +- Tspi_Context_Close( hContext ); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, 0); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", result); ++ } + ++ Tspi_Context_Close( hContext ); ++ print_end_test( function ); + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_CreateKeyDelegation-trans01.c b/tcg/transport/Tspi_TPM_Delegate_CreateKeyDelegation-trans01.c +index 66708e2..51a59c2 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_CreateKeyDelegation-trans01.c ++++ b/tcg/transport/Tspi_TPM_Delegate_CreateKeyDelegation-trans01.c +@@ -89,7 +89,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, FALSE, &hWrappingKey, +@@ -99,19 +99,12 @@ main_v1_2( char version ) + Tspi_Context_Close(hContext); + exit(result); + } +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } + +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); ++ result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; ++ print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); ++ goto done_trans; + } + + result = create_load_key(hContext, TSS_KEY_TYPE_STORAGE | TSS_KEY_AUTHORIZATION, hSRK, &hKey); +@@ -160,38 +153,27 @@ main_v1_2( char version ) + goto done; + } + +- result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_CreateDelegation(hKey, 'b', 0, NULL_HPCRS, hFamily, hDelegation); + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_CreateDelegation", (result) ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, hSigningKey); +- if ( result != TSS_SUCCESS ) +- { +- print_error( function, (result) ); +- goto done; + } + else + { + print_success( function, result ); + } +- +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, hSigningKey); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", result); ++ } ++ + Tspi_Context_Close( hContext ); ++ print_end_test( function ); + + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_CreateKeyDelegation-trans02.c b/tcg/transport/Tspi_TPM_Delegate_CreateKeyDelegation-trans02.c +index 42b5709..8263422 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_CreateKeyDelegation-trans02.c ++++ b/tcg/transport/Tspi_TPM_Delegate_CreateKeyDelegation-trans02.c +@@ -89,7 +89,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -100,19 +100,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); ++ result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; ++ print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); ++ goto done_trans; + } + + result = create_load_key(hContext, TSS_KEY_TYPE_STORAGE | TSS_KEY_AUTHORIZATION, hSRK, &hKey); +@@ -161,38 +153,27 @@ main_v1_2( char version ) + goto done; + } + +- result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_CreateDelegation(hKey, 'b', 0, NULL_HPCRS, hFamily, hDelegation); + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_CreateDelegation", (result) ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, hSigningKey); +- if ( result != TSS_SUCCESS ) +- { +- print_error( function, (result) ); +- goto done; + } + else + { + print_success( function, result ); + } +- +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, hSigningKey); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", result); ++ } ++ + Tspi_Context_Close( hContext ); ++ print_end_test( function ); + + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_CreateKeyDelegation-trans03.c b/tcg/transport/Tspi_TPM_Delegate_CreateKeyDelegation-trans03.c +index bdfa2f2..1a139e0 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_CreateKeyDelegation-trans03.c ++++ b/tcg/transport/Tspi_TPM_Delegate_CreateKeyDelegation-trans03.c +@@ -75,7 +75,7 @@ main_v1_2( char version ) + { + char * function = "Tspi_TPM_Delegate_CreateKeyDelegation-trans03"; + TSS_HCONTEXT hContext; +- TSS_HKEY hSRK, hWrappingKey; ++ TSS_HKEY hSRK, hSigningKey, hWrappingKey; + TSS_HTPM hTPM; + TSS_HPOLICY hTPMPolicy; + TSS_HKEY hKey; +@@ -89,7 +89,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -100,19 +100,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); ++ result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; ++ print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); ++ goto done_trans; + } + + result = create_load_key(hContext, TSS_KEY_TYPE_STORAGE | TSS_KEY_AUTHORIZATION, hSRK, &hKey); +@@ -161,38 +153,27 @@ main_v1_2( char version ) + goto done; + } + +- result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_CreateDelegation(hKey, 'b', 0, NULL_HPCRS, hFamily, hDelegation); + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_CreateDelegation", (result) ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, 0); +- if ( result != TSS_SUCCESS ) +- { +- print_error( function, (result) ); +- goto done; + } + else + { + print_success( function, result ); + } +- +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, NULL); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", result); ++ } ++ + Tspi_Context_Close( hContext ); ++ print_end_test( function ); + + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_CreateOwnerDelegation-trans01.c b/tcg/transport/Tspi_TPM_Delegate_CreateOwnerDelegation-trans01.c +index e8e225e..e714e13 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_CreateOwnerDelegation-trans01.c ++++ b/tcg/transport/Tspi_TPM_Delegate_CreateOwnerDelegation-trans01.c +@@ -88,7 +88,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, FALSE, &hWrappingKey, +@@ -98,20 +98,6 @@ main_v1_2( char version ) + Tspi_Context_Close(hContext); + exit(result); + } +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } + + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hDelegation); + if ( result != TSS_SUCCESS ) +@@ -163,26 +149,22 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_CreateDelegation", (result) ); +- goto done; ++ } ++ else ++ { ++ print_success( function, result ); + } + ++ /* Invalidate the family to avoid resource exhaustion */ ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++done: + result = Testsuite_Transport_Final(hContext, hSigningKey); + if ( result != TSS_SUCCESS ) + { +- print_error( function, (result) ); +- goto done; +- } +- else +- { +- print_success( function, result ); ++ print_error( "Testsuite_Transport_Final", (result) ); + } + + print_end_test( function ); +-done: +- /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); + + exit( result ); +diff --git a/tcg/transport/Tspi_TPM_Delegate_CreateOwnerDelegation-trans02.c b/tcg/transport/Tspi_TPM_Delegate_CreateOwnerDelegation-trans02.c +index d372cb5..66a75ec 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_CreateOwnerDelegation-trans02.c ++++ b/tcg/transport/Tspi_TPM_Delegate_CreateOwnerDelegation-trans02.c +@@ -88,7 +88,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -98,20 +98,6 @@ main_v1_2( char version ) + Tspi_Context_Close(hContext); + exit(result); + } +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } + + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hDelegation); + if ( result != TSS_SUCCESS ) +@@ -163,26 +149,22 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_CreateDelegation", (result) ); +- goto done; ++ } ++ else ++ { ++ print_success( function, result ); + } + ++ /* Invalidate the family to avoid resource exhaustion */ ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++done: + result = Testsuite_Transport_Final(hContext, hSigningKey); + if ( result != TSS_SUCCESS ) + { +- print_error( function, (result) ); +- goto done; +- } +- else +- { +- print_success( function, result ); ++ print_error( "Testsuite_Transport_Final", (result) ); + } + + print_end_test( function ); +-done: +- /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); + + exit( result ); +diff --git a/tcg/transport/Tspi_TPM_Delegate_CreateOwnerDelegation-trans03.c b/tcg/transport/Tspi_TPM_Delegate_CreateOwnerDelegation-trans03.c +index 18246de..89eca65 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_CreateOwnerDelegation-trans03.c ++++ b/tcg/transport/Tspi_TPM_Delegate_CreateOwnerDelegation-trans03.c +@@ -75,7 +75,7 @@ main_v1_2( char version ) + { + char * function = "Tspi_TPM_Delegate_CreateOwnerDelegation-trans03"; + TSS_HCONTEXT hContext; +- TSS_HKEY hSRK, hWrappingKey; ++ TSS_HKEY hSRK, hSigningKey, hWrappingKey; + TSS_HTPM hTPM; + TSS_HPOLICY hTPMPolicy; + TSS_HPOLICY hDelegation = NULL_HPOLICY; +@@ -88,7 +88,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -98,20 +98,6 @@ main_v1_2( char version ) + Tspi_Context_Close(hContext); + exit(result); + } +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } + + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hDelegation); + if ( result != TSS_SUCCESS ) +@@ -163,26 +149,22 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_CreateDelegation", (result) ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, 0); +- if ( result != TSS_SUCCESS ) +- { +- print_error( function, (result) ); +- goto done; + } + else + { + print_success( function, result ); + } + +- print_end_test( function ); +-done: + /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++done: ++ result = Testsuite_Transport_Final(hContext, NULL); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", (result) ); ++ } ++ ++ print_end_test( function ); + Tspi_Context_Close( hContext ); + + exit( result ); +diff --git a/tcg/transport/Tspi_TPM_Delegate_GetFamily-trans01.c b/tcg/transport/Tspi_TPM_Delegate_GetFamily-trans01.c +index f5a376d..8c190a6 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_GetFamily-trans01.c ++++ b/tcg/transport/Tspi_TPM_Delegate_GetFamily-trans01.c +@@ -88,7 +88,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, FALSE, &hWrappingKey, +@@ -99,27 +99,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; +- } ++ } else { + + result = Tspi_GetAttribUint32(hFamily, TSS_TSPATTRIB_DELFAMILY_INFO, + TSS_TSPATTRIB_DELFAMILYINFO_FAMILYID, &familyID); +@@ -151,7 +135,6 @@ main_v1_2( char version ) + goto done; + } + +- result = Testsuite_Transport_Final(hContext, hSigningKey); + if ( result != TSS_SUCCESS ) + { + if( !(checkNonAPI(result)) ) +@@ -178,13 +161,13 @@ main_v1_2( char version ) + } + } + +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++ } ++ result = Testsuite_Transport_Final(hContext, hSigningKey); + Tspi_Context_Close( hContext ); + ++ print_end_test( function ); + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_GetFamily-trans02.c b/tcg/transport/Tspi_TPM_Delegate_GetFamily-trans02.c +index 2249727..ddd1af0 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_GetFamily-trans02.c ++++ b/tcg/transport/Tspi_TPM_Delegate_GetFamily-trans02.c +@@ -88,7 +88,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -99,27 +99,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; +- } ++ } else { + + result = Tspi_GetAttribUint32(hFamily, TSS_TSPATTRIB_DELFAMILY_INFO, + TSS_TSPATTRIB_DELFAMILYINFO_FAMILYID, &familyID); +@@ -151,7 +135,6 @@ main_v1_2( char version ) + goto done; + } + +- result = Testsuite_Transport_Final(hContext, hSigningKey); + if ( result != TSS_SUCCESS ) + { + if( !(checkNonAPI(result)) ) +@@ -178,13 +161,13 @@ main_v1_2( char version ) + } + } + +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++ } ++ result = Testsuite_Transport_Final(hContext, hSigningKey); + Tspi_Context_Close( hContext ); + ++ print_end_test( function ); + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_GetFamily-trans03.c b/tcg/transport/Tspi_TPM_Delegate_GetFamily-trans03.c +index d45c5f2..aa07e69 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_GetFamily-trans03.c ++++ b/tcg/transport/Tspi_TPM_Delegate_GetFamily-trans03.c +@@ -88,7 +88,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -99,27 +99,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; +- } ++ } else { + + result = Tspi_GetAttribUint32(hFamily, TSS_TSPATTRIB_DELFAMILY_INFO, + TSS_TSPATTRIB_DELFAMILYINFO_FAMILYID, &familyID); +@@ -147,13 +131,6 @@ main_v1_2( char version ) + TSS_TSPATTRIB_DELFAMILYINFO_FAMILYID, &returnedID); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_GetAttribUint32", (result) ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, 0); +- if ( result != TSS_SUCCESS ) +- { + if( !(checkNonAPI(result)) ) + { + print_error( "Tspi_TPM_GetAttribUint32", result ); +@@ -162,7 +139,6 @@ main_v1_2( char version ) + { + print_error_nonapi( "Tspi_TPM_GetAttribUint32", result ); + } +- goto done; + } + else + { +@@ -170,7 +146,6 @@ main_v1_2( char version ) + { + print_error( "Tspi_GetAttribUint32: Family IDs do not match", TSS_E_FAIL ); + result = 1; +- goto done; + } + else + { +@@ -178,13 +153,13 @@ main_v1_2( char version ) + } + } + +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++ } ++ result = Testsuite_Transport_Final(hContext, 0); + Tspi_Context_Close( hContext ); + ++ print_end_test( function ); + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_InvalidateFamily-trans01.c b/tcg/transport/Tspi_TPM_Delegate_InvalidateFamily-trans01.c +index e9ccac7..7406c3d 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_InvalidateFamily-trans01.c ++++ b/tcg/transport/Tspi_TPM_Delegate_InvalidateFamily-trans01.c +@@ -87,7 +87,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, FALSE, &hWrappingKey, +@@ -98,21 +98,6 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +@@ -124,26 +109,20 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_InvalidateFamily", (result) ); +- goto done; + } +- ++ else ++ { ++ print_success( function, result ); ++ } ++done: + result = Testsuite_Transport_Final(hContext, hSigningKey); + if ( result != TSS_SUCCESS ) + { + print_error( "Testsuite_Transport_Final", (result) ); +- goto done; +- } +- else +- { +- print_success( function, result ); + } + +- print_end_test( function ); +-done: +- /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); +- exit( 0 ); ++ print_end_test( function ); ++ ++ exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_InvalidateFamily-trans02.c b/tcg/transport/Tspi_TPM_Delegate_InvalidateFamily-trans02.c +index 146c735..af5fd66 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_InvalidateFamily-trans02.c ++++ b/tcg/transport/Tspi_TPM_Delegate_InvalidateFamily-trans02.c +@@ -87,7 +87,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -98,21 +98,6 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +@@ -124,26 +109,20 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_InvalidateFamily", (result) ); +- goto done; + } +- ++ else ++ { ++ print_success( function, result ); ++ } ++done: + result = Testsuite_Transport_Final(hContext, hSigningKey); + if ( result != TSS_SUCCESS ) + { + print_error( "Testsuite_Transport_Final", (result) ); +- goto done; +- } +- else +- { +- print_success( function, result ); + } + +- print_end_test( function ); +-done: +- /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); +- exit( 0 ); ++ print_end_test( function ); ++ ++ exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_InvalidateFamily-trans03.c b/tcg/transport/Tspi_TPM_Delegate_InvalidateFamily-trans03.c +index 510c197..b09a717 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_InvalidateFamily-trans03.c ++++ b/tcg/transport/Tspi_TPM_Delegate_InvalidateFamily-trans03.c +@@ -75,7 +75,7 @@ main_v1_2( char version ) + { + char * function = "Tspi_TPM_Delegate_InvalidateFamily-trans03"; + TSS_HCONTEXT hContext; +- TSS_HKEY hSRK, hWrappingKey; ++ TSS_HKEY hSRK, hSigningKey, hWrappingKey; + TSS_HTPM hTPM; + TSS_HPOLICY hTPMPolicy; + TSS_HDELFAMILY hFamily = NULL_HDELFAMILY; +@@ -87,7 +87,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -98,21 +98,6 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +@@ -124,26 +109,20 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_InvalidateFamily", (result) ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, 0); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Testsuite_Transport_Final", (result) ); +- goto done; + } + else + { + print_success( function, result ); + } +- +- print_end_test( function ); + done: +- /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++ result = Testsuite_Transport_Final(hContext, NULL); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", (result) ); ++ } ++ + Tspi_Context_Close( hContext ); +- exit( 0 ); ++ print_end_test( function ); ++ ++ exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_ReadTables-trans01.c b/tcg/transport/Tspi_TPM_Delegate_ReadTables-trans01.c +index 594beba..a64445e 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_ReadTables-trans01.c ++++ b/tcg/transport/Tspi_TPM_Delegate_ReadTables-trans01.c +@@ -90,7 +90,6 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); + exit( result ); + } +@@ -103,26 +102,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; ++ goto done_trans; + } + + result = Tspi_TPM_Delegate_ReadTables(hContext, &familyTableSize, &familyTable, +@@ -132,40 +116,32 @@ main_v1_2( char version ) + print_error( "Tspi_TPM_Delegate_ReadTables", (result) ); + goto done; + } ++ else ++ { ++ print_success( function, result ); ++ } + +- result = Testsuite_Transport_Final(hContext, hSigningKey); +- if ( result != TSS_SUCCESS ) ++ result = Tspi_Context_FreeMemory(hContext, (BYTE *)familyTable); ++ if (result != TSS_SUCCESS) + { +- print_error( function, (result) ); +- goto done; ++ print_error( "Tspi_Context_FreeMemory", result ); + } +- else ++ result = Tspi_Context_FreeMemory(hContext, (BYTE *)delegateTable); ++ if (result != TSS_SUCCESS) + { +- result = Tspi_Context_FreeMemory(hContext, (BYTE *)familyTable); +- if (result != TSS_SUCCESS) +- { +- print_error( "Tspi_Context_FreeMemory", result ); +- goto done; +- } +- +- result = Tspi_Context_FreeMemory(hContext, (BYTE *)delegateTable); +- if (result != TSS_SUCCESS) +- { +- print_error( "Tspi_Context_FreeMemory", result ); +- goto done; +- } +- else +- { +- print_success( function, result ); +- } ++ print_error( "Tspi_Context_FreeMemory", result ); + } +- +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, hSigningKey); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( function, (result) ); ++ } + Tspi_Context_Close( hContext ); +- exit( 0 ); ++ print_end_test( function ); ++ ++ exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_ReadTables-trans02.c b/tcg/transport/Tspi_TPM_Delegate_ReadTables-trans02.c +index 25b6010..7a72693 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_ReadTables-trans02.c ++++ b/tcg/transport/Tspi_TPM_Delegate_ReadTables-trans02.c +@@ -90,7 +90,6 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); + exit( result ); + } +@@ -103,26 +102,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; ++ goto done_trans; + } + + result = Tspi_TPM_Delegate_ReadTables(hContext, &familyTableSize, &familyTable, +@@ -132,40 +116,32 @@ main_v1_2( char version ) + print_error( "Tspi_TPM_Delegate_ReadTables", (result) ); + goto done; + } ++ else ++ { ++ print_success( function, result ); ++ } + +- result = Testsuite_Transport_Final(hContext, hSigningKey); +- if ( result != TSS_SUCCESS ) ++ result = Tspi_Context_FreeMemory(hContext, (BYTE *)familyTable); ++ if (result != TSS_SUCCESS) + { +- print_error( "Testsuite_Transport_Final", (result) ); +- goto done; ++ print_error( "Tspi_Context_FreeMemory", result ); + } +- else ++ result = Tspi_Context_FreeMemory(hContext, (BYTE *)delegateTable); ++ if (result != TSS_SUCCESS) + { +- result = Tspi_Context_FreeMemory(hContext, (BYTE *)familyTable); +- if (result != TSS_SUCCESS) +- { +- print_error( "Tspi_Context_FreeMemory", result ); +- goto done; +- } +- +- result = Tspi_Context_FreeMemory(hContext, (BYTE *)delegateTable); +- if (result != TSS_SUCCESS) +- { +- print_error( "Tspi_Context_FreeMemory", result ); +- goto done; +- } +- else +- { +- print_success( function, result ); +- } ++ print_error( "Tspi_Context_FreeMemory", result ); + } +- +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, hSigningKey); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( function, (result) ); ++ } + Tspi_Context_Close( hContext ); +- exit( 0 ); ++ print_end_test( function ); ++ ++ exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_ReadTables-trans03.c b/tcg/transport/Tspi_TPM_Delegate_ReadTables-trans03.c +index 4d3c355..678617b 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_ReadTables-trans03.c ++++ b/tcg/transport/Tspi_TPM_Delegate_ReadTables-trans03.c +@@ -75,7 +75,7 @@ main_v1_2( char version ) + { + char * function = "Tspi_TPM_Delegate_ReadTables-trans03"; + TSS_HCONTEXT hContext; +- TSS_HKEY hSRK, hWrappingKey; ++ TSS_HKEY hSRK, hSigningKey, hWrappingKey; + TSS_HTPM hTPM; + TSS_HPOLICY hTPMPolicy; + TSS_HDELFAMILY hFamily = NULL_HDELFAMILY; +@@ -90,7 +90,6 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); + exit( result ); + } +@@ -103,26 +102,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; ++ goto done_trans; + } + + result = Tspi_TPM_Delegate_ReadTables(hContext, &familyTableSize, &familyTable, +@@ -132,40 +116,32 @@ main_v1_2( char version ) + print_error( "Tspi_TPM_Delegate_ReadTables", (result) ); + goto done; + } ++ else ++ { ++ print_success( function, result ); ++ } + +- result = Testsuite_Transport_Final(hContext, 0); +- if ( result != TSS_SUCCESS ) ++ result = Tspi_Context_FreeMemory(hContext, (BYTE *)familyTable); ++ if (result != TSS_SUCCESS) + { +- print_error( "Testsuite_Transport_Final", (result) ); +- goto done; ++ print_error( "Tspi_Context_FreeMemory", result ); + } +- else ++ result = Tspi_Context_FreeMemory(hContext, (BYTE *)delegateTable); ++ if (result != TSS_SUCCESS) + { +- result = Tspi_Context_FreeMemory(hContext, (BYTE *)familyTable); +- if (result != TSS_SUCCESS) +- { +- print_error( "Tspi_Context_FreeMemory", result ); +- goto done; +- } +- +- result = Tspi_Context_FreeMemory(hContext, (BYTE *)delegateTable); +- if (result != TSS_SUCCESS) +- { +- print_error( "Tspi_Context_FreeMemory", result ); +- goto done; +- } +- else +- { +- print_success( function, result ); +- } ++ print_error( "Tspi_Context_FreeMemory", result ); + } +- +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ +- if (hFamily != NULL_HDELFAMILY) +- Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++ Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, NULL); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( function, (result) ); ++ } + Tspi_Context_Close( hContext ); +- exit( 0 ); ++ print_end_test( function ); ++ ++ exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_UpdateVerificationCount-trans01.c b/tcg/transport/Tspi_TPM_Delegate_UpdateVerificationCount-trans01.c +index 4bb015c..b3e1339 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_UpdateVerificationCount-trans01.c ++++ b/tcg/transport/Tspi_TPM_Delegate_UpdateVerificationCount-trans01.c +@@ -92,7 +92,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, FALSE, &hWrappingKey, +@@ -103,19 +103,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); ++ result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; ++ print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); ++ goto done_trans; + } + + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hDelegation1); +@@ -157,13 +149,6 @@ main_v1_2( char version ) + goto done; + } + +- result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_CreateDelegation(hTPM, 'b', 0, NULL_HPCRS, hFamily, hDelegation1); + if ( result != TSS_SUCCESS ) + { +@@ -222,27 +207,24 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_UpdateVerificationCount", (result) ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, hSigningKey); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Testsuite_Transport_Final", (result) ); +- goto done; + } + else + { + print_success( function, result ); + } + +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ + if (hFamily != NULL_HDELFAMILY) + Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, hSigningKey); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", (result) ); ++ } + Tspi_Context_Close( hContext ); ++ print_end_test( function ); + + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_UpdateVerificationCount-trans02.c b/tcg/transport/Tspi_TPM_Delegate_UpdateVerificationCount-trans02.c +index 5e9db88..119d023 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_UpdateVerificationCount-trans02.c ++++ b/tcg/transport/Tspi_TPM_Delegate_UpdateVerificationCount-trans02.c +@@ -92,7 +92,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -103,19 +103,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); ++ result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; ++ print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); ++ goto done_trans; + } + + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hDelegation1); +@@ -157,13 +149,6 @@ main_v1_2( char version ) + goto done; + } + +- result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_CreateDelegation(hTPM, 'b', 0, NULL_HPCRS, hFamily, hDelegation1); + if ( result != TSS_SUCCESS ) + { +@@ -222,27 +207,24 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_UpdateVerificationCount", (result) ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, hSigningKey); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Testsuite_Transport_Final", (result) ); +- goto done; + } + else + { + print_success( function, result ); + } + +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ + if (hFamily != NULL_HDELFAMILY) + Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, hSigningKey); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", (result) ); ++ } + Tspi_Context_Close( hContext ); ++ print_end_test( function ); + + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_UpdateVerificationCount-trans03.c b/tcg/transport/Tspi_TPM_Delegate_UpdateVerificationCount-trans03.c +index 140c896..87e9f9f 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_UpdateVerificationCount-trans03.c ++++ b/tcg/transport/Tspi_TPM_Delegate_UpdateVerificationCount-trans03.c +@@ -78,7 +78,7 @@ main_v1_2( char version ) + { + char * function = "Tspi_TPM_Delegate_UpdateVerificationCount-trans03"; + TSS_HCONTEXT hContext; +- TSS_HKEY hSRK, hWrappingKey; ++ TSS_HKEY hSRK, hSigningKey, hWrappingKey; + TSS_HTPM hTPM; + TSS_HPOLICY hTPMPolicy; + TSS_HPOLICY hDelegation1 = NULL_HPOLICY; +@@ -92,7 +92,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -103,19 +103,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); ++ result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; ++ print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); ++ goto done_trans; + } + + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hDelegation1); +@@ -157,13 +149,6 @@ main_v1_2( char version ) + goto done; + } + +- result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; +- } +- + result = Tspi_TPM_Delegate_CreateDelegation(hTPM, 'b', 0, NULL_HPCRS, hFamily, hDelegation1); + if ( result != TSS_SUCCESS ) + { +@@ -222,27 +207,24 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "Tspi_TPM_Delegate_UpdateVerificationCount", (result) ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, 0); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Testsuite_Transport_Final", (result) ); +- goto done; + } + else + { + print_success( function, result ); + } + +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ + if (hFamily != NULL_HDELFAMILY) + Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, NULL); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", (result) ); ++ } + Tspi_Context_Close( hContext ); ++ print_end_test( function ); + + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_VerifyDelegation-trans01.c b/tcg/transport/Tspi_TPM_Delegate_VerifyDelegation-trans01.c +index cd18449..c3789dd 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_VerifyDelegation-trans01.c ++++ b/tcg/transport/Tspi_TPM_Delegate_VerifyDelegation-trans01.c +@@ -92,7 +92,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, FALSE, &hWrappingKey, +@@ -103,19 +103,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); ++ result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; ++ print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); ++ goto done_trans; + } + + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hDelegation1); +@@ -157,13 +149,6 @@ main_v1_2( char version ) + goto done; + } + +- result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; +- } +- + result = Tspi_SetAttribUint32(hFamily, TSS_TSPATTRIB_DELFAMILY_STATE, + TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED, TRUE); + if ( result != TSS_SUCCESS ) +@@ -238,27 +223,23 @@ main_v1_2( char version ) + if ( TSS_ERROR_CODE( result ) != TPM_E_FAMILYCOUNT ) + { + print_error( "Tspi_TPM_Delegate_VerifyDelegation", (result) ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, hSigningKey); +- if ( result == TSS_SUCCESS ) +- { +- print_error( "Testsuite_Transport_Final", (result) ); +- goto done; + } + else + { + print_success( function, result ); + } +- +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ + if (hFamily != NULL_HDELFAMILY) + Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, hSigningKey); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", (result) ); ++ } + Tspi_Context_Close( hContext ); ++ print_end_test( function ); + + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_VerifyDelegation-trans02.c b/tcg/transport/Tspi_TPM_Delegate_VerifyDelegation-trans02.c +index 50aa5d7..ad2cae7 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_VerifyDelegation-trans02.c ++++ b/tcg/transport/Tspi_TPM_Delegate_VerifyDelegation-trans02.c +@@ -92,7 +92,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -103,19 +103,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); ++ result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; ++ print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); ++ goto done_trans; + } + + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hDelegation1); +@@ -157,13 +149,6 @@ main_v1_2( char version ) + goto done; + } + +- result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; +- } +- + result = Tspi_SetAttribUint32(hFamily, TSS_TSPATTRIB_DELFAMILY_STATE, + TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED, TRUE); + if ( result != TSS_SUCCESS ) +@@ -183,7 +168,7 @@ main_v1_2( char version ) + result = Tspi_TPM_Delegate_VerifyDelegation(hDelegation1); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_TPM_Delegate_VerifyDelegation", (result) ); ++ print_error( function, (result) ); + goto done; + } + +@@ -238,27 +223,23 @@ main_v1_2( char version ) + if ( TSS_ERROR_CODE( result ) != TPM_E_FAMILYCOUNT ) + { + print_error( "Tspi_TPM_Delegate_VerifyDelegation", (result) ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, hSigningKey); +- if ( result == TSS_SUCCESS ) +- { +- print_error( function, (result) ); +- goto done; + } + else + { + print_success( function, result ); + } +- +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ + if (hFamily != NULL_HDELFAMILY) + Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, hSigningKey); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", (result) ); ++ } + Tspi_Context_Close( hContext ); ++ print_end_test( function ); + + exit( result ); + } +diff --git a/tcg/transport/Tspi_TPM_Delegate_VerifyDelegation-trans03.c b/tcg/transport/Tspi_TPM_Delegate_VerifyDelegation-trans03.c +index 33159a2..2cdabef 100644 +--- a/tcg/transport/Tspi_TPM_Delegate_VerifyDelegation-trans03.c ++++ b/tcg/transport/Tspi_TPM_Delegate_VerifyDelegation-trans03.c +@@ -78,7 +78,7 @@ main_v1_2( char version ) + { + char * function = "Tspi_TPM_Delegate_VerifyDelegation-trans03"; + TSS_HCONTEXT hContext; +- TSS_HKEY hSRK, hWrappingKey; ++ TSS_HKEY hSRK, hSigningKey, hWrappingKey; + TSS_HTPM hTPM; + TSS_HPOLICY hTPMPolicy; + TSS_HPOLICY hDelegation1 = NULL_HPOLICY; +@@ -92,7 +92,7 @@ main_v1_2( char version ) + if ( result != TSS_SUCCESS ) + { + print_error( "connect_load_all", (result) ); +- goto done; ++ exit(result); + } + + result = Testsuite_Transport_Init(hContext, hSRK, hTPM, TRUE, TRUE, &hWrappingKey, +@@ -103,19 +103,11 @@ main_v1_2( char version ) + exit(result); + } + +- result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hTPMPolicy ); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_GetPolicyObject", result ); +- goto done; +- } +- +- result = Tspi_Policy_SetSecret( hTPMPolicy, TESTSUITE_OWNER_SECRET_MODE, +- TESTSUITE_OWNER_SECRET_LEN, TESTSUITE_OWNER_SECRET ); ++ result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_Policy_SetSecret", result ); +- goto done; ++ print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); ++ goto done_trans; + } + + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hDelegation1); +@@ -157,13 +149,6 @@ main_v1_2( char version ) + goto done; + } + +- result = Tspi_TPM_Delegate_AddFamily(hTPM, 'a', &hFamily); +- if ( result != TSS_SUCCESS ) +- { +- print_error( "Tspi_TPM_Delegate_AddFamily", (result) ); +- goto done; +- } +- + result = Tspi_SetAttribUint32(hFamily, TSS_TSPATTRIB_DELFAMILY_STATE, + TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED, TRUE); + if ( result != TSS_SUCCESS ) +@@ -183,7 +168,7 @@ main_v1_2( char version ) + result = Tspi_TPM_Delegate_VerifyDelegation(hDelegation1); + if ( result != TSS_SUCCESS ) + { +- print_error( "Tspi_TPM_Delegate_VerifyDelegation", (result) ); ++ print_error( function, (result) ); + goto done; + } + +@@ -238,27 +223,23 @@ main_v1_2( char version ) + if ( TSS_ERROR_CODE( result ) != TPM_E_FAMILYCOUNT ) + { + print_error( "Tspi_TPM_Delegate_VerifyDelegation", (result) ); +- goto done; +- } +- +- result = Testsuite_Transport_Final(hContext, 0); +- if ( result == TSS_SUCCESS ) +- { +- print_error( function, (result) ); +- goto done; + } + else + { + print_success( function, result ); + } +- +- print_end_test( function ); + done: + /* Invalidate the family to avoid resource exhaustion */ + if (hFamily != NULL_HDELFAMILY) + Tspi_TPM_Delegate_InvalidateFamily(hTPM, hFamily); +- Tspi_Context_FreeMemory( hContext, NULL ); ++done_trans: ++ result = Testsuite_Transport_Final(hContext, NULL); ++ if ( result != TSS_SUCCESS ) ++ { ++ print_error( "Testsuite_Transport_Final", (result) ); ++ } + Tspi_Context_Close( hContext ); ++ print_end_test( function ); + + exit( result ); + } diff --git a/meta-tpm/recipes-tpm/tss-testsuite/tss-testsuite_0.3.bb b/meta-tpm/recipes-tpm/tss-testsuite/tss-testsuite_0.3.bb new file mode 100644 index 0000000..81b8542 --- /dev/null +++ b/meta-tpm/recipes-tpm/tss-testsuite/tss-testsuite_0.3.bb @@ -0,0 +1,58 @@ +SUMMARY = "Testcases to exercise the TSS stack/TSS API" +HOMEPAGE = "${SOURCEFORGE_MIRROR}/projects/trousers/files" +SECTION = "console/utils" +DESCRIPTION = "\ + These are the testcases that exercise the TSS stack. They can be run \ + either through the the LTP framework or standalone. The testcases \ + have been tested against the 20040304 version of LTP. \ + \ + Please do not execute these testcases on a machine where you are actively \ + using the TPM. \ +" + +LICENSE = "GPLv2" +LIC_FILES_CHKSUM = "file://LICENSE;md5=751419260aa954499f7abaabaa882bbe" + +SRC_URI = "\ + https://sourceforge.net/projects/trousers/files/TSS%20API%20test%20suite/0.3/testsuite-${PV}.tar.gz; \ + file://fix-missing-LDFLAGS-in-compile-command-line.patch; \ + file://fix-failure-of-.so-LD-with-cortexa8t-neon-wrswrap-linux.patch; \ + file://fix-hardcode-path-in-tsstests.sh.patch \ + file://testsuite-transport-init.patch \ + file://Tspi_TPM_LoadMaintenancePubKey01.patch \ + file://transport-Tspi_TPM_Delegate.patch \ + file://common_c_no_des.patch \ + file://Tspi_TPM_CreateIdentity_no_des.patch \ + file://Tspi_TPM_CreateIdentityWithCallbacks_no_des.patch \ +" +SRC_URI[md5sum] = "1ebd0e7783178abdfc8c40bc8cb8875f" +SRC_URI[sha256sum] = "5382539fa69cf480d44f924e54a0f2718134b26baa29137ba351a0eef4873c98" + +DEPENDS = "trousers" +RDEPENDS_${PN} = "tpm-tools openssl bash" + +CFLAGS += "-DOPENSSL_NO_DES" +EXTRA_OEMAKE = " -C tcg 'CC=${CC}' " +LDFLAGS += "-L${STAGING_LIBDIR} -lcrypto -lpthread" + +S = "${WORKDIR}/testsuite-${PV}" + +do_configure_prepend () { + cp ${S}/tcg/Makefile ${S} + cp ${S}/tcg/init/makefile ${S}/tcg/init/Makefile + # remove test case about DES + rm -rf ${S}/tcg/context/Tspi_Context_GetCapability13.c +} + +testsuite_SUBDIRS = "cmk context data delegation hash highlevel init key nv pcrcomposite policy tpm transport tspi" +do_install () { + install -d ${D}/opt/tss-testsuite/tcg + for i in ${testsuite_SUBDIRS}; do \ + echo "Installing ${i}"; \ + cp -rf tcg/${i} ${D}/opt/tss-testsuite/tcg/; \ + done; + install -m 0755 tsstests.sh ${D}/opt/tss-testsuite +} + +FILES_${PN} += "/opt/*" +FILES_${PN}-dbg += "/opt/tss-testsuite/tcg/*/.debug /opt/tss-testsuite/tcg/*/*/.debug" diff --git a/meta-tpm2/README.md b/meta-tpm2/README.md new file mode 100644 index 0000000..fbad353 --- /dev/null +++ b/meta-tpm2/README.md @@ -0,0 +1,21 @@ +### TPM 2.0 +This feature enables Trusted Platform Module (TPM 2.0) support, including +kernel option changes to enable tpm drivers, and picking up TPM 2.0 packages. + +Trusted Platform Module (TPM 2.0) is a microcontroller that stores keys, +passwords, and digital certificates. A TPM 2.0 offers the capabilities as +part of the overall platform security requirements. + +### Clear TPM +For TPM 2.0, the following typical steps can be performed to get the TPM +ready for use: + +- Clear and enable TPM from the BIOS or set the security jumper on the board. +- Take TPM ownership, setting Owner/Endorsement/Lockout passwords if + necessary. These passwords are used for the authorization to certain + TPM 2.0 commands. +``` + # tpm2_takeownership -o -e -l +``` +Then, you can use the TPM for a specific need, such as key generation, +sealing encrypted data, etc. diff --git a/meta-tpm2/conf/layer.conf b/meta-tpm2/conf/layer.conf new file mode 100644 index 0000000..0b8656e --- /dev/null +++ b/meta-tpm2/conf/layer.conf @@ -0,0 +1,12 @@ +# We have a conf and classes directory, add to BBPATH +BBPATH .= ":${LAYERDIR}" + +# We have recipes-* directories, add to BBFILES +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ + ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "tpm2" +BBFILE_PATTERN_tpm2 = "^${LAYERDIR}/" +BBFILE_PRIORITY_tpm2 = "10" + +LAYERDEPENDS_tpm2 = "core" diff --git a/meta-tpm2/recipes-base/packagegroups/packagegroup-tpm2-initramfs.bb b/meta-tpm2/recipes-base/packagegroups/packagegroup-tpm2-initramfs.bb new file mode 100644 index 0000000..87c811a --- /dev/null +++ b/meta-tpm2/recipes-base/packagegroups/packagegroup-tpm2-initramfs.bb @@ -0,0 +1 @@ +include packagegroup-tpm2.inc diff --git a/meta-tpm2/recipes-base/packagegroups/packagegroup-tpm2.bb b/meta-tpm2/recipes-base/packagegroups/packagegroup-tpm2.bb new file mode 100644 index 0000000..b0dc843 --- /dev/null +++ b/meta-tpm2/recipes-base/packagegroups/packagegroup-tpm2.bb @@ -0,0 +1,11 @@ +include packagegroup-tpm2.inc + +RDEPENDS_${PN} += "\ + tpm2-abrmd \ + tpm2.0-tools \ + rng-tools \ +" + +RRECOMMENDS_${PN} += "\ + kernel-module-tpm-rng \ +" diff --git a/meta-tpm2/recipes-base/packagegroups/packagegroup-tpm2.inc b/meta-tpm2/recipes-base/packagegroups/packagegroup-tpm2.inc new file mode 100644 index 0000000..9ffca61 --- /dev/null +++ b/meta-tpm2/recipes-base/packagegroups/packagegroup-tpm2.inc @@ -0,0 +1,5 @@ +DESCRIPTION = "Packagegroup for TPM2 TCG TSS userspace and utilities." +LICENSE = "MIT" +PR = "r0" + +inherit packagegroup diff --git a/meta-tpm2/recipes-kernel/linux/linux-yocto-rt_4.%.bbappend b/meta-tpm2/recipes-kernel/linux/linux-yocto-rt_4.%.bbappend new file mode 100644 index 0000000..edaf7f3 --- /dev/null +++ b/meta-tpm2/recipes-kernel/linux/linux-yocto-rt_4.%.bbappend @@ -0,0 +1 @@ +include linux-yocto-tpm2.inc diff --git a/meta-tpm2/recipes-kernel/linux/linux-yocto-tpm2.inc b/meta-tpm2/recipes-kernel/linux/linux-yocto-tpm2.inc new file mode 100644 index 0000000..32456ca --- /dev/null +++ b/meta-tpm2/recipes-kernel/linux/linux-yocto-tpm2.inc @@ -0,0 +1,6 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/linux-yocto:" + +SRC_URI += " \ + ${@bb.utils.contains('DISTRO_FEATURES', 'tpm2', \ + 'file://tpm2.scc file://tpm2.cfg', '', d)} \ +" diff --git a/meta-tpm2/recipes-kernel/linux/linux-yocto/tpm2.cfg b/meta-tpm2/recipes-kernel/linux/linux-yocto/tpm2.cfg new file mode 100644 index 0000000..d175fb5 --- /dev/null +++ b/meta-tpm2/recipes-kernel/linux/linux-yocto/tpm2.cfg @@ -0,0 +1,16 @@ +.......................................................................... +. WARNING +. +. This file is a kernel configuration fragment, and not a full kernel +. configuration file. The final kernel configuration is made up of +. an assembly of processed fragments, each of which is designed to +. capture a specific part of the final configuration (e.g. platform +. configuration, feature configuration, and board specific hardware +. configuration). For more information on kernel configuration, please +. consult the product documentation. +. +.......................................................................... + +CONFIG_TCG_TPM=y +CONFIG_TCG_TIS=y +CONFIG_TCG_CRB=y diff --git a/meta-tpm2/recipes-kernel/linux/linux-yocto/tpm2.scc b/meta-tpm2/recipes-kernel/linux/linux-yocto/tpm2.scc new file mode 100644 index 0000000..b369daa --- /dev/null +++ b/meta-tpm2/recipes-kernel/linux/linux-yocto/tpm2.scc @@ -0,0 +1,4 @@ +define KFEATURE_DESCRIPTION "TPM 2.x enablement" + +kconf hardware tpm2.cfg + diff --git a/meta-tpm2/recipes-kernel/linux/linux-yocto_4.%.bbappend b/meta-tpm2/recipes-kernel/linux/linux-yocto_4.%.bbappend new file mode 100644 index 0000000..edaf7f3 --- /dev/null +++ b/meta-tpm2/recipes-kernel/linux/linux-yocto_4.%.bbappend @@ -0,0 +1 @@ +include linux-yocto-tpm2.inc diff --git a/meta-tpm2/recipes-tpm/tpm2-abrmd/files/Fix-build-failure-when-searching-tabrmd.h.patch b/meta-tpm2/recipes-tpm/tpm2-abrmd/files/Fix-build-failure-when-searching-tabrmd.h.patch new file mode 100644 index 0000000..24dc022 --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2-abrmd/files/Fix-build-failure-when-searching-tabrmd.h.patch @@ -0,0 +1,293 @@ +From 034e9cd7e539e1feda2fbe9a3646e28156856594 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Thu, 15 Jun 2017 10:21:02 +0800 +Subject: [PATCH] Fix build failure when searching tabrmd.h + +Signed-off-by: Lans Zhang +--- + Makefile.am | 2 +- + src/access-broker.c | 2 +- + src/include/tabrmd.h | 56 --------------------------- + src/include/tcti-tabrmd.h | 2 +- + src/include/tss2/tabrmd.h | 56 +++++++++++++++++++++++++++ + src/resource-manager.c | 2 +- + src/tabrmd-error.c | 2 +- + src/tabrmd.c | 2 +- + src/tcti-tabrmd.c | 2 +- + test/integration/hash-sequence.int.c | 2 +- + test/integration/password-authorization.int.c | 2 +- + test/integration/tcti-cancel.int.c | 2 +- + test/integration/tcti-set-locality.int.c | 2 +- + 13 files changed, 67 insertions(+), 67 deletions(-) + delete mode 100644 src/include/tabrmd.h + create mode 100644 src/include/tss2/tabrmd.h + +diff --git a/Makefile.am b/Makefile.am +index 5f88429..4733d4f 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -90,7 +90,7 @@ install-data-hook: + $(DESTDIR)$(mandir)/man3/tss2_tcti_tabrmd_init_full.3 + + tpm2_abrmddir = $(includedir)/tss2 +-tpm2_abrmd_HEADERS = $(srcdir)/src/include/tabrmd.h ++tpm2_abrmd_HEADERS = $(srcdir)/src/include/tss2/tabrmd.h + libtcti_tabrmddir = $(includedir)/tcti + libtcti_tabrmd_HEADERS = $(srcdir)/src/include/tcti-tabrmd.h + +diff --git a/src/access-broker.c b/src/access-broker.c +index d21113d..f357101 100644 +--- a/src/access-broker.c ++++ b/src/access-broker.c +@@ -28,7 +28,7 @@ + #include + #include + +-#include "tabrmd.h" ++#include + + #include "access-broker.h" + #include "tcti.h" +diff --git a/src/include/tabrmd.h b/src/include/tabrmd.h +deleted file mode 100644 +index 42d41a2..0000000 +--- a/src/include/tabrmd.h ++++ /dev/null +@@ -1,56 +0,0 @@ +-/* +- * Copyright (c) 2017, Intel Corporation +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * +- * 1. Redistributions of source code must retain the above copyright notice, +- * this list of conditions and the following disclaimer. +- * +- * 2. Redistributions in binary form must reproduce the above copyright notice, +- * this list of conditions and the following disclaimer in the documentation +- * and/or other materials provided with the distribution. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +- * THE POSSIBILITY OF SUCH DAMAGE. +- */ +-#ifndef TSS2_TABD_H +-#define TSS2_TABD_H +- +-#include +-#include +- +-#define TABRMD_DBUS_INTERFACE "com.intel.tss2.TctiTabrmd" +-#define TABRMD_DBUS_NAME_DEFAULT "com.intel.tss2.Tabrmd" +-#define TABRMD_DBUS_PATH "/com/intel/tss2/Tabrmd/Tcti" +-#define TABRMD_DBUS_METHOD_CREATE_CONNECTION "CreateConnection" +-#define TABRMD_DBUS_METHOD_CANCEL "Cancel" +-#define TABRMD_DBUS_TYPE_DEFAULT G_BUS_TYPE_SYSTEM +- +-/* implementation specific RCs */ +-#define TSS2_RESMGR_RC_INTERNAL_ERROR (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | (1 << TSS2_LEVEL_IMPLEMENTATION_SPECIFIC_SHIFT)) +-#define TSS2_RESMGR_RC_SAPI_INIT (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | (2 << TSS2_LEVEL_IMPLEMENTATION_SPECIFIC_SHIFT)) +-#define TSS2_RESMGR_RC_OUT_OF_MEMORY (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | (3 << TSS2_LEVEL_IMPLEMENTATION_SPECIFIC_SHIFT)) +-/* RCs in the RESMGR layer */ +-#define TSS2_RESMGR_RC_BAD_VALUE (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | TSS2_BASE_RC_BAD_VALUE) +-#define TSS2_RESMGR_RC_NOT_PERMITTED (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | TSS2_BASE_RC_NOT_PERMITTED) +-#define TSS2_RESMGR_RC_NOT_IMPLEMENTED (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | TSS2_BASE_RC_NOT_IMPLEMENTED) +-#define TSS2_RESMGR_RC_GENERAL_FAILURE (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | TSS2_BASE_RC_GENERAL_FAILURE) +-#define TSS2_RESMGR_RC_OBJECT_MEMORY (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | TPM_RC_OBJECT_MEMORY) +- +-#define TABRMD_ERROR tabrmd_error_quark () +-GQuark tabrmd_error_quark (void); +- +-TSS2_RC tss2_tcti_tabrmd_dump_trans_state (TSS2_TCTI_CONTEXT *tcti_context); +- +-#endif /* TSS2_TABD_H */ +diff --git a/src/include/tcti-tabrmd.h b/src/include/tcti-tabrmd.h +index c145eb5..e8e0c7f 100644 +--- a/src/include/tcti-tabrmd.h ++++ b/src/include/tcti-tabrmd.h +@@ -35,7 +35,7 @@ extern "C" { + #include + #include + +-#include "tabrmd.h" ++#include + + #define TCTI_TABRMD_DBUS_TYPE_DEFAULT TABRMD_DBUS_TYPE_DEFAULT + #define TCTI_TABRMD_DBUS_NAME_DEFAULT TABRMD_DBUS_NAME_DEFAULT +diff --git a/src/include/tss2/tabrmd.h b/src/include/tss2/tabrmd.h +new file mode 100644 +index 0000000..42d41a2 +--- /dev/null ++++ b/src/include/tss2/tabrmd.h +@@ -0,0 +1,56 @@ ++/* ++ * Copyright (c) 2017, Intel Corporation ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF ++ * THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef TSS2_TABD_H ++#define TSS2_TABD_H ++ ++#include ++#include ++ ++#define TABRMD_DBUS_INTERFACE "com.intel.tss2.TctiTabrmd" ++#define TABRMD_DBUS_NAME_DEFAULT "com.intel.tss2.Tabrmd" ++#define TABRMD_DBUS_PATH "/com/intel/tss2/Tabrmd/Tcti" ++#define TABRMD_DBUS_METHOD_CREATE_CONNECTION "CreateConnection" ++#define TABRMD_DBUS_METHOD_CANCEL "Cancel" ++#define TABRMD_DBUS_TYPE_DEFAULT G_BUS_TYPE_SYSTEM ++ ++/* implementation specific RCs */ ++#define TSS2_RESMGR_RC_INTERNAL_ERROR (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | (1 << TSS2_LEVEL_IMPLEMENTATION_SPECIFIC_SHIFT)) ++#define TSS2_RESMGR_RC_SAPI_INIT (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | (2 << TSS2_LEVEL_IMPLEMENTATION_SPECIFIC_SHIFT)) ++#define TSS2_RESMGR_RC_OUT_OF_MEMORY (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | (3 << TSS2_LEVEL_IMPLEMENTATION_SPECIFIC_SHIFT)) ++/* RCs in the RESMGR layer */ ++#define TSS2_RESMGR_RC_BAD_VALUE (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | TSS2_BASE_RC_BAD_VALUE) ++#define TSS2_RESMGR_RC_NOT_PERMITTED (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | TSS2_BASE_RC_NOT_PERMITTED) ++#define TSS2_RESMGR_RC_NOT_IMPLEMENTED (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | TSS2_BASE_RC_NOT_IMPLEMENTED) ++#define TSS2_RESMGR_RC_GENERAL_FAILURE (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | TSS2_BASE_RC_GENERAL_FAILURE) ++#define TSS2_RESMGR_RC_OBJECT_MEMORY (TSS2_RC)(TSS2_RESMGR_ERROR_LEVEL | TPM_RC_OBJECT_MEMORY) ++ ++#define TABRMD_ERROR tabrmd_error_quark () ++GQuark tabrmd_error_quark (void); ++ ++TSS2_RC tss2_tcti_tabrmd_dump_trans_state (TSS2_TCTI_CONTEXT *tcti_context); ++ ++#endif /* TSS2_TABD_H */ +diff --git a/src/resource-manager.c b/src/resource-manager.c +index 6efdd82..8ad4e46 100644 +--- a/src/resource-manager.c ++++ b/src/resource-manager.c +@@ -35,7 +35,7 @@ + #include "resource-manager.h" + #include "sink-interface.h" + #include "source-interface.h" +-#include "tabrmd.h" ++#include + #include "tpm2-header.h" + #include "tpm2-command.h" + #include "tpm2-response.h" +diff --git a/src/tabrmd-error.c b/src/tabrmd-error.c +index 5ff5a7d..41a561d 100644 +--- a/src/tabrmd-error.c ++++ b/src/tabrmd-error.c +@@ -1,6 +1,6 @@ + #include + #include +-#include "tabrmd.h" ++#include + + static const GDBusErrorEntry tabrmd_error_entries[] = { + { +diff --git a/src/tabrmd.c b/src/tabrmd.c +index 2275aa5..7156cdf 100644 +--- a/src/tabrmd.c ++++ b/src/tabrmd.c +@@ -34,7 +34,7 @@ + #include + + #include +-#include "tabrmd.h" ++#include + #include "access-broker.h" + #include "connection.h" + #include "connection-manager.h" +diff --git a/src/tcti-tabrmd.c b/src/tcti-tabrmd.c +index d6d78ea..52418de 100644 +--- a/src/tcti-tabrmd.c ++++ b/src/tcti-tabrmd.c +@@ -35,7 +35,7 @@ + + #include + +-#include "tabrmd.h" ++#include + #include "tcti-tabrmd.h" + #include "tcti-tabrmd-priv.h" + #include "tpm2-header.h" +diff --git a/test/integration/hash-sequence.int.c b/test/integration/hash-sequence.int.c +index cf8331d..fd489f9 100644 +--- a/test/integration/hash-sequence.int.c ++++ b/test/integration/hash-sequence.int.c +@@ -34,7 +34,7 @@ + + #include + +-#include "tabrmd.h" ++#include + #include "tcti-tabrmd.h" + #include "common.h" + +diff --git a/test/integration/password-authorization.int.c b/test/integration/password-authorization.int.c +index e6298ef..5416eaa 100644 +--- a/test/integration/password-authorization.int.c ++++ b/test/integration/password-authorization.int.c +@@ -32,7 +32,7 @@ + #include + #include + +-#include "tabrmd.h" ++#include + #include "tcti-tabrmd.h" + #include "common.h" + +diff --git a/test/integration/tcti-cancel.int.c b/test/integration/tcti-cancel.int.c +index 31f0f9a..c2a808b 100644 +--- a/test/integration/tcti-cancel.int.c ++++ b/test/integration/tcti-cancel.int.c +@@ -27,7 +27,7 @@ + #include + #include + +-#include "tabrmd.h" ++#include + #include "tcti-tabrmd.h" + #include "common.h" + +diff --git a/test/integration/tcti-set-locality.int.c b/test/integration/tcti-set-locality.int.c +index 6b7509b..0a54b6a 100644 +--- a/test/integration/tcti-set-locality.int.c ++++ b/test/integration/tcti-set-locality.int.c +@@ -27,7 +27,7 @@ + #include + #include + +-#include "tabrmd.h" ++#include + #include "tcti-tabrmd.h" + #include "common.h" + +-- +2.7.5 + diff --git a/meta-tpm2/recipes-tpm/tpm2-abrmd/files/tpm2-abrmd-init.sh b/meta-tpm2/recipes-tpm/tpm2-abrmd/files/tpm2-abrmd-init.sh new file mode 100644 index 0000000..c8dfb7d --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2-abrmd/files/tpm2-abrmd-init.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +### BEGIN INIT INFO +# Provides: tpm2-abrmd +# Required-Start: $local_fs $remote_fs $network +# Required-Stop: $local_fs $remote_fs $network +# Should-Start: +# Should-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: starts tpm2-abrmd +# Description: tpm2-abrmd implements the TCG resource manager +### END INIT INFO + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +DAEMON=/usr/sbin/tpm2-abrmd +NAME=tpm2-abrmd +DESC="TCG TSS2 Access Broker and Resource Management daemon" +USER="tss" + +test -x "${DAEMON}" || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +case "${1}" in + start) + echo -n "Starting $DESC: " + + if [ ! -e /dev/tpm* ] + then + echo "device driver not loaded, skipping." + exit 0 + fi + + start-stop-daemon --start --quiet --oknodo --background --pidfile /var/run/${NAME}.pid --user ${USER} --chuid ${USER} --exec ${DAEMON} -- ${DAEMON_OPTS} + RETVAL="$?" + echo "$NAME." + [ "$RETVAL" = 0 ] && pidof $DAEMON > /var/run/${NAME}.pid + exit $RETVAL + ;; + + stop) + echo -n "Stopping $DESC: " + + start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/${NAME}.pid --user ${USER} --exec ${DAEMON} + RETVAL="$?" + echo "$NAME." + rm -f /var/run/${NAME}.pid + exit $RETVAL + ;; + + restart|force-reload) + "${0}" stop + sleep 1 + "${0}" start + exit $? + ;; + *) + echo "Usage: ${NAME} {start|stop|restart|force-reload|status}" >&2 + exit 3 + ;; +esac + +exit 0 diff --git a/meta-tpm2/recipes-tpm/tpm2-abrmd/files/tpm2-abrmd.default b/meta-tpm2/recipes-tpm/tpm2-abrmd/files/tpm2-abrmd.default new file mode 100644 index 0000000..987978a --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2-abrmd/files/tpm2-abrmd.default @@ -0,0 +1 @@ +DAEMON_OPTS="--tcti=device --logger=syslog --max-connections=20 --max-transient-objects=20 --fail-on-loaded-trans" diff --git a/meta-tpm2/recipes-tpm/tpm2-abrmd/tpm2-abrmd_git.bb b/meta-tpm2/recipes-tpm/tpm2-abrmd/tpm2-abrmd_git.bb new file mode 100644 index 0000000..17dc449 --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2-abrmd/tpm2-abrmd_git.bb @@ -0,0 +1,61 @@ +SUMMARY = "" +DESCRIPTION = "" +SECTION = "tpm" + +# This is a lie. The source for this project is covered by several licenses. +# We're currently working on a way to make this clear for those consuming the +# project. Till then I'm using 'BSD' as a place holder since the Intel license +# is "BSD-like". +LICENSE = "BSD" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/BSD;md5=3775480a712fc46a69647678acb234cb" + +DEPENDS += "autoconf-archive dbus glib-2.0 pkgconfig tpm2.0-tss glib-2.0-native" +RDEPENDS_${PN} += "libgcc dbus-glib" + +SRC_URI = " \ + git://github.com/01org/tpm2-abrmd.git;branch=master;name=tpm2-abrmd;destsuffix=tpm2-abrmd \ + file://tpm2-abrmd-init.sh \ + file://tpm2-abrmd.default \ + " + +SRCREV = "4f0bd204d07176084b245d005df665fbfdf68db5" +PV = "1.0.0+git${SRCPV}" +S = "${WORKDIR}/${BPN}" + +inherit autotools pkgconfig systemd update-rc.d useradd + +SYSTEMD_PACKAGES += "${PN}" +SYSTEMD_SERVICE_${PN} = "tpm2-abrmd.service" +SYSTEMD_AUTO_ENABLE_${PN} = "enable" + +INITSCRIPT_NAME = "tpm2-abrmd" +INITSCRIPT_PARAMS = "start 99 2 3 4 5 . stop 19 0 1 6 ." + +USERADD_PACKAGES = "${PN}" +GROUPADD_PARAM_${PN} = "tss" +USERADD_PARAM_${PN} = "-M -d /var/lib/tpm -s /bin/false -g tss tss" + +# break out tcti into a package: libtcti-tabrmd +# package up the service file + +EXTRA_OECONF += " \ + --with-systemdsystemunitdir=${systemd_system_unitdir} \ + --with-udevrulesdir=${sysconfdir}/udev/rules.d \ + " + +do_configure_prepend() { + # execute the bootstrap script + currentdir=$(pwd) + cd "${S}" + ACLOCAL="aclocal --system-acdir=${STAGING_DATADIR}/aclocal" ./bootstrap --force + cd "${currentdir}" +} + +do_install_append() { + install -d "${D}${sysconfdir}/init.d" + install -m 0755 "${WORKDIR}/tpm2-abrmd-init.sh" "${D}${sysconfdir}/init.d/tpm2-abrmd" + install -d "${D}${sysconfdir}/default" + install -m 0644 "${WORKDIR}/tpm2-abrmd.default" "${D}${sysconfdir}/default/tpm2-abrmd" +} + +BBCLASSEXTEND = "native" diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/0001-tpm2-tools-use-dynamic-linkage-with-tpm2-abrmd.patch b/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/0001-tpm2-tools-use-dynamic-linkage-with-tpm2-abrmd.patch new file mode 100644 index 0000000..8d91ca0 --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/0001-tpm2-tools-use-dynamic-linkage-with-tpm2-abrmd.patch @@ -0,0 +1,80 @@ +From 9aee7b2bc400a336f0a938ce80eba51707662612 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Mon, 19 Jun 2017 13:52:53 +0800 +Subject: [PATCH 1/2] tpm2-tools: use dynamic linkage with tpm2-abrmd + +tpm2-abrmd has huge dependencies and they are not necessary to be involved +in initramfs. + +Signed-off-by: Lans Zhang +--- + Makefile.am | 2 +- + lib/context-util.c | 22 ++++++++++++++++++++-- + 2 files changed, 21 insertions(+), 3 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index a3c43f8..68ba044 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -38,7 +38,7 @@ LIB_COMMON := lib/libcommon.a + AM_CFLAGS := $(INCLUDE_DIRS) $(TPM20_TSS_CFLAGS) $(EXTRA_CFLAGS) $(TCTI_TABRMD_CFLAGS) + AM_LDFLAGS := $(EXTRA_LDFLAGS) + +-LDADD = $(LIB_COMMON) $(TPM20_TSS_LIBS) $(TCTI_SOCK_LIBS) $(TCTI_DEV_LIBS) $(TCTI_TABRMD_LIBS) ++LDADD = $(LIB_COMMON) $(TPM20_TSS_LIBS) $(TCTI_SOCK_LIBS) $(TCTI_DEV_LIBS) $(TCTI_TABRMD_LIBS) -ldl + + sbin_PROGRAMS = \ + tools/tpm2_create \ +diff --git a/lib/context-util.c b/lib/context-util.c +index 7de22ac..2ef181d 100644 +--- a/lib/context-util.c ++++ b/lib/context-util.c +@@ -38,6 +38,7 @@ + #include + #endif + #ifdef HAVE_TCTI_TABRMD ++#include + #include + #endif + +@@ -134,10 +135,27 @@ TSS2_TCTI_CONTEXT* + tcti_tabrmd_init (void) + { + TSS2_TCTI_CONTEXT *tcti_ctx; ++ TSS2_RC (*init)(TSS2_TCTI_CONTEXT *, size_t *); ++ /* ++ * Intend to "forget" the handle in order to make sure libtcti-tabrmd ++ * is unloaded along with the deconstructed functions. ++ */ ++ void *tabrmd_handle; + TSS2_RC rc; + size_t size; + +- rc = tss2_tcti_tabrmd_init(NULL, &size); ++ tabrmd_handle = dlopen("libtcti-tabrmd.so.0", RTLD_LAZY); ++ if (!tabrmd_handle) { ++ fprintf (stderr, ++ "Unable to find out the tabrmd tcti library\n"); ++ return NULL; ++ } ++ ++ init = dlsym(tabrmd_handle, "tss2_tcti_tabrmd_init"); ++ if (!init) ++ return NULL; ++ ++ rc = init(NULL, &size); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERR ("Failed to get size for TABRMD TCTI context: 0x%" PRIx32, rc); + return NULL; +@@ -148,7 +166,7 @@ tcti_tabrmd_init (void) + strerror (errno)); + return NULL; + } +- rc = tss2_tcti_tabrmd_init (tcti_ctx, &size); ++ rc = init (tcti_ctx, &size); + if (rc != TSS2_RC_SUCCESS) { + LOG_ERR ("Failed to initialize TABRMD TCTI context: 0x%" PRIx32, rc); + free (tcti_ctx); +-- +2.7.5 + diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/0002-Fix-build-failure-with-glib-2.0.patch b/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/0002-Fix-build-failure-with-glib-2.0.patch new file mode 100644 index 0000000..faeaf2a --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/0002-Fix-build-failure-with-glib-2.0.patch @@ -0,0 +1,39 @@ +From 53f9b2f63c5370f4d269bf08d940cc8576fcbbf4 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Mon, 19 Jun 2017 13:54:34 +0800 +Subject: [PATCH 2/2] Fix build failure with glib-2.0 + +Signed-off-by: Lans Zhang +--- + Makefile.am | 2 +- + configure.ac | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/Makefile.am b/Makefile.am +index 68ba044..e792049 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -35,7 +35,7 @@ ACLOCAL_AMFLAGS = -I m4 + INCLUDE_DIRS = -I$(srcdir)/src -I$(srcdir)/lib + LIB_COMMON := lib/libcommon.a + +-AM_CFLAGS := $(INCLUDE_DIRS) $(TPM20_TSS_CFLAGS) $(EXTRA_CFLAGS) $(TCTI_TABRMD_CFLAGS) ++AM_CFLAGS := $(INCLUDE_DIRS) $(GLIB_CFLAGS) $(TPM20_TSS_CFLAGS) $(EXTRA_CFLAGS) $(TCTI_TABRMD_CFLAGS) + AM_LDFLAGS := $(EXTRA_LDFLAGS) + + LDADD = $(LIB_COMMON) $(TPM20_TSS_LIBS) $(TCTI_SOCK_LIBS) $(TCTI_DEV_LIBS) $(TCTI_TABRMD_LIBS) -ldl +diff --git a/configure.ac b/configure.ac +index ce781ea..08fa81c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -6,6 +6,7 @@ LT_INIT + AM_INIT_AUTOMAKE([foreign + subdir-objects]) + AC_CONFIG_FILES([Makefile]) ++PKG_CHECK_MODULES([GLIB], [glib-2.0]) + PKG_CHECK_MODULES([SAPI],[sapi]) + # disable libtcti-device selectively (enabled by default) + AC_ARG_WITH( +-- +2.7.5 + diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/ax_check_compile_flag.m4 b/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/ax_check_compile_flag.m4 new file mode 100644 index 0000000..dcabb92 --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/ax_check_compile_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/ax_check_link_flag.m4 b/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/ax_check_link_flag.m4 new file mode 100644 index 0000000..819409a --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/ax_check_link_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the linker or gives an error. +# (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_LINK_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/ax_check_preproc_flag.m4 b/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/ax_check_preproc_flag.m4 new file mode 100644 index 0000000..4850ff3 --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools/ax_check_preproc_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_preproc_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_PREPROC_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's +# preprocessor or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the preprocessor's default +# flags when the check is done. The check is thus made with the flags: +# "CPPFLAGS EXTRA-FLAGS FLAG". This can for example be used to force the +# preprocessor to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_PREPROC_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{COMPILE,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_PREPROC_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]cppflags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG preprocessor accepts $1], CACHEVAR, [ + ax_check_save_flags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $4 $1" + AC_PREPROC_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + CPPFLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_PREPROC_FLAGS diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools_git.bb b/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools_git.bb new file mode 100644 index 0000000..a914c3b --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tools/tpm2.0-tools_git.bb @@ -0,0 +1,48 @@ +SUMMARY = "Tools for TPM2." +DESCRIPTION = "tpm2.0-tools" +SECTION = "tpm" + +LICENSE = "BSD" +LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=91b7c548d73ea16537799e8060cea819" + +DEPENDS += "tpm2.0-tss tpm2-abrmd openssl curl autoconf-archive pkgconfig" +RDEPENDS_${PN} += "libtss2 libtctidevice" + +SRC_URI = " \ + git://github.com/01org/tpm2.0-tools.git;branch=master;name=tpm2.0-tools;destsuffix=tpm2.0-tools \ + file://ax_check_compile_flag.m4 \ + file://ax_check_preproc_flag.m4 \ + file://ax_check_link_flag.m4 \ + file://0001-tpm2-tools-use-dynamic-linkage-with-tpm2-abrmd.patch \ + file://0002-Fix-build-failure-with-glib-2.0.patch \ +" + +S = "${WORKDIR}/${BPN}" +SRCREV = "ada4c20d23d99b4b489c6c793e4132c1d5234b66" +PV = "2.0.0+git${SRCPV}" + +inherit autotools pkgconfig + +EXTRA_OECONF += " \ + --with-tcti-device \ + --without-tcti-socket \ + --with-tcti-tabrmd \ +" + +EXTRA_OEMAKE += " \ + CFLAGS="${CFLAGS} -Wno-implicit-fallthrough" \ +" + +do_configure_prepend() { + mkdir -p "${S}/m4" + cp "${WORKDIR}/ax_check_compile_flag.m4" "${S}/m4" + cp "${WORKDIR}/ax_check_preproc_flag.m4" "${S}/m4" + cp "${WORKDIR}/ax_check_link_flag.m4" "${S}/m4" + + # execute the bootstrap script + currentdir=$(pwd) + cd "${S}" + ACLOCAL="aclocal --system-acdir=${STAGING_DATADIR}/aclocal" \ + ./bootstrap --force + cd "${currentdir}" +} diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/0001-update-bootstrap.patch b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/0001-update-bootstrap.patch new file mode 100644 index 0000000..3f5fa81 --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/0001-update-bootstrap.patch @@ -0,0 +1,24 @@ +Index: TPM2.0-TSS/bootstrap +=================================================================== +--- TPM2.0-TSS.orig/bootstrap ++++ TPM2.0-TSS/bootstrap +@@ -13,6 +13,7 @@ src_listvar () { + } + + VARS_FILE=src_vars.mk ++AUTORECONF=${AUTORECONF:-autoreconf} + + echo "Generating file lists: ${VARS_FILE}" + ( +@@ -30,11 +31,3 @@ echo "Generating file lists: ${VARS_FILE + printf "SAMPLE_SRC = \$(SAMPLE_C) \$(SAMPLE_H)\n" + ) > ${VARS_FILE} + +-printf "Running libtoolize ...\n" +-libtoolize --install +-printf "Running aclocal ...\n" +-aclocal +-printf "Running autoconf ...\n" +-autoconf +-printf "Running automake ...\n" +-automake --add-missing diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/ax_check_compile_flag.m4 b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/ax_check_compile_flag.m4 new file mode 100644 index 0000000..dcabb92 --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/ax_check_compile_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/ax_check_link_flag.m4 b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/ax_check_link_flag.m4 new file mode 100644 index 0000000..819409a --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/ax_check_link_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the linker or gives an error. +# (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_LINK_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/ax_check_preproc_flag.m4 b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/ax_check_preproc_flag.m4 new file mode 100644 index 0000000..4850ff3 --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/ax_check_preproc_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_preproc_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_PREPROC_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's +# preprocessor or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the preprocessor's default +# flags when the check is done. The check is thus made with the flags: +# "CPPFLAGS EXTRA-FLAGS FLAG". This can for example be used to force the +# preprocessor to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_PREPROC_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{COMPILE,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_PREPROC_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]cppflags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG preprocessor accepts $1], CACHEVAR, [ + ax_check_save_flags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $4 $1" + AC_PREPROC_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + CPPFLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_PREPROC_FLAGS diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/ax_pthread.m4 b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/ax_pthread.m4 new file mode 100644 index 0000000..d383ad5 --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/ax_pthread.m4 @@ -0,0 +1,332 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. e.g. you should link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threads programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 21 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case ${host_os} in + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + darwin*) + ax_pthread_flags="-pthread $ax_pthread_flags" + ;; +esac + +# Clang doesn't consider unrecognized options an error unless we specify +# -Werror. We throw in some extra Clang-specific options to ensure that +# this doesn't happen for GCC, which also accepts -Werror. + +AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags]) +save_CFLAGS="$CFLAGS" +ax_pthread_extra_flags="-Werror" +CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument" +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])], + [AC_MSG_RESULT([yes])], + [ax_pthread_extra_flags= + AC_MSG_RESULT([no])]) +CFLAGS="$save_CFLAGS" + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $attr; return attr /* ; */])], + [attr_name=$attr; break], + []) + done + AC_MSG_RESULT([$attr_name]) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case ${host_os} in + aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; + osf* | hpux*) flag="-D_REENTRANT";; + solaris*) + if test "$GCC" = "yes"; then + flag="-D_REENTRANT" + else + # TODO: What about Clang on Solaris? + flag="-mt -D_REENTRANT" + fi + ;; + esac + AC_MSG_RESULT([$flag]) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != xyes; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + +AC_SUBST([PTHREAD_LIBS]) +AC_SUBST([PTHREAD_CFLAGS]) +AC_SUBST([PTHREAD_CC]) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/no-cmocka-configure-ac.diff b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/no-cmocka-configure-ac.diff new file mode 100644 index 0000000..9e5f2f5 --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss/no-cmocka-configure-ac.diff @@ -0,0 +1,10 @@ +Index: TPM2.0-TSS/configure.ac +=================================================================== +--- TPM2.0-TSS.orig/configure.ac ++++ TPM2.0-TSS/configure.ac +@@ -11,5 +11,4 @@ AX_PTHREAD([], [AC_MSG_ERROR([requires p + AM_INIT_AUTOMAKE([foreign + subdir-objects]) + AC_CONFIG_FILES([Makefile]) +-PKG_CHECK_MODULES([CMOCKA],[cmocka]) + AC_OUTPUT diff --git a/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss_git.bb b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss_git.bb new file mode 100644 index 0000000..cda3b30 --- /dev/null +++ b/meta-tpm2/recipes-tpm/tpm2.0-tss/tpm2.0-tss_git.bb @@ -0,0 +1,109 @@ +SUMMARY = "Software stack for TPM2." +DESCRIPTION = "tpm2.0-tss like woah." +SECTION = "tpm" + +# This is a lie. The source for this project is covered by several licenses. +# We're currently working on a way to make this clear for those consuming the +# project. Till then I'm using 'BSD' as a place holder since the Intel license +# is "BSD-like". +LICENSE = "BSD" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/BSD;md5=3775480a712fc46a69647678acb234cb" + +# This doesn't seem to work. Keeping it here for completeness. Remove once +# it's fixed upstream. +DEPENDS += "autoconf-archive pkgconfig" +#RDEPENDS_libtss2 += "libmarshal" +#RDEPENDS_libtctidevice += "libmarshal" + +SRC_URI = " \ + git://github.com/01org/TPM2.0-TSS.git;protocol=http;branch=1.x;name=TPM2.0-TSS;destsuffix=TPM2.0-TSS \ +" + +# CAPS? SRSLY? +S = "${WORKDIR}/${@d.getVar('BPN',d).upper()}" + +SRCREV = "1fa2f4d12449d5d639032fee28d922fe9d4877b5" +PV = "1.1.0+git${SRCPV}" + +RRECOMMENDS_${PN} += "\ + kernel-module-tpm-crb \ + kernel-module-tpm-tis \ +" + +TPM_DESCRIPTION = 'device/description' +FAMILY_MAJOR = 'TPM 2.0' + +PACKAGES = " \ + ${PN}-dbg \ + libtss2 \ + libtss2-dev \ + libtss2-staticdev \ + libtss2-doc \ + libtctidevice \ + libtctidevice-dev \ + libtctidevice-staticdev \ + libtctisocket \ + libtctisocket-dev \ + libtctisocket-staticdev \ + libmarshal \ + libmarshal-dev \ + libmarshal-staticdev \ +" + +FILES_libtss2 = "${libdir}/libsapi.so.*" +FILES_libtss2-dev = " \ + ${includedir}/sapi \ + ${includedir}/tcti/common.h \ + ${libdir}/libsapi.so \ + ${libdir}/pkgconfig/sapi.pc \ + ${libdir}/libsapi.la \ +" +FILES_libtss2-staticdev = " \ + ${libdir}/libsapi.a \ +" +FILES_libtss2-doc = " \ + ${mandir} \ +" +FILES_libtctidevice = "${libdir}/libtcti-device.so.*" +FILES_libtctidevice-dev = " \ + ${includedir}/tcti/tcti_device.h \ + ${libdir}/libtcti-device.so \ + ${libdir}/pkgconfig/tcti-device.pc \ + ${libdir}/libtcti-device.la \ +" +FILES_libtctidevice-staticdev = "${libdir}/libtcti-device.a" +FILES_libtctisocket = "${libdir}/libtcti-socket.so.*" +FILES_libtctisocket-dev = " \ + ${includedir}/tcti/tcti_socket.h \ + ${libdir}/libtcti-socket.so \ + ${libdir}/pkgconfig/tcti-socket.pc \ + ${libdir}/libtcti-socket.la \ +" +FILES_libtctisocket-staticdev = "${libdir}/libtcti-socket.a" +FILES_libmarshal = "${libdir}/libmarshal.so.*" +FILES_libmarshal-dev = "${libdir}/libmarshal.la ${libdir}/libmarshal.so" +FILES_libmarshal-staticdev = "${libdir}/libmarshal.a" + +inherit autotools + +# the autotools / autoconf-archive don't work as expected so we include the +# pthread macro ourselves for now +SRC_URI += " \ + file://ax_pthread.m4 \ + file://ax_check_compile_flag.m4 \ + file://ax_check_preproc_flag.m4 \ + file://ax_check_link_flag.m4 \ +" +do_configure_prepend () { + mkdir -p ${S}/m4 + cp ${WORKDIR}/ax_pthread.m4 ${S}/m4 + cp ${WORKDIR}/ax_check_compile_flag.m4 ${S}/m4 + cp ${WORKDIR}/ax_check_preproc_flag.m4 ${S}/m4 + cp ${WORKDIR}/ax_check_link_flag.m4 ${S}/m4 + # execute the bootstrap script + currentdir=$(pwd) + cd ${S} + ACLOCAL="aclocal --system-acdir=${STAGING_DATADIR}/aclocal" ./bootstrap --force + cd ${currentdir} +} + diff --git a/meta/conf/layer.conf b/meta/conf/layer.conf new file mode 100644 index 0000000..1e20761 --- /dev/null +++ b/meta/conf/layer.conf @@ -0,0 +1,14 @@ +# We have a conf and classes directory, add to BBPATH +BBPATH .= ":${LAYERDIR}" + +# We have recipes-* directories, add to BBFILES +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ + ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "secure-core" +BBFILE_PATTERN_secure-core = "^${LAYERDIR}/" +BBFILE_PRIORITY_secure-core = "10" + +LAYERDEPENDS_secure-core = "\ + core \ +" diff --git a/meta/recipes-core/images/secure-core-image.bb b/meta/recipes-core/images/secure-core-image.bb new file mode 100644 index 0000000..9fe73c5 --- /dev/null +++ b/meta/recipes-core/images/secure-core-image.bb @@ -0,0 +1,23 @@ +SUMMARY = "The root image of SecureCore." + +SECURE_CORE_IMAGE_EXTRA_INSTALL_append += "\ + ${@bb.utils.contains("DISTRO_FEATURES", "efi-secure-boot", \ + "packagegroup-efi-secure-boot", "", d)} \ + ${@bb.utils.contains("DISTRO_FEATURES", "tpm", \ + "packagegroup-tpm", "", d)} \ + ${@bb.utils.contains("DISTRO_FEATURES", "tpm2", \ + "packagegroup-tpm2", "", d)} \ + ${@bb.utils.contains("DISTRO_FEATURES", "encrypted-storage", \ + "packagegroup-encrypted-storage", "", d)} \ +" + +IMAGE_INSTALL = "packagegroup-core-boot ${SECURE_CORE_IMAGE_EXTRA_INSTALL}" + +IMAGE_LINGUAS = " " + +LICENSE = "MIT" + +inherit core-image + +IMAGE_ROOTFS_SIZE ?= "8192" +IMAGE_ROOTFS_EXTRA_SPACE_append = "${@bb.utils.contains("DISTRO_FEATURES", "systemd", " + 4096", "" ,d)}"