Skip to content

Commit dccd80c

Browse files
committed
Improvements to key handling & additional key operations
* Generate and accept "private" key files allowing more natural cert/key implementations * Add OpenSC like cert retrieval * Add engine command to generate key files * Add engine command to load symmetric "transport" key * Add ECDH support * Some changes to support future OpenSSL 1.1 compatibility.
1 parent dfe4a30 commit dccd80c

12 files changed

+1079
-460
lines changed

cryptoauthlib/lib/hal/hal_linux_i2c_userspace.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
#include "atca_hal.h"
4040
#include "hal_linux_i2c_userspace.h"
4141

42-
#include <linux/i2c-dev.h>
4342
#include <unistd.h>
4443
#include <sys/ioctl.h>
4544
#include <sys/types.h>
@@ -175,7 +174,7 @@ ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t *txdata, int txlength)
175174
return ATCA_COMM_FAIL;
176175

177176
// Set Slave Address
178-
if (ioctl(f_i2c, I2C_SLAVE, cfg->atcai2c.slave_address >> 1) < 0)
177+
if (ioctl(f_i2c, 0x0703, cfg->atcai2c.slave_address >> 1) < 0)
179178
{
180179
close(f_i2c);
181180
return ATCA_COMM_FAIL;
@@ -210,7 +209,7 @@ ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength
210209
return ATCA_COMM_FAIL;
211210

212211
// Set Slave Address
213-
if (ioctl(f_i2c, I2C_SLAVE, cfg->atcai2c.slave_address >> 1) < 0)
212+
if (ioctl(f_i2c, 0x0703, cfg->atcai2c.slave_address >> 1) < 0)
214213
{
215214
close(f_i2c);
216215
return ATCA_COMM_FAIL;
@@ -256,7 +255,7 @@ ATCA_STATUS hal_i2c_wake(ATCAIface iface)
256255
// Send the wake by writing to an address of 0x00
257256
// Create wake up pulse by sending a slave address 0f 0x00.
258257
// This slave address is sent to device by using a dummy write command.
259-
if (ioctl(f_i2c, I2C_SLAVE, 0x00) < 0)
258+
if (ioctl(f_i2c, 0x0703, 0x00) < 0)
260259
{
261260
close(f_i2c);
262261
return ATCA_COMM_FAIL;
@@ -272,7 +271,7 @@ ATCA_STATUS hal_i2c_wake(ATCAIface iface)
272271
atca_delay_us(cfg->wake_delay); // wait tWHI + tWLO which is configured based on device type and configuration structure
273272

274273
// Set Slave Address
275-
if (ioctl(f_i2c, I2C_SLAVE, cfg->atcai2c.slave_address >> 1) < 0)
274+
if (ioctl(f_i2c, 0x0703, cfg->atcai2c.slave_address >> 1) < 0)
276275
{
277276
close(f_i2c);
278277
return ATCA_COMM_FAIL;
@@ -309,7 +308,7 @@ ATCA_STATUS hal_i2c_idle(ATCAIface iface)
309308
return ATCA_COMM_FAIL;
310309

311310
// Set Slave Address
312-
if (ioctl(f_i2c, I2C_SLAVE, cfg->atcai2c.slave_address >> 1) < 0)
311+
if (ioctl(f_i2c, 0x0703, cfg->atcai2c.slave_address >> 1) < 0)
313312
{
314313
close(f_i2c);
315314
return ATCA_COMM_FAIL;
@@ -342,7 +341,7 @@ ATCA_STATUS hal_i2c_sleep(ATCAIface iface)
342341
return ATCA_COMM_FAIL;
343342

344343
// Set Slave Address
345-
if (ioctl(f_i2c, I2C_SLAVE, cfg->atcai2c.slave_address >> 1) < 0)
344+
if (ioctl(f_i2c, 0x0703, cfg->atcai2c.slave_address >> 1) < 0)
346345
{
347346
close(f_i2c);
348347
return ATCA_COMM_FAIL;

cryptoauthlib/lib/hal/hal_win_kit_cdc.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
* POSSIBILITY OF SUCH DAMAGE.
3737
*/
3838

39+
#ifdef ATCA_HAL_KIT_CDC
40+
3941
//#include "atca_basic.h"
4042
#include "atca_hal.h"
4143
#include "kit_phy.h"
@@ -510,4 +512,6 @@ ATCA_STATUS hal_kit_cdc_discover_devices(int busNum, ATCAIfaceCfg *cfg, int *fou
510512
// TODO: Implement
511513
*found = 0;
512514
return ATCA_UNIMPLEMENTED;
513-
}
515+
}
516+
517+
#endif

cryptoauthlib/lib/hal/hal_win_kit_hid.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
* POSSIBILITY OF SUCH DAMAGE.
3737
*/
3838

39+
#ifdef ATCA_HAL_KIT_HID
40+
3941
#include "atca_hal.h"
4042
#include "hal_win_kit_hid.h"
4143
#include "kit_protocol.h"
@@ -434,4 +436,6 @@ ATCA_STATUS hal_kit_hid_release(void* hal_data)
434436
return ATCA_SUCCESS;
435437
}
436438

439+
#endif
440+
437441
/** @} */

cryptoauthlib/lib/hal/kit_protocol.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,23 @@
5050
*
5151
@{ */
5252

53+
static ATCA_STATUS kit_fix_send(ATCAIface iface, char *txdata, int txlength)
54+
{
55+
if (!iface || !txdata || !txlength)
56+
{
57+
return ATCA_BAD_PARAM;
58+
}
5359

60+
if (ATECC508A == atgetifacecfg(iface)->devtype)
61+
{
62+
if ('s' == txdata[0] && ':' == txdata[1])
63+
{
64+
txdata[0] = 'e';
65+
}
66+
}
67+
68+
return kit_phy_send(iface, txdata, txlength);
69+
}
5470

5571
/** \brief HAL implementation of kit protocol init. This function calls back to the physical protocol to send the bytes
5672
* \param[in] iface instance
@@ -101,7 +117,7 @@ ATCA_STATUS kit_init(ATCAIface iface)
101117
copysize = (sizeof(selectaddresspre) + rxsize);
102118
memcpy(&selectaddress[(copysize - 1)], selectaddresspost, sizeof(selectaddresspost));
103119
copysize = (sizeof(selectaddresspre) + rxsize + sizeof(selectaddresspost));
104-
status = kit_phy_send(iface, selectaddress, copysize);
120+
status = kit_fix_send(iface, selectaddress, copysize);
105121

106122
// Receive the reply to select address "00()\n"
107123
memset(reply, 0, replysize);
@@ -136,8 +152,9 @@ ATCA_STATUS kit_send(ATCAIface iface, const uint8_t* txdata, int txlength)
136152
free(pkitbuf);
137153
return ATCA_GEN_FAIL;
138154
}
155+
139156
// Send the bytes
140-
status = kit_phy_send(iface, pkitbuf, nkitbuf);
157+
status = kit_fix_send(iface, pkitbuf, nkitbuf);
141158

142159
#ifdef KIT_DEBUG
143160
// Print the bytes
@@ -214,7 +231,7 @@ ATCA_STATUS kit_wake(ATCAIface iface)
214231
int rxsize = sizeof(rxdata);
215232

216233
// Send the bytes
217-
status = kit_phy_send(iface, wake, wakesize);
234+
status = kit_fix_send(iface, wake, wakesize);
218235

219236
#ifdef KIT_DEBUG
220237
// Print the bytes
@@ -255,7 +272,7 @@ ATCA_STATUS kit_idle(ATCAIface iface)
255272
int rxsize = sizeof(rxdata);
256273

257274
// Send the bytes
258-
status = kit_phy_send(iface, idle, idlesize);
275+
status = kit_fix_send(iface, idle, idlesize);
259276

260277
#ifdef KIT_DEBUG
261278
// Print the bytes
@@ -297,7 +314,7 @@ ATCA_STATUS kit_sleep(ATCAIface iface)
297314
int rxsize = sizeof(rxdata);
298315

299316
// Send the bytes
300-
status = kit_phy_send(iface, sleep, sleepsize);
317+
status = kit_fix_send(iface, sleep, sleepsize);
301318

302319
#ifdef KIT_DEBUG
303320
// Print the bytes

cryptoauthlib/lib/openssl/eccx08_cmd_defns.c

Lines changed: 78 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -54,32 +54,31 @@
5454

5555
#include "atcacert/atcacert_client.h"
5656

57-
5857
/* OpenSSL Engine API demands this list be in cmd number order otherwise it'll
5958
throw an invalid cmd number error*/
6059
const ENGINE_CMD_DEFN eccx08_cmd_defns[] = {
6160
{ ECCX08_CMD_GET_VERSION, "VERSION",
6261
"Get engine version", ENGINE_CMD_FLAG_NO_INPUT },
62+
{ ECCX08_CMD_GET_KEY, "GET_DEVICE_KEY",
63+
"Get engine key structure for DEVICE_KEY_SLOT and stores in the provided file", ENGINE_CMD_FLAG_STRING },
64+
{ ECCX08_CMD_GET_DEVICE_CERT, "GET_DEVICE_CERT",
65+
"Get device certificate from hardware and stores in the provided filename", ENGINE_CMD_FLAG_STRING },
6366
{ ECCX08_CMD_GET_SIGNER_CERT, "GET_SIGNER_CERT",
64-
"Get signer certificate from hardware", ENGINE_CMD_FLAG_STRING },
65-
// { ECCX08_CMD_GET_PUB_KEY, "GET_DEVICE_PUBKEY",
66-
// "Get device public key from hardware", ENGINE_CMD_FLAG_STRING },
67-
{ ECCX08_CMD_GET_DEVICE_CERT, "GET_DEVICE_CERT",
68-
"Get device certificate from hardware", ENGINE_CMD_FLAG_STRING },
69-
{ ECCX08_CMD_GET_DEVICE_CSR, "GET_DEVICE_CSR",
70-
"Generate a device CSR and save it", ENGINE_CMD_FLAG_STRING },
67+
"Get signer certificate from hardware and stores in the provided filename", ENGINE_CMD_FLAG_STRING },
7168
{ ECCX08_CMD_LOAD_CERT_CTRL, "LOAD_CERT_CTRL",
7269
"Load the device certificate into an OpenSSL cert", ENGINE_CMD_FLAG_INTERNAL },
73-
{ ECCX08_CMD_DEVICE_KEY_SLOT, "device_key_slot",
74-
"Where to find the device private key", ENGINE_CMD_FLAG_NUMERIC | ENGINE_CMD_FLAG_INTERNAL },
75-
{ ECCX08_CMD_ECDH_SLOT, "ecdh_key_slot",
70+
{ ECCX08_CMD_KEY_SLOT, "SET_KEY_SLOT",
71+
"Where to find the device private key", ENGINE_CMD_FLAG_NUMERIC },
72+
{ ECCX08_CMD_TRANSPORT_KEY, "set_transport_key",
73+
"Binary blob with the transport key secret (32 bytes)", ENGINE_CMD_FLAG_STRING | ENGINE_CMD_FLAG_INTERNAL },
74+
{ ECCX08_CMD_ECDH_SLOT, "set_ecdh_slot",
7675
"Base slot for ecdh key(s)", ENGINE_CMD_FLAG_NUMERIC | ENGINE_CMD_FLAG_INTERNAL },
77-
{ ECCX08_CMD_ECDH_SLOTS, "ecdh_slot_count",
76+
{ ECCX08_CMD_ECDH_SLOTS, "set_ecdh_count",
7877
"Number of sequential slots to use for ecdh key(s) - e.g. ecdh_key_slot...ecdh_key_slot+ecdh_slot_count-1",
7978
ENGINE_CMD_FLAG_NUMERIC | ENGINE_CMD_FLAG_INTERNAL },
80-
{ ECCX08_CMD_DEVICE_CERT, "device_cert",
79+
{ ECCX08_CMD_DEVICE_CERT, "set_device_cert_def",
8180
"Device Cert Configuration Section", ENGINE_CMD_FLAG_STRING | ENGINE_CMD_FLAG_INTERNAL },
82-
{ ECCX08_CMD_SIGNER_CERT, "signer_cert",
81+
{ ECCX08_CMD_SIGNER_CERT, "set_signer_cert_def",
8382
"Signer Cert Configuration Section", ENGINE_CMD_FLAG_STRING | ENGINE_CMD_FLAG_INTERNAL },
8483

8584
/* Structure has to end with a null element */
@@ -186,7 +185,6 @@ static int get_cert(char *filename, atcacert_def_t * pCertDef, atcacert_def_t *
186185
return status;
187186
}
188187

189-
190188
/**
191189
*
192190
* \brief Retrieves pre-programmed certificates from ATECCX08
@@ -202,26 +200,48 @@ static int get_device_cert(char *filename)
202200
return get_cert(filename, g_cert_def_2_device_ptr, g_cert_def_1_signer_ptr);
203201
}
204202

205-
// /**
206-
// * \brief Retrieves the signer public key from ATECCX08 chip and
207-
// * saves them into a global signerPubkey buffer.
208-
// *
209-
// * \return ATCA_SUCCESS for success
210-
// */
211-
// static int get_public_key(void)
212-
// {
213-
// ATCA_STATUS status = ATCA_GEN_FAIL;
214-
215-
// DEBUG_ENGINE("eccx08_cmd_ctrl(ECCX08_CMD_GET_PUB_KEY)\n");
216-
// // Get the signer public key from the signer certificate
217-
// status = atcacert_get_subj_public_key(g_cert_def_1_signer_ptr, signerCert, signerCertSize, signerPubkey);
218-
// if (status != ATCA_SUCCESS) {
219-
// DEBUG_ENGINE("eccx08_cmd_ctrl(): error in atcacert_get_subj_public_key\n");
220-
// goto err;
221-
// }
222-
// err:
223-
// return status;
224-
// }
203+
/**
204+
* \brief Retrieves key from ATECCX08 chip and builds a key structure and
205+
* saves it as as a private key file in PEM format
206+
*
207+
* \return ATCA_SUCCESS for success
208+
*/
209+
static int get_key(ENGINE* e, uint16_t keyid, char * filename)
210+
{
211+
ATCA_STATUS status = ATCA_GEN_FAIL;
212+
char* key_str[32];
213+
EVP_PKEY* pkey;
214+
215+
DEBUG_ENGINE("Entered\n");
216+
217+
snprintf(key_str, 32, "ATECCx08:%02x:%02x:%02x:%02x", pCfg->iface_type,
218+
pCfg->atcai2c.bus, pCfg->atcai2c.slave_address, keyid);
219+
key_str[31] = '\0';
220+
221+
pkey = eccx08_load_pubkey(e, key_str, NULL, NULL);
222+
223+
if (pkey)
224+
{
225+
EC_KEY * ec = EVP_PKEY_get1_EC_KEY(pkey);
226+
if (ec)
227+
{
228+
BIO * bio = BIO_new(BIO_s_file());
229+
BIO_write_filename(bio, filename);
230+
if (bio)
231+
{
232+
if (PEM_write_bio_ECPrivateKey(bio, ec, NULL, NULL, 0, NULL, NULL))
233+
{
234+
status = ATCA_SUCCESS;
235+
}
236+
BIO_free(bio);
237+
}
238+
EC_KEY_free(ec);
239+
}
240+
EVP_PKEY_free(pkey);
241+
}
242+
243+
return status;
244+
}
225245

226246
/**
227247
* \brief Retrieves pre-programmed signer certificate from
@@ -253,8 +273,7 @@ static int load_device_cert(cmd_load_cert_params* p)
253273
}
254274
}
255275

256-
257-
static ATCA_STATUS set_device_key_slot(i)
276+
static ATCA_STATUS set_device_key_slot(uint32_t i)
258277
{
259278
if (16 > i)
260279
{
@@ -264,7 +283,7 @@ static ATCA_STATUS set_device_key_slot(i)
264283
return ATCA_BAD_PARAM;
265284
}
266285

267-
static ATCA_STATUS set_ecdh_slot(i)
286+
static ATCA_STATUS set_ecdh_slot(uint32_t i)
268287
{
269288
if (16 > i)
270289
{
@@ -274,7 +293,7 @@ static ATCA_STATUS set_ecdh_slot(i)
274293
return ATCA_BAD_PARAM;
275294
}
276295

277-
static ATCA_STATUS set_ecdh_count(i)
296+
static ATCA_STATUS set_ecdh_count(uint32_t i)
278297
{
279298
if (16 > i)
280299
{
@@ -284,6 +303,16 @@ static ATCA_STATUS set_ecdh_count(i)
284303
return ATCA_BAD_PARAM;
285304
}
286305

306+
static ATCA_STATUS set_transport_key(uint8_t * p)
307+
{
308+
if (p)
309+
{
310+
memcpy(g_eccx08_transport_key, p, sizeof(g_eccx08_transport_key));
311+
return ATCA_SUCCESS;
312+
}
313+
return ATCA_BAD_PARAM;
314+
}
315+
287316
/**
288317
* \brief Configure the device cert from the config file
289318
* \param[in] pStr should contain the section name
@@ -338,27 +367,23 @@ int eccx08_cmd_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
338367

339368
switch (cmd) {
340369
case ECCX08_CMD_GET_VERSION:
341-
// if (cmd_buf) {
342-
//snprintf(cmd_buf, i, "The ateccx08 ENGINE version: %s", ECCX08_ENGINE_VERSION);
343370
DEBUG_ENGINE("ENGINE Version: %s\n", ECCX08_ENGINE_VERSION);
344-
// } else {
345-
// ret = 0;
346-
// }
347371
status = ATCA_SUCCESS;
348372
break;
349-
case ECCX08_CMD_GET_SIGNER_CERT:
350-
status = get_signer_cert(p);
373+
374+
case ECCX08_CMD_GET_KEY:
375+
status = get_key(e, eccx08_engine_config.device_key_slot, p);
351376
break;
352-
// case ECCX08_CMD_GET_PUB_KEY:
353-
// status = get_public_key();
354-
// break;
355377
case ECCX08_CMD_GET_DEVICE_CERT:
356378
status = get_device_cert(p);
357379
break;
380+
case ECCX08_CMD_GET_SIGNER_CERT:
381+
status = get_signer_cert(p);
382+
break;
358383
case ECCX08_CMD_LOAD_CERT_CTRL:
359384
status = load_device_cert(p);
360385
break;
361-
case ECCX08_CMD_DEVICE_KEY_SLOT:
386+
case ECCX08_CMD_KEY_SLOT:
362387
status = set_device_key_slot(i);
363388
break;
364389
case ECCX08_CMD_ECDH_SLOT:
@@ -373,6 +398,9 @@ int eccx08_cmd_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
373398
case ECCX08_CMD_SIGNER_CERT:
374399
status = config_signer_cert(p);
375400
break;
401+
case ECCX08_CMD_TRANSPORT_KEY:
402+
status = set_transport_key(p);
403+
break;
376404
default:
377405
DEBUG_ENGINE("Unknown command: %d with i=%d, p=%s\n", cmd, i, p?p:"");
378406
break;

0 commit comments

Comments
 (0)