diff options
Diffstat (limited to 'net/sctp/auth.c')
| -rw-r--r-- | net/sctp/auth.c | 110 | 
1 files changed, 53 insertions, 57 deletions
diff --git a/net/sctp/auth.c b/net/sctp/auth.c index ddbbf7c81fa..0e8529113dc 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -16,22 +16,15 @@   * See the GNU General Public License for more details.   *   * You should have received a copy of the GNU General Public License - * along with GNU CC; see the file COPYING.  If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * along with GNU CC; see the file COPYING.  If not, see + * <http://www.gnu.org/licenses/>.   *   * Please send any bug reports or fixes you make to the   * email address(es): - *    lksctp developers <lksctp-developers@lists.sourceforge.net> - * - * Or submit a bug report through the following website: - *    http://www.sf.net/projects/lksctp + *    lksctp developers <linux-sctp@vger.kernel.org>   *   * Written or modified by:   *   Vlad Yasevich     <vladislav.yasevich@hp.com> - * - * Any bugs reported given to us we will try to fix... any fixes shared will - * be incorporated into the next SCTP release.   */  #include <linux/slab.h> @@ -48,7 +41,7 @@ static struct sctp_hmac sctp_hmac_list[SCTP_AUTH_NUM_HMACS] = {  	},  	{  		.hmac_id = SCTP_AUTH_HMAC_ID_SHA1, -		.hmac_name="hmac(sha1)", +		.hmac_name = "hmac(sha1)",  		.hmac_len = SCTP_SHA1_SIG_SIZE,  	},  	{ @@ -58,7 +51,7 @@ static struct sctp_hmac sctp_hmac_list[SCTP_AUTH_NUM_HMACS] = {  #if defined (CONFIG_CRYPTO_SHA256) || defined (CONFIG_CRYPTO_SHA256_MODULE)  	{  		.hmac_id = SCTP_AUTH_HMAC_ID_SHA256, -		.hmac_name="hmac(sha256)", +		.hmac_name = "hmac(sha256)",  		.hmac_len = SCTP_SHA256_SIG_SIZE,  	}  #endif @@ -71,7 +64,7 @@ void sctp_auth_key_put(struct sctp_auth_bytes *key)  		return;  	if (atomic_dec_and_test(&key->refcnt)) { -		kfree(key); +		kzfree(key);  		SCTP_DBG_OBJCNT_DEC(keys);  	}  } @@ -82,7 +75,7 @@ static struct sctp_auth_bytes *sctp_auth_create_key(__u32 key_len, gfp_t gfp)  	struct sctp_auth_bytes *key;  	/* Verify that we are not going to overflow INT_MAX */ -	if ((INT_MAX - key_len) < sizeof(struct sctp_auth_bytes)) +	if (key_len > (INT_MAX - sizeof(struct sctp_auth_bytes)))  		return NULL;  	/* Allocate the shared key */ @@ -113,7 +106,7 @@ struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp)  	return new;  } -/* Free the shared key stucture */ +/* Free the shared key structure */  static void sctp_auth_shkey_free(struct sctp_shared_key *sh_key)  {  	BUG_ON(!list_empty(&sh_key->key_list)); @@ -122,7 +115,7 @@ static void sctp_auth_shkey_free(struct sctp_shared_key *sh_key)  	kfree(sh_key);  } -/* Destory the entire key list.  This is done during the +/* Destroy the entire key list.  This is done during the   * associon and endpoint free process.   */  void sctp_auth_destroy_keys(struct list_head *keys) @@ -170,7 +163,7 @@ static int sctp_auth_compare_vectors(struct sctp_auth_bytes *vector1,  		 * lead-zero padded.  If it is not, it  		 * is automatically larger numerically.  		 */ -		for (i = 0; i < abs(diff); i++ ) { +		for (i = 0; i < abs(diff); i++) {  			if (longer[i] != 0)  				return diff;  		} @@ -200,27 +193,28 @@ static struct sctp_auth_bytes *sctp_auth_make_key_vector(  	struct sctp_auth_bytes *new;  	__u32	len;  	__u32	offset = 0; +	__u16	random_len, hmacs_len, chunks_len = 0; + +	random_len = ntohs(random->param_hdr.length); +	hmacs_len = ntohs(hmacs->param_hdr.length); +	if (chunks) +		chunks_len = ntohs(chunks->param_hdr.length); -	len = ntohs(random->param_hdr.length) + ntohs(hmacs->param_hdr.length); -        if (chunks) -		len += ntohs(chunks->param_hdr.length); +	len = random_len + hmacs_len + chunks_len; -	new = kmalloc(sizeof(struct sctp_auth_bytes) + len, gfp); +	new = sctp_auth_create_key(len, gfp);  	if (!new)  		return NULL; -	new->len = len; - -	memcpy(new->data, random, ntohs(random->param_hdr.length)); -	offset += ntohs(random->param_hdr.length); +	memcpy(new->data, random, random_len); +	offset += random_len;  	if (chunks) { -		memcpy(new->data + offset, chunks, -			ntohs(chunks->param_hdr.length)); -		offset += ntohs(chunks->param_hdr.length); +		memcpy(new->data + offset, chunks, chunks_len); +		offset += chunks_len;  	} -	memcpy(new->data + offset, hmacs, ntohs(hmacs->param_hdr.length)); +	memcpy(new->data + offset, hmacs, hmacs_len);  	return new;  } @@ -232,9 +226,9 @@ static struct sctp_auth_bytes *sctp_auth_make_local_vector(  				    gfp_t gfp)  {  	return sctp_auth_make_key_vector( -				    (sctp_random_param_t*)asoc->c.auth_random, -				    (sctp_chunks_param_t*)asoc->c.auth_chunks, -				    (sctp_hmac_algo_param_t*)asoc->c.auth_hmacs, +				    (sctp_random_param_t *)asoc->c.auth_random, +				    (sctp_chunks_param_t *)asoc->c.auth_chunks, +				    (sctp_hmac_algo_param_t *)asoc->c.auth_hmacs,  				    gfp);  } @@ -324,7 +318,7 @@ static struct sctp_auth_bytes *sctp_auth_asoc_create_secret(  	if (!peer_key_vector || !local_key_vector)  		goto out; -	/* Figure out the order in wich the key_vectors will be +	/* Figure out the order in which the key_vectors will be  	 * added to the endpoint shared key.  	 * SCTP-AUTH, Section 6.1:  	 *   This is performed by selecting the numerically smaller key @@ -350,8 +344,8 @@ static struct sctp_auth_bytes *sctp_auth_asoc_create_secret(  	secret = sctp_auth_asoc_set_secret(ep_key, first_vector, last_vector,  					    gfp);  out: -	kfree(local_key_vector); -	kfree(peer_key_vector); +	sctp_auth_key_put(local_key_vector); +	sctp_auth_key_put(peer_key_vector);  	return secret;  } @@ -398,7 +392,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 (!sctp_auth_enable || !asoc->peer.auth_capable) +	if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)  		return 0;  	/* If the key_id is non-zero and we couldn't find an @@ -448,12 +442,13 @@ int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp)  	struct crypto_hash *tfm = NULL;  	__u16   id; -	/* if the transforms are already allocted, we are done */ -	if (!sctp_auth_enable) { +	/* If AUTH extension is disabled, we are done */ +	if (!ep->auth_enable) {  		ep->auth_hmacs = NULL;  		return 0;  	} +	/* If the transforms are already allocated, we are done */  	if (ep->auth_hmacs)  		return 0; @@ -503,8 +498,7 @@ void sctp_auth_destroy_hmacs(struct crypto_hash *auth_hmacs[])  	if (!auth_hmacs)  		return; -	for (i = 0; i < SCTP_AUTH_NUM_HMACS; i++) -	{ +	for (i = 0; i < SCTP_AUTH_NUM_HMACS; i++) {  		if (auth_hmacs[i])  			crypto_free_hash(auth_hmacs[i]);  	} @@ -542,18 +536,14 @@ struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc)  	for (i = 0; i < n_elt; i++) {  		id = ntohs(hmacs->hmac_ids[i]); -		/* Check the id is in the supported range */ -		if (id > SCTP_AUTH_HMAC_ID_MAX) { -			id = 0; -			continue; -		} - -		/* See is we support the id.  Supported IDs have name and -		 * length fields set, so that we can allocated and use +		/* Check the id is in the supported range. And +		 * see if we support the id.  Supported IDs have name and +		 * length fields set, so that we can allocate and use  		 * them.  We can safely just check for name, for without the  		 * name, we can't allocate the TFM.  		 */ -		if (!sctp_hmac_list[id].hmac_name) { +		if (id > SCTP_AUTH_HMAC_ID_MAX || +		    !sctp_hmac_list[id].hmac_name) {  			id = 0;  			continue;  		} @@ -655,15 +645,15 @@ static int __sctp_auth_cid(sctp_cid_t chunk, struct sctp_chunks_param *param)  	 */  	for (i = 0; !found && i < len; i++) {  		switch (param->chunks[i]) { -		    case SCTP_CID_INIT: -		    case SCTP_CID_INIT_ACK: -		    case SCTP_CID_SHUTDOWN_COMPLETE: -		    case SCTP_CID_AUTH: +		case SCTP_CID_INIT: +		case SCTP_CID_INIT_ACK: +		case SCTP_CID_SHUTDOWN_COMPLETE: +		case SCTP_CID_AUTH:  			break; -		    default: +		default:  			if (param->chunks[i] == chunk) -			    found = 1; +				found = 1;  			break;  		}  	} @@ -674,7 +664,10 @@ static int __sctp_auth_cid(sctp_cid_t chunk, struct sctp_chunks_param *param)  /* Check if peer requested that this chunk is authenticated */  int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc)  { -	if (!sctp_auth_enable || !asoc || !asoc->peer.auth_capable) +	if (!asoc) +		return 0; + +	if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)  		return 0;  	return __sctp_auth_cid(chunk, asoc->peer.peer_chunks); @@ -683,7 +676,10 @@ int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc)  /* Check if we requested that peer authenticate this chunk. */  int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc)  { -	if (!sctp_auth_enable || !asoc) +	if (!asoc) +		return 0; + +	if (!asoc->ep->auth_enable)  		return 0;  	return __sctp_auth_cid(chunk,  | 
