@@ -182,6 +182,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
182182 sctp_supported_ext_param_t ext_param ;
183183 int num_ext = 0 ;
184184 __u8 extensions [3 ];
185+ sctp_paramhdr_t * auth_chunks = NULL ,
186+ * auth_hmacs = NULL ;
185187
186188 /* RFC 2960 3.3.2 Initiation (INIT) (1)
187189 *
@@ -214,8 +216,6 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
214216 * An implementation supporting this extension [ADDIP] MUST list
215217 * the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and
216218 * INIT-ACK parameters.
217- * XXX: We don't support AUTH just yet, so don't list it. AUTH
218- * support should add it.
219219 */
220220 if (sctp_addip_enable ) {
221221 extensions [num_ext ] = SCTP_CID_ASCONF ;
@@ -226,6 +226,29 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
226226 chunksize += sizeof (aiparam );
227227 chunksize += vparam_len ;
228228
229+ /* Account for AUTH related parameters */
230+ if (sctp_auth_enable ) {
231+ /* Add random parameter length*/
232+ chunksize += sizeof (asoc -> c .auth_random );
233+
234+ /* Add HMACS parameter length if any were defined */
235+ auth_hmacs = (sctp_paramhdr_t * )asoc -> c .auth_hmacs ;
236+ if (auth_hmacs -> length )
237+ chunksize += ntohs (auth_hmacs -> length );
238+ else
239+ auth_hmacs = NULL ;
240+
241+ /* Add CHUNKS parameter length */
242+ auth_chunks = (sctp_paramhdr_t * )asoc -> c .auth_chunks ;
243+ if (auth_chunks -> length )
244+ chunksize += ntohs (auth_chunks -> length );
245+ else
246+ auth_hmacs = NULL ;
247+
248+ extensions [num_ext ] = SCTP_CID_AUTH ;
249+ num_ext += 1 ;
250+ }
251+
229252 /* If we have any extensions to report, account for that */
230253 if (num_ext )
231254 chunksize += sizeof (sctp_supported_ext_param_t ) + num_ext ;
@@ -285,6 +308,17 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
285308 aiparam .adaptation_ind = htonl (sp -> adaptation_ind );
286309 sctp_addto_chunk (retval , sizeof (aiparam ), & aiparam );
287310
311+ /* Add SCTP-AUTH chunks to the parameter list */
312+ if (sctp_auth_enable ) {
313+ sctp_addto_chunk (retval , sizeof (asoc -> c .auth_random ),
314+ asoc -> c .auth_random );
315+ if (auth_hmacs )
316+ sctp_addto_chunk (retval , ntohs (auth_hmacs -> length ),
317+ auth_hmacs );
318+ if (auth_chunks )
319+ sctp_addto_chunk (retval , ntohs (auth_chunks -> length ),
320+ auth_chunks );
321+ }
288322nodata :
289323 kfree (addrs .v );
290324 return retval ;
@@ -305,6 +339,9 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
305339 sctp_supported_ext_param_t ext_param ;
306340 int num_ext = 0 ;
307341 __u8 extensions [3 ];
342+ sctp_paramhdr_t * auth_chunks = NULL ,
343+ * auth_hmacs = NULL ,
344+ * auth_random = NULL ;
308345
309346 retval = NULL ;
310347
@@ -350,6 +387,26 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
350387 chunksize += sizeof (ext_param ) + num_ext ;
351388 chunksize += sizeof (aiparam );
352389
390+ if (asoc -> peer .auth_capable ) {
391+ auth_random = (sctp_paramhdr_t * )asoc -> c .auth_random ;
392+ chunksize += ntohs (auth_random -> length );
393+
394+ auth_hmacs = (sctp_paramhdr_t * )asoc -> c .auth_hmacs ;
395+ if (auth_hmacs -> length )
396+ chunksize += ntohs (auth_hmacs -> length );
397+ else
398+ auth_hmacs = NULL ;
399+
400+ auth_chunks = (sctp_paramhdr_t * )asoc -> c .auth_chunks ;
401+ if (auth_chunks -> length )
402+ chunksize += ntohs (auth_chunks -> length );
403+ else
404+ auth_chunks = NULL ;
405+
406+ extensions [num_ext ] = SCTP_CID_AUTH ;
407+ num_ext += 1 ;
408+ }
409+
353410 /* Now allocate and fill out the chunk. */
354411 retval = sctp_make_chunk (asoc , SCTP_CID_INIT_ACK , 0 , chunksize );
355412 if (!retval )
@@ -381,6 +438,17 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
381438 aiparam .adaptation_ind = htonl (sctp_sk (asoc -> base .sk )-> adaptation_ind );
382439 sctp_addto_chunk (retval , sizeof (aiparam ), & aiparam );
383440
441+ if (asoc -> peer .auth_capable ) {
442+ sctp_addto_chunk (retval , ntohs (auth_random -> length ),
443+ auth_random );
444+ if (auth_hmacs )
445+ sctp_addto_chunk (retval , ntohs (auth_hmacs -> length ),
446+ auth_hmacs );
447+ if (auth_chunks )
448+ sctp_addto_chunk (retval , ntohs (auth_chunks -> length ),
449+ auth_chunks );
450+ }
451+
384452 /* We need to remove the const qualifier at this point. */
385453 retval -> asoc = (struct sctp_association * ) asoc ;
386454
@@ -1736,6 +1804,12 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
17361804 !asoc -> peer .prsctp_capable )
17371805 asoc -> peer .prsctp_capable = 1 ;
17381806 break ;
1807+ case SCTP_CID_AUTH :
1808+ /* if the peer reports AUTH, assume that he
1809+ * supports AUTH.
1810+ */
1811+ asoc -> peer .auth_capable = 1 ;
1812+ break ;
17391813 case SCTP_CID_ASCONF :
17401814 case SCTP_CID_ASCONF_ACK :
17411815 /* don't need to do anything for ASCONF */
@@ -1871,7 +1945,42 @@ static int sctp_verify_param(const struct sctp_association *asoc,
18711945 case SCTP_PARAM_FWD_TSN_SUPPORT :
18721946 if (sctp_prsctp_enable )
18731947 break ;
1948+ goto fallthrough ;
1949+
1950+ case SCTP_PARAM_RANDOM :
1951+ if (!sctp_auth_enable )
1952+ goto fallthrough ;
1953+
1954+ /* SCTP-AUTH: Secion 6.1
1955+ * If the random number is not 32 byte long the association
1956+ * MUST be aborted. The ABORT chunk SHOULD contain the error
1957+ * cause 'Protocol Violation'.
1958+ */
1959+ if (SCTP_AUTH_RANDOM_LENGTH !=
1960+ ntohs (param .p -> length ) - sizeof (sctp_paramhdr_t ))
1961+ return sctp_process_inv_paramlength (asoc , param .p ,
1962+ chunk , err_chunk );
1963+ break ;
1964+
1965+ case SCTP_PARAM_CHUNKS :
1966+ if (!sctp_auth_enable )
1967+ goto fallthrough ;
1968+
1969+ /* SCTP-AUTH: Section 3.2
1970+ * The CHUNKS parameter MUST be included once in the INIT or
1971+ * INIT-ACK chunk if the sender wants to receive authenticated
1972+ * chunks. Its maximum length is 260 bytes.
1973+ */
1974+ if (260 < ntohs (param .p -> length ))
1975+ return sctp_process_inv_paramlength (asoc , param .p ,
1976+ chunk , err_chunk );
1977+ break ;
1978+
1979+ case SCTP_PARAM_HMAC_ALGO :
1980+ if (!sctp_auth_enable )
1981+ break ;
18741982 /* Fall Through */
1983+ fallthrough :
18751984 default :
18761985 SCTP_DEBUG_PRINTK ("Unrecognized param: %d for chunk %d.\n" ,
18771986 ntohs (param .p -> type ), cid );
@@ -1976,13 +2085,19 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
19762085 }
19772086
19782087 /* Process the initialization parameters. */
1979-
19802088 sctp_walk_params (param , peer_init , init_hdr .params ) {
19812089
19822090 if (!sctp_process_param (asoc , param , peer_addr , gfp ))
19832091 goto clean_up ;
19842092 }
19852093
2094+ /* AUTH: After processing the parameters, make sure that we
2095+ * have all the required info to potentially do authentications.
2096+ */
2097+ if (asoc -> peer .auth_capable && (!asoc -> peer .peer_random ||
2098+ !asoc -> peer .peer_hmacs ))
2099+ asoc -> peer .auth_capable = 0 ;
2100+
19862101 /* Walk list of transports, removing transports in the UNKNOWN state. */
19872102 list_for_each_safe (pos , temp , & asoc -> peer .transport_addr_list ) {
19882103 transport = list_entry (pos , struct sctp_transport , transports );
@@ -2222,6 +2337,47 @@ static int sctp_process_param(struct sctp_association *asoc,
22222337 break ;
22232338 }
22242339 /* Fall Through */
2340+ goto fall_through ;
2341+
2342+ case SCTP_PARAM_RANDOM :
2343+ if (!sctp_auth_enable )
2344+ goto fall_through ;
2345+
2346+ /* Save peer's random parameter */
2347+ asoc -> peer .peer_random = kmemdup (param .p ,
2348+ ntohs (param .p -> length ), gfp );
2349+ if (!asoc -> peer .peer_random ) {
2350+ retval = 0 ;
2351+ break ;
2352+ }
2353+ break ;
2354+
2355+ case SCTP_PARAM_HMAC_ALGO :
2356+ if (!sctp_auth_enable )
2357+ goto fall_through ;
2358+
2359+ /* Save peer's HMAC list */
2360+ asoc -> peer .peer_hmacs = kmemdup (param .p ,
2361+ ntohs (param .p -> length ), gfp );
2362+ if (!asoc -> peer .peer_hmacs ) {
2363+ retval = 0 ;
2364+ break ;
2365+ }
2366+
2367+ /* Set the default HMAC the peer requested*/
2368+ sctp_auth_asoc_set_default_hmac (asoc , param .hmac_algo );
2369+ break ;
2370+
2371+ case SCTP_PARAM_CHUNKS :
2372+ if (!sctp_auth_enable )
2373+ goto fall_through ;
2374+
2375+ asoc -> peer .peer_chunks = kmemdup (param .p ,
2376+ ntohs (param .p -> length ), gfp );
2377+ if (!asoc -> peer .peer_chunks )
2378+ retval = 0 ;
2379+ break ;
2380+ fall_through :
22252381 default :
22262382 /* Any unrecognized parameters should have been caught
22272383 * and handled by sctp_verify_param() which should be
0 commit comments