Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AES encrypt/decrypt and HMAC support for SE05X #242

Merged
merged 2 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
SE05X AES Encrypt and Decrypt

This sketch uses the SE05X to encrypt and decrypt given data
with an AES key, which was uploaded in the SE05XWriteAESKey
example. This sketch encrypts 32 bytes with AES ECB Mode
and then decrypt this data for comparing the results.

Circuit:
- Portenta C33
*/

#include <SE05X.h>


const int AES_KEY_ID = 666;
const byte data[32] = {
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
};


void print_hex(const byte in[], size_t len) {
for (size_t i = 0; i < len; i++) {
Serial.print(in[i] >> 4, HEX);
Serial.print(in[i] & 0x0f, HEX);
}
Serial.println();
}

void setup() {
Serial.begin(9600);
while (!Serial);


if (!SE05X.begin()) {
Serial.println("Error with secure element");
while(1);
}


size_t encrypted_data_len = 32;
size_t decrypted_data_len = 32;
byte encrypted_data[32];
byte decrypted_data[32];

int status1 = SE05X.AES_ECB_encrypt(AES_KEY_ID, data, sizeof(data), encrypted_data, &encrypted_data_len);
int status2 = SE05X.AES_ECB_decrypt(AES_KEY_ID, encrypted_data, sizeof(data), decrypted_data, &decrypted_data_len);
print_hex(data,32);
print_hex(encrypted_data,32);
print_hex(decrypted_data,32);
}

void loop() {

}
33 changes: 33 additions & 0 deletions libraries/SE05X/examples/SE05XAESWriteKey/SE05XAESWriteKey.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
SE05X WriteAESKey

This sketch uses the SE05X to securely store an AES key. When the key is uploaded to
SE05X, the sketch on the Arduino should be overwritten.

Circuit:
- Portenta C33
*/

#include <SE05X.h>

const int AES_KEY_ID = 666;
const byte aes_key[32] = {
0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0x33, 0x33, 0xFF, 0x33,
0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0x33, 0x33, 0xFF, 0x44
};

void setup() {
Serial.begin(9600);

if (!SE05X.begin()) {
Serial.println("Error with secure element");
while(1);
}

SE05X.deleteBinaryObject(AES_KEY_ID);
SE05X.writeAESKey(AES_KEY_ID, aes_key, sizeof(aes_key));
}

void loop() {

}
54 changes: 54 additions & 0 deletions libraries/SE05X/examples/SE05XHMAC/SE05XHMAC.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
SE05X HMAC

This sketch uses the SE05X to securely store and use an HMAC Key
and calculates the HMAC-SHA512 sum of a given message

Circuit:
- Portenta C33
*/

#include <SE05X.h>

const int HMAC_KEY_ID = 667;
const byte hmac_key[32] = {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};


void print_hex(const byte in[], size_t len) {
for (size_t i = 0; i < len; i++) {
Serial.print(in[i] >> 4, HEX);
Serial.print(in[i] & 0x0f, HEX);
}
Serial.println();
}

void setup() {
Serial.begin(9600);
while (!Serial);

if (!SE05X.begin()) {
Serial.println("Error with secure element");
while(1);
}

SE05X.deleteBinaryObject(HMAC_KEY_ID); //remove key if already exists

SE05X.writeHMACKey(HMAC_KEY_ID, hmac_key, sizeof(hmac_key));
String message = "This is a test for the Arduino Portenta C33 to test HMAC with SHA512 algorithm. This are some bytes of data, which should work";


byte buffer[64];
for(int i = 0; i < 64; i++)
buffer[i] = 0;

size_t len = 64; // 64 byte = 512 bit, length for SHA512
SE05X.HMAC_Generate(HMAC_KEY_ID, kSE05x_MACAlgo_HMAC_SHA512, (const byte*)message.c_str(), message.length(), buffer, &len);
print_hex(buffer,len);
}

void loop() {

}
93 changes: 92 additions & 1 deletion libraries/SE05X/src/SE05X.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,97 @@ int SE05XClass::readSlot(int slot, byte data[], int length)
return readBinaryObject(slot, data, length, &size);
}

int SE05XClass::AES_ECB_encrypt(int objectId, const byte data[], size_t data_length, byte output[], size_t *output_len)
{
smStatus_t status;
status = Se05x_API_CipherOneShot(&_se05x_session, objectId, kSE05x_CipherMode_AES_ECB_NOPAD, data, data_length, 0, 0, output, output_len, kSE05x_Cipher_Oper_OneShot_Encrypt);
if (status != SM_OK) {
SMLOG_E("Error in Se05x_API_CipherOneShot \n");
return 0;
}
return 1;
}

int SE05XClass::AES_ECB_decrypt(int objectId, const byte data[], size_t data_length, byte output[], size_t *output_len)
{
smStatus_t status;
status = Se05x_API_CipherOneShot(&_se05x_session, objectId, kSE05x_CipherMode_AES_ECB_NOPAD, data, data_length, 0, 0, output, output_len, kSE05x_Cipher_Oper_OneShot_Decrypt);
if (status != SM_OK) {
SMLOG_E("Error in Se05x_API_CipherOneShot \n");
return 0;
}
return 1;
}

