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