2 Common interfaces to call Security library.
4 Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "IpSecCryptIo.h"
18 // The informations for the supported Encrypt/Decrpt Alogrithm.
20 GLOBAL_REMOVE_IF_UNREFERENCED ENCRYPT_ALGORITHM mIpsecEncryptAlgorithmList
[IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE
] = {
21 {IKE_EALG_NULL
, 0, 0, 1, NULL
, NULL
, NULL
, NULL
},
22 {IKE_EALG_NONE
, 0, 0, 1, NULL
, NULL
, NULL
, NULL
},
23 {IKE_EALG_3DESCBC
, 24, 8, 8, TdesGetContextSize
, TdesInit
, TdesCbcEncrypt
, TdesCbcDecrypt
},
24 {IKE_EALG_AESCBC
, 16, 16, 16, AesGetContextSize
, AesInit
, AesCbcEncrypt
, AesCbcDecrypt
}
28 // The informations for the supported Authentication algorithm
30 GLOBAL_REMOVE_IF_UNREFERENCED AUTH_ALGORITHM mIpsecAuthAlgorithmList
[IPSEC_AUTH_ALGORITHM_LIST_SIZE
] = {
31 {IKE_AALG_NONE
, 0, 0, 0, NULL
, NULL
, NULL
, NULL
},
32 {IKE_AALG_NULL
, 0, 0, 0, NULL
, NULL
, NULL
, NULL
},
33 {IKE_AALG_SHA1HMAC
, 20, 12, 64, HmacSha1GetContextSize
, HmacSha1Init
, HmacSha1Update
, HmacSha1Final
}
37 // The information for the supported Hash aglorithm
39 GLOBAL_REMOVE_IF_UNREFERENCED HASH_ALGORITHM mIpsecHashAlgorithmList
[IPSEC_HASH_ALGORITHM_LIST_SIZE
] = {
40 {IKE_AALG_NONE
, 0, 0, 0, NULL
, NULL
, NULL
, NULL
},
41 {IKE_AALG_NULL
, 0, 0, 0, NULL
, NULL
, NULL
, NULL
},
42 {IKE_AALG_SHA1HMAC
, 20, 12, 64, Sha1GetContextSize
, Sha1Init
, Sha1Update
, Sha1Final
}
45 BOOLEAN mInitialRandomSeed
= FALSE
;
48 Get the block size of specified encryption algorithm.
50 @param[in] AlgorithmId The encryption algorithm ID.
52 @return The value of block size.
56 IpSecGetEncryptBlockSize (
62 for (Index
= 0; Index
< IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE
; Index
++) {
63 if (AlgorithmId
== mIpsecEncryptAlgorithmList
[Index
].AlgorithmId
) {
64 return mIpsecEncryptAlgorithmList
[Index
].BlockSize
;
72 Get the key length of the specified encryption algorithm.
74 @param[in] AlgorithmId The encryption algorithm ID.
76 @return The value of key length.
80 IpSecGetEncryptKeyLength (
86 for (Index
= 0; Index
< IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE
; Index
++) {
87 if (AlgorithmId
== mIpsecEncryptAlgorithmList
[Index
].AlgorithmId
) {
88 return mIpsecEncryptAlgorithmList
[Index
].KeyLength
;
96 Get the IV size of the specified encryption algorithm.
98 @param[in] AlgorithmId The encryption algorithm ID.
100 @return The value of IV size.
104 IpSecGetEncryptIvLength (
110 for (Index
= 0; Index
< IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE
; Index
++) {
111 if (AlgorithmId
== mIpsecEncryptAlgorithmList
[Index
].AlgorithmId
) {
112 return mIpsecEncryptAlgorithmList
[Index
].IvLength
;
120 Get the HMAC digest length by the specified Algorithm ID.
122 @param[in] AlgorithmId The specified Alogrithm ID.
124 @return The digest length of the specified Authentication Algorithm ID.
128 IpSecGetHmacDigestLength (
134 for (Index
= 0; Index
< IPSEC_AUTH_ALGORITHM_LIST_SIZE
; Index
++) {
135 if (mIpsecAuthAlgorithmList
[Index
].AlgorithmId
== AlgorithmId
) {
137 // Return the Digest Length of the Algorithm.
139 return mIpsecAuthAlgorithmList
[Index
].DigestLength
;
147 Get the ICV size of the specified Authenticaion algorithm.
149 @param[in] AlgorithmId The Authentication algorithm ID.
151 @return The value of ICV size.
161 for (Index
= 0; Index
< IPSEC_AUTH_ALGORITHM_LIST_SIZE
; Index
++) {
162 if (AlgorithmId
== mIpsecAuthAlgorithmList
[Index
].AlgorithmId
) {
163 return mIpsecAuthAlgorithmList
[Index
].IcvLength
;
171 Generate a random data for IV. If the IvSize is zero, not needed to create
172 IV and return EFI_SUCCESS.
174 @param[in] IvBuffer The pointer of the IV buffer.
175 @param[in] IvSize The IV size in bytes.
177 @retval EFI_SUCCESS Create a random data for IV.
187 return IpSecCryptoIoGenerateRandomBytes (IvBuffer
, IvSize
);
194 Get index of the specified encryption algorithm from the mIpsecEncryptAlgorithmList.
196 @param[in] AlgorithmId The encryption algorithm ID.
202 IpSecGetIndexFromEncList (
208 for (Index
= 0; Index
< IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE
; Index
++) {
209 if (AlgorithmId
== mIpsecEncryptAlgorithmList
[Index
].AlgorithmId
) {
218 Get index of the specified encryption algorithm from the mIpsecAuthAlgorithmList.
220 @param[in] AlgorithmId The encryption algorithm ID.
226 IpSecGetIndexFromAuthList (
232 for (Index
= 0; Index
< IPSEC_AUTH_ALGORITHM_LIST_SIZE
; Index
++) {
233 if (AlgorithmId
== mIpsecAuthAlgorithmList
[Index
].AlgorithmId
) {
235 // The BlockSize is same with IvSize.
247 This function calls relevant encryption interface from CryptoLib according to
248 the input algorithm ID. The InData should be multiple of block size. This function
249 doesn't perform the padding. If it has the Ivec data, the length of it should be
250 same with the block size. The block size is different from the different algorithm.
252 @param[in] AlgorithmId The Algorithm identification defined in RFC.
253 @param[in] Key Pointer to the buffer containing encrypting key.
254 @param[in] KeyBits The length of the key in bits.
255 @param[in] Ivec Point to the buffer containing the Initialization
257 @param[in] InData Point to the buffer containing the data to be
259 @param[in] InDataLength The length of InData in Bytes.
260 @param[out] OutData Point to the buffer that receives the encryption
263 @retval EFI_UNSUPPORTED The input Algorithm is not supported.
264 @retval EFI_OUT_OF_RESOURCE The required resource can't be allocated.
265 @retval EFI_SUCCESS The operation completed successfully.
269 IpSecCryptoIoEncrypt (
270 IN CONST UINT8 AlgorithmId
,
272 IN CONST UINTN KeyBits
,
273 IN CONST UINT8
*Ivec
, OPTIONAL
275 IN UINTN InDataLength
,
284 Status
= EFI_UNSUPPORTED
;
286 switch (AlgorithmId
) {
290 CopyMem (OutData
, InData
, InDataLength
);
293 case IKE_EALG_3DESCBC
:
294 case IKE_EALG_AESCBC
:
295 Index
= IpSecGetIndexFromEncList (AlgorithmId
);
302 ContextSize
= mIpsecEncryptAlgorithmList
[Index
].CipherGetContextSize ();
303 Context
= AllocateZeroPool (ContextSize
);
305 if (Context
== NULL
) {
306 return EFI_OUT_OF_RESOURCES
;
311 if (mIpsecEncryptAlgorithmList
[Index
].CipherInitiate (Context
, Key
, KeyBits
)) {
312 if (mIpsecEncryptAlgorithmList
[Index
].CipherEncrypt (Context
, InData
, InDataLength
, Ivec
, OutData
)) {
313 Status
= EFI_SUCCESS
;
323 if (Context
!= NULL
) {
333 This function calls relevant Decryption interface from CryptoLib according to
334 the input algorithm ID. The InData should be multiple of block size. This function
335 doesn't perform the padding. If it has the Ivec data, the length of it should be
336 same with the block size. The block size is different from the different algorithm.
338 @param[in] AlgorithmId The Algorithm identification defined in RFC.
339 @param[in] Key Pointer to the buffer containing encrypting key.
340 @param[in] KeyBits The length of the key in bits.
341 @param[in] Ivec Point to the buffer containing the Initialization
343 @param[in] InData Point to the buffer containing the data to be
345 @param[in] InDataLength The length of InData in Bytes.
346 @param[out] OutData Pointer to the buffer that receives the decryption
349 @retval EFI_UNSUPPORTED The input Algorithm is not supported.
350 @retval EFI_OUT_OF_RESOURCE The required resource can't be allocated.
351 @retval EFI_SUCCESS The operation completed successfully.
355 IpSecCryptoIoDecrypt (
356 IN CONST UINT8 AlgorithmId
,
358 IN CONST UINTN KeyBits
,
359 IN CONST UINT8
*Ivec
, OPTIONAL
361 IN UINTN InDataLength
,
370 Status
= EFI_UNSUPPORTED
;
372 switch (AlgorithmId
) {
376 CopyMem (OutData
, InData
, InDataLength
);
379 case IKE_EALG_3DESCBC
:
380 case IKE_EALG_AESCBC
:
381 Index
= IpSecGetIndexFromEncList(AlgorithmId
);
389 ContextSize
= mIpsecEncryptAlgorithmList
[Index
].CipherGetContextSize();
390 Context
= AllocateZeroPool (ContextSize
);
391 if (Context
== NULL
) {
392 return EFI_OUT_OF_RESOURCES
;
398 if (mIpsecEncryptAlgorithmList
[Index
].CipherInitiate (Context
, Key
, KeyBits
)) {
399 if (mIpsecEncryptAlgorithmList
[Index
].CipherDecrypt (Context
, InData
, InDataLength
, Ivec
, OutData
)) {
400 Status
= EFI_SUCCESS
;
409 if (Context
!= NULL
) {
417 Digests the Payload with key and store the result into the OutData.
419 This function calls relevant Hmac interface from CryptoLib according to
420 the input algorithm ID. It computes all datas from InDataFragment and output
421 the result into the OutData buffer. If the OutDataSize is larger than the related
422 HMAC algorithm output size, return EFI_INVALID_PARAMETER.
424 @param[in] AlgorithmId The authentication Identification.
425 @param[in] Key Pointer of the authentication key.
426 @param[in] KeyLength The length of the Key in bytes.
427 @param[in] InDataFragment The list contains all data to be authenticated.
428 @param[in] FragmentCount The size of the InDataFragment.
429 @param[out] OutData For in, the buffer to receive the output data.
430 For out, the buffer contains the authenticated data.
431 @param[in] OutDataSize The size of the buffer of OutData.
433 @retval EFI_UNSUPPORTED If the AuthAlg is not in the support list.
434 @retval EFI_INVALID_PARAMETER The OutData buffer size is larger than algorithm digest size.
435 @retval EFI_SUCCESS Authenticate the payload successfully.
436 @retval otherwise Authentication of the payload fails.
441 IN CONST UINT8 AlgorithmId
,
444 IN HASH_DATA_FRAGMENT
*InDataFragment
,
445 IN UINTN FragmentCount
,
458 Status
= EFI_UNSUPPORTED
;
461 OutHashSize
= IpSecGetHmacDigestLength (AlgorithmId
);
463 // If the expected hash data size is larger than the related Hash algorithm
464 // output length, return EFI_INVALID_PARAMETER.
466 if (OutDataSize
> OutHashSize
) {
467 return EFI_INVALID_PARAMETER
;
469 OutHashData
= AllocatePool (OutHashSize
);
471 if (OutHashData
== NULL
) {
472 return EFI_OUT_OF_RESOURCES
;
475 switch (AlgorithmId
) {
481 case IKE_AALG_SHA1HMAC
:
482 Index
= IpSecGetIndexFromAuthList (AlgorithmId
);
490 ContextSize
= mIpsecAuthAlgorithmList
[Index
].HmacGetContextSize();
491 HashContext
= AllocateZeroPool (ContextSize
);
493 if (HashContext
== NULL
) {
494 Status
= EFI_OUT_OF_RESOURCES
;
499 // Initiate HMAC context and hash the input data.
501 if (mIpsecAuthAlgorithmList
[Index
].HmacInitiate(HashContext
, Key
, KeyLength
)) {
502 for (FragmentIndex
= 0; FragmentIndex
< FragmentCount
; FragmentIndex
++) {
503 if (!mIpsecAuthAlgorithmList
[Index
].HmacUpdate (
505 InDataFragment
[FragmentIndex
].Data
,
506 InDataFragment
[FragmentIndex
].DataSize
512 if (mIpsecAuthAlgorithmList
[Index
].HmacFinal (HashContext
, OutHashData
)) {
514 // In some cases, like the Icv computing, the Icv size might be less than
515 // the key length size, so copy the part of hash data to the OutData.
517 CopyMem (OutData
, OutHashData
, OutDataSize
);
518 Status
= EFI_SUCCESS
;
529 if (HashContext
!= NULL
) {
530 FreePool (HashContext
);
532 if (OutHashData
!= NULL
) {
533 FreePool (OutHashData
);
540 Digests the Payload and store the result into the OutData.
542 This function calls relevant Hash interface from CryptoLib according to
543 the input algorithm ID. It computes all datas from InDataFragment and output
544 the result into the OutData buffer. If the OutDataSize is larger than the related
545 Hash algorithm output size, return EFI_INVALID_PARAMETER.
547 @param[in] AlgorithmId The authentication Identification.
548 @param[in] InDataFragment A list contains all data to be authenticated.
549 @param[in] FragmentCount The size of the InDataFragment.
550 @param[out] OutData For in, the buffer to receive the output data.
551 For out, the buffer contains the authenticated data.
552 @param[in] OutDataSize The size of the buffer of OutData.
554 @retval EFI_UNSUPPORTED If the AuthAlg is not in the support list.
555 @retval EFI_SUCCESS Authenticated the payload successfully.
556 @retval EFI_INVALID_PARAMETER If the OutDataSize is larger than the related Hash
557 algorithm could handle.
558 @retval otherwise Authentication of the payload failed.
563 IN CONST UINT8 AlgorithmId
,
564 IN HASH_DATA_FRAGMENT
*InDataFragment
,
565 IN UINTN FragmentCount
,
578 Status
= EFI_UNSUPPORTED
;
581 OutHashSize
= IpSecGetHmacDigestLength (AlgorithmId
);
583 // If the expected hash data size is larger than the related Hash algorithm
584 // output length, return EFI_INVALID_PARAMETER.
586 if (OutDataSize
> OutHashSize
) {
587 return EFI_INVALID_PARAMETER
;
589 OutHashData
= AllocatePool (OutHashSize
);
590 if (OutHashData
== NULL
) {
591 return EFI_OUT_OF_RESOURCES
;
594 switch (AlgorithmId
) {
600 case IKE_AALG_SHA1HMAC
:
601 Index
= IpSecGetIndexFromAuthList (AlgorithmId
);
608 ContextSize
= mIpsecHashAlgorithmList
[Index
].HashGetContextSize();
609 HashContext
= AllocateZeroPool (ContextSize
);
610 if (HashContext
== NULL
) {
611 Status
= EFI_OUT_OF_RESOURCES
;
616 // Initiate Hash context and hash the input data.
618 if (mIpsecHashAlgorithmList
[Index
].HashInitiate(HashContext
)) {
619 for (FragmentIndex
= 0; FragmentIndex
< FragmentCount
; FragmentIndex
++) {
620 if (!mIpsecHashAlgorithmList
[Index
].HashUpdate (
622 InDataFragment
[FragmentIndex
].Data
,
623 InDataFragment
[FragmentIndex
].DataSize
629 if (mIpsecHashAlgorithmList
[Index
].HashFinal (HashContext
, OutHashData
)) {
631 // In some cases, like the Icv computing, the Icv size might be less than
632 // the key length size, so copy the part of hash data to the OutData.
634 CopyMem (OutData
, OutHashData
, OutDataSize
);
635 Status
= EFI_SUCCESS
;
646 if (HashContext
!= NULL
) {
647 FreePool (HashContext
);
649 if (OutHashData
!= NULL
) {
650 FreePool (OutHashData
);
657 Generates the Diffie-Hellman public key.
659 This function first initiate a DHContext, then call the DhSetParameter() to set
660 the prime and primelength, at end call the DhGenerateKey() to generates random
661 secret exponent, and computes the public key. The output returned via parameter
662 PublicKey and PublicKeySize. DH context is updated accordingly. If the PublicKey
663 buffer is too small to hold the public key, EFI_INVALID_PARAMETER is returned
664 and PublicKeySize is set to the required buffer size to obtain the public key.
666 @param[in, out] DhContext Pointer to the DH context.
667 @param[in] Generator Value of generator.
668 @param[in] PrimeLength Length in bits of prime to be generated.
669 @param[in] Prime Pointer to the buffer to receive the generated
671 @param[out] PublicKey Pointer to the buffer to receive generated public key.
672 @param[in, out] PublicKeySize For in, the size of PublicKey buffer in bytes.
673 For out, the size of data returned in PublicKey
676 @retval EFI_SUCCESS The operation performs successfully.
677 @retval Otherwise The operation is failed.
681 IpSecCryptoIoDhGetPublicKey (
682 IN OUT UINT8
**DhContext
,
684 IN UINTN PrimeLength
,
685 IN CONST UINT8
*Prime
,
686 OUT UINT8
*PublicKey
,
687 IN OUT UINTN
*PublicKeySize
692 *DhContext
= DhNew ();
693 ASSERT (*DhContext
!= NULL
);
694 if (!DhSetParameter (*DhContext
, Generator
, PrimeLength
, Prime
)) {
695 Status
= EFI_INVALID_PARAMETER
;
699 if (!DhGenerateKey (*DhContext
, PublicKey
, PublicKeySize
)) {
700 Status
= EFI_INVALID_PARAMETER
;
706 if (*DhContext
!= NULL
) {
715 Generates exchanged common key.
717 Given peer's public key, this function computes the exchanged common key, based
718 on its own context including value of prime modulus and random secret exponent.
720 @param[in, out] DhContext Pointer to the DH context.
721 @param[in] PeerPublicKey Pointer to the peer's Public Key.
722 @param[in] PeerPublicKeySize Size of peer's public key in bytes.
723 @param[out] Key Pointer to the buffer to receive generated key.
724 @param[in, out] KeySize For in, the size of Key buffer in bytes.
725 For out, the size of data returned in Key
728 @retval EFI_SUCCESS The operation performs successfully.
729 @retval Otherwise The operation is failed.
733 IpSecCryptoIoDhComputeKey (
734 IN OUT UINT8
*DhContext
,
735 IN CONST UINT8
*PeerPublicKey
,
736 IN UINTN PeerPublicKeySize
,
738 IN OUT UINTN
*KeySize
741 if (!DhComputeKey (DhContext
, PeerPublicKey
, PeerPublicKeySize
, Key
, KeySize
)) {
742 return EFI_INVALID_PARAMETER
;
749 Releases the DH context. If DhContext is NULL, return EFI_INVALID_PARAMETER.
751 @param[in, out] DhContext Pointer to the DH context to be freed.
753 @retval EFI_SUCCESS The operation performs successfully.
754 @retval EFI_INVALID_PARAMETER The DhContext is NULL.
758 IpSecCryptoIoFreeDh (
759 IN OUT UINT8
**DhContext
762 if (*DhContext
== NULL
) {
763 return EFI_INVALID_PARAMETER
;
771 Generates random numbers of specified size.
773 If the Random Generator wasn't initiated, initiate it first, then call RandomBytes.
775 @param[out] OutBuffer Pointer to buffer to receive random value.
776 @param[in] Bytes Size of random bytes to generate.
778 @retval EFI_SUCCESS The operation performs successfully.
779 @retval Otherwise The operation is failed.
783 IpSecCryptoIoGenerateRandomBytes (
784 OUT UINT8
* OutBuffer
,
788 if (!mInitialRandomSeed
) {
789 RandomSeed (NULL
, 0);
790 mInitialRandomSeed
= TRUE
;
792 if (RandomBytes (OutBuffer
, Bytes
)) {
795 return EFI_INVALID_PARAMETER
;
800 Authenticate data with the certificate.
802 @param[in] InData Pointer to the Data to be signed.
803 @param[in] InDataSize InData size in bytes.
804 @param[in] PrivateKey Pointer to the private key.
805 @param[in] PrivateKeySize The size of Private Key in bytes.
806 @param[in] KeyPassWord Pointer to the password for retrieving private key.
807 @param[in] KeyPwdSize The size of Key Password in bytes.
808 @param[out] OutData The pointer to the signed data.
809 @param[in, out] OutDataSize Pointer to contain the size of out data.
813 IpSecCryptoIoAuthDataWithCertificate (
816 IN UINT8
*PrivateKey
,
817 IN UINTN PrivateKeySize
,
818 IN UINT8
*KeyPassWord
,
821 IN OUT UINTN
*OutDataSize
832 // Retrieve RSA Private Key from password-protected PEM data
834 RsaGetPrivateKeyFromPem (
835 (CONST UINT8
*)PrivateKey
,
837 (CONST CHAR8
*)KeyPassWord
,
838 (VOID
**) &RsaContext
840 if (RsaContext
== NULL
) {
848 if (!RsaPkcs1Sign (RsaContext
, InData
, InDataSize
, Signature
, &SigSize
)) {
849 Signature
= AllocateZeroPool (SigSize
);
854 RsaPkcs1Sign (RsaContext
, InData
, InDataSize
, Signature
, &SigSize
);
856 *OutData
= Signature
;
857 *OutDataSize
= SigSize
;
859 if (RsaContext
!= NULL
) {
860 RsaFree (RsaContext
);
865 Verify the singed data with the public key which is contained in a certificate.
867 @param[in] InCert Pointer to the Certificate which contains the
869 @param[in] CertLen The size of Certificate in bytes.
870 @param[in] InCa Pointer to the CA certificate
871 @param[in] CaLen The size of CA certificate in bytes.
872 @param[in] InData Pointer to octet message hash to be checked.
873 @param[in] InDataSize Size of the message hash in bytes.
874 @param[in] Singnature The pointer to the RSA PKCS1-V1_5 signature to be verified.
875 @param[in] SigSize Size of signature in bytes.
877 @retval TRUE Valid signature encoded in PKCS1-v1_5.
878 @retval FALSE Invalid signature or invalid RSA context.
882 IpSecCryptoIoVerifySignDataByCertificate (
889 IN UINT8
*Singnature
,
897 // Create the RSA Context
899 RsaContext
= RsaNew ();
900 if (RsaContext
== NULL
) {
905 // Verify the validity of X509 Certificate
907 if (!X509VerifyCert (InCert
, CertLen
, InCa
, CaLen
)) {
912 // Retrieve the RSA public Key from Certificate
914 RsaGetPublicKeyFromX509 ((CONST UINT8
*)InCert
, CertLen
, (VOID
**)&RsaContext
);
919 Status
= RsaPkcs1Verify (RsaContext
, InData
, InDataSize
, Singnature
, SigSize
);
921 if (RsaContext
!= NULL
) {
922 RsaFree (RsaContext
);
929 Retrieves the RSA Public Key from one X509 certificate (DER format only).
931 @param[in] InCert Pointer to the certificate.
932 @param[in] CertLen The size of the certificate in bytes.
933 @param[out] PublicKey Pointer to the retrieved public key.
934 @param[out] PublicKeyLen Size of Public Key in bytes.
936 @retval EFI_SUCCESS Successfully get the public Key.
937 @retval EFI_INVALID_PARAMETER The certificate is malformed.
941 IpSecCryptoIoGetPublicKeyFromCert (
944 OUT UINT8
**PublicKey
,
945 OUT UINTN
*PublicKeyLen
951 Status
= EFI_SUCCESS
;
954 // Create the RSA Context
956 RsaContext
= RsaNew ();
959 // Retrieve the RSA public key from CA Certificate
961 if (!RsaGetPublicKeyFromX509 ((CONST UINT8
*)InCert
, CertLen
, (VOID
**) &RsaContext
)) {
962 Status
= EFI_INVALID_PARAMETER
;
968 RsaGetKey (RsaContext
, RsaKeyN
, NULL
, PublicKeyLen
);
970 *PublicKey
= AllocateZeroPool (*PublicKeyLen
);
971 if (*PublicKey
== NULL
) {
972 Status
= EFI_OUT_OF_RESOURCES
;
976 if (!RsaGetKey (RsaContext
, RsaKeyN
, *PublicKey
, PublicKeyLen
)) {
977 Status
= EFI_INVALID_PARAMETER
;
981 if (RsaContext
!= NULL
) {
982 RsaFree (RsaContext
);
989 Retrieves the subject name from one X509 certificate (DER format only).
991 @param[in] InCert Pointer to the X509 certificate.
992 @param[in] CertSize The size of the X509 certificate in bytes.
993 @param[out] CertSubject Pointer to the retrieved certificate subject.
994 @param[out] SubjectSize The size of Certificate Subject in bytes.
996 @retval EFI_SUCCESS Retrieved the certificate subject successfully.
997 @retval EFI_INVALID_PARAMETER The certificate is malformed.
1001 IpSecCryptoIoGetSubjectFromCert (
1004 OUT UINT8
**CertSubject
,
1005 OUT UINTN
*SubjectSize
1010 Status
= EFI_SUCCESS
;
1013 X509GetSubjectName (InCert
, CertSize
, *CertSubject
, SubjectSize
);
1015 *CertSubject
= AllocateZeroPool (*SubjectSize
);
1016 if (!X509GetSubjectName (InCert
, CertSize
, *CertSubject
, SubjectSize
)) {
1017 Status
= EFI_INVALID_PARAMETER
;