1 /*
2  * Test driver for signature functions.
3  * Currently supports signing and verifying precalculated hashes, using
4  * only deterministic ECDSA on curves secp256r1, secp384r1 and secp521r1.
5  */
6 /*  Copyright The Mbed TLS Contributors
7  *  SPDX-License-Identifier: Apache-2.0
8  *
9  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
10  *  not use this file except in compliance with the License.
11  *  You may obtain a copy of the License at
12  *
13  *  http://www.apache.org/licenses/LICENSE-2.0
14  *
15  *  Unless required by applicable law or agreed to in writing, software
16  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  *  See the License for the specific language governing permissions and
19  *  limitations under the License.
20  */
21 
22 #if !defined(MBEDTLS_CONFIG_FILE)
23 #include "mbedtls/config.h"
24 #else
25 #include MBEDTLS_CONFIG_FILE
26 #endif
27 
28 #if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(PSA_CRYPTO_DRIVER_TEST)
29 #include "psa/crypto.h"
30 #include "psa_crypto_core.h"
31 #include "mbedtls/ecp.h"
32 
33 #include "test/drivers/signature.h"
34 
35 #include "mbedtls/md.h"
36 #include "mbedtls/ecdsa.h"
37 
38 #include "test/random.h"
39 
40 #include <string.h>
41 
42 test_driver_signature_hooks_t test_driver_signature_sign_hooks = TEST_DRIVER_SIGNATURE_INIT;
43 test_driver_signature_hooks_t test_driver_signature_verify_hooks = TEST_DRIVER_SIGNATURE_INIT;
44 
test_transparent_signature_sign_hash(const psa_key_attributes_t * attributes,const uint8_t * key,size_t key_length,psa_algorithm_t alg,const uint8_t * hash,size_t hash_length,uint8_t * signature,size_t signature_size,size_t * signature_length)45 psa_status_t test_transparent_signature_sign_hash(
46     const psa_key_attributes_t *attributes,
47     const uint8_t *key, size_t key_length,
48     psa_algorithm_t alg,
49     const uint8_t *hash, size_t hash_length,
50     uint8_t *signature, size_t signature_size, size_t *signature_length )
51 {
52     ++test_driver_signature_sign_hooks.hits;
53 
54     if( test_driver_signature_sign_hooks.forced_status != PSA_SUCCESS )
55         return( test_driver_signature_sign_hooks.forced_status );
56 
57     if( test_driver_signature_sign_hooks.forced_output != NULL )
58     {
59         if( test_driver_signature_sign_hooks.forced_output_length > signature_size )
60             return( PSA_ERROR_BUFFER_TOO_SMALL );
61         memcpy( signature, test_driver_signature_sign_hooks.forced_output,
62                 test_driver_signature_sign_hooks.forced_output_length );
63         *signature_length = test_driver_signature_sign_hooks.forced_output_length;
64         return( PSA_SUCCESS );
65     }
66 
67     psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
68 
69 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
70     defined(MBEDTLS_SHA256_C)
71     if( alg != PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ) )
72         return( PSA_ERROR_NOT_SUPPORTED );
73     mbedtls_ecp_group_id grp_id;
74     switch( psa_get_key_type( attributes ) )
75     {
76         case PSA_ECC_CURVE_SECP_R1:
77             switch( psa_get_key_bits( attributes ) )
78             {
79                 case 256:
80                     grp_id = MBEDTLS_ECP_DP_SECP256R1;
81                     break;
82                 case 384:
83                     grp_id = MBEDTLS_ECP_DP_SECP384R1;
84                     break;
85                 case 521:
86                     grp_id = MBEDTLS_ECP_DP_SECP521R1;
87                     break;
88                 default:
89                     return( PSA_ERROR_NOT_SUPPORTED );
90             }
91             break;
92         default:
93             return( PSA_ERROR_NOT_SUPPORTED );
94     }
95 
96     /* Beyond this point, the driver is actually doing the work of
97      * calculating the signature. */
98 
99     status = PSA_ERROR_GENERIC_ERROR;
100     int ret = 0;
101     mbedtls_mpi r, s;
102     mbedtls_mpi_init( &r );
103     mbedtls_mpi_init( &s );
104     mbedtls_ecp_keypair ecp;
105     mbedtls_ecp_keypair_init( &ecp );
106     size_t curve_bytes = PSA_BITS_TO_BYTES( ecp.grp.pbits );
107 
108     MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ecp.grp, grp_id ) );
109     MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( &ecp.grp, &ecp.Q,
110                                                     key, key_length ) );
111 
112     /* Code adapted from psa_ecdsa_sign() in psa_crypto.c. */
113     mbedtls_md_type_t md_alg = MBEDTLS_MD_SHA256;
114     if( signature_size < 2 * curve_bytes )
115     {
116         status = PSA_ERROR_BUFFER_TOO_SMALL;
117         goto cleanup;
118     }
119     MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp.grp, &r, &s, &ecp.d,
120                                   hash, hash_length, md_alg ) );
121     MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
122                                                signature,
123                                                curve_bytes ) );
124     MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
125                                                signature + curve_bytes,
126                                                curve_bytes ) );
127 cleanup:
128     status = mbedtls_to_psa_error( ret );
129     mbedtls_mpi_free( &r );
130     mbedtls_mpi_free( &s );
131     mbedtls_ecp_keypair_free( &ecp );
132     if( status == PSA_SUCCESS )
133         *signature_length = 2 * curve_bytes;
134 #else /* defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
135          defined(MBEDTLS_SHA256_C) */
136     (void) attributes;
137     (void) key;
138     (void) key_length;
139     (void) alg;
140     (void) hash;
141     (void) hash_length;
142 #endif /* defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
143           defined(MBEDTLS_SHA256_C) */
144 
145     return( status );
146 }
147 
test_opaque_signature_sign_hash(const psa_key_attributes_t * attributes,const uint8_t * key,size_t key_length,psa_algorithm_t alg,const uint8_t * hash,size_t hash_length,uint8_t * signature,size_t signature_size,size_t * signature_length)148 psa_status_t test_opaque_signature_sign_hash(
149     const psa_key_attributes_t *attributes,
150     const uint8_t *key, size_t key_length,
151     psa_algorithm_t alg,
152     const uint8_t *hash, size_t hash_length,
153     uint8_t *signature, size_t signature_size, size_t *signature_length )
154 {
155     (void) attributes;
156     (void) key;
157     (void) key_length;
158     (void) alg;
159     (void) hash;
160     (void) hash_length;
161     (void) signature;
162     (void) signature_size;
163     (void) signature_length;
164     return( PSA_ERROR_NOT_SUPPORTED );
165 }
166 
test_transparent_signature_verify_hash(const psa_key_attributes_t * attributes,const uint8_t * key,size_t key_length,psa_algorithm_t alg,const uint8_t * hash,size_t hash_length,const uint8_t * signature,size_t signature_length)167 psa_status_t test_transparent_signature_verify_hash(
168     const psa_key_attributes_t *attributes,
169     const uint8_t *key, size_t key_length,
170     psa_algorithm_t alg,
171     const uint8_t *hash, size_t hash_length,
172     const uint8_t *signature, size_t signature_length )
173 {
174     ++test_driver_signature_verify_hooks.hits;
175 
176     if( test_driver_signature_verify_hooks.forced_status != PSA_SUCCESS )
177         return( test_driver_signature_verify_hooks.forced_status );
178 
179     psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
180 
181 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
182     defined(MBEDTLS_SHA256_C)
183     if( alg != PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ) )
184         return( PSA_ERROR_NOT_SUPPORTED );
185     mbedtls_ecp_group_id grp_id;
186     switch( psa_get_key_type( attributes ) )
187     {
188         case PSA_ECC_CURVE_SECP_R1:
189             switch( psa_get_key_bits( attributes ) )
190             {
191                 case 256:
192                     grp_id = MBEDTLS_ECP_DP_SECP256R1;
193                     break;
194                 case 384:
195                     grp_id = MBEDTLS_ECP_DP_SECP384R1;
196                     break;
197                 case 521:
198                     grp_id = MBEDTLS_ECP_DP_SECP521R1;
199                     break;
200                 default:
201                     return( PSA_ERROR_NOT_SUPPORTED );
202             }
203             break;
204         default:
205             return( PSA_ERROR_NOT_SUPPORTED );
206     }
207 
208     /* Beyond this point, the driver is actually doing the work of
209      * calculating the signature. */
210 
211     status = PSA_ERROR_GENERIC_ERROR;
212     int ret = 0;
213     mbedtls_mpi r, s;
214     mbedtls_mpi_init( &r );
215     mbedtls_mpi_init( &s );
216     mbedtls_ecp_keypair ecp;
217     mbedtls_ecp_keypair_init( &ecp );
218     mbedtls_test_rnd_pseudo_info rnd_info;
219     memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
220     size_t curve_bytes = PSA_BITS_TO_BYTES( ecp.grp.pbits );
221 
222     MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ecp.grp, grp_id ) );
223 
224     /* Code adapted from psa_ecdsa_verify() in psa_crypto.c. */
225     if( signature_length < 2 * curve_bytes )
226     {
227         status = PSA_ERROR_BUFFER_TOO_SMALL;
228         goto cleanup;
229     }
230 
231     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
232                                               signature,
233                                               curve_bytes ) );
234     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
235                                               signature + curve_bytes,
236                                               curve_bytes ) );
237 
238     if( PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( attributes ) ) )
239         MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( &ecp.grp, &ecp.Q,
240                                                     key, key_length ) );
241     else
242     {
243         MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ecp.d, key, key_length ) );
244         MBEDTLS_MPI_CHK(
245             mbedtls_ecp_mul( &ecp.grp, &ecp.Q, &ecp.d, &ecp.grp.G,
246                              &mbedtls_test_rnd_pseudo_rand,
247                              &rnd_info ) );
248     }
249 
250     MBEDTLS_MPI_CHK( mbedtls_ecdsa_verify( &ecp.grp, hash, hash_length,
251                                 &ecp.Q, &r, &s ) );
252 cleanup:
253     status = mbedtls_to_psa_error( ret );
254     mbedtls_mpi_free( &r );
255     mbedtls_mpi_free( &s );
256     mbedtls_ecp_keypair_free( &ecp );
257 #else /* defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
258          defined(MBEDTLS_SHA256_C) */
259     (void) attributes;
260     (void) key;
261     (void) key_length;
262     (void) alg;
263     (void) hash;
264     (void) hash_length;
265     (void) signature;
266     (void) signature_length;
267 #endif /* defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
268           defined(MBEDTLS_SHA256_C) */
269 
270     return( status );
271 }
272 
test_opaque_signature_verify_hash(const psa_key_attributes_t * attributes,const uint8_t * key,size_t key_length,psa_algorithm_t alg,const uint8_t * hash,size_t hash_length,const uint8_t * signature,size_t signature_length)273 psa_status_t test_opaque_signature_verify_hash(
274     const psa_key_attributes_t *attributes,
275     const uint8_t *key, size_t key_length,
276     psa_algorithm_t alg,
277     const uint8_t *hash, size_t hash_length,
278     const uint8_t *signature, size_t signature_length )
279 {
280     (void) attributes;
281     (void) key;
282     (void) key_length;
283     (void) alg;
284     (void) hash;
285     (void) hash_length;
286     (void) signature;
287     (void) signature_length;
288     return( PSA_ERROR_NOT_SUPPORTED );
289 }
290 
291 #endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */
292