^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* SCTP kernel implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * (C) Copyright 2007 Hewlett-Packard Development Company, L.P.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file is part of the SCTP kernel implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Please send any bug reports or fixes you make to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * email address(es):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * lksctp developers <linux-sctp@vger.kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Written or modified by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Vlad Yasevich <vladislav.yasevich@hp.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <crypto/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/scatterlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <net/sctp/sctp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <net/sctp/auth.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static struct sctp_hmac sctp_hmac_list[SCTP_AUTH_NUM_HMACS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* id 0 is reserved. as all 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) .hmac_id = SCTP_AUTH_HMAC_ID_RESERVED_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .hmac_id = SCTP_AUTH_HMAC_ID_SHA1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .hmac_name = "hmac(sha1)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .hmac_len = SCTP_SHA1_SIG_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* id 2 is reserved as well */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .hmac_id = SCTP_AUTH_HMAC_ID_RESERVED_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #if IS_ENABLED(CONFIG_CRYPTO_SHA256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .hmac_id = SCTP_AUTH_HMAC_ID_SHA256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .hmac_name = "hmac(sha256)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .hmac_len = SCTP_SHA256_SIG_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) void sctp_auth_key_put(struct sctp_auth_bytes *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (!key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (refcount_dec_and_test(&key->refcnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) kfree_sensitive(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) SCTP_DBG_OBJCNT_DEC(keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* Create a new key structure of a given length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static struct sctp_auth_bytes *sctp_auth_create_key(__u32 key_len, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct sctp_auth_bytes *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* Verify that we are not going to overflow INT_MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (key_len > (INT_MAX - sizeof(struct sctp_auth_bytes)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Allocate the shared key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) key = kmalloc(sizeof(struct sctp_auth_bytes) + key_len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (!key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) key->len = key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) refcount_set(&key->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) SCTP_DBG_OBJCNT_INC(keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Create a new shared key container with a give key id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct sctp_shared_key *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Allocate the shared key container */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) new = kzalloc(sizeof(struct sctp_shared_key), gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) INIT_LIST_HEAD(&new->key_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) refcount_set(&new->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) new->key_id = key_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* Free the shared key structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static void sctp_auth_shkey_destroy(struct sctp_shared_key *sh_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) BUG_ON(!list_empty(&sh_key->key_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) sctp_auth_key_put(sh_key->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) sh_key->key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) kfree(sh_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) void sctp_auth_shkey_release(struct sctp_shared_key *sh_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (refcount_dec_and_test(&sh_key->refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) sctp_auth_shkey_destroy(sh_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) void sctp_auth_shkey_hold(struct sctp_shared_key *sh_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) refcount_inc(&sh_key->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* Destroy the entire key list. This is done during the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * associon and endpoint free process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) void sctp_auth_destroy_keys(struct list_head *keys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct sctp_shared_key *ep_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct sctp_shared_key *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (list_empty(keys))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) key_for_each_safe(ep_key, tmp, keys) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) list_del_init(&ep_key->key_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) sctp_auth_shkey_release(ep_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Compare two byte vectors as numbers. Return values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * 0 - vectors are equal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * < 0 - vector 1 is smaller than vector2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * > 0 - vector 1 is greater than vector2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * Algorithm is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * This is performed by selecting the numerically smaller key vector...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * If the key vectors are equal as numbers but differ in length ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * the shorter vector is considered smaller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * Examples (with small values):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * 000123456789 > 123456789 (first number is longer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * 000123456789 < 234567891 (second number is larger numerically)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * 123456789 > 2345678 (first number is both larger & longer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static int sctp_auth_compare_vectors(struct sctp_auth_bytes *vector1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct sctp_auth_bytes *vector2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) const __u8 *longer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) diff = vector1->len - vector2->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (diff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) longer = (diff > 0) ? vector1->data : vector2->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* Check to see if the longer number is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * lead-zero padded. If it is not, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * is automatically larger numerically.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) for (i = 0; i < abs(diff); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (longer[i] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* lengths are the same, compare numbers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return memcmp(vector1->data, vector2->data, vector1->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * Create a key vector as described in SCTP-AUTH, Section 6.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * The RANDOM parameter, the CHUNKS parameter and the HMAC-ALGO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * parameter sent by each endpoint are concatenated as byte vectors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * These parameters include the parameter type, parameter length, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * the parameter value, but padding is omitted; all padding MUST be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * removed from this concatenation before proceeding with further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * computation of keys. Parameters which were not sent are simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * omitted from the concatenation process. The resulting two vectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * are called the two key vectors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static struct sctp_auth_bytes *sctp_auth_make_key_vector(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct sctp_random_param *random,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct sctp_chunks_param *chunks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct sctp_hmac_algo_param *hmacs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct sctp_auth_bytes *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) __u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) __u32 offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) __u16 random_len, hmacs_len, chunks_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) random_len = ntohs(random->param_hdr.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) hmacs_len = ntohs(hmacs->param_hdr.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (chunks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) chunks_len = ntohs(chunks->param_hdr.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) len = random_len + hmacs_len + chunks_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) new = sctp_auth_create_key(len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) memcpy(new->data, random, random_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) offset += random_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (chunks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) memcpy(new->data + offset, chunks, chunks_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) offset += chunks_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) memcpy(new->data + offset, hmacs, hmacs_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* Make a key vector based on our local parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static struct sctp_auth_bytes *sctp_auth_make_local_vector(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return sctp_auth_make_key_vector(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) (struct sctp_random_param *)asoc->c.auth_random,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) (struct sctp_chunks_param *)asoc->c.auth_chunks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) (struct sctp_hmac_algo_param *)asoc->c.auth_hmacs, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* Make a key vector based on peer's parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static struct sctp_auth_bytes *sctp_auth_make_peer_vector(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return sctp_auth_make_key_vector(asoc->peer.peer_random,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) asoc->peer.peer_chunks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) asoc->peer.peer_hmacs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* Set the value of the association shared key base on the parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * given. The algorithm is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * From the endpoint pair shared keys and the key vectors the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * association shared keys are computed. This is performed by selecting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * the numerically smaller key vector and concatenating it to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * endpoint pair shared key, and then concatenating the numerically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * larger key vector to that. The result of the concatenation is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * association shared key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static struct sctp_auth_bytes *sctp_auth_asoc_set_secret(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct sctp_shared_key *ep_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct sctp_auth_bytes *first_vector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct sctp_auth_bytes *last_vector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct sctp_auth_bytes *secret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) __u32 offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) __u32 auth_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) auth_len = first_vector->len + last_vector->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (ep_key->key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) auth_len += ep_key->key->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) secret = sctp_auth_create_key(auth_len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (!secret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (ep_key->key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) memcpy(secret->data, ep_key->key->data, ep_key->key->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) offset += ep_key->key->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) memcpy(secret->data + offset, first_vector->data, first_vector->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) offset += first_vector->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) memcpy(secret->data + offset, last_vector->data, last_vector->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return secret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* Create an association shared key. Follow the algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * described in SCTP-AUTH, Section 6.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static struct sctp_auth_bytes *sctp_auth_asoc_create_secret(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct sctp_shared_key *ep_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct sctp_auth_bytes *local_key_vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct sctp_auth_bytes *peer_key_vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct sctp_auth_bytes *first_vector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *last_vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct sctp_auth_bytes *secret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* Now we need to build the key vectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * SCTP-AUTH , Section 6.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * The RANDOM parameter, the CHUNKS parameter and the HMAC-ALGO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * parameter sent by each endpoint are concatenated as byte vectors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * These parameters include the parameter type, parameter length, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * the parameter value, but padding is omitted; all padding MUST be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * removed from this concatenation before proceeding with further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * computation of keys. Parameters which were not sent are simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * omitted from the concatenation process. The resulting two vectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * are called the two key vectors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) local_key_vector = sctp_auth_make_local_vector(asoc, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) peer_key_vector = sctp_auth_make_peer_vector(asoc, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (!peer_key_vector || !local_key_vector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* Figure out the order in which the key_vectors will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * added to the endpoint shared key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * SCTP-AUTH, Section 6.1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * This is performed by selecting the numerically smaller key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * vector and concatenating it to the endpoint pair shared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * key, and then concatenating the numerically larger key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * vector to that. If the key vectors are equal as numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * but differ in length, then the concatenation order is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * endpoint shared key, followed by the shorter key vector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * followed by the longer key vector. Otherwise, the key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * vectors are identical, and may be concatenated to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * endpoint pair key in any order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) cmp = sctp_auth_compare_vectors(local_key_vector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) peer_key_vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (cmp < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) first_vector = local_key_vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) last_vector = peer_key_vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) first_vector = peer_key_vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) last_vector = local_key_vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) secret = sctp_auth_asoc_set_secret(ep_key, first_vector, last_vector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) sctp_auth_key_put(local_key_vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) sctp_auth_key_put(peer_key_vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return secret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * Populate the association overlay list with the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * from the endpoint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int sctp_auth_asoc_copy_shkeys(const struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct sctp_shared_key *sh_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct sctp_shared_key *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) BUG_ON(!list_empty(&asoc->endpoint_shared_keys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) key_for_each(sh_key, &ep->endpoint_shared_keys) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) new = sctp_auth_shkey_create(sh_key->key_id, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) goto nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) new->key = sh_key->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) sctp_auth_key_hold(new->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) list_add(&new->key_list, &asoc->endpoint_shared_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) sctp_auth_destroy_keys(&asoc->endpoint_shared_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Public interface to create the association shared key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * See code above for the algorithm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct sctp_auth_bytes *secret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct sctp_shared_key *ep_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct sctp_chunk *chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* If we don't support AUTH, or peer is not capable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * we don't need to do anything.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (!asoc->peer.auth_capable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* If the key_id is non-zero and we couldn't find an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * endpoint pair shared key, we can't compute the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * secret.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * For key_id 0, endpoint pair shared key is a NULL key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ep_key = sctp_auth_get_shkey(asoc, asoc->active_key_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) BUG_ON(!ep_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) secret = sctp_auth_asoc_create_secret(asoc, ep_key, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (!secret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) sctp_auth_key_put(asoc->asoc_shared_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) asoc->asoc_shared_key = secret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) asoc->shkey = ep_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /* Update send queue in case any chunk already in there now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * needs authenticating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) list_for_each_entry(chunk, &asoc->outqueue.out_chunk_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (sctp_auth_send_cid(chunk->chunk_hdr->type, asoc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) chunk->auth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (!chunk->shkey) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) chunk->shkey = asoc->shkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) sctp_auth_shkey_hold(chunk->shkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* Find the endpoint pair shared key based on the key_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct sctp_shared_key *sctp_auth_get_shkey(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) __u16 key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct sctp_shared_key *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /* First search associations set of endpoint pair shared keys */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) key_for_each(key, &asoc->endpoint_shared_keys) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (key->key_id == key_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (!key->deactivated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * Initialize all the possible digest transforms that we can use. Right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * now, the supported digests are SHA1 and SHA256. We do this here once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * because of the restrictiong that transforms may only be allocated in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * user context. This forces us to pre-allocated all possible transforms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * at the endpoint init time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct crypto_shash *tfm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) __u16 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* If the transforms are already allocated, we are done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (ep->auth_hmacs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* Allocated the array of pointers to transorms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ep->auth_hmacs = kcalloc(SCTP_AUTH_NUM_HMACS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) sizeof(struct crypto_shash *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (!ep->auth_hmacs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) for (id = 0; id < SCTP_AUTH_NUM_HMACS; id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /* See is we support the id. Supported IDs have name and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * length fields set, so that we can allocated and use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * them. We can safely just check for name, for without the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * name, we can't allocate the TFM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (!sctp_hmac_list[id].hmac_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* If this TFM has been allocated, we are all set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (ep->auth_hmacs[id])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* Allocate the ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) tfm = crypto_alloc_shash(sctp_hmac_list[id].hmac_name, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (IS_ERR(tfm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ep->auth_hmacs[id] = tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* Clean up any successful allocations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) sctp_auth_destroy_hmacs(ep->auth_hmacs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ep->auth_hmacs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* Destroy the hmac tfm array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) void sctp_auth_destroy_hmacs(struct crypto_shash *auth_hmacs[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (!auth_hmacs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) for (i = 0; i < SCTP_AUTH_NUM_HMACS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) crypto_free_shash(auth_hmacs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) kfree(auth_hmacs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct sctp_hmac *sctp_auth_get_hmac(__u16 hmac_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return &sctp_hmac_list[hmac_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* Get an hmac description information that we can use to build
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * the AUTH chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct sctp_hmac_algo_param *hmacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) __u16 n_elt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) __u16 id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /* If we have a default entry, use it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (asoc->default_hmac_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return &sctp_hmac_list[asoc->default_hmac_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* Since we do not have a default entry, find the first entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * we support and return that. Do not cache that id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) hmacs = asoc->peer.peer_hmacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (!hmacs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) n_elt = (ntohs(hmacs->param_hdr.length) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) sizeof(struct sctp_paramhdr)) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) for (i = 0; i < n_elt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) id = ntohs(hmacs->hmac_ids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /* Check the id is in the supported range. And
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * see if we support the id. Supported IDs have name and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * length fields set, so that we can allocate and use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * them. We can safely just check for name, for without the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * name, we can't allocate the TFM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (id > SCTP_AUTH_HMAC_ID_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) !sctp_hmac_list[id].hmac_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (id == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return &sctp_hmac_list[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static int __sctp_auth_find_hmacid(__be16 *hmacs, int n_elts, __be16 hmac_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) for (i = 0; i < n_elts; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (hmac_id == hmacs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /* See if the HMAC_ID is one that we claim as supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) int sctp_auth_asoc_verify_hmac_id(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) __be16 hmac_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct sctp_hmac_algo_param *hmacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) __u16 n_elt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (!asoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) hmacs = (struct sctp_hmac_algo_param *)asoc->c.auth_hmacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) n_elt = (ntohs(hmacs->param_hdr.length) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) sizeof(struct sctp_paramhdr)) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return __sctp_auth_find_hmacid(hmacs->hmac_ids, n_elt, hmac_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* Cache the default HMAC id. This to follow this text from SCTP-AUTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * Section 6.1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * The receiver of a HMAC-ALGO parameter SHOULD use the first listed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * algorithm it supports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) void sctp_auth_asoc_set_default_hmac(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct sctp_hmac_algo_param *hmacs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct sctp_endpoint *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) __u16 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) int n_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /* if the default id is already set, use it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (asoc->default_hmac_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) n_params = (ntohs(hmacs->param_hdr.length) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) sizeof(struct sctp_paramhdr)) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) ep = asoc->ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) for (i = 0; i < n_params; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) id = ntohs(hmacs->hmac_ids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /* Check the id is in the supported range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (id > SCTP_AUTH_HMAC_ID_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /* If this TFM has been allocated, use this id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (ep->auth_hmacs[id]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) asoc->default_hmac_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* Check to see if the given chunk is supposed to be authenticated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static int __sctp_auth_cid(enum sctp_cid chunk, struct sctp_chunks_param *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) unsigned short len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (!param || param->param_hdr.length == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) len = ntohs(param->param_hdr.length) - sizeof(struct sctp_paramhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /* SCTP-AUTH, Section 3.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * The chunk types for INIT, INIT-ACK, SHUTDOWN-COMPLETE and AUTH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * chunks MUST NOT be listed in the CHUNKS parameter. However, if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * a CHUNKS parameter is received then the types for INIT, INIT-ACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * SHUTDOWN-COMPLETE and AUTH chunks MUST be ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) for (i = 0; !found && i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) switch (param->chunks[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) case SCTP_CID_INIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) case SCTP_CID_INIT_ACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) case SCTP_CID_SHUTDOWN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) case SCTP_CID_AUTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (param->chunks[i] == chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /* Check if peer requested that this chunk is authenticated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int sctp_auth_send_cid(enum sctp_cid chunk, const struct sctp_association *asoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (!asoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (!asoc->peer.auth_capable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return __sctp_auth_cid(chunk, asoc->peer.peer_chunks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /* Check if we requested that peer authenticate this chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) int sctp_auth_recv_cid(enum sctp_cid chunk, const struct sctp_association *asoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (!asoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (!asoc->peer.auth_capable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return __sctp_auth_cid(chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) (struct sctp_chunks_param *)asoc->c.auth_chunks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) /* SCTP-AUTH: Section 6.2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) * The sender MUST calculate the MAC as described in RFC2104 [2] using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) * the hash function H as described by the MAC Identifier and the shared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * association key K based on the endpoint pair shared key described by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * the shared key identifier. The 'data' used for the computation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * the AUTH-chunk is given by the AUTH chunk with its HMAC field set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * zero (as shown in Figure 6) followed by all chunks that are placed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * after the AUTH chunk in the SCTP packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) struct sk_buff *skb, struct sctp_auth_chunk *auth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) struct sctp_shared_key *ep_key, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct sctp_auth_bytes *asoc_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct crypto_shash *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) __u16 key_id, hmac_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) unsigned char *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) int free_key = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) __u8 *digest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /* Extract the info we need:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * - hmac id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * - key id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) key_id = ntohs(auth->auth_hdr.shkey_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) hmac_id = ntohs(auth->auth_hdr.hmac_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (key_id == asoc->active_key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) asoc_key = asoc->asoc_shared_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /* ep_key can't be NULL here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) asoc_key = sctp_auth_asoc_create_secret(asoc, ep_key, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (!asoc_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) free_key = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /* set up scatter list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) end = skb_tail_pointer(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) tfm = asoc->ep->auth_hmacs[hmac_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) digest = auth->auth_hdr.hmac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (crypto_shash_setkey(tfm, &asoc_key->data[0], asoc_key->len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) crypto_shash_tfm_digest(tfm, (u8 *)auth, end - (unsigned char *)auth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (free_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) sctp_auth_key_put(asoc_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /* API Helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* Add a chunk to the endpoint authenticated chunk list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) int sctp_auth_ep_add_chunkid(struct sctp_endpoint *ep, __u8 chunk_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct sctp_chunks_param *p = ep->auth_chunk_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) __u16 nchunks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) __u16 param_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* If this chunk is already specified, we are done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (__sctp_auth_cid(chunk_id, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /* Check if we can add this chunk to the array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) param_len = ntohs(p->param_hdr.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) nchunks = param_len - sizeof(struct sctp_paramhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (nchunks == SCTP_NUM_CHUNK_TYPES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) p->chunks[nchunks] = chunk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) p->param_hdr.length = htons(param_len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) /* Add hmac identifires to the endpoint list of supported hmac ids */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) struct sctp_hmacalgo *hmacs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) int has_sha1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) __u16 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /* Scan the list looking for unsupported id. Also make sure that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * SHA1 is specified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) for (i = 0; i < hmacs->shmac_num_idents; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) id = hmacs->shmac_idents[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (id > SCTP_AUTH_HMAC_ID_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (SCTP_AUTH_HMAC_ID_SHA1 == id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) has_sha1 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (!sctp_hmac_list[id].hmac_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (!has_sha1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) for (i = 0; i < hmacs->shmac_num_idents; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) ep->auth_hmacs_list->hmac_ids[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) htons(hmacs->shmac_idents[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) ep->auth_hmacs_list->param_hdr.length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) htons(sizeof(struct sctp_paramhdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) hmacs->shmac_num_idents * sizeof(__u16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /* Set a new shared key on either endpoint or association. If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * key with a same ID already exists, replace the key (remove the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * old key and add a new one).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) int sctp_auth_set_key(struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct sctp_authkey *auth_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) struct sctp_shared_key *cur_key, *shkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct sctp_auth_bytes *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) struct list_head *sh_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) int replace = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) /* Try to find the given key id to see if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) * we are doing a replace, or adding a new key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (asoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (!asoc->peer.auth_capable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) sh_keys = &asoc->endpoint_shared_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (!ep->auth_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) sh_keys = &ep->endpoint_shared_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) key_for_each(shkey, sh_keys) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (shkey->key_id == auth_key->sca_keynumber) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) replace = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) cur_key = sctp_auth_shkey_create(auth_key->sca_keynumber, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (!cur_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /* Create a new key data based on the info passed in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) key = sctp_auth_create_key(auth_key->sca_keylength, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (!key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) kfree(cur_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) cur_key->key = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (!replace) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) list_add(&cur_key->key_list, sh_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) list_del_init(&shkey->key_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) sctp_auth_shkey_release(shkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) list_add(&cur_key->key_list, sh_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (asoc && asoc->active_key_id == auth_key->sca_keynumber)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) int sctp_auth_set_active_key(struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) __u16 key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct sctp_shared_key *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) struct list_head *sh_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) /* The key identifier MUST correst to an existing key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (asoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (!asoc->peer.auth_capable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) sh_keys = &asoc->endpoint_shared_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (!ep->auth_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) sh_keys = &ep->endpoint_shared_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) key_for_each(key, sh_keys) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (key->key_id == key_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (!found || key->deactivated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (asoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) asoc->active_key_id = key_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) ep->active_key_id = key_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) int sctp_auth_del_key_id(struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) __u16 key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) struct sctp_shared_key *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct list_head *sh_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /* The key identifier MUST NOT be the current active key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * The key identifier MUST correst to an existing key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (asoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (!asoc->peer.auth_capable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (asoc->active_key_id == key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) sh_keys = &asoc->endpoint_shared_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (!ep->auth_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (ep->active_key_id == key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) sh_keys = &ep->endpoint_shared_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) key_for_each(key, sh_keys) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (key->key_id == key_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) /* Delete the shared key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) list_del_init(&key->key_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) sctp_auth_shkey_release(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) int sctp_auth_deact_key_id(struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct sctp_association *asoc, __u16 key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) struct sctp_shared_key *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) struct list_head *sh_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) /* The key identifier MUST NOT be the current active key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * The key identifier MUST correst to an existing key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (asoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (!asoc->peer.auth_capable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (asoc->active_key_id == key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) sh_keys = &asoc->endpoint_shared_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (!ep->auth_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (ep->active_key_id == key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) sh_keys = &ep->endpoint_shared_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) key_for_each(key, sh_keys) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (key->key_id == key_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) /* refcnt == 1 and !list_empty mean it's not being used anywhere
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * and deactivated will be set, so it's time to notify userland
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * that this shkey can be freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (asoc && !list_empty(&key->key_list) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) refcount_read(&key->refcnt) == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct sctp_ulpevent *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ev = sctp_ulpevent_make_authkey(asoc, key->key_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) SCTP_AUTH_FREE_KEY, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) asoc->stream.si->enqueue_event(&asoc->ulpq, ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) key->deactivated = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) int sctp_auth_init(struct sctp_endpoint *ep, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* Allocate space for HMACS and CHUNKS authentication
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * variables. There are arrays that we encode directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * into parameters to make the rest of the operations easier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (!ep->auth_hmacs_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct sctp_hmac_algo_param *auth_hmacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) auth_hmacs = kzalloc(struct_size(auth_hmacs, hmac_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) SCTP_AUTH_NUM_HMACS), gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (!auth_hmacs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) goto nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /* Initialize the HMACS parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * SCTP-AUTH: Section 3.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) * Every endpoint supporting SCTP chunk authentication MUST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * support the HMAC based on the SHA-1 algorithm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) auth_hmacs->param_hdr.type = SCTP_PARAM_HMAC_ALGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) auth_hmacs->param_hdr.length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) htons(sizeof(struct sctp_paramhdr) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) auth_hmacs->hmac_ids[0] = htons(SCTP_AUTH_HMAC_ID_SHA1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) ep->auth_hmacs_list = auth_hmacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (!ep->auth_chunk_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) struct sctp_chunks_param *auth_chunks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) auth_chunks = kzalloc(sizeof(*auth_chunks) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) SCTP_NUM_CHUNK_TYPES, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (!auth_chunks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) goto nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /* Initialize the CHUNKS parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) auth_chunks->param_hdr.length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) htons(sizeof(struct sctp_paramhdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) ep->auth_chunk_list = auth_chunks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) /* Allocate and initialize transorms arrays for supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * HMACs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) err = sctp_auth_init_hmacs(ep, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) goto nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) /* Free all allocations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) kfree(ep->auth_hmacs_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) kfree(ep->auth_chunk_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) ep->auth_hmacs_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) ep->auth_chunk_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) void sctp_auth_free(struct sctp_endpoint *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) kfree(ep->auth_hmacs_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) kfree(ep->auth_chunk_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) ep->auth_hmacs_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) ep->auth_chunk_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) sctp_auth_destroy_hmacs(ep->auth_hmacs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) ep->auth_hmacs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }