OpenVPN
crypto_epoch.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2024-2026 OpenVPN Inc <sales@openvpn.net>
9 * Copyright (C) 2024-2026 Arne Schwabe <arne@rfc2549.org>
10 *
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2
14 * as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, see <https://www.gnu.org/licenses/>.
23 */
24
25
26#ifdef HAVE_CONFIG_H
27#include "config.h"
28#endif
29
30#include <inttypes.h>
31#include <string.h>
32#include <stdlib.h>
33
34#include "crypto_backend.h"
35#include "packet_id.h"
36#include "crypto.h"
37#include "crypto_epoch.h"
38#include "buffer.h"
39#include "integer.h"
40
41void
42ovpn_hkdf_expand(const uint8_t *secret, const uint8_t *info, int info_len, uint8_t *out,
43 int out_len)
44{
46 hmac_ctx_init(hmac_ctx, secret, "SHA256");
47
48 const int digest_size = SHA256_DIGEST_LENGTH;
49
50 /* T(0) = empty string */
51 uint8_t t_prev[SHA256_DIGEST_LENGTH];
52 int t_prev_len = 0;
53
54 for (uint8_t block = 1; (block - 1) * digest_size < out_len; block++)
55 {
57
58 /* calculate T(block) */
59 hmac_ctx_update(hmac_ctx, t_prev, t_prev_len);
60 hmac_ctx_update(hmac_ctx, info, info_len);
61 hmac_ctx_update(hmac_ctx, &block, 1);
62 hmac_ctx_final(hmac_ctx, t_prev);
63 t_prev_len = digest_size;
64
65 /* Copy a full hmac output or remaining bytes */
66 int out_offset = (block - 1) * digest_size;
67 int copylen = min_int(digest_size, out_len - out_offset);
68
69 memcpy(out + out_offset, t_prev, copylen);
70 }
73}
74
75#if defined(__GNUC__) || defined(__clang__)
76#pragma GCC diagnostic push
77#pragma GCC diagnostic ignored "-Wsign-compare"
78#endif
79
80bool
81ovpn_expand_label(const uint8_t *secret, size_t secret_len, const uint8_t *label, size_t label_len,
82 const uint8_t *context, size_t context_len, uint8_t *out, int out_len)
83{
84 if (secret_len != 32 || label_len > 250 || context_len > 255 || label_len < 1)
85 {
86 /* Our current implementation is not a general purpose one
87 * and assumes that the secret size matches the size of the
88 * hash (SHA256) key. Also label length and context length
89 * need need to be in range */
90 return false;
91 }
92 ASSERT(out_len >= 0 && out_len <= UINT16_MAX);
93
94 struct gc_arena gc = gc_new();
95 /* 2 byte for the outlen encoded as uint16, 5 bytes for "ovpn ",
96 * 1 byte for context len byte and 1 byte for label len byte */
97 const uint8_t *label_prefix = (const uint8_t *)("ovpn ");
98 uint8_t prefix_len = 5;
99
100 size_t hkdf_label_len = 2 + prefix_len + 1 + label_len + 1 + context_len;
102
104 buf_write_u8(&hkdf_label, prefix_len + (uint8_t)label_len);
105 buf_write(&hkdf_label, label_prefix, prefix_len);
107
109 if (context_len > 0)
110 {
112 }
113
115
117
118 gc_free(&gc);
119 return true;
120}
121
122#if defined(__GNUC__) || defined(__clang__)
123#pragma GCC diagnostic pop
124#endif
125
131static void
133{
134 struct epoch_key new_epoch_key = { 0 };
135 new_epoch_key.epoch = epoch_key->epoch + 1;
136 const uint8_t epoch_update_label[] = "datakey upd";
137 /* length of the array without extra \0 byte from the string */
138 const size_t epoch_update_label_len = sizeof(epoch_update_label) - 1;
139
140 /* E_N+1 = OVPN-Expand-Label(E_N, "datakey upd", "", 32) */
141 ovpn_expand_label(epoch_key->epoch_key, sizeof(epoch_key->epoch_key), epoch_update_label,
142 epoch_update_label_len, NULL, 0, new_epoch_key.epoch_key,
143 sizeof(new_epoch_key.epoch_key));
144 *epoch_key = new_epoch_key;
145}
146
147void
149 const struct key_type *kt)
150{
151 key->hmac_size = cipher_kt_iv_size(kt->cipher);
152 key->cipher_size = cipher_kt_key_size(kt->cipher);
153
154 /* Generate data key from epoch key:
155 * K_i = OVPN-Expand-Label(E_i, "data_key", "", key_size)
156 * implicit_iv = OVPN-Expand-Label(E_i, "data_iv", "", implicit_iv_len)
157 */
158
159 const uint8_t epoch_data_key_label[] = "data_key";
160 /* length of the array without extra \0 byte from the string */
161 const size_t epoch_data_key_label_len = sizeof(epoch_data_key_label) - 1;
162
163 ovpn_expand_label(epoch_key->epoch_key, sizeof(epoch_key->epoch_key), epoch_data_key_label,
164 epoch_data_key_label_len, NULL, 0, (uint8_t *)(&key->cipher),
165 key->cipher_size);
166
167 const uint8_t epoch_data_iv_label[] = "data_iv";
168 /* length of the array without extra \0 byte from the string */
169 const size_t epoch_data_iv_label_len = sizeof(epoch_data_iv_label) - 1;
170
171 ovpn_expand_label(epoch_key->epoch_key, sizeof(epoch_key->epoch_key), epoch_data_iv_label,
172 epoch_data_iv_label_len, NULL, 0, (uint8_t *)(&key->hmac), key->hmac_size);
173 key->epoch = epoch_key->epoch;
174}
175
176static void
178{
179 /* Ensure that we are NEVER regenerating the same key that has already
180 * been generated. Since we also reset the packet ID counter this would be
181 * catastrophic as we would do IV reuse which breaks ciphers like AES-GCM */
183 char name[32] = { 0 };
184 snprintf(name, sizeof(name), "Epoch Data key %" PRIu16, co->epoch_key_send.epoch);
185
186 struct key_parameters send_key = { 0 };
187
189
190 init_key_bi_ctx_send(&co->key_ctx_bi.encrypt, &send_key, &co->epoch_key_type, name);
192 CLEAR(send_key);
193}
194
195
196static void
198{
199 struct key_parameters recv_key = { 0 };
201
202 char name[32];
203
204 snprintf(name, sizeof(name), "Epoch Data key %" PRIu16, co->epoch_key_recv.epoch);
205
206 init_key_bi_ctx_recv(ctx, &recv_key, &co->epoch_key_type, name);
207 CLEAR(recv_key);
208}
209
210void
212{
213 /* We want the future receive keys to start just after the epoch of
214 * the currently used decryption key. */
216 uint16_t current_decrypt_epoch = co->key_ctx_bi.decrypt.epoch;
217
218 /* Either we have not generated any future keys yet (first initialisation)
219 * or the last index is the same as our current epoch key
220 * (last generated receive epoch key should match the epoch key).
221 *
222 * The last generated key might have been moved to the decrypt key already.
223 */
224 struct key_ctx *highest_future_key =
226
227 ASSERT(co->epoch_key_recv.epoch == 1 || highest_future_key->epoch == co->epoch_key_recv.epoch
228 || current_decrypt_epoch == co->epoch_key_recv.epoch);
229
230 /* free the keys that are not used anymore */
231 for (uint16_t i = 0; i < co->epoch_data_keys_future_count; i++)
232 {
233 /* Keys in future keys are always epoch > 1 if initialised */
234 if (co->epoch_data_keys_future[i].epoch > 0
235 && co->epoch_data_keys_future[i].epoch < current_decrypt_epoch)
236 {
237 /* Key is old, free it */
239 }
240 }
241
242 /* The current epoch_key_recv is the higest currently generated key */
243 uint16_t current_highest_key = co->epoch_key_recv.epoch;
244
245 /* The current highest generated epoch key should be either the last
246 * key in the future key array or been already moved the current decrypt
247 * key (and then all future keys need to be generated)*/
248 ASSERT(current_highest_key == highest_future_key->epoch
249 || current_highest_key == current_decrypt_epoch);
250
251 /* Calculate the number of keys that need to be generated,
252 * if no keys have been generated assume only the first key is defined */
253 uint16_t desired_highest_key = current_decrypt_epoch + co->epoch_data_keys_future_count;
254 uint16_t num_keys_generate = desired_highest_key - current_highest_key;
255
256 /* Move the old keys out of the way so the order of keys stays strictly
257 * monotonic and consecutive. */
258 /* first check that the destination we are going to overwrite is freed */
259 for (uint16_t i = 0; i < num_keys_generate; i++)
260 {
262 }
263 memmove(co->epoch_data_keys_future, co->epoch_data_keys_future + num_keys_generate,
264 (co->epoch_data_keys_future_count - num_keys_generate) * sizeof(struct key_ctx));
265
266 /* Clear and regenerate the array elements at the end */
267 for (uint16_t i = co->epoch_data_keys_future_count - num_keys_generate;
268 i < co->epoch_data_keys_future_count; i++)
269 {
272
274 }
275
276 /* Assert that all keys are initialised */
277 for (uint16_t i = 0; i < co->epoch_data_keys_future_count; i++)
278 {
280 }
281}
282
283void
291
292void
293epoch_replace_update_recv_key(struct crypto_options *co, uint16_t new_epoch)
294{
295 /* Find the key of the new epoch in future keys */
296 uint16_t fki;
297 for (fki = 0; fki < co->epoch_data_keys_future_count; fki++)
298 {
299 if (co->epoch_data_keys_future[fki].epoch == new_epoch)
300 {
301 break;
302 }
303 }
304 /* we should only ever be called when we successfully decrypted/authenticated
305 * a packet from a peer, ie the epoch recv key *MUST* be in that
306 * array */
307 ASSERT(fki < co->epoch_data_keys_future_count);
308 ASSERT(co->epoch_data_keys_future[fki].epoch == new_epoch);
309
310 struct key_ctx *new_ctx = &co->epoch_data_keys_future[fki];
311
312 /* Check if the new recv key epoch is higher than the send key epoch. If
313 * yes we will replace the send key as well */
314 if (co->key_ctx_bi.encrypt.epoch < new_epoch)
315 {
317
318 /* Update the epoch_key for send to match the current key being used.
319 * This is a bit of extra work but since we are a maximum of 16
320 * keys behind, a maximum 16 HMAC invocations are a small price to
321 * pay for not keeping all the old epoch keys around in future_keys
322 * array */
323 while (co->epoch_key_send.epoch < new_epoch)
324 {
326 }
328 }
329
330 /* Replace receive key */
334
335 co->key_ctx_bi.decrypt = *new_ctx;
336
337 /* Zero the old location instead to of free_key_ctx since we moved the keys
338 * and do not want to free the pointers in the old place */
339 memset(new_ctx, 0, sizeof(struct key_ctx));
340
341 /* Generate new future keys */
343}
344
345void
347{
348 for (uint16_t i = 0; i < co->epoch_data_keys_future_count; i++)
349 {
351 }
352
353 free(co->epoch_data_keys_future);
358}
359
360void
362 const struct epoch_key *e1_send, const struct epoch_key *e1_recv,
363 uint16_t future_key_count)
364{
365 ASSERT(e1_send->epoch == 1 && e1_recv->epoch == 1);
366 co->epoch_key_recv = *e1_recv;
367 co->epoch_key_send = *e1_send;
368
371
374 co->key_ctx_bi.initialized = true;
375
376 co->epoch_data_keys_future_count = future_key_count;
379}
380
381struct key_ctx *
383{
384 /* Current decrypt key is the most likely one */
385 if (opt->key_ctx_bi.decrypt.epoch == epoch)
386 {
387 return &opt->key_ctx_bi.decrypt;
388 }
391 {
393 }
394 else if (epoch > opt->key_ctx_bi.decrypt.epoch
396 {
397 /* Key in the range of future keys */
398 int index = epoch - (opt->key_ctx_bi.decrypt.epoch + 1);
399
400 /* If we have reached the edge of the valid keys we do not return
401 * the key anymore since regenerating the new keys would move us
402 * over the window of valid keys and would need all kind of
403 * special casing, so we stop returning the key in this case */
404 if (epoch > (UINT16_MAX - opt->epoch_data_keys_future_count - 1))
405 {
406 return NULL;
407 }
408 else
409 {
410 return &opt->epoch_data_keys_future[index];
411 }
412 }
413 else
414 {
415 return NULL;
416 }
417}
418
419
420void
422{
423 if (opt->epoch_key_send.epoch == UINT16_MAX)
424 {
425 /* limit of epoch keys reached, cannot move to a newer key anymore */
426 return;
427 }
428 if (opt->aead_usage_limit)
429 {
431 opt->packet_id.send.id))
432 {
433 /* Send key limit reached */
435 }
436 /* draft 8 of the aead usage limit still had but draft 9 complete
437 * dropped this statement:
438 *
439 * In particular, in two-party communication, one participant cannot
440 * regard apparent overuse of a key by other participants as
441 * being in error, when it could be that the other participant has
442 * better information about bounds.
443 *
444 * OpenVPN 2.x implements a compromise of not regarding this as an
445 * error but still accepting packets of the usage limit but tries to
446 * push the peer to a new epoch key by increasing our own key epoch
447 *
448 * Also try to push the sender to use a new key if we are the
449 * decryption fail warn limit.
450 * */
451 else if (opt->key_ctx_bi.encrypt.epoch == opt->key_ctx_bi.decrypt.epoch
453 opt->packet_id.rec.id)
455 {
456 /* Receive key limit reached. Increase our own send key to signal
457 * that we want to use a new epoch. Peer should then also move its
458 * key but is not required to do this */
460 }
461 }
462
464 {
466 }
467}
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:89
static bool buf_write_u16(struct buffer *dest, uint16_t data)
Definition buffer.h:691
static uint8_t * buf_bptr(const struct buffer *buf)
Definition buffer.h:241
#define ALLOC_ARRAY_CLEAR(dptr, type, n)
Definition buffer.h:1104
static int buf_len(const struct buffer *buf)
Definition buffer.h:254
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:661
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Definition buffer.h:685
static void gc_free(struct gc_arena *a)
Definition buffer.h:1049
static struct gc_arena gc_new(void)
Definition buffer.h:1041
void init_key_bi_ctx_send(struct key_ctx *ctx, const struct key_parameters *key_params, const struct key_type *kt, const char *name)
Definition crypto.c:1043
uint64_t cipher_get_aead_limits(const char *ciphername)
Check if the cipher is an AEAD cipher and needs to be limited to a certain number of number of blocks...
Definition crypto.c:350
void free_key_ctx(struct key_ctx *ctx)
Definition crypto.c:1086
void init_key_bi_ctx_recv(struct key_ctx *ctx, const struct key_parameters *key_params, const struct key_type *kt, const char *name)
Definition crypto.c:1055
Data Channel Cryptography Module.
static bool cipher_decrypt_verify_fail_warn(const struct key_ctx *ctx)
Check if the number of failed decryption is approaching the limit and we should try to move to a new ...
Definition crypto.h:731
static bool aead_usage_limit_reached(const uint64_t limit, const struct key_ctx *key_ctx, int64_t higest_pid)
Checks if the usage limit for an AEAD cipher is reached.
Definition crypto.h:760
Data Channel Cryptography SSL library-specific backend interface.
void hmac_ctx_update(hmac_ctx_t *ctx, const uint8_t *src, int src_len)
hmac_ctx_t * hmac_ctx_new(void)
void hmac_ctx_reset(hmac_ctx_t *ctx)
void hmac_ctx_init(hmac_ctx_t *ctx, const uint8_t *key, const char *mdname)
void hmac_ctx_final(hmac_ctx_t *ctx, uint8_t *dst)
void hmac_ctx_free(hmac_ctx_t *ctx)
int cipher_kt_iv_size(const char *ciphername)
Returns the size of the IV used by the cipher, in bytes, or 0 if no IV is used.
int cipher_kt_key_size(const char *ciphername)
Returns the size of keys used by the cipher, in bytes.
void hmac_ctx_cleanup(hmac_ctx_t *ctx)
void epoch_generate_future_receive_keys(struct crypto_options *co)
Generates and fills the epoch_data_keys_future with next valid future keys in crypto_options using th...
void epoch_replace_update_recv_key(struct crypto_options *co, uint16_t new_epoch)
This is called when the peer uses a new send key that is not the default key.
static void epoch_key_iterate(struct epoch_key *epoch_key)
Iterates the epoch key to make it E_n+1, ie increase the epoch by one and derive the new key material...
bool ovpn_expand_label(const uint8_t *secret, size_t secret_len, const uint8_t *label, size_t label_len, const uint8_t *context, size_t context_len, uint8_t *out, int out_len)
Variant of the RFC 8446 TLS 1.3 HKDF-Expand-Label function with the following differences/restriction...
static void epoch_init_send_key_ctx(struct crypto_options *co)
void free_epoch_key_ctx(struct crypto_options *co)
Frees the extra data structures used by epoch keys in crypto_options.
void epoch_check_send_iterate(struct crypto_options *opt)
Checks if we need to iterate the send epoch key.
static void epoch_init_recv_key(struct key_ctx *ctx, struct crypto_options *co)
struct key_ctx * epoch_lookup_decrypt_key(struct crypto_options *opt, uint16_t epoch)
Using an epoch, this function will try to retrieve a decryption key context that matches that epoch f...
void epoch_init_key_ctx(struct crypto_options *co, const struct key_type *key_type, const struct epoch_key *e1_send, const struct epoch_key *e1_recv, uint16_t future_key_count)
Initialises data channel keys and internal structures for epoch data keys using the provided E0 epoch...
void epoch_data_key_derive(struct key_parameters *key, const struct epoch_key *epoch_key, const struct key_type *kt)
Generate a data channel key pair from the epoch key.
void ovpn_hkdf_expand(const uint8_t *secret, const uint8_t *info, int info_len, uint8_t *out, int out_len)
Implementation of the RFC5869 HKDF-Expand function with the following restrictions.
void epoch_iterate_send_key(struct crypto_options *co)
Updates the send key and send_epoch_key in cryptio_options->key_ctx_bi to use the next epoch.
#define SHA256_DIGEST_LENGTH
static int min_int(int x, int y)
Definition integer.h:105
#define CLEAR(x)
Definition basic.h:32
#define ASSERT(x)
Definition error.h:219
void packet_id_move_recv(struct packet_id_rec *dest, struct packet_id_rec *src)
Move the packet id recv structure from src to dest.
Definition packet_id.c:109
static void reset_packet_id_send(struct packet_id_send *p)
Reset the current send packet id to its initial state.
Definition packet_id.h:312
#define PACKET_ID_EPOCH_MAX
Definition packet_id.h:47
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:65
Contains all state information for one tunnel.
Definition openvpn.h:471
Security parameter state for processing data channel packets.
Definition crypto.h:293
struct epoch_key epoch_key_send
last epoch_key used for generation of the current send data keys.
Definition crypto.h:303
struct key_type epoch_key_type
the key_type that is used to generate the epoch keys
Definition crypto.h:309
struct key_ctx epoch_retiring_data_receive_key
The old key before the sender switched to a new epoch data key.
Definition crypto.h:330
uint64_t aead_usage_limit
The limit for AEAD cipher, this is the sum of packets + blocks that are allowed to be used.
Definition crypto.h:315
struct key_ctx * epoch_data_keys_future
Keeps the future epoch data keys for decryption.
Definition crypto.h:324
struct key_ctx_bi key_ctx_bi
OpenSSL cipher and HMAC contexts for both sending and receiving directions.
Definition crypto.h:294
uint16_t epoch_data_keys_future_count
number of keys stored in epoch_data_keys_future
Definition crypto.h:327
struct packet_id_rec epoch_retiring_key_pid_recv
Definition crypto.h:331
struct epoch_key epoch_key_recv
epoch_key used for the highest receive epoch keys
Definition crypto.h:306
struct packet_id packet_id
Current packet ID state for both sending and receiving directions.
Definition crypto.h:333
uint8_t epoch_key[SHA256_DIGEST_LENGTH]
Definition crypto.h:193
uint16_t epoch
Definition crypto.h:194
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
Container for two sets of OpenSSL cipher and/or HMAC contexts for both sending and receiving directio...
Definition crypto.h:280
bool initialized
Definition crypto.h:285
struct key_ctx decrypt
cipher and/or HMAC contexts for receiving direction.
Definition crypto.h:283
struct key_ctx encrypt
Cipher and/or HMAC contexts for sending direction.
Definition crypto.h:281
Container for one set of cipher and/or HMAC contexts.
Definition crypto.h:202
uint16_t epoch
OpenVPN data channel epoch, this variable holds the epoch number this key belongs to.
Definition crypto.h:228
internal structure similar to struct key that holds key information but is not represented on wire an...
Definition crypto.h:163
const char * cipher
const name of the cipher
Definition crypto.h:142
Container for unidirectional cipher and HMAC key material.
Definition crypto.h:152
uint8_t cipher[MAX_CIPHER_KEY_LENGTH]
Key material for cipher operations.
Definition crypto.h:153
uint8_t hmac[MAX_HMAC_KEY_LENGTH]
Key material for HMAC operations.
Definition crypto.h:155
uint64_t id
Definition packet_id.h:117
struct seq_list * seq_list
Definition packet_id.h:122
uint64_t id
Definition packet_id.h:153
struct packet_id_send send
Definition packet_id.h:200
struct packet_id_rec rec
Definition packet_id.h:201
struct gc_arena gc
Definition test_ssl.c:131