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 "bignum_harden.h"
20 #include "cipher_adapt.h"
21 #include "mbedtls/error.h"
22 #include "mbedtls/platform_util.h"
23 #include "mbedtls/platform.h"
24 #include "dfx.h"
25
26 #define max(a, b) (a) > (b) ? (a) : (b)
27 #define min(a, b) (a) < (b) ? (a) : (b)
28 #define max_three(a, b, c) max( max( a, b ), c )
29 #define min_three(a, b, c) min( min( a, b ), c )
30
31 #if defined(MBEDTLS_BIGNUM_EXP_MOD_USE_HARDWARE) || defined(MBEDTLS_BIGNUM_MOD_USE_HARDWARE)
get_size_align(size_t size_a,size_t size_b,size_t size_c,size_t * size_align)32 static void get_size_align( size_t size_a, size_t size_b, size_t size_c, size_t *size_align )
33 {
34 size_t sizes[] = {
35 #if defined(DRV_PKE_LEN_1024_SUPPORT)
36 DRV_PKE_LEN_1024,
37 #endif
38 DRV_PKE_LEN_2048, DRV_PKE_LEN_3072, DRV_PKE_LEN_4096 };
39 int sizes_count = sizeof( sizes ) / sizeof( sizes[0] );
40 *size_align = max_three( size_a, size_b, size_c );
41
42 for( int i = 0; i < sizes_count - 1; i++ )
43 {
44 if ( *size_align <= sizes[i] )
45 {
46 *size_align = sizes[i];
47 return;
48 }
49 }
50 *size_align = sizes[sizes_count - 1];
51 }
52 #endif /* MBEDTLS_BIGNUM_EXP_MOD_USE_HARDWARE || MBEDTLS_BIGNUM_MOD_USE_HARDWARE */
53
54 #if defined(MBEDTLS_BIGNUM_EXP_MOD_USE_HARDWARE)
check_exp_mod_harden_can_do(const mbedtls_mpi * A,const mbedtls_mpi * E,const mbedtls_mpi * N)55 int check_exp_mod_harden_can_do( const mbedtls_mpi *A,
56 const mbedtls_mpi *E, const mbedtls_mpi *N )
57 {
58 size_t size_a, size_e, size_n, size_max;
59 size_a = mbedtls_mpi_size( A );
60 size_e = mbedtls_mpi_size( E );
61 size_n = mbedtls_mpi_size( N );
62 size_max = max_three( size_a, size_e, size_n );
63
64 if( IS_PKE_EXP_MOD_FUNC_REGISTERED() != TD_TRUE )
65 return ( 0 );
66 if (size_max > DRV_PKE_LEN_4096)
67 return( 0 );
68
69 #if defined(DRV_PKE_LEN_1024_SUPPORT)
70 get_size_align( size_a, size_e, size_n, &size_max );
71 return( ( size_max - size_n ) <= 2 );
72 #else
73 return( 1 );
74 #endif
75 }
76
exp_mod_harden(mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * E,const mbedtls_mpi * N)77 int exp_mod_harden( mbedtls_mpi *X, const mbedtls_mpi *A,
78 const mbedtls_mpi *E, const mbedtls_mpi *N )
79 {
80 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
81 drv_pke_data hw_data[3];
82 size_t size_align = 0;
83 const mbedtls_mpi *inputs[] = { A, E, N };
84 unsigned char *buffer = NULL;
85
86 mbedtls_harden_log_func_enter();
87
88 get_size_align( mbedtls_mpi_size( A ), mbedtls_mpi_size( E ), mbedtls_mpi_size( N ), &size_align );
89
90 buffer = mbedtls_calloc( 3, size_align );
91 if ( buffer == NULL )
92 {
93 mbedtls_harden_log_err("mbedtls_calloc failed!\n");
94 return MBEDTLS_ERR_MPI_ALLOC_FAILED;
95 }
96
97 for (int i = 0; i < 3; i++)
98 {
99 hw_data[i].data = buffer + (i * size_align);
100 hw_data[i].length = size_align;
101 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( inputs[i], hw_data[i].data, hw_data[i].length ) );
102 }
103
104 ret = CIPHER_PKE_INIT();
105 if( ret != MBEDTLS_HARDEN_SUCCESS )
106 {
107 mbedtls_harden_log_err("CIPHER_PKE_INIT failed! ret = 0x%x\n", ret);
108 ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
109 goto cleanup;
110 }
111
112 ret = CIPHER_PKE_EXP_MOD( &hw_data[2], &hw_data[1], &hw_data[0], &hw_data[0] );
113 if( ret != MBEDTLS_HARDEN_SUCCESS )
114 {
115 ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
116 goto cleanup;
117 }
118
119 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, hw_data[0].data, hw_data[0].length ) );
120 ret = 0;
121
122 cleanup:
123 CIPHER_PKE_DEINIT();
124 if( buffer != NULL )
125 {
126 mbedtls_platform_zeroize( buffer, 3 * size_align );
127 mbedtls_free( buffer );
128 }
129
130 mbedtls_harden_log_func_exit();
131
132 return( ret );
133 }
134 #endif /* MBEDTLS_BIGNUM_EXP_MOD_USE_HARDWARE */
135
136 #if defined(MBEDTLS_BIGNUM_MOD_USE_HARDWARE)
check_mod_harden_can_do(const mbedtls_mpi * A,const mbedtls_mpi * B)137 int check_mod_harden_can_do( const mbedtls_mpi *A, const mbedtls_mpi *B )
138 {
139 size_t size_a, size_b, size_max;
140 size_a = mbedtls_mpi_size( A );
141 size_b = mbedtls_mpi_size( B );
142 size_max = max( size_a, size_b );
143
144 if( IS_PKE_MOD_FUNC_REGISTERED() != TD_TRUE )
145 return ( 0 );
146 if ( A->MBEDTLS_PRIVATE(s) < 0 || mbedtls_mpi_cmp_int( B, 0 ) == 0 || size_max > DRV_PKE_LEN_4096 )
147 return( 0 );
148
149 #if defined(DRV_PKE_LEN_1024_SUPPORT)
150 if ( size_a > 2 * size_b || mbedtls_mpi_get_bit( B, 0 ) == 0 )
151 return( 0 );
152 return( 1 );
153 #else
154 return( 1 );
155 #endif
156 }
157
mod_harden(mbedtls_mpi * R,const mbedtls_mpi * A,const mbedtls_mpi * B)158 int mod_harden( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
159 {
160 int ret;
161 size_t size_align = 0;
162 drv_pke_data hw_data[3];
163 unsigned char *buffer = NULL;
164
165 mbedtls_harden_log_func_enter();
166
167 get_size_align( mbedtls_mpi_size( A ), mbedtls_mpi_size( B ), 0, &size_align );
168
169 buffer = mbedtls_calloc( 3, size_align );
170 if ( buffer == NULL )
171 {
172 mbedtls_harden_log_err("mbedtls_calloc failed!\n");
173 return MBEDTLS_ERR_MPI_ALLOC_FAILED;
174 }
175
176 for (int i = 0; i < 3; i++)
177 {
178 hw_data[i].data = buffer + (i * size_align);
179 hw_data[i].length = size_align;
180 }
181 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( A, hw_data[0].data, hw_data[0].length ) );
182 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( B, hw_data[1].data, hw_data[1].length ) );
183
184 ret = CIPHER_PKE_INIT();
185 if( ret != MBEDTLS_HARDEN_SUCCESS )
186 {
187 mbedtls_harden_log_err("CIPHER_PKE_INIT failed! ret = 0x%x\n", ret);
188 ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
189 goto cleanup;
190 }
191
192 ret = CIPHER_PKE_MOD( &hw_data[0], &hw_data[1], &hw_data[2] );
193 if( ret != MBEDTLS_HARDEN_SUCCESS )
194 {
195 mbedtls_harden_log_err("CIPHER_PKE_MOD failed! ret = 0x%x\n", ret);
196 ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
197 goto cleanup;
198 }
199
200 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( R, hw_data[2].data, hw_data[2].length ) );
201
202 cleanup:
203 CIPHER_PKE_DEINIT();
204 if( buffer != NULL )
205 {
206 mbedtls_platform_zeroize( buffer, 3 * size_align );
207 mbedtls_free( buffer );
208 }
209
210 mbedtls_harden_log_func_exit();
211
212 return( ret );
213 }
214 #endif /* MBEDTLS_BIGNUM_MOD_USE_HARDWARE */