[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>
This commit is contained in:
parent
07d4ee583e
commit
1b489e11d4
6 changed files with 35 additions and 28 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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! */
|
||||
|
|
|
@ -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 @@ int sctp_inet_listen(struct socket *sock, int backlog)
|
|||
sctp_release_sock(sk);
|
||||
return err;
|
||||
cleanup:
|
||||
sctp_crypto_free_tfm(tfm);
|
||||
crypto_free_hash(tfm);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue