diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l
index 647f775b17c4192112df7b9fb20dfeab5f0acaf1..e00de6cb8047587d178ea083e50a1e837ee75f19 100644
--- a/gtests/net/packetdrill/lexer.l
+++ b/gtests/net/packetdrill/lexer.l
@@ -307,6 +307,12 @@ sac_outbound_streams            return SAC_OUTBOUND_STREAMS;
 sac_inbound_streams             return SAC_INBOUND_STREAMS;
 sac_assoc_id                    return SAC_ASSOC_ID;
 sac_info                        return SAC_INFO;
+auth_type                       return AUTH_TYPE;
+auth_flags                      return AUTH_FLAGS;
+auth_length                     return AUTH_LENGTH;
+auth_keynumber                  return AUTH_KEYNUMBER;
+auth_indication                 return AUTH_INDICATION;
+auth_assoc_id                   return AUTH_ASSOC_ID;
 sender_dry_type                 return SENDER_DRY_TYPE;
 sender_dry_flags                return SENDER_DRY_FLAGS;
 sender_dry_length               return SENDER_DRY_LENGTH;
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index a224bc494d2a75d78eec22da076781ef0ea2bd0c..14838d613145e41603fb7db3acbd9eb70e1bbf58 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -556,6 +556,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> SAC_TYPE SAC_FLAGS SAC_LENGTH SAC_STATE SAC_ERROR SAC_OUTBOUND_STREAMS
 %token <reserved> SAC_INBOUND_STREAMS SAC_ASSOC_ID SAC_INFO
 %token <reserved> SSFE_TYPE SSFE_FLAGS SSFE_LENGTH SSFE_ERROR SSFE_INFO SSFE_ASSOC_ID SSFE_DATA
+%token <reserved> AUTH_TYPE AUTH_FLAGS AUTH_LENGTH AUTH_INDICATION AUTH_ASSOC_ID
 %token <floating> FLOAT
 %token <integer> INTEGER HEX_INTEGER
 %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR
@@ -617,6 +618,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %type <expression> sctp_assoc_change sac_type sac_flags sac_length sac_state sac_error sac_outbound_streams
 %type <expression> sac_inbound_streams sac_assoc_id sac_info
 %type <expression> sctp_send_failed_event ssfe_type ssfe_flags ssfe_length ssfe_error ssfe_assoc_id
+%type <expression> sctp_authkey_event auth_type auth_flags auth_length auth_keynumber auth_indication auth_assoc_id
 %type <errno_info> opt_errno
 %type <chunk_list> sctp_chunk_list_spec
 %type <chunk_list_item> sctp_chunk_spec
@@ -2595,6 +2597,7 @@ data
 | sctp_shutdown_event       { $$ = $1; }
 | sctp_sender_dry_event     { $$ = $1; }
 | sctp_send_failed_event    { $$ = $1; }
+| sctp_authkey_event        { $$ = $1; }
 ;
 
 msghdr
@@ -3580,6 +3583,87 @@ sctp_shutdown_event
 	$$->value.sctp_shutdown_event->sse_length = $6;
 };
 
