blob: 265d1ac4d54ec46b06845163263cea91b8ba873e [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 Crone5ca3d82020-11-26 16:36:16 +0100154psa_status_t mbedtls_psa_ecp_export_key( psa_key_type_t type,
155 mbedtls_ecp_keypair *ecp,
156 uint8_t *data,
157 size_t data_size,
158 size_t *data_length )
159{
160 psa_status_t status;
161
162 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
163 {
164 /* Check whether the public part is loaded */
165 if( mbedtls_ecp_is_zero( &ecp->Q ) )
166 {
167 /* Calculate the public key */
168 status = mbedtls_to_psa_error(
169 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
170 mbedtls_psa_get_random,
171 MBEDTLS_PSA_RANDOM_STATE ) );
172 if( status != PSA_SUCCESS )
173 return( status );
174 }
175
176 status = mbedtls_to_psa_error(
177 mbedtls_ecp_point_write_binary( &ecp->grp, &ecp->Q,
178 MBEDTLS_ECP_PF_UNCOMPRESSED,
179 data_length,
180 data,
181 data_size ) );
182 if( status != PSA_SUCCESS )
183 memset( data, 0, data_size );
184
185 return( status );
186 }
187 else
188 {
189 if( data_size < PSA_BITS_TO_BYTES( ecp->grp.nbits ) )
190 return( PSA_ERROR_BUFFER_TOO_SMALL );
191
192 status = mbedtls_to_psa_error(
193 mbedtls_ecp_write_key( ecp,
194 data,
195 PSA_BITS_TO_BYTES( ecp->grp.nbits ) ) );
196 if( status == PSA_SUCCESS )
197 *data_length = PSA_BITS_TO_BYTES( ecp->grp.nbits );
198 else
199 memset( data, 0, data_size );
200
201 return( status );
202 }
203}
204
Ronald Cronf1057d32020-11-26 19:19:10 +0100205static psa_status_t ecp_export_public_key(
Ronald Crone5ca3d82020-11-26 16:36:16 +0100206 const psa_key_attributes_t *attributes,
207 const uint8_t *key_buffer, size_t key_buffer_size,
208 uint8_t *data, size_t data_size, size_t *data_length )
209{
210 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
211 mbedtls_ecp_keypair *ecp = NULL;
212
213 status = mbedtls_psa_ecp_load_representation(
214 attributes->core.type, key_buffer, key_buffer_size, &ecp );
215 if( status != PSA_SUCCESS )
216 return( status );
217
218 status = mbedtls_psa_ecp_export_key(
219 PSA_KEY_TYPE_ECC_PUBLIC_KEY(
220 PSA_KEY_TYPE_ECC_GET_FAMILY( attributes->core.type ) ),
221 ecp, data, data_size, data_length );
222
223 mbedtls_ecp_keypair_free( ecp );
224 mbedtls_free( ecp );
225
226 return( status );
227}
Ronald Cronf1057d32020-11-26 19:19:10 +0100228#endif /* defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
229 * defined(BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
230
231#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
232 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
233
234psa_status_t mbedtls_psa_ecp_export_public_key(
235 const psa_key_attributes_t *attributes,
236 const uint8_t *key_buffer, size_t key_buffer_size,
237 uint8_t *data, size_t data_size, size_t *data_length )
238{
239 return( ecp_export_public_key( attributes, key_buffer, key_buffer_size,
240 data, data_size, data_length ) );
241}
242
Ronald Crone5ca3d82020-11-26 16:36:16 +0100243#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
244 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
245
Ronald Cronf1057d32020-11-26 19:19:10 +0100246/*
247 * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
248 */
249
250#if defined(PSA_CRYPTO_DRIVER_TEST)
251
252#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \
253 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
254psa_status_t mbedtls_transparent_test_driver_ecp_export_public_key(
255 const psa_key_attributes_t *attributes,
256 const uint8_t *key_buffer, size_t key_buffer_size,
257 uint8_t *data, size_t data_size, size_t *data_length )
258{
259 return( ecp_export_public_key( attributes, key_buffer, key_buffer_size,
260 data, data_size, data_length ) );
261}
262#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) ||
263 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) */
264
265#endif /* PSA_CRYPTO_DRIVER_TEST */
266
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100267#endif /* MBEDTLS_PSA_CRYPTO_C */