• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 #include "tee_elf_verify_openssl.h"
13 #include <mbedtls/cipher.h>
14 #include <mbedtls/bignum.h>
15 #include <mbedtls/ecp.h>
16 #include <mbedtls/ecdh.h>
17 #include <mbedtls/rsa.h>
18 #include <mbedtls/md.h>
19 #include <mbedtls/bignum.h>
20 #include "tee_log.h"
21 #include "securec.h"
22 #include "tee_v3_elf_verify.h"
23 #include <tee_crypto_signature_verify.h>
24 
25 static const char *g_ecies_hmac_salt = "salt for ecies kdf";
26 
mbd_rand(void * rng_state,unsigned char * out,size_t len)27 static inline int32_t mbd_rand(void *rng_state, unsigned char *out, size_t len)
28 {
29     (void)rng_state;
30     TEE_GenerateRandom(out, len);
31     return 0;
32 }
33 
rsa_build_key_with_ed(struct rsa_priv_key * priv_key,mbedtls_rsa_context * ctx)34 static int32_t rsa_build_key_with_ed(struct rsa_priv_key *priv_key, mbedtls_rsa_context *ctx)
35 {
36     int32_t rc;
37     rc = mbedtls_mpi_read_binary(&ctx->P, priv_key->p, get_effective_size(priv_key->p, priv_key->p_size));
38     rc |= mbedtls_mpi_read_binary(&ctx->Q, priv_key->q, get_effective_size(priv_key->q, priv_key->q_size));
39     rc |= mbedtls_mpi_read_binary(&ctx->DQ, priv_key->dq, get_effective_size(priv_key->dq, priv_key->dq_size));
40     rc |= mbedtls_mpi_read_binary(&ctx->DP, priv_key->dp, get_effective_size(priv_key->dp, priv_key->dp_size));
41     rc |= mbedtls_mpi_read_binary(&ctx->QP, priv_key->qinv, get_effective_size(priv_key->qinv, priv_key->qinv_size));
42     rc |= mbedtls_mpi_read_binary(&ctx->D, priv_key->d, get_effective_size(priv_key->d, priv_key->d_size));
43     rc |= mbedtls_mpi_read_binary(&ctx->E, priv_key->e, get_effective_size(priv_key->e, priv_key->e_size));
44     if (rc != 0) {
45         tloge("write binary fail, rc:%d", rc);
46         return rc;
47     }
48 
49     rc = mbedtls_mpi_mul_mpi(&ctx->N, &ctx->P, &ctx->Q);
50     if (rc != 0) {
51         tloge("read mul fail, rc:%d", rc);
52         return rc;
53     }
54 
55     ctx->len = mbedtls_mpi_size(&ctx->N);
56 
57     rc = mbedtls_rsa_complete(ctx);
58     if (rc != 0)
59         tloge("mbedtls rsa complete fail, rc:%d", rc);
60 
61     return rc;
62 }
63 
get_private_key(int32_t img_version,enum ta_type type,mbedtls_rsa_context * ctx)64 TEE_Result get_private_key(int32_t img_version, enum ta_type type, mbedtls_rsa_context *ctx)
65 {
66     uint8_t aes_key[AES_KEY_LEN];
67     const struct ecies_key_struct *ecies_key_data = NULL;
68     struct rsa_priv_key priv_key;
69 
70     if (ctx == NULL)
71         return TEE_ERROR_BAD_PARAMETERS;
72 
73     ecies_key_data = get_ecies_key_data(img_version, type);
74     if (ecies_key_data == NULL) {
75         tloge("Failed to get ecies key data\n");
76         return TEE_ERROR_BAD_PARAMETERS;
77     }
78 
79     TEE_Result ret = get_rsa_priv_aes_key(ecies_key_data, aes_key, sizeof(aes_key));
80     if (ret != TEE_SUCCESS) {
81         tloge("Failed to get AES key to decrypt RSA private components\n");
82         return ret;
83     }
84 
85     (void)memset_s(&priv_key, sizeof(priv_key), 0, sizeof(priv_key));
86     ret = aes_decrypt_rsa_private(ecies_key_data, aes_key, sizeof(aes_key), &priv_key);
87     (void)memset_s(aes_key, sizeof(aes_key), 0, sizeof(aes_key));
88     if (ret != TEE_SUCCESS) {
89         tloge("Failed to decrypt RSA private components\n");
90         return ret;
91     }
92 
93     int32_t rc = rsa_build_key_with_ed(&priv_key, ctx);
94     if (rc != 0)
95         return TEE_ERROR_GENERIC;
96 
97     (void)memset_s(&priv_key, sizeof(priv_key), 0, sizeof(priv_key));
98     return TEE_SUCCESS;
99 }
100 
tee_secure_img_decrypt_cipher_layer(const uint8_t * cipher_layer,uint32_t cipher_size,uint8_t * plaintext_layer,uint32_t * plaintext_size)101 TEE_Result tee_secure_img_decrypt_cipher_layer(const uint8_t *cipher_layer, uint32_t cipher_size,
102     uint8_t *plaintext_layer, uint32_t *plaintext_size)
103 {
104     TEE_Result ret;
105     bool check = (cipher_layer == NULL || cipher_size == 0 || plaintext_layer == NULL ||
106         plaintext_size == NULL || *plaintext_size < cipher_size);
107     if (check)
108         return TEE_ERROR_BAD_PARAMETERS;
109 
110     enum ta_type type = V3_TYPE_2048;
111     if (judge_rsa_key_type(cipher_size, &type) != TEE_SUCCESS)
112         return TEE_ERROR_BAD_PARAMETERS;
113 
114     mbedtls_rsa_context ctx;
115     mbedtls_rsa_init(&ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1);
116     ret = get_private_key(CIPHER_LAYER_VERSION, type, &ctx);
117     if (ret != TEE_SUCCESS) {
118         tloge("get private key fail!");
119         goto clean;
120     }
121 
122     size_t out_len = *plaintext_size;
123     int32_t rc = mbedtls_rsa_rsaes_oaep_decrypt(&ctx, mbd_rand, NULL, MBEDTLS_RSA_PRIVATE, NULL, 0, &out_len,
124         cipher_layer, plaintext_layer, *plaintext_size);
125     if (rc != 0) {
126         tloge("rsa decrypt fail, rc:%d", rc);
127         ret = TEE_ERROR_GENERIC;
128         goto clean;
129     }
130     *plaintext_size = out_len;
131     ret = TEE_SUCCESS;
132 clean:
133     mbedtls_rsa_free(&ctx);
134     return ret;
135 }
136 
ecies_kem_init(const struct ecc_derive_data_st * ecc_data,mbedtls_ecp_group * grp,mbedtls_ecp_point * q,mbedtls_mpi * d)137 static TEE_Result ecies_kem_init(const struct ecc_derive_data_st *ecc_data,
138     mbedtls_ecp_group *grp, mbedtls_ecp_point *q, mbedtls_mpi *d)
139 {
140     int32_t rc = mbedtls_mpi_read_binary(d, ecc_data->ec1_priv, ECIES_PRIV_LEN);
141     if (rc != 0) {
142         tloge("read binary failed\n");
143         return TEE_ERROR_GENERIC;
144     }
145 
146     mbedtls_ecp_group_load(grp, MBEDTLS_ECP_DP_SECP256R1);
147     rc = mbedtls_ecp_point_read_binary(grp, q, ecc_data->ec2_pub, ecc_data->ec2_len);
148     if (rc != 0) {
149         tloge("ecp point read binary failed\n");
150         return TEE_ERROR_GENERIC;
151     }
152 
153     return TEE_SUCCESS;
154 }
155 
check_ecc_params_invalid(const struct ecc_derive_data_st * ecc_data,uint8_t * key)156 static bool check_ecc_params_invalid(const struct ecc_derive_data_st *ecc_data, uint8_t *key)
157 {
158     if (ecc_data == NULL || key == NULL)
159         return true;
160 
161     return (ecc_data->ec1_len != ECIES_PRIV_LEN || ecc_data->ec2_len != ECIES_PUB_LEN);
162 }
163 
164 /* generate a 256 bytes AES key with ECDH + HMAC */
ecies_kem_decrypt(const struct ecc_derive_data_st * ecc_data,uint8_t * key,uint32_t key_len)165 int32_t ecies_kem_decrypt(const struct ecc_derive_data_st *ecc_data, uint8_t *key, uint32_t key_len)
166 {
167     mbedtls_ecp_group grp;
168     mbedtls_ecp_point q;
169     mbedtls_mpi d, z;
170     int32_t rc;
171 
172     if (check_ecc_params_invalid(ecc_data, key) || key_len < SHA256_LEN) {
173         tloge("key len invalid\n");
174         return -1;
175     }
176 
177     mbedtls_mpi_init(&d);
178     mbedtls_mpi_init(&z);
179     mbedtls_ecp_group_init(&grp);
180     mbedtls_ecp_point_init(&q);
181 
182     if (ecies_kem_init(ecc_data, &grp, &q, &d) != TEE_SUCCESS) {
183         tloge("Failed to initialize ctx\n");
184         rc = -1;
185         goto clean;
186     }
187 
188     rc = mbedtls_ecdh_compute_shared(&grp, &z, &q, &d, NULL, NULL);
189     if (rc != 0) {
190         tloge("ecdh compute shared fail!! rc:%d", rc);
191         goto clean;
192     }
193     uint8_t secret[AES_KEY_LEN];
194     mbedtls_mpi_write_binary(&z, secret, sizeof(secret));
195     const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
196     if (md_info == NULL) {
197         tloge("hmac md is NULL");
198         rc = -1;
199         goto clean;
200     }
201 
202     rc = mbedtls_md_hmac(md_info, secret, sizeof(secret),
203         (uint8_t *)g_ecies_hmac_salt, strlen(g_ecies_hmac_salt) + 1, key);
204     if (rc != 0)
205         tloge("hmac failed\n");
206 
207 clean:
208     mbedtls_ecp_group_free(&grp);
209     mbedtls_ecp_point_free(&q);
210     mbedtls_mpi_free(&d);
211     mbedtls_mpi_free(&z);
212     return rc;
213 }
214 
215 #define BYTE2BIT 8
216 #define IV_LEN 16
aes_cbc_256_decrypt(const uint8_t * key,const uint8_t * iv,const uint8_t * in,uint32_t in_len,uint8_t * out)217 int32_t aes_cbc_256_decrypt(const uint8_t *key, const uint8_t *iv,
218     const uint8_t *in, uint32_t in_len, uint8_t *out)
219 {
220     mbedtls_cipher_context_t cipher_ctx;
221 
222     if (key == NULL || iv == NULL || in == NULL || out == NULL)
223         return -1;
224 
225     mbedtls_cipher_init(&cipher_ctx);
226     const mbedtls_cipher_info_t *cipher_info = NULL;
227     cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_CBC);
228     if (cipher_info == NULL) {
229         tloge("cipher_info is invalid");
230         goto clean;
231     }
232 
233     int32_t rc = mbedtls_cipher_setup(&cipher_ctx, cipher_info);
234     if (rc != 0) {
235         tloge("aes cipher setup failed,rc:%d", rc);
236         goto clean;
237     }
238 
239     rc = mbedtls_cipher_setkey(&cipher_ctx, key, AES_KEY_LEN * BYTE2BIT, MBEDTLS_DECRYPT);
240     if (rc != 0) {
241         tloge("aes cipher setkey failed,rc:%d\n", rc);
242         goto clean;
243     }
244 
245     rc = mbedtls_cipher_set_iv(&cipher_ctx, iv, IV_LEN);
246     if (rc != 0) {
247         tloge("aes cipher set iv failed,rc:%d\n", rc);
248         goto clean;
249     }
250 
251     size_t update_len;
252     size_t olen;
253     rc = mbedtls_cipher_update(&cipher_ctx, in, in_len, out, &update_len);
254     if (rc != 0) {
255         tloge("aes cipher update failed,rc:%d\n", rc);
256         goto clean;
257     }
258 
259     rc = mbedtls_cipher_finish(&cipher_ctx, out + update_len, &olen);
260     if (rc != 0) {
261         tloge("aes cipher finish failed,rc:%d\n", rc);
262         goto clean;
263     }
264 
265     mbedtls_cipher_free(&cipher_ctx);
266     return (uint32_t)(update_len + olen);
267 
268 clean:
269     mbedtls_cipher_free(&cipher_ctx);
270     return -1;
271 }
272