|
|
|
@ -2,6 +2,13 @@ |
|
|
|
#include <AES.h> |
|
|
|
#include <SHA256.h> |
|
|
|
|
|
|
|
#ifdef USE_CC310_HW_CRYPTO |
|
|
|
#include <Adafruit_nRFCrypto.h> |
|
|
|
#include "nrf_cc310/include/crys_hash.h" |
|
|
|
#include "nrf_cc310/include/crys_hmac.h" |
|
|
|
#include "nrf_cc310/include/ssi_aes.h" |
|
|
|
#endif |
|
|
|
|
|
|
|
#ifdef ARDUINO |
|
|
|
#include <Arduino.h> |
|
|
|
#endif |
|
|
|
@ -15,19 +22,58 @@ uint32_t RNG::nextInt(uint32_t _min, uint32_t _max) { |
|
|
|
} |
|
|
|
|
|
|
|
void Utils::sha256(uint8_t *hash, size_t hash_len, const uint8_t* msg, int msg_len) { |
|
|
|
#ifdef USE_CC310_HW_CRYPTO |
|
|
|
static CRYS_HASH_Result_t result; |
|
|
|
nRFCrypto.begin(); |
|
|
|
CRYS_HASH(CRYS_HASH_SHA256_mode, (uint8_t*)msg, (size_t)msg_len, result); |
|
|
|
nRFCrypto.end(); |
|
|
|
memcpy(hash, result, hash_len); |
|
|
|
#else |
|
|
|
SHA256 sha; |
|
|
|
sha.update(msg, msg_len); |
|
|
|
sha.finalize(hash, hash_len); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
void Utils::sha256(uint8_t *hash, size_t hash_len, const uint8_t* frag1, int frag1_len, const uint8_t* frag2, int frag2_len) { |
|
|
|
#ifdef USE_CC310_HW_CRYPTO |
|
|
|
static CRYS_HASHUserContext_t ctx; |
|
|
|
static CRYS_HASH_Result_t result; |
|
|
|
nRFCrypto.begin(); |
|
|
|
CRYS_HASH_Init(&ctx, CRYS_HASH_SHA256_mode); |
|
|
|
CRYS_HASH_Update(&ctx, (uint8_t*)frag1, (size_t)frag1_len); |
|
|
|
CRYS_HASH_Update(&ctx, (uint8_t*)frag2, (size_t)frag2_len); |
|
|
|
CRYS_HASH_Finish(&ctx, result); |
|
|
|
nRFCrypto.end(); |
|
|
|
memcpy(hash, result, hash_len); |
|
|
|
#else |
|
|
|
SHA256 sha; |
|
|
|
sha.update(frag1, frag1_len); |
|
|
|
sha.update(frag2, frag2_len); |
|
|
|
sha.finalize(hash, hash_len); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
int Utils::decrypt(const uint8_t* shared_secret, uint8_t* dest, const uint8_t* src, int src_len) { |
|
|
|
#ifdef USE_CC310_HW_CRYPTO |
|
|
|
static SaSiAesUserContext_t ctx; |
|
|
|
SaSiAesUserKeyData_t keyData = { (uint8_t*)shared_secret, CIPHER_KEY_SIZE }; |
|
|
|
uint8_t* dp = dest; |
|
|
|
const uint8_t* sp = src; |
|
|
|
size_t dummy_out = 0; |
|
|
|
|
|
|
|
nRFCrypto.begin(); |
|
|
|
SaSi_AesInit(&ctx, SASI_AES_DECRYPT, SASI_AES_MODE_ECB, SASI_AES_PADDING_NONE); |
|
|
|
SaSi_AesSetKey(&ctx, SASI_AES_USER_KEY, &keyData, sizeof(keyData)); |
|
|
|
while (sp - src < src_len) { |
|
|
|
SaSi_AesBlock(&ctx, (uint8_t*)sp, 16, dp); |
|
|
|
dp += 16; sp += 16; |
|
|
|
} |
|
|
|
SaSi_AesFinish(&ctx, 0, NULL, 0, NULL, &dummy_out); |
|
|
|
SaSi_AesFree(&ctx); |
|
|
|
nRFCrypto.end(); |
|
|
|
return sp - src; |
|
|
|
#else |
|
|
|
AES128 aes; |
|
|
|
uint8_t* dp = dest; |
|
|
|
const uint8_t* sp = src; |
|
|
|
@ -39,9 +85,34 @@ int Utils::decrypt(const uint8_t* shared_secret, uint8_t* dest, const uint8_t* s |
|
|
|
} |
|
|
|
|
|
|
|
return sp - src; // will always be multiple of 16
|
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
int Utils::encrypt(const uint8_t* shared_secret, uint8_t* dest, const uint8_t* src, int src_len) { |
|
|
|
#ifdef USE_CC310_HW_CRYPTO |
|
|
|
static SaSiAesUserContext_t ctx; |
|
|
|
SaSiAesUserKeyData_t keyData = { (uint8_t*)shared_secret, CIPHER_KEY_SIZE }; |
|
|
|
uint8_t* dp = dest; |
|
|
|
size_t dummy_out = 0; |
|
|
|
|
|
|
|
nRFCrypto.begin(); |
|
|
|
SaSi_AesInit(&ctx, SASI_AES_ENCRYPT, SASI_AES_MODE_ECB, SASI_AES_PADDING_NONE); |
|
|
|
SaSi_AesSetKey(&ctx, SASI_AES_USER_KEY, &keyData, sizeof(keyData)); |
|
|
|
while (src_len >= 16) { |
|
|
|
SaSi_AesBlock(&ctx, (uint8_t*)src, 16, dp); |
|
|
|
dp += 16; src += 16; src_len -= 16; |
|
|
|
} |
|
|
|
if (src_len > 0) { // remaining partial block — zero-pad to 16 bytes
|
|
|
|
uint8_t tmp[16] = {}; |
|
|
|
memcpy(tmp, src, src_len); |
|
|
|
SaSi_AesBlock(&ctx, tmp, 16, dp); |
|
|
|
dp += 16; |
|
|
|
} |
|
|
|
SaSi_AesFinish(&ctx, 0, NULL, 0, NULL, &dummy_out); |
|
|
|
SaSi_AesFree(&ctx); |
|
|
|
nRFCrypto.end(); |
|
|
|
return dp - dest; |
|
|
|
#else |
|
|
|
AES128 aes; |
|
|
|
uint8_t* dp = dest; |
|
|
|
|
|
|
|
@ -58,15 +129,27 @@ int Utils::encrypt(const uint8_t* shared_secret, uint8_t* dest, const uint8_t* s |
|
|
|
dp += 16; |
|
|
|
} |
|
|
|
return dp - dest; // will always be multiple of 16
|
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
int Utils::encryptThenMAC(const uint8_t* shared_secret, uint8_t* dest, const uint8_t* src, int src_len) { |
|
|
|
int enc_len = encrypt(shared_secret, dest + CIPHER_MAC_SIZE, src, src_len); |
|
|
|
|
|
|
|
#ifdef USE_CC310_HW_CRYPTO |
|
|
|
static CRYS_HMACUserContext_t hmac_ctx; |
|
|
|
static CRYS_HASH_Result_t hmac_result; |
|
|
|
nRFCrypto.begin(); |
|
|
|
CRYS_HMAC_Init(&hmac_ctx, CRYS_HASH_SHA256_mode, (uint8_t*)shared_secret, PUB_KEY_SIZE); |
|
|
|
CRYS_HMAC_Update(&hmac_ctx, dest + CIPHER_MAC_SIZE, enc_len); |
|
|
|
CRYS_HMAC_Finish(&hmac_ctx, hmac_result); |
|
|
|
nRFCrypto.end(); |
|
|
|
memcpy(dest, hmac_result, CIPHER_MAC_SIZE); |
|
|
|
#else |
|
|
|
SHA256 sha; |
|
|
|
sha.resetHMAC(shared_secret, PUB_KEY_SIZE); |
|
|
|
sha.update(dest + CIPHER_MAC_SIZE, enc_len); |
|
|
|
sha.finalizeHMAC(shared_secret, PUB_KEY_SIZE, dest, CIPHER_MAC_SIZE); |
|
|
|
#endif |
|
|
|
|
|
|
|
return CIPHER_MAC_SIZE + enc_len; |
|
|
|
} |
|
|
|
@ -75,12 +158,25 @@ int Utils::MACThenDecrypt(const uint8_t* shared_secret, uint8_t* dest, const uin |
|
|
|
if (src_len <= CIPHER_MAC_SIZE) return 0; // invalid src bytes
|
|
|
|
|
|
|
|
uint8_t hmac[CIPHER_MAC_SIZE]; |
|
|
|
#ifdef USE_CC310_HW_CRYPTO |
|
|
|
{ |
|
|
|
static CRYS_HMACUserContext_t hmac_ctx; |
|
|
|
static CRYS_HASH_Result_t hmac_result; |
|
|
|
nRFCrypto.begin(); |
|
|
|
CRYS_HMAC_Init(&hmac_ctx, CRYS_HASH_SHA256_mode, (uint8_t*)shared_secret, PUB_KEY_SIZE); |
|
|
|
CRYS_HMAC_Update(&hmac_ctx, (uint8_t*)(src + CIPHER_MAC_SIZE), src_len - CIPHER_MAC_SIZE); |
|
|
|
CRYS_HMAC_Finish(&hmac_ctx, hmac_result); |
|
|
|
nRFCrypto.end(); |
|
|
|
memcpy(hmac, hmac_result, CIPHER_MAC_SIZE); |
|
|
|
} |
|
|
|
#else |
|
|
|
{ |
|
|
|
SHA256 sha; |
|
|
|
sha.resetHMAC(shared_secret, PUB_KEY_SIZE); |
|
|
|
sha.update(src + CIPHER_MAC_SIZE, src_len - CIPHER_MAC_SIZE); |
|
|
|
sha.finalizeHMAC(shared_secret, PUB_KEY_SIZE, hmac, CIPHER_MAC_SIZE); |
|
|
|
} |
|
|
|
#endif |
|
|
|
if (memcmp(hmac, src, CIPHER_MAC_SIZE) == 0) { |
|
|
|
return decrypt(shared_secret, dest, src + CIPHER_MAC_SIZE, src_len - CIPHER_MAC_SIZE); |
|
|
|
} |
|
|
|
@ -150,4 +246,4 @@ int Utils::parseTextParts(char* text, const char* parts[], int max_num, char sep |
|
|
|
return num; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|