blob: 03ba14dd7fc33c661e0b8878bd68147ececb84b5 [file] [log] [blame]
Ronald Cron00b7bfc2020-11-25 15:25:26 +01001/*
2 * PSA ECP layer on top of Mbed TLS crypto
3 */
4/*
5 * Copyright The Mbed TLS Contributors
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21#include "common.h"
22
23#if defined(MBEDTLS_PSA_CRYPTO_C)
24
25#include <psa/crypto.h>
26#include "psa_crypto_core.h"
27#include "psa_crypto_ecp.h"
Ronald Crone5ca3d82020-11-26 16:36:16 +010028#include "psa_crypto_random_impl.h"
Ronald Cron00b7bfc2020-11-25 15:25:26 +010029
30#include <stdlib.h>
31#include <string.h>
32#include "mbedtls/platform.h"
33#if !defined(MBEDTLS_PLATFORM_C)
34#define mbedtls_calloc calloc
35#define mbedtls_free free
36#endif
37
38#include <mbedtls/ecp.h>
39#include <mbedtls/error.h>
40
Ronald Cronf1057d32020-11-26 19:19:10 +010041#if ( defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
42 ( defined(PSA_CRYPTO_DRIVER_TEST) && \
43 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) ) )
44#define BUILTIN_KEY_TYPE_ECC_KEY_PAIR 1
45#endif
46
47#if ( defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
48 ( defined(PSA_CRYPTO_DRIVER_TEST) && \
49 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) ) )
50#define BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1
51#endif
52
53#if defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
54 defined(BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
Ronald Cron00b7bfc2020-11-25 15:25:26 +010055 defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
56 defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) || \
57 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
58psa_status_t mbedtls_psa_ecp_load_representation(
59 psa_key_type_t type, const uint8_t *data, size_t data_length,
60 mbedtls_ecp_keypair **p_ecp )
61{
62 mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
63 psa_status_t status;
64 mbedtls_ecp_keypair *ecp = NULL;
65 size_t curve_size = data_length;
66
67 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) &&
68 PSA_KEY_TYPE_ECC_GET_FAMILY( type ) != PSA_ECC_FAMILY_MONTGOMERY )
69 {
70 /* A Weierstrass public key is represented as:
71 * - The byte 0x04;
72 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
73 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
74 * So its data length is 2m+1 where m is the curve size in bits.
75 */
76 if( ( data_length & 1 ) == 0 )
77 return( PSA_ERROR_INVALID_ARGUMENT );
78 curve_size = data_length / 2;
79
80 /* Montgomery public keys are represented in compressed format, meaning
81 * their curve_size is equal to the amount of input. */
82
83 /* Private keys are represented in uncompressed private random integer
84 * format, meaning their curve_size is equal to the amount of input. */
85 }
86
87 /* Allocate and initialize a key representation. */
88 ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
89 if( ecp == NULL )
90 return( PSA_ERROR_INSUFFICIENT_MEMORY );
91 mbedtls_ecp_keypair_init( ecp );
92
93 /* Load the group. */
94 grp_id = mbedtls_ecc_group_of_psa( PSA_KEY_TYPE_ECC_GET_FAMILY( type ),
95 curve_size );
96 if( grp_id == MBEDTLS_ECP_DP_NONE )
97 {
98 status = PSA_ERROR_INVALID_ARGUMENT;
99 goto exit;
100 }
101
102 status = mbedtls_to_psa_error(
103 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
104 if( status != PSA_SUCCESS )
105 goto exit;
106
107 /* Load the key material. */
108 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
109 {
110 /* Load the public value. */
111 status = mbedtls_to_psa_error(
112 mbedtls_ecp_point_read_binary( &ecp->grp, &ecp->Q,
113 data,
114 data_length ) );
115 if( status != PSA_SUCCESS )
116 goto exit;
117
118 /* Check that the point is on the curve. */
119 status = mbedtls_to_psa_error(
120 mbedtls_ecp_check_pubkey( &ecp->grp, &ecp->Q ) );
121 if( status != PSA_SUCCESS )
122 goto exit;
123 }
124 else
125 {
126 /* Load and validate the secret value. */
127 status = mbedtls_to_psa_error(
128 mbedtls_ecp_read_key( ecp->grp.id,
129 ecp,
130 data,
131 data_length ) );
132 if( status != PSA_SUCCESS )
133 goto exit;
134 }
135
136 *p_ecp = ecp;
137exit:
138 if( status != PSA_SUCCESS )
139 {
140 mbedtls_ecp_keypair_free( ecp );
141 mbedtls_free( ecp );
142 }
143
144 return( status );
145}
Ronald Cronf1057d32020-11-26 19:19:10 +0100146#endif /* defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
147 * defined(BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) ||
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100148 * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
149 * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) ||
150 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
151
Ronald Cronf1057d32020-11-26 19:19:10 +0100152#if defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
153 defined(BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Ronald Crond6ec3032020-11-27 18:54:57 +0100154
155psa_status_t mbedtls_psa_ecp_import_key(
156 const psa_key_attributes_t *attributes,
157 const uint8_t *data, size_t data_length,
158 uint8_t *key_buffer, size_t key_buffer_size,
159 size_t *key_buffer_length, size_t *bits )
160{
161 psa_status_t status;
162 mbedtls_ecp_keypair *ecp = NULL;
163
164 /* Parse input */
165 status = mbedtls_psa_ecp_load_representation( attributes->core.type,
166 data,
167 data_length,
168 &ecp );
169 if( status != PSA_SUCCESS )
170 goto exit;
171
172 if( PSA_KEY_TYPE_ECC_GET_FAMILY( attributes->core.type ) ==
173 PSA_ECC_FAMILY_MONTGOMERY )
174 *bits = ecp->grp.nbits + 1;
175 else
176 *bits = ecp->grp.nbits;
177
178 /* Re-export the data to PSA export format. There is currently no support
179 * for other input formats then the export format, so this is a 1-1
180 * copy operation. */
181 status = mbedtls_psa_ecp_export_key( attributes->core.type,
182 ecp,
183 key_buffer,
184 key_buffer_size,
185 key_buffer_length );
186exit:
187 /* Always free the PK object (will also free contained ECP context) */
188 mbedtls_ecp_keypair_free( ecp );
189 mbedtls_free( ecp );
190
191 return( status );
192}
193
Ronald Crone5ca3d82020-11-26 16:36:16 +0100194psa_status_t mbedtls_psa_ecp_export_key( psa_key_type_t type,
195 mbedtls_ecp_keypair *ecp,
196 uint8_t *data,
197 size_t data_size,
198 size_t *data_length )
199{
200 psa_status_t status;
201
202 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
203 {
204 /* Check whether the public part is loaded */
205 if( mbedtls_ecp_is_zero( &ecp->Q ) )
206 {
207 /* Calculate the public key */
208 status = mbedtls_to_psa_error(
209 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
210 mbedtls_psa_get_random,
211 MBEDTLS_PSA_RANDOM_STATE ) );
212 if( status != PSA_SUCCESS )
213 return( status );
214 }
215
216 status = mbedtls_to_psa_error(
217 mbedtls_ecp_point_write_binary( &ecp->grp, &ecp->Q,
218 MBEDTLS_ECP_PF_UNCOMPRESSED,
219 data_length,
220 data,
221 data_size ) );
222 if( status != PSA_SUCCESS )
223 memset( data, 0, data_size );
224
225 return( status );
226 }
227 else
228 {
229 if( data_size < PSA_BITS_TO_BYTES( ecp->grp.nbits ) )
230 return( PSA_ERROR_BUFFER_TOO_SMALL );
231
232 status = mbedtls_to_psa_error(
233 mbedtls_ecp_write_key( ecp,
234 data,
235 PSA_BITS_TO_BYTES( ecp->grp.nbits ) ) );
236 if( status == PSA_SUCCESS )
237 *data_length = PSA_BITS_TO_BYTES( ecp->grp.nbits );
238 else
239 memset( data, 0, data_size );
240
241 return( status );
242 }
243}
244
Ronald Cronf1057d32020-11-26 19:19:10 +0100245static psa_status_t ecp_export_public_key(
Ronald Crone5ca3d82020-11-26 16:36:16 +0100246 const psa_key_attributes_t *attributes,
247 const uint8_t *key_buffer, size_t key_buffer_size,
248 uint8_t *data, size_t data_size, size_t *data_length )
249{
250 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
251 mbedtls_ecp_keypair *ecp = NULL;
252
253 status = mbedtls_psa_ecp_load_representation(
254 attributes->core.type, key_buffer, key_buffer_size, &ecp );
255 if( status != PSA_SUCCESS )
256 return( status );
257
258 status = mbedtls_psa_ecp_export_key(
259 PSA_KEY_TYPE_ECC_PUBLIC_KEY(
260 PSA_KEY_TYPE_ECC_GET_FAMILY( attributes->core.type ) ),
261 ecp, data, data_size, data_length );
262
263 mbedtls_ecp_keypair_free( ecp );
264 mbedtls_free( ecp );
265
266 return( status );
267}
Ronald Cronf1057d32020-11-26 19:19:10 +0100268#endif /* defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
269 * defined(BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
270
271#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
272 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
273
274psa_status_t mbedtls_psa_ecp_export_public_key(
275 const psa_key_attributes_t *attributes,
276 const uint8_t *key_buffer, size_t key_buffer_size,
277 uint8_t *data, size_t data_size, size_t *data_length )
278{
279 return( ecp_export_public_key( attributes, key_buffer, key_buffer_size,
280 data, data_size, data_length ) );
281}
282
Ronald Crone5ca3d82020-11-26 16:36:16 +0100283#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
284 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
285
Ronald Cronf1057d32020-11-26 19:19:10 +0100286/*
287 * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
288 */
289
290#if defined(PSA_CRYPTO_DRIVER_TEST)
291
292#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \
293 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
294psa_status_t mbedtls_transparent_test_driver_ecp_export_public_key(
295 const psa_key_attributes_t *attributes,
296 const uint8_t *key_buffer, size_t key_buffer_size,
297 uint8_t *data, size_t data_size, size_t *data_length )
298{
299 return( ecp_export_public_key( attributes, key_buffer, key_buffer_size,
300 data, data_size, data_length ) );
301}
302#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) ||
303 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) */
304
305#endif /* PSA_CRYPTO_DRIVER_TEST */
306
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100307#endif /* MBEDTLS_PSA_CRYPTO_C */