21
21
#define MODULE_NAME "nbus"
22
22
23
23
24
+ uint8_t nbus_my_id [4 ] = {0 , 0 , 0 , 1 };
25
+ uint8_t nbus_my_ep = 0 ;
26
+ uint16_t nbus_tx_counter = 0 ;
27
+
28
+
24
29
/**
25
30
* tl;dr of the nbus2 packet format
26
31
*
50
55
*/
51
56
52
57
58
+ static void marker (uint32_t port , uint32_t pin , bool len ) {
59
+ gpio_set (port , pin );
60
+ if (len ) {
61
+ vTaskDelay (1 );
62
+ } else {
63
+ for (int i = 0 ; i < 1000 ; i ++ ) {
64
+ ;
65
+ }
66
+ }
67
+ gpio_clear (port , pin );
68
+ }
69
+
70
+
53
71
/**
54
72
* @brief Receive exact number of bytes from the input stream
55
73
*
@@ -80,6 +98,7 @@ static nbus_ret_t stream_receive_expect(Nbus *self, uint8_t *buf, size_t size) {
80
98
return NBUS_RET_TIMEOUT ;
81
99
} else {
82
100
/* Something wrong, EOF, EOT or whatever. */
101
+ u_log (system_log , LOG_TYPE_WARN , U_LOG_MODULE_PREFIX ("stream_receive_expect: no-OK %d" ), ret );
83
102
return NBUS_RET_FAILED ;
84
103
}
85
104
}
@@ -133,7 +152,7 @@ static nbus_ret_t stream_wait_for_eot(Nbus *self) {
133
152
134
153
135
154
static nbus_ret_t pbuf_receive_expect (Nbus * self , struct nbus_pbuf * pbuf , size_t len ) {
136
- if (pbuf -> buf_len + len > pbuf -> buf_size ) {
155
+ if (( pbuf -> buf_len + len ) > pbuf -> buf_size ) {
137
156
stream_wait_for_eot (self );
138
157
return NBUS_RET_FAILED ;
139
158
}
@@ -167,85 +186,108 @@ static nbus_ret_t pbuf_receive_expect(Nbus *self, struct nbus_pbuf *pbuf, size_t
167
186
* Key derivation alone is 80 us but it is done only once.
168
187
* Chacha20 decryption alone is 38 us.
169
188
*/
170
- static nbus_ret_t receive_process_header (Nbus * self , struct nbus_pbuf * pbuf ) {
171
- if (pbuf_receive_expect (self , pbuf , 24 ) != NBUS_RET_OK ) {
189
+ static nbus_ret_t nbus_pbuf_receive_header (struct nbus_pbuf * self , Nbus * nbus ) {
190
+ if (pbuf_receive_expect (nbus , self , 24 ) != NBUS_RET_OK ) {
191
+ //u_log(system_log, LOG_TYPE_WARN, U_LOG_MODULE_PREFIX("bad header recv"));
172
192
return NBUS_RET_FAILED ;
173
193
}
194
+ //u_log(system_log, LOG_TYPE_WARN, U_LOG_MODULE_PREFIX("ke = 0x%02x 0x%02x"), pbuf->ke[0], pbuf->ke[1]);
174
195
175
- /* 24 bytes received correctly. Decrypt the header (bytes 8-23)
176
- * using the derived key Ke and SIV as a nonce (bytes 0-7). */
177
- b2s_derive_keys (self -> mac_key , self -> mac_key_len , pbuf -> ke , pbuf -> km );
178
- //b2s_crypt(
179
- //pbuf->buf + 8, /* Fixed part of the header starts from byte 8, it is 16 bytes long. */
180
- //16,
181
- //pbuf->buf, /* SIV starts t the beginning, it is always 8 bytees long. */
182
- //8,
183
- //pbuf->ke
184
- //);
185
- gpio_set (GPIOA , GPIO15 );
186
- chacha20_context ctx ;
187
- chacha20_keysetup (& ctx , pbuf -> ke , 128 );
188
- chacha20_nonce (& ctx , pbuf -> buf );
189
-
190
- for (uint32_t counter = 0 ; counter < 16 ; counter ++ ) {
191
- chacha20_counter (& ctx , counter );
192
-
193
- uint8_t keystream [64 ];
194
- chacha20_keystream (& ctx , keystream );
195
- for (size_t i = 0 ; i < 16 ; i ++ ) {
196
- pbuf -> buf [i + 8 ] ^= keystream [i ];
197
- }
198
- }
199
- gpio_clear (GPIOA , GPIO15 );
200
-
201
- //u_log(system_log, LOG_TYPE_DEBUG, U_LOG_MODULE_PREFIX("decrypted magic 0x%02x 0x%02x"), pbuf->buf[8], pbuf->buf[9]);
196
+ /* Decrypt the header. */
197
+ ChaCha20 ch ;
198
+ chacha20_keysetup (& ch , self -> ke , 128 );
199
+ chacha20_nonce (& ch , self -> buf );
200
+ chacha20_encrypt (& ch , self -> buf + 8 , self -> buf + 8 , 16 );
202
201
203
202
/* Check the magic. It is right at the beginning of the fixed header. */
204
- if (pbuf -> buf [8 ] != 'n' || pbuf -> buf [9 ] != '2' ) {
203
+ if (self -> buf [8 ] != 'n' || self -> buf [9 ] != '2' ) {
204
+ u_log (system_log , LOG_TYPE_WARN , U_LOG_MODULE_PREFIX ("bac magic" ));
205
205
return NBUS_RET_FAILED ;
206
206
}
207
207
208
- memcpy (pbuf -> dstid , pbuf -> buf + 16 , 4 );
209
- memcpy (pbuf -> srcid , pbuf -> buf + 20 , 4 );
210
-
211
208
return NBUS_RET_OK ;
212
209
}
213
210
214
211
215
- static nbus_ret_t receive_process_data ( Nbus * self , struct nbus_pbuf * pbuf ) {
216
- size_t packet_len = pbuf -> buf [10 ] << 8 | pbuf -> buf [11 ];
212
+ static nbus_ret_t nbus_pbuf_receive_data ( struct nbus_pbuf * self , Nbus * nbus ) {
213
+ size_t packet_len = self -> buf [10 ] << 8 | self -> buf [11 ];
217
214
if (packet_len == 0 ) {
218
215
/* Zero length packet is valid, do not read anything. */
219
216
return NBUS_RET_OK ;
220
217
}
221
- if (pbuf_receive_expect (self , pbuf , packet_len ) != NBUS_RET_OK ) {
218
+ if (pbuf_receive_expect (nbus , self , packet_len ) != NBUS_RET_OK ) {
222
219
return NBUS_RET_FAILED ;
223
220
}
224
- //u_log(system_log, LOG_TYPE_DEBUG, U_LOG_MODULE_PREFIX("received packet data len %u"), packet_len);
225
221
222
+ //u_log(system_log, LOG_TYPE_DEBUG, U_LOG_MODULE_PREFIX("received packet data len %u"), packet_len);
223
+ //u_log(system_log, LOG_TYPE_WARN, U_LOG_MODULE_PREFIX("data 0x%02x, 0x%02x, 0x%02x, 0x%02x"), pbuf->buf[24], pbuf->buf[25], pbuf->buf[26], pbuf->buf[27]);
226
224
227
- /* Decrypt data only, headers are already decrypted. It is not possible yet, so do a workaround
228
- * (encrypt header back, decrypt as a whole). */
229
- /** @todo This decryption takes 2.16 ms for a 1024 byte packet */
230
- b2s_crypt (pbuf -> buf + 8 , 16 , pbuf -> buf , 8 , pbuf -> ke );
231
- b2s_crypt (pbuf -> buf + 8 , pbuf -> buf_len - 8 , pbuf -> buf , 8 , pbuf -> ke );
232
- /** @todo The same decryption using chacha20 should be around 680 us
233
- * and 570 us when XORing 32 bits at once. */
225
+ /* Decrypt data only, headers are already decrypted. */
226
+ ChaCha20 ch ;
227
+ chacha20_keysetup (& ch , self -> ke , 128 );
228
+ chacha20_nonce (& ch , self -> buf );
229
+ /* Consume first counter. */
230
+ uint8_t foo [8 ] = {0 };
231
+ chacha20_encrypt (& ch , foo , foo , sizeof (foo ));
232
+ chacha20_encrypt (& ch , self -> buf + 24 , self -> buf + 24 , packet_len );
234
233
235
234
/* Compute MAC from header and data. Compare with the SIV from the message. */
236
- /** @todo MAC computation takes 440 us for a 1024 byte packet (blake2s) */
237
- //uint8_t mac[BLAKE2S_OUTBYTES];
238
- //b2s_siv(pbuf->buf + 8, pbuf->buf_len - 8, mac, sizeof(mac), pbuf->km);
239
- /** @todo MAC computation takes 59 us for a 1024 byte packet (halfsiphash) */
240
235
uint8_t mac [8 ];
241
- halfsiphash (pbuf -> buf + 8 , pbuf -> buf_len - 8 , pbuf -> km , mac , sizeof (mac ));
236
+ halfsiphash (self -> buf + 8 , self -> buf_len - 8 , self -> km , mac , sizeof (mac ));
237
+
238
+ if (memcmp (self -> buf , mac , 8 )) {
239
+ //syslog(LOG_ERR, "pbuf: receive data bad MAC");
240
+ return NBUS_RET_FAILED ;
241
+ }
242
+
243
+ return NBUS_RET_OK ;
244
+ }
245
+
242
246
243
- if (memcmp (pbuf -> buf , mac , 8 )) {
244
- //u_log(system_log, LOG_TYPE_WARN, U_LOG_MODULE_PREFIX("bad MAC 0x%02x 0x%02x != 0x%02x 0x%02x"), pbuf->buf[0], pbuf->buf[1], mac[0], mac[1]);
247
+ static nbus_ret_t nbus_pbuf_send (struct nbus_pbuf * self , void * buf , size_t len , uint8_t dst_id [4 ], uint8_t dst_ep ) {
248
+ if ((len + 24 ) > self -> buf_size ) {
249
+ return NBUS_RET_FAILED ;
250
+ }
251
+ memcpy (self -> buf + 24 , buf , len );
252
+ self -> buf_len = len + 24 ;
253
+
254
+ self -> buf [8 ] = 'n' ;
255
+ self -> buf [9 ] = '2' ;
256
+
257
+ self -> buf [10 ] = len / 256 ;
258
+ self -> buf [11 ] = len % 256 ;
259
+
260
+ self -> buf [12 ] = nbus_tx_counter / 256 ;
261
+ self -> buf [13 ] = nbus_tx_counter % 256 ;
262
+ nbus_tx_counter ++ ;
263
+
264
+ /* Set IDs and endpoints. */
265
+ self -> buf [14 ] = (dst_ep & 0xf ) << 4 | (nbus_my_ep & 0xf );
266
+ self -> buf [15 ] = 0 ;
267
+ memcpy (self -> buf + 16 , dst_id , 4 );
268
+ memcpy (self -> buf + 20 , nbus_my_id , 4 );
269
+
270
+ return NBUS_RET_OK ;
271
+ }
272
+
273
+
274
+ static nbus_ret_t nbus_pbuf_transmit (struct nbus_pbuf * self , Nbus * nbus ) {
275
+
276
+ /* Compute SIV first */
277
+ halfsiphash (self -> buf + 8 , self -> buf_len - 8 , self -> km , self -> buf , 8 );
278
+
279
+ ChaCha20 ch ;
280
+ chacha20_keysetup (& ch , self -> ke , 128 );
281
+ chacha20_nonce (& ch , self -> buf );
282
+ /* Encrypt the header first. */
283
+ chacha20_encrypt (& ch , self -> buf + 8 , self -> buf + 8 , 16 );
284
+ /* Counter is incremented, the rest of the input is kept. Encrypt the data. */
285
+ chacha20_encrypt (& ch , self -> buf + 24 , self -> buf + 24 , self -> buf_len - 24 );
286
+
287
+ if (nbus -> stream -> vmt -> write (nbus -> stream , self -> buf , self -> buf_len ) != STREAM_RET_OK ) {
245
288
return NBUS_RET_FAILED ;
246
289
}
247
290
248
- //b2s_crypt(pbuf->data, pbuf->len, pbuf->siv, 8, self->ke);
249
291
return NBUS_RET_OK ;
250
292
}
251
293
@@ -254,6 +296,7 @@ static void addr_to_str(uint8_t addr[4], char *s, size_t size) {
254
296
snprintf (s , size , "0x%02x%02x%02x%02x" , addr [0 ], addr [1 ], addr [2 ], addr [3 ]);
255
297
}
256
298
299
+ /*
257
300
static void print_pbuf(Nbus *self, struct nbus_pbuf *pbuf, const char *prefix) {
258
301
(void)self;
259
302
@@ -264,7 +307,7 @@ static void print_pbuf(Nbus *self, struct nbus_pbuf *pbuf, const char *prefix) {
264
307
265
308
u_log(system_log, LOG_TYPE_DEBUG, U_LOG_MODULE_PREFIX("%s%s -> %s, len %u, 0x%02x 0x%02x"), prefix, srcid, dstid, pbuf->buf_len, pbuf->buf[24], pbuf->buf[25]);
266
309
}
267
-
310
+ */
268
311
269
312
static void nbus_mac_task (void * p ) {
270
313
Nbus * self = (Nbus * )p ;
@@ -274,40 +317,57 @@ static void nbus_mac_task(void *p) {
274
317
if (pbuf == NULL ) {
275
318
/* Cannot allocate a buffer, we must drop the packet. Wait at least for EOT. */
276
319
stream_wait_for_eot (self );
320
+ u_log (system_log , LOG_TYPE_WARN , U_LOG_MODULE_PREFIX ("buffer allocation error" ));
277
321
goto err ;
278
322
}
279
- if (receive_process_header (self , pbuf ) != NBUS_RET_OK ) {
323
+
324
+ if (nbus_pbuf_receive_header (pbuf , self ) != NBUS_RET_OK ) {
280
325
stream_wait_for_eot (self );
326
+ u_log (system_log , LOG_TYPE_WARN , U_LOG_MODULE_PREFIX ("packet header reception error" ));
281
327
goto err ;
282
328
}
329
+ /* After first 24 bytes */
330
+ marker (GPIOE , GPIO11 , false);
283
331
284
- if (receive_process_data (self , pbuf ) != NBUS_RET_OK ) {
332
+ if (nbus_pbuf_receive_data (pbuf , self ) != NBUS_RET_OK ) {
333
+ u_log (system_log , LOG_TYPE_WARN , U_LOG_MODULE_PREFIX ("packet data reception error" ));
285
334
goto err ;
286
335
}
287
-
288
336
//print_pbuf(self, pbuf, "received ");
289
337
290
-
291
-
292
338
/* End of packet. No additional data should be in the receive buffer. Check for EOT now
293
339
* before a new packet reception starts. */
294
340
if (stream_eot_expect (self ) != NBUS_RET_OK ) {
295
341
/* No EOT, additional data received, wait for one. */
296
342
stream_wait_for_eot (self );
343
+ //goto err;
297
344
}
298
345
299
- self -> stream -> vmt -> write (self -> stream , "\x00\x55\x00\x55\x00\x55\x00\x55" , 8 );
346
+ //self->stream->vmt->write(self->stream, pbuf->buf, pbuf->buf_len);
347
+ nbus_pbuf_release (self , pbuf );
348
+
349
+ struct nbus_pbuf * txp = nbus_pbuf_allocate (self );
350
+ uint8_t txbuf [256 ] = {0 };
351
+ uint8_t dstid [4 ] = {0 , 0 , 0 , 1 };
352
+ nbus_pbuf_send (txp , txbuf , sizeof (txbuf ), dstid , 1 );
353
+ nbus_pbuf_transmit (txp , self );
354
+ nbus_pbuf_release (self , txp );
355
+ /* Consume echo until EOT. */
356
+ stream_wait_for_eot (self );
357
+
358
+ continue ;
300
359
301
360
err :
302
361
nbus_pbuf_release (self , pbuf );
303
-
362
+ marker ( GPIOE , GPIO10 , false);
304
363
}
305
364
vTaskDelete (NULL );
306
365
}
307
366
308
367
309
368
static void nbus_hk_task (void * p ) {
310
369
Nbus * self = (Nbus * )p ;
370
+ (void )self ;
311
371
312
372
while (true) {
313
373
vTaskDelay (1000 );
@@ -363,6 +423,12 @@ struct nbus_pbuf *nbus_pbuf_allocate(Nbus *self) {
363
423
if (self -> pbufs [i ].used == false) {
364
424
self -> pbufs [i ].used = true;
365
425
self -> pbufs [i ].buf_len = 0 ;
426
+ self -> pbufs [i ].buf_size = NBUS_PBUF_DATA_SIZE ;
427
+ memset (self -> pbufs [i ].buf , 0 , 24 );
428
+
429
+ /* Prepare keys for the new pbuf */
430
+ b2s_derive_keys (self -> mac_key , self -> mac_key_len , self -> pbufs [i ].ke , self -> pbufs [i ].km );
431
+
366
432
return & (self -> pbufs [i ]);
367
433
}
368
434
}
0 commit comments