UEFI 2.4 X509 Certificate Hash and RFC3161 Timestamp Verification support for Secure Boot

Main ChangeLogs includes:
1. Introduce the new GUID and structure definitions for certificate hash and timestamp support;
2. Update Image Verification Library to support DBT signature checking;
3. Update the related SecureBoot Configuration Pages;

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Qin Long <qin.long@intel.com> 
Reviewed-by: Guo Dong <guo.dong@intel.com>
Reviewed-by: Siyuan Fu <siyuan.fu@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16380 6f19259b-4bc3-4df7-8a09-765794883524
MdeModulePkg/Core/PiSmmCore/PiSmmCore.c: Fix compiler warning about variable set but unused

Fix compiler warning about variable set but unused by returning status
of last operation.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Garrett Kirkendall <garrett.kirkendall@amd.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16381 6f19259b-4bc3-4df7-8a09-765794883524
OvmfPg: flash driver: fix type of EFI_SIZE_TO_PAGES argument (VS2010)

The MarkMemoryRangeForRuntimeAccess() function passes the Length parameter
(of type UINT64) to the macro EFI_SIZE_TO_PAGES(). When building for the
Ia32 platform, this violates the interface contract of the macro:

    [...] Passing in a parameter that is larger than UINTN may produce
    unexpected results.

In addition, it trips up compilation by VS2010 for the Ia32 platform and
the NOOPT target -- it generates calls to intrinsics, which are not
allowed in edk2.

Fix both issues with the following steps:

(1) Demote the Length parameter of MarkMemoryRangeForRuntimeAccess() to
UINTN. Even a UINT32 value is plenty for representing the size of the
flash chip holding the variable store. Length parameter is used in the
following contexts:
- passed to gDS->RemoveMemorySpace() -- takes an UINT64
- passed to gDS->AddMemorySpace() -- ditto
- passed to EFI_SIZE_TO_PAGES() -- requires an UINTN. This also guarantees
  that the return type of EFI_SIZE_TO_PAGES() will be UINTN, hence we can
  drop the outer cast.

(2) The only caller of MarkMemoryRangeForRuntimeAccess() is
FvbInitialize(). The latter function populates the local Length variable
(passed to MarkMemoryRangeForRuntimeAccess()) from
PcdGet32(PcdOvmfFirmwareFdSize). Therefore we can simply demote the local
variable to UINTN in this function as well.
- There's only one other use of Length in FvbInitialize(): it is passed to
  GetFvbInfo(). GetFvbInfo() takes an UINT64, so passing an UINTN is fine.

Suggested-by: Scott Duplichan <scott@notabs.org>

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <lersek@redhat.com>

Build-tested-by: Scott Duplichan <scott@notabs.org>

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16382 6f19259b-4bc3-4df7-8a09-765794883524
OvmfPg: flash driver: drop gratuitous 64-by-32 bit divisions (VS2010)

In the InitializeVariableFvHeader() function, all three of "Offset",
"Start" and "BlockSize" have type UINTN. Therefore the (Offset /
BlockSize) and (Start / BlockSize) divisions can be compiled on all
platforms without intrinsics.

In the current expressions

  (EFI_LBA) Offset / BlockSize
  (EFI_LBA) Start / BlockSize

"Offset" and "Start" are cast to UINT64 (== EFI_LBA), which leads to
64-by-32 bit divisions on Ia32, breaking the VS2010 / NOOPT / Ia32 build.
The simplest way to fix them is to realize we don't need casts at all.
(The prototypes of QemuFlashEraseBlock() and QemuFlashWrite() are visible
via "QemuFlash.h", and they will easily take our UINTN quotients as
UINT64.)

Suggested-by: Scott Duplichan <scott@notabs.org>

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <lersek@redhat.com>

Build-tested-by: Scott Duplichan <scott@notabs.org>

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16383 6f19259b-4bc3-4df7-8a09-765794883524
OvmfPkg: flash driver: drop needlessly wide multiplication (VS2010)

The current types of subexpressions used in QemuFlashPtr() are as follows.
(We also show the types of "larger" subexpressions, according to operator
binding.)

  mFlashBase + (Lba * mFdBlockSize) + Offset
      ^          ^         ^            ^
      |          |         |            |
   (UINT8*)   EFI_LBA    UINTN        UINTN
              (UINT64)

  ---------------------------------   ------
              (UINT8*)                UINTN

  ------------------------------------------
                    (UINT8*)

When building with VS2010 for Ia32 / NOOPT, the 64-by-32 bit
multiplication is translated to an intrinsic, which is not allowed in
edk2.

Recognize that "Lba" is always bounded by "mFdBlockCount" (an UINTN) here
-- all callers of QemuFlashPtr() ensure that. In addition, the flash chip
in question is always under 4GB, which is why we can address it at all on
Ia32. Narrow "Lba" to UINTN, without any loss of range.

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Scott Duplichan <scott@notabs.org>

[commit message by lersek@redhat.com]

Signed-off-by: Laszlo Ersek <lersek@redhat.com>

Build-tested-by: Scott Duplichan <scott@notabs.org>

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16384 6f19259b-4bc3-4df7-8a09-765794883524
OvmfPkg: QemuVideoDxe: the VBE shim needs no 64-bit shifts (VS2010)

The SegmentC local variable has type EFI_PHYSICAL_ADDRESS for (justified)
style reasons. However, the 64-bit bit-shifts that it undergoes result in
intrinsic calls when built with VS2010 for Ia32 / NOOPT.

The concrete value of SegmentC, 0xC0000, and the results  of the bitops
that are based on it, are statically computeable. Cast SegmentC to UINT32
before subjecting it to bitwise operations; we can see in advance that
this won't lead to range loss.

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Scott Duplichan <scott@notabs.org>

