Commit a29a5bd4f5c3e8ba2e89688feab8b01c44f1654f

Authored by Vlad Yasevich
Committed by David S. Miller
1 parent 1f485649f5

[SCTP]: Implement SCTP-AUTH initializations.

The patch initializes AUTH related members of the generic SCTP
structures and provides a way to enable/disable auth extension.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 5 changed files with 133 additions and 0 deletions Side-by-side Diff

net/sctp/associola.c
... ... @@ -74,6 +74,8 @@
74 74 {
75 75 struct sctp_sock *sp;
76 76 int i;
  77 + sctp_paramhdr_t *p;
  78 + int err;
77 79  
78 80 /* Retrieve the SCTP per socket area. */
79 81 sp = sctp_sk((struct sock *)sk);
... ... @@ -298,6 +300,30 @@
298 300 asoc->default_timetolive = sp->default_timetolive;
299 301 asoc->default_rcv_context = sp->default_rcv_context;
300 302  
  303 + /* AUTH related initializations */
  304 + INIT_LIST_HEAD(&asoc->endpoint_shared_keys);
  305 + err = sctp_auth_asoc_copy_shkeys(ep, asoc, gfp);
  306 + if (err)
  307 + goto fail_init;
  308 +
  309 + asoc->active_key_id = ep->active_key_id;
  310 + asoc->asoc_shared_key = NULL;
  311 +
  312 + asoc->default_hmac_id = 0;
  313 + /* Save the hmacs and chunks list into this association */
  314 + if (ep->auth_hmacs_list)
  315 + memcpy(asoc->c.auth_hmacs, ep->auth_hmacs_list,
  316 + ntohs(ep->auth_hmacs_list->param_hdr.length));
  317 + if (ep->auth_chunk_list)
  318 + memcpy(asoc->c.auth_chunks, ep->auth_chunk_list,
  319 + ntohs(ep->auth_chunk_list->param_hdr.length));
  320 +
  321 + /* Get the AUTH random number for this association */
  322 + p = (sctp_paramhdr_t *)asoc->c.auth_random;
  323 + p->type = SCTP_PARAM_RANDOM;
  324 + p->length = htons(sizeof(sctp_paramhdr_t) + SCTP_AUTH_RANDOM_LENGTH);
  325 + get_random_bytes(p+1, SCTP_AUTH_RANDOM_LENGTH);
  326 +
301 327 return asoc;
302 328  
303 329 fail_init:
... ... @@ -407,6 +433,12 @@
407 433 if (asoc->addip_last_asconf)
408 434 sctp_chunk_free(asoc->addip_last_asconf);
409 435  
  436 + /* AUTH - Free the endpoint shared keys */
  437 + sctp_auth_destroy_keys(&asoc->endpoint_shared_keys);
  438 +
  439 + /* AUTH - Free the association shared key */
  440 + sctp_auth_key_put(asoc->asoc_shared_key);
  441 +
410 442 sctp_association_put(asoc);
411 443 }
412 444  
... ... @@ -1112,6 +1144,8 @@
1112 1144 sctp_assoc_set_id(asoc, GFP_ATOMIC);
1113 1145 }
1114 1146 }
  1147 +
  1148 + /* SCTP-AUTH: XXX something needs to be done here*/
1115 1149 }
1116 1150  
1117 1151 /* Update the retran path for sending a retransmitted packet.
net/sctp/endpointola.c
... ... @@ -69,12 +69,56 @@
69 69 struct sock *sk,
70 70 gfp_t gfp)
71 71 {
  72 + struct sctp_hmac_algo_param *auth_hmacs = NULL;
  73 + struct sctp_chunks_param *auth_chunks = NULL;
  74 + struct sctp_shared_key *null_key;
  75 + int err;
  76 +
72 77 memset(ep, 0, sizeof(struct sctp_endpoint));
73 78  
74 79 ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp);
75 80 if (!ep->digest)
76 81 return NULL;
77 82  
  83 + if (sctp_auth_enable) {
  84 + /* Allocate space for HMACS and CHUNKS authentication
  85 + * variables. There are arrays that we encode directly
  86 + * into parameters to make the rest of the operations easier.
  87 + */
  88 + auth_hmacs = kzalloc(sizeof(sctp_hmac_algo_param_t) +
  89 + sizeof(__u16) * SCTP_AUTH_NUM_HMACS, gfp);
  90 + if (!auth_hmacs)
  91 + goto nomem;
  92 +
  93 + auth_chunks = kzalloc(sizeof(sctp_chunks_param_t) +
  94 + SCTP_NUM_CHUNK_TYPES, gfp);
  95 + if (!auth_chunks)
  96 + goto nomem;
  97 +
  98 + /* Initialize the HMACS parameter.
  99 + * SCTP-AUTH: Section 3.3
  100 + * Every endpoint supporting SCTP chunk authentication MUST
  101 + * support the HMAC based on the SHA-1 algorithm.
  102 + */
  103 + auth_hmacs->param_hdr.type = SCTP_PARAM_HMAC_ALGO;
  104 + auth_hmacs->param_hdr.length =
  105 + htons(sizeof(sctp_paramhdr_t) + 2);
  106 + auth_hmacs->hmac_ids[0] = htons(SCTP_AUTH_HMAC_ID_SHA1);
  107 +
  108 + /* Initialize the CHUNKS parameter */
  109 + auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS;
  110 +
  111 + /* If the Add-IP functionality is enabled, we must
  112 + * authenticate, ASCONF and ASCONF-ACK chunks
  113 + */
  114 + if (sctp_addip_enable) {
  115 + auth_chunks->chunks[0] = SCTP_CID_ASCONF;
  116 + auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK;
  117 + auth_chunks->param_hdr.length =
  118 + htons(sizeof(sctp_paramhdr_t) + 2);
  119 + }
  120 + }
  121 +
