EnigmaIOT  0.9.8
Secure sensor and gateway platform based on ESP8266 and ESP32
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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