diff --git "a/docs/\345\246\202\344\275\225\344\270\272EFI\346\226\207\344\273\266\347\255\276\345\220\215.md" b/docs/how to sign EFI file.md similarity index 73% rename from "docs/\345\246\202\344\275\225\344\270\272EFI\346\226\207\344\273\266\347\255\276\345\220\215.md" rename to docs/how to sign EFI file.md index 098f78afa6e5399b4391beffca49a0fe71a792db..901ee601569e3c042eda77a0975ffe851b05cb5a 100644 --- "a/docs/\345\246\202\344\275\225\344\270\272EFI\346\226\207\344\273\266\347\255\276\345\220\215.md" +++ b/docs/how to sign EFI file.md @@ -1,11 +1,8 @@ ---- -title: How to sign an EFI image ---- - +# How to sign an EFI image ## WHY -As [UEFI](https://en.wikipedia.org/wiki/UEFI) and [Secure boot](https://en.wikipedia.org/wiki/UEFI#Secure_Boot) was introduced, a signed UEFI executable is required in secure boot verificaion process to ensure the UEFI driver and/or OS boot loader are trusted. +As [UEFI](https://en.wikipedia.org/wiki/UEFI) and [Secure boot](https://en.wikipedia.org/wiki/UEFI#Secure_Boot) was introduced, a signed UEFI executable is required in secure boot verification process to ensure the UEFI driver and/or OS boot loader are trusted. ## HOWs @@ -14,31 +11,31 @@ In the latest [UEFI spec](https://uefi.org/specs/UEFI/2.10/32_Secure_Boot_and_Dr ### What a signed UEFI executable looks like As described in [UEFI spec](https://uefi.org/specs/UEFI/2.10/32_Secure_Boot_and_Driver_Signing.html), a Digital Signatures was embedded into the executable so that we can put the executable in any insecure location and verify the UEFI executable was not tampered. -Since the UEFI executable is a [PE/COFF format file](https://en.wikipedia.org/wiki/Portable_Executable) and the UEFI spec follow [Microsoft Authenticode Spec](https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/authenticode_pe.docx) to sign the executable, here's a brif sign outline and process: +Since the UEFI executable is a [PE/COFF format file](https://en.wikipedia.org/wiki/Portable_Executable) and the UEFI spec follow [Microsoft Authenticode Spec](https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/authenticode_pe.docx) to sign the executable, here's a brief sign outline and process: 1. using the method in `Microsoft Authenticode` to calculate the image digest(mostly sha256/sha1) -1. sign the `digest` using the private key from vendor to generate the `signature` in a PKCS #7 SignedData structure -1. embedded the `signature` into the executable and put the location and size of the signature in the `5th Data Directory` in PE/COFF file's `optional header` -1. the signature is a `WIN_CERTIFICATE` structure defined in[5], which come with a `wCertificateType=WIN_CERT_TYPE_PKCS_SIGNED_DATA` and the `bCertificate` formatted as a `PKCS#7 SignedData structure` -1. multi signatures are allowed in a single image(referred as signatures table blow), each signature MUST start at a virtual address aligned to quadword-aligned[2] -1. the signatures MAY end up with some zore-bytes so that the size of `signatures table` can be aligned to quadword +2. sign the `digest` using the private key from vendor to generate the `signature` in a PKCS #7 SignedData structure +3. embedded the `signature` into the executable and put the location and size of the signature in the `5th Data Directory` in PE/COFF file's `optional header` +4. the signature is a `WIN_CERTIFICATE` structure defined in[5], which come with a `wCertificateType=WIN_CERT_TYPE_PKCS_SIGNED_DATA` and the `bCertificate` formatted as a `PKCS#7 SignedData structure` +5. multi signatures are allowed in a single image(referred as signatures table blow), each signature MUST start at a virtual address aligned to quadword-aligned[2] +6. the signatures MAY end up with some zero-bytes so that the size of `signatures table` can be aligned to quadword Here's an brief image to illustrates the signature outline. -![](./signatrust_outline.png) +![](./images/signatrust_outline.png) ### How to generate the PKCS #7 SignedData The SignedData is a normal PKCS #7 SignedData with some tweaks defined in Authenticode Spec[1] So in the SignedData structure, something we should keep in mind: 1. the ContentInfo contains a structure called `SpcIndirectDataContent` which is described in the Spec[1], and the oid is fixed `1.3.6.1.4.1.311.2.1.4` -1. the `SpcIndirectDataContent` was encoded in `binary DER-encoded ASN.1` format -1. the digest algorithm was a choice from `sha256(default)`, `sha1` and `MD5(backwards only)`(details below) -1. in Authenticode, only one `signerInfo structure` is needed in `signerInfos` +2. the `SpcIndirectDataContent` was encoded in `binary DER-encoded ASN.1` format +3. the digest algorithm was a choice from `sha256(default)`, `sha1` and `MD5(backwards only)`(details below) +4. in Authenticode, only one `signerInfo structure` is needed in `signerInfos` Here's an image to illustrates the signedData. -![](./signedData.png) +![](./images/signedData.png) ### How to generate the file digest It's described in[1] in chapter `Calculating the PE Image Hash` @@ -53,15 +50,15 @@ There're two steps to verify the signatures. - There is ONE and only ONE SignerInfo in signedData - Digest algorithms are consistent (Signature.digest_algorithm == ContentInfo.digest_algorithm == SignerInfo.digest_algorithm) - Check that ContentInfo.digest matches the computed digest of the image(described above) -1. verify the certificates in PKCS7 signedData structure against with the trusted store +2. verify the certificates in PKCS7 signedData structure against with the trusted store see the code[3] and code[4] ## References 1. [Windows Authenticode Portable Executable Signature Format](https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/authenticode_pe.docx) -1. [Microsoft Portable Executable and Common Object File Format Specification](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format) -1. [verifying-windows-binaries-without-windows](https://blog.trailofbits.com/2020/05/27/verifying-windows-binaries-without-windows/) -1. [PE Authenticode by lief](https://lief-project.github.io/doc/latest/tutorials/13_pe_authenticode.html) -1. [WIN_CERTIFICATE](https://learn.microsoft.com/en-us/windows/win32/api/wintrust/ns-wintrust-win_certificate) -1. [UEFI Spec](https://uefi.org/specs/UEFI/2.10/32_Secure_Boot_and_Driver_Signing.html) -1. [signify](https://github.com/ralphje/signify/blob/master/signify/authenticode/structures.py) \ No newline at end of file +2. [Microsoft Portable Executable and Common Object File Format Specification](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format) +3. [verifying-windows-binaries-without-windows](https://blog.trailofbits.com/2020/05/27/verifying-windows-binaries-without-windows/) +4. [PE Authenticode by lief](https://lief-project.github.io/doc/latest/tutorials/13_pe_authenticode.html) +5. [WIN_CERTIFICATE](https://learn.microsoft.com/en-us/windows/win32/api/wintrust/ns-wintrust-win_certificate) +6. [UEFI Spec](https://uefi.org/specs/UEFI/2.10/32_Secure_Boot_and_Driver_Signing.html) +7. [signify](https://github.com/ralphje/signify/blob/master/signify/authenticode/structures.py) \ No newline at end of file