BaseTools/Source/Python: Add -noattr to capsule signing openssl commands

This makes capsule PKCS#7 signatures reproducible.

openssl smime -sign embeds a signingTime signed attribute (current
UTCTime) by default. Because the attribute is inside the signed
digest, the resulting RSA signature differs on every invocation even
when the key and payload are identical, breaking reproducible builds
of signed FMP capsules.

Pass -noattr to drop all signed attributes from the SignerInfo. The
signature is then computed directly over the content, producing
byte-identical output across runs.

The FMP update path is unaffected: FmpAuthenticationLibPkcs7 calls
Pkcs7Verify() without extracting signed attributes, and rollback
protection uses FwVersion / LowestSupportedVersion in
FMP_PAYLOAD_HEADER plus the auth header MonotonicCount, not
signingTime. signingTime is only consumed by DxeImageVerificationLib
for Secure Boot dbt checks on PE/COFF images, which is a separate
code path.

Signed-off-by: Michał Kopeć <michal.kopec@3mdeb.com>
This commit is contained in:
Michał Kopeć
2026-05-18 11:00:44 +02:00
parent eedcdea610
commit 0fb9d21dda
2 changed files with 2 additions and 2 deletions
@@ -182,7 +182,7 @@ def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPublicCer
ToolPath = ''
Command = ''
Command = Command + '"{Path}" '.format (Path = os.path.join (ToolPath, 'openssl'))
Command = Command + 'smime -sign -binary -outform DER -md {HashAlgorithm} '.format (HashAlgorithm = HashAlgorithm)
Command = Command + 'smime -sign -binary -noattr -outform DER -md {HashAlgorithm} '.format (HashAlgorithm = HashAlgorithm)
Command = Command + '-signer "{Private}" -certfile "{Public}"'.format (Private = SignerPrivateCertFile, Public = OtherPublicCertFile)
if Verbose:
print (Command)
@@ -201,7 +201,7 @@ if __name__ == '__main__':
#
# Sign the input file using the specified private key and capture signature from STDOUT
#
Process = subprocess.Popen('%s smime -sign -binary -signer "%s" -outform DER -md sha256 -certfile "%s"' % (OpenSslCommand, args.SignerPrivateCertFileName, args.OtherPublicCertFileName), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
Process = subprocess.Popen('%s smime -sign -binary -noattr -signer "%s" -outform DER -md sha256 -certfile "%s"' % (OpenSslCommand, args.SignerPrivateCertFileName, args.OtherPublicCertFileName), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
Signature = Process.communicate(input=FullInputFileBuffer)[0]
if Process.returncode != 0:
sys.exit(Process.returncode)