瀏覽代碼

Add encryption for the sent packet

Bernd Gottschlag 5 年之前
父節點
當前提交
1381cb6634

+ 118
- 0
weather-sensor/firmware/encryption.c 查看文件

@@ -0,0 +1,118 @@
1
+#include <stdint.h>
2
+
3
+#define LENGTH_OF_BLOCK 8
4
+
5
+void xxtea_Encrypt(uint32_t * data, uint8_t dataLength, const uint32_t key[4]);
6
+void xxtea_Decrypt(uint32_t * data, uint8_t dataLength, const uint32_t key[4]);
7
+
8
+/* The data packets are encrypted using the xxtea algorithm. */
9
+void Encrypt(uint32_t * data, uint8_t dataLength, uint64_t salt, const uint32_t key[4])
10
+{
11
+	/* This function assumes that the dataLength is a multiple of the length of the
12
+	 * salt (8)
13
+	 *
14
+	 * The data is encrypted using cipher block chaining:
15
+	 * (https://upload.wikimedia.org/wikipedia/commons/8/80/CBC_encryption.svg)
16
+	 */
17
+
18
+	uint8_t i;
19
+	uint8_t * previousCipherBlock = (uint8_t*) &salt;
20
+	uint8_t * currentPlaintextBlock = (uint8_t*) data;
21
+
22
+	for (i = 0; i < dataLength/LENGTH_OF_BLOCK; i++)
23
+	{
24
+		/* XOR of current plain text block and previous cipher block */
25
+		//for (j = 0; j < LENGTH_OF_BLOCK; j++)
26
+		//{
27
+		//	currentPlaintextBlock[j] ^= previousCipherBlock[j];
28
+		//}
29
+		*((uint64_t*) currentPlaintextBlock) ^= *((uint64_t*) previousCipherBlock);
30
+
31
+		/* Encrypt the block */
32
+		xxtea_Encrypt((uint32_t*) currentPlaintextBlock, LENGTH_OF_BLOCK, key);
33
+
34
+		/* Setup for next block */
35
+		previousCipherBlock = currentPlaintextBlock;
36
+		currentPlaintextBlock += LENGTH_OF_BLOCK;
37
+	}
38
+
39
+}
40
+
41
+
42
+void Decrypt(uint32_t * data, uint8_t dataLength, uint64_t salt, const uint32_t key[4])
43
+{
44
+	/* This function assumes that the dataLength is a multiple of the length of the
45
+	 * salt (8)
46
+	 *
47
+	 * The data is encrypted using cipher block chaining:
48
+	 * (https://upload.wikimedia.org/wikipedia/commons/2/2a/CBC_decryption.svg)
49
+	 */
50
+
51
+	/* The data is decrypted from back to front as front to back cannot be done in
52
+	 * place
53
+	 */
54
+	uint8_t i;
55
+	uint8_t * previousCipherBlock = (uint8_t*) data + dataLength - 2 * LENGTH_OF_BLOCK;
56
+	uint8_t * currentCipherBlock = (uint8_t*) data + dataLength - LENGTH_OF_BLOCK;
57
+
58
+	for (i = dataLength/LENGTH_OF_BLOCK; i > 0; i--)
59
+	{
60
+		/* Decrypt the block */
61
+		xxtea_Decrypt((uint32_t*) currentCipherBlock, LENGTH_OF_BLOCK, key);
62
+
63
+		/* XOR of the decrypted block with cipher block in front of it */
64
+		*((uint64_t*) currentCipherBlock) ^= *((uint64_t*) previousCipherBlock);
65
+
66
+		/* Setup for next block */
67
+		currentCipherBlock = previousCipherBlock;
68
+		if (previousCipherBlock != (uint8_t*) data)
69
+		{
70
+			previousCipherBlock -= LENGTH_OF_BLOCK;
71
+		}
72
+		else
73
+		{
74
+			previousCipherBlock = (uint8_t*) &salt;
75
+		}
76
+	}
77
+}
78
+
79
+void xxtea_Encrypt(uint32_t * data, uint8_t dataLength, const uint32_t key[4])
80
+{
81
+    uint32_t sum = 0, z, y, e;
82
+    uint8_t i = 6 + 52/(dataLength/4), r;
83
+    const int16_t n = dataLength / 4 - 1;
84
+
85
+    z = data[n]; // left neighbour for the first round
86
+    do {
87
+        // cycle
88
+        sum += 0x9e3779b9ul;
89
+        e = (sum >> 2) & 3;
90
+        for (r = 0; r <= n; r++) {
91
+            // round
92
+            y = data[(r+1) % (n + 1)]; // right neighbour
93
+            data[r] += ((z>>5 ^ y<<2) + (y>>3 ^ z<<4)) ^ ((sum^y) + (key[(r^e) & 3] ^ z));
94
+            z = data[r]; // left neighbour for the next round
95
+        }
96
+    } while (--i);
97
+}
98
+
99
+void xxtea_Decrypt(uint32_t * data, uint8_t dataLength, const uint32_t key[4])
100
+{
101
+    uint32_t sum, z, y, e;
102
+    int16_t i = 6 + 52/(dataLength/4), r;
103
+    const int16_t n = dataLength / 4;
104
+
105
+    sum = (uint32_t) ((uint64_t) (6 + 52/(dataLength/4)) * 0x9e3779b9ul);
106
+    y = data[0];
107
+    do {
108
+        // cycle
109
+        e = sum >> 2;
110
+        for (r = n-1; r >= 0; --r) {
111
+            // round
112
+            z = data[(r+n-1) % n];
113
+            data[r] -= ((z>>5 ^ y<<2) + (y>>3 ^ z<<4)) ^ ((sum^y) + (key[(r^e) & 3] ^ z));
114
+            y = data[r];
115
+        }
116
+        sum -= 0x9e3779b9;
117
+    } while (--i);
118
+}

