summaryrefslogtreecommitdiffstats
path: root/SecurityPkg
diff options
context:
space:
mode:
authorJan Bobek <jbobek@nvidia.com>2023-01-23 05:53:48 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-01-23 06:03:31 +0000
commit37d3eb026a766b2405daae47e02094c2ec248646 (patch)
tree6de0eac64b9c4812a869152e53f6c76301e0dd3c /SecurityPkg
parent7afef31b2b17d1a8d5248eb562352c6d3505ea14 (diff)
downloadedk2-37d3eb026a766b2405daae47e02094c2ec248646.tar.gz
edk2-37d3eb026a766b2405daae47e02094c2ec248646.tar.bz2
edk2-37d3eb026a766b2405daae47e02094c2ec248646.zip
SecurityPkg/AuthVariableLib: Check SHA-256 OID with ContentInfo present
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4305 Based on whether the DER-encoded ContentInfo structure is present in authenticated SetVariable payload or not, the SHA-256 OID can be located at different places. UEFI specification explicitly states the driver shall support both cases, but the old code assumed ContentInfo was not present and incorrectly rejected authenticated variable updates when it were present. Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Min Xu <min.m.xu@intel.com> Signed-off-by: Jan Bobek <jbobek@nvidia.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Diffstat (limited to 'SecurityPkg')
-rw-r--r--SecurityPkg/Library/AuthVariableLib/AuthService.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c b/SecurityPkg/Library/AuthVariableLib/AuthService.c
index 054ee4d1d9..9beeca09ae 100644
--- a/SecurityPkg/Library/AuthVariableLib/AuthService.c
+++ b/SecurityPkg/Library/AuthVariableLib/AuthService.c
@@ -1925,7 +1925,7 @@ VerifyTimeBasedPayload (
// SignedData.digestAlgorithms shall contain the digest algorithm used when preparing the
// signature. Only a digest algorithm of SHA-256 is accepted.
//
- // According to PKCS#7 Definition:
+ // According to PKCS#7 Definition (https://www.rfc-editor.org/rfc/rfc2315):
// SignedData ::= SEQUENCE {
// version Version,
// digestAlgorithms DigestAlgorithmIdentifiers,
@@ -1933,15 +1933,49 @@ VerifyTimeBasedPayload (
// .... }
// The DigestAlgorithmIdentifiers can be used to determine the hash algorithm
// in VARIABLE_AUTHENTICATION_2 descriptor.
- // This field has the fixed offset (+13) and be calculated based on two bytes of length encoding.
+ // This field has the fixed offset (+13) or (+32) based on whether the DER-encoded
+ // ContentInfo structure is present or not, and can be calculated based on two
+ // bytes of length encoding.
+ //
+ // Both condition can be handled in WrapPkcs7Data() in CryptPkcs7VerifyCommon.c.
+ //
+ // See below examples:
+ //
+ // 1. Without ContentInfo
+ // 30 82 0c da // SEQUENCE (5 element) (3294 BYTES) -- SignedData
+ // 02 01 01 // INTEGER 1 -- Version
+ // 31 0f // SET (1 element) (15 BYTES) -- DigestAlgorithmIdentifiers
+ // 30 0d // SEQUENCE (2 element) (13 BYTES) -- AlgorithmIdentifier
+ // 06 09 // OBJECT-IDENTIFIER (9 BYTES) -- algorithm
+ // 60 86 48 01 65 03 04 02 01 // sha256 [2.16.840.1.101.3.4.2.1]
+ // 05 00 // NULL (0 BYTES) -- parameters
+ //
+ // Example from: https://uefi.org/revocationlistfile
+ //
+ // 2. With ContentInfo
+ // 30 82 05 90 // SEQUENCE (1424 BYTES) -- ContentInfo
+ // 06 09 // OBJECT-IDENTIFIER (9 BYTES) -- ContentType
+ // 2a 86 48 86 f7 0d 01 07 02 // signedData [1.2.840.113549.1.7.2]
+ // a0 82 05 81 // CONTEXT-SPECIFIC CONSTRUCTED TAG 0 (1409 BYTES) -- content
+ // 30 82 05 7d // SEQUENCE (1405 BYTES) -- SignedData
+ // 02 01 01 // INTEGER 1 -- Version
+ // 31 0f // SET (1 element) (15 BYTES) -- DigestAlgorithmIdentifiers
+ // 30 0d // SEQUENCE (13 BYTES) -- AlgorithmIdentifier
+ // 06 09 // OBJECT-IDENTIFIER (9 BYTES) -- algorithm
+ // 60 86 48 01 65 03 04 02 01 // sha256 [2.16.840.1.101.3.4.2.1]
+ // 05 00 // NULL (0 BYTES) -- parameters
+ //
+ // Example generated with: https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot#Manual_process
//
if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
- if (SigDataSize >= (13 + sizeof (mSha256OidValue))) {
- if (((*(SigData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE) ||
- (CompareMem (SigData + 13, &mSha256OidValue, sizeof (mSha256OidValue)) != 0))
- {
- return EFI_SECURITY_VIOLATION;
- }
+ if ( ( (SigDataSize >= (13 + sizeof (mSha256OidValue)))
+ && ( ((*(SigData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
+ || (CompareMem (SigData + 13, &mSha256OidValue, sizeof (mSha256OidValue)) != 0)))
+ && ( (SigDataSize >= (32 + sizeof (mSha256OidValue)))
+ && ( ((*(SigData + 20) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
+ || (CompareMem (SigData + 32, &mSha256OidValue, sizeof (mSha256OidValue)) != 0))))
+ {
+ return EFI_SECURITY_VIOLATION;
}
}