EnigmaIOT  0.9.8
Secure sensor and gateway platform based on ESP8266 and ESP32
cryptModule.cpp
Go to the documentation of this file.
1 
11 #include "cryptModule.h"
12 #include <Curve25519.h>
13 #include <ChaChaPoly.h>
14 #include <Poly1305.h>
15 #include <SHA256.h>
16 #include "helperFunctions.h"
17 
19 
20 uint8_t* CryptModule::getSHA256 (uint8_t* buffer, uint8_t length) {
21  const uint8_t HASH_LEN = 32;
22 
23  uint8_t key[HASH_LEN];
24 
25  if (length < HASH_LEN) {
26  DEBUG_ERROR ("Too small buffer. Should be 32 bytes");
27  return NULL;
28  }
29 
30  SHA256 hash;
31 
32  // hash.reset (); // Not needed, implicit to constructor
33  hash.update ((void*)buffer, length);
34  hash.finalize (key, HASH_LEN);
35  hash.clear ();
36 
37  /*br_sha256_context* shaContext = new br_sha256_context ();
38  br_sha256_init (shaContext);
39  br_sha224_update (shaContext, (void*)buffer, length);
40  br_sha256_out (shaContext, key);
41  delete shaContext;*/
42 
43  if (length > HASH_LEN) {
44  length = HASH_LEN;
45  }
46 
47  memcpy (buffer, key, length);
48 
49  return buffer;
50 }
51 
52 bool CryptModule::decryptBuffer (const uint8_t* data, size_t length,
53  const uint8_t* iv, uint8_t ivlen, const uint8_t* key, uint8_t keylen,
54  const uint8_t* aad, uint8_t aadLen, const uint8_t* tag, uint8_t tagLen) {
55  if (key && iv && data) {
56 
57  DEBUG_VERBOSE ("IV: %s", printHexBuffer (iv, ivlen));
58  DEBUG_VERBOSE ("Key: %s", printHexBuffer (key, keylen));
59  DEBUG_VERBOSE ("AAD: %s", printHexBuffer (aad, aadLen));
60  cipher.clear ();
61 
62  if (cipher.setKey (key, keylen)) {
63  if (cipher.setIV ((uint8_t*)iv, ivlen)) {
64  cipher.addAuthData ((uint8_t*)aad, aadLen);
65  cipher.decrypt ((uint8_t*)data, (uint8_t*)data, length);
66  bool ok = cipher.checkTag ((uint8_t*)tag, tagLen);
67  cipher.clear ();
68  DEBUG_VERBOSE ("Tag: %s", printHexBuffer (tag, tagLen));
69  if (!ok) {
70  DEBUG_ERROR ("Data authentication error");
71  }
72  return ok;
73  } else {
74  DEBUG_ERROR ("Error setting IV");
75  }
76  } else {
77  DEBUG_ERROR ("Error setting key");
78  }
79  } else {
80  DEBUG_ERROR ("Error in key or IV");
81  }
82 
83  return false;
84 }
85 
86 bool CryptModule::encryptBuffer (const uint8_t* data, size_t length,
87  const uint8_t* iv, uint8_t ivlen, const uint8_t* key, uint8_t keylen,
88  const uint8_t* aad, uint8_t aadLen, const uint8_t* tag, uint8_t tagLen) {
89 
90  if (key && iv && data) {
91 
92  DEBUG_VERBOSE ("IV: %s", printHexBuffer (iv, ivlen));
93  DEBUG_VERBOSE ("Key: %s", printHexBuffer (key, keylen));
94  DEBUG_VERBOSE ("AAD: %s", printHexBuffer (aad, aadLen));
95  cipher.clear ();
96 
97  if (cipher.setKey ((uint8_t*)key, keylen)) {
98  if (cipher.setIV ((uint8_t*)iv, ivlen)) {
99  cipher.addAuthData ((uint8_t*)aad, aadLen);
100  cipher.encrypt ((uint8_t*)data, (uint8_t*)data, length);
101  cipher.computeTag ((uint8_t*)tag, tagLen);
102  cipher.clear ();
103  DEBUG_VERBOSE ("Tag: %s", printHexBuffer (tag, tagLen));
104  return true;
105  } else {
106  DEBUG_ERROR ("Error setting IV");
107  }
108  } else {
109  DEBUG_ERROR ("Error setting key");
110  }
111  } else {
112  DEBUG_ERROR ("Error on input data for encryption");
113  }
114 
115  return false;
116 
117 }
118 
119 uint32_t CryptModule::random () {
120 #ifdef ESP8266
121  return *(volatile uint32_t*)RANDOM_32;
122 #elif defined ESP32
123  return esp_random ();
124 #endif
125 }
126 
127 uint8_t* CryptModule::random (const uint8_t* buf, size_t len) {
128  if (buf) {
129  for (unsigned int i = 0; i < len; i += sizeof (uint32_t)) {
130  uint32_t rnd = random ();
131  if (i < len - (len % sizeof (int32_t))) {
132  memcpy (const_cast<uint8_t*>(buf) + i, &rnd, sizeof (uint32_t));
133  } else {
134  memcpy (const_cast<uint8_t*>(buf) + i, &rnd, len % sizeof (int32_t));
135  }
136  }
137  }
138  return const_cast<uint8_t*>(buf);
139 }
140 
142  Curve25519::dh1 (publicDHKey, privateDHKey);
143  DEBUG_VERBOSE ("Public key: %s", printHexBuffer (publicDHKey, KEY_LENGTH));
144 
145  DEBUG_VERBOSE ("Private key: %s", printHexBuffer (privateDHKey, KEY_LENGTH));
146 }
147 
148 bool CryptModule::getDH2 (const uint8_t* remotePubKey) {
149  DEBUG_VERBOSE ("Remote public key: %s", printHexBuffer (const_cast<uint8_t*>(remotePubKey), KEY_LENGTH));
150  DEBUG_VERBOSE ("Private key: %s", printHexBuffer (privateDHKey, KEY_LENGTH));
151 
152  if (!Curve25519::dh2 (const_cast<uint8_t*>(remotePubKey), privateDHKey)) {
153  DEBUG_WARN ("DH2 error");
154  return false;
155  }
156  memset (publicDHKey, 0, KEY_LENGTH); // delete public key from memory
157 
158  return true;
159 }
160 
161 /*size_t CryptModule::getBlockSize ()
162 {
163  CYPHER_TYPE cipher;
164  return cipher.blockSize();
165 }*/
166 
CryptModule::decryptBuffer
static bool decryptBuffer(const uint8_t *data, size_t length, const uint8_t *iv, uint8_t ivlen, const uint8_t *key, uint8_t keylen, const uint8_t *aad, uint8_t aadLen, const uint8_t *tag, uint8_t tagLen)
Decrypts a buffer using a shared key.
Definition: cryptModule.cpp:52
CryptModule::getDH1
void getDH1()
Starts first stage of Diffie Hellman key agreement algorithm.
Definition: cryptModule.cpp:141
cryptModule.h
Crypto library that implements EnigmaIoT encryption, decryption and key agreement fuctions.
cipher
CYPHER_TYPE cipher
Definition: cryptModule.cpp:18
CryptModule::privateDHKey
uint8_t privateDHKey[KEY_LENGTH]
Temporary private key store used during key agreement.
Definition: cryptModule.h:141
CryptModule::encryptBuffer
static bool encryptBuffer(const uint8_t *data, size_t length, const uint8_t *iv, uint8_t ivlen, const uint8_t *key, uint8_t keylen, const uint8_t *aad, uint8_t aadLen, const uint8_t *tag, uint8_t tagLen)
Decrypts a buffer using a shared key.
Definition: cryptModule.cpp:86
Crypto
CryptModule Crypto
Singleton Crypto class instance.
Definition: cryptModule.cpp:167
CryptModule
EnigmaIoT Crypto module. Wraps Arduino CryptoLib classes and methods.
Definition: cryptModule.h:35
printHexBuffer
char * printHexBuffer(const uint8_t *buffer, uint16_t len)
Debug helper function that generates a string that represent a buffer hexadecimal values.
Definition: helperFunctions.cpp:16
CryptModule::getSHA256
static uint8_t * getSHA256(uint8_t *buffer, uint8_t length)
Generates a SHA256 hash from input.
Definition: cryptModule.cpp:20
CryptModule::random
static uint32_t random()
Gets a random number.
Definition: cryptModule.cpp:119
KEY_LENGTH
const uint8_t KEY_LENGTH
Key length used by selected crypto algorythm. The only tested value is 32. Change it only if you know...
Definition: EnigmaIoTconfigAdvanced.h:70
CYPHER_TYPE
#define CYPHER_TYPE
Definition: EnigmaIoTconfigAdvanced.h:74
data
@ data
Definition: GwOutput_generic.h:23
CryptModule::getDH2
bool getDH2(const uint8_t *remotePubKey)
Starts second stage of Diffie Hellman key agreement algorithm and calculate shares key.
Definition: cryptModule.cpp:148
helperFunctions.h
Auxiliary function definition.
CryptModule::publicDHKey
uint8_t publicDHKey[KEY_LENGTH]
Temporary public key store used during key agreement.
Definition: cryptModule.h:142