aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_statefuns.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r--net/sctp/sm_statefuns.c218
1 files changed, 216 insertions, 2 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 385486360fe9..5aef4aafdfdc 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -138,6 +138,11 @@ static sctp_disposition_t sctp_sf_violation_chunk(
138 void *arg, 138 void *arg,
139 sctp_cmd_seq_t *commands); 139 sctp_cmd_seq_t *commands);
140 140
141static sctp_ierror_t sctp_sf_authenticate(const struct sctp_endpoint *ep,
142 const struct sctp_association *asoc,
143 const sctp_subtype_t type,
144 struct sctp_chunk *chunk);
145
141/* Small helper function that checks if the chunk length 146/* Small helper function that checks if the chunk length
142 * is of the appropriate length. The 'required_length' argument 147 * is of the appropriate length. The 'required_length' argument
143 * is set to be the size of a specific chunk we are testing. 148 * is set to be the size of a specific chunk we are testing.
@@ -495,8 +500,6 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
495 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, 500 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
496 &err_chunk)) { 501 &err_chunk)) {
497 502
498 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
499
500 /* This chunk contains fatal error. It is to be discarded. 503 /* This chunk contains fatal error. It is to be discarded.
501 * Send an ABORT, with causes if there is any. 504 * Send an ABORT, with causes if there is any.
502 */ 505 */
@@ -521,6 +524,22 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
521 sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); 524 sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
522 error = SCTP_ERROR_INV_PARAM; 525 error = SCTP_ERROR_INV_PARAM;
523 } 526 }
527
528 /* SCTP-AUTH, Section 6.3:
529 * It should be noted that if the receiver wants to tear
530 * down an association in an authenticated way only, the
531 * handling of malformed packets should not result in
532 * tearing down the association.
533 *
534 * This means that if we only want to abort associations
535 * in an authenticated way (i.e AUTH+ABORT), then we
536 * can't destory this association just becuase the packet
537 * was malformed.
538 */
539 if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
540 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
541
542 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
524 return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED, 543 return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED,
525 asoc, chunk->transport); 544 asoc, chunk->transport);
526 } 545 }
@@ -699,6 +718,36 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
699 if (error) 718 if (error)
700 goto nomem_init; 719 goto nomem_init;
701 720
721 /* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo
722 * is supposed to be authenticated and we have to do delayed
723 * authentication. We've just recreated the association using
724 * the information in the cookie and now it's much easier to
725 * do the authentication.
726 */
727 if (chunk->auth_chunk) {
728 struct sctp_chunk auth;
729 sctp_ierror_t ret;
730
731 /* set-up our fake chunk so that we can process it */
732 auth.skb = chunk->auth_chunk;
733 auth.asoc = chunk->asoc;
734 auth.sctp_hdr = chunk->sctp_hdr;
735 auth.chunk_hdr = (sctp_chunkhdr_t *)skb_push(chunk->auth_chunk,
736 sizeof(sctp_chunkhdr_t));
737 skb_pull(chunk->auth_chunk, sizeof(sctp_chunkhdr_t));
738 auth.transport = chunk->transport;
739
740 ret = sctp_sf_authenticate(ep, new_asoc, type, &auth);
741
742 /* We can now safely free the auth_chunk clone */
743 kfree_skb(chunk->auth_chunk);
744
745 if (ret != SCTP_IERROR_NO_ERROR) {
746 sctp_association_free(new_asoc);
747 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
748 }
749 }
750
702 repl = sctp_make_cookie_ack(new_asoc, chunk); 751 repl = sctp_make_cookie_ack(new_asoc, chunk);
703 if (!repl) 752 if (!repl)
704 goto nomem_init; 753 goto nomem_init;
@@ -3653,6 +3702,156 @@ gen_shutdown:
3653} 3702}
3654 3703
3655/* 3704/*
3705 * SCTP-AUTH Section 6.3 Receving authenticated chukns
3706 *
3707 * The receiver MUST use the HMAC algorithm indicated in the HMAC
3708 * Identifier field. If this algorithm was not specified by the
3709 * receiver in the HMAC-ALGO parameter in the INIT or INIT-ACK chunk
3710 * during association setup, the AUTH chunk and all chunks after it MUST
3711 * be discarded and an ERROR chunk SHOULD be sent with the error cause
3712 * defined in Section 4.1.
3713 *
3714 * If an endpoint with no shared key receives a Shared Key Identifier
3715 * other than 0, it MUST silently discard all authenticated chunks. If
3716 * the endpoint has at least one endpoint pair shared key for the peer,
3717 * it MUST use the key specified by the Shared Key Identifier if a
3718 * key has been configured for that Shared Key Identifier. If no
3719 * endpoint pair shared key has been configured for that Shared Key
3720 * Identifier, all authenticated chunks MUST be silently discarded.
3721 *
3722 * Verification Tag: 8.5 Verification Tag [Normal verification]
3723 *
3724 * The return value is the disposition of the chunk.
3725 */
3726static sctp_ierror_t sctp_sf_authenticate(const struct sctp_endpoint *ep,
3727 const struct sctp_association *asoc,
3728 const sctp_subtype_t type,
3729 struct sctp_chunk *chunk)
3730{
3731 struct sctp_authhdr *auth_hdr;
3732 struct sctp_hmac *hmac;
3733 unsigned int sig_len;
3734 __u16 key_id;
3735 __u8 *save_digest;
3736 __u8 *digest;
3737
3738 /* Pull in the auth header, so we can do some more verification */
3739 auth_hdr = (struct sctp_authhdr *)chunk->skb->data;
3740 chunk->subh.auth_hdr = auth_hdr;
3741 skb_pull(chunk->skb, sizeof(struct sctp_authhdr));
3742
3743 /* Make sure that we suport the HMAC algorithm from the auth
3744 * chunk.
3745 */
3746 if (!sctp_auth_asoc_verify_hmac_id(asoc, auth_hdr->hmac_id))
3747 return SCTP_IERROR_AUTH_BAD_HMAC;
3748
3749 /* Make sure that the provided shared key identifier has been
3750 * configured
3751 */
3752 key_id = ntohs(auth_hdr->shkey_id);
3753 if (key_id != asoc->active_key_id && !sctp_auth_get_shkey(asoc, key_id))
3754 return SCTP_IERROR_AUTH_BAD_KEYID;
3755
3756
3757 /* Make sure that the length of the signature matches what
3758 * we expect.
3759 */
3760 sig_len = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_auth_chunk_t);
3761 hmac = sctp_auth_get_hmac(ntohs(auth_hdr->hmac_id));
3762 if (sig_len != hmac->hmac_len)
3763 return SCTP_IERROR_PROTO_VIOLATION;
3764
3765 /* Now that we've done validation checks, we can compute and
3766 * verify the hmac. The steps involved are:
3767 * 1. Save the digest from the chunk.
3768 * 2. Zero out the digest in the chunk.
3769 * 3. Compute the new digest
3770 * 4. Compare saved and new digests.
3771 */
3772 digest = auth_hdr->hmac;
3773 skb_pull(chunk->skb, sig_len);
3774
3775 save_digest = kmemdup(digest, sig_len, GFP_ATOMIC);
3776 if (!save_digest)
3777 goto nomem;
3778
3779 memset(digest, 0, sig_len);
3780
3781 sctp_auth_calculate_hmac(asoc, chunk->skb,
3782 (struct sctp_auth_chunk *)chunk->chunk_hdr,
3783 GFP_ATOMIC);
3784
3785 /* Discard the packet if the digests do not match */
3786 if (memcmp(save_digest, digest, sig_len)) {
3787 kfree(save_digest);
3788 return SCTP_IERROR_BAD_SIG;
3789 }
3790
3791 kfree(save_digest);
3792 chunk->auth = 1;
3793
3794 return SCTP_IERROR_NO_ERROR;
3795nomem:
3796 return SCTP_IERROR_NOMEM;
3797}
3798
3799sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,
3800 const struct sctp_association *asoc,
3801 const sctp_subtype_t type,
3802 void *arg,
3803 sctp_cmd_seq_t *commands)
3804{
3805 struct sctp_authhdr *auth_hdr;
3806 struct sctp_chunk *chunk = arg;
3807 struct sctp_chunk *err_chunk;
3808 sctp_ierror_t error;
3809
3810 if (!sctp_vtag_verify(chunk, asoc)) {
3811 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
3812 SCTP_NULL());
3813 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3814 }
3815
3816 /* Make sure that the AUTH chunk has valid length. */
3817 if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_auth_chunk)))
3818 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3819 commands);
3820
3821 auth_hdr = (struct sctp_authhdr *)chunk->skb->data;
3822 error = sctp_sf_authenticate(ep, asoc, type, chunk);
3823 switch (error) {
3824 case SCTP_IERROR_AUTH_BAD_HMAC:
3825 /* Generate the ERROR chunk and discard the rest
3826 * of the packet
3827 */
3828 err_chunk = sctp_make_op_error(asoc, chunk,
3829 SCTP_ERROR_UNSUP_HMAC,
3830 &auth_hdr->hmac_id,
3831 sizeof(__u16));
3832 if (err_chunk) {
3833 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
3834 SCTP_CHUNK(err_chunk));
3835 }
3836 /* Fall Through */
3837 case SCTP_IERROR_AUTH_BAD_KEYID:
3838 case SCTP_IERROR_BAD_SIG:
3839 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3840 break;
3841 case SCTP_IERROR_PROTO_VIOLATION:
3842 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3843 commands);
3844 break;
3845 case SCTP_IERROR_NOMEM:
3846 return SCTP_DISPOSITION_NOMEM;
3847 default:
3848 break;
3849 }
3850
3851 return SCTP_DISPOSITION_CONSUME;
3852}
3853
3854/*
3656 * Process an unknown chunk. 3855 * Process an unknown chunk.
3657 * 3856 *
3658 * Section: 3.2. Also, 2.1 in the implementor's guide. 3857 * Section: 3.2. Also, 2.1 in the implementor's guide.
@@ -3857,6 +4056,20 @@ static sctp_disposition_t sctp_sf_abort_violation(
3857 if (!abort) 4056 if (!abort)
3858 goto nomem; 4057 goto nomem;
3859 4058
4059 /* SCTP-AUTH, Section 6.3:
4060 * It should be noted that if the receiver wants to tear
4061 * down an association in an authenticated way only, the
4062 * handling of malformed packets should not result in
4063 * tearing down the association.
4064 *
4065 * This means that if we only want to abort associations
4066 * in an authenticated way (i.e AUTH+ABORT), then we
4067 * can't destory this association just becuase the packet
4068 * was malformed.
4069 */
4070 if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
4071 goto discard;
4072
3860 if (asoc) { 4073 if (asoc) {
3861 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); 4074 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
3862 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 4075 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
@@ -3894,6 +4107,7 @@ static sctp_disposition_t sctp_sf_abort_violation(
3894 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 4107 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
3895 } 4108 }
3896 4109
4110discard:
3897 sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands); 4111 sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
3898 4112
3899 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 4113 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);