fixup! feat(core): Implement OPTIGA provisioning in prodtest.

Andrew Kozlik 11 months ago
parent fe5ca60637
commit 4a61ce9469

@ -132,31 +132,39 @@ static void vcp_write_as_hex(uint8_t *data, uint16_t len) {
}
#ifdef USE_OPTIGA
static uint16_t get_byte_from_hex(const char *hex) {
static uint16_t get_byte_from_hex(const char **hex) {
uint8_t result = 0;
// Skip whitespace.
while (**hex == ' ') {
*hex += 1;
}
for (int i = 0; i < 2; i++) {
result <<= 4;
if (hex[i] >= '0' && hex[i] <= '9') {
result |= hex[i] - '0';
} else if (hex[i] >= 'A' && hex[i] <= 'F') {
result |= hex[i] - 'A' + 10;
} else if (hex[i] >= 'a' && hex[i] <= 'f') {
result |= hex[i] - 'a' + 10;
} else if (hex[i] == '\0') {
char c = **hex;
if (c >= '0' && c <= '9') {
result |= c - '0';
} else if (c >= 'A' && c <= 'F') {
result |= c - 'A' + 10;
} else if (c >= 'a' && c <= 'f') {
result |= c - 'a' + 10;
} else if (c == '\0') {
return 0x100;
} else {
return 0xFFFF;
}
*hex += 1;
}
return result;
}
static int get_from_hex(uint8_t *buf, uint16_t buf_len, const char *hex) {
int len = 0;
uint16_t b = get_byte_from_hex(hex);
uint16_t b = get_byte_from_hex(&hex);
for (len = 0; len < buf_len && b <= 0xff; ++len) {
buf[len] = b;
b = get_byte_from_hex(hex + len * 2);
b = get_byte_from_hex(&hex);
}
if (b == 0x100) {
@ -650,6 +658,15 @@ bool set_metadata(uint16_t oid, const optiga_metadata *metadata) {
}
bool pair_optiga(void) {
// The pairing key may already be written and locked. The success of the
// pairing procedure is determined by optiga_sec_chan_handshake(). Therefore
// it is OK for some of the intermediate operations to fail.
// Enable writing the pairing secret to OPTIGA.
optiga_metadata metadata = {0};
metadata.change = OPTIGA_ACCESS_ALWAYS;
set_metadata(OID_KEY_PAIRING, &metadata); // Ignore result.
// Generate pairing secret.
uint8_t secret[SECRET_OPTIGA_KEY_LEN] = {0};
optiga_result ret = optiga_get_random(secret, sizeof(secret));
@ -692,7 +709,8 @@ void optiga_lock(void) {
}
// Delete trust anchor.
optiga_result ret = optiga_set_data_object(0xe0e8, false, NULL, 0);
optiga_result ret =
optiga_set_data_object(0xe0e8, false, (const uint8_t *)"\0", 1);
if (OPTIGA_SUCCESS != ret) {
vcp_printf("ERROR: optiga_set_data error %d for 0xe0e8.", ret);
return;
@ -757,6 +775,8 @@ void optiga_lock(void) {
if (!set_metadata(OID_KEY_PAIRING, &metadata)) {
return;
}
vcp_printf("OK");
}
void optigaid_read(void) {
@ -790,6 +810,11 @@ void cert_read(uint16_t oid) {
}
void cert_write(uint16_t oid, char *data) {
// Enable writing to the certificate slot.
optiga_metadata metadata = {0};
metadata.change = OPTIGA_ACCESS_ALWAYS;
set_metadata(oid, &metadata); // Ignore result.
uint8_t data_bytes[1024];
int len = get_from_hex(data_bytes, sizeof(data_bytes), data);
@ -814,6 +839,7 @@ void pubkey_read(uint16_t oid) {
uint8_t key_usage = OPTIGA_KEY_USAGE_KEYAGREE;
metadata.key_usage.ptr = &key_usage;
metadata.key_usage.len = 1;
metadata.execute = OPTIGA_ACCESS_ALWAYS;
if (!set_metadata(oid, &metadata)) {
return;
@ -853,6 +879,7 @@ void keyfido_write(char *data) {
uint8_t key_usage = OPTIGA_KEY_USAGE_KEYAGREE;
metadata.key_usage.ptr = &key_usage;
metadata.key_usage.len = 1;
metadata.execute = OPTIGA_ACCESS_ALWAYS;
if (!set_metadata(OID_KEY_DEV, &metadata)) {
return;
@ -883,7 +910,7 @@ void keyfido_write(char *data) {
bn_write_be(&pub.y, public_key + 4 + 32);
// Execute ECDH with device private key.
uint8_t secret[64] = {0};
uint8_t secret[32] = {0};
size_t secret_size = 0;
optiga_result ret = optiga_calc_ssec(OPTIGA_CURVE_P256, OID_KEY_DEV,
public_key, sizeof(public_key), secret,

Loading…
Cancel
Save