struct sctp_sndrcvinfo *srinfo;
        struct sctp_sndinfo *sinfo;
        struct sctp_prinfo *prinfo;
+       struct sctp_authinfo *authinfo;
        struct msghdr *addrs_msg;
 };
 
 
        __u32 pr_value;
 };
 
+/* 5.3.8 SCTP AUTH Information Structure (SCTP_AUTHINFO)
+ *
+ *   This cmsghdr structure specifies SCTP options for sendmsg().
+ *
+ *   cmsg_level    cmsg_type      cmsg_data[]
+ *   ------------  ------------   -------------------
+ *   IPPROTO_SCTP  SCTP_AUTHINFO  struct sctp_authinfo
+ */
+struct sctp_authinfo {
+       __u16 auth_keynumber;
+};
+
 /*
  *  sinfo_flags: 16 bits (unsigned integer)
  *
 #define SCTP_NXTINFO   SCTP_NXTINFO
        SCTP_PRINFO,            /* 5.3.7 SCTP PR-SCTP Information Structure */
 #define SCTP_PRINFO    SCTP_PRINFO
-       SCTP_AUTHINFO,          /* 5.3.8 SCTP AUTH Information Structure (RESERVED) */
+       SCTP_AUTHINFO,          /* 5.3.8 SCTP AUTH Information Structure */
 #define SCTP_AUTHINFO  SCTP_AUTHINFO
        SCTP_DSTADDRV4,         /* 5.3.9 SCTP Destination IPv4 Address Structure */
 #define SCTP_DSTADDRV4 SCTP_DSTADDRV4
 
                        max_data -= SCTP_PAD4(sizeof(struct sctp_auth_chunk) +
                                              hmac_desc->hmac_len);
 
-               shkey = asoc->shkey;
+               if (sinfo->sinfo_tsn &&
+                   sinfo->sinfo_ssn != asoc->active_key_id) {
+                       shkey = sctp_auth_get_shkey(asoc, sinfo->sinfo_ssn);
+                       if (!shkey) {
+                               err = -EINVAL;
+                               goto errout;
+                       }
+               } else {
+                       shkey = asoc->shkey;
+               }
        }
 
        /* Check what's our max considering the above */
 
 
        if (!cmsgs->srinfo && !cmsgs->prinfo)
                sinfo->sinfo_timetolive = asoc->default_timetolive;
+
+       if (cmsgs->authinfo) {
+               /* Reuse sinfo_tsn to indicate that authinfo was set and
+                * sinfo_ssn to save the keyid on tx path.
+                */
+               sinfo->sinfo_tsn = 1;
+               sinfo->sinfo_ssn = cmsgs->authinfo->auth_keynumber;
+       }
 }
 
 static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
                        if (cmsgs->prinfo->pr_policy == SCTP_PR_SCTP_NONE)
                                cmsgs->prinfo->pr_value = 0;
                        break;
+               case SCTP_AUTHINFO:
+                       /* SCTP Socket API Extension
+                        * 5.3.8 SCTP AUTH Information Structure (SCTP_AUTHINFO)
+                        *
+                        * This cmsghdr structure specifies SCTP options for sendmsg().
+                        *
+                        * cmsg_level    cmsg_type      cmsg_data[]
+                        * ------------  ------------   ---------------------
+                        * IPPROTO_SCTP  SCTP_AUTHINFO  struct sctp_authinfo
+                        */
+                       if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_authinfo)))
+                               return -EINVAL;
+
+                       cmsgs->authinfo = CMSG_DATA(cmsg);
+                       break;
                case SCTP_DSTADDRV4:
                case SCTP_DSTADDRV6:
                        /* SCTP Socket API Extension