]>
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 | |
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 | |
25 | STATIC\r | |
26 | const\r | |
7c342378 | 27 | EVP_MD *\r |
22ac5cc9 | 28 | GetEvpMD (\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 | |
79 | BOOLEAN\r | |
80 | EFIAPI\r | |
81 | RsaPssSign (\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 |