diff options
| author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2026-06-13 10:18:17 +0200 |
|---|---|---|
| committer | Sander Vrijders <sander@ouroboros.rocks> | 2026-06-29 08:32:58 +0200 |
| commit | 22e2380b09730a2f18deefd688585edb430d3299 (patch) | |
| tree | 1fc03db35d93833220482f9c5f70d4c9d2d618c1 /src/lib/dev.c | |
| parent | df14e6cc81c296d91e9124cd09f25a83defb522f (diff) | |
| download | ouroboros-22e2380b09730a2f18deefd688585edb430d3299.tar.gz ouroboros-22e2380b09730a2f18deefd688585edb430d3299.zip | |
lib: Harden symmetric-key rotation
Flow crypto signalled rotation with a single phase-parity bit, so a
loss burst that hid an even number of rotations went unnoticed and
wedged the flow for good.
Each packet now carries a small cleartext selector naming its key
directly, so a receiver that falls behind recovers on the next packet
instead of getting stuck.
The selector also serves as the AEAD nonce and is authenticated as
associated data (AAD). Key rotation moves into a new backend-agnostic
keyrot module that rotates sub-keys to bound AEAD usage while
preserving forward secrecy.
Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks>
Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/lib/dev.c')
| -rw-r--r-- | src/lib/dev.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/src/lib/dev.c b/src/lib/dev.c index ce358ac4..543bd13e 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -98,7 +98,7 @@ struct flow { ssize_t part_idx; struct crypt_ctx * crypt; - int headsz; /* IV */ + int headsz; /* selector */ int tailsz; /* Tag + CRC */ struct timespec snd_act; @@ -296,7 +296,7 @@ static int spb_decrypt(struct flow * flow, in.len = ssm_pk_buff_len(spb); if (crypt_decrypt(flow->crypt, in, &out) < 0) - return -ENOMEM; + return -ECRYPT; head = ssm_pk_buff_pop(spb, flow->headsz) + flow->headsz; @@ -711,11 +711,10 @@ static int flow_init(struct flow_info * info, flow->tailsz = 0; if (IS_ENCRYPTED(sk)) { - sk->rot_bit = KEY_ROTATION_BIT; flow->crypt = crypt_create_ctx(sk); if (flow->crypt == NULL) goto fail_crypt; - flow->headsz = crypt_get_ivsz(flow->crypt); + flow->headsz = crypt_get_headsz(flow->crypt); flow->tailsz = crypt_get_tagsz(flow->crypt); } @@ -1012,7 +1011,9 @@ int flow_accept(qosspec_t * qs, if (err < 0) return err; - crypt.key = key; + crypt.key = key; + crypt.epoch = 0; + crypt.role = CRYPT_ROLE_RESP; err = flow__irm_result_des(&msg, &flow, &crypt); if (err < 0) @@ -1067,7 +1068,9 @@ int flow_alloc(const char * dst, clock_gettime(PTHREAD_COND_CLOCK, &t1); - crypt.key = key; + crypt.key = key; + crypt.epoch = 0; + crypt.role = CRYPT_ROLE_INIT; err = flow__irm_result_des(&msg, &flow, &crypt); if (err < 0) @@ -1106,7 +1109,9 @@ int flow_join(const char * dst, if (err < 0) return err; - crypt.key = key; + crypt.key = key; + crypt.epoch = 0; + crypt.role = CRYPT_ROLE_INIT; err = flow__irm_result_des(&msg, &flow, &crypt); if (err < 0) @@ -2228,7 +2233,8 @@ int np1_flow_alloc(pid_t n_pid, int flow_id) { struct flow_info flow; - struct crypt_sk crypt = { .nid = NID_undef, .key = NULL }; + struct crypt_sk crypt = { .nid = NID_undef, .key = NULL, + .epoch = 0, .role = CRYPT_ROLE_INIT }; memset(&flow, 0, sizeof(flow)); @@ -2321,7 +2327,9 @@ int ipcp_flow_req_arr(const buffer_t * dst, if (err < 0) return err; - crypt.key = key; + crypt.key = key; + crypt.epoch = 0; + crypt.role = CRYPT_ROLE_INIT; err = flow__irm_result_des(&msg, &flow, &crypt); if (err < 0) |