+auth_type
+: AUTH_TYPE '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("auth_type out of range");
+	}
+	$$ = new_integer_expression($3, "%hu");
+}
+| AUTH_TYPE '=' WORD {
+	$$ = new_expression(EXPR_WORD);
+	$$->value.string = $3;
+}
+| AUTH_TYPE '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+auth_flags
+: AUTH_FLAGS '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("auth_flags out of range");
+	}
+	$$ = new_integer_expression($3, "%hu");
+}
+| AUTH_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+auth_length
+: AUTH_LENGTH '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("auth_length out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| AUTH_LENGTH '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+auth_keynumber
+: AUTH_KEYNUMBER '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("auth_keynumber out of range");
+	}
+	$$ = new_integer_expression($3, "%hu");
+}
+| AUTH_KEYNUMBER '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+auth_indication
+: AUTH_INDICATION '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("auth_indication out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| AUTH_INDICATION '=' WORD {
+	$$ = new_expression(EXPR_WORD);
+	$$->value.string = $3;
+}
+| AUTH_INDICATION '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+auth_assoc_id
+: AUTH_ASSOC_ID '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("auth_assoc_id out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| AUTH_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+sctp_authkey_event
+: '{' auth_type ',' auth_flags ',' auth_length ',' auth_keynumber ',' auth_indication ',' auth_assoc_id '}' {
+	$$ = new_expression(EXPR_SCTP_AUTHKEY_EVENT);
+	$$->value.sctp_authkey_event = calloc(1, sizeof(struct sctp_authkey_event_expr));
+	$$->value.sctp_authkey_event->auth_type = $2;
+	$$->value.sctp_authkey_event->auth_flags = $4;
+	$$->value.sctp_authkey_event->auth_length = $6;
+	$$->value.sctp_authkey_event->auth_keynumber = $8;
+	$$->value.sctp_authkey_event->auth_indication = $10;
+	$$->value.sctp_authkey_event->auth_assoc_id = $12;
+}
+;
+
 sender_dry_type
 : SENDER_DRY_TYPE '=' INTEGER {
 	if (!is_valid_u16($3)) {
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index bb38680c19303cf5e3b1e0502ab2490395ca3dd5..040c41965f3536ebed68c02f793f8ea470539672 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -528,6 +528,7 @@ static int iovec_new(struct expression *expression,
 		assert(iov_expr->iov_base->type == EXPR_ELLIPSIS ||
 		       iov_expr->iov_base->type == EXPR_SCTP_ASSOC_CHANGE ||
 		       iov_expr->iov_base->type == EXPR_SCTP_SHUTDOWN_EVENT ||
+		       iov_expr->iov_base->type == EXPR_SCTP_AUTHKEY_EVENT ||
 		       iov_expr->iov_base->type == EXPR_SCTP_SENDER_DRY_EVENT ||
 		       iov_expr->iov_base->type == EXPR_SCTP_SEND_FAILED_EVENT);
 		assert(iov_expr->iov_len->type == EXPR_INTEGER);
@@ -3438,6 +3439,34 @@ static int check_sctp_shutdown_event(struct sctp_shutdown_event_expr *expr,
 }
 #endif
 
+#if defined(__FreeBSD__) || defined(linux)
+static int check_sctp_authkey_event(struct sctp_authkey_event_expr *expr,
+				     struct sctp_authkey_event *sctp_event,
+				     char **error) {
+
+	if (check_u16_expr(expr->auth_type, sctp_event->auth_type,
+			   "sctp_authkey_event.auth_type", error))
+		return STATUS_ERR;
+	if (check_u16_expr(expr->auth_flags, sctp_event->auth_flags,
+			   "sctp_authkey_event.auth_flags", error))
+		return STATUS_ERR;
+	if (check_u32_expr(expr->auth_length, sctp_event->auth_length,
+			   "sctp_authkey_event.auth_length", error))
+		return STATUS_ERR;
+	if (check_u16_expr(expr->auth_keynumber, sctp_event->auth_keynumber,
+			   "sctp_authkey_event.auth_keynumber", error))
+		return STATUS_ERR;
+	if (check_u32_expr(expr->auth_indication, sctp_event->auth_indication,
+			   "sctp_authkey_event.auth_indication", error))
+		return STATUS_ERR;
+	if (check_u32_expr(expr->auth_assoc_id, sctp_event->auth_assoc_id,
+			   "sctp_authkey_event.auth_assoc_id", error))
+		return STATUS_ERR;
+
+	return STATUS_OK;
+}
+#endif
+
 #if defined(__FreeBSD__) || defined(linux)
 static int check_sctp_sender_dry_event(struct sctp_sender_dry_event_expr *expr,
 				       struct sctp_sender_dry_event *sctp_event,
@@ -3518,6 +3547,12 @@ static int check_sctp_notification(struct iovec *iov,
 						      error))
 				return STATUS_ERR;
 			break;
+		case EXPR_SCTP_AUTHKEY_EVENT:
+			if (check_sctp_authkey_event(script_iov_base->value.sctp_authkey_event,
+						     (struct sctp_authkey_event *) iov->iov_base,
+						     error))
+				return STATUS_ERR;
+			break;
 		case EXPR_SCTP_SENDER_DRY_EVENT:
 			if (check_sctp_sender_dry_event(script_iov_base->value.sctp_sender_dry_event,
 						       (struct sctp_sender_dry_event *) iov->iov_base,
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index 5ceb9c6d00475a120085b825197acaa434a0a46b..a20c7f14d4f2eda680fd327bcff566a2bf3c610a 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -88,6 +88,7 @@ struct expression_type_entry expression_type_table[] = {
 	{ EXPR_SCTP_RECVV_RN,        "sctp_recvv_rn "  },
 	{ EXPR_SCTP_ASSOC_CHANGE,    "sctp_assoc_change"},
 	{ EXPR_SCTP_SHUTDOWN_EVENT,  "sctp_shutdown_event"},
+	{ EXPR_SCTP_AUTHKEY_EVENT,   "sctp_authkey_event"},
 	{ EXPR_SCTP_SENDER_DRY_EVENT,"sctp_sender_dry_event"},
 	{ EXPR_SCTP_SEND_FAILED_EVENT,"sctp_send_failed_event"},
 	{ NUM_EXPR_TYPES,            NULL}
@@ -449,6 +450,14 @@ void free_expression(struct expression *expression)
 		free_expression(expression->value.sctp_shutdown_event->sse_flags);
 		free_expression(expression->value.sctp_shutdown_event->sse_length);
 		break;
+	case EXPR_SCTP_AUTHKEY_EVENT:
+		free_expression(expression->value.sctp_authkey_event->auth_type);
+		free_expression(expression->value.sctp_authkey_event->auth_flags);
+		free_expression(expression->value.sctp_authkey_event->auth_length);
+		free_expression(expression->value.sctp_authkey_event->auth_keynumber);
+		free_expression(expression->value.sctp_authkey_event->auth_indication);
+		free_expression(expression->value.sctp_authkey_event->auth_assoc_id);
+		break;
 	case EXPR_SCTP_SENDER_DRY_EVENT:
 		free_expression(expression->value.sctp_sender_dry_event->sender_dry_type);
 		free_expression(expression->value.sctp_sender_dry_event->sender_dry_flags);
@@ -1462,6 +1471,50 @@ static int evaluate_sctp_shutdown_event_expression(struct expression *in,
 	return STATUS_OK;
 }
 
+static int evaluate_sctp_authkey_event_expression(struct expression *in,
+						   struct expression *out,
+						   char **error)
+{
+	struct sctp_authkey_event_expr *in_event;
+	struct sctp_authkey_event_expr *out_event;
+
+	assert(in->type == EXPR_SCTP_AUTHKEY_EVENT);
+	assert(in->value.sctp_authkey_event);
+	assert(out->type == EXPR_SCTP_AUTHKEY_EVENT);
+
+	out->value.sctp_authkey_event = calloc(1, sizeof(struct sctp_authkey_event_expr));
+
+	in_event = in->value.sctp_authkey_event;
+	out_event = out->value.sctp_authkey_event;
+
+	if (evaluate(in_event->auth_type,
+		     &out_event->auth_type,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->auth_flags,
+		     &out_event->auth_flags,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->auth_length,
+		     &out_event->auth_length,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->auth_keynumber,
+		     &out_event->auth_keynumber,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->auth_indication,
+		     &out_event->auth_indication,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->auth_assoc_id,
+		     &out_event->auth_assoc_id,
+		     error))
+		return STATUS_ERR;
+
+	return STATUS_OK;
+}
+
 static int evaluate_sctp_sender_dry_event_expression(struct expression *in,
 						     struct expression *out,
 						     char **error)
@@ -1637,6 +1690,9 @@ static int evaluate(struct expression *in,
 	case EXPR_SCTP_SHUTDOWN_EVENT:
 		result = evaluate_sctp_shutdown_event_expression(in, out, error);
 		break;
+	case EXPR_SCTP_AUTHKEY_EVENT:
+		result = evaluate_sctp_authkey_event_expression(in, out, error);
+		break;
 	case EXPR_SCTP_SENDER_DRY_EVENT:
 		result = evaluate_sctp_sender_dry_event_expression(in, out, error);
 		break;
diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h
index fe4463278ac4f5c7abd38274f148f0acc058b70d..fdf4a7f148ccec9a679fadae22391a240a8c1667 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -68,6 +68,7 @@ enum expression_t {
 	EXPR_SCTP_RECVV_RN,       /* struct sctp_recvv_rn for syscall sctp_recvv */
 	EXPR_SCTP_ASSOC_CHANGE,   /* expression tree for sctp_assoc_change_event */
 	EXPR_SCTP_SHUTDOWN_EVENT, /* expression tree for sctp_shutdown_event */
+	EXPR_SCTP_AUTHKEY_EVENT,  /* expression tree for sctp_authentication_event */
 	EXPR_SCTP_SENDER_DRY_EVENT, /* expression tree for sctp_sender_dry_event */
 	EXPR_SCTP_SEND_FAILED_EVENT, /* expression tree for sctp_send_failed_event */
 	NUM_EXPR_TYPES,
@@ -111,6 +112,7 @@ struct expression {
 		struct sctp_recvv_rn_expr *sctp_recvv_rn;
 		struct sctp_assoc_change_expr *sctp_assoc_change;
 		struct sctp_shutdown_event_expr *sctp_shutdown_event;
+		struct sctp_authkey_event_expr *sctp_authkey_event;
 		struct sctp_sender_dry_event_expr *sctp_sender_dry_event;
 		struct sctp_send_failed_event_expr *sctp_send_failed_event;
 	} value;
@@ -343,6 +345,16 @@ struct sctp_shutdown_event_expr {
 	struct expression *sse_length;
 };
 
+/* Parse tree for sctp_authentication_event for notifications. */
+struct sctp_authkey_event_expr {
+	struct expression *auth_type;
+	struct expression *auth_flags;
+	struct expression *auth_length;
+	struct expression *auth_keynumber;
+	struct expression *auth_indication;
+	struct expression *auth_assoc_id;
+};
+
 /* Parse tree for sctp_sender_dry_event for notifications. */
 struct sctp_sender_dry_event_expr {
 	struct expression *sender_dry_type;
diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c
index a1aceb96f248cbfcd0b7e6d0fcf3572dc209391d..d4ee1bef97420a83a94e6778e7aee9e60b66946c 100644
--- a/gtests/net/packetdrill/symbols_freebsd.c
+++ b/gtests/net/packetdrill/symbols_freebsd.c
@@ -211,6 +211,9 @@ struct int_symbol platform_symbols_table[] = {
 	{ SCTP_COMM_LOST,                   "SCTP_COMM_LOST"                  },
 	{ SCTP_RESTART,                     "SCTP_RESTART"                    },
 	{ SCTP_SHUTDOWN_COMP,               "SCTP_SHUTDOWN_COMP"              },
+	{ SCTP_AUTH_NEW_KEY,                "SCTP_AUTH_NEW_KEY"               },
+	{ SCTP_AUTH_NO_AUTH,                "SCTP_AUTH_NO_AUTH"               },
+	{ SCTP_AUTH_FREE_KEY,               "SCTP_AUTH_FREE_KEY"              },
 	{ SCTP_ASSOC_SUPPORTS_PR,           "SCTP_ASSOC_SUPPORTS_PR"          },
 	{ SCTP_ASSOC_SUPPORTS_AUTH,         "SCTP_ASSOC_SUPPORTS_AUTH"        },
 	{ SCTP_ASSOC_SUPPORTS_ASCONF,       "SCTP_ASSOC_SUPPORTS_ASCONF"      },
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_assoc_change_event.pkt b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_assoc_change_event.pkt
index 88a49593e833e1363063e09c5680a5fc20992183..dcbf791c2fec9bc3af303e1a6e51684f79c8eb39 100644
--- a/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_assoc_change_event.pkt
+++ b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_assoc_change_event.pkt
@@ -11,8 +11,7 @@
 +0.1 < sctp: COOKIE_ACK[flgs=0]
 +0.0 sctp_recvv(3, [{iov_base={sac_type=SCTP_ASSOC_CHANGE, sac_flags=0, sac_length=21, sac_state=SCTP_COMM_UP, sac_error=0, sac_outbound_streams=1, 
 sac_inbound_streams=1, sac_assoc_id=3, sac_info=[SCTP_ASSOC_SUPPORTS_MULTIBUF, 0x00]}, iov_len=1000}], 1, ..., 20, NULL, [0], [SCTP_RECVV_NOINFO], 
-[MSG_NOTIFICATION|MSG_EOR]) 
-= 21
+[MSG_NOTIFICATION|MSG_EOR]) = 21
 
 +0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
 +0.0 < sctp: SHUTDOWN[flgs=0, cum_tsn=0]
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_authentication_event.pkt b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_authentication_event.pkt
new file mode 100644
index 0000000000000000000000000000000000000000..cf7a4ce7ec91e5ddd463685b57cb12342a8c4595
--- /dev/null
+++ b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_authentication_event.pkt
@@ -0,0 +1,20 @@
++0.0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3
++0.0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
++0.0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
+// Check the handshake with an empty(!) cookie
++0.1 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_AUTHENTICATION_EVENT, se_on=1}, 8) = 0
++0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_AUTHENTICATION_EVENT, se_on=1}, [8]) = 0
++0.0 > sctp: INIT[flgs=0, tag=1, a_rwnd=..., os=..., is=..., tsn=1, ...]
++0.1 < sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=1500, os=1, is=1, tsn=1, STATE_COOKIE[len=4, val=...]]
++0.0 > sctp: COOKIE_ECHO[flgs=0, len=4, val=...]
++0.1 < sctp: COOKIE_ACK[flgs=0]
+
++0.0 sctp_recvv(3, [{iov_base={auth_type=SCTP_AUTHENTICATION_EVENT, auth_flags=0, auth_length=20, auth_keynumber=0, auth_indication=SCTP_AUTH_NO_AUTH,
+auth_assoc_id=3}, iov_len=1000}], 1, ..., 20, NULL, [0], [SCTP_RECVV_NOINFO], [MSG_NOTIFICATION|MSG_EOR]) = 20
+
++0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
++0.0 < sctp: SHUTDOWN[flgs=0, cum_tsn=0]
+*    > sctp: SHUTDOWN_ACK[flgs=0]
++0.0 < sctp: SHUTDOWN_COMPLETE[flgs=0]
+