.
Overview.
Initially I was about to build a hardware wallet for crypto tokens. But it would take more time that I have. Thus I did a simple version of hardware key vault which can be extended to build a hardware wallet if I have the time to re-visit this project.
.
Pre-requisites.
To implement this project, you need to prepare and setup your Azure Sphere kit. There are tons of materials available around the internet, so I will not go into details about how to setup the device. Here I will just list a few useful links for convenient reference:
Avnet's Azure Sphere Starter-Kit (Out of Box Demo) Part 1 of 3
Avnet's Azure Sphere Starter-Kit (Out of Box Demo) Part 2 of 3
Avnet's Azure Sphere Starter-Kit (Out of Box Demo) Part 3 of 3
To continue, please complete at least the part 2 of the above reference.
First Implementation.
I was looking for ways to send text/string to the Azure Sphere kit and some kind individual pointed out that I can make use of the device twins. I believe, which I am not sure, the direct messaging option can do the job too. However, I don't have time to explore. I will use the device twins to accomplish this.
If you have complete the part 2 above, you are pretty much have all the things ready. You just need to make the following changes to the device_twin.c
file:
char *keyVaultText;
...
...
twin_t twinArray[] = {
{.twinKey = "keyVaultText",.twinVar = &keyVaultText,.twinFd = NULL,.twinGPIO = NO_GPIO_ASSOCIATED_WITH_TWIN,.twinType = TYPE_STRING,.active_high = false},
...
}
...
...
case TYPE_STRING:
twinArray[i].twinVar = (char *)json_object_get_string(desiredProperties, twinArray[i].twinKey);
Log_Debug("Received device update. New %s is %s\n", twinArray[i].twinKey, (char*)twinArray[i].twinVar);
//Log_Debug("ERROR: TYPE_STRING case not implemented!");
checkAndUpdateDeviceTwin(twinArray[i].twinKey, twinArray[i].twinVar, TYPE_STRING, true);
break;
This implementation echos back whatever text/string that was passed thru device twins' reported properties
.
.
At the second implementation, AES encryption functions are added to the project. I was thinking to use the encryption functions provided by Azure Sphere library. But a user commented that "...have seen other end products that do this sort of key vault functionality, but most do not rely upon system software libraries for encryption since those are subject to automatic system upgrades which is unacceptable to some security teams"
. So I searched and found some tiny encryption code to use. Because I am not sure of the licensing right, I will not include the code here. But here are the reference to those code:
In my project, I have add the following files based on the code of the above references:
aes.h, base64.h
aes.c, base64.c
In additional, make further changes to device_twin.c
as follows:
case TYPE_STRING:
//test_encrypt_cbc();
twinArray[i].twinVar = (char *)json_object_get_string(desiredProperties, twinArray[i].twinKey);
Log_Debug("Received device update. New %s is %s\n", twinArray[i].twinKey, (char*)twinArray[i].twinVar);
//Log_Debug("ERROR: TYPE_STRING case not implemented!");
encrypt_cbc(twinArray[i].twinVar);
Log_Debug("cypher text: %s\n", base64_encode(twinArray[i].twinVar, 32, NULL));
twinArray[i].twinVar = base64_encode(twinArray[i].twinVar, 32, NULL);
//base64_encode_inplace(twinArray[i].twinVar, 32, NULL);
checkAndUpdateDeviceTwin(twinArray[i].twinKey, twinArray[i].twinVar, TYPE_STRING, true);
break;
.
Encryption test function
static int test_encrypt_cbc(void) {
uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
uint8_t out[] = { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 };
uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
uint8_t in[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 };
struct AES_ctx ctx;
AES_init_ctx_iv(&ctx, key, iv);
AES_CBC_encrypt_buffer(&ctx, in, 64);
printf("CBC encrypt: ");
if (0 == memcmp((char*)out, (char*)in, 64)) {
printf("SUCCESS!\n");
return(0);
}
else {
printf("FAILURE!\n");
return(1);
}
}
.
Encryption function
static void encrypt_cbc(uint8_t in[]) {
uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
struct AES_ctx ctx;
AES_init_ctx_iv(&ctx, key, iv);
AES_CBC_encrypt_buffer(&ctx, in, 64);
}
.
This tests the encryption function.
.
This shows the cypher text at Visual Studio IDE.
.
This shows cypher text in device twins at Azure portal.
.
Summary.
Of course, this is a simple implementation. More key vault functions can be added and building a hardware wallet using the Azure Sphere kit is the next step.
.
Comments