]>
git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c
2 This file contains UEFI wrapper functions for RSA PKCS1v2 OAEP encryption routines.
4 SPDX-License-Identifier: BSD-2-Clause-Patent
6 Copyright (C) 2016 Microsoft Corporation. All Rights Reserved.
7 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
11 #include "InternalCryptLib.h"
12 #include <openssl/objects.h>
13 #include <openssl/rsa.h>
14 #include <openssl/x509.h>
15 #include <Library/MemoryAllocationLib.h>
18 Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the
19 encrypted message in a newly allocated buffer.
21 Things that can cause a failure include:
22 - X509 key size does not match any known key size.
23 - Fail to parse X509 certificate.
24 - Fail to allocate an intermediate buffer.
25 - Null pointer provided for a non-optional parameter.
26 - Data size is too large for the provided key size (max size is a function of key size
27 and hash digest size).
29 @param[in] PublicKey A pointer to the DER-encoded X509 certificate that
30 will be used to encrypt the data.
31 @param[in] PublicKeySize Size of the X509 cert buffer.
32 @param[in] InData Data to be encrypted.
33 @param[in] InDataSize Size of the data buffer.
34 @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer
35 to be used when initializing the PRNG. NULL otherwise.
36 @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.
38 @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted
40 @param[out] EncryptedDataSize Size of the encrypted message buffer.
42 @retval TRUE Encryption was successful.
43 @retval FALSE Encryption failed.
49 IN CONST UINT8
*PublicKey
,
50 IN UINTN PublicKeySize
,
53 IN CONST UINT8
*PrngSeed
, OPTIONAL
54 IN UINTN PrngSeedSize
, OPTIONAL
55 OUT UINT8
**EncryptedData
,
56 OUT UINTN
*EncryptedDataSize
60 CONST UINT8
*TempPointer
;
62 EVP_PKEY
*InternalPublicKey
;
63 EVP_PKEY_CTX
*PkeyCtx
;
68 // Check input parameters.
70 if (PublicKey
== NULL
|| InData
== NULL
||
71 EncryptedData
== NULL
|| EncryptedDataSize
== NULL
) {
76 // Check public key size.
78 if (PublicKeySize
> 0xFFFFFFFF) {
80 // Public key size is too large for implementation.
85 *EncryptedData
= NULL
;
86 *EncryptedDataSize
= 0;
90 InternalPublicKey
= NULL
;
96 // If it provides a seed then use it.
97 // Ohterwise, we'll seed with fixed values and hope that the PRNG has already been
98 // used enough to generate sufficient entropy.
100 if (PrngSeed
!= NULL
) {
101 RandomSeed (PrngSeed
, PrngSeedSize
);
103 RandomSeed (NULL
, 0);
107 // Parse the X509 cert and extract the public key.
109 TempPointer
= PublicKey
;
110 CertData
= d2i_X509 (&CertData
, &TempPointer
, (UINT32
)PublicKeySize
);
111 if (CertData
== NULL
) {
113 // Fail to parse X509 cert.
119 // Extract the public key from the x509 cert in a format that
122 InternalPublicKey
= X509_get_pubkey (CertData
);
123 if (InternalPublicKey
== NULL
) {
125 // Fail to extract public key.
131 // Create a context for the public key operation.
133 PkeyCtx
= EVP_PKEY_CTX_new (InternalPublicKey
, NULL
);
134 if (PkeyCtx
== NULL
) {
136 // Fail to create contex.
141 // Initialize the context and set the desired padding.
143 if (EVP_PKEY_encrypt_init (PkeyCtx
) <= 0 ||
144 EVP_PKEY_CTX_set_rsa_padding (PkeyCtx
, RSA_PKCS1_OAEP_PADDING
) <= 0) {
146 // Fail to initialize the context.
152 // Determine the required buffer length for malloc'ing.
154 if (EVP_PKEY_encrypt (PkeyCtx
, NULL
, &OutDataSize
, InData
, InDataSize
) <= 0) {
156 // Fail to determine output buffer size.
162 // Allocate a buffer for the output data.
164 OutData
= AllocatePool (OutDataSize
);
165 if (OutData
== NULL
) {
167 // Fail to allocate the output buffer.
175 if (EVP_PKEY_encrypt (PkeyCtx
, OutData
, &OutDataSize
, InData
, InDataSize
) <= 0) {
177 // Fail to encrypt data, need to free the output buffer.
188 *EncryptedData
= OutData
;
189 *EncryptedDataSize
= OutDataSize
;
196 if (CertData
!= NULL
) {
197 X509_free (CertData
);
199 if (InternalPublicKey
!= NULL
) {
200 EVP_PKEY_free (InternalPublicKey
);
202 if (PkeyCtx
!= NULL
) {
203 EVP_PKEY_CTX_free (PkeyCtx
);