]> git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c
CryptoPkg: Apply uncrustify changes
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Pk / CryptRsaPssSign.c
1 /** @file
2 RSA PSS Asymmetric Cipher Wrapper Implementation over OpenSSL.
3
4 This file implements following APIs which provide basic capabilities for RSA:
5 1) RsaPssSign
6
7 Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10 **/
11
12 #include "InternalCryptLib.h"
13
14 #include <openssl/bn.h>
15 #include <openssl/rsa.h>
16 #include <openssl/objects.h>
17 #include <openssl/evp.h>
18
19 /**
20 Retrieve a pointer to EVP message digest object.
21
22 @param[in] DigestLen Length of the message digest.
23
24 **/
25 STATIC
26 const
27 EVP_MD *
28 GetEvpMD (
29 IN UINT16 DigestLen
30 )
31 {
32 switch (DigestLen) {
33 case SHA256_DIGEST_SIZE:
34 return EVP_sha256 ();
35 break;
36 case SHA384_DIGEST_SIZE:
37 return EVP_sha384 ();
38 break;
39 case SHA512_DIGEST_SIZE:
40 return EVP_sha512 ();
41 break;
42 default:
43 return NULL;
44 }
45 }
46
47 /**
48 Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme.
49
50 This function carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme defined in
51 RFC 8017.
52 Mask generation function is the same as the message digest algorithm.
53 If the Signature buffer is too small to hold the contents of signature, FALSE
54 is returned and SigSize is set to the required buffer size to obtain the signature.
55
56 If RsaContext is NULL, then return FALSE.
57 If Message is NULL, then return FALSE.
58 If MsgSize is zero or > INT_MAX, then return FALSE.
59 If DigestLen is NOT 32, 48 or 64, return FALSE.
60 If SaltLen is not equal to DigestLen, then return FALSE.
61 If SigSize is large enough but Signature is NULL, then return FALSE.
62 If this interface is not supported, then return FALSE.
63
64 @param[in] RsaContext Pointer to RSA context for signature generation.
65 @param[in] Message Pointer to octet message to be signed.
66 @param[in] MsgSize Size of the message in bytes.
67 @param[in] DigestLen Length of the digest in bytes to be used for RSA signature operation.
68 @param[in] SaltLen Length of the salt in bytes to be used for PSS encoding.
69 @param[out] Signature Pointer to buffer to receive RSA PSS signature.
70 @param[in, out] SigSize On input, the size of Signature buffer in bytes.
71 On output, the size of data returned in Signature buffer in bytes.
72
73 @retval TRUE Signature successfully generated in RSASSA-PSS.
74 @retval FALSE Signature generation failed.
75 @retval FALSE SigSize is too small.
76 @retval FALSE This interface is not supported.
77
78 **/
79 BOOLEAN
80 EFIAPI
81 RsaPssSign (
82 IN VOID *RsaContext,
83 IN CONST UINT8 *Message,
84 IN UINTN MsgSize,
85 IN UINT16 DigestLen,
86 IN UINT16 SaltLen,
87 OUT UINT8 *Signature,
88 IN OUT UINTN *SigSize
89 )
90 {
91 BOOLEAN Result;
92 UINTN RsaSigSize;
93 EVP_PKEY *EvpRsaKey;
94 EVP_MD_CTX *EvpVerifyCtx;
95 EVP_PKEY_CTX *KeyCtx;
96 CONST EVP_MD *HashAlg;
97
98 Result = FALSE;
99 EvpRsaKey = NULL;
100 EvpVerifyCtx = NULL;
101 KeyCtx = NULL;
102 HashAlg = NULL;
103
104 if (RsaContext == NULL) {
105 return FALSE;
106 }
107
108 if ((Message == NULL) || (MsgSize == 0) || (MsgSize > INT_MAX)) {
109 return FALSE;
110 }
111
112 RsaSigSize = RSA_size (RsaContext);
113 if (*SigSize < RsaSigSize) {
114 *SigSize = RsaSigSize;
115 return FALSE;
116 }
117
118 if (Signature == NULL) {
119 return FALSE;
120 }
121
122 if (SaltLen != DigestLen) {
123 return FALSE;
124 }
125
126 HashAlg = GetEvpMD (DigestLen);
127
128 if (HashAlg == NULL) {
129 return FALSE;
130 }
131
132 EvpRsaKey = EVP_PKEY_new ();
133 if (EvpRsaKey == NULL) {
134 goto _Exit;
135 }
136
137 EVP_PKEY_set1_RSA (EvpRsaKey, RsaContext);
138
139 EvpVerifyCtx = EVP_MD_CTX_create ();
140 if (EvpVerifyCtx == NULL) {
141 goto _Exit;
142 }
143
144 Result = EVP_DigestSignInit (EvpVerifyCtx, &KeyCtx, HashAlg, NULL, EvpRsaKey) > 0;
145 if (KeyCtx == NULL) {
146 goto _Exit;
147 }
148
149 if (Result) {
150 Result = EVP_PKEY_CTX_set_rsa_padding (KeyCtx, RSA_PKCS1_PSS_PADDING) > 0;
151 }
152
153 if (Result) {
154 Result = EVP_PKEY_CTX_set_rsa_pss_saltlen (KeyCtx, SaltLen) > 0;
155 }
156
157 if (Result) {
158 Result = EVP_PKEY_CTX_set_rsa_mgf1_md (KeyCtx, HashAlg) > 0;
159 }
160
161 if (Result) {
162 Result = EVP_DigestSignUpdate (EvpVerifyCtx, Message, (UINT32)MsgSize) > 0;
163 }
164
165 if (Result) {
166 Result = EVP_DigestSignFinal (EvpVerifyCtx, Signature, SigSize) > 0;
167 }
168
169 _Exit:
170 if (EvpRsaKey != NULL) {
171 EVP_PKEY_free (EvpRsaKey);
172 }
173
174 if (EvpVerifyCtx != NULL) {
175 EVP_MD_CTX_destroy (EvpVerifyCtx);
176 }
177
178 return Result;
179 }