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