1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifdef HKS_CONFIG_FILE
17 #include HKS_CONFIG_FILE
18 #else
19 #include "hks_config.h"
20 #endif
21 
22 #ifdef HKS_SUPPORT_RSA_C
23 
24 #include "hks_openssl_rsa.h"
25 
26 #include <openssl/bn.h>
27 #include <openssl/evp.h>
28 #include <openssl/ossl_typ.h>
29 #include <openssl/rsa.h>
30 #include <stdbool.h>
31 #include <stddef.h>
32 
33 #include "hks_log.h"
34 #include "hks_mem.h"
35 #include "hks_openssl_engine.h"
36 #include "hks_template.h"
37 #include "securec.h"
38 
RsaGenKeyCheckParam(const struct HksKeySpec * spec)39 static int32_t RsaGenKeyCheckParam(const struct HksKeySpec *spec)
40 {
41     switch (spec->keyLen) {
42         case HKS_RSA_KEY_SIZE_512:
43         case HKS_RSA_KEY_SIZE_768:
44         case HKS_RSA_KEY_SIZE_1024:
45         case HKS_RSA_KEY_SIZE_2048:
46         case HKS_RSA_KEY_SIZE_3072:
47         case HKS_RSA_KEY_SIZE_4096:
48             return HKS_SUCCESS;
49         default:
50             HKS_LOG_E("Invlid rsa key len %" LOG_PUBLIC "x!", spec->keyLen);
51             return HKS_ERROR_INVALID_ARGUMENT;
52     }
53 }
54 
GetRsaPssSaltLen(const struct HksUsageSpec * usageSpec)55 static int32_t GetRsaPssSaltLen(const struct HksUsageSpec *usageSpec)
56 {
57     switch (usageSpec->pssSaltLenType) {
58         case HKS_RSA_PSS_SALTLEN_DIGEST:
59             return RSA_PSS_SALTLEN_DIGEST;
60         case HKS_RSA_PSS_SALTLEN_MAX:
61             return RSA_PSS_SALTLEN_MAX;
62         default:
63             HKS_LOG_E("Invalid rsa salt len type %" LOG_PUBLIC "x!", usageSpec->pssSaltLenType);
64             return HKS_ERROR_NOT_SUPPORTED;
65     }
66 }
67 
RsaCheckKeyMaterial(const struct HksBlob * key)68 static int32_t RsaCheckKeyMaterial(const struct HksBlob *key)
69 {
70     const struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)(key->data);
71     if (keyMaterial->keyAlg != HKS_ALG_RSA) {
72         return HKS_ERROR_INVALID_KEY_INFO;
73     }
74     if (key->size != sizeof(struct KeyMaterialRsa) + keyMaterial->nSize + keyMaterial->eSize + keyMaterial->dSize) {
75         return HKS_ERROR_INVALID_KEY_INFO;
76     }
77     return HKS_SUCCESS;
78 }
79 
InitRsaKeyBuf(const struct KeyMaterialRsa * keyMaterial,struct HksBlob * bufBlob)80 int32_t InitRsaKeyBuf(const struct KeyMaterialRsa *keyMaterial, struct HksBlob *bufBlob)
81 {
82     uint32_t maxSize;
83     if (keyMaterial->nSize >= keyMaterial->eSize) {
84         maxSize = keyMaterial->nSize;
85     } else {
86         maxSize = keyMaterial->eSize;
87     }
88 
89     if (maxSize < keyMaterial->dSize) {
90         maxSize = keyMaterial->dSize;
91     }
92 
93     bufBlob->data = (uint8_t *)HksMalloc(maxSize);
94     HKS_IF_NULL_LOGE_RETURN(bufBlob->data, HKS_ERROR_MALLOC_FAIL, "HksMalloc failed!")
95 
96     bufBlob->size = maxSize;
97     return HKS_SUCCESS;
98 }
99 
InitRsaStruct(const struct HksBlob * key,const bool needPrivateExponent)100 static RSA *InitRsaStruct(const struct HksBlob *key, const bool needPrivateExponent)
101 {
102     const struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)(key->data);
103     struct HksBlob bufBlob = { 0, NULL };
104     int32_t ret = InitRsaKeyBuf(keyMaterial, &bufBlob);
105     HKS_IF_NOT_SUCC_RETURN(ret, NULL)
106 
107     bool copyFail = false;
108     uint32_t offset = sizeof(*keyMaterial);
109     if (memcpy_s(bufBlob.data, bufBlob.size, key->data + offset, keyMaterial->nSize) != EOK) {
110         copyFail = true;
111     }
112     BIGNUM *n = BN_bin2bn(bufBlob.data, keyMaterial->nSize, NULL);
113     offset += keyMaterial->nSize;
114     if (memcpy_s(bufBlob.data, bufBlob.size, key->data + offset, keyMaterial->eSize) != EOK) {
115         copyFail = true;
116     }
117     BIGNUM *e = BN_bin2bn(bufBlob.data, keyMaterial->eSize, NULL);
118     offset += keyMaterial->eSize;
119     BIGNUM *d = NULL;
120     if (needPrivateExponent) {
121         if (memcpy_s(bufBlob.data, bufBlob.size, key->data + offset, keyMaterial->dSize) != EOK) {
122             copyFail = true;
123         }
124         d = BN_bin2bn(bufBlob.data, keyMaterial->dSize, NULL);
125     }
126 
127     RSA *rsa = NULL;
128     do {
129         if (copyFail) {
130             break;
131         }
132 
133         rsa = RSA_new();
134         if (rsa != NULL) {
135             ret = RSA_set0_key(rsa, n, e, d);
136             if (ret != HKS_OPENSSL_SUCCESS) {
137                 RSA_free(rsa);
138                 rsa = NULL;
139                 break;
140             }
141         }
142     } while (0);
143 
144     if (rsa == NULL) {
145         SELF_FREE_PTR(n, BN_free);
146         SELF_FREE_PTR(e, BN_free);
147         SELF_FREE_PTR(d, BN_free);
148     }
149 
150     (void)memset_s(bufBlob.data, bufBlob.size, 0, HKS_KEY_BYTES(keyMaterial->keySize));
151     HKS_FREE(bufBlob.data);
152     return rsa;
153 }
154 
HksOpensslCheckRsaKey(const struct HksBlob * key)155 int32_t HksOpensslCheckRsaKey(const struct HksBlob *key)
156 {
157     struct KeyMaterialRsa *pubKeyMaterial = (struct KeyMaterialRsa *)key->data;
158     BIGNUM *e = NULL;
159     BIGNUM *eMin = NULL;
160     uint8_t bnE[] = { 0x01, 0x00, 0x01 };
161     int32_t ret = HKS_SUCCESS;
162     do {
163         e = BN_bin2bn(key->data + sizeof(struct KeyMaterialRsa) + pubKeyMaterial->nSize, pubKeyMaterial->eSize, NULL);
164         if (e == NULL) {
165             ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
166             break;
167         }
168         eMin = BN_bin2bn(bnE, sizeof(bnE), NULL);
169         if (eMin == NULL) {
170             ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
171             break;
172         }
173         if (BN_cmp(e, eMin) < 0) {
174             HKS_LOG_E("rsa public key is not secure");
175             ret = HKS_ERROR_INVALID_KEY_INFO;
176         }
177     } while (0);
178 
179     BN_free(e);
180     BN_free(eMin);
181     return ret;
182 }
183 
184 #ifdef HKS_SUPPORT_RSA_GENERATE_KEY
RsaSaveKeyMaterial(const RSA * rsa,const uint32_t keySize,struct HksBlob * key)185 static int32_t RsaSaveKeyMaterial(const RSA *rsa, const uint32_t keySize, struct HksBlob *key)
186 {
187     const uint32_t keyByteLen = keySize / HKS_BITS_PER_BYTE;
188     const uint32_t rawMaterialLen = sizeof(struct KeyMaterialRsa) + keyByteLen * HKS_RSA_KEYPAIR_CNT;
189     uint8_t *rawMaterial = (uint8_t *)HksMalloc(rawMaterialLen);
190     HKS_IF_NULL_RETURN(rawMaterial, HKS_ERROR_MALLOC_FAIL)
191 
192     (void)memset_s(rawMaterial, rawMaterialLen, 0, rawMaterialLen);
193 
194     struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)rawMaterial;
195     keyMaterial->keyAlg = HKS_ALG_RSA;
196     keyMaterial->keySize = keySize;
197 
198     uint8_t tmp_buff[keyByteLen];
199     if (memset_s(tmp_buff, keyByteLen, 0, keyByteLen) != EOK) {
200         HKS_FREE(rawMaterial);
201         return HKS_ERROR_INSUFFICIENT_MEMORY;
202     }
203 
204     uint32_t offset = sizeof(*keyMaterial);
205     keyMaterial->nSize = (uint32_t)BN_bn2bin(RSA_get0_n(rsa), tmp_buff);
206     if (memcpy_s(rawMaterial + offset, keyByteLen, tmp_buff, keyMaterial->nSize) != EOK) {
207         HKS_FREE(rawMaterial);
208         return HKS_ERROR_INSUFFICIENT_MEMORY;
209     }
210 
211     offset += keyMaterial->nSize;
212     keyMaterial->eSize = (uint32_t)BN_bn2bin(RSA_get0_e(rsa), tmp_buff);
213     if (memcpy_s(rawMaterial + offset, keyByteLen, tmp_buff, keyMaterial->eSize) != EOK) {
214         HKS_FREE(rawMaterial);
215         return HKS_ERROR_INSUFFICIENT_MEMORY;
216     }
217 
218     offset += keyMaterial->eSize;
219     keyMaterial->dSize = (uint32_t)BN_bn2bin(RSA_get0_d(rsa), tmp_buff);
220     if (memcpy_s(rawMaterial + offset, keyByteLen, tmp_buff, keyMaterial->dSize) != EOK) {
221         HKS_FREE(rawMaterial);
222         return HKS_ERROR_INSUFFICIENT_MEMORY;
223     }
224 
225     key->data = rawMaterial;
226     key->size = sizeof(struct KeyMaterialRsa) + keyMaterial->nSize + keyMaterial->eSize + keyMaterial->dSize;
227 
228     return HKS_SUCCESS;
229 }
230 
HksOpensslRsaGenerateKey(const struct HksKeySpec * spec,struct HksBlob * key)231 int32_t HksOpensslRsaGenerateKey(const struct HksKeySpec *spec, struct HksBlob *key)
232 {
233     HKS_IF_NOT_SUCC_LOGE_RETURN(RsaGenKeyCheckParam(spec),
234         HKS_ERROR_INVALID_ARGUMENT, "rsa generate key invalid params!")
235 
236     RSA *rsa = RSA_new();
237     BIGNUM *e = BN_new();
238     if (rsa == NULL || e == NULL) {
239         SELF_FREE_PTR(rsa, RSA_free);
240         SELF_FREE_PTR(e, BN_free);
241         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
242     }
243 
244     if (BN_set_word(e, RSA_F4) != HKS_OPENSSL_SUCCESS) {
245         SELF_FREE_PTR(rsa, RSA_free);
246         SELF_FREE_PTR(e, BN_free);
247         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
248     }
249 
250     if (RSA_generate_key_ex(rsa, spec->keyLen, e, NULL) != HKS_OPENSSL_SUCCESS) {
251         HksLogOpensslError();
252         BN_free(e);
253         RSA_free(rsa);
254         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
255     }
256     BN_free(e);
257 
258     int32_t ret = RsaSaveKeyMaterial(rsa, spec->keyLen, key);
259 
260     RSA_free(rsa);
261 
262     return ret;
263 }
264 #endif /* HKS_SUPPORT_RSA_GENERATE_KEY */
265 
266 #ifdef HKS_SUPPORT_RSA_GET_PUBLIC_KEY
HksOpensslGetRsaPubKey(const struct HksBlob * input,struct HksBlob * output)267 int32_t HksOpensslGetRsaPubKey(const struct HksBlob *input, struct HksBlob *output)
268 {
269     struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)input->data;
270     output->size = sizeof(struct KeyMaterialRsa) + keyMaterial->nSize + keyMaterial->eSize;
271 
272     struct KeyMaterialRsa *publickeyMaterial = (struct KeyMaterialRsa *)output->data;
273     publickeyMaterial->keyAlg = keyMaterial->keyAlg;
274     publickeyMaterial->keySize = keyMaterial->keySize;
275     publickeyMaterial->nSize = keyMaterial->nSize;
276     publickeyMaterial->eSize = keyMaterial->eSize;
277     publickeyMaterial->dSize = 0;
278 
279     (void)memcpy_s(output->data + sizeof(struct KeyMaterialRsa), output->size - sizeof(struct KeyMaterialRsa),
280         input->data + sizeof(struct KeyMaterialRsa), keyMaterial->nSize + keyMaterial->eSize);
281 
282     return HKS_SUCCESS;
283 }
284 #endif /* HKS_SUPPORT_RSA_GET_PUBLIC_KEY */
285 
286 #ifdef HKS_SUPPORT_RSA_CRYPT
GetRsaCryptPadding(uint32_t padding,uint32_t * rsaPadding)287 static int32_t GetRsaCryptPadding(uint32_t padding, uint32_t *rsaPadding)
288 {
289     switch (padding) {
290 #ifdef HKS_SUPPORT_RSA_ECB_NOPADDING
291         case HKS_PADDING_NONE:
292             *rsaPadding = RSA_NO_PADDING;
293             return HKS_SUCCESS;
294 #endif
295 #ifdef HKS_SUPPORT_RSA_ECB_PKCS1PADDING
296         case HKS_PADDING_PKCS1_V1_5:
297             *rsaPadding = RSA_PKCS1_PADDING;
298             return HKS_SUCCESS;
299 #endif
300 #if defined(HKS_SUPPORT_RSA_ECB_OEAPPADDING) || defined(HKS_SUPPORT_RSA_ECB_OAEPPADDING_SHA1MGF1) ||              \
301     defined(HKS_SUPPORT_RSA_ECB_OAEPPADDING_SHA224MGF1) || defined(HKS_SUPPORT_RSA_ECB_OAEPPADDING_SHA256MGF1) || \
302     defined(HKS_SUPPORT_RSA_ECB_OAEPPADDING_SHA384MGF1) || defined(HKS_SUPPORT_RSA_ECB_OAEPPADDING_SHA512MGF1)
303         case HKS_PADDING_OAEP:
304             *rsaPadding = RSA_PKCS1_OAEP_PADDING;
305             return HKS_SUCCESS;
306 #endif
307         default:
308             return HKS_ERROR_NOT_SUPPORTED;
309     }
310 }
311 
InitEvpPkeyCtx(const struct HksBlob * key,bool encrypt)312 static EVP_PKEY_CTX *InitEvpPkeyCtx(const struct HksBlob *key, bool encrypt)
313 {
314     int32_t ret = RsaCheckKeyMaterial(key);
315     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, NULL, "check key material failed")
316 
317     RSA *rsa = InitRsaStruct(key, !encrypt);
318     HKS_IF_NULL_LOGE_RETURN(rsa, NULL, "initialize rsa key failed")
319 
320     EVP_PKEY *pkey = EVP_PKEY_new();
321     if (pkey == NULL) {
322         RSA_free(rsa);
323         HksLogOpensslError();
324         return NULL;
325     }
326 
327     ret = EVP_PKEY_assign_RSA(pkey, rsa);
328     if (ret != HKS_OPENSSL_SUCCESS) {
329         HksLogOpensslError();
330         RSA_free(rsa);
331         EVP_PKEY_free(pkey);
332         return NULL;
333     }
334 
335     EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
336     if (ctx == NULL) {
337         HksLogOpensslError();
338         EVP_PKEY_free(pkey);
339         return NULL;
340     }
341 
342     if (encrypt) {
343         ret = EVP_PKEY_encrypt_init(ctx);
344     } else {
345         ret = EVP_PKEY_decrypt_init(ctx);
346     }
347     if (ret != HKS_OPENSSL_SUCCESS) {
348         HksLogOpensslError();
349         EVP_PKEY_free(pkey);
350         EVP_PKEY_CTX_free(ctx);
351         return NULL;
352     }
353 
354     EVP_PKEY_free(pkey);
355     return ctx;
356 }
357 
HksOpensslRsaCryptInit(EVP_PKEY_CTX * ctx,const struct HksUsageSpec * usageSpec)358 static int32_t HksOpensslRsaCryptInit(EVP_PKEY_CTX *ctx, const struct HksUsageSpec *usageSpec)
359 {
360     int32_t ret;
361     uint32_t padding = 0;
362     HKS_IF_NOT_SUCC_LOGE_RETURN(GetRsaCryptPadding(usageSpec->padding, &padding),
363         HKS_ERROR_CRYPTO_ENGINE_ERROR, "Unsupport padding.")
364 
365     ret = EVP_PKEY_CTX_set_rsa_padding(ctx, padding);
366     if (ret <= 0) {
367         HksLogOpensslError();
368         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
369     }
370 
371     if (usageSpec->padding == HKS_PADDING_OAEP) {
372         const EVP_MD *md = GetOpensslAlg(usageSpec->digest);
373         const EVP_MD *mgfMd;
374         if (usageSpec->digest == HKS_DIGEST_SHA256 && usageSpec->mgfDigest == HKS_DIGEST_SHA1) {
375             mgfMd = GetOpensslAlg(usageSpec->mgfDigest);
376         } else {
377             mgfMd = md;
378         }
379         if ((md == NULL) || mgfMd == NULL || (EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0) ||
380             (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgfMd) <= 0)) {
381             return HKS_ERROR_CRYPTO_ENGINE_ERROR;
382         }
383     }
384     return HKS_SUCCESS;
385 }
386 
HksOpensslRsaCrypt(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const bool encrypt,struct HksBlob * cipherText)387 static int32_t HksOpensslRsaCrypt(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
388     const struct HksBlob *message, const bool encrypt, struct HksBlob *cipherText)
389 {
390     int32_t ret;
391     EVP_PKEY_CTX *ctx = InitEvpPkeyCtx(key, encrypt);
392     if (ctx == NULL) {
393         HksLogOpensslError();
394         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
395     }
396 
397     if (HksOpensslRsaCryptInit(ctx, usageSpec) != HKS_SUCCESS) {
398         EVP_PKEY_CTX_free(ctx);
399         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
400     }
401 
402     size_t outLen;
403     if (encrypt) {
404         ret = EVP_PKEY_encrypt(ctx, NULL, &outLen, message->data, message->size);
405     } else {
406         ret = EVP_PKEY_decrypt(ctx, NULL, &outLen, message->data, message->size);
407     }
408     if (ret != HKS_OPENSSL_SUCCESS) {
409         HksLogOpensslError();
410         EVP_PKEY_CTX_free(ctx);
411         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
412     }
413 
414     if (outLen > cipherText->size) {
415         HksLogOpensslError();
416         EVP_PKEY_CTX_free(ctx);
417         return HKS_ERROR_INVALID_ARGUMENT;
418     }
419 
420     if (encrypt) {
421         ret = EVP_PKEY_encrypt(ctx, cipherText->data, &outLen, message->data, message->size);
422     } else {
423         ret = EVP_PKEY_decrypt(ctx, cipherText->data, &outLen, message->data, message->size);
424     }
425     if (ret != HKS_OPENSSL_SUCCESS) {
426         HksLogOpensslError();
427         EVP_PKEY_CTX_free(ctx);
428         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
429     }
430     cipherText->size = outLen;
431 
432     EVP_PKEY_CTX_free(ctx);
433     return HKS_SUCCESS;
434 }
435 
HksOpensslRsaEncrypt(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * cipherText,struct HksBlob * tagAead)436 int32_t HksOpensslRsaEncrypt(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
437     const struct HksBlob *message, struct HksBlob *cipherText, struct HksBlob *tagAead)
438 {
439     (void)tagAead;
440     return HksOpensslRsaCrypt(key, usageSpec, message, true, cipherText);
441 }
442 
HksOpensslRsaDecrypt(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * cipherText)443 int32_t HksOpensslRsaDecrypt(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
444     const struct HksBlob *message, struct HksBlob *cipherText)
445 {
446     return HksOpensslRsaCrypt(key, usageSpec, message, false, cipherText);
447 }
448 #endif /* HKS_SUPPORT_RSA_CRYPT */
449 
450 #ifdef HKS_SUPPORT_RSA_SIGN_VERIFY
GetRsaSignPadding(uint32_t padding,uint32_t * rsaPadding)451 static int32_t GetRsaSignPadding(uint32_t padding, uint32_t *rsaPadding)
452 {
453     switch (padding) {
454         case HKS_PADDING_PKCS1_V1_5:
455             *rsaPadding = RSA_PKCS1_PADDING;
456             return HKS_SUCCESS;
457         case HKS_PADDING_PSS:
458             *rsaPadding = RSA_PKCS1_PSS_PADDING;
459             return HKS_SUCCESS;
460         case HKS_PADDING_NONE:
461             *rsaPadding = RSA_NO_PADDING;
462             return HKS_SUCCESS;
463         default:
464             return HKS_ERROR_NOT_SUPPORTED;
465     }
466 }
467 
SetRsaPadding(EVP_PKEY_CTX * ctx,const struct HksUsageSpec * usageSpec)468 static int32_t SetRsaPadding(EVP_PKEY_CTX *ctx, const struct HksUsageSpec *usageSpec)
469 {
470     uint32_t opensslPadding = 0;
471     int32_t ret = GetRsaSignPadding(usageSpec->padding, &opensslPadding);
472     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_PADDING, "Unsupport padding.")
473 
474     if (EVP_PKEY_CTX_set_rsa_padding(ctx, opensslPadding) != HKS_OPENSSL_SUCCESS) {
475         HksLogOpensslError();
476         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
477     }
478     if (usageSpec->padding == HKS_PADDING_PSS) {
479         if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, GetRsaPssSaltLen(usageSpec)) != HKS_OPENSSL_SUCCESS) {
480             HksLogOpensslError();
481             return HKS_ERROR_CRYPTO_ENGINE_ERROR;
482         }
483     }
484     return HKS_SUCCESS;
485 }
486 
InitRsaEvpKey(const struct HksBlob * key,bool signing)487 static EVP_PKEY *InitRsaEvpKey(const struct HksBlob *key, bool signing)
488 {
489     RSA *rsa = InitRsaStruct(key, signing);
490     HKS_IF_NULL_LOGE_RETURN(rsa, NULL, "initialize rsa key failed")
491 
492     EVP_PKEY *pkey = EVP_PKEY_new();
493     if (pkey == NULL) {
494         HKS_LOG_E("evp pkey new failed");
495         SELF_FREE_PTR(rsa, RSA_free);
496         return NULL;
497     }
498 
499     if (EVP_PKEY_assign_RSA(pkey, rsa) != HKS_OPENSSL_SUCCESS) {
500         HksLogOpensslError();
501         SELF_FREE_PTR(rsa, RSA_free);
502         SELF_FREE_PTR(pkey, EVP_PKEY_free);
503         return NULL;
504     }
505 
506     return pkey;
507 }
508 
InitRsaCtx(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,bool signing,uint32_t len)509 static EVP_PKEY_CTX *InitRsaCtx(const struct HksBlob *key, const struct HksUsageSpec *usageSpec, bool signing,
510     uint32_t len)
511 {
512     const EVP_MD *opensslAlg = GetOpensslAlg(usageSpec->digest);
513     if (usageSpec->digest == HKS_DIGEST_NONE) {
514         opensslAlg = GetOpensslAlgFromLen(len);
515     }
516 
517     if (opensslAlg == NULL) {
518         HKS_LOG_E("get openssl algorithm fail");
519         return NULL;
520     }
521     EVP_PKEY *pkey = NULL;
522     EVP_PKEY_CTX *ctx = NULL;
523     int32_t ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
524     do {
525         pkey = InitRsaEvpKey(key, signing);
526         HKS_IF_NULL_BREAK(pkey)
527 
528         ctx = EVP_PKEY_CTX_new(pkey, NULL);
529         HKS_IF_NULL_BREAK(ctx)
530 
531         if (signing) {
532             ret = EVP_PKEY_sign_init(ctx);
533         } else {
534             ret = EVP_PKEY_verify_init(ctx);
535         }
536         if (ret != HKS_OPENSSL_SUCCESS) {
537             break;
538         }
539 
540         ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
541         HKS_IF_NOT_SUCC_BREAK(SetRsaPadding(ctx, usageSpec))
542         if (EVP_PKEY_CTX_set_signature_md(ctx, opensslAlg) != HKS_OPENSSL_SUCCESS) {
543             break;
544         }
545         ret = HKS_SUCCESS;
546     } while (0);
547 
548     SELF_FREE_PTR(pkey, EVP_PKEY_free);
549     if (ret != HKS_SUCCESS) {
550         HksLogOpensslError();
551         SELF_FREE_PTR(ctx, EVP_PKEY_CTX_free);
552     }
553 
554     return ctx;
555 }
556 
HksOpensslRsaSign(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * signature)557 int32_t HksOpensslRsaSign(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
558     const struct HksBlob *message, struct HksBlob *signature)
559 {
560     EVP_PKEY_CTX *ctx = InitRsaCtx(key, usageSpec, true, message->size);
561     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_INVALID_KEY_INFO, "initialize rsa context failed")
562 
563     size_t sigSize = (size_t)signature->size;
564     if (EVP_PKEY_sign(ctx, signature->data, &sigSize, message->data, message->size) != HKS_OPENSSL_SUCCESS) {
565         HksLogOpensslError();
566         EVP_PKEY_CTX_free(ctx);
567         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
568     }
569     signature->size = (uint32_t)sigSize;
570     EVP_PKEY_CTX_free(ctx);
571     return HKS_SUCCESS;
572 }
573 
HksOpensslRsaVerify(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const struct HksBlob * signature)574 int32_t HksOpensslRsaVerify(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
575     const struct HksBlob *message, const struct HksBlob *signature)
576 {
577     EVP_PKEY_CTX *ctx = InitRsaCtx(key, usageSpec, false, message->size);
578     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_INVALID_KEY_INFO, "initialize rsa context failed")
579 
580     if (EVP_PKEY_verify(ctx, signature->data, signature->size, message->data, message->size) != HKS_OPENSSL_SUCCESS) {
581         HksLogOpensslError();
582         EVP_PKEY_CTX_free(ctx);
583         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
584     }
585     EVP_PKEY_CTX_free(ctx);
586     return HKS_SUCCESS;
587 }
588 #endif /* HKS_SUPPORT_RSA_SIGN_VERIFY */
589 #endif /* HKS_SUPPORT_RSA_C */
590