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