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
68 #if PERIODIC_TELEMETRY
73 pprz_msg_send_SECURE_LINK_STATUS(trans, dev, AC_ID,
91 #if PPRZLINK_DEFAULT_VER == 2
92 void gec_encapsulate_and_send_msg(
struct pprzlink_msg *
msg,
long fd);
105 static void put_bytes(
struct pprzlink_msg *msg,
long fd __attribute__((unused)),
106 enum TransportDataType type __attribute__((unused)),
107 enum TransportDataFormat format __attribute__((unused)),
const void *bytes,
112 for (i = 0; i < len; i++) {
117 static void put_named_byte(
struct pprzlink_msg *msg,
118 long fd __attribute__((unused)),
119 enum TransportDataType type __attribute__((unused)),
120 enum TransportDataFormat format __attribute__((unused)),
uint8_t byte,
121 const char *name __attribute__((unused)))
133 + get_trans(msg)->pprz_tp.trans_tx.size_of(msg, len);
139 static void start_message(
struct pprzlink_msg *msg,
140 long fd __attribute__((unused)),
141 uint8_t payload_len __attribute__((unused)))
144 memset(get_trans(msg)->
tx_msg, _FD, TRANSPORT_PAYLOAD_LEN);
145 get_trans(msg)->tx_msg_idx = 0;
151 static void overrun(
struct pprzlink_msg *msg)
153 get_trans(msg)->pprz_tp.trans_tx.overrun(msg);
159 static void count_bytes(
struct pprzlink_msg *msg,
uint8_t bytes)
161 get_trans(msg)->pprz_tp.trans_tx.count_bytes(msg, bytes);
173 static int check_available_space(
struct pprzlink_msg *msg,
long *
fd,
177 return get_trans(msg)->pprz_tp.trans_tx.check_available_space(msg, fd,
190 static void end_message(
struct pprzlink_msg *msg,
long fd)
195 gec_encapsulate_and_send_msg(msg, fd);
211 void gec_encapsulate_and_send_msg(
struct pprzlink_msg *msg,
long fd)
213 get_trans(msg)->pprz_tp.trans_tx.start_message(msg, fd,
215 get_trans(msg)->pprz_tp.trans_tx.put_bytes(msg, _FD, DL_TYPE_UINT8,
217 get_trans(msg)->pprz_tp.trans_tx.end_message(msg, fd);
221 #if PPRZLINK_DEFAULT_VER == 1
222 void gec_encapsulate_and_send_msg(
struct gec_transport *trans,
223 struct link_device *
dev,
long fd);
226 struct link_device *
dev __attribute__((unused)),
227 long fd __attribute__((unused)),
228 enum TransportDataType type __attribute__((unused)),
229 enum TransportDataFormat format __attribute__((unused)),
const void *bytes,
234 for (i = 0; i < len; i++) {
240 struct link_device *
dev __attribute__((unused)),
241 long fd __attribute__((unused)),
242 enum TransportDataType type __attribute__((unused)),
243 enum TransportDataFormat format __attribute__((unused)),
uint8_t byte,
244 const char *name __attribute__((unused)))
256 struct link_device *
dev __attribute__((unused)),
257 long fd __attribute__((unused)),
258 uint8_t payload_len __attribute__((unused)))
261 memset(trans->
tx_msg, _FD, TRANSPORT_PAYLOAD_LEN);
265 static void end_message(
struct gec_transport *trans,
struct link_device *
dev,
271 gec_encapsulate_and_send_msg(trans, dev, fd);
282 void gec_encapsulate_and_send_msg(
struct gec_transport *trans,
283 struct link_device *dev,
long fd)
286 trans->
pprz_tp.trans_tx.put_bytes(trans, dev, _FD, DL_TYPE_UINT8,
288 trans->
pprz_tp.trans_tx.end_message(trans, dev, fd);
291 static void overrun(
struct gec_transport *trans __attribute__((unused)),
292 struct link_device *dev)
294 trans->
pprz_tp.trans_tx.overrun(trans, dev);
297 static void count_bytes(
struct gec_transport *trans __attribute__((unused)),
298 struct link_device *dev,
uint8_t bytes)
300 trans->
pprz_tp.trans_tx.count_bytes(trans, dev, bytes);
303 static int check_available_space(
305 struct link_device *dev,
long *fd,
uint16_t bytes)
308 return trans->
pprz_tp.trans_tx.check_available_space(trans, dev, fd, bytes);
312 #endif // PPRZLINK_DEFAULT_VER == 1
313 #endif // PPRZLINK_DEFAULT_VER == 2
319 t->
trans_tx.size_of = (size_of_t) size_of;
321 (check_available_space_t) check_available_space;
322 t->
trans_tx.put_bytes = (put_bytes_t) put_bytes;
323 t->
trans_tx.put_named_byte = (put_named_byte_t) put_named_byte;
324 t->
trans_tx.start_message = (start_message_t) start_message;
325 t->
trans_tx.end_message = (end_message_t) end_message;
326 t->
trans_tx.overrun = (overrun_t) overrun;
327 t->
trans_tx.count_bytes = (count_bytes_t) count_bytes;
338 #ifdef GEC_STATUS_LED
351 #if PERIODIC_TELEMETRY
365 if (*payload_len <= PPRZ_MSG_ID) {
383 memcpy(auth, buf, PPRZ_AUTH_LEN);
386 uint32_t mlen = *payload_len - PPRZ_AUTH_LEN;
388 uint32_t res = Hacl_Chacha20Poly1305_aead_encrypt(ciphertext, tag,
389 &buf[PPRZ_AUTH_LEN], mlen, auth,
393 memset(buf, 0, TRANSPORT_PAYLOAD_LEN);
400 *payload_len += PPRZ_AUTH_LEN;
401 memcpy(&buf[PPRZ_CIPH_IDX], ciphertext, mlen);
402 *payload_len += mlen;
426 if (*payload_len < PPRZ_PLAINTEXT_MSG_MIN_LEN) {
431 buf[PPRZ_PLAINTEXT_MSG_ID_IDX])) {
433 memmove(buf, &buf[1], *payload_len - 1);
440 if (*payload_len < PPRZ_ENCRYPTED_MSG_MIN_LEN) {
465 memcpy(ciphertext, &buf[PPRZ_CIPH_IDX], mlen);
469 uint32_t res = Hacl_Chacha20Poly1305_aead_decrypt(plaintext, ciphertext,
476 memset(buf, 0, TRANSPORT_PAYLOAD_LEN);
478 memcpy(buf, auth, PPRZ_AUTH_LEN);
479 *payload_len += PPRZ_AUTH_LEN;
480 memcpy(&buf[PPRZ_AUTH_LEN], plaintext, mlen);
481 *payload_len += mlen;
564 #ifdef GEC_STATUS_LED
590 if (SenderIdOfPprzMsg(buf) != 0) {
597 if (IdOfPprzMsg(buf) != DL_KEY_EXCHANGE_GCS) {
603 if (DL_KEY_EXCHANGE_GCS_msg_type(buf) !=
P_AE) {
609 if (DL_KEY_EXCHANGE_GCS_msg_data_length(buf) !=
PPRZ_KEY_LEN) {
616 DL_KEY_EXCHANGE_GCS_msg_data(buf),
sizeof(
struct gec_pubkey));
646 if (Hacl_Chacha20Poly1305_aead_encrypt(&msg_data[PPRZ_KEY_LEN],
653 #if PPRZLINK_DEFAULT_VER == 2
679 struct pprzlink_msg msg2;
683 gec_encapsulate_and_send_msg(&msg2, 0);
685 #if PPRZLINK_DEFAULT_VER ==1
707 #endif // PPRZLINK 1.0
708 #endif // PPRZLINK 2.0
737 if (SenderIdOfPprzMsg(buf) != 0) {
744 if (IdOfPprzMsg(buf) != DL_KEY_EXCHANGE_GCS) {
750 if (DL_KEY_EXCHANGE_GCS_msg_type(buf) !=
SIG) {
756 if (DL_KEY_EXCHANGE_GCS_msg_data_length(buf)
764 if (Hacl_Chacha20Poly1305_aead_decrypt(sign,
765 DL_KEY_EXCHANGE_GCS_msg_data(buf),
799 whitelist->
init =
true;
807 if (whitelist->
init) {
808 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
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]
static void DlCheckAndParse(struct link_device *dev, struct transport_tx *trans, uint8_t *buf, bool *msg_available)
Check for new message and parse.
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...