]> git.proxmox.com Git - mirror_edk2.git/blobdiff - CryptoPkg/Include/Library/BaseCryptLib.h
CryptoPkg/BaseCryptLib.h: Add new API VerifyEKUsInPkcs7Signature
[mirror_edk2.git] / CryptoPkg / Include / Library / BaseCryptLib.h
index 45dac3b4c10c4ad1f9de1c8309530c8107fe96dd..f9191f6e96d33d2e0c0a2d666e79fa992ca93f9c 100644 (file)
@@ -4,14 +4,8 @@
   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 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -897,6 +891,8 @@ Sha512HashAll (
 \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
@@ -910,6 +906,36 @@ HmacMd5GetContextSize (
   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
@@ -994,11 +1020,11 @@ HmacMd5Update (
   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
@@ -1015,6 +1041,8 @@ HmacMd5Final (
 \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
@@ -1028,6 +1056,36 @@ HmacSha1GetContextSize (
   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
@@ -1112,11 +1170,11 @@ HmacSha1Update (
   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
@@ -1133,6 +1191,8 @@ HmacSha1Final (
 \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
@@ -1146,6 +1206,31 @@ HmacSha256GetContextSize (
   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
@@ -1230,11 +1315,11 @@ HmacSha256Update (
   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
@@ -1699,10 +1784,10 @@ Arc4Init (
   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
@@ -1731,10 +1816,10 @@ Arc4Encrypt (
   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
@@ -2080,6 +2165,76 @@ X509GetSubjectName (
   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
@@ -2250,6 +2405,36 @@ Pkcs5HashPassword (
   OUT UINT8        *OutKey\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
@@ -2262,10 +2447,13 @@ Pkcs5HashPassword (
   @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
@@ -2307,10 +2495,13 @@ Pkcs7FreeSigners (
   @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
@@ -2346,7 +2537,8 @@ Pkcs7GetCertificatesList (
   @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
@@ -2401,6 +2593,48 @@ Pkcs7Verify (
   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
@@ -2414,13 +2648,13 @@ Pkcs7Verify (
   @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