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, size_t info_len,
43 uint8_t *out, size_t out_len)
44{
46 hmac_ctx_init(hmac_ctx, secret, "SHA256");
47
48 ASSERT(info_len <= INT_MAX);
49 const unsigned int digest_size = SHA256_DIGEST_LENGTH;
50
51 /* T(0) = empty string */
52 uint8_t t_prev[SHA256_DIGEST_LENGTH];
53 unsigned int t_prev_len = 0;
54
55 for (uint8_t block = 1; (block - 1) * digest_size < out_len; block++)
56 {
58
59 /* calculate T(block) */
60 hmac_ctx_update(hmac_ctx, t_prev, t_prev_len);
61 hmac_ctx_update(hmac_ctx, info, (int)info_len);
62 hmac_ctx_update(hmac_ctx, &block, 1);
63 hmac_ctx_final(hmac_ctx, t_prev);
64 t_prev_len = digest_size;
65
66 /* Copy a full hmac output or remaining bytes */
67 size_t out_offset = (block - 1) * digest_size;
68 size_t copylen = min_size(digest_size, out_len - out_offset);
69
70 memcpy(out + out_offset, t_prev, copylen);
71 }
74}
75
76bool
77ovpn_expand_label(const uint8_t *secret, size_t secret_len, const uint8_t *label, size_t label_len,
78 const uint8_t *context, size_t context_len, uint8_t *out, size_t out_len)
79{
80 if (secret_len != 32 || label_len > 250 || context_len > 255 || label_len < 1)
81 {
82 /* Our current implementation is not a general purpose one
83 * and assumes that the secret size matches the size of the
84 * hash (SHA256) key. Also label length and context length
85 * need need to be in range */
86 return false;
87 }
88 ASSERT(out_len <= UINT16_MAX);
89
90 struct gc_arena gc = gc_new();
91 /* 2 byte for the outlen encoded as uint16, 5 bytes for "ovpn ",
92 * 1 byte for context len byte and 1 byte for label len byte */
93 const uint8_t *label_prefix = (const uint8_t *)("ovpn ");
94 uint8_t prefix_len = 5;
95
96 size_t hkdf_label_len = 2 + prefix_len + 1 + label_len + 1 + context_len;
98
100 buf_write_u8(&hkdf_label, prefix_len + (uint8_t)label_len);
101 buf_write(&hkdf_label, label_prefix, prefix_len);
103
105 if (context_len > 0)
106 {
108 }
109
111
113
114 gc_free(&gc);
115 return true;
116}
117
123static void
125{
126 struct epoch_key new_epoch_key = { 0 };
127 new_epoch_key.epoch = epoch_key->epoch + 1;
128 const uint8_t epoch_update_label[] = "datakey upd";
129 /* length of the array without extra \0 byte from the string */
130 const size_t epoch_update_label_len = sizeof(epoch_update_label) - 1;
131
132 /* E_N+1 = OVPN-Expand-Label(E_N, "datakey upd", "", 32) */
133 ovpn_expand_label(epoch_key->epoch_key, sizeof(epoch_key->epoch_key), epoch_update_label,
134 epoch_update_label_len, NULL, 0, new_epoch_key.epoch_key,
135 sizeof(new_epoch_key.epoch_key));
136 *epoch_key = new_epoch_key;
137}
138
139void
141 const struct key_type *kt)
142{
143 key->hmac_size = cipher_kt_iv_size(kt->cipher);
144 key->cipher_size = cipher_kt_key_size(kt->cipher);
145
146 /* Generate data key from epoch key:
147 * K_i = OVPN-Expand-Label(E_i, "data_key", "", key_size)
148 * implicit_iv = OVPN-Expand-Label(E_i, "data_iv", "", implicit_iv_len)
149 */
150
151 const uint8_t epoch_data_key_label[] = "data_key";
152 /* length of the array without extra \0 byte from the string */
153 const size_t epoch_data_key_label_len = sizeof(epoch_data_key_label) - 1;
154
155 ovpn_expand_label(epoch_key->epoch_key, sizeof(epoch_key->epoch_key), epoch_data_key_label,
156 epoch_data_key_label_len, NULL, 0, (uint8_t *)(&key->cipher),
157 key->cipher_size);
158
159 const uint8_t epoch_data_iv_label[] = "data_iv";
160 /* length of the array without extra \0 byte from the string */
161 const size_t epoch_data_iv_label_len = sizeof(epoch_data_iv_label) - 1;
162
163 ovpn_expand_label(epoch_key->epoch_key, sizeof(epoch_key->epoch_key), epoch_data_iv_label,
164 epoch_data_iv_label_len, NULL, 0, (uint8_t *)(&key->hmac), key->hmac_size);
165 key->epoch = epoch_key->epoch;
166}
167
168static void
170{
171 /* Ensure that we are NEVER regenerating the same key that has already
172 * been generated. Since we also reset the packet ID counter this would be
173 * catastrophic as we would do IV reuse which breaks ciphers like AES-GCM */
175 char name[32] = { 0 };
176 snprintf(name, sizeof(name), "Epoch Data key %" PRIu16, co->epoch_key_send.epoch);
177
178 struct key_parameters send_key = { 0 };
179
181
182 init_key_bi_ctx_send(&co->key_ctx_bi.encrypt, &send_key, &co->epoch_key_type, name);
184 CLEAR(send_key);
185}
186
187
188static void
190{
191 struct key_parameters recv_key = { 0 };
193
194 char name[32];
195
196 snprintf(name, sizeof(name), "Epoch Data key %" PRIu16, co->epoch_key_recv.epoch);
197
198 init_key_bi_ctx_recv(ctx, &recv_key, &co->epoch_key_type, name);
199 CLEAR(recv_key);
200}
201
202void
204{
205 /* We want the future receive keys to start just after the epoch of
206 * the currently used decryption key. */
208 uint16_t current_decrypt_epoch = co->key_ctx_bi.decrypt.epoch;
209
210 /* Either we have not generated any future keys yet (first initialisation)
211 * or the last index is the same as our current epoch key
212 * (last generated receive epoch key should match the epoch key).
213 *
214 * The last generated key might have been moved to the decrypt key already.
215 */
216 struct key_ctx *highest_future_key =
218
219 ASSERT(co->epoch_key_recv.epoch == 1 || highest_future_key->epoch == co->epoch_key_recv.epoch
220 || current_decrypt_epoch == co->epoch_key_recv.epoch);
221
222 /* free the keys that are not used anymore */
223 for (uint16_t i = 0; i < co->epoch_data_keys_future_count; i++)
224 {
225 /* Keys in future keys are always epoch > 1 if initialised */
226 if (co->epoch_data_keys_future[i].epoch > 0
227 && co->epoch_data_keys_future[i].epoch < current_decrypt_epoch)
228 {
229 /* Key is old, free it */
231 }
232 }
233
234 /* The current epoch_key_recv is the higest currently generated key */
235 uint16_t current_highest_key = co->epoch_key_recv.epoch;
236
237 /* The current highest generated epoch key should be either the last
238 * key in the future key array or been already moved the current decrypt
239 * key (and then all future keys need to be generated)*/
240 ASSERT(current_highest_key == highest_future_key->epoch
241 || current_highest_key == current_decrypt_epoch);
242
243 /* Calculate the number of keys that need to be generated,
244 * if no keys have been generated assume only the first key is defined */
245 uint16_t desired_highest_key = current_decrypt_epoch + co->epoch_data_keys_future_count;
246 uint16_t num_keys_generate = desired_highest_key - current_highest_key;
247
248 /* Move the old keys out of the way so the order of keys stays strictly
249 * monotonic and consecutive. */
250 /* first check that the destination we are going to overwrite is freed */
251 for (uint16_t i = 0; i < num_keys_generate; i++)
252 {
254 }
255 memmove(co->epoch_data_keys_future, co->epoch_data_keys_future + num_keys_generate,
256 (co->epoch_data_keys_future_count - num_keys_generate) * sizeof(struct key_ctx));
257
258 /* Clear and regenerate the array elements at the end */
259 for (uint16_t i = co->epoch_data_keys_future_count - num_keys_generate;
260 i < co->epoch_data_keys_future_count; i++)
261 {
264
266 }
267
268 /* Assert that all keys are initialised */
269 for (uint16_t i = 0; i < co->epoch_data_keys_future_count; i++)
270 {
272 }
273}
274
275void
283
284void
285epoch_replace_update_recv_key(struct crypto_options *co, uint16_t new_epoch)
286{
287 /* Find the key of the new epoch in future keys */
288 uint16_t fki;
289 for (fki = 0; fki < co->epoch_data_keys_future_count; fki++)
290 {
291 if (co->epoch_data_keys_future[fki].epoch == new_epoch)
292 {
293 break;
294 }
295 }
296 /* we should only ever be called when we successfully decrypted/authenticated
297 * a packet from a peer, ie the epoch recv key *MUST* be in that
298 * array */
299 ASSERT(fki < co->epoch_data_keys_future_count);
300 ASSERT(co->epoch_data_keys_future[fki].epoch == new_epoch);
301
302 struct key_ctx *new_ctx = &co->epoch_data_keys_future[fki];
303
304 /* Check if the new recv key epoch is higher than the send key epoch. If
305 * yes we will replace the send key as well */
306 if (co->key_ctx_bi.encrypt.epoch < new_epoch)
307 {
309
310 /* Update the epoch_key for send to match the current key being used.
311 * This is a bit of extra work but since we are a maximum of 16
312 * keys behind, a maximum 16 HMAC invocations are a small price to
313 * pay for not keeping all the old epoch keys around in future_keys
314 * array */
315 while (co->epoch_key_send.epoch < new_epoch)
316 {
318 }
320 }
321
322 /* Replace receive key */
326
327 co->key_ctx_bi.decrypt = *new_ctx;
328
329 /* Zero the old location instead to of free_key_ctx since we moved the keys
330 * and do not want to free the pointers in the old place */
331 memset(new_ctx, 0, sizeof(struct key_ctx));
332
333 /* Generate new future keys */
335}
336
337void
339{
340 for (uint16_t i = 0; i < co->epoch_data_keys_future_count; i++)
341 {
343 }
344
345 free(co->epoch_data_keys_future);
350}
351
352void
354 const struct epoch_key *e1_send, const struct epoch_key *e1_recv,
355 uint16_t future_key_count)
356{
357 ASSERT(e1_send->epoch == 1 && e1_recv->epoch == 1);
358 co->epoch_key_recv = *e1_recv;
359 co->epoch_key_send = *e1_send;
360
363
366 co->key_ctx_bi.initialized = true;
367
368 co->epoch_data_keys_future_count = future_key_count;
371}
372
373struct key_ctx *
375{
376 /* Current decrypt key is the most likely one */
377 if (opt->key_ctx_bi.decrypt.epoch == epoch)
378 {
379 return &opt->key_ctx_bi.decrypt;
380 }
383 {
385 }
386 else if (epoch > opt->key_ctx_bi.decrypt.epoch
388 {
389 /* Key in the range of future keys */
390 int index = epoch - (opt->key_ctx_bi.decrypt.epoch + 1);
391
392 /* If we have reached the edge of the valid keys we do not return
393 * the key anymore since regenerating the new keys would move us
394 * over the window of valid keys and would need all kind of
395 * special casing, so we stop returning the key in this case */
396 if (epoch > (UINT16_MAX - opt->epoch_data_keys_future_count - 1))
397 {
398 return NULL;
399 }
400 else
401 {
402 return &opt->epoch_data_keys_future[index];
403 }
404 }
405 else
406 {
407 return NULL;
408 }
409}
410
411
412void
414{
415 if (opt->epoch_key_send.epoch == UINT16_MAX)
416 {
417 /* limit of epoch keys reached, cannot move to a newer key anymore */
418 return;
419 }
420 if (opt->aead_usage_limit)
421 {
423 opt->packet_id.send.id))
424 {
425 /* Send key limit reached */
427 }
428 /* draft 8 of the aead usage limit still had but draft 9 complete
429 * dropped this statement:
430 *
431 * In particular, in two-party communication, one participant cannot
432 * regard apparent overuse of a key by other participants as
433 * being in error, when it could be that the other participant has
434 * better information about bounds.
435 *
436 * OpenVPN 2.x implements a compromise of not regarding this as an
437 * error but still accepting packets of the usage limit but tries to
438 * push the peer to a new epoch key by increasing our own key epoch
439 *
440 * Also try to push the sender to use a new key if we are the
441 * decryption fail warn limit.
442 * */
443 else if (opt->key_ctx_bi.encrypt.epoch == opt->key_ctx_bi.decrypt.epoch
445 opt->packet_id.rec.id)
447 {
448 /* Receive key limit reached. Increase our own send key to signal
449 * that we want to use a new epoch. Peer should then also move its
450 * key but is not required to do this */
452 }
453 }
454
456 {
458 }
459}
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:1038
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:345
void free_key_ctx(struct key_ctx *ctx)
Definition crypto.c:1081
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:1050
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)
unsigned 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.
void hmac_ctx_free(hmac_ctx_t *ctx)
unsigned 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...
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.
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, size_t out_len)
Variant of the RFC 8446 TLS 1.3 HKDF-Expand-Label function with the following differences/restriction...
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, size_t info_len, uint8_t *out, size_t 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 size_t min_size(size_t x, size_t y)
Definition integer.h:79
#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