int SE05XClass::writeAESKey(int objectId, const byte data[], size_t length)
{
smStatus_t status;
SE05x_Result_t result;
uint16_t offset = 0;
uint16_t size;

status = Se05x_API_CheckObjectExists(&_se05x_session, objectId, &result);
if (status != SM_OK) {
SMLOG_E("Error in Se05x_API_CheckObjectExists \n");
return 0;
}

if (result == kSE05x_Result_SUCCESS) {
SMLOG_E("Object exists \n");
return 0;
}

uint16_t left = length;

status = Se05x_API_WriteSymmKey(&_se05x_session, NULL, 3, objectId, NULL, data, length, kSE05x_INS_NA, kSE05x_SymmKeyType_AES);

if (status != SM_OK) {
SMLOG_E("Error in Se05x_API_WriteSymmKey \n");
return 0;
}
return 1;
}

int SE05XClass::writeHMACKey(int objectId, const byte data[], size_t length)
{
smStatus_t status;
SE05x_Result_t result;
uint8_t exists = 0;
uint16_t offset = 0;
uint16_t size;

status = Se05x_API_CheckObjectExists(&_se05x_session, objectId, &result);
if (status != SM_OK) {
SMLOG_E("Error in Se05x_API_CheckObjectExists \n");
return 0;
}

if (result == kSE05x_Result_SUCCESS) {
SMLOG_E("Object exists \n");
exists = 1;
}

status = Se05x_API_WriteSymmKey(&_se05x_session, NULL, 0, objectId, SE05x_KeyID_KEK_NONE, data, length, kSE05x_INS_NA, kSE05x_SymmKeyType_HMAC);

if (status != SM_OK) {
SMLOG_E("Error in Se05x_API_WriteSymmKey \n");
return 0;
}
return 1;
}

int SE05XClass::HMAC_Generate(int objectId, uint8_t mac_operation, const byte data[], size_t data_length, byte output[], size_t *output_len)
{
smStatus_t status;
status = Se05x_API_MACOneShot_G(&_se05x_session, objectId, mac_operation, data, data_length, output, output_len);

if (status != SM_OK) {
SMLOG_E("Error in Se05x_API_CipherOneShot \n");
return status;
}
return 1;
}

int SE05XClass::writeBinaryObject(int objectId, const byte data[], size_t length)
{
smStatus_t status;
Expand Down Expand Up @@ -668,7 +759,7 @@ int SE05XClass::deleteBinaryObject(int objectId)

status = Se05x_API_DeleteSecureObject(&_se05x_session, objectId);
if (status != SM_OK) {
SMLOG_E("Error in Se05x_API_CheckObjectExists \n");
SMLOG_E("Error in Se05x_API_DeleteSecureObject \n");
return 0;
}

Expand Down
68 changes: 68 additions & 0 deletions libraries/SE05X/src/SE05X.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,74 @@ class SE05XClass
*/
int readBinaryObject(int ObjectId, byte data[], size_t dataMaxLen, size_t* length);

/** AES_ECB_encrypt
*
* Enrypts something with AES ECB
*
* @param[in] ObjectId SE050 object ID
* @param[in] data Input data buffer
* @param[in] length Input data buffer size (should be a multiple of 16 bytes)
* @param[out] output Output data buffer
* @param[out] output_length Output data buffer size (same as input)
*
* @return 0 on Failure 1 on Success
*/
int AES_ECB_encrypt(int objectId, const byte data[], size_t data_length, byte output[], size_t *output_len);

/** AES_ECB_decrypt
*
* Enrypts something with AES ECB
*
* @param[in] ObjectId SE050 object ID
* @param[in] data Input data buffer
* @param[in] length Input data buffer size (should be a multiple of 16 bytes)
* @param[out] output Output data buffer
* @param[out] output_length Output data buffer size (same as input)
*
* @return 0 on Failure 1 on Success
*/
int AES_ECB_decrypt(int objectId, const byte data[], size_t data_length, byte output[], size_t *output_len);

/** writeAESKey
*
* Writes symmetric key into SE050 object.
*
* @param[in] ObjectId SE050 object ID
* @param[in] data Input data buffer
* @param[in] length Input data buffer size
*
* @return 0 on Failure 1 on Success
*/
int writeAESKey(int ObjectId, const byte data[], size_t length);

/** writeHMACKey
*
* Writes symmetric key into SE050 object.
*
* @param[in] ObjectId SE050 object ID for the hmac key
* @param[in] data Input data buffer
* @param[in] length Input data buffer size
*
* @return 0 on Failure 1 on Success
*/
int writeHMACKey(int ObjectId, const byte data[], size_t length);

/** HMAC_Generate
*
* Computes the HMAC digest with SE050 chip
*
* @param[in] objectId SE050 object ID for the hmac key
* @param[in] mac_operation Type of Hash function for HMAC
* @param[in] data Input data buffer
* @param[in] length Input data buffer size
* @param[out] output Output data buffer
* @param[out] output_length Output data buffer size (should be 32 bytes for SHA256)
*
* @return 0 on Failure 1 on Success
*/
int HMAC_Generate(int objectId, uint8_t mac_operation, const byte data[], size_t data_length, byte output[], size_t *output_len);


/** writeBinaryObject
*
* Writes binary data into SE050 object.
Expand Down
Loading
Loading