Commit | Line | Data |
---|---|---|
22ac5cc9 SA |
1 | /** @file\r |
2 | RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.\r | |
3 | \r | |
4 | This file implements following APIs which provide basic capabilities for RSA:\r | |
5 | 1) RsaPssVerify\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 | Verifies the RSA signature with RSASSA-PSS signature scheme defined in RFC 8017.\r | |
49 | Implementation determines salt length automatically from the signature encoding.\r | |
50 | Mask generation function is the same as the message digest algorithm.\r | |
20ca5288 | 51 | Salt length should be equal to digest length.\r |
22ac5cc9 SA |
52 | \r |
53 | @param[in] RsaContext Pointer to RSA context for signature verification.\r | |
54 | @param[in] Message Pointer to octet message to be verified.\r | |
55 | @param[in] MsgSize Size of the message in bytes.\r | |
56 | @param[in] Signature Pointer to RSASSA-PSS signature to be verified.\r | |
57 | @param[in] SigSize Size of signature in bytes.\r | |
58 | @param[in] DigestLen Length of digest for RSA operation.\r | |
59 | @param[in] SaltLen Salt length for PSS encoding.\r | |
60 | \r | |
61 | @retval TRUE Valid signature encoded in RSASSA-PSS.\r | |
62 | @retval FALSE Invalid signature or invalid RSA context.\r | |
63 | \r | |
64 | **/\r | |
65 | BOOLEAN\r | |
66 | EFIAPI\r | |
67 | RsaPssVerify (\r | |
68 | IN VOID *RsaContext,\r | |
69 | IN CONST UINT8 *Message,\r | |
70 | IN UINTN MsgSize,\r | |
71 | IN CONST UINT8 *Signature,\r | |
72 | IN UINTN SigSize,\r | |
73 | IN UINT16 DigestLen,\r | |
74 | IN UINT16 SaltLen\r | |
75 | )\r | |
76 | {\r | |
7c342378 MK |
77 | BOOLEAN Result;\r |
78 | EVP_PKEY *EvpRsaKey;\r | |
79 | EVP_MD_CTX *EvpVerifyCtx;\r | |
80 | EVP_PKEY_CTX *KeyCtx;\r | |
22ac5cc9 SA |
81 | CONST EVP_MD *HashAlg;\r |
82 | \r | |
7c342378 MK |
83 | Result = FALSE;\r |
84 | EvpRsaKey = NULL;\r | |
22ac5cc9 | 85 | EvpVerifyCtx = NULL;\r |
7c342378 MK |
86 | KeyCtx = NULL;\r |
87 | HashAlg = NULL;\r | |
22ac5cc9 SA |
88 | \r |
89 | if (RsaContext == NULL) {\r | |
90 | return FALSE;\r | |
91 | }\r | |
7c342378 MK |
92 | \r |
93 | if ((Message == NULL) || (MsgSize == 0) || (MsgSize > INT_MAX)) {\r | |
22ac5cc9 SA |
94 | return FALSE;\r |
95 | }\r | |
7c342378 MK |
96 | \r |
97 | if ((Signature == NULL) || (SigSize == 0) || (SigSize > INT_MAX)) {\r | |
22ac5cc9 SA |
98 | return FALSE;\r |
99 | }\r | |
7c342378 | 100 | \r |
20ca5288 | 101 | if (SaltLen != DigestLen) {\r |
22ac5cc9 SA |
102 | return FALSE;\r |
103 | }\r | |
104 | \r | |
7c342378 | 105 | HashAlg = GetEvpMD (DigestLen);\r |
22ac5cc9 SA |
106 | \r |
107 | if (HashAlg == NULL) {\r | |
108 | return FALSE;\r | |
109 | }\r | |
110 | \r | |
7c342378 | 111 | EvpRsaKey = EVP_PKEY_new ();\r |
22ac5cc9 SA |
112 | if (EvpRsaKey == NULL) {\r |
113 | goto _Exit;\r | |
114 | }\r | |
115 | \r | |
7c342378 | 116 | EVP_PKEY_set1_RSA (EvpRsaKey, RsaContext);\r |
22ac5cc9 | 117 | \r |
7c342378 | 118 | EvpVerifyCtx = EVP_MD_CTX_create ();\r |
22ac5cc9 SA |
119 | if (EvpVerifyCtx == NULL) {\r |
120 | goto _Exit;\r | |
121 | }\r | |
122 | \r | |
7c342378 | 123 | Result = EVP_DigestVerifyInit (EvpVerifyCtx, &KeyCtx, HashAlg, NULL, EvpRsaKey) > 0;\r |
22ac5cc9 SA |
124 | if (KeyCtx == NULL) {\r |
125 | goto _Exit;\r | |
126 | }\r | |
127 | \r | |
128 | if (Result) {\r | |
7c342378 | 129 | Result = EVP_PKEY_CTX_set_rsa_padding (KeyCtx, RSA_PKCS1_PSS_PADDING) > 0;\r |
22ac5cc9 | 130 | }\r |
7c342378 | 131 | \r |
22ac5cc9 | 132 | if (Result) {\r |
7c342378 | 133 | Result = EVP_PKEY_CTX_set_rsa_pss_saltlen (KeyCtx, SaltLen) > 0;\r |
22ac5cc9 | 134 | }\r |
7c342378 | 135 | \r |
22ac5cc9 | 136 | if (Result) {\r |
7c342378 | 137 | Result = EVP_PKEY_CTX_set_rsa_mgf1_md (KeyCtx, HashAlg) > 0;\r |
22ac5cc9 | 138 | }\r |
7c342378 | 139 | \r |
22ac5cc9 | 140 | if (Result) {\r |
7c342378 | 141 | Result = EVP_DigestVerifyUpdate (EvpVerifyCtx, Message, (UINT32)MsgSize) > 0;\r |
22ac5cc9 | 142 | }\r |
7c342378 | 143 | \r |
22ac5cc9 | 144 | if (Result) {\r |
7c342378 | 145 | Result = EVP_DigestVerifyFinal (EvpVerifyCtx, Signature, (UINT32)SigSize) > 0;\r |
22ac5cc9 SA |
146 | }\r |
147 | \r | |
7c342378 | 148 | _Exit:\r |
22ac5cc9 | 149 | if (EvpRsaKey != NULL) {\r |
7c342378 | 150 | EVP_PKEY_free (EvpRsaKey);\r |
22ac5cc9 | 151 | }\r |
7c342378 | 152 | \r |
22ac5cc9 | 153 | if (EvpVerifyCtx != NULL) {\r |
7c342378 | 154 | EVP_MD_CTX_destroy (EvpVerifyCtx);\r |
22ac5cc9 SA |
155 | }\r |
156 | \r | |
157 | return Result;\r | |
158 | }\r |