]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/sctp/auth.c
Merge tag 'backlight-next-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee...
[linux.git] / net / sctp / auth.c
index de4c78d4a21e886d91516696348f93501f0a346e..4278764d82b82731483c15023d81ce7b6fab4b9b 100644 (file)
@@ -389,7 +389,7 @@ int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
        /* If we don't support AUTH, or peer is not capable
         * we don't need to do anything.
         */
-       if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)
+       if (!asoc->peer.auth_capable)
                return 0;
 
        /* If the key_id is non-zero and we couldn't find an
@@ -675,7 +675,7 @@ int sctp_auth_send_cid(enum sctp_cid chunk, const struct sctp_association *asoc)
        if (!asoc)
                return 0;
 
-       if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)
+       if (!asoc->peer.auth_capable)
                return 0;
 
        return __sctp_auth_cid(chunk, asoc->peer.peer_chunks);
@@ -687,7 +687,7 @@ int sctp_auth_recv_cid(enum sctp_cid chunk, const struct sctp_association *asoc)
        if (!asoc)
                return 0;
 
-       if (!asoc->ep->auth_enable)
+       if (!asoc->peer.auth_capable)
                return 0;
 
        return __sctp_auth_cid(chunk,
@@ -831,10 +831,15 @@ int sctp_auth_set_key(struct sctp_endpoint *ep,
        /* Try to find the given key id to see if
         * we are doing a replace, or adding a new key
         */
-       if (asoc)
+       if (asoc) {
+               if (!asoc->peer.auth_capable)
+                       return -EACCES;
                sh_keys = &asoc->endpoint_shared_keys;
-       else
+       } else {
+               if (!ep->auth_enable)
+                       return -EACCES;
                sh_keys = &ep->endpoint_shared_keys;
+       }
 
        key_for_each(shkey, sh_keys) {
                if (shkey->key_id == auth_key->sca_keynumber) {
@@ -875,10 +880,15 @@ int sctp_auth_set_active_key(struct sctp_endpoint *ep,
        int found = 0;
 
        /* The key identifier MUST correst to an existing key */
-       if (asoc)
+       if (asoc) {
+               if (!asoc->peer.auth_capable)
+                       return -EACCES;
                sh_keys = &asoc->endpoint_shared_keys;
-       else
+       } else {
+               if (!ep->auth_enable)
+                       return -EACCES;
                sh_keys = &ep->endpoint_shared_keys;
+       }
 
        key_for_each(key, sh_keys) {
                if (key->key_id == key_id) {
@@ -911,11 +921,15 @@ int sctp_auth_del_key_id(struct sctp_endpoint *ep,
         * The key identifier MUST correst to an existing key
         */
        if (asoc) {
+               if (!asoc->peer.auth_capable)
+                       return -EACCES;
                if (asoc->active_key_id == key_id)
                        return -EINVAL;
 
                sh_keys = &asoc->endpoint_shared_keys;
        } else {
+               if (!ep->auth_enable)
+                       return -EACCES;
                if (ep->active_key_id == key_id)
                        return -EINVAL;
 
@@ -950,11 +964,15 @@ int sctp_auth_deact_key_id(struct sctp_endpoint *ep,
         * The key identifier MUST correst to an existing key
         */
        if (asoc) {
+               if (!asoc->peer.auth_capable)
+                       return -EACCES;
                if (asoc->active_key_id == key_id)
                        return -EINVAL;
 
                sh_keys = &asoc->endpoint_shared_keys;
        } else {
+               if (!ep->auth_enable)
+                       return -EACCES;
                if (ep->active_key_id == key_id)
                        return -EINVAL;
 
@@ -989,3 +1007,72 @@ int sctp_auth_deact_key_id(struct sctp_endpoint *ep,
 
        return 0;
 }
+
+int sctp_auth_init(struct sctp_endpoint *ep, gfp_t gfp)
+{
+       int err = -ENOMEM;
+
+       /* Allocate space for HMACS and CHUNKS authentication
+        * variables.  There are arrays that we encode directly
+        * into parameters to make the rest of the operations easier.
+        */
+       if (!ep->auth_hmacs_list) {
+               struct sctp_hmac_algo_param *auth_hmacs;
+
+               auth_hmacs = kzalloc(struct_size(auth_hmacs, hmac_ids,
+                                                SCTP_AUTH_NUM_HMACS), gfp);
+               if (!auth_hmacs)
+                       goto nomem;
+               /* Initialize the HMACS parameter.
+                * SCTP-AUTH: Section 3.3
+                *    Every endpoint supporting SCTP chunk authentication MUST
+                *    support the HMAC based on the SHA-1 algorithm.
+                */
+               auth_hmacs->param_hdr.type = SCTP_PARAM_HMAC_ALGO;
+               auth_hmacs->param_hdr.length =
+                               htons(sizeof(struct sctp_paramhdr) + 2);
+               auth_hmacs->hmac_ids[0] = htons(SCTP_AUTH_HMAC_ID_SHA1);
+               ep->auth_hmacs_list = auth_hmacs;
+       }
+
+       if (!ep->auth_chunk_list) {
+               struct sctp_chunks_param *auth_chunks;
+
+               auth_chunks = kzalloc(sizeof(*auth_chunks) +
+                                     SCTP_NUM_CHUNK_TYPES, gfp);
+               if (!auth_chunks)
+                       goto nomem;
+               /* Initialize the CHUNKS parameter */
+               auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS;
+               auth_chunks->param_hdr.length =
+                               htons(sizeof(struct sctp_paramhdr));
+               ep->auth_chunk_list = auth_chunks;
+       }
+
+       /* Allocate and initialize transorms arrays for supported
+        * HMACs.
+        */
+       err = sctp_auth_init_hmacs(ep, gfp);
+       if (err)
+               goto nomem;
+
+       return 0;
+
+nomem:
+       /* Free all allocations */
+       kfree(ep->auth_hmacs_list);
+       kfree(ep->auth_chunk_list);
+       ep->auth_hmacs_list = NULL;
+       ep->auth_chunk_list = NULL;
+       return err;
+}
+
+void sctp_auth_free(struct sctp_endpoint *ep)
+{
+       kfree(ep->auth_hmacs_list);
+       kfree(ep->auth_chunk_list);
+       ep->auth_hmacs_list = NULL;
+       ep->auth_chunk_list = NULL;
+       sctp_auth_destroy_hmacs(ep->auth_hmacs);
+       ep->auth_hmacs = NULL;
+}