Skip to content

Commit bae7de4

Browse files
authored
Merge pull request #5 from AndrzejKurek/key-generation
Add private key generation
2 parents b43091e + 1d61177 commit bae7de4

File tree

1 file changed

+79
-9
lines changed

1 file changed

+79
-9
lines changed

atecc608a_se.c

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,21 @@ psa_status_t atecc608a_to_psa_error(ATCA_STATUS ret)
122122
}
123123
}
124124

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+
125140
static psa_status_t is_public_key_slot(uint16_t key_slot)
126141
{
127142
/* 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,
142157
uint8_t *p_data, size_t data_size,
143158
size_t *p_data_length)
144159
{
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);
146164
const uint16_t slot = key;
147165
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
148166

@@ -153,11 +171,9 @@ static psa_status_t atecc608a_export_public_key(psa_key_slot_number_t key,
153171

154172
ASSERT_SUCCESS_PSA(atecc608a_init());
155173

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);
159176

160-
p_data[0] = 4;
161177
*p_data_length = key_data_len;
162178

163179
#ifdef DEBUG_PRINT
@@ -203,9 +219,63 @@ static psa_status_t atecc608a_import_public_key(psa_key_slot_number_t key_slot,
203219

204220
ASSERT_SUCCESS_PSA(atecc608a_init());
205221

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+
209279
exit:
210280
atecc608a_deinit();
211281
return status;
@@ -311,7 +381,7 @@ static psa_drv_se_key_management_t atecc608a_key_management =
311381
{
312382
/* So far there is no public key import function in the API, so use this instead */
313383
.p_import = atecc608a_import_public_key,
314-
.p_generate = 0,
384+
.p_generate = atecc608a_generate_key,
315385
.p_destroy = 0,
316386
/* So far there is no public key export function in the API, so use this instead */
317387
.p_export = atecc608a_export_public_key,

0 commit comments

Comments
 (0)