1 /** @file
2   RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
3 
4   This file implements following APIs which provide basic capabilities for RSA:
5   1) RsaNew
6   2) RsaFree
7   3) RsaSetKey
8   4) RsaPkcs1Verify
9 
10 Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>
11 SPDX-License-Identifier: BSD-2-Clause-Patent
12 
13 **/
14 
15 #include "InternalCryptLib.h"
16 
17 #include <openssl/bn.h>
18 #include <openssl/rsa.h>
19 #include <openssl/objects.h>
20 
21 /**
22   Allocates and initializes one RSA context for subsequent use.
23 
24   @return  Pointer to the RSA context that has been initialized.
25            If the allocations fails, RsaNew() returns NULL.
26 
27 **/
28 VOID *
29 EFIAPI
30 RsaNew (
31   VOID
32   )
33 {
34   //
35   // Allocates & Initializes RSA Context by OpenSSL RSA_new()
36   //
37   return (VOID *) RSA_new ();
38 }
39 
40 /**
41   Release the specified RSA context.
42 
43   @param[in]  RsaContext  Pointer to the RSA context to be released.
44 
45 **/
46 VOID
47 EFIAPI
48 RsaFree (
49   IN  VOID  *RsaContext
50   )
51 {
52   //
53   // Free OpenSSL RSA Context
54   //
55   RSA_free ((RSA *) RsaContext);
56 }
57 
58 /**
59   Sets the tag-designated key component into the established RSA context.
60 
61   This function sets the tag-designated RSA key component into the established
62   RSA context from the user-specified non-negative integer (octet string format
63   represented in RSA PKCS#1).
64   If BigNumber is NULL, then the specified key component in RSA context is cleared.
65 
66   If RsaContext is NULL, then return FALSE.
67 
68   @param[in, out]  RsaContext  Pointer to RSA context being set.
69   @param[in]       KeyTag      Tag of RSA key component being set.
70   @param[in]       BigNumber   Pointer to octet integer buffer.
71                                If NULL, then the specified key component in RSA
72                                context is cleared.
73   @param[in]       BnSize      Size of big number buffer in bytes.
74                                If BigNumber is NULL, then it is ignored.
75 
76   @retval  TRUE   RSA key component was set successfully.
77   @retval  FALSE  Invalid RSA key component tag.
78 
79 **/
80 BOOLEAN
81 EFIAPI
82 RsaSetKey (
83   IN OUT  VOID         *RsaContext,
84   IN      RSA_KEY_TAG  KeyTag,
85   IN      CONST UINT8  *BigNumber,
86   IN      UINTN        BnSize
87   )
88 {
89   RSA     *RsaKey;
90   BIGNUM  *BnN;
91   BIGNUM  *BnE;
92   BIGNUM  *BnD;
93   BIGNUM  *BnP;
94   BIGNUM  *BnQ;
95   BIGNUM  *BnDp;
96   BIGNUM  *BnDq;
97   BIGNUM  *BnQInv;
98 
99   //
100   // Check input parameters.
101   //
102   if (RsaContext == NULL || BnSize > INT_MAX) {
103     return FALSE;
104   }
105 
106   BnN    = NULL;
107   BnE    = NULL;
108   BnD    = NULL;
109   BnP    = NULL;
110   BnQ    = NULL;
111   BnDp   = NULL;
112   BnDq   = NULL;
113   BnQInv = NULL;
114 
115   //
116   // Retrieve the components from RSA object.
117   //
118   RsaKey = (RSA *) RsaContext;
119   RSA_get0_key (RsaKey, (const BIGNUM **)&BnN, (const BIGNUM **)&BnE, (const BIGNUM **)&BnD);
120   RSA_get0_factors (RsaKey, (const BIGNUM **)&BnP, (const BIGNUM **)&BnQ);
121   RSA_get0_crt_params (RsaKey, (const BIGNUM **)&BnDp, (const BIGNUM **)&BnDq, (const BIGNUM **)&BnQInv);
122 
123   //
124   // Set RSA Key Components by converting octet string to OpenSSL BN representation.
125   // NOTE: For RSA public key (used in signature verification), only public components
126   //       (N, e) are needed.
127   //
128   switch (KeyTag) {
129 
130   //
131   // RSA Public Modulus (N), Public Exponent (e) and Private Exponent (d)
132   //
133   case RsaKeyN:
134   case RsaKeyE:
135   case RsaKeyD:
136     if (BnN == NULL) {
137       BnN = BN_new ();
138     }
139     if (BnE == NULL) {
140       BnE = BN_new ();
141     }
142     if (BnD == NULL) {
143       BnD = BN_new ();
144     }
145 
146     if ((BnN == NULL) || (BnE == NULL) || (BnD == NULL)) {
147       return FALSE;
148     }
149 
150     switch (KeyTag) {
151     case RsaKeyN:
152       BnN = BN_bin2bn (BigNumber, (UINT32)BnSize, BnN);
153       break;
154     case RsaKeyE:
155       BnE = BN_bin2bn (BigNumber, (UINT32)BnSize, BnE);
156       break;
157     case RsaKeyD:
158       BnD = BN_bin2bn (BigNumber, (UINT32)BnSize, BnD);
159       break;
160     default:
161       return FALSE;
162     }
163     if (RSA_set0_key (RsaKey, BN_dup(BnN), BN_dup(BnE), BN_dup(BnD)) == 0) {
164       return FALSE;
165     }
166 
167     break;
168 
169   //
170   // RSA Secret Prime Factor of Modulus (p and q)
171   //
172   case RsaKeyP:
173   case RsaKeyQ:
174     if (BnP == NULL) {
175       BnP = BN_new ();
176     }
177     if (BnQ == NULL) {
178       BnQ = BN_new ();
179     }
180     if ((BnP == NULL) || (BnQ == NULL)) {
181       return FALSE;
182     }
183 
184     switch (KeyTag) {
185     case RsaKeyP:
186       BnP = BN_bin2bn (BigNumber, (UINT32)BnSize, BnP);
187       break;
188     case RsaKeyQ:
189       BnQ = BN_bin2bn (BigNumber, (UINT32)BnSize, BnQ);
190       break;
191     default:
192       return FALSE;
193     }
194     if (RSA_set0_factors (RsaKey, BN_dup(BnP), BN_dup(BnQ)) == 0) {
195       return FALSE;
196     }
197 
198     break;
199 
200   //
201   // p's CRT Exponent (== d mod (p - 1)),  q's CRT Exponent (== d mod (q - 1)),
202   // and CRT Coefficient (== 1/q mod p)
203   //
204   case RsaKeyDp:
205   case RsaKeyDq:
206   case RsaKeyQInv:
207     if (BnDp == NULL) {
208       BnDp = BN_new ();
209     }
210     if (BnDq == NULL) {
211       BnDq = BN_new ();
212     }
213     if (BnQInv == NULL) {
214       BnQInv = BN_new ();
215     }
216     if ((BnDp == NULL) || (BnDq == NULL) || (BnQInv == NULL)) {
217       return FALSE;
218     }
219 
220     switch (KeyTag) {
221     case RsaKeyDp:
222       BnDp = BN_bin2bn (BigNumber, (UINT32)BnSize, BnDp);
223       break;
224     case RsaKeyDq:
225       BnDq = BN_bin2bn (BigNumber, (UINT32)BnSize, BnDq);
226       break;
227     case RsaKeyQInv:
228       BnQInv = BN_bin2bn (BigNumber, (UINT32)BnSize, BnQInv);
229       break;
230     default:
231       return FALSE;
232     }
233     if (RSA_set0_crt_params (RsaKey, BN_dup(BnDp), BN_dup(BnDq), BN_dup(BnQInv)) == 0) {
234       return FALSE;
235     }
236 
237     break;
238 
239   default:
240     return FALSE;
241   }
242 
243   return TRUE;
244 }
245 
246 /**
247   Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in
248   RSA PKCS#1.
249 
250   If RsaContext is NULL, then return FALSE.
251   If MessageHash is NULL, then return FALSE.
252   If Signature is NULL, then return FALSE.
253   If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-384 or SHA-512 digest, then return FALSE.
254 
255   @param[in]  RsaContext   Pointer to RSA context for signature verification.
256   @param[in]  MessageHash  Pointer to octet message hash to be checked.
257   @param[in]  HashSize     Size of the message hash in bytes.
258   @param[in]  Signature    Pointer to RSA PKCS1-v1_5 signature to be verified.
259   @param[in]  SigSize      Size of signature in bytes.
260 
261   @retval  TRUE   Valid signature encoded in PKCS1-v1_5.
262   @retval  FALSE  Invalid signature or invalid RSA context.
263 
264 **/
265 BOOLEAN
266 EFIAPI
267 RsaPkcs1Verify (
268   IN  VOID         *RsaContext,
269   IN  CONST UINT8  *MessageHash,
270   IN  UINTN        HashSize,
271   IN  CONST UINT8  *Signature,
272   IN  UINTN        SigSize
273   )
274 {
275   INT32    DigestType;
276   UINT8    *SigBuf;
277 
278   //
279   // Check input parameters.
280   //
281   if (RsaContext == NULL || MessageHash == NULL || Signature == NULL) {
282     return FALSE;
283   }
284 
285   if (SigSize > INT_MAX || SigSize == 0) {
286     return FALSE;
287   }
288 
289   //
290   // Determine the message digest algorithm according to digest size.
291   //   Only MD5, SHA-1, SHA-256, SHA-384 or SHA-512 algorithm is supported.
292   //
293   switch (HashSize) {
294   case MD5_DIGEST_SIZE:
295     DigestType = NID_md5;
296     break;
297 
298   case SHA1_DIGEST_SIZE:
299     DigestType = NID_sha1;
300     break;
301 
302   case SHA256_DIGEST_SIZE:
303     DigestType = NID_sha256;
304     break;
305 
306   case SHA384_DIGEST_SIZE:
307     DigestType = NID_sha384;
308     break;
309 
310   case SHA512_DIGEST_SIZE:
311     DigestType = NID_sha512;
312     break;
313 
314   default:
315     return FALSE;
316   }
317 
318   SigBuf = (UINT8 *) Signature;
319   return (BOOLEAN) RSA_verify (
320                      DigestType,
321                      MessageHash,
322                      (UINT32) HashSize,
323                      SigBuf,
324                      (UINT32) SigSize,
325                      (RSA *) RsaContext
326                      );
327 }
328