+ 8
- 0
weather-sensor/firmware/encryption.h 查看文件

@@ -0,0 +1,8 @@
1
+#ifndef ENCRYPTION_H
2
+#define ENCRYPTION_H
3
+
4
+
5
+void Encrypt(uint32_t * data, uint8_t dataLength , uint64_t salt, const uint32_t key[4]);
6
+void Decrypt(uint32_t * data, uint8_t dataLength, uint64_t salt, const uint32_t key[4]);
7
+
8
+#endif

+ 15
- 3
weather-sensor/firmware/main.c 查看文件

@@ -16,10 +16,13 @@
16 16
 #include "bme280_defs.h"
17 17
 #include "pin_programming.h"
18 18
 #include "crc.h"
19
+#include "encryption.h"
19 20
 
20 21
 
21 22
 
22 23
 uint8_t ownId;
24
+const uint8_t encryptionKey[16] = {0x9e, 0x37, 0x79, 0xb9, 0x9b, 0x97, 0x73, 0xe9, 0xb9, 0x79, 0x37, 0x9e, 0x6b, 0x69, 0x51, 0x56}; /* TODO: use exernal file with the keys */
25
+uint64_t salt;
23 26
 
24 27
 char bool_case = 0;
25 28
 int timer = 0;
@@ -92,6 +95,9 @@ int main (void)
92 95
 	Initialize_BME280();
93 96
 	Set_Up_Power_Save_Mode();
94 97
 
98
+	/* Initialize the salt */
99
+	salt = 0xFFFFFFFFFFFFFFFFull;
100
+	salt &= ~ownId;
95 101
 
96 102
 	/* Delay the change of the operating frequency by the function Enter_Power_Save_Mode for the
97 103
 	 * first function pass. If it is changed before the ISP can flash the MCU the clocks of the ISP
@@ -116,8 +122,8 @@ int main (void)
116 122
 
117 123
 			memset((uint8_t*)&reportPacket, 0, sizeof(reportPacket)); //Reinitialize the buffer with zeros
118 124
 
119
-			reportPacket.senderId = ownId;
120
-			//reportPacket.salt; /* TODO */
125
+			salt &= ~(1ull<<55);
126
+			reportPacket.salt = salt;
121 127
 			reportPacket.payload.values.packetIdentifier.elementCount = 3;
122 128
 			reportPacket.payload.values.packetIdentifier.packetType = PACKET_TYPE_REPORT;
123 129
 
@@ -134,7 +140,13 @@ int main (void)
134 140
 			reportPacket.crc = crc;
135 141
 
136 142
 			/* Encrypt the packet */
137
-			/* TODO */
143
+			/* TODO: 
144
+			 * - increment the salt for every packet
145
+			 * - Receive salt from the base station
146
+			 */
147
+			Encrypt((uint32_t*) &reportPacket.payload.buffer,
148
+			        PACKET_BUFFER_LENGTH + sizeof(crc),
149
+			        salt, (uint32_t*) encryptionKey);
138 150
 
139 151
 			NRF24L01_Send_Message((uint8_t*)&reportPacket, sizeof(reportPacket));
140 152
 

+ 1
- 2
weather-sensor/firmware/nrf24l01.h 查看文件

@@ -55,8 +55,7 @@ typedef struct __attribute__((packed)) BITFIELD_PACKET_COUNT_ELEMENT
55 55
 
56 56
 typedef struct __attribute__((packed)) PACKET
57 57
 {
58
-	uint8_t senderId;
59
-	uint8_t salt[7];
58
+	uint64_t salt; /* 1 byte device id, 7 bytes remainder */
60 59
 	union {
61 60
 		struct {
62 61
 			BITFIELD_PACKET_COUNT_ELEMENT packetIdentifier;

Loading…
取消
儲存