Commit 1b489e11 authored by Herbert Xu's avatar Herbert Xu

[SCTP]: Use HMAC template and hash interface

This patch converts SCTP to use the new HMAC template and hash interface.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 07d4ee58
...@@ -312,9 +312,9 @@ enum { SCTP_MAX_GABS = 16 }; ...@@ -312,9 +312,9 @@ enum { SCTP_MAX_GABS = 16 };
*/ */
#if defined (CONFIG_SCTP_HMAC_MD5) #if defined (CONFIG_SCTP_HMAC_MD5)
#define SCTP_COOKIE_HMAC_ALG "md5" #define SCTP_COOKIE_HMAC_ALG "hmac(md5)"
#elif defined (CONFIG_SCTP_HMAC_SHA1) #elif defined (CONFIG_SCTP_HMAC_SHA1)
#define SCTP_COOKIE_HMAC_ALG "sha1" #define SCTP_COOKIE_HMAC_ALG "hmac(sha1)"
#else #else
#define SCTP_COOKIE_HMAC_ALG NULL #define SCTP_COOKIE_HMAC_ALG NULL
#endif #endif
......
...@@ -330,17 +330,6 @@ static inline void sctp_v6_exit(void) { return; } ...@@ -330,17 +330,6 @@ static inline void sctp_v6_exit(void) { return; }
#endif /* #if defined(CONFIG_IPV6) */ #endif /* #if defined(CONFIG_IPV6) */
/* Some wrappers, in case crypto not available. */
#if defined (CONFIG_CRYPTO_HMAC)
#define sctp_crypto_alloc_tfm crypto_alloc_tfm
#define sctp_crypto_free_tfm crypto_free_tfm
#define sctp_crypto_hmac crypto_hmac
#else
#define sctp_crypto_alloc_tfm(x...) NULL
#define sctp_crypto_free_tfm(x...)
#define sctp_crypto_hmac(x...)
#endif
/* Map an association to an assoc_id. */ /* Map an association to an assoc_id. */
static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc) static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc)
......
...@@ -87,6 +87,7 @@ struct sctp_bind_addr; ...@@ -87,6 +87,7 @@ struct sctp_bind_addr;
struct sctp_ulpq; struct sctp_ulpq;
struct sctp_ep_common; struct sctp_ep_common;
struct sctp_ssnmap; struct sctp_ssnmap;
struct crypto_hash;
#include <net/sctp/tsnmap.h> #include <net/sctp/tsnmap.h>
...@@ -264,7 +265,7 @@ struct sctp_sock { ...@@ -264,7 +265,7 @@ struct sctp_sock {
struct sctp_pf *pf; struct sctp_pf *pf;
/* Access to HMAC transform. */ /* Access to HMAC transform. */
struct crypto_tfm *hmac; struct crypto_hash *hmac;
/* What is our base endpointer? */ /* What is our base endpointer? */
struct sctp_endpoint *ep; struct sctp_endpoint *ep;
......
...@@ -173,7 +173,7 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep) ...@@ -173,7 +173,7 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return); SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return);
/* Free up the HMAC transform. */ /* Free up the HMAC transform. */
sctp_crypto_free_tfm(sctp_sk(ep->base.sk)->hmac); crypto_free_hash(sctp_sk(ep->base.sk)->hmac);
/* Cleanup. */ /* Cleanup. */
sctp_inq_free(&ep->base.inqueue); sctp_inq_free(&ep->base.inqueue);
......
...@@ -1282,10 +1282,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, ...@@ -1282,10 +1282,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
retval = kmalloc(*cookie_len, GFP_ATOMIC); retval = kmalloc(*cookie_len, GFP_ATOMIC);
if (!retval) { if (!retval)
*cookie_len = 0;
goto nodata; goto nodata;
}
/* Clear this memory since we are sending this data structure /* Clear this memory since we are sending this data structure
* out on the network. * out on the network.
...@@ -1321,19 +1319,29 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, ...@@ -1321,19 +1319,29 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
ntohs(init_chunk->chunk_hdr->length), raw_addrs, addrs_len); ntohs(init_chunk->chunk_hdr->length), raw_addrs, addrs_len);
if (sctp_sk(ep->base.sk)->hmac) { if (sctp_sk(ep->base.sk)->hmac) {
struct hash_desc desc;
/* Sign the message. */ /* Sign the message. */
sg.page = virt_to_page(&cookie->c); sg.page = virt_to_page(&cookie->c);
sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE; sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
sg.length = bodysize; sg.length = bodysize;
keylen = SCTP_SECRET_SIZE; keylen = SCTP_SECRET_SIZE;
key = (char *)ep->secret_key[ep->current_key]; key = (char *)ep->secret_key[ep->current_key];
desc.tfm = sctp_sk(ep->base.sk)->hmac;
desc.flags = 0;
sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen, if (crypto_hash_setkey(desc.tfm, key, keylen) ||
&sg, 1, cookie->signature); crypto_hash_digest(&desc, &sg, bodysize, cookie->signature))
goto free_cookie;
} }
nodata:
return retval; return retval;
free_cookie:
kfree(retval);
nodata:
*cookie_len = 0;
return NULL;
} }
/* Unpack the cookie from COOKIE ECHO chunk, recreating the association. */ /* Unpack the cookie from COOKIE ECHO chunk, recreating the association. */
...@@ -1354,6 +1362,7 @@ struct sctp_association *sctp_unpack_cookie( ...@@ -1354,6 +1362,7 @@ struct sctp_association *sctp_unpack_cookie(
sctp_scope_t scope; sctp_scope_t scope;
struct sk_buff *skb = chunk->skb; struct sk_buff *skb = chunk->skb;
struct timeval tv; struct timeval tv;
struct hash_desc desc;
/* Header size is static data prior to the actual cookie, including /* Header size is static data prior to the actual cookie, including
* any padding. * any padding.
...@@ -1389,17 +1398,25 @@ struct sctp_association *sctp_unpack_cookie( ...@@ -1389,17 +1398,25 @@ struct sctp_association *sctp_unpack_cookie(
sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE; sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
sg.length = bodysize; sg.length = bodysize;
key = (char *)ep->secret_key[ep->current_key]; key = (char *)ep->secret_key[ep->current_key];
desc.tfm = sctp_sk(ep->base.sk)->hmac;
desc.flags = 0;
memset(digest, 0x00, SCTP_SIGNATURE_SIZE); memset(digest, 0x00, SCTP_SIGNATURE_SIZE);
sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen, &sg, if (crypto_hash_setkey(desc.tfm, key, keylen) ||
1, digest); crypto_hash_digest(&desc, &sg, bodysize, digest)) {
*error = -SCTP_IERROR_NOMEM;
goto fail;
}
if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) {
/* Try the previous key. */ /* Try the previous key. */
key = (char *)ep->secret_key[ep->last_key]; key = (char *)ep->secret_key[ep->last_key];
memset(digest, 0x00, SCTP_SIGNATURE_SIZE); memset(digest, 0x00, SCTP_SIGNATURE_SIZE);
sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen, if (crypto_hash_setkey(desc.tfm, key, keylen) ||
&sg, 1, digest); crypto_hash_digest(&desc, &sg, bodysize, digest)) {
*error = -SCTP_IERROR_NOMEM;
goto fail;
}
if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) {
/* Yikes! Still bad signature! */ /* Yikes! Still bad signature! */
......
...@@ -4898,7 +4898,7 @@ SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog) ...@@ -4898,7 +4898,7 @@ SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog)
int sctp_inet_listen(struct socket *sock, int backlog) int sctp_inet_listen(struct socket *sock, int backlog)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct crypto_tfm *tfm=NULL; struct crypto_hash *tfm = NULL;
int err = -EINVAL; int err = -EINVAL;
if (unlikely(backlog < 0)) if (unlikely(backlog < 0))
...@@ -4911,7 +4911,7 @@ int sctp_inet_listen(struct socket *sock, int backlog) ...@@ -4911,7 +4911,7 @@ int sctp_inet_listen(struct socket *sock, int backlog)
/* Allocate HMAC for generating cookie. */ /* Allocate HMAC for generating cookie. */
if (sctp_hmac_alg) { if (sctp_hmac_alg) {
tfm = sctp_crypto_alloc_tfm(sctp_hmac_alg, 0); tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC);
if (!tfm) { if (!tfm) {
err = -ENOSYS; err = -ENOSYS;
goto out; goto out;
...@@ -4937,7 +4937,7 @@ out: ...@@ -4937,7 +4937,7 @@ out:
sctp_release_sock(sk); sctp_release_sock(sk);
return err; return err;
cleanup: cleanup:
sctp_crypto_free_tfm(tfm); crypto_free_hash(tfm);
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment