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-2025 OpenVPN Inc <sales@openvpn.net>
9 * Copyright (C) 2024-2025 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{
45 hmac_ctx_t *hmac_ctx = hmac_ctx_new();
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 {
56 hmac_ctx_reset(hmac_ctx);
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 }
71 hmac_ctx_cleanup(hmac_ctx);
72 hmac_ctx_free(hmac_ctx);
73}
74
75#if defined(__GNUC__) || defined(__clang__)
76#pragma GCC diagnostic push
77#pragma GCC diagnostic ignored "-Wconversion"
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, uint16_t 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
93 struct gc_arena gc = gc_new();
94 /* 2 byte for the outlen encoded as uint16, 5 bytes for "ovpn ",
95 * 1 byte for context len byte and 1 byte for label len byte */
96 const uint8_t *label_prefix = (const uint8_t *)("ovpn ");
97 int prefix_len = 5;
98
99 int hkdf_label_len = 2 + prefix_len + 1 + label_len + 1 + context_len;
101
103 buf_write_u8(&hkdf_label, prefix_len + label_len);
104 buf_write(&hkdf_label, label_prefix, prefix_len);
106
108 if (context_len > 0)
109 {
111 }
112
114
116
117 gc_free(&gc);
118 return true;
119}
120
126static void
128{
129 struct epoch_key new_epoch_key = { 0 };
130 new_epoch_key.epoch = epoch_key->epoch + 1;
131 const uint8_t epoch_update_label[] = "datakey upd";
132 /* length of the array without extra \0 byte from the string */
133 const size_t epoch_update_label_len = sizeof(epoch_update_label) - 1;
134
135 /* E_N+1 = OVPN-Expand-Label(E_N, "datakey upd", "", 32) */
136 ovpn_expand_label(epoch_key->epoch_key, sizeof(epoch_key->epoch_key), epoch_update_label,
137 epoch_update_label_len, NULL, 0, new_epoch_key.epoch_key,
138 sizeof(new_epoch_key.epoch_key));
139 *epoch_key = new_epoch_key;
140}
141
142void
144 const struct key_type *kt)
145{
146 key->hmac_size = cipher_kt_iv_size(kt->cipher);
147 key->cipher_size = cipher_kt_key_size(kt->cipher);
148
149 /* Generate data key from epoch key:
150 * K_i = OVPN-Expand-Label(E_i, "data_key", "", key_size)
151 * implicit_iv = OVPN-Expand-Label(E_i, "data_iv", "", implicit_iv_len)
152 */
153
154 const uint8_t epoch_data_key_label[] = "data_key";
155 /* length of the array without extra \0 byte from the string */
156 const size_t epoch_data_key_label_len = sizeof(epoch_data_key_label) - 1;
157
158 ovpn_expand_label(epoch_key->epoch_key, sizeof(epoch_key->epoch_key), epoch_data_key_label,
159 epoch_data_key_label_len, NULL, 0, (uint8_t *)(&key->cipher),
160 key->cipher_size);
161
162 const uint8_t epoch_data_iv_label[] = "data_iv";
163 /* length of the array without extra \0 byte from the string */
164 const size_t epoch_data_iv_label_len = sizeof(epoch_data_iv_label) - 1;
165
166 ovpn_expand_label(epoch_key->epoch_key, sizeof(epoch_key->epoch_key), epoch_data_iv_label,
167 epoch_data_iv_label_len, NULL, 0, (uint8_t *)(&key->hmac), key->hmac_size);
168 key->epoch = epoch_key->epoch;
169}
170
171#if defined(__GNUC__) || defined(__clang__)
172#pragma GCC diagnostic pop
173#endif
174
175static void
177{
178 /* Ensure that we are NEVER regenerating the same key that has already
179 * been generated. Since we also reset the packet ID counter this would be
180 * catastrophic as we would do IV reuse which breaks ciphers like AES-GCM */
182 char name[32] = { 0 };
183 snprintf(name, sizeof(name), "Epoch Data key %" PRIu16, co->epoch_key_send.epoch);
184
185 struct key_parameters send_key = { 0 };
186
188
189 init_key_bi_ctx_send(&co->key_ctx_bi.encrypt, &send_key, &co->epoch_key_type, name);
191 CLEAR(send_key);
192}
193
194
195static void
197{
198 struct key_parameters recv_key = { 0 };
200
201 char name[32];
202
203 snprintf(name, sizeof(name), "Epoch Data key %" PRIu16, co->epoch_key_recv.epoch);
204
205 init_key_bi_ctx_recv(ctx, &recv_key, &co->epoch_key_type, name);
206 CLEAR(recv_key);
207}
208
209void
211{
212 /* We want the future receive keys to start just after the epoch of
213 * the currently used decryption key. */
215 uint16_t current_decrypt_epoch = co->key_ctx_bi.decrypt.epoch;
216
217 /* Either we have not generated any future keys yet (first initialisation)
218 * or the last index is the same as our current epoch key
219 * (last generated receive epoch key should match the epoch key) */
220 struct key_ctx *highest_future_key =
222
223 ASSERT(co->epoch_key_recv.epoch == 1 || highest_future_key->epoch == co->epoch_key_recv.epoch);
224
225 /* free the keys that are not used anymore */
226 for (uint16_t i = 0; i < co->epoch_data_keys_future_count; i++)
227 {
228 /* Keys in future keys are always epoch > 1 if initialised */
229 if (co->epoch_data_keys_future[i].epoch > 0
230 && co->epoch_data_keys_future[i].epoch < current_decrypt_epoch)
231 {
232 /* Key is old, free it */
234 }
235 }
236
237 /* Calculate the number of keys that need to be generated,
238 * if no keys have been generated assume only the first key is defined */
239 uint16_t current_highest_key = highest_future_key->epoch ? highest_future_key->epoch : 1;
240 uint16_t desired_highest_key = current_decrypt_epoch + co->epoch_data_keys_future_count;
241 uint16_t num_keys_generate = desired_highest_key - current_highest_key;
242
243
244 /* Move the old keys out of the way so the order of keys stays strictly
245 * monotonic and consecutive. */
246 /* first check that the destination we are going to overwrite is freed */
247 for (uint16_t i = 0; i < num_keys_generate; i++)
248 {
250 }
251 memmove(co->epoch_data_keys_future, co->epoch_data_keys_future + num_keys_generate,
252 (co->epoch_data_keys_future_count - num_keys_generate) * sizeof(struct key_ctx));
253
254 /* Clear and regenerate the array elements at the end */
255 for (uint16_t i = co->epoch_data_keys_future_count - num_keys_generate;
257 {
260
262 }
263
264 /* Assert that all keys are initialised */
265 for (uint16_t i = 0; i < co->epoch_data_keys_future_count; i++)
266 {
268 }
269}
270
271void
279
280void
281epoch_replace_update_recv_key(struct crypto_options *co, uint16_t new_epoch)
282{
283 /* Find the key of the new epoch in future keys */
284 uint16_t fki;
285 for (fki = 0; fki < co->epoch_data_keys_future_count; fki++)
286 {
287 if (co->epoch_data_keys_future[fki].epoch == new_epoch)
288 {
289 break;
290 }
291 }
292 /* we should only ever be called when we successfully decrypted/authenticated
293 * a packet from a peer, ie the epoch recv key *MUST* be in that
294 * array */
295 ASSERT(fki < co->epoch_data_keys_future_count);
296 ASSERT(co->epoch_data_keys_future[fki].epoch == new_epoch);
297
298 struct key_ctx *new_ctx = &co->epoch_data_keys_future[fki];
299
300 /* Check if the new recv key epoch is higher than the send key epoch. If
301 * yes we will replace the send key as well */
302 if (co->key_ctx_bi.encrypt.epoch < new_epoch)
303 {
305
306 /* Update the epoch_key for send to match the current key being used.
307 * This is a bit of extra work but since we are a maximum of 16
308 * keys behind, a maximum 16 HMAC invocations are a small price to
309 * pay for not keeping all the old epoch keys around in future_keys
310 * array */
311 while (co->epoch_key_send.epoch < new_epoch)
312 {
314 }
316 }
317
318 /* Replace receive key */
322
323 co->key_ctx_bi.decrypt = *new_ctx;
324
325 /* Zero the old location instead to of free_key_ctx since we moved the keys
326 * and do not want to free the pointers in the old place */
327 memset(new_ctx, 0, sizeof(struct key_ctx));
328
329 /* Generate new future keys */
331}
332
333void
335{
336 for (uint16_t i = 0; i < co->epoch_data_keys_future_count; i++)
337 {
339 }
340
341 free(co->epoch_data_keys_future);
346}
347
348void
350 const struct epoch_key *e1_send, const struct epoch_key *e1_recv,
351 uint16_t future_key_count)
352{
353 ASSERT(e1_send->epoch == 1 && e1_recv->epoch == 1);
354 co->epoch_key_recv = *e1_recv;
355 co->epoch_key_send = *e1_send;
356
359
362 co->key_ctx_bi.initialized = true;
363
364 co->epoch_data_keys_future_count = future_key_count;
367}
368
369struct key_ctx *
371{
372 /* Current decrypt key is the most likely one */
373 if (opt->key_ctx_bi.decrypt.epoch == epoch)
374 {
375 return &opt->key_ctx_bi.decrypt;
376 }
379 {
381 }
382 else if (epoch > opt->key_ctx_bi.decrypt.epoch
384 {
385 /* Key in the range of future keys */
386 int index = epoch - (opt->key_ctx_bi.decrypt.epoch + 1);
387
388 /* If we have reached the edge of the valid keys we do not return
389 * the key anymore since regenerating the new keys would move us
390 * over the window of valid keys and would need all kind of
391 * special casing, so we stop returning the key in this case */
392 if (epoch > (UINT16_MAX - opt->epoch_data_keys_future_count - 1))
393 {
394 return NULL;
395 }
396 else
397 {
398 return &opt->epoch_data_keys_future[index];
399 }
400 }
401 else
402 {
403 return NULL;
404 }
405}
406
407
408void
410{
411 if (opt->epoch_key_send.epoch == UINT16_MAX)
412 {
413 /* limit of epoch keys reached, cannot move to a newer key anymore */
414 return;
415 }
416 if (opt->aead_usage_limit)
417 {
419 opt->packet_id.send.id))
420 {
421 /* Send key limit reached */
423 }
424 /* draft 8 of the aead usage limit still had but draft 9 complete
425 * dropped this statement:
426 *
427 * In particular, in two-party communication, one participant cannot
428 * regard apparent overuse of a key by other participants as
429 * being in error, when it could be that the other participant has
430 * better information about bounds.
431 *
432 * OpenVPN 2.x implements a compromise of not regarding this as an
433 * error but still accepting packets of the usage limit but tries to
434 * push the peer to a new epoch key by increasing our own key epoch
435 *
436 * Also try to push the sender to use a new key if we are the
437 * decryption fail warn limit.
438 * */
439 else if (opt->key_ctx_bi.encrypt.epoch == opt->key_ctx_bi.decrypt.epoch
441 opt->packet_id.rec.id)
443 {
444 /* Receive key limit reached. Increase our own send key to signal
445 * that we want to use a new epoch. Peer should then also move its
446 * key but is not required to do this */
448 }
449 }
450
452 {
454 }
455}
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:690
static uint8_t * buf_bptr(const struct buffer *buf)
Definition buffer.h:240
#define ALLOC_ARRAY_CLEAR(dptr, type, n)
Definition buffer.h:1058
static int buf_len(const struct buffer *buf)
Definition buffer.h:253
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:660
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Definition buffer.h:684
static void gc_free(struct gc_arena *a)
Definition buffer.h:1015
static struct gc_arena gc_new(void)
Definition buffer.h:1007
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:1037
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:343
void free_key_ctx(struct key_ctx *ctx)
Definition crypto.c:1080
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:1049
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:722
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:751
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)
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, uint16_t out_len)
Variant of the RFC 8446 TLS 1.3 HKDF-Expand-Label function with the following differences/restriction...
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.
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.
mbedtls_md_context_t hmac_ctx_t
Generic HMAC context.
#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:474
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:302
struct key_type epoch_key_type
the key_type that is used to generate the epoch keys
Definition crypto.h:308
struct key_ctx epoch_retiring_data_receive_key
The old key before the sender switched to a new epoch data key.
Definition crypto.h:328
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:313
struct key_ctx * epoch_data_keys_future
Keeps the future epoch data keys for decryption.
Definition crypto.h:322
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:325
struct packet_id_rec epoch_retiring_key_pid_recv
Definition crypto.h:329
struct epoch_key epoch_key_recv
epoch_key used for the highest receive epoch keys
Definition crypto.h:305
struct packet_id packet_id
Current packet ID state for both sending and receiving directions.
Definition crypto.h:331
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