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