Paparazzi UAS  v5.18.0_stable
Paparazzi is a free software Unmanned Aircraft System.
gec.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Michal Podhradsky <mpodhradsky@galois.com>
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
28 
29 #if defined(__linux__) || defined(__CYGWIN__)
30 #include <arpa/inet.h>
31 #endif
32 
33 void gec_sts_init(struct gec_sts_ctx *sts)
34 {
35  // reset all keys
36  gec_clear_sts(sts);
37 
38  // load their public key
39  uint8_t theirPublicKey[PPRZ_KEY_LEN] = GCS_PUBLIC;
40  memcpy(&sts->their_public_key, theirPublicKey, PPRZ_KEY_LEN);
41  sts->their_public_key.ready = true;
42 
43  // load my private key
44  uint8_t myPublicKey[PPRZ_KEY_LEN] = UAV_PUBLIC;
45  memcpy(&sts->my_private_key.pub, myPublicKey, PPRZ_KEY_LEN);
46  uint8_t myPrivateKey[PPRZ_KEY_LEN] = UAV_PRIVATE;
47  memcpy(&sts->my_private_key.priv, myPrivateKey, PPRZ_KEY_LEN);
48  sts->my_private_key.ready = true;
49 
50  // generate ephemeral key
52 }
53 
54 void gec_clear_sts(struct gec_sts_ctx *sts)
55 {
56  memset(&sts->their_public_ephemeral, 0, sizeof(struct gec_pubkey));
57  sts->their_public_ephemeral.ready = false;
58  memset(&sts->my_private_ephemeral, 0, sizeof(struct gec_privkey));
59  sts->my_private_ephemeral.ready = false;
60  memset(&sts->rx_sym_key, 0, sizeof(struct gec_sym_key));
61  sts->rx_sym_key.ready = false;
62  memset(&sts->tx_sym_key, 0, sizeof(struct gec_sym_key));
63  sts->tx_sym_key.ready = false;
64 
66  sts->party = RESPONDER;
67  sts->last_error = ERROR_NONE;
68 }
69 
74 {
75  for (uint16_t i = 0; i < PPRZ_KEY_LEN; i += sizeof(uint32_t)) {
76  uint32_t tmp = rng_wait_and_get();
77  sk->priv[i] = (uint8_t) tmp;
78  sk->priv[i + 1] = (uint8_t)(tmp >> 8);
79  sk->priv[i + 2] = (uint8_t)(tmp >> 16);
80  sk->priv[i + 3] = (uint8_t)(tmp >> 24);
81  }
82  uint8_t basepoint[32] = { 0 };
83  basepoint[0] = 9; // default basepoint
84  Hacl_Curve25519_crypto_scalarmult(sk->pub, sk->priv, basepoint);
85  sk->ready = true;
86 }
87 
92 {
93  uint8_t tmp[PPRZ_KEY_LEN * 2] = { 0 };
94  uint8_t input[PPRZ_KEY_LEN + 1] = { 0 };
95 
96  // Ka|| Sa = kdf(z,0)
97  memcpy(input, z, PPRZ_KEY_LEN);
98  input[PPRZ_KEY_LEN] = 0;
99  Hacl_SHA2_512_hash(tmp, input, sizeof(input));
100  memcpy(ctx->rx_sym_key.key, tmp, PPRZ_KEY_LEN); // K_a
101  memcpy(ctx->rx_sym_key.nonce, &tmp[PPRZ_KEY_LEN], PPRZ_NONCE_LEN); // S_a
102  ctx->rx_sym_key.counter = 0;
103  ctx->rx_sym_key.ready = true;
104 
105  // Kb|| Sb = kdf(z,1)
106  input[PPRZ_KEY_LEN] = 1;
107  Hacl_SHA2_512_hash(tmp, input, sizeof(input));
108  memcpy(ctx->tx_sym_key.key, tmp, PPRZ_KEY_LEN); // K_b
109  memcpy(ctx->tx_sym_key.nonce, &tmp[PPRZ_KEY_LEN], PPRZ_NONCE_LEN); // S_b
110  ctx->tx_sym_key.counter = 0;
111  ctx->tx_sym_key.ready = true;
112 }
113 
118 {
119  // assume big endian
120  uint32_t x = (bytes[3] << 24) + (bytes[2] << 16) + (bytes[1] << 8) + bytes[0];
121  // now check the appropriate endiannes
122  /* ... for Linux */
123 #if defined(__linux__) || defined(__CYGWIN__)
124  return ntohl(x);
125  /* ... generic big-endian fallback code */
126 #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
127  // the byte order is the same as for network
128  return x;
129  /* ... generic little-endian fallback code */
130 #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
131  // do a byte swap
132  return htobe32(x);
133  /* ... couldn't determine endian-ness of the target platform */
134 #else
135 #pragma message "Please define __BYTE_ORDER__!"
136 #endif /* defined(__linux__) || ... */
137 }
138 
143 {
144  //first account for appropriate endiannes
145  /* ... for Linux */
146 #if defined(__linux__) || defined(__CYGWIN__)
147  n = htonl(n);
148  /* ... generic big-endian fallback code */
149 #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
150  // the byte order is the same as for network
151  // do nothing
152  /* ... generic little-endian fallback code */
153 #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
154  // do a byte swap
155  n = htobe32(n);
156  /* ... couldn't determine endian-ness of the target platform */
157 #else
158 #pragma message "Error: Please define __BYTE_ORDER__!"
159 #endif /* defined(__linux__) || ... */
160 
161  bytes[3] = (n >> 24) & 0xFF;
162  bytes[2] = (n >> 16) & 0xFF;
163  bytes[1] = (n >> 8) & 0xFF;
164  bytes[0] = n & 0xFF;
165 }
gec_counter_to_bytes
void gec_counter_to_bytes(uint32_t n, uint8_t *bytes)
Convert counter to bytes in network byte order.
Definition: gec.c:142
PPRZ_KEY_LEN
#define PPRZ_KEY_LEN
Definition: gec.h:53
gec_sts_ctx::protocol_stage
stage_t protocol_stage
Definition: gec.h:122
gec_sym_key::nonce
uint8_t nonce[PPRZ_NONCE_LEN]
Definition: gec.h:78
uint16_t
unsigned short uint16_t
Definition: types.h:16
gec_sts_ctx::my_private_ephemeral
struct gec_privkey my_private_ephemeral
Definition: gec.h:119
gec_clear_sts
void gec_clear_sts(struct gec_sts_ctx *sts)
Definition: gec.c:54
gec_pubkey::ready
bool ready
Definition: gec.h:73
gec_sts_ctx::their_public_ephemeral
struct gec_pubkey their_public_ephemeral
Definition: gec.h:118
gec.h
ERROR_NONE
@ ERROR_NONE
Definition: gec.h:95
gec_sts_ctx::party
party_t party
Definition: gec.h:123
uint32_t
unsigned long uint32_t
Definition: types.h:18
PPRZ_NONCE_LEN
#define PPRZ_NONCE_LEN
Definition: gec.h:57
gec_privkey::ready
bool ready
Definition: gec.h:69
gec_privkey
Definition: gec.h:67
gec_sym_key::key
uint8_t key[PPRZ_KEY_LEN]
Definition: gec.h:77
gec_sts_ctx::tx_sym_key
struct gec_sym_key tx_sym_key
Definition: gec.h:121
gec_sym_key::ready
bool ready
Definition: gec.h:79
gec_bytes_to_counter
uint32_t gec_bytes_to_counter(uint8_t *bytes)
Convert from network byte order (big endian) to the machine byte order.
Definition: gec.c:117
gec_sym_key::counter
uint32_t counter
Definition: gec.h:79
gec_privkey::priv
uint8_t priv[PPRZ_KEY_LEN]
Definition: gec.h:68
gec_sts_ctx::last_error
sts_error_t last_error
Definition: gec.h:124
uint8_t
unsigned char uint8_t
Definition: types.h:14
gec_sts_ctx::my_private_key
struct gec_privkey my_private_key
Definition: gec.h:117
gec_generate_ephemeral_keys
void gec_generate_ephemeral_keys(struct gec_privkey *sk)
Generate private and public key pairs for future use.
Definition: gec.c:73
gec_sts_init
void gec_sts_init(struct gec_sts_ctx *sts)
Definition: gec.c:33
WAIT_MSG1
@ WAIT_MSG1
Definition: gec.h:83
gec_sym_key
Definition: gec.h:76
gec_sts_ctx::their_public_key
struct gec_pubkey their_public_key
Definition: gec.h:116
gec_sts_ctx
Definition: gec.h:115
gec_sts_ctx::rx_sym_key
struct gec_sym_key rx_sym_key
Definition: gec.h:120
gec_privkey::pub
uint8_t pub[PPRZ_KEY_LEN]
Definition: gec.h:69
rng_wait_and_get
uint32_t rng_wait_and_get(void)
Definition: rng_arch.c:104
gec_derive_key_material
void gec_derive_key_material(struct gec_sts_ctx *ctx, uint8_t *z)
Derive key material for both sender and receiver.
Definition: gec.c:91
RESPONDER
@ RESPONDER
Definition: gec.h:87
gec_pubkey
Definition: gec.h:72