summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-08-20 15:07:14 +1000
committerHerbert Xu <herbert@gondor.apana.org.au>2006-09-21 11:46:19 +1000
commit1b489e11d4df82514792f9f981f31976f8a94ddf (patch)
treefe047012069eb528fc18518fc4340a02ab9b0adc
parent07d4ee583e21830ec5604d31f65cdc60a6eca19e (diff)
downloadlinux-3.10-1b489e11d4df82514792f9f981f31976f8a94ddf.tar.gz
linux-3.10-1b489e11d4df82514792f9f981f31976f8a94ddf.tar.bz2
linux-3.10-1b489e11d4df82514792f9f981f31976f8a94ddf.zip
[SCTP]: Use HMAC template and hash interface
This patch converts SCTP to use the new HMAC template and hash interface. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/sctp/constants.h4
-rw-r--r--include/net/sctp/sctp.h11
-rw-r--r--include/net/sctp/structs.h3
-rw-r--r--net/sctp/endpointola.c2
-rw-r--r--net/sctp/sm_make_chunk.c37
-rw-r--r--net/sctp/socket.c6
6 files changed, 35 insertions, 28 deletions
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index c51541ee024..57166bfdf8e 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -312,9 +312,9 @@ enum { SCTP_MAX_GABS = 16 };
*/
#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)
-#define SCTP_COOKIE_HMAC_ALG "sha1"
+#define SCTP_COOKIE_HMAC_ALG "hmac(sha1)"
#else
#define SCTP_COOKIE_HMAC_ALG NULL
#endif
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 92eae0e0f3f..1c1abce5f6b 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; }
#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. */
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 e5aa7ff1f5b..0412e730c76 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -87,6 +87,7 @@ struct sctp_bind_addr;
struct sctp_ulpq;
struct sctp_ep_common;
struct sctp_ssnmap;
+struct crypto_hash;
#include <net/sctp/tsnmap.h>
@@ -264,7 +265,7 @@ struct sctp_sock {
struct sctp_pf *pf;
/* Access to HMAC transform. */
- struct crypto_tfm *hmac;
+ struct crypto_hash *hmac;
/* What is our base endpointer? */
struct sctp_endpoint *ep;
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index ffda1d68052..35c49ff2d06 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -173,7 +173,7 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return);
/* 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. */
sctp_inq_free(&ep->base.inqueue);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 17b509282cf..7745bdea781 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,
retval = kmalloc(*cookie_len, GFP_ATOMIC);
- if (!retval) {
- *cookie_len = 0;
+ if (!retval)
goto nodata;
- }
/* Clear this memory since we are sending this data structure
* out on the network.
@@ -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);
if (sctp_sk(ep->base.sk)->hmac) {
+ struct hash_desc desc;
+
/* Sign the message. */
sg.page = virt_to_page(&cookie->c);
sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
sg.length = bodysize;
keylen = SCTP_SECRET_SIZE;
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,
- &sg, 1, cookie->signature);
+ if (crypto_hash_setkey(desc.tfm, key, keylen) ||
+ crypto_hash_digest(&desc, &sg, bodysize, cookie->signature))
+ goto free_cookie;
}
-nodata:
return retval;
+
+free_cookie:
+ kfree(retval);
+nodata:
+ *cookie_len = 0;
+ return NULL;
}
/* Unpack the cookie from COOKIE ECHO chunk, recreating the association. */
@@ -1354,6 +1362,7 @@ struct sctp_association *sctp_unpack_cookie(
sctp_scope_t scope;
struct sk_buff *skb = chunk->skb;
struct timeval tv;
+ struct hash_desc desc;
/* Header size is static data prior to the actual cookie, including
* any padding.
@@ -1389,17 +1398,25 @@ struct sctp_association *sctp_unpack_cookie(
sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
sg.length = bodysize;
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);
- sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen, &sg,
- 1, digest);
+ if (crypto_hash_setkey(desc.tfm, key, keylen) ||
+ crypto_hash_digest(&desc, &sg, bodysize, digest)) {
+ *error = -SCTP_IERROR_NOMEM;
+ goto fail;
+ }
if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) {
/* Try the previous key. */
key = (char *)ep->secret_key[ep->last_key];
memset(digest, 0x00, SCTP_SIGNATURE_SIZE);
- sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen,
- &sg, 1, digest);
+ if (crypto_hash_setkey(desc.tfm, key, keylen) ||
+ crypto_hash_digest(&desc, &sg, bodysize, digest)) {
+ *error = -SCTP_IERROR_NOMEM;
+ goto fail;
+ }
if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) {
/* Yikes! Still bad signature! */
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index dab15949958..85caf796388 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)
int sctp_inet_listen(struct socket *sock, int backlog)
{
struct sock *sk = sock->sk;
- struct crypto_tfm *tfm=NULL;
+ struct crypto_hash *tfm = NULL;
int err = -EINVAL;
if (unlikely(backlog < 0))
@@ -4911,7 +4911,7 @@ int sctp_inet_listen(struct socket *sock, int backlog)
/* Allocate HMAC for generating cookie. */
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) {
err = -ENOSYS;
goto out;
@@ -4937,7 +4937,7 @@ out:
sctp_release_sock(sk);
return err;
cleanup:
- sctp_crypto_free_tfm(tfm);
+ crypto_free_hash(tfm);
goto out;
}