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
//\r
VOID *mHashCtx = NULL;\r
\r
-//\r
-// Pointer to runtime buffer.\r
-// For "Append" operation to an existing variable, a read/modify/write operation\r
-// is supported by firmware internally. Reserve runtime buffer to cache previous\r
-// variable data in runtime phase because memory allocation is forbidden in virtual mode.\r
-//\r
-VOID *mStorageArea = NULL;\r
-\r
//\r
// The serialization of the values of the VariableName, VendorGuid and Attributes\r
// parameters of the SetVariable() call and the TimeStamp component of the\r
}\r
\r
//\r
- // Reserved runtime buffer for "Append" operation in virtual mode.\r
+ // Reserve runtime buffer for public key database. The size excludes variable header and name size.\r
//\r
- mStorageArea = AllocateRuntimePool (MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)));\r
- if (mStorageArea == NULL) {\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
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->NonVolatileLastVariableOffset,\r
FALSE,\r
NULL,\r
- TRUE,\r
+ NULL,\r
+ 0,\r
TRUE\r
);\r
if (EFI_ERROR (Status)) {\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
return Status;\r
}\r
\r
- if (mPlatformMode != SETUP_MODE || IsPk) {\r
+ if ((mPlatformMode != SETUP_MODE) || IsPk) {\r
Status = VendorKeyIsModified ();\r
}\r
} else if (mPlatformMode == USER_MODE) {\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
// 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