• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #define HUKS_DISABLE_LOG_AT_FILE_TO_REDUCE_ROM_SIZE
16 
17 #ifdef HKS_CONFIG_FILE
18 #include HKS_CONFIG_FILE
19 #else
20 #include "hks_config.h"
21 #endif
22 
23 #ifdef _CUT_AUTHENTICATE_
24 #undef HKS_SUPPORT_RSA_C
25 #endif
26 
27 #ifdef HKS_SUPPORT_RSA_C
28 
29 #include "hks_mbedtls_rsa.h"
30 
31 #include <mbedtls/bignum.h>
32 #include <mbedtls/ctr_drbg.h>
33 #include <mbedtls/entropy.h>
34 #include <mbedtls/rsa.h>
35 #include <securec.h>
36 
37 #include "hks_log.h"
38 #include "hks_mbedtls_common.h"
39 #include "hks_common_check.h"
40 #include "hks_mem.h"
41 #include "hks_template.h"
42 
43 #define HKS_RSA_PUBLIC_EXPONENT 65537
44 #define HKS_RSA_KEYPAIR_CNT 3
45 #define MBEDTLS_RSA_PUBLIC	0
46 #define MBEDTLS_RSA_PRIVATE	1
47 #define HKS_RSA_KEYSIZE_CNT 8
48 #define MBEDTLS_RSA_PSS_DIGEST_NUM 2
49 
50 typedef struct HksMbedtlsSignVerifyParam {
51     uint32_t mbedtlsAlg;
52     int32_t padding;
53     uint32_t pssSaltLen;
54 } HksMbedtlsSignVerifyParam;
55 
RsaCheckKeySize(const uint32_t keySize)56 static int32_t RsaCheckKeySize(const uint32_t keySize)
57 {
58 #ifdef HKS_SUPPORT_RSA_C_FLEX_KEYSIZE
59     if ((keySize >= HKS_RSA_KEY_SIZE_1024) && (keySize <= HKS_RSA_KEY_SIZE_2048)) {
60         if ((keySize % HKS_RSA_KEYSIZE_CNT) == 0) {
61             return HKS_SUCCESS;
62         }
63     }
64 #endif
65     switch (keySize) {
66         case HKS_RSA_KEY_SIZE_512:
67         case HKS_RSA_KEY_SIZE_768:
68         case HKS_RSA_KEY_SIZE_1024:
69         case HKS_RSA_KEY_SIZE_2048:
70         case HKS_RSA_KEY_SIZE_3072:
71         case HKS_RSA_KEY_SIZE_4096:
72             break;
73         default:
74             HKS_LOG_E("Invalid rsa key size! keySize = 0x%" LOG_PUBLIC "X", keySize);
75             return HKS_ERROR_INVALID_KEY_SIZE;
76     }
77 
78     return HKS_SUCCESS;
79 }
80 
RsaKeyMaterialNedSizeCheck(const struct KeyMaterialRsa * keyMaterial)81 int32_t RsaKeyMaterialNedSizeCheck(const struct KeyMaterialRsa *keyMaterial)
82 {
83     const uint32_t maxKeyByteLen = HKS_RSA_KEY_SIZE_4096 / HKS_BITS_PER_BYTE;
84     if ((keyMaterial->nSize > maxKeyByteLen) || (keyMaterial->eSize > maxKeyByteLen) ||
85         (keyMaterial->dSize > maxKeyByteLen)) {
86         HKS_LOG_E("Invalid rsa keyMaterial! nSize = 0x%" LOG_PUBLIC "X, eSize = 0x%" LOG_PUBLIC "X, "
87             "dSize = 0x%" LOG_PUBLIC "X",
88             keyMaterial->nSize,
89             keyMaterial->eSize,
90             keyMaterial->dSize);
91         return HKS_ERROR_INVALID_ARGUMENT;
92     }
93 
94     return HKS_SUCCESS;
95 }
96 
RsaKeyCheck(const struct HksBlob * key)97 int32_t RsaKeyCheck(const struct HksBlob *key)
98 {
99     const struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)(key->data);
100 
101     int32_t ret = RsaCheckKeySize(keyMaterial->keySize);
102     HKS_IF_NOT_SUCC_RETURN(ret, ret)
103 
104     ret = RsaKeyMaterialNedSizeCheck(keyMaterial);
105     HKS_IF_NOT_SUCC_RETURN(ret, ret)
106 
107     if (key->size < (sizeof(struct KeyMaterialRsa) + keyMaterial->nSize + keyMaterial->eSize + keyMaterial->dSize)) {
108         HKS_LOG_E("Rsa key size too small! key size = 0x%" LOG_PUBLIC "X", key->size);
109         return HKS_ERROR_INVALID_KEY_INFO;
110     }
111 
112     return HKS_SUCCESS;
113 }
114 
115 #ifdef HKS_SUPPORT_RSA_GENERATE_KEY
RsaSaveKeyMaterial(const mbedtls_rsa_context * ctx,const uint32_t keySize,struct HksBlob * key)116 static int32_t RsaSaveKeyMaterial(const mbedtls_rsa_context *ctx, const uint32_t keySize, struct HksBlob *key)
117 {
118     const uint32_t keyByteLen = keySize / HKS_BITS_PER_BYTE;
119     const uint32_t rawMaterialLen = sizeof(struct KeyMaterialRsa) + keyByteLen * HKS_RSA_KEYPAIR_CNT;
120     uint8_t *rawMaterial = (uint8_t *)HksMalloc(rawMaterialLen);
121     HKS_IF_NULL_RETURN(rawMaterial, HKS_ERROR_MALLOC_FAIL)
122     (void)memset_s(rawMaterial, rawMaterialLen, 0, rawMaterialLen);
123 
124     /* RSA key data internal struct: struct KeyMaterialRsa + nData + eData + dData */
125     struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)rawMaterial;
126     keyMaterial->keyAlg = HKS_ALG_RSA;
127     keyMaterial->keySize = keySize;
128     keyMaterial->nSize = keyByteLen;
129     keyMaterial->eSize = keyByteLen;
130     keyMaterial->dSize = keyByteLen;
131 
132     int32_t ret;
133     do {
134         uint32_t offset = sizeof(*keyMaterial);
135         ret = mbedtls_mpi_write_binary(&(ctx->MBEDTLS_PRIVATE(N)), rawMaterial + offset, keyMaterial->nSize);
136         if (ret != HKS_MBEDTLS_SUCCESS) {
137             HKS_LOG_E("Rsa save keyMaterial mpi write N failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
138             break;
139         }
140 
141         offset = offset + keyMaterial->nSize;
142         ret = mbedtls_mpi_write_binary(&(ctx->MBEDTLS_PRIVATE(E)), rawMaterial + offset, keyMaterial->eSize);
143         if (ret != HKS_MBEDTLS_SUCCESS) {
144             HKS_LOG_E("Rsa save keyMaterial mpi write E failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
145             break;
146         }
147 
148         offset = offset + keyMaterial->eSize;
149         ret = mbedtls_mpi_write_binary(&(ctx->MBEDTLS_PRIVATE(D)), rawMaterial + offset, keyMaterial->dSize);
150         if (ret != HKS_MBEDTLS_SUCCESS) {
151             HKS_LOG_E("Rsa save keyMaterial mpi write D failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
152             break;
153         }
154 
155         key->data = rawMaterial;
156         key->size = rawMaterialLen;
157     } while (0);
158 
159     if (ret != HKS_MBEDTLS_SUCCESS) {
160         (void)memset_s(rawMaterial, rawMaterialLen, 0, rawMaterialLen);
161         HKS_FREE(rawMaterial);
162         ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
163     }
164 
165     return ret;
166 }
167 
HksMbedtlsRsaGenerateKey(const struct HksKeySpec * spec,struct HksBlob * key)168 int32_t HksMbedtlsRsaGenerateKey(const struct HksKeySpec *spec, struct HksBlob *key)
169 {
170     mbedtls_rsa_context ctx;
171     (void)memset_s(&ctx, sizeof(mbedtls_rsa_context), 0, sizeof(mbedtls_rsa_context));
172     mbedtls_rsa_init(&ctx);
173     ctx.MBEDTLS_PRIVATE(padding) = 0;
174     ctx.MBEDTLS_PRIVATE(hash_id) = 0;
175 
176     mbedtls_ctr_drbg_context ctrDrbg;
177     mbedtls_entropy_context entropy;
178     (void)memset_s(&entropy, sizeof(mbedtls_entropy_context), 0, sizeof(mbedtls_entropy_context));
179     (void)memset_s(&ctrDrbg, sizeof(mbedtls_ctr_drbg_context), 0, sizeof(mbedtls_ctr_drbg_context));
180     int32_t ret = HksCtrDrbgSeed(&ctrDrbg, &entropy);
181     if (ret != HKS_SUCCESS) {
182         mbedtls_rsa_free(&ctx);
183         return ret;
184     }
185 
186     do {
187         ret = mbedtls_rsa_gen_key(&ctx, mbedtls_ctr_drbg_random, &ctrDrbg, spec->keyLen, HKS_RSA_PUBLIC_EXPONENT);
188         if (ret != HKS_MBEDTLS_SUCCESS) {
189             HKS_LOG_E("Mbedtls rsa generate key failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
190             ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
191             break;
192         }
193 
194         ret = RsaSaveKeyMaterial(&ctx, spec->keyLen, key);
195     } while (0);
196 
197     mbedtls_rsa_free(&ctx);
198     mbedtls_ctr_drbg_free(&ctrDrbg);
199     mbedtls_entropy_free(&entropy);
200     return ret;
201 }
202 #endif /* HKS_SUPPORT_RSA_GENERATE_KEY */
203 
204 #if defined(HKS_SUPPORT_RSA_CRYPT) || defined(HKS_SUPPORT_RSA_SIGN_VERIFY)
RsaKeyMaterialToCtx(const struct HksBlob * key,const bool needPrivateExponent,mbedtls_rsa_context * ctx)205 int32_t RsaKeyMaterialToCtx(const struct HksBlob *key, const bool needPrivateExponent, mbedtls_rsa_context *ctx)
206 {
207     const struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)(key->data);
208 
209     mbedtls_mpi n;
210     mbedtls_mpi e;
211     mbedtls_mpi d;
212 
213     mbedtls_mpi_init(&n);
214     mbedtls_mpi_init(&e);
215     mbedtls_mpi_init(&d);
216 
217     int32_t ret;
218     do {
219         uint32_t offset = sizeof(*keyMaterial);
220         ret = mbedtls_mpi_read_binary(&n, key->data + offset, keyMaterial->nSize);
221         if (ret != HKS_MBEDTLS_SUCCESS) {
222             HKS_LOG_E("Mbedtls rsa keyMaterial to ctx read N failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
223             break;
224         }
225 
226         offset = offset + keyMaterial->nSize;
227         ret = mbedtls_mpi_read_binary(&e, key->data + offset, keyMaterial->eSize);
228         if (ret != HKS_MBEDTLS_SUCCESS) {
229             HKS_LOG_E("Mbedtls rsa keyMaterial to ctx read E failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
230             break;
231         }
232 
233         if (needPrivateExponent) {
234             offset = offset + keyMaterial->eSize;
235             ret = mbedtls_mpi_read_binary(&d, key->data + offset, keyMaterial->dSize);
236             if (ret != HKS_MBEDTLS_SUCCESS) {
237                 HKS_LOG_E("Mbedtls rsa keyMaterial to ctx read D failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
238                 break;
239             }
240         }
241 
242         ret = mbedtls_rsa_import(ctx, &n, NULL, NULL, (needPrivateExponent ? &d : NULL), &e);
243         if (ret != HKS_MBEDTLS_SUCCESS) {
244             HKS_LOG_E("Mbedtls rsa keyMaterial to ctx import failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
245             break;
246         }
247 
248         ret = mbedtls_rsa_complete(ctx);
249         if (ret != HKS_MBEDTLS_SUCCESS) {
250             HKS_LOG_E("Mbedtls rsa keyMaterial to ctx complete failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
251         }
252     } while (0);
253 
254     mbedtls_mpi_free(&n);
255     mbedtls_mpi_free(&e);
256     mbedtls_mpi_free(&d);
257 
258     if (ret != HKS_MBEDTLS_SUCCESS) {
259         ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
260     }
261     return ret;
262 }
263 #endif /* HKS_SUPPORT_RSA_CRYPT or HKS_SUPPORT_RSA_SIGN_VERIFY */
264 
265 #ifdef HKS_SUPPORT_RSA_CRYPT
HksToMbedtlsPadding(uint32_t hksPadding,int32_t * padding)266 static int32_t HksToMbedtlsPadding(uint32_t hksPadding, int32_t *padding)
267 {
268     switch (hksPadding) {
269 #ifdef HKS_SUPPORT_RSA_ECB_NOPADDING
270         case HKS_PADDING_NONE:
271             return HKS_SUCCESS;
272 #endif
273         case HKS_PADDING_PKCS1_V1_5:
274             *padding = MBEDTLS_RSA_PKCS_V15;
275             break;
276         case HKS_PADDING_OAEP:
277             *padding = MBEDTLS_RSA_PKCS_V21;
278             break;
279         default:
280             return HKS_ERROR_NOT_SUPPORTED;
281     }
282     return HKS_SUCCESS;
283 }
284 
HksMbedtlsRsaCryptMbedtls(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const bool encrypt,struct HksBlob * cipherText,size_t * outlen,mbedtls_rsa_context * ctx)285 static int32_t HksMbedtlsRsaCryptMbedtls(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
286     const struct HksBlob *message, const bool encrypt, struct HksBlob *cipherText, size_t *outlen,
287     mbedtls_rsa_context *ctx)
288 {
289     mbedtls_ctr_drbg_context ctrDrbg;
290     mbedtls_entropy_context entropy;
291     (void)memset_s(&entropy, sizeof(mbedtls_entropy_context), 0, sizeof(mbedtls_entropy_context));
292     (void)memset_s(&ctrDrbg, sizeof(mbedtls_ctr_drbg_context), 0, sizeof(mbedtls_ctr_drbg_context));
293     int32_t ret = HksCtrDrbgSeed(&ctrDrbg, &entropy);
294     HKS_IF_NOT_SUCC_RETURN(ret, ret)
295 
296     do {
297         ret = RsaKeyMaterialToCtx(key, !encrypt, ctx); /* encrypt don't need private exponent (d) */
298         HKS_IF_NOT_SUCC_BREAK(ret)
299 #ifdef HKS_SUPPORT_RSA_ECB_NOPADDING
300         if (usageSpec->padding == HKS_PADDING_NONE) {
301             if (ctx->private_len != message->size) {
302                 HKS_LOG_E("Mbedtls rsa crypt nopadding failed! message size = 0x%" LOG_PUBLIC "X", message->size);
303                 ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
304                 break;
305             }
306             if (encrypt) {
307                 ret = mbedtls_rsa_public(ctx, message->data, cipherText->data);
308                 *outlen = mbedtls_rsa_get_len(ctx);
309             } else {
310                 ret = mbedtls_rsa_private(ctx, mbedtls_ctr_drbg_random, &ctrDrbg,
311                     message->data, cipherText->data);
312                 *outlen = mbedtls_rsa_get_len(ctx);
313             }
314             break;
315         }
316 #endif
317         if (encrypt) {
318             ret = mbedtls_rsa_pkcs1_encrypt(ctx, mbedtls_ctr_drbg_random,
319                 &ctrDrbg, (size_t)message->size, message->data, cipherText->data);
320             *outlen = mbedtls_rsa_get_len(ctx);
321         } else {
322             ret = mbedtls_rsa_pkcs1_decrypt(ctx, mbedtls_ctr_drbg_random, &ctrDrbg,
323                 outlen, message->data, cipherText->data, (size_t)cipherText->size);
324         }
325     } while (0);
326 
327     mbedtls_rsa_free(ctx);
328     mbedtls_ctr_drbg_free(&ctrDrbg);
329     mbedtls_entropy_free(&entropy);
330 
331     return ret;
332 }
333 
HksMbedtlsRsaCrypt(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const bool encrypt,struct HksBlob * cipherText)334 static int32_t HksMbedtlsRsaCrypt(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
335     const struct HksBlob *message, const bool encrypt, struct HksBlob *cipherText)
336 {
337     int32_t ret = RsaKeyCheck(key);
338     HKS_IF_NOT_SUCC_RETURN(ret, ret)
339 
340     int32_t padding = MBEDTLS_RSA_PKCS_V15;
341     ret = HksToMbedtlsPadding(usageSpec->padding, &padding);
342     HKS_IF_NOT_SUCC_RETURN(ret, ret)
343 
344     mbedtls_rsa_context ctx;
345     (void)memset_s(&ctx, sizeof(mbedtls_rsa_context), 0, sizeof(mbedtls_rsa_context));
346     mbedtls_rsa_init(&ctx);
347 
348     if (padding == MBEDTLS_RSA_PKCS_V21) {
349         uint32_t mbedtlsAlg;
350         ret = HksToMbedtlsDigestAlg(usageSpec->digest, &mbedtlsAlg);
351         mbedtls_rsa_set_padding(&ctx, padding, (mbedtls_md_type_t)mbedtlsAlg);
352         HKS_IF_NOT_SUCC_RETURN(ret, ret)
353     }
354 
355     size_t outlen;
356     ret = HksMbedtlsRsaCryptMbedtls(key, usageSpec, message, encrypt, cipherText, &outlen, &ctx);
357     if (ret != HKS_SUCCESS) {
358         HKS_LOG_E("Mbedtls rsa crypt failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
359         (void)memset_s(cipherText->data, cipherText->size, 0, cipherText->size);
360         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
361     }
362     cipherText->size = (uint32_t)outlen;
363 
364     return ret;
365 }
366 
HksMbedtlsRsaEncrypt(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * cipherText,struct HksBlob * tagAead)367 int32_t HksMbedtlsRsaEncrypt(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
368     const struct HksBlob *message, struct HksBlob *cipherText, struct HksBlob *tagAead)
369 {
370     (void)tagAead;
371     return HksMbedtlsRsaCrypt(key, usageSpec, message, true, cipherText);
372 }
373 
HksMbedtlsRsaDecrypt(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * cipherText)374 int32_t HksMbedtlsRsaDecrypt(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
375     const struct HksBlob *message, struct HksBlob *cipherText)
376 {
377     return HksMbedtlsRsaCrypt(key, usageSpec, message, false, cipherText);
378 }
379 #endif /* HKS_SUPPORT_RSA_CRYPT */
380 
381 #ifdef HKS_SUPPORT_RSA_SIGN_VERIFY
HksToMbedtlsSignPadding(uint32_t hksPadding,int32_t * padding)382 static int32_t HksToMbedtlsSignPadding(uint32_t hksPadding, int32_t *padding)
383 {
384     switch (hksPadding) {
385         case HKS_PADDING_PKCS1_V1_5:
386             *padding = MBEDTLS_RSA_PKCS_V15;
387             break;
388         case HKS_PADDING_PSS:
389             *padding = MBEDTLS_RSA_PKCS_V21;
390             break;
391         default:
392             return HKS_ERROR_NOT_SUPPORTED;
393     }
394     return HKS_SUCCESS;
395 }
396 
HksToMbedtlsRsaSetPssSaltLen(const struct HksBlob * key,const uint32_t digest,const uint32_t hksPssSaltLen,HksMbedtlsSignVerifyParam * param)397 static int32_t HksToMbedtlsRsaSetPssSaltLen(const struct HksBlob *key, const uint32_t digest,
398     const uint32_t hksPssSaltLen, HksMbedtlsSignVerifyParam *param)
399 {
400     const struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)(key->data);
401     uint32_t digestLen = 0;
402     int32_t ret = HksGetDigestLen(digest, &digestLen);
403     HKS_IF_NOT_SUCC_RETURN(ret, ret);
404     int32_t saltLen = 0;
405 
406     switch (hksPssSaltLen) {
407         case HKS_RSA_PSS_SALTLEN_DIGEST:
408             saltLen = digestLen;
409             break;
410         case HKS_RSA_PSS_SALTLEN_MAX:
411             saltLen = (keyMaterial->keySize / HKS_BITS_PER_BYTE) - digestLen - MBEDTLS_RSA_PSS_DIGEST_NUM;
412             if (saltLen < 0) {
413                 return HKS_ERROR_INVALID_KEY_SIZE;
414             }
415             break;
416         default:
417             return HKS_ERROR_NOT_SUPPORTED;
418     }
419     param->pssSaltLen = saltLen;
420 
421     return HKS_SUCCESS;
422 }
423 
HksMbedtlsRsaSignHandle(mbedtls_rsa_context * ctx,mbedtls_ctr_drbg_context * ctrDrbg,HksMbedtlsSignVerifyParam * signParam,const struct HksBlob * message,struct HksBlob * signature)424 static int32_t HksMbedtlsRsaSignHandle(mbedtls_rsa_context *ctx, mbedtls_ctr_drbg_context *ctrDrbg,
425     HksMbedtlsSignVerifyParam *signParam, const struct HksBlob *message, struct HksBlob *signature)
426 {
427     int32_t ret = HKS_SUCCESS;
428     if (signParam->padding == MBEDTLS_RSA_PKCS_V21) {
429         // 支持传入saltlen
430         ret = mbedtls_rsa_rsassa_pss_sign_ext(ctx, mbedtls_ctr_drbg_random, ctrDrbg,
431             (mbedtls_md_type_t)signParam->mbedtlsAlg, message->size, message->data, signParam->pssSaltLen,
432             signature->data);
433     } else {
434         ret = mbedtls_rsa_pkcs1_sign(ctx, mbedtls_ctr_drbg_random, ctrDrbg,
435             (mbedtls_md_type_t)signParam->mbedtlsAlg, message->size, message->data, signature->data);
436     }
437 
438     return ret;
439 }
440 
HksMbedtlsRsaVerifyHandle(mbedtls_rsa_context * ctx,mbedtls_ctr_drbg_context * ctrDrbg,HksMbedtlsSignVerifyParam * verifyParam,const struct HksBlob * message,struct HksBlob * signature)441 static int32_t HksMbedtlsRsaVerifyHandle(mbedtls_rsa_context *ctx, mbedtls_ctr_drbg_context *ctrDrbg,
442     HksMbedtlsSignVerifyParam *verifyParam, const struct HksBlob *message, struct HksBlob *signature)
443 {
444     (void)ctrDrbg;
445     int32_t ret = HKS_SUCCESS;
446     if (verifyParam->padding == MBEDTLS_RSA_PKCS_V21) {
447         // 支持传入saltlen
448         ret = mbedtls_rsa_rsassa_pss_verify_ext(ctx, (mbedtls_md_type_t)verifyParam->mbedtlsAlg,
449             message->size, message->data, (mbedtls_md_type_t)verifyParam->mbedtlsAlg, verifyParam->pssSaltLen,
450             signature->data);
451     } else {
452         ret = mbedtls_rsa_pkcs1_verify(ctx,
453             (mbedtls_md_type_t)verifyParam->mbedtlsAlg, message->size, message->data, signature->data);
454     }
455 
456     return ret;
457 }
458 
HksMbedtlsRsaSignVerify(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const bool sign,struct HksBlob * signature)459 static int32_t HksMbedtlsRsaSignVerify(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
460     const struct HksBlob *message, const bool sign, struct HksBlob *signature)
461 {
462     uint32_t mbedtlsAlg;
463     int32_t ret = HksToMbedtlsDigestAlg(usageSpec->digest, &mbedtlsAlg);
464     HKS_IF_NOT_SUCC_RETURN(ret, ret)
465     int32_t padding;
466     ret = HksToMbedtlsSignPadding(usageSpec->padding, &padding);
467     HKS_IF_NOT_SUCC_RETURN(ret, ret)
468 
469     mbedtls_ctr_drbg_context ctrDrbg;
470     mbedtls_entropy_context entropy;
471     (void)memset_s(&entropy, sizeof(mbedtls_entropy_context), 0, sizeof(mbedtls_entropy_context));
472     (void)memset_s(&ctrDrbg, sizeof(mbedtls_ctr_drbg_context), 0, sizeof(mbedtls_ctr_drbg_context));
473     ret = HksCtrDrbgSeed(&ctrDrbg, &entropy);
474     HKS_IF_NOT_SUCC_RETURN(ret, ret)
475 
476     mbedtls_rsa_context ctx;
477     (void)memset_s(&ctx, sizeof(mbedtls_rsa_context), 0, sizeof(mbedtls_rsa_context));
478     mbedtls_rsa_init(&ctx);
479     mbedtls_rsa_set_padding(&ctx, padding, (mbedtls_md_type_t)mbedtlsAlg);
480     HksMbedtlsSignVerifyParam mbedtlsSignVerifyParam = { 0 };
481     if (padding == MBEDTLS_RSA_PKCS_V21) {
482         ret = HksToMbedtlsRsaSetPssSaltLen(key, usageSpec->digest, usageSpec->pssSaltLenType, &mbedtlsSignVerifyParam);
483         HKS_IF_NOT_SUCC_RETURN(ret, ret)
484     }
485     mbedtlsSignVerifyParam.mbedtlsAlg = mbedtlsAlg;
486     mbedtlsSignVerifyParam.padding = padding;
487 
488     do {
489         ret = RsaKeyMaterialToCtx(key, sign, &ctx); /* sign need private exponent (d) */
490         HKS_IF_NOT_SUCC_BREAK(ret)
491         if (sign) {
492             ret = HksMbedtlsRsaSignHandle(&ctx, &ctrDrbg, &mbedtlsSignVerifyParam, message, signature);
493         } else {
494             ret = HksMbedtlsRsaVerifyHandle(&ctx, &ctrDrbg, &mbedtlsSignVerifyParam, message, signature);
495         }
496         if (ret != HKS_MBEDTLS_SUCCESS) {
497             HKS_LOG_E("Mbedtls rsa sign/verify failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
498             ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
499             (void)memset_s(signature->data, signature->size, 0, signature->size);
500         }
501     } while (0);
502 
503     if (sign) {
504         signature->size = mbedtls_rsa_get_len(&ctx);
505     }
506 
507     mbedtls_rsa_free(&ctx);
508     mbedtls_ctr_drbg_free(&ctrDrbg);
509     mbedtls_entropy_free(&entropy);
510     return ret;
511 }
512 
RsaCheckNoPadding(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message)513 static int32_t RsaCheckNoPadding(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
514     const struct HksBlob *message)
515 {
516     if (usageSpec->digest != HKS_DIGEST_NONE) {
517         HKS_LOG_E("check rsa digest fail");
518         return HKS_ERROR_INVALID_DIGEST;
519     }
520 
521     const struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)(key->data);
522 #ifdef HKS_SUPPORT_RSA_C_FLEX_KEYSIZE
523     if (keyMaterial->keySize < HKS_RSA_KEY_SIZE_1024 || keyMaterial->keySize > HKS_RSA_KEY_SIZE_2048 ||
524         keyMaterial->keySize % HKS_RSA_KEYSIZE_CNT != 0) {
525         HKS_LOG_E("check rsa key size fail");
526         return HKS_ERROR_INVALID_KEY_SIZE;
527     }
528 #endif
529 
530     if (message->size * HKS_BITS_PER_BYTE != keyMaterial->keySize) {
531         HKS_LOG_E("check rsa message size fail");
532         return HKS_ERROR_INVALID_ARGUMENT;
533     }
534 
535     return HKS_SUCCESS;
536 }
537 
HksMbedtlsRsaSignForNoPadding(mbedtls_rsa_context * ctx,mbedtls_ctr_drbg_context * ctrDrbg,const struct HksBlob * message,struct HksBlob * signature)538 static int32_t HksMbedtlsRsaSignForNoPadding(mbedtls_rsa_context *ctx, mbedtls_ctr_drbg_context *ctrDrbg,
539     const struct HksBlob *message, struct HksBlob *signature)
540 {
541     int32_t ret = mbedtls_rsa_private(ctx, mbedtls_ctr_drbg_random, ctrDrbg, message->data, signature->data);
542     if (ret != HKS_SUCCESS) {
543         HKS_LOG_E("mbedtls rsa no padding sign failed, mbedtls ret = %" LOG_PUBLIC "d", ret);
544         (void)memset_s(signature->data, signature->size, 0, signature->size);
545         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
546     }
547 
548     signature->size = (uint32_t)mbedtls_rsa_get_len(ctx);
549     return HKS_SUCCESS;
550 }
551 
HksMbedtlsRsaVerifyForNoPadding(mbedtls_rsa_context * ctx,const struct HksBlob * message,struct HksBlob * signature)552 static int32_t HksMbedtlsRsaVerifyForNoPadding(mbedtls_rsa_context *ctx, const struct HksBlob *message,
553     struct HksBlob *signature)
554 {
555     uint8_t *decryptedHash = (uint8_t *)HksMalloc(message->size);
556     if (decryptedHash == NULL) {
557         HKS_LOG_E("HksMalloc failed");
558         return HKS_ERROR_MALLOC_FAIL;
559     }
560 
561     int32_t ret = mbedtls_rsa_public(ctx, signature->data, decryptedHash);
562     if (ret != HKS_SUCCESS) {
563         HKS_LOG_E("get message hash from signature fail, mbedtls ret = %" LOG_PUBLIC "d", ret);
564         HKS_FREE(decryptedHash);
565         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
566     }
567 
568     if (memcmp(decryptedHash, message->data, message->size) != 0) {
569         HKS_LOG_E("mbedtls rsa no padding verify failed");
570         HKS_FREE(decryptedHash);
571         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
572     }
573 
574     HKS_FREE(decryptedHash);
575     return HKS_SUCCESS;
576 }
577 
HksMbedtlsRsaSignVerifyForNoPadding(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const bool sign,struct HksBlob * signature)578 static int32_t HksMbedtlsRsaSignVerifyForNoPadding(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
579     const struct HksBlob *message, const bool sign, struct HksBlob *signature)
580 {
581     int32_t ret = RsaCheckNoPadding(key, usageSpec, message);
582     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check rsa no padding fail")
583 
584     mbedtls_ctr_drbg_context ctrDrbg;
585     mbedtls_entropy_context entropy;
586     (void)memset_s(&ctrDrbg, sizeof(mbedtls_ctr_drbg_context), 0, sizeof(mbedtls_ctr_drbg_context));
587     (void)memset_s(&entropy, sizeof(mbedtls_entropy_context), 0, sizeof(mbedtls_entropy_context));
588     ret = HksCtrDrbgSeed(&ctrDrbg, &entropy);
589     HKS_IF_NOT_SUCC_RETURN(ret, ret)
590 
591     mbedtls_rsa_context ctx;
592     (void)memset_s(&ctx, sizeof(mbedtls_rsa_context), 0, sizeof(mbedtls_rsa_context));
593     mbedtls_rsa_init(&ctx);
594 
595     do {
596         ret = RsaKeyMaterialToCtx(key, sign, &ctx); /* sign need private exponent (d) */
597         HKS_IF_NOT_SUCC_BREAK(ret)
598 
599         if (sign) {
600             ret = HksMbedtlsRsaSignForNoPadding(&ctx, &ctrDrbg, message, signature);
601         } else {
602             ret = HksMbedtlsRsaVerifyForNoPadding(&ctx, message, signature);
603         }
604         if (ret != HKS_SUCCESS) {
605             HKS_LOG_E("mbedtls rsa sign/verify failed");
606         }
607     } while (0);
608 
609     mbedtls_rsa_free(&ctx);
610     mbedtls_ctr_drbg_free(&ctrDrbg);
611     mbedtls_entropy_free(&entropy);
612 
613     return ret;
614 }
615 
HksMbedtlsRsaSign(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * signature)616 int32_t HksMbedtlsRsaSign(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
617     const struct HksBlob *message, struct HksBlob *signature)
618 {
619     int32_t ret = RsaKeyCheck(key);
620     HKS_IF_NOT_SUCC_RETURN(ret, ret)
621     if (usageSpec->padding != HKS_PADDING_NONE) {
622         ret = HksMbedtlsRsaSignVerify(key, usageSpec, message, true, signature);
623     } else {
624         ret = HksMbedtlsRsaSignVerifyForNoPadding(key, usageSpec, message, true, signature);
625     }
626 
627     if (ret != HKS_SUCCESS) {
628         HKS_LOG_E("HksMbedtlsRsaSign, ret = %" LOG_PUBLIC "d", ret);
629     }
630     return ret;
631 }
632 
HksMbedtlsRsaVerify(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const struct HksBlob * signature)633 int32_t HksMbedtlsRsaVerify(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
634     const struct HksBlob *message, const struct HksBlob *signature)
635 {
636     int32_t ret = RsaKeyCheck(key);
637     HKS_IF_NOT_SUCC_RETURN(ret, ret)
638     if (usageSpec->padding != HKS_PADDING_NONE) {
639         ret = HksMbedtlsRsaSignVerify(key, usageSpec, message, false, (struct HksBlob *)signature);
640     } else {
641         ret = HksMbedtlsRsaSignVerifyForNoPadding(key, usageSpec, message, false, (struct HksBlob *)signature);
642     }
643 
644     if (ret != HKS_SUCCESS) {
645         HKS_LOG_E("HksMbedtlsRsaVerify, ret = %" LOG_PUBLIC "d", ret);
646     }
647     return ret;
648 }
649 #endif /* HKS_SUPPORT_RSA_SIGN_VERIFY */
650 
651 #ifdef HKS_SUPPORT_RSA_GET_PUBLIC_KEY
GetRsaPubKeyCheckParams(const struct HksBlob * keyIn,const struct HksBlob * keyOut)652 static int32_t GetRsaPubKeyCheckParams(const struct HksBlob *keyIn, const struct HksBlob *keyOut)
653 {
654     int32_t ret = RsaKeyCheck(keyIn);
655     HKS_IF_NOT_SUCC_RETURN(ret, ret)
656 
657     /* check keyOut size */
658     const struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)(keyIn->data);
659     if (keyOut->size < (sizeof(struct HksPubKeyInfo) + keyMaterial->nSize + keyMaterial->eSize)) {
660         HKS_LOG_E("Rsa public keyOut size too small! keyOut size = 0x%" LOG_PUBLIC "X", keyOut->size);
661         return HKS_ERROR_BUFFER_TOO_SMALL;
662     }
663 
664     return HKS_SUCCESS;
665 }
666 
HksMbedtlsGetRsaPubKey(const struct HksBlob * keyIn,struct HksBlob * keyOut)667 int32_t HksMbedtlsGetRsaPubKey(const struct HksBlob *keyIn, struct HksBlob *keyOut)
668 {
669     int32_t ret = GetRsaPubKeyCheckParams(keyIn, keyOut);
670     HKS_IF_NOT_SUCC_RETURN(ret, ret)
671 
672     /* n + e, so need size is: sizeof(struct HksPubKeyInfo) + nSize + eSize */
673     const struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)(keyIn->data);
674     const uint32_t outLen = sizeof(struct HksPubKeyInfo) + keyMaterial->nSize + keyMaterial->eSize;
675     if (memcpy_s(keyOut->data, keyOut->size, (void *)keyMaterial, outLen) != EOK) {
676         HKS_LOG_E("Memcpy rsa pub key failed!");
677         (void)memset_s(keyOut->data, keyOut->size, 0, keyOut->size);
678         return HKS_ERROR_INSUFFICIENT_MEMORY;
679     }
680     ((struct KeyMaterialRsa *)(keyOut->data))->dSize = 0;
681     keyOut->size = outLen;
682 
683     return HKS_SUCCESS;
684 }
685 #endif /* HKS_SUPPORT_RSA_GET_PUBLIC_KEY */
686 #endif /* HKS_SUPPORT_RSA_C */
687