• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */