Skip to content

Commit 2726a01

Browse files
authored
Merge pull request #242 from pennam/se050_aes_hmac
Add AES encrypt/decrypt and HMAC support for SE05X
2 parents be29127 + 432b075 commit 2726a01

File tree

8 files changed

+439
-1
lines changed

8 files changed

+439
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
SE05X AES Encrypt and Decrypt
3+
4+
This sketch uses the SE05X to encrypt and decrypt given data
5+
with an AES key, which was uploaded in the SE05XWriteAESKey
6+
example. This sketch encrypts 32 bytes with AES ECB Mode
7+
and then decrypt this data for comparing the results.
8+
9+
Circuit:
10+
- Portenta C33
11+
*/
12+
13+
#include <SE05X.h>
14+
15+
16+
const int AES_KEY_ID = 666;
17+
const byte data[32] = {
18+
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
19+
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
20+
};
21+
22+
23+
void print_hex(const byte in[], size_t len) {
24+
for (size_t i = 0; i < len; i++) {
25+
Serial.print(in[i] >> 4, HEX);
26+
Serial.print(in[i] & 0x0f, HEX);
27+
}
28+
Serial.println();
29+
}
30+
31+
void setup() {
32+
Serial.begin(9600);
33+
while (!Serial);
34+
35+
36+
if (!SE05X.begin()) {
37+
Serial.println("Error with secure element");
38+
while(1);
39+
}
40+
41+
42+
size_t encrypted_data_len = 32;
43+
size_t decrypted_data_len = 32;
44+
byte encrypted_data[32];
45+
byte decrypted_data[32];
46+
47+
int status1 = SE05X.AES_ECB_encrypt(AES_KEY_ID, data, sizeof(data), encrypted_data, &encrypted_data_len);
48+
int status2 = SE05X.AES_ECB_decrypt(AES_KEY_ID, encrypted_data, sizeof(data), decrypted_data, &decrypted_data_len);
49+
print_hex(data,32);
50+
print_hex(encrypted_data,32);
51+
print_hex(decrypted_data,32);
52+
}
53+
54+
void loop() {
55+
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
SE05X WriteAESKey
3+
4+
This sketch uses the SE05X to securely store an AES key. When the key is uploaded to
5+
SE05X, the sketch on the Arduino should be overwritten.
6+
7+
Circuit:
8+
- Portenta C33
9+
*/
10+
11+
#include <SE05X.h>
12+
13+
const int AES_KEY_ID = 666;
14+
const byte aes_key[32] = {
15+
0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0x33, 0x33, 0xFF, 0x33,
16+
0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0x33, 0x33, 0xFF, 0x44
17+
};
18+
19+
void setup() {
20+
Serial.begin(9600);
21+
22+
if (!SE05X.begin()) {
23+
Serial.println("Error with secure element");
24+
while(1);
25+
}
26+
27+
SE05X.deleteBinaryObject(AES_KEY_ID);
28+
SE05X.writeAESKey(AES_KEY_ID, aes_key, sizeof(aes_key));
29+
}
30+
31+
void loop() {
32+
33+
}

Diff for: libraries/SE05X/examples/SE05XHMAC/SE05XHMAC.ino

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
SE05X HMAC
3+
4+
This sketch uses the SE05X to securely store and use an HMAC Key
5+
and calculates the HMAC-SHA512 sum of a given message
6+
7+
Circuit:
8+
- Portenta C33
9+
*/
10+
11+
#include <SE05X.h>
12+
13+
const int HMAC_KEY_ID = 667;
14+
const byte hmac_key[32] = {
15+
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
16+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
17+
};
18+
19+
20+
void print_hex(const byte in[], size_t len) {
21+
for (size_t i = 0; i < len; i++) {
22+
Serial.print(in[i] >> 4, HEX);
23+
Serial.print(in[i] & 0x0f, HEX);
24+
}
25+
Serial.println();
26+
}
27+
28+
void setup() {
29+
Serial.begin(9600);
30+
while (!Serial);
31+
32+
if (!SE05X.begin()) {
33+
Serial.println("Error with secure element");
34+
while(1);
35+
}
36+
37+
SE05X.deleteBinaryObject(HMAC_KEY_ID); //remove key if already exists
38+
39+
SE05X.writeHMACKey(HMAC_KEY_ID, hmac_key, sizeof(hmac_key));
40+
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";
41+
42+
43+
byte buffer[64];
44+
for(int i = 0; i < 64; i++)
45+
buffer[i] = 0;
46+
47+
size_t len = 64; // 64 byte = 512 bit, length for SHA512
48+
SE05X.HMAC_Generate(HMAC_KEY_ID, kSE05x_MACAlgo_HMAC_SHA512, (const byte*)message.c_str(), message.length(), buffer, &len);
49+
print_hex(buffer,len);
50+
}
51+
52+
void loop() {
53+
54+
}

Diff for: libraries/SE05X/src/SE05X.cpp

+92-1
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,97 @@ int SE05XClass::readSlot(int slot, byte data[], int length)
595595
return readBinaryObject(slot, data, length, &size);
596596
}
597597

598+
int SE05XClass::AES_ECB_encrypt(int objectId, const byte data[], size_t data_length, byte output[], size_t *output_len)
599+
{
600+
smStatus_t status;
601+
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);
602+
if (status != SM_OK) {
603+
SMLOG_E("Error in Se05x_API_CipherOneShot \n");
604+
return 0;
605+
}
606+
return 1;
607+
}
608+
609+
int SE05XClass::AES_ECB_decrypt(int objectId, const byte data[], size_t data_length, byte output[], size_t *output_len)
610+
{
611+
smStatus_t status;
612+
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);
613+
if (status != SM_OK) {
614+
SMLOG_E("Error in Se05x_API_CipherOneShot \n");
615+
return 0;
616+
}
617+
return 1;
618+
}
619+
620+
int SE05XClass::writeAESKey(int objectId, const byte data[], size_t length)
621+
{
622+
smStatus_t status;
623+
SE05x_Result_t result;
624+
uint16_t offset = 0;
625+
uint16_t size;
626+
627+
status = Se05x_API_CheckObjectExists(&_se05x_session, objectId, &result);
628+
if (status != SM_OK) {
629+
SMLOG_E("Error in Se05x_API_CheckObjectExists \n");
630+
return 0;
631+
}
632+
633+
if (result == kSE05x_Result_SUCCESS) {
634+
SMLOG_E("Object exists \n");
635+
return 0;
636+
}
637+
638+
uint16_t left = length;
639+
640+
status = Se05x_API_WriteSymmKey(&_se05x_session, NULL, 3, objectId, NULL, data, length, kSE05x_INS_NA, kSE05x_SymmKeyType_AES);
641+
642+
if (status != SM_OK) {
643+
SMLOG_E("Error in Se05x_API_WriteSymmKey \n");
644+
return 0;
645+
}
646+
return 1;
647+
}
648+
649+
int SE05XClass::writeHMACKey(int objectId, const byte data[], size_t length)
650+
{
651+
smStatus_t status;
652+
SE05x_Result_t result;
653+
uint8_t exists = 0;
654+
uint16_t offset = 0;
655+
uint16_t size;
656+
657+
status = Se05x_API_CheckObjectExists(&_se05x_session, objectId, &result);
658+
if (status != SM_OK) {
659+
SMLOG_E("Error in Se05x_API_CheckObjectExists \n");
660+
return 0;
661+
}
662+
663+
if (result == kSE05x_Result_SUCCESS) {
664+
SMLOG_E("Object exists \n");
665+
exists = 1;
666+
}
667+
668+
status = Se05x_API_WriteSymmKey(&_se05x_session, NULL, 0, objectId, SE05x_KeyID_KEK_NONE, data, length, kSE05x_INS_NA, kSE05x_SymmKeyType_HMAC);
669+
670+
if (status != SM_OK) {
671+
SMLOG_E("Error in Se05x_API_WriteSymmKey \n");
672+
return 0;
673+
}
674+
return 1;
675+
}
676+
677+
int SE05XClass::HMAC_Generate(int objectId, uint8_t mac_operation, const byte data[], size_t data_length, byte output[], size_t *output_len)
678+
{
679+
smStatus_t status;
680+
status = Se05x_API_MACOneShot_G(&_se05x_session, objectId, mac_operation, data, data_length, output, output_len);
681+
682+
if (status != SM_OK) {
683+
SMLOG_E("Error in Se05x_API_CipherOneShot \n");
684+
return status;
685+
}
686+
return 1;
687+
}
688+
598689
int SE05XClass::writeBinaryObject(int objectId, const byte data[], size_t length)
599690
{
600691
smStatus_t status;
@@ -668,7 +759,7 @@ int SE05XClass::deleteBinaryObject(int objectId)
668759

669760
status = Se05x_API_DeleteSecureObject(&_se05x_session, objectId);
670761
if (status != SM_OK) {
671-
SMLOG_E("Error in Se05x_API_CheckObjectExists \n");
762+
SMLOG_E("Error in Se05x_API_DeleteSecureObject \n");
672763
return 0;
673764
}
674765

Diff for: libraries/SE05X/src/SE05X.h

+68
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,74 @@ class SE05XClass
194194
*/
195195
int readBinaryObject(int ObjectId, byte data[], size_t dataMaxLen, size_t* length);
196196

197+
/** AES_ECB_encrypt
198+
*
199+
* Enrypts something with AES ECB
200+
*
201+
* @param[in] ObjectId SE050 object ID
202+
* @param[in] data Input data buffer
203+
* @param[in] length Input data buffer size (should be a multiple of 16 bytes)
204+
* @param[out] output Output data buffer
205+
* @param[out] output_length Output data buffer size (same as input)
206+
*
207+
* @return 0 on Failure 1 on Success
208+
*/
209+
int AES_ECB_encrypt(int objectId, const byte data[], size_t data_length, byte output[], size_t *output_len);
210+
211+
/** AES_ECB_decrypt
212+
*
213+
* Enrypts something with AES ECB
214+
*
215+
* @param[in] ObjectId SE050 object ID
216+
* @param[in] data Input data buffer
217+
* @param[in] length Input data buffer size (should be a multiple of 16 bytes)
218+
* @param[out] output Output data buffer
219+
* @param[out] output_length Output data buffer size (same as input)
220+
*
221+
* @return 0 on Failure 1 on Success
222+
*/
223+
int AES_ECB_decrypt(int objectId, const byte data[], size_t data_length, byte output[], size_t *output_len);
224+
225+
/** writeAESKey
226+
*
227+
* Writes symmetric key into SE050 object.
228+
*
229+
* @param[in] ObjectId SE050 object ID
230+
* @param[in] data Input data buffer
231+
* @param[in] length Input data buffer size
232+
*
233+
* @return 0 on Failure 1 on Success
234+
*/
235+
int writeAESKey(int ObjectId, const byte data[], size_t length);
236+
237+
/** writeHMACKey
238+
*
239+
* Writes symmetric key into SE050 object.
240+
*
241+
* @param[in] ObjectId SE050 object ID for the hmac key
242+
* @param[in] data Input data buffer
243+
* @param[in] length Input data buffer size
244+
*
245+
* @return 0 on Failure 1 on Success
246+
*/
247+
int writeHMACKey(int ObjectId, const byte data[], size_t length);
248+
249+
/** HMAC_Generate
250+
*
251+
* Computes the HMAC digest with SE050 chip
252+
*
253+
* @param[in] objectId SE050 object ID for the hmac key
254+
* @param[in] mac_operation Type of Hash function for HMAC
255+
* @param[in] data Input data buffer
256+
* @param[in] length Input data buffer size
257+
* @param[out] output Output data buffer
258+
* @param[out] output_length Output data buffer size (should be 32 bytes for SHA256)
259+
*
260+
* @return 0 on Failure 1 on Success
261+
*/
262+
int HMAC_Generate(int objectId, uint8_t mac_operation, const byte data[], size_t data_length, byte output[], size_t *output_len);
263+
264+
197265
/** writeBinaryObject
198266
*
199267
* Writes binary data into SE050 object.

0 commit comments

Comments
 (0)