32
32
#include <string.h>
33
33
34
34
#include "crypto.h"
35
+ #include "crypto_epoch.h"
36
+ #include "packet_id.h"
35
37
#include "error.h"
36
38
#include "integer.h"
37
39
#include "platform.h"
@@ -68,7 +70,15 @@ openvpn_encrypt_aead(struct buffer *buf, struct buffer work,
68
70
{
69
71
struct gc_arena gc ;
70
72
int outlen = 0 ;
73
+ const bool use_epoch_data_format = opt -> flags & CO_EPOCH_DATA_KEY_FORMAT ;
74
+
75
+ if (use_epoch_data_format )
76
+ {
77
+ epoch_check_send_iterate (opt );
78
+ }
79
+
71
80
const struct key_ctx * ctx = & opt -> key_ctx_bi .encrypt ;
81
+
72
82
uint8_t * mac_out = NULL ;
73
83
const int mac_len = OPENVPN_AEAD_TAG_LENGTH ;
74
84
@@ -89,14 +99,24 @@ openvpn_encrypt_aead(struct buffer *buf, struct buffer work,
89
99
buf_set_write (& iv_buffer , iv , iv_len );
90
100
91
101
/* IV starts with packet id to make the IV unique for packet */
92
- if (! packet_id_write ( & opt -> packet_id . send , & iv_buffer , false, false) )
102
+ if (use_epoch_data_format )
93
103
{
94
- msg (D_CRYPT_ERRORS , "ENCRYPT ERROR: packet ID roll over" );
95
- goto err ;
104
+ if (!packet_id_write_epoch (& opt -> packet_id .send , ctx -> epoch , & iv_buffer ))
105
+ {
106
+ msg (D_CRYPT_ERRORS , "ENCRYPT ERROR: packet ID roll over" );
107
+ goto err ;
108
+ }
109
+ }
110
+ else
111
+ {
112
+ if (!packet_id_write (& opt -> packet_id .send , & iv_buffer , false, false))
113
+ {
114
+ msg (D_CRYPT_ERRORS , "ENCRYPT ERROR: packet ID roll over" );
115
+ goto err ;
116
+ }
96
117
}
97
-
98
118
/* Write packet id part of IV to work buffer */
99
- ASSERT (buf_write (& work , iv , packet_id_size (false )));
119
+ ASSERT (buf_write (& work , iv , buf_len ( & iv_buffer )));
100
120
101
121
/* Remainder of IV consists of implicit part (unique per session)
102
122
* XOR of packet and implicit IV */
@@ -128,7 +148,7 @@ openvpn_encrypt_aead(struct buffer *buf, struct buffer work,
128
148
dmsg (D_PACKET_CONTENT , "ENCRYPT AD: %s" ,
129
149
format_hex (BPTR (& work ), BLEN (& work ), 0 , & gc ));
130
150
131
- if (!( opt -> flags & CO_EPOCH_DATA_KEY_FORMAT ) )
151
+ if (!use_epoch_data_format )
132
152
{
133
153
/* Reserve space for authentication tag */
134
154
mac_out = buf_write_alloc (& work , mac_len );
@@ -149,7 +169,7 @@ openvpn_encrypt_aead(struct buffer *buf, struct buffer work,
149
169
ASSERT (buf_inc_len (& work , outlen ));
150
170
151
171
/* if the tag is at end the end, allocate it now */
152
- if (opt -> flags & CO_EPOCH_DATA_KEY_FORMAT )
172
+ if (use_epoch_data_format )
153
173
{
154
174
/* Reserve space for authentication tag */
155
175
mac_out = buf_write_alloc (& work , mac_len );
@@ -365,14 +385,35 @@ cipher_get_aead_limits(const char *ciphername)
365
385
366
386
bool
367
387
crypto_check_replay (struct crypto_options * opt ,
368
- const struct packet_id_net * pin , const char * error_prefix ,
388
+ const struct packet_id_net * pin , uint16_t epoch ,
389
+ const char * error_prefix ,
369
390
struct gc_arena * gc )
370
391
{
371
392
bool ret = false;
372
- packet_id_reap_test (& opt -> packet_id .rec );
373
- if (packet_id_test (& opt -> packet_id .rec , pin ))
393
+ struct packet_id_rec * recv ;
394
+
395
+ if (epoch == 0 || opt -> key_ctx_bi .decrypt .epoch == epoch )
396
+ {
397
+ recv = & opt -> packet_id .rec ;
398
+ }
399
+ else if (epoch == opt -> epoch_retiring_data_receive_key .epoch )
400
+ {
401
+ recv = & opt -> epoch_retiring_key_pid_recv ;
402
+ }
403
+ else
404
+ {
405
+ /* We have an epoch that is neither current or old recv key but
406
+ * is authenticated, ie we need to move to a new current recv key */
407
+ msg (D_GENKEY , "Received data packet with new epoch %d. Updating "
408
+ "receive key" , epoch );
409
+ epoch_replace_update_recv_key (opt , epoch );
410
+ recv = & opt -> packet_id .rec ;
411
+ }
412
+
413
+ packet_id_reap_test (recv );
414
+ if (packet_id_test (recv , pin ))
374
415
{
375
- packet_id_add (& opt -> packet_id . rec , pin );
416
+ packet_id_add (recv , pin );
376
417
if (opt -> pid_persist && (opt -> flags & CO_PACKET_ID_LONG_FORM ))
377
418
{
378
419
packet_id_persist_save_obj (opt -> pid_persist , & opt -> packet_id );
@@ -408,8 +449,9 @@ openvpn_decrypt_aead(struct buffer *buf, struct buffer work,
408
449
static const char error_prefix [] = "AEAD Decrypt error" ;
409
450
struct packet_id_net pin = { 0 };
410
451
const struct key_ctx * ctx = & opt -> key_ctx_bi .decrypt ;
411
- int outlen ;
412
452
struct gc_arena gc ;
453
+ const bool use_epoch_data_format = opt -> flags & CO_EPOCH_DATA_KEY_FORMAT ;
454
+ const int tag_size = OPENVPN_AEAD_TAG_LENGTH ;
413
455
414
456
gc_init (& gc );
415
457
@@ -428,20 +470,58 @@ openvpn_decrypt_aead(struct buffer *buf, struct buffer work,
428
470
/* IV and Packet ID required for this mode */
429
471
ASSERT (packet_id_initialized (& opt -> packet_id ));
430
472
473
+ /* Ensure that the packet size is long enough */
474
+ int min_packet_len = packet_id_size (false) + tag_size + 1 ;
475
+
476
+ if (use_epoch_data_format )
477
+ {
478
+ min_packet_len += sizeof (uint32_t );
479
+ }
480
+
481
+ if (buf -> len < min_packet_len )
482
+ {
483
+ CRYPT_ERROR ("missing IV info, missing tag or no payload" );
484
+ }
485
+
486
+ uint16_t epoch = 0 ;
431
487
/* Combine IV from explicit part from packet and implicit part from context */
432
488
{
433
489
uint8_t iv [OPENVPN_MAX_IV_LENGTH ] = { 0 };
434
490
const int iv_len = cipher_ctx_iv_length (ctx -> cipher );
435
- const size_t packet_iv_len = packet_id_size (false);
436
491
437
- if (buf -> len < packet_id_size (false))
492
+ /* Read packet id. For epoch data format also lookup the epoch key
493
+ * to be able to use the implicit IV of the correct decryption key */
494
+ if (use_epoch_data_format )
438
495
{
439
- CRYPT_ERROR ( "missing IV info" );
440
- }
496
+ /* packet ID format is 16 bit epoch + 48 per epoch packet-counter */
497
+ const size_t packet_iv_len = sizeof ( uint64_t );
441
498
442
- memcpy (iv , BPTR (buf ), packet_iv_len );
499
+ /* copy the epoch-counter part into the IV */
500
+ memcpy (iv , BPTR (buf ), packet_iv_len );
443
501
444
- /* Remainder of IV consists of implicit part (unique per session)
502
+ epoch = packet_id_read_epoch (& pin , buf );
503
+ if (epoch == 0 )
504
+ {
505
+ CRYPT_ERROR ("error reading packet-id" );
506
+ }
507
+ ctx = epoch_lookup_decrypt_key (opt , epoch );
508
+ if (!ctx )
509
+ {
510
+ CRYPT_ERROR ("data packet with unknown epoch" );
511
+ }
512
+ }
513
+ else
514
+ {
515
+ const size_t packet_iv_len = packet_id_size (false);
516
+ /* Packet ID form is a 32 bit packet counter */
517
+ memcpy (iv , BPTR (buf ), packet_iv_len );
518
+ if (!packet_id_read (& pin , buf , false))
519
+ {
520
+ CRYPT_ERROR ("error reading packet-id" );
521
+ }
522
+ }
523
+
524
+ /* Remainder of IV consists of implicit part (unique per session/epoch key)
445
525
* XOR of packet counter and implicit IV */
446
526
for (int i = 0 ; i < iv_len ; i ++ )
447
527
{
@@ -457,25 +537,12 @@ openvpn_decrypt_aead(struct buffer *buf, struct buffer work,
457
537
}
458
538
}
459
539
460
- /* Read packet ID from packet */
461
- if (!packet_id_read (& pin , buf , false))
462
- {
463
- CRYPT_ERROR ("error reading packet-id" );
464
- }
465
-
466
- /* keep the tag value to feed in later */
467
- const int tag_size = OPENVPN_AEAD_TAG_LENGTH ;
468
- if (buf -> len < tag_size + 1 )
469
- {
470
- CRYPT_ERROR ("missing tag or no payload" );
471
- }
472
-
473
540
const int ad_size = BPTR (buf ) - ad_start ;
474
541
475
542
uint8_t * tag_ptr = NULL ;
476
543
int data_len = 0 ;
477
544
478
- if (opt -> flags & CO_EPOCH_DATA_KEY_FORMAT )
545
+ if (use_epoch_data_format )
479
546
{
480
547
data_len = BLEN (buf ) - tag_size ;
481
548
tag_ptr = BPTR (buf ) + data_len ;
@@ -496,13 +563,13 @@ openvpn_decrypt_aead(struct buffer *buf, struct buffer work,
496
563
CRYPT_ERROR ("potential buffer overflow" );
497
564
}
498
565
499
-
500
566
/* feed in tag and the authenticated data */
501
567
ASSERT (cipher_ctx_update_ad (ctx -> cipher , ad_start , ad_size ));
502
568
dmsg (D_PACKET_CONTENT , "DECRYPT AD: %s" ,
503
569
format_hex (ad_start , ad_size , 0 , & gc ));
504
570
505
571
/* Decrypt and authenticate packet */
572
+ int outlen ;
506
573
if (!cipher_ctx_update (ctx -> cipher , BPTR (& work ), & outlen , BPTR (buf ),
507
574
data_len ))
508
575
{
@@ -525,7 +592,7 @@ openvpn_decrypt_aead(struct buffer *buf, struct buffer work,
525
592
dmsg (D_PACKET_CONTENT , "DECRYPT TO: %s" ,
526
593
format_hex (BPTR (& work ), BLEN (& work ), 80 , & gc ));
527
594
528
- if (!crypto_check_replay (opt , & pin , error_prefix , & gc ))
595
+ if (!crypto_check_replay (opt , & pin , epoch , error_prefix , & gc ))
529
596
{
530
597
goto error_exit ;
531
598
}
@@ -696,7 +763,7 @@ openvpn_decrypt_v1(struct buffer *buf, struct buffer work,
696
763
}
697
764
}
698
765
699
- if (have_pin && !crypto_check_replay (opt , & pin , error_prefix , & gc ))
766
+ if (have_pin && !crypto_check_replay (opt , & pin , 0 , error_prefix , & gc ))
700
767
{
701
768
goto error_exit ;
702
769
}
0 commit comments