Commit a29a5bd4f5c3e8ba2e89688feab8b01c44f1654f
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); |
net/sctp/output.c
... | ... | @@ -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 |
net/sctp/protocol.c
net/sctp/sysctl.c
... | ... | @@ -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 |