• 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 = keyMaterial->nSize >= keyMaterial->eSize ? keyMaterial->nSize : keyMaterial->eSize;
89 
90     if (maxSize < keyMaterial->dSize) {
91         maxSize = keyMaterial->dSize;
92     }
93 
94     bufBlob->data = (uint8_t *)HksMalloc(maxSize);
95     HKS_IF_NULL_LOGE_RETURN(bufBlob->data, HKS_ERROR_MALLOC_FAIL, "HksMalloc failed!")
96 
97     bufBlob->size = maxSize;
98     return HKS_SUCCESS;
99 }
100 
InitRsaStruct(const struct HksBlob * key,const bool needPrivateExponent)101 static RSA *InitRsaStruct(const struct HksBlob *key, const bool needPrivateExponent)
102 {
103     const struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)(key->data);
104     struct HksBlob bufBlob = { 0, NULL };
105     int32_t ret = InitRsaKeyBuf(keyMaterial, &bufBlob);
106     HKS_IF_NOT_SUCC_RETURN(ret, NULL)
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     RSA *rsa = NULL;
127     do {
128         if (copyFail) {
129             break;
130         }
131         rsa = RSA_new();
132         if (rsa != NULL) {
133             ret = RSA_set0_key(rsa, n, e, d);
134             if (ret != HKS_OPENSSL_SUCCESS) {
135                 RSA_free(rsa);
136                 rsa = NULL;
137                 break;
138             }
139         }
140     } while (0);
141     if (rsa == NULL) {
142         SELF_FREE_PTR(n, BN_free);
143         SELF_FREE_PTR(e, BN_free);
144         SELF_FREE_PTR(d, BN_free);
145     }
146     memset_s(bufBlob.data, bufBlob.size, 0, bufBlob.size);
147     HKS_MEMSET_FREE_BLOB(bufBlob);
148     return rsa;
149 }
150 
HksOpensslCheckRsaKey(const struct HksBlob * key)151 int32_t HksOpensslCheckRsaKey(const struct HksBlob *key)
152 {
153     struct KeyMaterialRsa *pubKeyMaterial = (struct KeyMaterialRsa *)key->data;
154     BIGNUM *e = NULL;
155     BIGNUM *eMin = NULL;
156     uint8_t bnE[] = { 0x01, 0x00, 0x01 };
157     int32_t ret = HKS_SUCCESS;
158     do {
159         e = BN_bin2bn(key->data + sizeof(struct KeyMaterialRsa) + pubKeyMaterial->nSize, pubKeyMaterial->eSize, NULL);
160         if (e == NULL) {
161             ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
162             break;
163         }
164         eMin = BN_bin2bn(bnE, sizeof(bnE), NULL);
165         if (eMin == NULL) {
166             ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
167             break;
168         }
169         if (BN_cmp(e, eMin) < 0) {
170             HKS_LOG_E("rsa public key is not secure");
171             ret = HKS_ERROR_INVALID_KEY_INFO;
172         }
173     } while (0);
174 
175     BN_free(e);
176     BN_free(eMin);
177     return ret;
178 }
179 
180 #ifdef HKS_SUPPORT_RSA_GENERATE_KEY
RsaSaveKeyMaterial(const RSA * rsa,const uint32_t keySize,struct HksBlob * key)181 static int32_t RsaSaveKeyMaterial(const RSA *rsa, const uint32_t keySize, struct HksBlob *key)
182 {
183     const uint32_t keyByteLen = keySize / HKS_BITS_PER_BYTE;
184     const uint32_t rawMaterialLen = sizeof(struct KeyMaterialRsa) + keyByteLen * HKS_RSA_KEYPAIR_CNT;
185     uint8_t *rawMaterial = (uint8_t *)HksMalloc(rawMaterialLen);
186     HKS_IF_NULL_RETURN(rawMaterial, HKS_ERROR_MALLOC_FAIL)
187 
188     (void)memset_s(rawMaterial, rawMaterialLen, 0, rawMaterialLen);
189 
190     struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)rawMaterial;
191     keyMaterial->keyAlg = HKS_ALG_RSA;
192     keyMaterial->keySize = keySize;
193 
194     uint8_t tmp_buff[keyByteLen];
195     if (memset_s(tmp_buff, keyByteLen, 0, keyByteLen) != EOK) {
196         HKS_FREE(rawMaterial);
197         return HKS_ERROR_INSUFFICIENT_MEMORY;
198     }
199 
200     uint32_t offset = sizeof(*keyMaterial);
201     keyMaterial->nSize = (uint32_t)BN_bn2bin(RSA_get0_n(rsa), tmp_buff);
202     if (memcpy_s(rawMaterial + offset, keyByteLen, tmp_buff, keyMaterial->nSize) != EOK) {
203         HKS_FREE(rawMaterial);
204         return HKS_ERROR_INSUFFICIENT_MEMORY;
205     }
206 
207     offset += keyMaterial->nSize;
208     keyMaterial->eSize = (uint32_t)BN_bn2bin(RSA_get0_e(rsa), tmp_buff);
209     if (memcpy_s(rawMaterial + offset, keyByteLen, tmp_buff, keyMaterial->eSize) != EOK) {
210         HKS_FREE(rawMaterial);
211         return HKS_ERROR_INSUFFICIENT_MEMORY;
212     }
213 
214     offset += keyMaterial->eSize;
215     keyMaterial->dSize = (uint32_t)BN_bn2bin(RSA_get0_d(rsa), tmp_buff);
216     if (memcpy_s(rawMaterial + offset, keyByteLen, tmp_buff, keyMaterial->dSize) != EOK) {
217         HKS_FREE(rawMaterial);
218         return HKS_ERROR_INSUFFICIENT_MEMORY;
219     }
220 
221     key->data = rawMaterial;
222     key->size = sizeof(struct KeyMaterialRsa) + keyMaterial->nSize + keyMaterial->eSize + keyMaterial->dSize;
223 
224     return HKS_SUCCESS;
225 }
226 
HksOpensslRsaGenerateKey(const struct HksKeySpec * spec,struct HksBlob * key)227 int32_t HksOpensslRsaGenerateKey(const struct HksKeySpec *spec, struct HksBlob *key)
228 {
229     HKS_IF_NOT_SUCC_LOGE_RETURN(RsaGenKeyCheckParam(spec),
230         HKS_ERROR_INVALID_ARGUMENT, "rsa generate key invalid params!")
231 
232     RSA *rsa = RSA_new();
233     BIGNUM *e = BN_new();
234     if (rsa == NULL || e == NULL) {
235         SELF_FREE_PTR(rsa, RSA_free);
236         SELF_FREE_PTR(e, BN_free);
237         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
238     }
239 
240     if (BN_set_word(e, RSA_F4) != HKS_OPENSSL_SUCCESS) {
241         SELF_FREE_PTR(rsa, RSA_free);
242         SELF_FREE_PTR(e, BN_free);
243         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
244     }
245 
246     if (RSA_generate_key_ex(rsa, spec->keyLen, e, NULL) != HKS_OPENSSL_SUCCESS) {
247         HksLogOpensslError();
248         BN_free(e);
249         RSA_free(rsa);
250         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
251     }
252     BN_free(e);
253 
254     int32_t ret = RsaSaveKeyMaterial(rsa, spec->keyLen, key);
255 
256     RSA_free(rsa);
257 
258     return ret;
259 }
260 #endif /* HKS_SUPPORT_RSA_GENERATE_KEY */
261 
262 #ifdef HKS_SUPPORT_RSA_GET_PUBLIC_KEY
HksOpensslGetRsaPubKey(const struct HksBlob * input,struct HksBlob * output)263 int32_t HksOpensslGetRsaPubKey(const struct HksBlob *input, struct HksBlob *output)
264 {
265     struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)input->data;
266     output->size = sizeof(struct KeyMaterialRsa) + keyMaterial->nSize + keyMaterial->eSize;
267 
268     struct KeyMaterialRsa *publickeyMaterial = (struct KeyMaterialRsa *)output->data;
269     publickeyMaterial->keyAlg = keyMaterial->keyAlg;
270     publickeyMaterial->keySize = keyMaterial->keySize;
271     publickeyMaterial->nSize = keyMaterial->nSize;
272     publickeyMaterial->eSize = keyMaterial->eSize;
273     publickeyMaterial->dSize = 0;
274 
275     if (memcpy_s(output->data + sizeof(struct KeyMaterialRsa), output->size - sizeof(struct KeyMaterialRsa),
276         input->data + sizeof(struct KeyMaterialRsa), keyMaterial->nSize + keyMaterial->eSize) != EOK) {
277             HKS_LOG_E("copy output->data + sizeof(struct KeyMaterialRsa) failed!");
278             return HKS_ERROR_INSUFFICIENT_MEMORY;
279         }
280 
281     return HKS_SUCCESS;
282 }
283 #endif /* HKS_SUPPORT_RSA_GET_PUBLIC_KEY */
284 
285 #ifdef HKS_SUPPORT_RSA_CRYPT
GetRsaCryptPadding(uint32_t padding,uint32_t * rsaPadding)286 static int32_t GetRsaCryptPadding(uint32_t padding, uint32_t *rsaPadding)
287 {
288     switch (padding) {
289 #ifdef HKS_SUPPORT_RSA_ECB_NOPADDING
290         case HKS_PADDING_NONE:
291             *rsaPadding = RSA_NO_PADDING;
292             return HKS_SUCCESS;
293 #endif
294 #ifdef HKS_SUPPORT_RSA_ECB_PKCS1PADDING
295         case HKS_PADDING_PKCS1_V1_5:
296             *rsaPadding = RSA_PKCS1_PADDING;
297             return HKS_SUCCESS;
298 #endif
299 #if defined(HKS_SUPPORT_RSA_ECB_OEAPPADDING) || defined(HKS_SUPPORT_RSA_ECB_OAEPPADDING_SHA1MGF1) ||              \
300     defined(HKS_SUPPORT_RSA_ECB_OAEPPADDING_SHA224MGF1) || defined(HKS_SUPPORT_RSA_ECB_OAEPPADDING_SHA256MGF1) || \
301     defined(HKS_SUPPORT_RSA_ECB_OAEPPADDING_SHA384MGF1) || defined(HKS_SUPPORT_RSA_ECB_OAEPPADDING_SHA512MGF1)
302         case HKS_PADDING_OAEP:
303             *rsaPadding = RSA_PKCS1_OAEP_PADDING;
304             return HKS_SUCCESS;
305 #endif
306         default:
307             return HKS_ERROR_NOT_SUPPORTED;
308     }
309 }
310 
InitEvpPkeyCtx(const struct HksBlob * key,bool encrypt)311 static EVP_PKEY_CTX *InitEvpPkeyCtx(const struct HksBlob *key, bool encrypt)
312 {
313     int32_t ret = RsaCheckKeyMaterial(key);
314     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, NULL, "check key material failed")
315 
316     RSA *rsa = InitRsaStruct(key, !encrypt);
317     HKS_IF_NULL_LOGE_RETURN(rsa, NULL, "initialize rsa key failed")
318 
319     EVP_PKEY *pkey = EVP_PKEY_new();
320     if (pkey == NULL) {
321         RSA_free(rsa);
322         HksLogOpensslError();
323         return NULL;
324     }
325 
326     ret = EVP_PKEY_assign_RSA(pkey, rsa);
327     if (ret != HKS_OPENSSL_SUCCESS) {
328         HksLogOpensslError();
329         RSA_free(rsa);
330         EVP_PKEY_free(pkey);
331         return NULL;
332     }
333 
334     EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
335     if (ctx == NULL) {
336         HksLogOpensslError();
337         EVP_PKEY_free(pkey);
338         return NULL;
339     }
340 
341     if (encrypt) {
342         ret = EVP_PKEY_encrypt_init(ctx);
343     } else {
344         ret = EVP_PKEY_decrypt_init(ctx);
345     }
346     if (ret != HKS_OPENSSL_SUCCESS) {
347         HksLogOpensslError();
348         EVP_PKEY_free(pkey);
349         EVP_PKEY_CTX_free(ctx);
350         return NULL;
351     }
352 
353     EVP_PKEY_free(pkey);
354     return ctx;
355 }
356 
HksOpensslRsaCryptInit(EVP_PKEY_CTX * ctx,const struct HksUsageSpec * usageSpec)357 static int32_t HksOpensslRsaCryptInit(EVP_PKEY_CTX *ctx, const struct HksUsageSpec *usageSpec)
358 {
359     int32_t ret;
360     uint32_t padding = 0;
361     HKS_IF_NOT_SUCC_LOGE_RETURN(GetRsaCryptPadding(usageSpec->padding, &padding),
362         HKS_ERROR_CRYPTO_ENGINE_ERROR, "Unsupport padding.")
363 
364     ret = EVP_PKEY_CTX_set_rsa_padding(ctx, padding);
365     if (ret <= 0) {
366         HksLogOpensslError();
367         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
368     }
369 
370     if (usageSpec->padding == HKS_PADDING_OAEP) {
371         const EVP_MD *md = GetOpensslAlg(usageSpec->digest);
372         const EVP_MD *mgfMd;
373         if (usageSpec->digest == HKS_DIGEST_SHA256 && usageSpec->mgfDigest == HKS_DIGEST_SHA1) {
374             mgfMd = GetOpensslAlg(usageSpec->mgfDigest);
375         } else {
376             mgfMd = md;
377         }
378         if ((md == NULL) || mgfMd == NULL || (EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0) ||
379             (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgfMd) <= 0)) {
380             return HKS_ERROR_CRYPTO_ENGINE_ERROR;
381         }
382     }
383     return HKS_SUCCESS;
384 }
385 
HksOpensslRsaCrypt(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const bool encrypt,struct HksBlob * cipherText)386 static int32_t HksOpensslRsaCrypt(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
387     const struct HksBlob *message, const bool encrypt, struct HksBlob *cipherText)
388 {
389     int32_t ret;
390     EVP_PKEY_CTX *ctx = InitEvpPkeyCtx(key, encrypt);
391     if (ctx == NULL) {
392         HksLogOpensslError();
393         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
394     }
395 
396     if (HksOpensslRsaCryptInit(ctx, usageSpec) != HKS_SUCCESS) {
397         EVP_PKEY_CTX_free(ctx);
398         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
399     }
400 
401     size_t outLen;
402     if (encrypt) {
403         ret = EVP_PKEY_encrypt(ctx, NULL, &outLen, message->data, message->size);
404     } else {
405         ret = EVP_PKEY_decrypt(ctx, NULL, &outLen, message->data, message->size);
406     }
407     if (ret != HKS_OPENSSL_SUCCESS) {
408         HksLogOpensslError();
409         EVP_PKEY_CTX_free(ctx);
410         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
411     }
412 
413     if (outLen > cipherText->size) {
414         HksLogOpensslError();
415         EVP_PKEY_CTX_free(ctx);
416         return HKS_ERROR_INVALID_ARGUMENT;
417     }
418 
419     if (encrypt) {
420         ret = EVP_PKEY_encrypt(ctx, cipherText->data, &outLen, message->data, message->size);
421     } else {
422         ret = EVP_PKEY_decrypt(ctx, cipherText->data, &outLen, message->data, message->size);
423     }
424     if (ret != HKS_OPENSSL_SUCCESS) {
425         HksLogOpensslError();
426         EVP_PKEY_CTX_free(ctx);
427         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
428     }
429     cipherText->size = outLen;
430 
431     EVP_PKEY_CTX_free(ctx);
432     return HKS_SUCCESS;
433 }
434 
HksOpensslRsaEncrypt(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * cipherText,struct HksBlob * tagAead)435 int32_t HksOpensslRsaEncrypt(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
436     const struct HksBlob *message, struct HksBlob *cipherText, struct HksBlob *tagAead)
437 {
438     (void)tagAead;
439     return HksOpensslRsaCrypt(key, usageSpec, message, true, cipherText);
440 }
441 
HksOpensslRsaDecrypt(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * cipherText)442 int32_t HksOpensslRsaDecrypt(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
443     const struct HksBlob *message, struct HksBlob *cipherText)
444 {
445     return HksOpensslRsaCrypt(key, usageSpec, message, false, cipherText);
446 }
447 #endif /* HKS_SUPPORT_RSA_CRYPT */
448 
449 #ifdef HKS_SUPPORT_RSA_SIGN_VERIFY
GetRsaSignPadding(uint32_t padding,uint32_t * rsaPadding)450 static int32_t GetRsaSignPadding(uint32_t padding, uint32_t *rsaPadding)
451 {
452     switch (padding) {
453         case HKS_PADDING_PKCS1_V1_5:
454             *rsaPadding = RSA_PKCS1_PADDING;
455             return HKS_SUCCESS;
456         case HKS_PADDING_PSS:
457             *rsaPadding = RSA_PKCS1_PSS_PADDING;
458             return HKS_SUCCESS;
459         case HKS_PADDING_NONE:
460             *rsaPadding = RSA_NO_PADDING;
461             return HKS_SUCCESS;
462         default:
463             return HKS_ERROR_NOT_SUPPORTED;
464     }
465 }
466 
SetRsaPadding(EVP_PKEY_CTX * ctx,const struct HksUsageSpec * usageSpec)467 static int32_t SetRsaPadding(EVP_PKEY_CTX *ctx, const struct HksUsageSpec *usageSpec)
468 {
469     uint32_t opensslPadding = 0;
470     int32_t ret = GetRsaSignPadding(usageSpec->padding, &opensslPadding);
471     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_PADDING, "Unsupport padding.")
472 
473     if (EVP_PKEY_CTX_set_rsa_padding(ctx, opensslPadding) != HKS_OPENSSL_SUCCESS) {
474         HksLogOpensslError();
475         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
476     }
477     if (usageSpec->padding == HKS_PADDING_PSS) {
478         if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, GetRsaPssSaltLen(usageSpec)) != HKS_OPENSSL_SUCCESS) {
479             HksLogOpensslError();
480             return HKS_ERROR_CRYPTO_ENGINE_ERROR;
481         }
482     }
483     return HKS_SUCCESS;
484 }
485 
InitRsaEvpKey(const struct HksBlob * key,bool signing)486 static EVP_PKEY *InitRsaEvpKey(const struct HksBlob *key, bool signing)
487 {
488     RSA *rsa = InitRsaStruct(key, signing);
489     HKS_IF_NULL_LOGE_RETURN(rsa, NULL, "initialize rsa key failed")
490 
491     EVP_PKEY *pkey = EVP_PKEY_new();
492     if (pkey == NULL) {
493         HKS_LOG_E("evp pkey new failed");
494         SELF_FREE_PTR(rsa, RSA_free);
495         return NULL;
496     }
497 
498     if (EVP_PKEY_assign_RSA(pkey, rsa) != HKS_OPENSSL_SUCCESS) {
499         HksLogOpensslError();
500         SELF_FREE_PTR(rsa, RSA_free);
501         SELF_FREE_PTR(pkey, EVP_PKEY_free);
502         return NULL;
503     }
504 
505     return pkey;
506 }
507 
InitRsaCtx(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,bool signing,uint32_t len)508 static EVP_PKEY_CTX *InitRsaCtx(const struct HksBlob *key, const struct HksUsageSpec *usageSpec, bool signing,
509     uint32_t len)
510 {
511     const EVP_MD *opensslAlg = GetOpensslAlg(usageSpec->digest);
512     if (usageSpec->digest == HKS_DIGEST_NONE) {
513         opensslAlg = GetOpensslAlgFromLen(len);
514     }
515 
516     if (opensslAlg == NULL) {
517         HKS_LOG_E("get openssl algorithm fail");
518         return NULL;
519     }
520     EVP_PKEY *pkey = NULL;
521     EVP_PKEY_CTX *ctx = NULL;
522     int32_t ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
523     do {
524         pkey = InitRsaEvpKey(key, signing);
525         HKS_IF_NULL_BREAK(pkey)
526 
527         ctx = EVP_PKEY_CTX_new(pkey, NULL);
528         HKS_IF_NULL_BREAK(ctx)
529 
530         if (signing) {
531             ret = EVP_PKEY_sign_init(ctx);
532         } else {
533             ret = EVP_PKEY_verify_init(ctx);
534         }
535         HKS_IF_TRUE_BREAK(ret != HKS_OPENSSL_SUCCESS)
536 
537         ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
538         HKS_IF_NOT_SUCC_BREAK(SetRsaPadding(ctx, usageSpec))
539         HKS_IF_TRUE_BREAK(EVP_PKEY_CTX_set_signature_md(ctx, opensslAlg) != HKS_OPENSSL_SUCCESS)
540         ret = HKS_SUCCESS;
541     } while (0);
542 
543     SELF_FREE_PTR(pkey, EVP_PKEY_free);
544     if (ret != HKS_SUCCESS) {
545         HksLogOpensslError();
546         SELF_FREE_PTR(ctx, EVP_PKEY_CTX_free);
547     }
548 
549     return ctx;
550 }
551 
RsaCheckNoPadding(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message)552 static int32_t RsaCheckNoPadding(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
553     const struct HksBlob *message)
554 {
555     if (usageSpec->digest != HKS_DIGEST_NONE) {
556         HKS_LOG_E("check rsa digest fail");
557         return HKS_ERROR_INVALID_DIGEST;
558     }
559 
560     const struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)(key->data);
561     if (message->size * HKS_BITS_PER_BYTE != keyMaterial->keySize) {
562         HKS_LOG_E("check rsa message size fail");
563         return HKS_ERROR_INVALID_ARGUMENT;
564     }
565 
566     return HKS_SUCCESS;
567 }
568 
HksOpensslRsaSignForNoPadding(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * signature)569 static int32_t HksOpensslRsaSignForNoPadding(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
570     const struct HksBlob *message, struct HksBlob *signature)
571 {
572     int32_t ret = RsaCheckKeyMaterial(key);
573     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check rsa key material fail")
574 
575     ret = RsaCheckNoPadding(key, usageSpec, message);
576     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check rsa no padding fail")
577 
578     RSA *rsa = InitRsaStruct(key, true);
579     HKS_IF_NULL_LOGE_RETURN(rsa, HKS_ERROR_INSUFFICIENT_MEMORY, "initialize rsa key fail")
580 
581     int sigSize = RSA_private_encrypt((int)message->size, message->data, signature->data, rsa, RSA_NO_PADDING);
582     if (sigSize < 0) {
583         HksLogOpensslError();
584         HKS_LOG_E("rsa nopadding sign fail");
585         SELF_FREE_PTR(rsa, RSA_free);
586         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
587     }
588     signature->size = (uint32_t)sigSize;
589 
590     SELF_FREE_PTR(rsa, RSA_free);
591     return HKS_SUCCESS;
592 }
593 
HksOpensslRsaSignForNomal(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * signature)594 static int32_t HksOpensslRsaSignForNomal(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
595     const struct HksBlob *message, struct HksBlob *signature)
596 {
597     EVP_PKEY_CTX *ctx = InitRsaCtx(key, usageSpec, true, message->size);
598     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_INVALID_KEY_INFO, "initialize rsa context failed")
599 
600     size_t sigSize = (size_t)signature->size;
601     if (EVP_PKEY_sign(ctx, signature->data, &sigSize, message->data, message->size) != HKS_OPENSSL_SUCCESS) {
602         HksLogOpensslError();
603         EVP_PKEY_CTX_free(ctx);
604         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
605     }
606     signature->size = (uint32_t)sigSize;
607     EVP_PKEY_CTX_free(ctx);
608     return HKS_SUCCESS;
609 }
610 
HksOpensslRsaSign(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * signature)611 int32_t HksOpensslRsaSign(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
612     const struct HksBlob *message, struct HksBlob *signature)
613 {
614     int32_t ret = 0;
615     if (usageSpec->padding == HKS_PADDING_NONE) {
616         ret = HksOpensslRsaSignForNoPadding(key, usageSpec, message, signature);
617     } else {
618         ret = HksOpensslRsaSignForNomal(key, usageSpec, message, signature);
619     }
620 
621     if (ret != HKS_SUCCESS) {
622         HKS_LOG_E("HksOpensslRsaSign fail, ret = %" LOG_PUBLIC "u", ret);
623     }
624     return ret;
625 }
626 
HksOpensslRsaVerifyForNoPadding(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const struct HksBlob * signature)627 static int32_t HksOpensslRsaVerifyForNoPadding(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
628     const struct HksBlob *message, const struct HksBlob *signature)
629 {
630     int32_t ret = RsaCheckKeyMaterial(key);
631     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check rsa key material fail")
632 
633     ret = RsaCheckNoPadding(key, usageSpec, message);
634     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check rsa no padding fail")
635 
636     RSA *rsa = InitRsaStruct(key, true);
637     HKS_IF_NULL_LOGE_RETURN(rsa, HKS_ERROR_INSUFFICIENT_MEMORY, "initialize rsa key fail")
638 
639     uint8_t *decryptedHash = (uint8_t *)HksMalloc(message->size);
640     if (decryptedHash == NULL) {
641         HKS_LOG_E("HksMalloc failed");
642         SELF_FREE_PTR(rsa, RSA_free);
643         return HKS_ERROR_MALLOC_FAIL;
644     }
645 
646     do {
647         if (RSA_public_decrypt((int)signature->size, signature->data, decryptedHash, rsa, RSA_NO_PADDING) < 0) {
648             HksLogOpensslError();
649             HKS_LOG_E("get message hash from rsa signature failed");
650             ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
651             break;
652         }
653         if (memcmp(decryptedHash, message->data, message->size) != 0) {
654             HKS_LOG_E("rsa nopadding verify failed");
655             ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
656             break;
657         }
658     } while (0);
659 
660     HKS_FREE(decryptedHash);
661     SELF_FREE_PTR(rsa, RSA_free);
662     return ret;
663 }
664 
HksOpensslRsaVerifyForNormal(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const struct HksBlob * signature)665 static int32_t HksOpensslRsaVerifyForNormal(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
666     const struct HksBlob *message, const struct HksBlob *signature)
667 {
668     EVP_PKEY_CTX *ctx = InitRsaCtx(key, usageSpec, false, message->size);
669     HKS_IF_NULL_LOGE_RETURN(ctx, HKS_ERROR_INVALID_KEY_INFO, "initialize rsa context failed")
670 
671     if (EVP_PKEY_verify(ctx, signature->data, signature->size, message->data, message->size) != HKS_OPENSSL_SUCCESS) {
672         HksLogOpensslError();
673         EVP_PKEY_CTX_free(ctx);
674         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
675     }
676     EVP_PKEY_CTX_free(ctx);
677     return HKS_SUCCESS;
678 }
679 
HksOpensslRsaVerify(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const struct HksBlob * signature)680 int32_t HksOpensslRsaVerify(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
681     const struct HksBlob *message, const struct HksBlob *signature)
682 {
683     int32_t ret = 0;
684     if (usageSpec->padding == HKS_PADDING_NONE) {
685         ret = HksOpensslRsaVerifyForNoPadding(key, usageSpec, message, signature);
686     } else {
687         ret = HksOpensslRsaVerifyForNormal(key, usageSpec, message, signature);
688     }
689 
690     if (ret != HKS_SUCCESS) {
691         HKS_LOG_E("HksOpensslRsaVerify fail, ret = %" LOG_PUBLIC "u", ret);
692     }
693     return ret;
694 }
695 #endif /* HKS_SUPPORT_RSA_SIGN_VERIFY */
696 #endif /* HKS_SUPPORT_RSA_C */
697