Skip to content

Commit 53131ba

Browse files
committed
esp: anti-replay window.
1 parent eaa6bec commit 53131ba

3 files changed

Lines changed: 98 additions & 12 deletions

File tree

src/test/esp_sa_list.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ static struct wolfIP_esp_sa test_in_sa_list[WOLFIP_ESP_NUM_SA] =
77
{0x2f, 0xa9, 0xd8, 0xc8}, /* spi */
88
0x010A0A0A, /* src */
99
0x020A0A0A, /* dst */
10-
0,0, /* oseq, seq */
10+
{0, ESP_REPLAY_WIN, 0}, /* replay_t state */
1111
0, {0}, 0, /* null enc */
1212
ESP_AUTH_SHA256_RFC4868,
1313
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
@@ -20,7 +20,7 @@ static struct wolfIP_esp_sa test_in_sa_list[WOLFIP_ESP_NUM_SA] =
2020
{0x76, 0x4f, 0x47, 0xc9}, /* spi */
2121
0x010A0A0A, /* src */
2222
0x020A0A0A, /* dst */
23-
0,0, /* oseq, seq */
23+
{0, ESP_REPLAY_WIN, 0}, /* replay_t state */
2424
ESP_ENC_CBC_AES,
2525
{0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
2626
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03},
@@ -36,7 +36,7 @@ static struct wolfIP_esp_sa test_in_sa_list[WOLFIP_ESP_NUM_SA] =
3636
{0x01, 0x01, 0x01, 0x01}, /* spi */
3737
0x010A0A0A, /* src */
3838
0x020A0A0A, /* dst */
39-
0,0, /* oseq, seq */
39+
{0, ESP_REPLAY_WIN, 0}, /* replay_t state */
4040
ESP_ENC_GCM_RFC4106,
4141
{0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
4242
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
@@ -57,7 +57,7 @@ static struct wolfIP_esp_sa test_out_sa_list[WOLFIP_ESP_NUM_SA] =
5757
{0xf6, 0xe9, 0xb8, 0x0d}, /* spi */
5858
0x020A0A0A, /* src */
5959
0x030A0A0A, /* dst */
60-
0,0, /* oseq, seq */
60+
{0, ESP_REPLAY_WIN, 0}, /* replay_t state */
6161
0, {0}, 0, /* null enc */
6262
ESP_AUTH_SHA256_RFC4868,
6363
{0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
@@ -70,7 +70,7 @@ static struct wolfIP_esp_sa test_out_sa_list[WOLFIP_ESP_NUM_SA] =
7070
{0x49, 0xeb, 0xfd, 0xd4}, /* spi */
7171
0x020A0A0A, /* src */
7272
0x030A0A0A, /* dst */
73-
0,0, /* oseq, seq */
73+
{0, ESP_REPLAY_WIN, 0}, /* replay_t state */
7474
ESP_ENC_CBC_AES,
7575
{0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
7676
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04},
@@ -87,7 +87,7 @@ static struct wolfIP_esp_sa test_out_sa_list[WOLFIP_ESP_NUM_SA] =
8787
{0x02, 0x02, 0x02, 0x02}, /* spi */
8888
0x020A0A0A, /* src */
8989
0x010A0A0A, /* dst */
90-
0,0, /* oseq, seq */
90+
{0, ESP_REPLAY_WIN, 0}, /* replay_t state */
9191
ESP_ENC_GCM_RFC4106,
9292
{0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
9393
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,

src/wolfesp.c

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ esp_aes_rfc4106_enc(const struct wolfIP_esp_sa * esp_sa, uint8_t * esp_data,
575575
uint32_t seq_num = 0;
576576
uint8_t * seq_num_u8 = (uint8_t *) &seq_num;
577577

578-
seq_num = ee32(esp_sa->oseq);
578+
seq_num = ee32(esp_sa->replay.oseq);
579579

580580
/* copy in the pre_iv. */
581581
memcpy(iv, esp_sa->pre_iv, sizeof(esp_sa->pre_iv));
@@ -666,6 +666,77 @@ esp_check_icv_hmac(const struct wolfIP_esp_sa * esp_sa, uint8_t * esp_data,
666666
return rc;
667667
}
668668

669+
/**
670+
* Check sequence number against replay_t state.
671+
*
672+
* return 0 on success.
673+
* */
674+
static int
675+
esp_check_replay(struct replay_t * replay, uint32_t seq)
676+
{
677+
#if !defined(ESP_REPLAY_WIN)
678+
/* anti-replay service not enabled */
679+
(void)replay;
680+
(void)seq;
681+
#else
682+
uint8_t diff = 0;
683+
uint32_t bitn = 0;
684+
uint32_t seq_low = replay->hi_seq - ESP_REPLAY_WIN;
685+
686+
#if WOLFIP_DEBUG_ESP
687+
printf("info: seq: %u\n", seq);
688+
#endif
689+
690+
if (seq >= ESP_MAX_32_SEQ) {
691+
printf("error: seq exhausted: %d\n", seq);
692+
return -1;
693+
}
694+
695+
if (seq < seq_low) {
696+
printf("error: seq (%d) below window (%d)\n", seq, seq_low);
697+
return -1;
698+
}
699+
700+
/* Simple 32 bit replay window:
701+
* seq_low - - - - - - - seq - - - - - - hi_seq
702+
* <------------ ESP_REPLAY_WIN -------------->
703+
* */
704+
if (seq < replay->hi_seq) {
705+
/* seq number within window. */
706+
bitn = 1U << (replay->hi_seq - seq);
707+
708+
if ((replay->bitmap & bitn) != 0U) {
709+
printf("error: seq replayed: %d, %d\n", bitn, seq);
710+
return -1;
711+
}
712+
else {
713+
#if WOLFIP_DEBUG_ESP
714+
printf("info: new seq : %d\n", seq);
715+
#endif
716+
replay->bitmap |= bitn;
717+
}
718+
}
719+
else {
720+
/* seq number above window. */
721+
#if WOLFIP_DEBUG_ESP
722+
printf("info: new hi_seq : %d, %d\n", replay->hi_seq, seq);
723+
#endif
724+
diff = seq - replay->hi_seq;
725+
if (diff < ESP_REPLAY_WIN) {
726+
/* within a window width, slide up. */
727+
replay->bitmap = replay->bitmap << diff;
728+
}
729+
else {
730+
/* reset window. */
731+
replay->bitmap = 1;
732+
}
733+
replay->hi_seq = seq;
734+
}
735+
#endif /* ESP_REPLAY_WIN */
736+
737+
return 0;
738+
}
739+
669740
/**
670741
* Decapsulate an ipv4 ESP packet, transport mode. The packet is
671742
* unwrapped in-place without extra copying.
@@ -702,6 +773,7 @@ esp_transport_unwrap(struct wolfIP *s, struct wolfIP_ip_packet *ip,
702773
uint8_t pad_len = 0;
703774
uint8_t nxt_hdr = 0;
704775
uint8_t iv_len = 0;
776+
int err = 0;
705777

706778
memset(spi, 0, sizeof(spi));
707779

@@ -750,6 +822,11 @@ esp_transport_unwrap(struct wolfIP *s, struct wolfIP_ip_packet *ip,
750822
return -1;
751823
}
752824

825+
err = esp_check_replay(&esp_sa->replay, seq);
826+
if (err) {
827+
return -1;
828+
}
829+
753830
iv_len = esp_iv_len_from_enc(esp_sa->enc);
754831

755832
{
@@ -767,7 +844,6 @@ esp_transport_unwrap(struct wolfIP *s, struct wolfIP_ip_packet *ip,
767844
}
768845

769846
if (esp_sa->icv_len) {
770-
int err = 0;
771847
switch (esp_sa->auth) {
772848
case ESP_AUTH_MD5_RFC2403:
773849
case ESP_AUTH_SHA1_RFC2404:
@@ -922,8 +998,8 @@ esp_transport_wrap(struct wolfIP_ip_packet *ip, uint16_t * ip_len)
922998
memcpy(payload, esp_sa->spi, sizeof(esp_sa->spi));
923999
payload += ESP_SPI_LEN;
9241000

925-
esp_sa->oseq++;
926-
seq_n = ee32(esp_sa->oseq);
1001+
esp_sa->replay.oseq++;
1002+
seq_n = ee32(esp_sa->replay.oseq);
9271003
memcpy(payload, &seq_n, sizeof(seq_n));
9281004
payload += ESP_SEQ_LEN;
9291005

wolfesp.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ typedef enum {
3737
ESP_AUTH_GCM_RFC4543 /* rfc4543 gmac */
3838
} esp_auth_t;
3939

40+
/* simple static 32 bit replay window */
41+
#define ESP_MAX_32_SEQ 0xffffffffUL
42+
#define ESP_REPLAY_WIN 32
43+
44+
struct replay_t {
45+
uint32_t bitmap; /* inbound sequence bitmap */
46+
uint32_t hi_seq; /* inbound high sequence number */
47+
uint32_t oseq; /* outbound sequence number */
48+
};
49+
50+
typedef struct replay_t replay_t;
4051

4152
/* Minimal ESP Security Association structure.
4253
* Supports only transport mode.
@@ -45,8 +56,7 @@ struct wolfIP_esp_sa {
4556
uint8_t spi[ESP_SPI_LEN]; /* security parameter index */
4657
ip4 src; /* ip src and dst in network byte order */
4758
ip4 dst;
48-
uint32_t oseq; /* outbound sequence number */
49-
uint32_t seq; /* inbound sequence number */
59+
replay_t replay;
5060
esp_enc_t enc;
5161
uint8_t enc_key[ESP_MAX_KEY_LEN + ESP_GCM_RFC4106_SALT_LEN];
5262
uint8_t enc_key_len;

0 commit comments

Comments
 (0)