primitives (Hash Serials, HMAC, RSA, Diffie-Hellman, etc) for UEFI security\r
functionality enabling.\r
\r
-Copyright (c) 2009 - 2016, 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
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
\r
/**\r
Retrieves the size, in bytes, of the context buffer required for HMAC-MD5 operations.\r
+ (NOTE: This API is deprecated.\r
+ Use HmacMd5New() / HmacMd5Free() for HMAC-MD5 Context operations.)\r
\r
If this interface is not supported, then return zero.\r
\r
VOID\r
);\r
\r
+/**\r
+ Allocates and initializes one HMAC_CTX context for subsequent HMAC-MD5 use.\r
+\r
+ If this interface is not supported, then return NULL.\r
+\r
+ @return Pointer to the HMAC_CTX context that has been initialized.\r
+ If the allocations fails, HmacMd5New() returns NULL.\r
+ @retval NULL This interface is not supported.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+HmacMd5New (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Release the specified HMAC_CTX context.\r
+\r
+ If this interface is not supported, then do nothing.\r
+\r
+ @param[in] HmacMd5Ctx Pointer to the HMAC_CTX context to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+HmacMd5Free (\r
+ IN VOID *HmacMd5Ctx\r
+ );\r
+\r
/**\r
Initializes user-supplied memory pointed by HmacMd5Context as HMAC-MD5 context for\r
subsequent use.\r
finalized by HmacMd5Final(). Behavior with invalid HMAC-MD5 context is undefined.\r
\r
If HmacMd5Context is NULL, then return FALSE.\r
- If HashValue is NULL, then return FALSE.\r
+ If HmacValue is NULL, then return FALSE.\r
If this interface is not supported, then return FALSE.\r
\r
@param[in, out] HmacMd5Context Pointer to the HMAC-MD5 context.\r
- @param[out] HashValue Pointer to a buffer that receives the HMAC-MD5 digest\r
+ @param[out] HmacValue Pointer to a buffer that receives the HMAC-MD5 digest\r
value (16 bytes).\r
\r
@retval TRUE HMAC-MD5 digest computation succeeded.\r
\r
/**\r
Retrieves the size, in bytes, of the context buffer required for HMAC-SHA1 operations.\r
+ (NOTE: This API is deprecated.\r
+ Use HmacSha1New() / HmacSha1Free() for HMAC-SHA1 Context operations.)\r
\r
If this interface is not supported, then return zero.\r
\r
VOID\r
);\r
\r
+/**\r
+ Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA1 use.\r
+\r
+ If this interface is not supported, then return NULL.\r
+\r
+ @return Pointer to the HMAC_CTX context that has been initialized.\r
+ If the allocations fails, HmacSha1New() returns NULL.\r
+ @return NULL This interface is not supported.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+HmacSha1New (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Release the specified HMAC_CTX context.\r
+\r
+ If this interface is not supported, then do nothing.\r
+\r
+ @param[in] HmacSha1Ctx Pointer to the HMAC_CTX context to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+HmacSha1Free (\r
+ IN VOID *HmacSha1Ctx\r
+ );\r
+\r
/**\r
Initializes user-supplied memory pointed by HmacSha1Context as HMAC-SHA1 context for\r
subsequent use.\r
not be finalized by HmacSha1Final(). Behavior with invalid HMAC-SHA1 context is undefined.\r
\r
If HmacSha1Context is NULL, then return FALSE.\r
- If HashValue is NULL, then return FALSE.\r
+ If HmacValue is NULL, then return FALSE.\r
If this interface is not supported, then return FALSE.\r
\r
@param[in, out] HmacSha1Context Pointer to the HMAC-SHA1 context.\r
- @param[out] HashValue Pointer to a buffer that receives the HMAC-SHA1 digest\r
+ @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA1 digest\r
value (20 bytes).\r
\r
@retval TRUE HMAC-SHA1 digest computation succeeded.\r
\r
/**\r
Retrieves the size, in bytes, of the context buffer required for HMAC-SHA256 operations.\r
+ (NOTE: This API is deprecated.\r
+ Use HmacSha256New() / HmacSha256Free() for HMAC-SHA256 Context operations.)\r
\r
If this interface is not supported, then return zero.\r
\r
VOID\r
);\r
\r
+/**\r
+ Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA256 use.\r
+\r
+ @return Pointer to the HMAC_CTX context that has been initialized.\r
+ If the allocations fails, HmacSha256New() returns NULL.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+HmacSha256New (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Release the specified HMAC_CTX context.\r
+\r
+ @param[in] HmacSha256Ctx Pointer to the HMAC_CTX context to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+HmacSha256Free (\r
+ IN VOID *HmacSha256Ctx\r
+ );\r
+\r
/**\r
Initializes user-supplied memory pointed by HmacSha256Context as HMAC-SHA256 context for\r
subsequent use.\r
not be finalized by HmacSha256Final(). Behavior with invalid HMAC-SHA256 context is undefined.\r
\r
If HmacSha256Context is NULL, then return FALSE.\r
- If HashValue is NULL, then return FALSE.\r
+ If HmacValue is NULL, then return FALSE.\r
If this interface is not supported, then return FALSE.\r
\r
@param[in, out] HmacSha256Context Pointer to the HMAC-SHA256 context.\r
- @param[out] HashValue Pointer to a buffer that receives the HMAC-SHA256 digest\r
+ @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA256 digest\r
value (32 bytes).\r
\r
@retval TRUE HMAC-SHA256 digest computation succeeded.\r
If Output is NULL, then return FALSE.\r
If this interface is not supported, then return FALSE.\r
\r
- @param[in] Arc4Context Pointer to the ARC4 context.\r
- @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
- @param[in] InputSize Size of the Input buffer in bytes.\r
- @param[out] Output Pointer to a buffer that receives the ARC4 encryption output.\r
+ @param[in, out] Arc4Context Pointer to the ARC4 context.\r
+ @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
+ @param[in] InputSize Size of the Input buffer in bytes.\r
+ @param[out] Output Pointer to a buffer that receives the ARC4 encryption output.\r
\r
@retval TRUE ARC4 encryption succeeded.\r
@retval FALSE ARC4 encryption failed.\r
If Output is NULL, then return FALSE.\r
If this interface is not supported, then return FALSE.\r
\r
- @param[in] Arc4Context Pointer to the ARC4 context.\r
- @param[in] Input Pointer to the buffer containing the data to be decrypted.\r
- @param[in] InputSize Size of the Input buffer in bytes.\r
- @param[out] Output Pointer to a buffer that receives the ARC4 decryption output.\r
+ @param[in, out] Arc4Context Pointer to the ARC4 context.\r
+ @param[in] Input Pointer to the buffer containing the data to be decrypted.\r
+ @param[in] InputSize Size of the Input buffer in bytes.\r
+ @param[out] Output Pointer to a buffer that receives the ARC4 decryption output.\r
\r
@retval TRUE ARC4 decryption succeeded.\r
@retval FALSE ARC4 decryption failed.\r
IN OUT UINTN *SubjectSize\r
);\r
\r
+/**\r
+ Retrieve the common name (CN) string from one X.509 certificate.\r
+\r
+ @param[in] Cert Pointer to the DER-encoded X509 certificate.\r
+ @param[in] CertSize Size of the X509 certificate in bytes.\r
+ @param[out] CommonName Buffer to contain the retrieved certificate common\r
+ name string (UTF8). At most CommonNameSize bytes will be\r
+ written and the string will be null terminated. May be\r
+ NULL in order to determine the size buffer needed.\r
+ @param[in,out] CommonNameSize The size in bytes of the CommonName buffer on input,\r
+ and the size of buffer returned CommonName on output.\r
+ If CommonName is NULL then the amount of space needed\r
+ in buffer (including the final null) is returned.\r
+\r
+ @retval RETURN_SUCCESS The certificate CommonName retrieved successfully.\r
+ @retval RETURN_INVALID_PARAMETER If Cert is NULL.\r
+ If CommonNameSize is NULL.\r
+ If CommonName is not NULL and *CommonNameSize is 0.\r
+ If Certificate is invalid.\r
+ @retval RETURN_NOT_FOUND If no CommonName entry exists.\r
+ @retval RETURN_BUFFER_TOO_SMALL If the CommonName is NULL. The required buffer size\r
+ (including the final null) is returned in the\r
+ CommonNameSize parameter.\r
+ @retval RETURN_UNSUPPORTED The operation is not supported.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+X509GetCommonName (\r
+ IN CONST UINT8 *Cert,\r
+ IN UINTN CertSize,\r
+ OUT CHAR8 *CommonName, OPTIONAL\r
+ IN OUT UINTN *CommonNameSize\r
+ );\r
+\r
+/**\r
+ Retrieve the organization name (O) string from one X.509 certificate.\r
+\r
+ @param[in] Cert Pointer to the DER-encoded X509 certificate.\r
+ @param[in] CertSize Size of the X509 certificate in bytes.\r
+ @param[out] NameBuffer Buffer to contain the retrieved certificate organization\r
+ name string. At most NameBufferSize bytes will be\r
+ written and the string will be null terminated. May be\r
+ NULL in order to determine the size buffer needed.\r
+ @param[in,out] NameBufferSize The size in bytes of the Name buffer on input,\r
+ and the size of buffer returned Name on output.\r
+ If NameBuffer is NULL then the amount of space needed\r
+ in buffer (including the final null) is returned.\r
+\r
+ @retval RETURN_SUCCESS The certificate Organization Name retrieved successfully.\r
+ @retval RETURN_INVALID_PARAMETER If Cert is NULL.\r
+ If NameBufferSize is NULL.\r
+ If NameBuffer is not NULL and *CommonNameSize is 0.\r
+ If Certificate is invalid.\r
+ @retval RETURN_NOT_FOUND If no Organization Name entry exists.\r
+ @retval RETURN_BUFFER_TOO_SMALL If the NameBuffer is NULL. The required buffer size\r
+ (including the final null) is returned in the\r
+ CommonNameSize parameter.\r
+ @retval RETURN_UNSUPPORTED The operation is not supported.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+X509GetOrganizationName (\r
+ IN CONST UINT8 *Cert,\r
+ IN UINTN CertSize,\r
+ OUT CHAR8 *NameBuffer, OPTIONAL\r
+ IN OUT UINTN *NameBufferSize\r
+ );\r
+\r
/**\r
Verify one X509 certificate was issued by the trusted CA.\r
\r
OUT UINT8 *OutKey\r
);\r
\r
+/**\r
+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the\r
+ encrypted message in a newly allocated buffer.\r
+\r
+ Things that can cause a failure include:\r
+ - X509 key size does not match any known key size.\r
+ - Fail to parse X509 certificate.\r
+ - Fail to allocate an intermediate buffer.\r
+ - Null pointer provided for a non-optional parameter.\r
+ - Data size is too large for the provided key size (max size is a function of key size\r
+ and hash digest size).\r
+\r
+ @param[in] PublicKey A pointer to the DER-encoded X509 certificate that\r
+ will be used to encrypt the data.\r
+ @param[in] PublicKeySize Size of the X509 cert buffer.\r
+ @param[in] InData Data to be encrypted.\r
+ @param[in] InDataSize Size of the data buffer.\r
+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer\r
+ to be used when initializing the PRNG. NULL otherwise.\r
+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.\r
+ 0 otherwise.\r
+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted\r
+ message.\r
+ @param[out] EncryptedDataSize Size of the encrypted message buffer.\r
+\r
+ @retval TRUE Encryption was successful.\r
+ @retval FALSE Encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Pkcs1v2Encrypt (\r
+ IN CONST UINT8 *PublicKey,\r
+ IN UINTN PublicKeySize,\r
+ IN UINT8 *InData,\r
+ IN UINTN InDataSize,\r
+ IN CONST UINT8 *PrngSeed, OPTIONAL\r
+ IN UINTN PrngSeedSize, OPTIONAL\r
+ OUT UINT8 **EncryptedData,\r
+ OUT UINTN *EncryptedDataSize\r
+ );\r
+\r
+/**\r
+ The 3rd parameter of Pkcs7GetSigners will return all embedded\r
+ X.509 certificate in one given PKCS7 signature. The format is:\r
+ //\r
+ // UINT8 CertNumber;\r
+ // UINT32 Cert1Length;\r
+ // UINT8 Cert1[];\r
+ // UINT32 Cert2Length;\r
+ // UINT8 Cert2[];\r
+ // ...\r
+ // UINT32 CertnLength;\r
+ // UINT8 Certn[];\r
+ //\r
+\r
+ The two following C-structure are used for parsing CertStack more clearly.\r
+**/\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+ UINT32 CertDataLength; // The length in bytes of X.509 certificate.\r
+ UINT8 CertDataBuffer[0]; // The X.509 certificate content (DER).\r
+} EFI_CERT_DATA;\r
+\r
+typedef struct {\r
+ UINT8 CertNumber; // Number of X.509 certificate.\r
+ //EFI_CERT_DATA CertArray[]; // An array of X.509 certificate.\r
+} EFI_CERT_STACK;\r
+\r
+#pragma pack()\r
+\r
/**\r
Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7:\r
Cryptographic Message Syntax Standard". The input signed data could be wrapped\r
@param[in] P7Data Pointer to the PKCS#7 message to verify.\r
@param[in] P7Length Length of the PKCS#7 message in bytes.\r
@param[out] CertStack Pointer to Signer's certificates retrieved from P7Data.\r
- It's caller's responsibility to free the buffer.\r
+ It's caller's responsibility to free the buffer with\r
+ Pkcs7FreeSigners().\r
+ This data structure is EFI_CERT_STACK type.\r
@param[out] StackLength Length of signer's certificates in bytes.\r
@param[out] TrustedCert Pointer to a trusted certificate from Signer's certificates.\r
- It's caller's responsibility to free the buffer.\r
+ It's caller's responsibility to free the buffer with\r
+ Pkcs7FreeSigners().\r
@param[out] CertLength Length of the trusted certificate in bytes.\r
\r
@retval TRUE The operation is finished successfully.\r
@param[in] P7Data Pointer to the PKCS#7 message.\r
@param[in] P7Length Length of the PKCS#7 message in bytes.\r
@param[out] SignerChainCerts Pointer to the certificates list chained to signer's\r
- certificate. It's caller's responsibility to free the buffer.\r
+ certificate. It's caller's responsibility to free the buffer\r
+ with Pkcs7FreeSigners().\r
+ This data structure is EFI_CERT_STACK type.\r
@param[out] ChainLength Length of the chained certificates list buffer in bytes.\r
@param[out] UnchainCerts Pointer to the unchained certificates lists. It's caller's\r
- responsibility to free the buffer.\r
+ responsibility to free the buffer with Pkcs7FreeSigners().\r
+ This data structure is EFI_CERT_STACK type.\r
@param[out] UnchainLength Length of the unchained certificates list buffer in bytes.\r
\r
@retval TRUE The operation is finished successfully.\r
@param[in] OtherCerts Pointer to an optional additional set of certificates to\r
include in the PKCS#7 signedData (e.g. any intermediate\r
CAs in the chain).\r
- @param[out] SignedData Pointer to output PKCS#7 signedData.\r
+ @param[out] SignedData Pointer to output PKCS#7 signedData. It's caller's\r
+ responsibility to free the buffer with FreePool().\r
@param[out] SignedDataSize Size of SignedData in bytes.\r
\r
@retval TRUE PKCS#7 data signing succeeded.\r
IN UINTN DataLength\r
);\r
\r
+/**\r
+ This function receives a PKCS7 formatted signature, and then verifies that\r
+ the specified Enhanced or Extended Key Usages (EKU's) are present in the end-entity\r
+ leaf signing certificate.\r
+ Note that this function does not validate the certificate chain.\r
+\r
+ Applications for custom EKU's are quite flexible. For example, a policy EKU\r
+ may be present in an Issuing Certificate Authority (CA), and any sub-ordinate\r
+ certificate issued might also contain this EKU, thus constraining the\r
+ sub-ordinate certificate. Other applications might allow a certificate\r
+ embedded in a device to specify that other Object Identifiers (OIDs) are\r
+ present which contains binary data specifying custom capabilities that\r
+ the device is able to do.\r
+\r
+ @param[in] Pkcs7Signature The PKCS#7 signed information content block. An array\r
+ containing the content block with both the signature,\r
+ the signer's certificate, and any necessary intermediate\r
+ certificates.\r
+ @param[in] Pkcs7SignatureSize Number of bytes in Pkcs7Signature.\r
+ @param[in] RequiredEKUs Array of null-terminated strings listing OIDs of\r
+ required EKUs that must be present in the signature.\r
+ @param[in] RequiredEKUsSize Number of elements in the RequiredEKUs string array.\r
+ @param[in] RequireAllPresent If this is TRUE, then all of the specified EKU's\r
+ must be present in the leaf signer. If it is\r
+ FALSE, then we will succeed if we find any\r
+ of the specified EKU's.\r
+\r
+ @retval EFI_SUCCESS The required EKUs were found in the signature.\r
+ @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
+ @retval EFI_NOT_FOUND One or more EKU's were not found in the signature.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+VerifyEKUsInPkcs7Signature (\r
+ IN CONST UINT8 *Pkcs7Signature,\r
+ IN CONST UINT32 SignatureSize,\r
+ IN CONST CHAR8 *RequiredEKUs[],\r
+ IN CONST UINT32 RequiredEKUsSize,\r
+ IN BOOLEAN RequireAllPresent\r
+ );\r
+\r
/**\r
Extracts the attached content from a PKCS#7 signed data if existed. The input signed\r
data could be wrapped in a ContentInfo structure.\r
@param[in] P7Data Pointer to the PKCS#7 signed data to process.\r
@param[in] P7Length Length of the PKCS#7 signed data in bytes.\r
@param[out] Content Pointer to the extracted content from the PKCS#7 signedData.\r
- It's caller's responsibility to free the buffer.\r
+ It's caller's responsibility to free the buffer with FreePool().\r
@param[out] ContentSize The size of the extracted content in bytes.\r
\r
@retval TRUE The P7Data was correctly formatted for processing.\r
@retval FALSE The P7Data was not correctly formatted for processing.\r
\r
-*/\r
+**/\r
BOOLEAN\r
EFIAPI\r
Pkcs7GetAttachedContent (\r