They will do basic validation for authentication data structure, then call crypto library\r
to verify the signature.\r
\r
-Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
///\r
/// Global database array for scratch\r
///\r
-UINT8 mPubKeyStore[MAX_KEYDB_SIZE];\r
+UINT8 *mPubKeyStore;\r
UINT32 mPubKeyNumber;\r
-UINT8 mCertDbStore[MAX_CERTDB_SIZE];\r
+UINT32 mMaxKeyNumber;\r
+UINT32 mMaxKeyDbSize;\r
+UINT8 *mCertDbStore;\r
+UINT32 mMaxCertDbSize;\r
UINT32 mPlatformMode;\r
UINT8 mVendorKeyState;\r
\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
+ //\r
+ // Reserve runtime buffer for public key database. The size excludes variable header and name size.\r
+ //\r
+ mMaxKeyDbSize = PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER) - sizeof (AUTHVAR_KEYDB_NAME);\r
+ mMaxKeyNumber = mMaxKeyDbSize / EFI_CERT_TYPE_RSA2048_SIZE;\r
+ mPubKeyStore = AllocateRuntimePool (mMaxKeyDbSize);\r
+ if (mPubKeyStore == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Reserve runtime buffer for certificate database. The size excludes variable header and name size.\r
+ //\r
+ mMaxCertDbSize = PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER) - sizeof (EFI_CERT_DB_NAME);\r
+ mCertDbStore = AllocateRuntimePool (mMaxCertDbSize);\r
+ if (mCertDbStore == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
//\r
// Prepare runtime buffer for serialized data of time-based authenticated\r
// Variable, i.e. (VariableName, VendorGuid, Attributes, TimeStamp, Data).\r
Add public key in store and return its index.\r
\r
@param[in] PubKey Input pointer to Public Key data\r
+ @param[in] VariableDataEntry The variable data entry \r
\r
@return Index of new added item\r
\r
**/\r
UINT32\r
AddPubKeyInStore (\r
- IN UINT8 *PubKey\r
+ IN UINT8 *PubKey,\r
+ IN VARIABLE_ENTRY_CONSISTENCY *VariableDataEntry\r
)\r
{\r
- EFI_STATUS Status;\r
- BOOLEAN IsFound;\r
- UINT32 Index;\r
- VARIABLE_POINTER_TRACK Variable;\r
- UINT8 *Ptr;\r
- UINT8 *Data;\r
- UINTN DataSize;\r
+ EFI_STATUS Status;\r
+ BOOLEAN IsFound;\r
+ UINT32 Index;\r
+ VARIABLE_POINTER_TRACK Variable;\r
+ UINT8 *Ptr;\r
+ UINT8 *Data;\r
+ UINTN DataSize;\r
+ VARIABLE_ENTRY_CONSISTENCY PublicKeyEntry;\r
+ UINT32 Attributes;\r
\r
if (PubKey == NULL) {\r
return 0;\r
&mVariableModuleGlobal->VariableGlobal,\r
FALSE\r
);\r
- ASSERT_EFI_ERROR (Status);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Get public key database variable failure, Status = %r\n", Status));\r
return 0;\r
}\r
\r
//\r
// Add public key in database.\r
//\r
- if (mPubKeyNumber == MAX_KEY_NUM) {\r
+ if (mPubKeyNumber == mMaxKeyNumber) {\r
//\r
// Public key dadatase is full, try to reclaim invalid key.\r
//\r
&mVariableModuleGlobal->VariableGlobal,\r
FALSE\r
);\r
- ASSERT_EFI_ERROR (Status);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Get public key database variable failure, Status = %r\n", Status));\r
return 0;\r
}\r
\r
CopyMem (mPubKeyStore, (UINT8 *) Data, DataSize);\r
mPubKeyNumber = (UINT32) (DataSize / EFI_CERT_TYPE_RSA2048_SIZE);\r
\r
- if (mPubKeyNumber == MAX_KEY_NUM) {\r
+ if (mPubKeyNumber == mMaxKeyNumber) {\r
return 0;\r
} \r
}\r
\r
+ //\r
+ // Check the variable space for both public key and variable data.\r
+ //\r
+ PublicKeyEntry.VariableSize = (mPubKeyNumber + 1) * EFI_CERT_TYPE_RSA2048_SIZE;\r
+ PublicKeyEntry.Guid = &gEfiAuthenticatedVariableGuid;\r
+ PublicKeyEntry.Name = AUTHVAR_KEYDB_NAME;\r
+ Attributes = VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;\r
+\r
+ if (!CheckRemainingSpaceForConsistency (Attributes, &PublicKeyEntry, VariableDataEntry, NULL)) {\r
+ //\r
+ // No enough variable space.\r
+ //\r
+ return 0;\r
+ }\r
+\r
CopyMem (mPubKeyStore + mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);\r
Index = ++mPubKeyNumber;\r
//\r
&gEfiAuthenticatedVariableGuid,\r
mPubKeyStore,\r
mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,\r
+ Attributes,\r
0,\r
0,\r
&Variable,\r
NULL\r
);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Update public key database variable failure, Status = %r\n", Status));\r
+ return 0;\r
+ }\r
}\r
\r
return Index;\r
EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;\r
UINT32 KeyIndex;\r
UINT64 MonotonicCount;\r
+ VARIABLE_ENTRY_CONSISTENCY VariableDataEntry;\r
\r
KeyIndex = 0;\r
CertData = NULL;\r
\r
if (!IsFirstTime) {\r
//\r
- // Check input PubKey.\r
+ // 2 cases need to check here\r
+ // 1. Internal PubKey variable. PubKeyIndex is always 0 \r
+ // 2. Other counter-based AuthVariable. Check input PubKey.\r
//\r
- if (CompareMem (PubKey, mPubKeyStore + (KeyIndex - 1) * EFI_CERT_TYPE_RSA2048_SIZE, EFI_CERT_TYPE_RSA2048_SIZE) != 0) {\r
+ if (KeyIndex == 0 || CompareMem (PubKey, mPubKeyStore + (KeyIndex - 1) * EFI_CERT_TYPE_RSA2048_SIZE, EFI_CERT_TYPE_RSA2048_SIZE) != 0) {\r
return EFI_SECURITY_VIOLATION;\r
}\r
//\r
// Now, the signature has been verified!\r
//\r
if (IsFirstTime && !IsDeletion) {\r
+ VariableDataEntry.VariableSize = DataSize - AUTHINFO_SIZE;\r
+ VariableDataEntry.Guid = VendorGuid;\r
+ VariableDataEntry.Name = VariableName;\r
+\r
//\r
// Update public key database variable if need.\r
//\r
- KeyIndex = AddPubKeyInStore (PubKey);\r
+ KeyIndex = AddPubKeyInStore (PubKey, &VariableDataEntry);\r
if (KeyIndex == 0) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
NameSize = (UINT32) StrLen (VariableName);\r
CertNodeSize = sizeof (AUTH_CERT_DB_DATA) + (UINT32) CertDataSize + NameSize * sizeof (CHAR16); \r
NewCertDbSize = (UINT32) DataSize + CertNodeSize;\r
- if (NewCertDbSize > MAX_CERTDB_SIZE) {\r
+ if (NewCertDbSize > mMaxCertDbSize) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
NewCertDb = (UINT8*) mCertDbStore;\r
WrapSigData = NULL;\r
SignerCerts = NULL;\r
RootCert = NULL;\r
+ CertsInCertDb = NULL;\r
\r
//\r
// When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is\r