[lersek@redhat.com: dropped now superfluous outermost parens; commit msg]

Signed-off-by: Laszlo Ersek <lersek@redhat.com>

Build-tested-by: Scott Duplichan <scott@notabs.org>

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16385 6f19259b-4bc3-4df7-8a09-765794883524
OvmfPkg: VirtioScsiDxe: drop 64-bit shift in PopulateRequest() (VS2010)

"Lun" has type UINT64 in this function. The result of the expression

  (UINT8) ((Lun >> 8) | 0x40)

depends only on bits [15:8] of "Lun", therefore we can cast "Lun" to
UINT32 before shifting it.

This eliminates an intrinsic when building with VS2010 for Ia32 / NOOPT.

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Scott Duplichan <scott@notabs.org>

[lersek@redhat.com: added commit message]

Signed-off-by: Laszlo Ersek <lersek@redhat.com>

Build-tested-by: Scott Duplichan <scott@notabs.org>

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16386 6f19259b-4bc3-4df7-8a09-765794883524
CryptoPkg: TimestampTokenVerify(): fix gcc-4.8 / Ia32 build failure

SVN r16339 ("CryptoPkg Updates to support RFC3161 timestamp signature
verification.") introduced the following build failure:

> CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c: In function
> 'TimestampTokenVerify':
> CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c:538:3: error: passing
> argument 2 of 'd2i_TS_TST_INFO' from incompatible pointer type [-Werror]
>    TstInfo = d2i_TS_TST_INFO (NULL, &TstTemp, (int)TstSize);
>    ^
> In file included from CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c:22:0:
> CryptoPkg/Include/openssl/asn1t.h:803:10: note: expected 'const unsigned
> char **' but argument is of type 'UINT8 **'
>   stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
>           ^
> CryptoPkg/Include/openssl/asn1t.h:799:2: note: in expansion of macro
> 'IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname'
>   IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
>   ^
> CryptoPkg/Include/openssl/asn1t.h:778:42: note: in expansion of macro
> 'IMPLEMENT_ASN1_FUNCTIONS_fname'
>  #define IMPLEMENT_ASN1_FUNCTIONS(stname)
> IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
>                                           ^
> CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c:136:1: note: in expansion of
> macro 'IMPLEMENT_ASN1_FUNCTIONS'
>  IMPLEMENT_ASN1_FUNCTIONS (TS_TST_INFO)
>  ^
> cc1: all warnings being treated as errors

Note that the cast

  (const unsigned char **) &TstTemp

does not match the general edk2 coding style, but it *does* match
other similar casts in this file.

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <lersek@redhat.com>

Build-tested-by: Scott Duplichan <scott@notabs.org>

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

Reviewed-by: Qin Long <qin.long@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16387 6f19259b-4bc3-4df7-8a09-765794883524
CryptoPkg: OpenSslSupport.h: edk2-ize offsetof() macro for gcc-4.8 / X64

Code added in SVN r16339 ("CryptoPkg Updates to support RFC3161 timestamp
signature verification.") introduced many new uses of the offsetof()
macro. Since the offsetof() macro in "OpenSslSupport.h" casts a pointer to
an "int", it triggers a large number of

  error: cast from pointer to integer of different size
  [-Werror=pointer-to-int-cast]

errors when building CryptoPkg with gcc-4.8 for X64.

Remedy this by directing offsetof() to the OFFSET_OF() macro in
"MdePkg/Include/Base.h" (which matches how "OpenSslSupport.h" resolves the
va_*() macros too).

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <lersek@redhat.com>

Build-tested-by: Scott Duplichan <scott@notabs.org>

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

Reviewed-by: Qin Long <qin.long@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16388 6f19259b-4bc3-4df7-8a09-765794883524
SecurityPkg: VariableServiceSetVariable(): fix dbt <-> GUID association

SVN r16380 ("UEFI 2.4 X509 Certificate Hash and RFC3161 Timestamp
Verification support for Secure Boot") broke the "dbt" variable's
association with its expected namespace GUID.

According to "MdePkg/Include/Guid/ImageAuthentication.h", *all* of the
"db", "dbx", and "dbt" (== EFI_IMAGE_SECURITY_DATABASE2) variables have
their special meanings in the EFI_IMAGE_SECURITY_DATABASE_GUID namespace.

However, the above commit introduced the following expression in
VariableServiceSetVariable():

> -  } else if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
> -          ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0))) {
> +  } else if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
> +          ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0))
> +           || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2)) == 0) {

Simply replacing the individual expressions with the predicates
"GuidMatch", "DbMatch", "DbxMatch", and "DbtMatch", the above
transformation becomes:

> -  } else if (GuidMatch &&
> -          ((DbMatch) || (DbxMatch))) {
> +  } else if (GuidMatch &&
> +          ((DbMatch) || (DbxMatch))
> +           || DbtMatch) {

In shorter form, we change

  GuidMatch && (DbMatch || DbxMatch)

into

  GuidMatch && (DbMatch || DbxMatch) || DbtMatch

which is incorrect, because this way "dbt" will match outside of the
intended namespace / GUID.

The error was caught by gcc:

> SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c: In function
> 'VariableServiceSetVariable':
>
> SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c:3188:71: error:
> suggest parentheses around '&&' within '||' [-Werror=parentheses]
>
>    } else if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
>                                                                        ^
> cc1: all warnings being treated as errors

Fix the parentheses.

This change may have security implications.

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <lersek@redhat.com>

Reviewed-by: Qin Long <qin.long@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16389 6f19259b-4bc3-4df7-8a09-765794883524