in AZ3166/tools/dice_device_enrollment/src/dice_device_enrollment/RIoT/Core/RiotCore.c [78:290]
int RiotStart(uint8_t *CDI, uint16_t CDILen, const char *RegistrationId, uint8_t* riotFw, uint32_t riotFwSize)
{
int status;
RIOT_ECC_PUBLIC deviceIDPub, aliasKeyPub;
RIOT_ECC_PRIVATE deviceIDPriv, aliasKeyPriv;
RIOT_ECC_SIGNATURE tbsSig;
DERBuilderContext derCtx;
uint8_t *base;
uint32_t length;
uint32_t dcType;
// Update subject common of alias certificate TBD data to input registration Id
x509AliasTBSData.SubjectCommon = RegistrationId;
// Validate Compound Device Identifier, pointer and length
if (!(CDI) || (CDILen != RIOT_DIGEST_LENGTH)) {
// Invalid state, remediate.
printf("Failure: Invalid CDI information from DICE.\r\n");
return RIOT_INVALID_PARAMETER;
}
// Don't use CDI directly
if ((status = RiotCrypt_Hash(cDigest, RIOT_DIGEST_LENGTH, CDI, CDILen)) != RIOT_SUCCESS){
printf("Failure: RiotCrypt_Hash returned invalid status %d\r\n.", status);
return status;
}
// Derive DeviceID key pair from CDI
if ((status = RiotCrypt_DeriveEccKey(&deviceIDPub, &deviceIDPriv, cDigest, RIOT_DIGEST_LENGTH,
(const uint8_t *)RIOT_LABEL_IDENTITY, lblSize(RIOT_LABEL_IDENTITY))) != RIOT_SUCCESS){
printf("Failure: RiotCrypt_DeriveEccKey returned invalid status %d.\r\n", status);
return status;
}
// Pickup start of FW image and calculate its length
// It must be the address of DPS code
base = (uint8_t*)riotFw;
length = riotFwSize;
#if logging
printf("Riot FW code:\r\n");
for (int i = 0; i < length; i++) {
if (i == (length - 1)) {
printf("%02x\r\n", base[i]);
}
else {
printf("%02x", base[i]);
}
}
#endif
// Measure FW, i.e., calculate FWID
if ((status = RiotCrypt_Hash(FWID, RIOT_DIGEST_LENGTH, base, length)) != RIOT_SUCCESS){
printf("Failure: RiotCrypt_Hash returned invalid status %d.\r\n", status);
return status;
}
FWID[RIOT_DIGEST_LENGTH] = 0;
// Combine CDI and FWID, result in cDigest
if ((status = RiotCrypt_Hash2(cDigest, RIOT_DIGEST_LENGTH, cDigest, RIOT_DIGEST_LENGTH,
FWID, RIOT_DIGEST_LENGTH)) != RIOT_SUCCESS){
printf("Failure: RiotCrypt_Hash2 returned invalid status %d.\r\n", status);
return status;
}
cDigest[RIOT_DIGEST_LENGTH] = 0;
// Derive Alias key pair from CDI and FWID
if ((status = RiotCrypt_DeriveEccKey(&aliasKeyPub, &aliasKeyPriv, cDigest, RIOT_DIGEST_LENGTH,
(const uint8_t *)RIOT_LABEL_ALIAS,lblSize(RIOT_LABEL_ALIAS))) != RIOT_SUCCESS){
printf("Failure: RiotCrypt_DeriveEccKey returned invalid status %d.\r\n", status);
return status;
}
// Clean up potentially sensitive data
memset(cDigest, 0x00, RIOT_DIGEST_LENGTH);
// Build the TBS (to be signed) region of Alias Key Certificate
DERInitContext(&derCtx, derBuffer, DER_MAX_TBS);
if ((status = X509GetAliasCertTBS(&derCtx, &x509AliasTBSData, &aliasKeyPub, &deviceIDPub,
FWID, RIOT_DIGEST_LENGTH)) != 0){
printf("Failure: X509GetAliasCertTBS returned invalid status %d.\r\n", status);
return status;
}
// Sign the Alias Key Certificate's TBS region
if ((status = RiotCrypt_Sign(&tbsSig, derCtx.Buffer, derCtx.Position, &deviceIDPriv)) != RIOT_SUCCESS){
printf("Failure: RiotCrypt_Sign returned invalid status %d.\r\n", status);
return status;
}
// Generate Alias Key Certificate
if ((status = X509MakeAliasCert(&derCtx, &tbsSig)) != 0){
printf("Failure: X509MakeAliasCert returned invalid status %d.\r\n", status);
return status;
}
// Copy Alias Key Certificate
length = sizeof(g_AKCert);
if ((status = DERtoPEM(&derCtx, CERT_TYPE, g_AKCert, &length)) != 0){
printf("Failure: DERtoPEM returned invalid status %d.\r\n", status);
return status;
}
g_AKCert[length] = '\0';
g_AKCertLen = length;
// Clean up potentially sensitive data
memset(FWID, 0, sizeof(FWID));
// Copy DeviceID Public
DERInitContext(&derCtx, derBuffer, DER_MAX_TBS);
if ((status = X509GetDEREccPub(&derCtx, deviceIDPub)) != 0){
printf("Failure: X509GetDEREccPub returned invalid status %d.\r\n", status);
return status;
}
length = sizeof(g_DeviceIDPub);
if ((status = DERtoPEM(&derCtx, PUBLICKEY_TYPE, g_DeviceIDPub, &length)) != 0){
printf("Failure: DERtoPEM returned invalid status %d.\r\n", status);
return status;
}
g_DeviceIDPub[length] = '\0';
g_DeviceIDPubLen = length;
// Copy Alias Key Pair
DERInitContext(&derCtx, derBuffer, DER_MAX_TBS);
if ((status = X509GetDEREcc(&derCtx, aliasKeyPub, aliasKeyPriv)) != 0){
printf("Failure: X509GetDEREcc returned invalid status %d.\r\n", status);
return status;
}
length = sizeof(g_AliasKey);
if ((status = DERtoPEM(&derCtx, ECC_PRIVATEKEY_TYPE, g_AliasKey, &length)) != 0){
printf("Failure: DERtoPEM returned invalid status %d.\r\n", status);
return status;
}
g_AliasKey[length] = '\0';
g_AliasKeyLen = length;
// We don't do CSRs on this device, this should be true.
if(SelfSignedDeviceCert) {
// Build the TBS (to be signed) region of DeviceID Certificate
DERInitContext(&derCtx, derBuffer, DER_MAX_TBS);
if ((status = X509GetDeviceCertTBS(&derCtx, &x509DeviceTBSData, &deviceIDPub)) != 0){
printf("Failure: X509GetDeviceCertTBS returned invalid status %d.\r\n", status);
return status;
}
// Sign the DeviceID Certificate's TBS region
if ((status = RiotCrypt_Sign(&tbsSig, derCtx.Buffer, derCtx.Position, &deviceIDPriv)) != RIOT_SUCCESS){
printf("Failure: RiotCrypt_Sign returned invalid status %d.\r\n", status);
return status;
}
// Generate DeviceID Certificate
if ((status = X509MakeDeviceCert(&derCtx, &tbsSig)) != 0){
printf("Failure: X509MakeDeviceCert returned invalid status %d.\r\n", status);
return status;
}
// DeviceID Cert type
dcType = CERT_TYPE;
}
else {
// Initialize, create CSR TBS region
DERInitContext(&derCtx, derBuffer, DER_MAX_TBS);
if ((status = X509GetDERCsrTbs(&derCtx, &x509AliasTBSData, &deviceIDPub)) != 0){
printf("Failure: X509GetDERCsrTbs returned invalid status %d.\r\n", status);
return status;
}
// Sign the Alias Key Certificate's TBS region
if ((status = RiotCrypt_Sign(&tbsSig, derCtx.Buffer, derCtx.Position, &deviceIDPriv)) != RIOT_SUCCESS){
printf("Failure: RiotCrypt_Sign returned invalid status %d.\r\n", status);
return status;
}
// Create CSR for DeviceID
if ((status = X509GetDERCsr(&derCtx, &tbsSig)) != 0){
printf("Failure: X509GetDERCsr returned invalid status %d.\r\n", status);
return status;
}
// DeviceID CSR type
dcType = CERT_REQ_TYPE;
}
// Copy CSR/self-signed Cert
length = sizeof(g_DICert);
if ((status = DERtoPEM(&derCtx, dcType, g_DICert, &length)) != 0){
printf("Failure: DERtoPEM returned invalid status %d.\r\n", status);
return status;
}
g_DICert[length] = '\0';
g_DICertLen = length;
// Clean up sensitive data
memset(&deviceIDPriv, 0, sizeof(RIOT_ECC_PRIVATE));
// Display info for Alias Key Certificate
#if logging
char *buf;
buf = RIoTGetAliasCert(NULL);
(void)printf("Alias Key Certificate\r\n%s\r\n", buf);
buf = RIoTGetDeviceID(NULL);
(void)printf("\r\nDeviceID Public\r\n%s\r\n", buf);
buf = RIoTGetAliasKey(NULL);
(void)printf("Alias Key Pair\r\n%s\r\n", buf);
buf = RIoTGetDeviceCert(NULL);
(void)printf("Device Certificate\r\n%s\r\n", buf);
#endif
// Must not return. If we do, DICE will trigger reset.
return 0;
}