78 122 /* Initialize the base structure. */
79 123 /* What type of endpoint are we? */
80 124 ep->base.type = SCTP_EP_TYPE_SOCKET;
81 125  
... ... @@ -114,7 +158,36 @@
114 158 ep->last_key = ep->current_key = 0;
115 159 ep->key_changed_at = jiffies;
116 160  
  161 + /* SCTP-AUTH extensions*/
  162 + INIT_LIST_HEAD(&ep->endpoint_shared_keys);
  163 + null_key = sctp_auth_shkey_create(0, GFP_KERNEL);
  164 + if (!null_key)
  165 + goto nomem;
  166 +
  167 + list_add(&null_key->key_list, &ep->endpoint_shared_keys);
  168 +
  169 + /* Allocate and initialize transorms arrays for suported HMACs. */
  170 + err = sctp_auth_init_hmacs(ep, gfp);
  171 + if (err)
  172 + goto nomem_hmacs;
  173 +
  174 + /* Add the null key to the endpoint shared keys list and
  175 + * set the hmcas and chunks pointers.
  176 + */
  177 + ep->auth_hmacs_list = auth_hmacs;
  178 + ep->auth_chunk_list = auth_chunks;
  179 +
117 180 return ep;
  181 +
  182 +nomem_hmacs:
  183 + sctp_auth_destroy_keys(&ep->endpoint_shared_keys);
  184 +nomem:
  185 + /* Free all allocations */
  186 + kfree(auth_hmacs);
  187 + kfree(auth_chunks);
  188 + kfree(ep->digest);
  189 + return NULL;
  190 +
118 191 }
119 192  
120 193 /* Create a sctp_endpoint with all that boring stuff initialized.
... ... @@ -186,6 +259,16 @@
186 259  
187 260 /* Free the digest buffer */
188 261 kfree(ep->digest);
  262 +
  263 + /* SCTP-AUTH: Free up AUTH releated data such as shared keys
  264 + * chunks and hmacs arrays that were allocated
  265 + */
  266 + sctp_auth_destroy_keys(&ep->endpoint_shared_keys);
  267 + kfree(ep->auth_hmacs_list);
  268 + kfree(ep->auth_chunk_list);
  269 +
  270 + /* AUTH - Free any allocated HMAC transform containers */
  271 + sctp_auth_destroy_hmacs(ep->auth_hmacs);
189 272  
190 273 /* Cleanup. */
191 274 sctp_inq_free(&ep->base.inqueue);
... ... @@ -79,7 +79,9 @@
79 79 packet->vtag = vtag;
80 80 packet->has_cookie_echo = 0;
81 81 packet->has_sack = 0;
  82 + packet->has_auth = 0;
82 83 packet->ipfragok = 0;
  84 + packet->auth = NULL;
83 85  
84 86 if (ecn_capable && sctp_packet_empty(packet)) {
85 87 chunk = sctp_get_ecne_prepend(packet->transport->asoc);
86 88  
... ... @@ -121,8 +123,10 @@
121 123 packet->vtag = 0;
122 124 packet->has_cookie_echo = 0;
123 125 packet->has_sack = 0;
  126 + packet->has_auth = 0;
124 127 packet->ipfragok = 0;
125 128 packet->malloced = 0;
  129 + packet->auth = NULL;
126 130 return packet;
127 131 }
128 132  
... ... @@ -1185,6 +1185,9 @@
1185 1185 /* Enable PR-SCTP by default. */
1186 1186 sctp_prsctp_enable = 1;
1187 1187  
  1188 + /* Disable AUTH by default. */
  1189 + sctp_auth_enable = 0;
  1190 +
1188 1191 sctp_sysctl_register();
1189 1192  
1190 1193 INIT_LIST_HEAD(&sctp_address_families);
... ... @@ -254,6 +254,15 @@
254 254 .mode = 0644,
255 255 .proc_handler = &proc_dointvec,
256 256 },
  257 + {
  258 + .ctl_name = CTL_UNNUMBERED,
  259 + .procname = "auth_enable",
  260 + .data = &sctp_auth_enable,
  261 + .maxlen = sizeof(int),
  262 + .mode = 0644,
  263 + .proc_handler = &proc_dointvec,
  264 + .strategy = &sysctl_intvec
  265 + },
257 266 { .ctl_name = 0 }
258 267 };
259 268