-
Notifications
You must be signed in to change notification settings - Fork 0
/
Generator.cpp
102 lines (95 loc) · 3.3 KB
/
Generator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "Generator.h"
Generator::Generator()
: generatorState(GeneratorState())
, cipherText(new uint8_t[16])
, aesPlainText(new uint8_t[N_BLOCK])
{
}
Generator::~Generator()
{
delete[] cipherText;
delete[] aesPlainText;
}
void
Generator::reseedGenerator(uint8_t* seed, uint16_t seedSize)
{
uint16_t newKeySize = seedSize + generatorState.getKeySize();
uint8_t *newKey = new uint8_t[newKeySize]; // create new key to be hashed
//K ← SHAd-256(K || s) <--- (This is stright out of Bruce Schneier and Neils Fergusons Practical Cryptography)
#if defined(ARDUINO) && ARDUINO >= 100
memcpy(newKey, generatorState.getKey(), generatorState.getKeySize());
memcpy(newKey + generatorState.getKeySize(), seed, seedSize);
#else
std::copy(generatorState.getKey(), generatorState.getKey() + generatorState.getKeySize(), newKey);
std::copy(seed, seed + seedSize, newKey + generatorState.getKeySize());
#endif
sha.init();
for (uint16_t keyIndex = 0; keyIndex < newKeySize; keyIndex++)
{
sha.write(newKey[keyIndex]);
}
uint8_t *shaResult = sha.result();
generatorState.setKey(shaResult, 32);
generatorState.addToCounter();
delete[] newKey;
}
uint8_t*
Generator::generateRandomData(uint32_t numberOfBytes, uint8_t *randomBytes)
{
/*
* This should be in generateBlocks. However, for this I have put it here otherwise
* it will harm performance with isZeroCount() being called exessive times
*/
if (generatorState.isZeroCount())
{
delete[] randomBytes;
randomBytes = NULL;
return randomBytes;
}
if (numberOfBytes >= 1 && numberOfBytes < 1048576) //1048576 = 2^20
{
uint8_t rNoB = ceil(numberOfBytes / 16.0);
uint8_t *random16kBytes = new uint8_t[rNoB * 16];
if (generateBlocks(rNoB, random16kBytes))
{
#if defined(ARDUINO) && ARDUINO >= 100
memcpy(randomBytes, random16kBytes, numberOfBytes);
#else
std::copy(random16kBytes, random16kBytes + numberOfBytes, randomBytes);
#endif
uint8_t *newKey = new uint8_t[2 * 16];
generateBlocks(2, newKey);
generatorState.setKey(newKey, 32);
delete[] newKey;
}
delete[] random16kBytes;
}
return randomBytes;
}
bool Generator::generateBlocks(uint8_t numberOfBlocks, uint8_t* pseudroRandomData)
{
// if (numberOfBlocks >= 1 && !generatorState.isZeroCount())
if (numberOfBlocks >= 1)
{
uint8_t *keyPtr = generatorState.getKey();
aes.clean();
aes.set_key(keyPtr, generatorState.getKeySize());
for (uint8_t index = 0; index < numberOfBlocks; index++)
{
uint8_t *v = generatorState.getCount();
for (uint8_t indexCounter = 0; indexCounter < MAX_COUNTER_SIZE; indexCounter++)
{
aesPlainText[indexCounter] = v[indexCounter];
}
aes.encrypt(aesPlainText, cipherText);
generatorState.addToCounter();
#if defined(ARDUINO) && ARDUINO >= 100
memcpy(pseudroRandomData + (16 * index), cipherText, 16);
#else
std::copy(cipherText, cipherText + 16, pseudroRandomData + (16 * index));
#endif
}
return 1;
}
return 0;
}