AES128ESP32 Library
Loading...
Searching...
No Matches
crypto.h
Go to the documentation of this file.
1#pragma once
2#ifndef _Cr2X_
3#define _Cr2X_
4#include <cstring>
5#include <list>
6#include "psa/crypto_values.h"
7
8// #define DEBUGLEVEL 2
9#include "delays.h"
10#include "psaerr2str.h"
11#include "pbkdf2.h"
12
13#define PRINTERRORxxxx(function) \
14 DEBUG2(String(function) + " failed " + errortoString(status)); \
15 STOP;
16
17#include "psa/crypto.h"
18// AES128
19
56class crypto {
57#define NUMBYTES 16
58#define IVSIZE 12
59 // pass2Key *keyset;
60 // psa_status_t status;
61 /* Dummy data for encryption: IV/nonce - */
62
63 /*const */ unsigned char iv[IVSIZE] = { 0x00 };
64 size_t givlen = 0; // generated IV
65 psa_key_id_t key; // this is the PSA key
66 size_t key_bits = NUMBYTES * 8;
67 psa_aead_operation_t op;
68public:
69 crypto() {}
71 bool begin() {
72 DEBUG3("");
73
74 psa_status_t status = psa_crypto_init();
75 if (status != PSA_SUCCESS) {
76 //DEBUG2("psa_crypto_init failed " + errortoString(status));
77 PRINTERROR2(status, "psa_crytpo_init");
78 return false;
79 }
80 DEBUG3("begin success");
81 return true;
82 }
83
87 void setkeyaccess(pass2Key *keyholder) {
88 key = keyholder->newkeyid;
89 }
90
94 void setkeyaccess(pass2Key &keyholder) {
95 key = keyholder.newkeyid;
96 }
97
103 unsigned char *getIVbytes(size_t &IVsize) {
104 IVsize = givlen;
105 return iv;
106 }
107
113 void setIVbytes(unsigned char *bytes, size_t byteslength) {
114 assert(byteslength == IVSIZE);
115 memcpy(iv, bytes, byteslength);
116 givlen = byteslength;
117 }
118
122 void clearIV() {
123 memset(iv, 0, IVSIZE);
124 givlen = 0;
125 }
126
128 // probably should be private or protected??
129private:
130 void buildKeyForAESEncryptOrDecrypt(bool shouldEncrypt = true) {
131 if ((shouldEncrypt != PSA_KEY_USAGE_DECRYPT) || (shouldEncrypt != PSA_KEY_USAGE_ENCRYPT))
132 assert(true);
133
134 psa_status_t status;
135 /*psa_aead_operation_t */ op = PSA_AEAD_OPERATION_INIT;
136 if (shouldEncrypt == true) {
137 status = psa_aead_encrypt_setup(&op, key, PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 8));
138 if (status != PSA_SUCCESS) {
139 PRINTERROR2(status, "psa_aead_encrypt_setup");
140 }
141 if (!givlen) {
142 status = psa_aead_generate_nonce(&op, iv, sizeof(iv), &givlen);
143 if (status != PSA_SUCCESS) {
144 PRINTERROR2(status, "psa_aead_generate_nonce");
145 }
146 DEBUG3("generated iv size = " + String(givlen));
147 assert(givlen == IVSIZE);
148 } else {
149 // 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce().
150 status = psa_aead_set_nonce(&op, iv, sizeof(iv));
151 if (status != PSA_SUCCESS) {
152 PRINTERROR2(status, "psa_aead_set_nonce");
153 }
154 }
155 } else {
156 status = psa_aead_decrypt_setup(&op, key, PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 8));
157 if (status != PSA_SUCCESS) {
158 PRINTERROR2(status, "psa_aead_decrypt_setup");
159 }
160 // 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce().
161 status = psa_aead_set_nonce(&op, iv, sizeof(iv));
162 if (status != PSA_SUCCESS) {
163 PRINTERROR2(status, "psa_aead_set_nonce");
164 }
165 }
166 }
167
168
181public:
182 String Decrypt(unsigned char *bytes, size_t len) {
183 DEBUG3("");
184 psa_status_t status;
185 String rtn = "";
186 unsigned char outbuf[key_bits / 8];
187 assert(sizeof(outbuf) == 16);
188 unsigned char inpbuf[key_bits / 8];
189 assert(len % 16 == 0);
190
191 buildKeyForAESEncryptOrDecrypt(false);
192 DEBUG3("len = " + String(len));
193 int lastcharactercount = 0;
194 size_t olen;
195 while (lastcharactercount < len) {
196 DEBUG3("while lastcharactercount = " + String(lastcharactercount));
197 for (int i = 0; i < sizeof(inpbuf); i++)
198 inpbuf[i] = *bytes++;
199
200 DUMP("inpbuf decrypt", inpbuf, sizeof(inpbuf));
201 lastcharactercount = lastcharactercount + sizeof(inpbuf);
202 status = psa_aead_update(&op, inpbuf, sizeof(inpbuf), outbuf, sizeof(outbuf), &olen);
203 if (status != PSA_SUCCESS) {
204 PRINTERROR2(status, "psa_aead_update");
205 }
206
207 for (int i = 0; i < olen; i++)
208 if (outbuf[i])
209 rtn.concat((char)outbuf[i]);
210
211 DUMP("outbuf decrypt", outbuf, sizeof(outbuf));
212 } // while
213 psa_aead_abort(&op);
214 return rtn;
215 }
216
217 unsigned char *
218 Encrypt(String datatoEncrypt, size_t &outputsize) {
219 psa_status_t status;
220 unsigned char outbuf[key_bits / 8];
221 assert(sizeof(outbuf) == 16);
222 unsigned char inpbuf[key_bits / 8];
223
224 buildKeyForAESEncryptOrDecrypt();
225
226 size_t olen;
227 std::list<unsigned char> outputbytes;
228 int lastcharactercount = 0;
229 int maxlength = datatoEncrypt.length();
230
231 // copy at most key_bits /8
232 while (lastcharactercount < maxlength) {
233 // DEBUG2("********* LOOP ******* ");
234 String dataforthisround = datatoEncrypt.substring(lastcharactercount, lastcharactercount + 16);
235 // DEBUG2("Data for this round = " + dataforthisround + " , length = " + dataforthisround.length());
236 dataforthisround.getBytes(inpbuf, dataforthisround.length() + 1);
237 lastcharactercount += dataforthisround.length();
238
239 // i think i need to erase the end-- note i'm using zero bytes because its a string
240 int stilltodo = sizeof(inpbuf) - dataforthisround.length();
241 unsigned char *p = inpbuf + dataforthisround.length();
242 for (int i = 0; i < stilltodo; i++)
243 *p++ = 0; //'*';
244 // = '*'; // only for validation
245 DUMP("inpbuf", inpbuf, sizeof(inpbuf));
246 // *************
247 // 123456789012345678
248 /* * If this function returns an error status, the operation enters an error
249 * state and must be aborted by calling psa_aead_abort(). */
250 status = psa_aead_update(&op, inpbuf, sizeof(inpbuf), outbuf, sizeof(outbuf), &olen);
251 if (status != PSA_SUCCESS) {
252 PRINTERROR2(status, "psa_aead_update");
253 }
254 // DEBUG2("olen for update = " + String(olen));
255 // move encrytped data to output buffer
256 for (int i = 0; i < olen; i++)
257 outputbytes.push_back(outbuf[i]);
258
259 DUMP("outbuf", outbuf, olen);
260 }
261
262 status = psa_aead_abort(&op);
263 if (status != PSA_SUCCESS) {
264 PRINTERROR2(status, "psa_aead_update");
265 }
266 int numbytes = outputbytes.size();
267 outputsize = numbytes;
268 unsigned char *rtn = (unsigned char *)malloc((size_t)numbytes);
269 // DEBUG2("****************END size=" + String(numbytes));
270 // char work[10];
271 for (int i = 0; i < numbytes; i++) {
272 // sprintf(work, "%02X ", outputbytes.front());
273 rtn[i] = outputbytes.front();
274 // sprintf(work, "%d-%02X ",i, outputbytes.front());
275 outputbytes.pop_front();
276 // Serial.println(work);
277 }
278 // Serial.println();
279
280 /*
281// I don't need this, before this required using psa_read_update_ad which I'm not using. but I might it in the futura
282 status = psa_aead_finish(&op, outbuf, sizeof(outbuf), &olen, authenticationtag, sizeof(authenticationtag), &olen_tag);
283 if (status != PSA_SUCCESS) {
284 PRINTERROR("psa_aead_finish");
285 }
286 */
287 return rtn;
288 }
289};
290
291#endif
crypto()
Definition crypto.h:69
bool begin()
Definition crypto.h:71
void setkeyaccess(pass2Key *keyholder)
Definition crypto.h:87
void setIVbytes(unsigned char *bytes, size_t byteslength)
Definition crypto.h:113
unsigned char * Encrypt(String datatoEncrypt, size_t &outputsize)
Definition crypto.h:218
void clearIV()
Definition crypto.h:122
void setkeyaccess(pass2Key &keyholder)
Definition crypto.h:94
unsigned char * getIVbytes(size_t &IVsize)
Definition crypto.h:103
String Decrypt(unsigned char *bytes, size_t len)
Definition crypto.h:182
#define IVSIZE
Definition crypto.h:58
#define NUMBYTES
Definition crypto.h:57
#define DEBUG3
Definition delays.h:58
#define PRINTERROR2(status, function)
Definition psaerr2str.h:4
#define DUMP(t, b, l)
Definition psaerr2str.h:13