]>
Commit | Line | Data |
---|---|---|
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 | |
7 | Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r | |
8 | SPDX-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 | |
26 | STATIC\r | |
27 | const\r | |
28 | EVP_MD*\r | |
29 | GetEvpMD (\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 | |
81 | BOOLEAN\r | |
82 | EFIAPI\r | |
83 | RsaPssSign (\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 |