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