29 #include "pprzlink/messages.h"
32 #if PPRZLINK_DEFAULT_VER == 2
36 #define PPRZ_PLAINTEXT_MSG_ID_IDX 4
38 #define PPRZ_PLAINTEXT_MSG_MIN_LEN 5
40 #define PPRZ_ENCRYPTED_MSG_MIN_LEN 25
42 #define PPRZ_AUTH_LEN 2
44 #define PPRZ_CIPH_IDX 7
46 #if PPRZLINK_DEFAULT_VER == 1
50 #define PPRZ_PLAINTEXT_MSG_ID_IDX 2
52 #define PPRZ_PLAINTEXT_MSG_MIN_LEN 3
54 #define PPRZ_ENCRYPTED_MSG_MIN_LEN 23
56 #define PPRZ_AUTH_LEN 1
58 #define PPRZ_CIPH_IDX 6
59 #endif // PPRZLINK_DEFAULT_VER = 1
60 #endif // PPRZLINK_DEFAULT_VER = 2
67 #define GEC_UPDATE_DL TRUE
72 #if PERIODIC_TELEMETRY
77 pprz_msg_send_SECURE_LINK_STATUS(trans, dev, AC_ID,
95 #if PPRZLINK_DEFAULT_VER == 2
96 void gec_encapsulate_and_send_msg(
struct pprzlink_msg *
msg,
long fd);
109 static void put_bytes(
struct pprzlink_msg *msg,
long fd __attribute__((unused)),
110 enum TransportDataType type __attribute__((unused)),
111 enum TransportDataFormat format __attribute__((unused)),
const void *bytes,
116 for (i = 0; i < len; i++) {
121 static void put_named_byte(
struct pprzlink_msg *msg,
122 long fd __attribute__((unused)),
123 enum TransportDataType type __attribute__((unused)),
124 enum TransportDataFormat format __attribute__((unused)),
uint8_t byte,
125 const char *name __attribute__((unused)))
137 + get_trans(msg)->pprz_tp.trans_tx.size_of(msg, len);
143 static void start_message(
struct pprzlink_msg *msg,
144 long fd __attribute__((unused)),
145 uint8_t payload_len __attribute__((unused)))
148 memset(get_trans(msg)->
tx_msg, _FD, TRANSPORT_PAYLOAD_LEN);
149 get_trans(msg)->tx_msg_idx = 0;
155 static void overrun(
struct pprzlink_msg *msg)
157 get_trans(msg)->pprz_tp.trans_tx.overrun(msg);
163 static void count_bytes(
struct pprzlink_msg *msg,
uint8_t bytes)
165 get_trans(msg)->pprz_tp.trans_tx.count_bytes(msg, bytes);
177 static int check_available_space(
struct pprzlink_msg *msg,
long *
fd,
181 return get_trans(msg)->pprz_tp.trans_tx.check_available_space(msg, fd,
194 static void end_message(
struct pprzlink_msg *msg,
long fd)
199 gec_encapsulate_and_send_msg(msg, fd);
215 void gec_encapsulate_and_send_msg(
struct pprzlink_msg *msg,
long fd)
217 get_trans(msg)->pprz_tp.trans_tx.start_message(msg, fd,
219 get_trans(msg)->pprz_tp.trans_tx.put_bytes(msg, _FD, DL_TYPE_UINT8,
221 get_trans(msg)->pprz_tp.trans_tx.end_message(msg, fd);
225 #if PPRZLINK_DEFAULT_VER == 1
226 void gec_encapsulate_and_send_msg(
struct gec_transport *trans,
227 struct link_device *
dev,
long fd);
230 struct link_device *
dev __attribute__((unused)),
231 long fd __attribute__((unused)),
232 enum TransportDataType type __attribute__((unused)),
233 enum TransportDataFormat format __attribute__((unused)),
const void *bytes,
238 for (i = 0; i < len; i++) {
244 struct link_device *
dev __attribute__((unused)),
245 long fd __attribute__((unused)),
246 enum TransportDataType type __attribute__((unused)),
247 enum TransportDataFormat format __attribute__((unused)),
uint8_t byte,
248 const char *name __attribute__((unused)))
260 struct link_device *
dev __attribute__((unused)),
261 long fd __attribute__((unused)),
262 uint8_t payload_len __attribute__((unused)))
265 memset(trans->
tx_msg, _FD, TRANSPORT_PAYLOAD_LEN);
269 static void end_message(
struct gec_transport *trans,
struct link_device *
dev,
275 gec_encapsulate_and_send_msg(trans, dev, fd);
286 void gec_encapsulate_and_send_msg(
struct gec_transport *trans,
287 struct link_device *dev,
long fd)
290 trans->
pprz_tp.trans_tx.put_bytes(trans, dev, _FD, DL_TYPE_UINT8,
292 trans->
pprz_tp.trans_tx.end_message(trans, dev, fd);
295 static void overrun(
struct gec_transport *trans __attribute__((unused)),
296 struct link_device *dev)
298 trans->
pprz_tp.trans_tx.overrun(trans, dev);
301 static void count_bytes(
struct gec_transport *trans __attribute__((unused)),
302 struct link_device *dev,
uint8_t bytes)
304 trans->
pprz_tp.trans_tx.count_bytes(trans, dev, bytes);
307 static int check_available_space(
309 struct link_device *dev,
long *fd,
uint16_t bytes)
312 return trans->
pprz_tp.trans_tx.check_available_space(trans, dev, fd, bytes);
316 #endif // PPRZLINK_DEFAULT_VER == 1
317 #endif // PPRZLINK_DEFAULT_VER == 2
323 t->
trans_tx.size_of = (size_of_t) size_of;
325 (check_available_space_t) check_available_space;
326 t->
trans_tx.put_bytes = (put_bytes_t) put_bytes;
327 t->
trans_tx.put_named_byte = (put_named_byte_t) put_named_byte;
328 t->
trans_tx.start_message = (start_message_t) start_message;
329 t->
trans_tx.end_message = (end_message_t) end_message;
330 t->
trans_tx.overrun = (overrun_t) overrun;
331 t->
trans_tx.count_bytes = (count_bytes_t) count_bytes;
342 #ifdef GEC_STATUS_LED
355 #if PERIODIC_TELEMETRY
369 if (*payload_len <= PPRZ_MSG_ID) {
387 memcpy(auth, buf, PPRZ_AUTH_LEN);
390 uint32_t mlen = *payload_len - PPRZ_AUTH_LEN;
392 uint32_t res = Hacl_Chacha20Poly1305_aead_encrypt(ciphertext, tag,
393 &buf[PPRZ_AUTH_LEN], mlen, auth,
397 memset(buf, 0, TRANSPORT_PAYLOAD_LEN);
404 *payload_len += PPRZ_AUTH_LEN;
405 memcpy(&buf[PPRZ_CIPH_IDX], ciphertext, mlen);
406 *payload_len += mlen;
430 if (*payload_len < PPRZ_PLAINTEXT_MSG_MIN_LEN) {
435 buf[PPRZ_PLAINTEXT_MSG_ID_IDX])) {
437 memmove(buf, &buf[1], *payload_len - 1);
444 if (*payload_len < PPRZ_ENCRYPTED_MSG_MIN_LEN) {
469 memcpy(ciphertext, &buf[PPRZ_CIPH_IDX], mlen);
473 uint32_t res = Hacl_Chacha20Poly1305_aead_decrypt(plaintext, ciphertext,
480 memset(buf, 0, TRANSPORT_PAYLOAD_LEN);
482 memcpy(buf, auth, PPRZ_AUTH_LEN);
483 *payload_len += PPRZ_AUTH_LEN;
484 memcpy(&buf[PPRZ_AUTH_LEN], plaintext, mlen);
485 *payload_len += mlen;
568 #ifdef GEC_STATUS_LED
594 if (SenderIdOfPprzMsg(buf) != 0) {
601 if (IdOfPprzMsg(buf) != DL_KEY_EXCHANGE_GCS) {
607 if (DL_KEY_EXCHANGE_GCS_msg_type(buf) !=
P_AE) {
613 if (DL_KEY_EXCHANGE_GCS_msg_data_length(buf) !=
PPRZ_KEY_LEN) {
620 DL_KEY_EXCHANGE_GCS_msg_data(buf),
sizeof(
struct gec_pubkey));
650 if (Hacl_Chacha20Poly1305_aead_encrypt(&msg_data[PPRZ_KEY_LEN],
657 #if PPRZLINK_DEFAULT_VER == 2
683 struct pprzlink_msg msg2;
687 gec_encapsulate_and_send_msg(&msg2, 0);
689 #if PPRZLINK_DEFAULT_VER ==1
711 #endif // PPRZLINK 1.0
712 #endif // PPRZLINK 2.0
741 if (SenderIdOfPprzMsg(buf) != 0) {
748 if (IdOfPprzMsg(buf) != DL_KEY_EXCHANGE_GCS) {
754 if (DL_KEY_EXCHANGE_GCS_msg_type(buf) !=
SIG) {
760 if (DL_KEY_EXCHANGE_GCS_msg_data_length(buf)
768 if (Hacl_Chacha20Poly1305_aead_decrypt(sign,
769 DL_KEY_EXCHANGE_GCS_msg_data(buf),
803 whitelist->
init =
true;
811 if (whitelist->
init) {
812 for (
uint8_t i = 0; i < whitelist->
idx; i++) {
#define KEY_EXCHANGE_MSG_ID_UAV
uint8_t key[PPRZ_KEY_LEN]
bool gec_is_in_the_whitelist(struct gec_whitelist *whitelist, uint8_t id)
Periodic telemetry system header (includes downlink utility and generated code).
uint8_t pub[PPRZ_KEY_LEN]
struct gec_privkey my_private_ephemeral
void gec_dl_init(void)
Init function.
Handling of messages coming from ground and other A/Cs.
#define PPRZ_MUTEX_LOCK(_mtx)
Galois embedded crypto implementation.
struct gec_pubkey their_public_key
void gec_derive_key_material(struct gec_sts_ctx *ctx, uint8_t *z)
Derive key material for both sender and receiver.
void gec_add_to_whitelist(struct gec_whitelist *whitelist, uint8_t id)
static void send_secure_link_info(struct transport_tx *trans, struct link_device *dev)
struct transport_tx trans_tx
#define PPRZ_CRYPTO_OVERHEAD
uint32_t gec_bytes_to_counter(uint8_t *bytes)
Convert from network byte order (big endian) to the machine byte order.
struct gec_transport gec_tp
PPRZ transport structure.
struct gec_sym_key rx_sym_key
uint8_t pub[PPRZ_KEY_LEN]
struct gec_pubkey their_public_ephemeral
bool gec_encrypt_message(uint8_t *buf, uint8_t *payload_len)
Attempts message encryption Adds crypto_byte, counter and tag Returns encrypted pprzlink message (cry...
#define DefaultPeriodic
Set default periodic telemetry.
void gec_sts_init(struct gec_sts_ctx *sts)
struct gec_whitelist whitelist
bool gec_decrypt_message(uint8_t *buf, volatile uint8_t *payload_len)
Attemp message decryption If a message is unencrypted, pass it through only if the MSG_ID is in the w...
struct pprz_transport pprz_tp
uint8_t tx_msg[TRANSPORT_PAYLOAD_LEN]
#define PPRZ_MUTEX_INIT(_mtx)
void gec_transport_init(struct gec_transport *t)
Whitelist for sending and receiving unencrypted messages (mostly for KEY_EXCHANGE messages) ...
uint8_t whitelist[WHITELIST_LEN]
#define PPRZ_MSG_TYPE_PLAINTEXT
static const struct usb_device_descriptor dev
static void DlCheckAndParse(struct link_device *dev, struct transport_tx *trans, uint8_t *buf, bool *msg_available, bool update_dl)
Check for new message and parse.
bool gec_process_msg3(uint8_t *buf)
Process incoming message (expected MSG3) if the right (KEY_EXCHANGE) message received with the right ...
struct gec_sym_key tx_sym_key
void gec_process_msg1(uint8_t *buf)
NOTE: for RESPONDER party only Process incoming message (expected MSG1) if the right (KEY_EXCHANGE) m...
uint8_t nonce[PPRZ_NONCE_LEN]
static void insert_byte(struct gec_transport *t, const uint8_t byte)
Simply insert byte to the message buffer.
#define PPRZ_MSG_TYPE_ENCRYPTED
#define KEY_EXCHANGE_MSG_ID_GCS
uint8_t dl_buffer[MSG_SIZE]
void gec_generate_ephemeral_keys(struct gec_privkey *sk)
Generate private and public key pairs for future use.
arch independent LED (Light Emitting Diodes) API
#define DatalinkFillDlBuffer(_buf, _len)
Convenience macro to fill dl_buffer.
void gec_counter_to_bytes(uint32_t n, uint8_t *bytes)
Convert counter to bytes in network byte order.
uint8_t priv[PPRZ_KEY_LEN]
struct transport_rx trans_rx
uint8_t msg[10]
Buffer used for general comunication over SPI (out buffer)
Datalink using Galois Embedded Crypto.
#define PPRZ_MUTEX_UNLOCK(_mtx)
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
struct gec_privkey my_private_key
void gec_dl_event(void)
Parse incoming message bytes (PPRZ_STX..CHCKSUM B) and returns a new decrypted message if it is avail...