);\r
}\r
\r
-/**\r
- Update the variable region with Variable information.\r
-\r
- @param[in] VariableName Name of variable.\r
- @param[in] VendorGuid Guid of variable.\r
- @param[in] Data Data pointer.\r
- @param[in] DataSize Size of Data.\r
- @param[in] Attributes Attribute value of the variable.\r
- @param[in] KeyIndex Index of associated public key.\r
- @param[in] MonotonicCount Value of associated monotonic count.\r
-\r
- @retval EFI_SUCCESS The update operation is success.\r
- @retval EFI_INVALID_PARAMETER Invalid parameter.\r
- @retval EFI_WRITE_PROTECTED Variable is write-protected.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-AuthServiceInternalUpdateVariableWithMonotonicCount (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes,\r
- IN UINT32 KeyIndex,\r
- IN UINT64 MonotonicCount\r
- )\r
-{\r
- AUTH_VARIABLE_INFO AuthVariableInfo;\r
-\r
- ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
- AuthVariableInfo.VariableName = VariableName;\r
- AuthVariableInfo.VendorGuid = VendorGuid;\r
- AuthVariableInfo.Data = Data;\r
- AuthVariableInfo.DataSize = DataSize;\r
- AuthVariableInfo.Attributes = Attributes;\r
- AuthVariableInfo.PubKeyIndex = KeyIndex;\r
- AuthVariableInfo.MonotonicCount = MonotonicCount;\r
-\r
- return mAuthVarLibContextIn->UpdateVariable (\r
- &AuthVariableInfo\r
- );\r
-}\r
-\r
/**\r
Update the variable region with Variable information.\r
\r
return FALSE;\r
}\r
\r
-/**\r
- Get available public key index.\r
-\r
- @param[in] PubKey Pointer to Public Key data.\r
-\r
- @return Public key index, 0 if no any public key index available.\r
-\r
-**/\r
-UINT32\r
-GetAvailableKeyIndex (\r
- IN UINT8 *PubKey\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 *Data;\r
- UINTN DataSize;\r
- UINT8 *Ptr;\r
- UINT32 Index;\r
- BOOLEAN IsFound;\r
- EFI_GUID VendorGuid;\r
- CHAR16 Name[1];\r
- AUTH_VARIABLE_INFO AuthVariableInfo;\r
- UINT32 KeyIndex;\r
-\r
- Status = AuthServiceInternalFindVariable (\r
- AUTHVAR_KEYDB_NAME,\r
- &gEfiAuthenticatedVariableGuid,\r
- (VOID **) &Data,\r
- &DataSize\r
- );\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
- if (mPubKeyNumber == mMaxKeyNumber) {\r
- Name[0] = 0;\r
- AuthVariableInfo.VariableName = Name;\r
- ZeroMem (&VendorGuid, sizeof (VendorGuid));\r
- AuthVariableInfo.VendorGuid = &VendorGuid;\r
- mPubKeyNumber = 0;\r
- //\r
- // Collect valid key data.\r
- //\r
- do {\r
- Status = mAuthVarLibContextIn->FindNextVariable (AuthVariableInfo.VariableName, AuthVariableInfo.VendorGuid, &AuthVariableInfo);\r
- if (!EFI_ERROR (Status)) {\r
- if (AuthVariableInfo.PubKeyIndex != 0) {\r
- for (Ptr = Data; Ptr < (Data + DataSize); Ptr += sizeof (AUTHVAR_KEY_DB_DATA)) {\r
- if (ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) Ptr)->KeyIndex)) == AuthVariableInfo.PubKeyIndex) {\r
- //\r
- // Check if the key data has been collected.\r
- //\r
- for (Index = 0; Index < mPubKeyNumber; Index++) {\r
- if (ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyIndex)) == AuthVariableInfo.PubKeyIndex) {\r
- break;\r
- }\r
- }\r
- if (Index == mPubKeyNumber) {\r
- //\r
- // New key data.\r
- //\r
- CopyMem ((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + mPubKeyNumber, Ptr, sizeof (AUTHVAR_KEY_DB_DATA));\r
- mPubKeyNumber++;\r
- }\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- } while (Status != EFI_NOT_FOUND);\r
-\r
- //\r
- // No available space to add new public key.\r
- //\r
- if (mPubKeyNumber == mMaxKeyNumber) {\r
- return 0;\r
- }\r
- }\r
-\r
- //\r
- // Find available public key index.\r
- //\r
- for (KeyIndex = 1; KeyIndex <= mMaxKeyNumber; KeyIndex++) {\r
- IsFound = FALSE;\r
- for (Ptr = mPubKeyStore; Ptr < (mPubKeyStore + mPubKeyNumber * sizeof (AUTHVAR_KEY_DB_DATA)); Ptr += sizeof (AUTHVAR_KEY_DB_DATA)) {\r
- if (ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) Ptr)->KeyIndex)) == KeyIndex) {\r
- IsFound = TRUE;\r
- break;\r
- }\r
- }\r
- if (!IsFound) {\r
- break;\r
- }\r
- }\r
-\r
- return KeyIndex;\r
-}\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 public key.\r
-\r
-**/\r
-UINT32\r
-AddPubKeyInStore (\r
- IN UINT8 *PubKey,\r
- IN VARIABLE_ENTRY_CONSISTENCY *VariableDataEntry\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 Index;\r
- VARIABLE_ENTRY_CONSISTENCY PublicKeyEntry;\r
- UINT32 Attributes;\r
- UINT32 KeyIndex;\r
-\r
- if (PubKey == NULL) {\r
- return 0;\r
- }\r
-\r
- //\r
- // Check whether the public key entry does exist.\r
- //\r
- for (Index = 0; Index < mPubKeyNumber; Index++) {\r
- if (CompareMem (((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyData, PubKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {\r
- return ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyIndex));\r
- }\r
- }\r
-\r
- KeyIndex = GetAvailableKeyIndex (PubKey);\r
- if (KeyIndex == 0) {\r
- return 0;\r
- }\r
-\r
- //\r
- // Check the variable space for both public key and variable data.\r
- //\r
- PublicKeyEntry.VariableSize = (mPubKeyNumber + 1) * sizeof (AUTHVAR_KEY_DB_DATA);\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 (!mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (Attributes, &PublicKeyEntry, VariableDataEntry, NULL)) {\r
- //\r
- // No enough variable space.\r
- //\r
- return 0;\r
- }\r
-\r
- WriteUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + mPubKeyNumber)->KeyIndex), KeyIndex);\r
- CopyMem (((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + mPubKeyNumber)->KeyData, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);\r
- mPubKeyNumber++;\r
-\r
- //\r
- // Update public key database variable.\r
- //\r
- Status = AuthServiceInternalUpdateVariable (\r
- AUTHVAR_KEYDB_NAME,\r
- &gEfiAuthenticatedVariableGuid,\r
- mPubKeyStore,\r
- mPubKeyNumber * sizeof (AUTHVAR_KEY_DB_DATA),\r
- Attributes\r
- );\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
- return KeyIndex;\r
-}\r
-\r
-/**\r
- Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256_GUID type.\r
- Follow the steps in UEFI2.2.\r
-\r
- Caution: This function may receive untrusted input.\r
- This function may be invoked in SMM mode, and datasize and data are external input.\r
- This function will do basic validation, before parse the data.\r
- This function will parse the authentication carefully to avoid security issues, like\r
- buffer overflow, integer overflow.\r
-\r
- @param[in] Data Pointer to data with AuthInfo.\r
- @param[in] DataSize Size of Data.\r
- @param[in] PubKey Public key used for verification.\r
-\r
- @retval EFI_INVALID_PARAMETER Invalid parameter.\r
- @retval EFI_SECURITY_VIOLATION If authentication failed.\r
- @retval EFI_SUCCESS Authentication successful.\r
-\r
-**/\r
-EFI_STATUS\r
-VerifyCounterBasedPayload (\r
- IN UINT8 *Data,\r
- IN UINTN DataSize,\r
- IN UINT8 *PubKey\r
- )\r
-{\r
- BOOLEAN Status;\r
- EFI_VARIABLE_AUTHENTICATION *CertData;\r
- EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;\r
- UINT8 Digest[SHA256_DIGEST_SIZE];\r
- VOID *Rsa;\r
- UINTN PayloadSize;\r
-\r
- PayloadSize = DataSize - AUTHINFO_SIZE;\r
- Rsa = NULL;\r
- CertData = NULL;\r
- CertBlock = NULL;\r
-\r
- if (Data == NULL || PubKey == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;\r
- CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);\r
-\r
- //\r
- // wCertificateType should be WIN_CERT_TYPE_EFI_GUID.\r
- // Cert type should be EFI_CERT_TYPE_RSA2048_SHA256_GUID.\r
- //\r
- if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||\r
- !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertTypeRsa2048Sha256Guid)) {\r
- //\r
- // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.\r
- //\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- //\r
- // Hash data payload with SHA256.\r
- //\r
- ZeroMem (Digest, SHA256_DIGEST_SIZE);\r
- Status = Sha256Init (mHashCtx);\r
- if (!Status) {\r
- goto Done;\r
- }\r
- Status = Sha256Update (mHashCtx, Data + AUTHINFO_SIZE, PayloadSize);\r
- if (!Status) {\r
- goto Done;\r
- }\r
- //\r
- // Hash Size.\r
- //\r
- Status = Sha256Update (mHashCtx, &PayloadSize, sizeof (UINTN));\r
- if (!Status) {\r
- goto Done;\r
- }\r
- //\r
- // Hash Monotonic Count.\r
- //\r
- Status = Sha256Update (mHashCtx, &CertData->MonotonicCount, sizeof (UINT64));\r
- if (!Status) {\r
- goto Done;\r
- }\r
- Status = Sha256Final (mHashCtx, Digest);\r
- if (!Status) {\r
- goto Done;\r
- }\r
- //\r
- // Generate & Initialize RSA Context.\r
- //\r
- Rsa = RsaNew ();\r
- ASSERT (Rsa != NULL);\r
- //\r
- // Set RSA Key Components.\r
- // NOTE: Only N and E are needed to be set as RSA public key for signature verification.\r
- //\r
- Status = RsaSetKey (Rsa, RsaKeyN, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);\r
- if (!Status) {\r
- goto Done;\r
- }\r
- Status = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE));\r
- if (!Status) {\r
- goto Done;\r
- }\r
- //\r
- // Verify the signature.\r
- //\r
- Status = RsaPkcs1Verify (\r
- Rsa,\r
- Digest,\r
- SHA256_DIGEST_SIZE,\r
- CertBlock->Signature,\r
- EFI_CERT_TYPE_RSA2048_SHA256_SIZE\r
- );\r
-\r
-Done:\r
- if (Rsa != NULL) {\r
- RsaFree (Rsa);\r
- }\r
- if (Status) {\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-}\r
-\r
/**\r
Update platform mode.\r
\r
}\r
\r
/**\r
- Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set\r
+ Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set\r
\r
Caution: This function may receive untrusted input.\r
This function may be invoked in SMM mode, and datasize and data are external input.\r
\r
@return EFI_INVALID_PARAMETER Invalid parameter.\r
@return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with\r
- EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.\r
+ EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.\r
@return EFI_OUT_OF_RESOURCES The Database to save the public key is full.\r
- @return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\r
+ @return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\r
set, but the AuthInfo does NOT pass the validation\r
check carried out by the firmware.\r
@return EFI_SUCCESS Variable is not write-protected or pass validation successfully.\r
)\r
{\r
EFI_STATUS Status;\r
- BOOLEAN IsDeletion;\r
- BOOLEAN IsFirstTime;\r
- UINT8 *PubKey;\r
- EFI_VARIABLE_AUTHENTICATION *CertData;\r
- EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;\r
- UINT32 KeyIndex;\r
- UINT64 MonotonicCount;\r
- VARIABLE_ENTRY_CONSISTENCY VariableDataEntry;\r
- UINT32 Index;\r
AUTH_VARIABLE_INFO OrgVariableInfo;\r
\r
- KeyIndex = 0;\r
- CertData = NULL;\r
- CertBlock = NULL;\r
- PubKey = NULL;\r
- IsDeletion = FALSE;\r
Status = EFI_SUCCESS;\r
\r
ZeroMem (&OrgVariableInfo, sizeof (OrgVariableInfo));\r
\r
if ((!EFI_ERROR (Status)) && IsDeleteAuthVariable (OrgVariableInfo.Attributes, Data, DataSize, Attributes) && UserPhysicalPresent()) {\r
//\r
- // Allow the delete operation of common authenticated variable at user physical presence.\r
+ // Allow the delete operation of common authenticated variable(AT or AW) at user physical presence.\r
//\r
Status = AuthServiceInternalUpdateVariable (\r
VariableName,\r
}\r
\r
//\r
- // A time-based authenticated variable and a count-based authenticated variable\r
- // can't be updated by each other.\r
- //\r
- if (OrgVariableInfo.Data != NULL) {\r
- if (((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) &&\r
- ((OrgVariableInfo.Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0)) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-\r
- if (((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) &&\r
- ((OrgVariableInfo.Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0)) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- }\r
-\r
- //\r
- // Process Time-based Authenticated variable.\r
- //\r
- if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ //\r
+ // Reject Counter Based Auth Variable processing request.\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ } else if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ //\r
+ // Process Time-based Authenticated variable.\r
+ //\r
return VerifyTimeBasedPayloadAndUpdate (\r
VariableName,\r
VendorGuid,\r
);\r
}\r
\r
- //\r
- // Determine if first time SetVariable with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS.\r
- //\r
- if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
- //\r
- // Determine current operation type.\r
- //\r
- if (DataSize == AUTHINFO_SIZE) {\r
- IsDeletion = TRUE;\r
- }\r
- //\r
- // Determine whether this is the first time with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.\r
- //\r
- if (OrgVariableInfo.Data == NULL) {\r
- IsFirstTime = TRUE;\r
- } else if ((OrgVariableInfo.Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
- IsFirstTime = TRUE;\r
- } else {\r
- KeyIndex = OrgVariableInfo.PubKeyIndex;\r
- IsFirstTime = FALSE;\r
- }\r
- } else if ((OrgVariableInfo.Data != NULL) &&\r
- ((OrgVariableInfo.Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) != 0)\r
- ) {\r
+ if ((OrgVariableInfo.Data != NULL) &&\r
+ ((OrgVariableInfo.Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) != 0)) {\r
//\r
// If the variable is already write-protected, it always needs authentication before update.\r
//\r
return EFI_WRITE_PROTECTED;\r
- } else {\r
- //\r
- // If without EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, set and attributes collision.\r
- // That means it is not authenticated variable, just update variable as usual.\r
- //\r
- Status = AuthServiceInternalUpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes);\r
- return Status;\r
}\r
\r
//\r
- // Get PubKey and check Monotonic Count value corresponding to the variable.\r
- //\r
- CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;\r
- CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);\r
- PubKey = CertBlock->PublicKey;\r
-\r
- //\r
- // Update Monotonic Count value.\r
+ // Not authenticated variable, just update variable as usual.\r
//\r
- MonotonicCount = CertData->MonotonicCount;\r
-\r
- if (!IsFirstTime) {\r
- //\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 (KeyIndex == 0) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- for (Index = 0; Index < mPubKeyNumber; Index++) {\r
- if (ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyIndex)) == KeyIndex) {\r
- if (CompareMem (((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyData, PubKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {\r
- break;\r
- } else {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- }\r
- }\r
- if (Index == mPubKeyNumber) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-\r
- //\r
- // Compare the current monotonic count and ensure that it is greater than the last SetVariable\r
- // operation with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute set.\r
- //\r
- if (MonotonicCount <= OrgVariableInfo.MonotonicCount) {\r
- //\r
- // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.\r
- //\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- }\r
- //\r
- // Verify the certificate in Data payload.\r
- //\r
- Status = VerifyCounterBasedPayload (Data, DataSize, PubKey);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\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, &VariableDataEntry);\r
- if (KeyIndex == 0) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
+ Status = AuthServiceInternalUpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes);\r
+ return Status;\r
\r
- //\r
- // Verification pass.\r
- //\r
- return AuthServiceInternalUpdateVariableWithMonotonicCount (VariableName, VendorGuid, (UINT8*)Data + AUTHINFO_SIZE, DataSize - AUTHINFO_SIZE, Attributes, KeyIndex, MonotonicCount);\r
}\r
\r
/**\r
AuthVarTypePayload\r
} AUTHVAR_TYPE;\r
\r
-///\r
-/// "AuthVarKeyDatabase" variable for the Public Key store\r
-/// of variables with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.\r
-///\r
-/// GUID: gEfiAuthenticatedVariableGuid\r
-///\r
-/// We need maintain atomicity.\r
-///\r
-/// Format:\r
-/// +----------------------------+\r
-/// | AUTHVAR_KEY_DB_DATA | <-- First AuthVarKey\r
-/// +----------------------------+\r
-/// | ...... |\r
-/// +----------------------------+\r
-/// | AUTHVAR_KEY_DB_DATA | <-- Last AuthKey\r
-/// +----------------------------+\r
-///\r
-#define AUTHVAR_KEYDB_NAME L"AuthVarKeyDatabase"\r
-\r
-#define EFI_CERT_TYPE_RSA2048_SHA256_SIZE 256\r
-#define EFI_CERT_TYPE_RSA2048_SIZE 256\r
-\r
-#pragma pack(1)\r
-typedef struct {\r
- UINT32 KeyIndex;\r
- UINT8 KeyData[EFI_CERT_TYPE_RSA2048_SIZE];\r
-} AUTHVAR_KEY_DB_DATA;\r
-#pragma pack()\r
-\r
///\r
/// "certdb" variable stores the signer's certificates for non PK/KEK/DB/DBX\r
/// variables with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS|EFI_VARIABLE_NON_VOLATILE set.\r
} AUTH_CERT_DB_DATA;\r
#pragma pack()\r
\r
-extern UINT8 *mPubKeyStore;\r
-extern UINT32 mPubKeyNumber;\r
-extern UINT32 mMaxKeyNumber;\r
-extern UINT32 mMaxKeyDbSize;\r
extern UINT8 *mCertDbStore;\r
extern UINT32 mMaxCertDbSize;\r
extern UINT32 mPlatformMode;\r
);\r
\r
/**\r
- Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set\r
+ Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set\r
\r
Caution: This function may receive untrusted input.\r
This function may be invoked in SMM mode, and datasize and data are external input.\r
\r
@return EFI_INVALID_PARAMETER Invalid parameter.\r
@return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with\r
- EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.\r
+ EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.\r
@return EFI_OUT_OF_RESOURCES The Database to save the public key is full.\r
- @return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\r
+ @return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\r
set, but the AuthInfo does NOT pass the validation\r
check carried out by the firmware.\r
@return EFI_SUCCESS Variable is not write-protected or pass validation successfully.\r
IN UINT32 Attributes\r
);\r
\r
-/**\r
- Update the variable region with Variable information.\r
-\r
- @param[in] VariableName Name of variable.\r
- @param[in] VendorGuid Guid of variable.\r
- @param[in] Data Data pointer.\r
- @param[in] DataSize Size of Data.\r
- @param[in] Attributes Attribute value of the variable.\r
- @param[in] KeyIndex Index of associated public key.\r
- @param[in] MonotonicCount Value of associated monotonic count.\r
-\r
- @retval EFI_SUCCESS The update operation is success.\r
- @retval EFI_INVALID_PARAMETER Invalid parameter.\r
- @retval EFI_WRITE_PROTECTED Variable is write-protected.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-AuthServiceInternalUpdateVariableWithMonotonicCount (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes,\r
- IN UINT32 KeyIndex,\r
- IN UINT64 MonotonicCount\r
- );\r
-\r
/**\r
Update the variable region with Variable information.\r
\r
///\r
/// Global database array for scratch\r
///\r
-UINT8 *mPubKeyStore;\r
-UINT32 mPubKeyNumber;\r
-UINT32 mMaxKeyNumber;\r
-UINT32 mMaxKeyDbSize;\r
UINT8 *mCertDbStore;\r
UINT32 mMaxCertDbSize;\r
UINT32 mPlatformMode;\r
sizeof (UINT8)\r
}\r
},\r
- {\r
- &gEfiAuthenticatedVariableGuid,\r
- AUTHVAR_KEYDB_NAME,\r
- {\r
- VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
- VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
- VARIABLE_ATTRIBUTE_NV_BS_RT_AW,\r
- sizeof (UINT8),\r
- MAX_UINTN\r
- }\r
- },\r
{\r
&gEfiCertDbGuid,\r
EFI_CERT_DB_NAME,\r
},\r
};\r
\r
-VOID **mAuthVarAddressPointer[10];\r
+VOID **mAuthVarAddressPointer[9];\r
\r
AUTH_VAR_LIB_CONTEXT_IN *mAuthVarLibContextIn = NULL;\r
\r
)\r
{\r
EFI_STATUS Status;\r
- UINT8 VarValue;\r
UINT32 VarAttr;\r
UINT8 *Data;\r
UINTN DataSize;\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 = (UINT32) (mAuthVarLibContextIn->MaxAuthVariableSize - sizeof (AUTHVAR_KEYDB_NAME));\r
- mMaxKeyNumber = mMaxKeyDbSize / sizeof (AUTHVAR_KEY_DB_DATA);\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
// Use EFI_CERT_DB_VOLATILE_NAME size since it is longer.\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- //\r
- // Check "AuthVarKeyDatabase" variable's existence.\r
- // If it doesn't exist, create a new one with initial value of 0 and EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.\r
- //\r
- Status = AuthServiceInternalFindVariable (\r
- AUTHVAR_KEYDB_NAME,\r
- &gEfiAuthenticatedVariableGuid,\r
- (VOID **) &Data,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;\r
- VarValue = 0;\r
- mPubKeyNumber = 0;\r
- Status = AuthServiceInternalUpdateVariable (\r
- AUTHVAR_KEYDB_NAME,\r
- &gEfiAuthenticatedVariableGuid,\r
- &VarValue,\r
- sizeof(UINT8),\r
- VarAttr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- } else {\r
- //\r
- // Load database in global variable for cache.\r
- //\r
- ASSERT ((DataSize != 0) && (Data != NULL));\r
- //\r
- // "AuthVarKeyDatabase" is an internal variable. Its DataSize is always ensured not to exceed mPubKeyStore buffer size(See definition before)\r
- // Therefore, there is no memory overflow in underlying CopyMem.\r
- //\r
- CopyMem (mPubKeyStore, (UINT8 *) Data, DataSize);\r
- mPubKeyNumber = (UINT32) (DataSize / sizeof (AUTHVAR_KEY_DB_DATA));\r
- }\r
-\r
Status = AuthServiceInternalFindVariable (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_INFO, "Variable %s does not exist.\n", EFI_PLATFORM_KEY_NAME));\r
AuthVarLibContextOut->StructSize = sizeof (AUTH_VAR_LIB_CONTEXT_OUT);\r
AuthVarLibContextOut->AuthVarEntry = mAuthVarEntry;\r
AuthVarLibContextOut->AuthVarEntryCount = ARRAY_SIZE (mAuthVarEntry);\r
- mAuthVarAddressPointer[0] = (VOID **) &mPubKeyStore;\r
- mAuthVarAddressPointer[1] = (VOID **) &mCertDbStore;\r
- mAuthVarAddressPointer[2] = (VOID **) &mHashCtx;\r
- mAuthVarAddressPointer[3] = (VOID **) &mAuthVarLibContextIn;\r
- mAuthVarAddressPointer[4] = (VOID **) &(mAuthVarLibContextIn->FindVariable),\r
- mAuthVarAddressPointer[5] = (VOID **) &(mAuthVarLibContextIn->FindNextVariable),\r
- mAuthVarAddressPointer[6] = (VOID **) &(mAuthVarLibContextIn->UpdateVariable),\r
- mAuthVarAddressPointer[7] = (VOID **) &(mAuthVarLibContextIn->GetScratchBuffer),\r
- mAuthVarAddressPointer[8] = (VOID **) &(mAuthVarLibContextIn->CheckRemainingSpaceForConsistency),\r
- mAuthVarAddressPointer[9] = (VOID **) &(mAuthVarLibContextIn->AtRuntime),\r
+ mAuthVarAddressPointer[0] = (VOID **) &mCertDbStore;\r
+ mAuthVarAddressPointer[1] = (VOID **) &mHashCtx;\r
+ mAuthVarAddressPointer[2] = (VOID **) &mAuthVarLibContextIn;\r
+ mAuthVarAddressPointer[3] = (VOID **) &(mAuthVarLibContextIn->FindVariable),\r
+ mAuthVarAddressPointer[4] = (VOID **) &(mAuthVarLibContextIn->FindNextVariable),\r
+ mAuthVarAddressPointer[5] = (VOID **) &(mAuthVarLibContextIn->UpdateVariable),\r
+ mAuthVarAddressPointer[6] = (VOID **) &(mAuthVarLibContextIn->GetScratchBuffer),\r
+ mAuthVarAddressPointer[7] = (VOID **) &(mAuthVarLibContextIn->CheckRemainingSpaceForConsistency),\r
+ mAuthVarAddressPointer[8] = (VOID **) &(mAuthVarLibContextIn->AtRuntime),\r
AuthVarLibContextOut->AddressPointer = mAuthVarAddressPointer;\r
AuthVarLibContextOut->AddressPointerCount = ARRAY_SIZE (mAuthVarAddressPointer);\r
\r
}\r
\r
/**\r
- Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.\r
+ Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.\r
\r
@param[in] VariableName Name of the variable.\r
@param[in] VendorGuid Variable vendor GUID.\r
@retval EFI_INVALID_PARAMETER Invalid parameter.\r
@retval EFI_WRITE_PROTECTED Variable is write-protected.\r
@retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
- @retval EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\r
- or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS\r
+ @retval EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS\r
set, but the AuthInfo does NOT pass the validation\r
check carried out by the firmware.\r
@retval EFI_UNSUPPORTED Unsupported to process authenticated variable.\r