Skip to content

Commit

Permalink
sad: introduce sad_set_last_seqid() and sad_check_seqid()
Browse files Browse the repository at this point in the history
The standard specifies that the header sequence id should be checked to
confirm the message has not been replayed. It specifies a seqid check
for each message that has it's own sequence id pool but this is most
relevant for sync/followup messages for which slaves do not confirm
seqid currently.

The standard also mentioned a seqid window. The seqid window specifies
how far the seqid can advance from the last know seqid before it is
considered a replay attack from before a seqid rollover.

This patch introduces sad_check_seqid() in sad.c to check the seqid and
sad_set_last_seqid() which is updates the last seqid upon successful
sync in port_synchronize() and reset upon state transition in
port_e2e_transition() and port_p2p_transition.

Signed-off-by: Clay Kaiser <Clay.Kaiser@ibm.com>
Reviewed-by: Erez Geva <ErezGeva2@gmail.com>
Reviewed-by: Miroslav Lichvar <mlichvar@redhat.com>
  • Loading branch information
Clay Kaiser (via linuxptp-devel Mailing List) authored and richardcochran committed Jun 4, 2024
1 parent 60980bb commit e2e3aa0
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
8 changes: 8 additions & 0 deletions port.c
Original file line number Diff line number Diff line change
Expand Up @@ -1399,6 +1399,8 @@ static void port_synchronize(struct port *p,
break;
}

sad_set_last_seqid(clock_config(p->clock), p->spp, seqid);

last_state = clock_servo_state(p->clock);
state = clock_synchronize(p->clock, t2, t1c);
switch (state) {
Expand Down Expand Up @@ -2824,6 +2826,7 @@ static void port_e2e_transition(struct port *p, enum port_state next)
case PS_FAULTY:
case PS_DISABLED:
port_disable(p);
sad_set_last_seqid(clock_config(p->clock), p->spp, -1);
break;
case PS_LISTENING:
port_set_announce_tmo(p);
Expand All @@ -2837,13 +2840,15 @@ static void port_e2e_transition(struct port *p, enum port_state next)
set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/
}
port_set_sync_tx_tmo(p);
sad_set_last_seqid(clock_config(p->clock), p->spp, -1);
break;
case PS_PASSIVE:
port_set_announce_tmo(p);
break;
case PS_UNCALIBRATED:
flush_last_sync(p);
flush_delay_req(p);
sad_set_last_seqid(clock_config(p->clock), p->spp, -1);
/* fall through */
case PS_SLAVE:
port_set_announce_tmo(p);
Expand All @@ -2868,6 +2873,7 @@ static void port_p2p_transition(struct port *p, enum port_state next)
case PS_FAULTY:
case PS_DISABLED:
port_disable(p);
sad_set_last_seqid(clock_config(p->clock), p->spp, -1);
break;
case PS_LISTENING:
port_set_announce_tmo(p);
Expand All @@ -2882,13 +2888,15 @@ static void port_p2p_transition(struct port *p, enum port_state next)
set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/
}
port_set_sync_tx_tmo(p);
sad_set_last_seqid(clock_config(p->clock), p->spp, -1);
break;
case PS_PASSIVE:
port_set_announce_tmo(p);
break;
case PS_UNCALIBRATED:
flush_last_sync(p);
flush_peer_delay(p);
sad_set_last_seqid(clock_config(p->clock), p->spp, -1);
/* fall through */
case PS_SLAVE:
port_set_announce_tmo(p);
Expand Down
72 changes: 72 additions & 0 deletions sad.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,73 @@ static inline size_t sad_get_auth_tlv_len(struct security_association *sa,
icv_len; /* size of icv (defined by key) */
}

/**
* update the last received seqid
*/
void sad_set_last_seqid(struct config *cfg,
int spp, Integer32 seqid)
{
struct security_association* sa;
/* immediately return if security is not configured */
if (spp < 0) {
return;
}
/* retrieve sa specified by spp */
sa = sad_get_association(cfg, spp);
if (!sa) {
return;
}

sa->last_seqid = (seqid == -1) ? seqid : (UInteger16) seqid;
}

/**
* confirm seqid from inbound message header is with in seqid window.
*/
static int sad_check_seqid(struct ptp_message *msg,
Integer32 last_seqid,
UInteger16 seqid_window)
{
UInteger16 new_seqid;
/* do not check seqid if seqid_window is zero */
if (seqid_window < 1) {
return 0;
}

/* (for now) only check seqid on sync/followup msgs */
switch (msg_type(msg)) {
case SYNC:
case FOLLOW_UP:
new_seqid = msg->header.sequenceId;
/* last_seqid < 0 means unitialized */
if (last_seqid < 0) {
return 0;
/* verify received seqid is greater than last */
/* use mod(uint16) to handle wrap within window */
} else if (new_seqid < (UInteger16)(last_seqid + 1) &&
(UInteger16)(new_seqid + seqid_window) <
(UInteger16)(last_seqid + 1 + seqid_window)) {
pr_debug("replayed seqid: received seqid %u "
"smaller than last %u",
new_seqid, last_seqid);
return -EBADMSG;
/* verify received seqid is less than seqid window */
/* use mod(uint16) to handle wrap within window */
} else if (new_seqid > (UInteger16)(last_seqid + seqid_window) &&
(UInteger16)(new_seqid + seqid_window) >
(UInteger16)(last_seqid + 2 * seqid_window)) {
pr_debug("replayed seqid: received seqid %u "
"beyond seqid_window %u + %d",
new_seqid, last_seqid, seqid_window);
return -EBADMSG;
}
break;
default:
break;
}
return 0;
}

static int sad_check_auth_tlv(struct security_association *sa,
struct ptp_message *msg,
struct ptp_message *raw)
Expand Down Expand Up @@ -180,6 +247,11 @@ int sad_process_auth(struct config *cfg, int spp,
if (!sa) {
return -EPROTO;
}
/* check seqid in header first (sync/followup only) */
err = sad_check_seqid(msg, sa->last_seqid, sa->seqid_window);
if (err) {
return err;
}
/* detect and process any auth tlvs */
err = sad_check_auth_tlv(sa, msg, raw);
return err;
Expand Down
9 changes: 9 additions & 0 deletions sad.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ struct security_association {
Integer32 last_seqid;
};

/**
* Set the last received sequence id for SYNC/FOLLOW_UP
* @param cfg pointer to config that contains sad
* @param spp security parameters pointer for desired sa
* @param seqid sequence id to store in SA
*/
void sad_set_last_seqid(struct config *cfg,
int spp, Integer32 seqid);

/**
* inbound message authentication processing:
* 1. check seqid (on sync/followup)
Expand Down

0 comments on commit e2e3aa0

Please sign in to comment.