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