1 /**
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 * Description: mbedtls harden adapt internal source file.
15 *
16 * Create: 2023-05-10
17 */
18
19 #include "ecc_harden_common.h"
20 #include "mbedtls/platform.h"
21 #include "mbedtls/platform_util.h"
22 #include "common.h"
23 #include "mbedtls_platform_hardware_config.h"
24
25 typedef struct {
26 mbedtls_ecp_group_id group_id;
27 drv_pke_ecc_curve_type curve_type;
28 unsigned int klen;
29 } curve_info;
30
31 static const curve_info g_curve_info_table[] = {
32 { MBEDTLS_ECP_DP_NONE, DRV_PKE_ECC_TYPE_INVALID, 0 },
33 #if defined(MBEDTLS_SECP192R1_USE_HARDWARE)
34 { MBEDTLS_ECP_DP_SECP192R1, DRV_PKE_ECC_TYPE_FIPS_P192R, DRV_PKE_LEN_192 },
35 #endif
36 #if defined(MBEDTLS_SECP224R1_USE_HARDWARE)
37 { MBEDTLS_ECP_DP_SECP224R1, DRV_PKE_ECC_TYPE_FIPS_P224R, DRV_PKE_LEN_224 },
38 #endif
39 #if defined(MBEDTLS_SECP256R1_USE_HARDWARE)
40 { MBEDTLS_ECP_DP_SECP256R1, DRV_PKE_ECC_TYPE_FIPS_P256R, DRV_PKE_LEN_256 },
41 #endif
42 #if defined(MBEDTLS_SECP384R1_USE_HARDWARE)
43 { MBEDTLS_ECP_DP_SECP384R1, DRV_PKE_ECC_TYPE_FIPS_P384R, DRV_PKE_LEN_384 },
44 #endif
45 #if defined(MBEDTLS_SECP521R1_USE_HARDWARE)
46 #if defined(HARDWARE_521_ALIGN_576_LEN)
47 { MBEDTLS_ECP_DP_SECP521R1, DRV_PKE_ECC_TYPE_FIPS_P521R, DRV_PKE_LEN_576 },
48 #else
49 { MBEDTLS_ECP_DP_SECP521R1, DRV_PKE_ECC_TYPE_FIPS_P521R, DRV_PKE_LEN_521 },
50 #endif
51 #endif
52 #if defined(MBEDTLS_BP256R1_USE_HARDWARE)
53 { MBEDTLS_ECP_DP_BP256R1, DRV_PKE_ECC_TYPE_RFC5639_P256, DRV_PKE_LEN_256 },
54 #endif
55 #if defined(MBEDTLS_BP384R1_USE_HARDWARE)
56 { MBEDTLS_ECP_DP_BP384R1, DRV_PKE_ECC_TYPE_RFC5639_P384, DRV_PKE_LEN_384 },
57 #endif
58 #if defined(MBEDTLS_BP512R1_USE_HARDWARE)
59 { MBEDTLS_ECP_DP_BP512R1, DRV_PKE_ECC_TYPE_RFC5639_P512, DRV_PKE_LEN_512 },
60 #endif
61 #if defined(MBEDTLS_CURVE25519_USE_HARDWARE)
62 { MBEDTLS_ECP_DP_CURVE25519, DRV_PKE_ECC_TYPE_RFC7748, DRV_PKE_LEN_256 },
63 #endif
64 #if defined(MBEDTLS_SECP256K1_USE_HARDWARE)
65 { MBEDTLS_ECP_DP_SECP256K1, DRV_PKE_ECC_TYPE_FIPS_P256K, DRV_PKE_LEN_256 },
66 #endif
67 #if defined(MBEDTLS_CURVE448_USE_HARDWARE)
68 { MBEDTLS_ECP_DP_CURVE448, DRV_PKE_ECC_TYPE_RFC7748_448, DRV_PKE_LEN_448 },
69 #endif
70 };
71
get_curve_type(mbedtls_ecp_group_id grp_id,drv_pke_ecc_curve_type * curve_type,unsigned int * klen)72 void get_curve_type( mbedtls_ecp_group_id grp_id, drv_pke_ecc_curve_type *curve_type, unsigned int *klen )
73 {
74 unsigned int i = 0;
75 for (i = 0; i < sizeof(g_curve_info_table) / sizeof(g_curve_info_table[0]); i++) {
76 if (g_curve_info_table[i].group_id == grp_id) {
77 *curve_type = g_curve_info_table[i].curve_type;
78 *klen = g_curve_info_table[i].klen;
79 return;
80 }
81 }
82 *curve_type = DRV_PKE_ECC_TYPE_INVALID;
83 *klen = 0;
84 }
85
check_ecc_harden_can_do(mbedtls_ecp_group * grp,int (* f_rng)(void *,unsigned char *,size_t))86 int check_ecc_harden_can_do( mbedtls_ecp_group *grp, int (*f_rng)(void *, unsigned char *, size_t) )
87 {
88 drv_pke_ecc_curve_type curve_type = DRV_PKE_ECC_TYPE_INVALID;
89 unsigned int klen = 0;
90
91 if( IS_PKE_ECC_FUNC_REGISTERED() != TD_TRUE || IS_HASH_FUNC_REGISTERED() != TD_TRUE )
92 return ( 0 );
93
94 (void)f_rng;
95
96 get_curve_type( grp->id, &curve_type, &klen );
97 return curve_type != DRV_PKE_ECC_TYPE_INVALID;
98 }
99
ecp_priv_key_alloc(const unsigned int klen,drv_pke_data * priv_key)100 int ecp_priv_key_alloc( const unsigned int klen, drv_pke_data *priv_key )
101 {
102 int ret;
103
104 if( priv_key == NULL )
105 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
106
107 priv_key->length = klen;
108 priv_key->data = mbedtls_calloc( 1, klen );
109 if( priv_key->data == NULL )
110 {
111 ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
112 goto cleanup;
113 }
114
115 return( 0 );
116
117 cleanup:
118 ecp_priv_key_free(priv_key);
119 return( ret );
120 }
121
ecp_priv_key_free(drv_pke_data * priv_key)122 void ecp_priv_key_free( drv_pke_data *priv_key )
123 {
124 if( priv_key == NULL)
125 return;
126
127 if( priv_key->data != NULL )
128 {
129 mbedtls_platform_zeroize( priv_key->data, priv_key->length );
130 mbedtls_free( priv_key->data );
131 priv_key->data = NULL;
132 }
133 priv_key->length = 0;
134 }
135
ecp_pub_key_alloc(const unsigned int klen,drv_pke_ecc_point * pub_key)136 int ecp_pub_key_alloc( const unsigned int klen, drv_pke_ecc_point *pub_key )
137 {
138 int ret;
139
140 if( pub_key == NULL )
141 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
142
143 pub_key->length = klen;
144 pub_key->x = mbedtls_calloc( 1, klen );
145 pub_key->y = mbedtls_calloc( 1, klen );
146 if( pub_key->x == NULL || pub_key->y == NULL )
147 {
148 ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
149 goto cleanup;
150 }
151
152 return( 0 );
153
154 cleanup:
155 ecp_pub_key_free(pub_key);
156 return( ret );
157 }
158
ecp_pub_key_free(drv_pke_ecc_point * pub_key)159 void ecp_pub_key_free( drv_pke_ecc_point *pub_key )
160 {
161 if( pub_key == NULL)
162 return;
163
164 if( pub_key->x != NULL )
165 {
166 mbedtls_platform_zeroize( pub_key->x, pub_key->length );
167 mbedtls_free( pub_key->x );
168 pub_key->x = NULL;
169 }
170 if( pub_key->y != NULL )
171 {
172 mbedtls_platform_zeroize( pub_key->y, pub_key->length );
173 mbedtls_free( pub_key->y );
174 pub_key->y = NULL;
175 }
176 pub_key->length = 0;
177 }
178
ecp_priv_key_create(drv_pke_ecc_curve_type ecc_type,unsigned int klen,const mbedtls_mpi * d,drv_pke_data * priv_key)179 int ecp_priv_key_create( drv_pke_ecc_curve_type ecc_type, unsigned int klen, const mbedtls_mpi *d,
180 drv_pke_data *priv_key )
181 {
182 int ret;
183
184 if( d == NULL )
185 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
186
187 ret = ecp_priv_key_alloc( klen, priv_key );
188 if( ret != 0 )
189 return( ret );
190
191 if( ecc_type == DRV_PKE_ECC_TYPE_RFC7748 )
192 {
193 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( d, priv_key->data, klen ) );
194 }
195 else
196 {
197 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, priv_key->data, klen ) );
198 }
199
200 return( 0 );
201
202 cleanup:
203 ecp_priv_key_free(priv_key);
204 return( ret );
205 }
206
ecp_pub_key_create(drv_pke_ecc_curve_type ecc_type,unsigned int klen,const mbedtls_ecp_point * pub,drv_pke_ecc_point * pub_key)207 int ecp_pub_key_create( drv_pke_ecc_curve_type ecc_type, unsigned int klen, const mbedtls_ecp_point *pub,
208 drv_pke_ecc_point *pub_key )
209 {
210 int ret;
211
212 if( pub == NULL )
213 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
214
215 ret = ecp_pub_key_alloc( klen, pub_key );
216 if( ret != 0 )
217 return( ret );
218
219 if( ecc_type == DRV_PKE_ECC_TYPE_RFC7748 )
220 {
221 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &pub->MBEDTLS_PRIVATE(X), pub_key->x, klen ) );
222 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &pub->MBEDTLS_PRIVATE(Y), pub_key->y, klen ) );
223 }
224 else
225 {
226 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &pub->MBEDTLS_PRIVATE(X), pub_key->x, klen ) );
227 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &pub->MBEDTLS_PRIVATE(Y), pub_key->y, klen ) );
228 }
229
230 return( 0 );
231
232 cleanup:
233 ecp_pub_key_free( pub_key );
234 return( ret );
235 }