diff options
-rw-r--r-- | include/net/sctp/constants.h | 4 | ||||
-rw-r--r-- | include/net/sctp/sctp.h | 11 | ||||
-rw-r--r-- | include/net/sctp/structs.h | 3 | ||||
-rw-r--r-- | net/sctp/endpointola.c | 2 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 37 | ||||
-rw-r--r-- | net/sctp/socket.c | 6 |
6 files changed, 35 insertions, 28 deletions
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index c51541ee0247..57166bfdf8eb 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h | |||
@@ -312,9 +312,9 @@ enum { SCTP_MAX_GABS = 16 }; | |||
312 | */ | 312 | */ |
313 | 313 | ||
314 | #if defined (CONFIG_SCTP_HMAC_MD5) | 314 | #if defined (CONFIG_SCTP_HMAC_MD5) |
315 | #define SCTP_COOKIE_HMAC_ALG "md5" | 315 | #define SCTP_COOKIE_HMAC_ALG "hmac(md5)" |
316 | #elif defined (CONFIG_SCTP_HMAC_SHA1) | 316 | #elif defined (CONFIG_SCTP_HMAC_SHA1) |
317 | #define SCTP_COOKIE_HMAC_ALG "sha1" | 317 | #define SCTP_COOKIE_HMAC_ALG "hmac(sha1)" |
318 | #else | 318 | #else |
319 | #define SCTP_COOKIE_HMAC_ALG NULL | 319 | #define SCTP_COOKIE_HMAC_ALG NULL |
320 | #endif | 320 | #endif |
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 92eae0e0f3f1..1c1abce5f6b6 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h | |||
@@ -330,17 +330,6 @@ static inline void sctp_v6_exit(void) { return; } | |||
330 | 330 | ||
331 | #endif /* #if defined(CONFIG_IPV6) */ | 331 | #endif /* #if defined(CONFIG_IPV6) */ |
332 | 332 | ||
333 | /* Some wrappers, in case crypto not available. */ | ||
334 | #if defined (CONFIG_CRYPTO_HMAC) | ||
335 | #define sctp_crypto_alloc_tfm crypto_alloc_tfm | ||
336 | #define sctp_crypto_free_tfm crypto_free_tfm | ||
337 | #define sctp_crypto_hmac crypto_hmac | ||
338 | #else | ||
339 | #define sctp_crypto_alloc_tfm(x...) NULL | ||
340 | #define sctp_crypto_free_tfm(x...) | ||
341 | #define sctp_crypto_hmac(x...) | ||
342 | #endif | ||
343 | |||
344 | 333 | ||
345 | /* Map an association to an assoc_id. */ | 334 | /* Map an association to an assoc_id. */ |
346 | static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc) | 335 | static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc) |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index e5aa7ff1f5b5..0412e730c765 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -87,6 +87,7 @@ struct sctp_bind_addr; | |||
87 | struct sctp_ulpq; | 87 | struct sctp_ulpq; |
88 | struct sctp_ep_common; | 88 | struct sctp_ep_common; |
89 | struct sctp_ssnmap; | 89 | struct sctp_ssnmap; |
90 | struct crypto_hash; | ||
90 | 91 | ||
91 | 92 | ||
92 | #include <net/sctp/tsnmap.h> | 93 | #include <net/sctp/tsnmap.h> |
@@ -264,7 +265,7 @@ struct sctp_sock { | |||
264 | struct sctp_pf *pf; | 265 | struct sctp_pf *pf; |
265 | 266 | ||
266 | /* Access to HMAC transform. */ | 267 | /* Access to HMAC transform. */ |
267 | struct crypto_tfm *hmac; | 268 | struct crypto_hash *hmac; |
268 | 269 | ||
269 | /* What is our base endpointer? */ | 270 | /* What is our base endpointer? */ |
270 | struct sctp_endpoint *ep; | 271 | struct sctp_endpoint *ep; |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index ffda1d680529..35c49ff2d062 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -173,7 +173,7 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep) | |||
173 | SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return); | 173 | SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return); |
174 | 174 | ||
175 | /* Free up the HMAC transform. */ | 175 | /* Free up the HMAC transform. */ |
176 | sctp_crypto_free_tfm(sctp_sk(ep->base.sk)->hmac); | 176 | crypto_free_hash(sctp_sk(ep->base.sk)->hmac); |
177 | 177 | ||
178 | /* Cleanup. */ | 178 | /* Cleanup. */ |
179 | sctp_inq_free(&ep->base.inqueue); | 179 | sctp_inq_free(&ep->base.inqueue); |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 17b509282cf2..7745bdea7817 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -1282,10 +1282,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, | |||
1282 | 1282 | ||
1283 | retval = kmalloc(*cookie_len, GFP_ATOMIC); | 1283 | retval = kmalloc(*cookie_len, GFP_ATOMIC); |
1284 | 1284 | ||
1285 | if (!retval) { | 1285 | if (!retval) |
1286 | *cookie_len = 0; | ||
1287 | goto nodata; | 1286 | goto nodata; |
1288 | } | ||
1289 | 1287 | ||
1290 | /* Clear this memory since we are sending this data structure | 1288 | /* Clear this memory since we are sending this data structure |
1291 | * out on the network. | 1289 | * out on the network. |
@@ -1321,19 +1319,29 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, | |||
1321 | ntohs(init_chunk->chunk_hdr->length), raw_addrs, addrs_len); | 1319 | ntohs(init_chunk->chunk_hdr->length), raw_addrs, addrs_len); |
1322 | 1320 | ||
1323 | if (sctp_sk(ep->base.sk)->hmac) { | 1321 | if (sctp_sk(ep->base.sk)->hmac) { |
1322 | struct hash_desc desc; | ||
1323 | |||
1324 | /* Sign the message. */ | 1324 | /* Sign the message. */ |
1325 | sg.page = virt_to_page(&cookie->c); | 1325 | sg.page = virt_to_page(&cookie->c); |
1326 | sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE; | 1326 | sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE; |
1327 | sg.length = bodysize; | 1327 | sg.length = bodysize; |
1328 | keylen = SCTP_SECRET_SIZE; | 1328 | keylen = SCTP_SECRET_SIZE; |
1329 | key = (char *)ep->secret_key[ep->current_key]; | 1329 | key = (char *)ep->secret_key[ep->current_key]; |
1330 | desc.tfm = sctp_sk(ep->base.sk)->hmac; | ||
1331 | desc.flags = 0; | ||
1330 | 1332 | ||
1331 | sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen, | 1333 | if (crypto_hash_setkey(desc.tfm, key, keylen) || |
1332 | &sg, 1, cookie->signature); | 1334 | crypto_hash_digest(&desc, &sg, bodysize, cookie->signature)) |
1335 | goto free_cookie; | ||
1333 | } | 1336 | } |
1334 | 1337 | ||
1335 | nodata: | ||
1336 | return retval; | 1338 | return retval; |
1339 | |||
1340 | free_cookie: | ||
1341 | kfree(retval); | ||
1342 | nodata: | ||
1343 | *cookie_len = 0; | ||
1344 | return NULL; | ||
1337 | } | 1345 | } |
1338 | 1346 | ||
1339 | /* Unpack the cookie from COOKIE ECHO chunk, recreating the association. */ | 1347 | /* Unpack the cookie from COOKIE ECHO chunk, recreating the association. */ |
@@ -1354,6 +1362,7 @@ struct sctp_association *sctp_unpack_cookie( | |||
1354 | sctp_scope_t scope; | 1362 | sctp_scope_t scope; |
1355 | struct sk_buff *skb = chunk->skb; | 1363 | struct sk_buff *skb = chunk->skb; |
1356 | struct timeval tv; | 1364 | struct timeval tv; |
1365 | struct hash_desc desc; | ||
1357 | 1366 | ||
1358 | /* Header size is static data prior to the actual cookie, including | 1367 | /* Header size is static data prior to the actual cookie, including |
1359 | * any padding. | 1368 | * any padding. |
@@ -1389,17 +1398,25 @@ struct sctp_association *sctp_unpack_cookie( | |||
1389 | sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE; | 1398 | sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE; |
1390 | sg.length = bodysize; | 1399 | sg.length = bodysize; |
1391 | key = (char *)ep->secret_key[ep->current_key]; | 1400 | key = (char *)ep->secret_key[ep->current_key]; |
1401 | desc.tfm = sctp_sk(ep->base.sk)->hmac; | ||
1402 | desc.flags = 0; | ||
1392 | 1403 | ||
1393 | memset(digest, 0x00, SCTP_SIGNATURE_SIZE); | 1404 | memset(digest, 0x00, SCTP_SIGNATURE_SIZE); |
1394 | sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen, &sg, | 1405 | if (crypto_hash_setkey(desc.tfm, key, keylen) || |
1395 | 1, digest); | 1406 | crypto_hash_digest(&desc, &sg, bodysize, digest)) { |
1407 | *error = -SCTP_IERROR_NOMEM; | ||
1408 | goto fail; | ||
1409 | } | ||
1396 | 1410 | ||
1397 | if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { | 1411 | if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { |
1398 | /* Try the previous key. */ | 1412 | /* Try the previous key. */ |
1399 | key = (char *)ep->secret_key[ep->last_key]; | 1413 | key = (char *)ep->secret_key[ep->last_key]; |
1400 | memset(digest, 0x00, SCTP_SIGNATURE_SIZE); | 1414 | memset(digest, 0x00, SCTP_SIGNATURE_SIZE); |
1401 | sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen, | 1415 | if (crypto_hash_setkey(desc.tfm, key, keylen) || |
1402 | &sg, 1, digest); | 1416 | crypto_hash_digest(&desc, &sg, bodysize, digest)) { |
1417 | *error = -SCTP_IERROR_NOMEM; | ||
1418 | goto fail; | ||
1419 | } | ||
1403 | 1420 | ||
1404 | if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { | 1421 | if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { |
1405 | /* Yikes! Still bad signature! */ | 1422 | /* Yikes! Still bad signature! */ |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index dab15949958e..85caf7963886 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -4898,7 +4898,7 @@ SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog) | |||
4898 | int sctp_inet_listen(struct socket *sock, int backlog) | 4898 | int sctp_inet_listen(struct socket *sock, int backlog) |
4899 | { | 4899 | { |
4900 | struct sock *sk = sock->sk; | 4900 | struct sock *sk = sock->sk; |
4901 | struct crypto_tfm *tfm=NULL; | 4901 | struct crypto_hash *tfm = NULL; |
4902 | int err = -EINVAL; | 4902 | int err = -EINVAL; |
4903 | 4903 | ||
4904 | if (unlikely(backlog < 0)) | 4904 | if (unlikely(backlog < 0)) |
@@ -4911,7 +4911,7 @@ int sctp_inet_listen(struct socket *sock, int backlog) | |||
4911 | 4911 | ||
4912 | /* Allocate HMAC for generating cookie. */ | 4912 | /* Allocate HMAC for generating cookie. */ |
4913 | if (sctp_hmac_alg) { | 4913 | if (sctp_hmac_alg) { |
4914 | tfm = sctp_crypto_alloc_tfm(sctp_hmac_alg, 0); | 4914 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); |
4915 | if (!tfm) { | 4915 | if (!tfm) { |
4916 | err = -ENOSYS; | 4916 | err = -ENOSYS; |
4917 | goto out; | 4917 | goto out; |
@@ -4937,7 +4937,7 @@ out: | |||
4937 | sctp_release_sock(sk); | 4937 | sctp_release_sock(sk); |
4938 | return err; | 4938 | return err; |
4939 | cleanup: | 4939 | cleanup: |
4940 | sctp_crypto_free_tfm(tfm); | 4940 | crypto_free_hash(tfm); |
4941 | goto out; | 4941 | goto out; |
4942 | } | 4942 | } |
4943 | 4943 | ||