@@ -122,6 +122,21 @@ psa_status_t atecc608a_to_psa_error(ATCA_STATUS ret)
122
122
}
123
123
}
124
124
125
+ /* The driver works with pubkeys as concatenated x and y values, and the PSA
126
+ * format for pubkeys is 0x04 + x + y. Always use a pubkey buffer in PSA
127
+ * format, with enough space for the PSA format. To translate this buffer for
128
+ * use with cryptoauthlib, use pubkey_for_driver(). To ensure the buffer is in
129
+ * valid PSA format after cryptoauthlib operations, call pubkey_for_psa(). */
130
+ static uint8_t * pubkey_for_driver (uint8_t * data )
131
+ {
132
+ return & data [1 ];
133
+ }
134
+
135
+ static void pubkey_for_psa (uint8_t * data )
136
+ {
137
+ data [0 ] = 0x4 ;
138
+ }
139
+
125
140
static psa_status_t is_public_key_slot (uint16_t key_slot )
126
141
{
127
142
/* Keys 8 to 15 can store public keys. Slots 1-7 are too small. */
@@ -142,7 +157,10 @@ static psa_status_t atecc608a_export_public_key(psa_key_slot_number_t key,
142
157
uint8_t * p_data , size_t data_size ,
143
158
size_t * p_data_length )
144
159
{
145
- const size_t key_data_len = 65 ;
160
+ const size_t key_data_len = PSA_KEY_EXPORT_MAX_SIZE (
161
+ PSA_KEY_TYPE_ECC_PUBLIC_KEY (
162
+ PSA_ECC_CURVE_SECP256R1 ),
163
+ 256 );
146
164
const uint16_t slot = key ;
147
165
psa_status_t status = PSA_ERROR_GENERIC_ERROR ;
148
166
@@ -153,11 +171,9 @@ static psa_status_t atecc608a_export_public_key(psa_key_slot_number_t key,
153
171
154
172
ASSERT_SUCCESS_PSA (atecc608a_init ());
155
173
156
- /* atcab_get_pubkey returns concatenated x and y values, and the desired
157
- * format is 0x04 + x + y. Start at &p_data[1] and add a 0x04 at p_data[0]. */
158
- ASSERT_SUCCESS (atcab_get_pubkey (slot , & p_data [1 ]));
174
+ ASSERT_SUCCESS (atcab_get_pubkey (slot , pubkey_for_driver (p_data )));
175
+ pubkey_for_psa (p_data );
159
176
160
- p_data [0 ] = 4 ;
161
177
* p_data_length = key_data_len ;
162
178
163
179
#ifdef DEBUG_PRINT
@@ -203,9 +219,63 @@ static psa_status_t atecc608a_import_public_key(psa_key_slot_number_t key_slot,
203
219
204
220
ASSERT_SUCCESS_PSA (atecc608a_init ());
205
221
206
- /* PSA public key format is {0x04, X, Y}, and the cryptoauthlib accepts
207
- * raw {X,Y}. */
208
- ASSERT_SUCCESS (atcab_write_pubkey (key_id , p_data + 1 ));
222
+ ASSERT_SUCCESS (atcab_write_pubkey (key_id , pubkey_for_driver (p_data )));
223
+ exit :
224
+ atecc608a_deinit ();
225
+ return status ;
226
+ }
227
+
228
+ static psa_status_t atecc608a_generate_key (psa_key_slot_number_t key_slot ,
229
+ psa_key_type_t type ,
230
+ psa_key_usage_t usage ,
231
+ size_t bits ,
232
+ const void * extra ,
233
+ size_t extra_size ,
234
+ uint8_t * p_pubkey_out ,
235
+ size_t pubkey_out_size ,
236
+ size_t * p_pubkey_length )
237
+ {
238
+ const uint16_t key_id = key_slot ;
239
+ psa_status_t status = PSA_ERROR_GENERIC_ERROR ;
240
+
241
+ /* The hardware has slots 0-15 */
242
+ if (key_slot > 15 )
243
+ {
244
+ return PSA_ERROR_INVALID_ARGUMENT ;
245
+ }
246
+
247
+ if (type != PSA_KEY_TYPE_ECC_KEYPAIR (PSA_ECC_CURVE_SECP256R1 ))
248
+ {
249
+ return PSA_ERROR_NOT_SUPPORTED ;
250
+ }
251
+
252
+ if (bits != PSA_BYTES_TO_BITS (ATCA_PRIV_KEY_SIZE ))
253
+ {
254
+ return PSA_ERROR_NOT_SUPPORTED ;
255
+ }
256
+
257
+ if (p_pubkey_out != NULL && pubkey_out_size < 1 + ATCA_PUB_KEY_SIZE )
258
+ {
259
+ return PSA_ERROR_BUFFER_TOO_SMALL ;
260
+ }
261
+
262
+ ASSERT_SUCCESS_PSA (atecc608a_init ());
263
+
264
+ if (p_pubkey_out != NULL )
265
+ {
266
+ ASSERT_SUCCESS (atcab_genkey (key_id , pubkey_for_driver (p_pubkey_out )));
267
+ pubkey_for_psa (p_pubkey_out );
268
+ }
269
+ else
270
+ {
271
+ ASSERT_SUCCESS (atcab_genkey (key_id , NULL ));
272
+ }
273
+
274
+ if (p_pubkey_length != NULL )
275
+ {
276
+ * p_pubkey_length = 1 + ATCA_PUB_KEY_SIZE ;
277
+ }
278
+
209
279
exit :
210
280
atecc608a_deinit ();
211
281
return status ;
@@ -311,7 +381,7 @@ static psa_drv_se_key_management_t atecc608a_key_management =
311
381
{
312
382
/* So far there is no public key import function in the API, so use this instead */
313
383
.p_import = atecc608a_import_public_key ,
314
- .p_generate = 0 ,
384
+ .p_generate = atecc608a_generate_key ,
315
385
.p_destroy = 0 ,
316
386
/* So far there is no public key export function in the API, so use this instead */
317
387
.p_export = atecc608a_export_public_key ,
0 commit comments