aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/command.h1
-rw-r--r--net/sctp/associola.c21
-rw-r--r--net/sctp/sm_make_chunk.c162
-rw-r--r--net/sctp/sm_sideeffect.c5
-rw-r--r--net/sctp/sm_statefuns.c35
5 files changed, 220 insertions, 4 deletions
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index f56c8d695a82..b8733364557f 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -102,6 +102,7 @@ typedef enum {
102 SCTP_CMD_SET_SK_ERR, /* Set sk_err */ 102 SCTP_CMD_SET_SK_ERR, /* Set sk_err */
103 SCTP_CMD_ASSOC_CHANGE, /* generate and send assoc_change event */ 103 SCTP_CMD_ASSOC_CHANGE, /* generate and send assoc_change event */
104 SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */ 104 SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */
105 SCTP_CMD_ASSOC_SHKEY, /* generate the association shared keys */
105 SCTP_CMD_LAST 106 SCTP_CMD_LAST
106} sctp_verb_t; 107} sctp_verb_t;
107 108
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index ee4b212e66b1..3bdd8dcb76a7 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -415,6 +415,9 @@ void sctp_association_free(struct sctp_association *asoc)
415 415
416 /* Free peer's cached cookie. */ 416 /* Free peer's cached cookie. */
417 kfree(asoc->peer.cookie); 417 kfree(asoc->peer.cookie);
418 kfree(asoc->peer.peer_random);
419 kfree(asoc->peer.peer_chunks);
420 kfree(asoc->peer.peer_hmacs);
418 421
419 /* Release the transport structures. */ 422 /* Release the transport structures. */
420 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { 423 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
@@ -1145,7 +1148,23 @@ void sctp_assoc_update(struct sctp_association *asoc,
1145 } 1148 }
1146 } 1149 }
1147 1150
1148 /* SCTP-AUTH: XXX something needs to be done here*/ 1151 /* SCTP-AUTH: Save the peer parameters from the new assocaitions
1152 * and also move the association shared keys over
1153 */
1154 kfree(asoc->peer.peer_random);
1155 asoc->peer.peer_random = new->peer.peer_random;
1156 new->peer.peer_random = NULL;
1157
1158 kfree(asoc->peer.peer_chunks);
1159 asoc->peer.peer_chunks = new->peer.peer_chunks;
1160 new->peer.peer_chunks = NULL;
1161
1162 kfree(asoc->peer.peer_hmacs);
1163 asoc->peer.peer_hmacs = new->peer.peer_hmacs;
1164 new->peer.peer_hmacs = NULL;
1165
1166 sctp_auth_key_put(asoc->asoc_shared_key);
1167 sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC);
1149} 1168}
1150 1169
1151/* Update the retran path for sending a retransmitted packet. 1170/* Update the retran path for sending a retransmitted packet.
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 71cc204a9ea5..4c02875786ac 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -182,6 +182,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
182 sctp_supported_ext_param_t ext_param; 182 sctp_supported_ext_param_t ext_param;
183 int num_ext = 0; 183 int num_ext = 0;
184 __u8 extensions[3]; 184 __u8 extensions[3];
185 sctp_paramhdr_t *auth_chunks = NULL,
186 *auth_hmacs = NULL;
185 187
186 /* RFC 2960 3.3.2 Initiation (INIT) (1) 188 /* RFC 2960 3.3.2 Initiation (INIT) (1)
187 * 189 *
@@ -214,8 +216,6 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
214 * An implementation supporting this extension [ADDIP] MUST list 216 * An implementation supporting this extension [ADDIP] MUST list
215 * the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and 217 * the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and
216 * INIT-ACK parameters. 218 * INIT-ACK parameters.
217 * XXX: We don't support AUTH just yet, so don't list it. AUTH
218 * support should add it.
219 */ 219 */
220 if (sctp_addip_enable) { 220 if (sctp_addip_enable) {
221 extensions[num_ext] = SCTP_CID_ASCONF; 221 extensions[num_ext] = SCTP_CID_ASCONF;
@@ -226,6 +226,29 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
226 chunksize += sizeof(aiparam); 226 chunksize += sizeof(aiparam);
227 chunksize += vparam_len; 227 chunksize += vparam_len;
228 228
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
229 /* If we have any extensions to report, account for that */ 252 /* If we have any extensions to report, account for that */
230 if (num_ext) 253 if (num_ext)
231 chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; 254 chunksize += sizeof(sctp_supported_ext_param_t) + num_ext;
@@ -285,6 +308,17 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
285 aiparam.adaptation_ind = htonl(sp->adaptation_ind); 308 aiparam.adaptation_ind = htonl(sp->adaptation_ind);
286 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam); 309 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
287 310
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 }
288nodata: 322nodata:
289 kfree(addrs.v); 323 kfree(addrs.v);
290 return retval; 324 return retval;
@@ -305,6 +339,9 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
305 sctp_supported_ext_param_t ext_param; 339 sctp_supported_ext_param_t ext_param;
306 int num_ext = 0; 340 int num_ext = 0;
307 __u8 extensions[3]; 341 __u8 extensions[3];
342 sctp_paramhdr_t *auth_chunks = NULL,
343 *auth_hmacs = NULL,
344 *auth_random = NULL;
308 345
309 retval = NULL; 346 retval = NULL;
310 347
@@ -350,6 +387,26 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
350 chunksize += sizeof(ext_param) + num_ext; 387 chunksize += sizeof(ext_param) + num_ext;
351 chunksize += sizeof(aiparam); 388 chunksize += sizeof(aiparam);
352 389
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
353 /* Now allocate and fill out the chunk. */ 410 /* Now allocate and fill out the chunk. */
354 retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); 411 retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
355 if (!retval) 412 if (!retval)
@@ -381,6 +438,17 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
381 aiparam.adaptation_ind = htonl(sctp_sk(asoc->base.sk)->adaptation_ind); 438 aiparam.adaptation_ind = htonl(sctp_sk(asoc->base.sk)->adaptation_ind);
382 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam); 439 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
383 440
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
384 /* We need to remove the const qualifier at this point. */ 452 /* We need to remove the const qualifier at this point. */
385 retval->asoc = (struct sctp_association *) asoc; 453 retval->asoc = (struct sctp_association *) asoc;
386 454
@@ -1736,6 +1804,12 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
1736 !asoc->peer.prsctp_capable) 1804 !asoc->peer.prsctp_capable)
1737 asoc->peer.prsctp_capable = 1; 1805 asoc->peer.prsctp_capable = 1;
1738 break; 1806 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;
1739 case SCTP_CID_ASCONF: 1813 case SCTP_CID_ASCONF:
1740 case SCTP_CID_ASCONF_ACK: 1814 case SCTP_CID_ASCONF_ACK:
1741 /* don't need to do anything for ASCONF */ 1815 /* don't need to do anything for ASCONF */
@@ -1871,7 +1945,42 @@ static int sctp_verify_param(const struct sctp_association *asoc,
1871 case SCTP_PARAM_FWD_TSN_SUPPORT: 1945 case SCTP_PARAM_FWD_TSN_SUPPORT:
1872 if (sctp_prsctp_enable) 1946 if (sctp_prsctp_enable)
1873 break; 1947 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;
1874 /* Fall Through */ 1982 /* Fall Through */
1983fallthrough:
1875 default: 1984 default:
1876 SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n", 1985 SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n",
1877 ntohs(param.p->type), cid); 1986 ntohs(param.p->type), cid);
@@ -1976,13 +2085,19 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
1976 } 2085 }
1977 2086
1978 /* Process the initialization parameters. */ 2087 /* Process the initialization parameters. */
1979
1980 sctp_walk_params(param, peer_init, init_hdr.params) { 2088 sctp_walk_params(param, peer_init, init_hdr.params) {
1981 2089
1982 if (!sctp_process_param(asoc, param, peer_addr, gfp)) 2090 if (!sctp_process_param(asoc, param, peer_addr, gfp))
1983 goto clean_up; 2091 goto clean_up;
1984 } 2092 }
1985 2093
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
1986 /* Walk list of transports, removing transports in the UNKNOWN state. */ 2101 /* Walk list of transports, removing transports in the UNKNOWN state. */
1987 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { 2102 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
1988 transport = list_entry(pos, struct sctp_transport, transports); 2103 transport = list_entry(pos, struct sctp_transport, transports);
@@ -2222,6 +2337,47 @@ static int sctp_process_param(struct sctp_association *asoc,
2222 break; 2337 break;
2223 } 2338 }
2224 /* Fall Through */ 2339 /* 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;
2380fall_through:
2225 default: 2381 default:
2226 /* Any unrecognized parameters should have been caught 2382 /* Any unrecognized parameters should have been caught
2227 * and handled by sctp_verify_param() which should be 2383 * and handled by sctp_verify_param() which should be
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 8d7890083493..bbdc938da86f 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1524,6 +1524,11 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1524 sctp_cmd_adaptation_ind(commands, asoc); 1524 sctp_cmd_adaptation_ind(commands, asoc);
1525 break; 1525 break;
1526 1526
1527 case SCTP_CMD_ASSOC_SHKEY:
1528 error = sctp_auth_asoc_init_active_key(asoc,
1529 GFP_ATOMIC);
1530 break;
1531
1527 default: 1532 default:
1528 printk(KERN_WARNING "Impossible command: %u, %p\n", 1533 printk(KERN_WARNING "Impossible command: %u, %p\n",
1529 cmd->verb, cmd->obj.ptr); 1534 cmd->verb, cmd->obj.ptr);
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index ec0328b1cdb1..385486360fe9 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -549,6 +549,11 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
549 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, 549 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
550 SCTP_STATE(SCTP_STATE_COOKIE_ECHOED)); 550 SCTP_STATE(SCTP_STATE_COOKIE_ECHOED));
551 551
552 /* SCTP-AUTH: genereate the assocition shared keys so that
553 * we can potentially signe the COOKIE-ECHO.
554 */
555 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_SHKEY, SCTP_NULL());
556
552 /* 5.1 C) "A" shall then send the State Cookie received in the 557 /* 5.1 C) "A" shall then send the State Cookie received in the
553 * INIT ACK chunk in a COOKIE ECHO chunk, ... 558 * INIT ACK chunk in a COOKIE ECHO chunk, ...
554 */ 559 */
@@ -686,6 +691,14 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
686 peer_init, GFP_ATOMIC)) 691 peer_init, GFP_ATOMIC))
687 goto nomem_init; 692 goto nomem_init;
688 693
694 /* SCTP-AUTH: Now that we've populate required fields in
695 * sctp_process_init, set up the assocaition shared keys as
696 * necessary so that we can potentially authenticate the ACK
697 */
698 error = sctp_auth_asoc_init_active_key(new_asoc, GFP_ATOMIC);
699 if (error)
700 goto nomem_init;
701
689 repl = sctp_make_cookie_ack(new_asoc, chunk); 702 repl = sctp_make_cookie_ack(new_asoc, chunk);
690 if (!repl) 703 if (!repl)
691 goto nomem_init; 704 goto nomem_init;
@@ -1247,6 +1260,26 @@ static void sctp_tietags_populate(struct sctp_association *new_asoc,
1247 new_asoc->c.initial_tsn = asoc->c.initial_tsn; 1260 new_asoc->c.initial_tsn = asoc->c.initial_tsn;
1248} 1261}
1249 1262
1263static void sctp_auth_params_populate(struct sctp_association *new_asoc,
1264 const struct sctp_association *asoc)
1265{
1266 /* Only perform this if AUTH extension is enabled */
1267 if (!sctp_auth_enable)
1268 return;
1269
1270 /* We need to provide the same parameter information as
1271 * was in the original INIT. This means that we need to copy
1272 * the HMACS, CHUNKS, and RANDOM parameter from the original
1273 * assocaition.
1274 */
1275 memcpy(new_asoc->c.auth_random, asoc->c.auth_random,
1276 sizeof(asoc->c.auth_random));
1277 memcpy(new_asoc->c.auth_hmacs, asoc->c.auth_hmacs,
1278 sizeof(asoc->c.auth_hmacs));
1279 memcpy(new_asoc->c.auth_chunks, asoc->c.auth_chunks,
1280 sizeof(asoc->c.auth_chunks));
1281}
1282
1250/* 1283/*
1251 * Compare vtag/tietag values to determine unexpected COOKIE-ECHO 1284 * Compare vtag/tietag values to determine unexpected COOKIE-ECHO
1252 * handling action. 1285 * handling action.
@@ -1404,6 +1437,8 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
1404 1437
1405 sctp_tietags_populate(new_asoc, asoc); 1438 sctp_tietags_populate(new_asoc, asoc);
1406 1439
1440 sctp_auth_params_populate(new_asoc, asoc);
1441
1407 /* B) "Z" shall respond immediately with an INIT ACK chunk. */ 1442 /* B) "Z" shall respond immediately with an INIT ACK chunk. */
1408 1443
1409 /* If there are errors need to be reported for unknown parameters, 1444 /* If there are errors need to be reported for unknown parameters,