Print this page
Bayard's initial drop, needs finishing, or at least testing.

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/inet/ip/ipsecesp.c
          +++ new/usr/src/uts/common/inet/ip/ipsecesp.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
       24 + * Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
  24   25   */
  25   26  
  26   27  #include <sys/types.h>
  27   28  #include <sys/stream.h>
  28   29  #include <sys/stropts.h>
  29   30  #include <sys/errno.h>
  30   31  #include <sys/strlog.h>
  31   32  #include <sys/tihdr.h>
  32   33  #include <sys/socket.h>
  33   34  #include <sys/ddi.h>
↓ open down ↓ 54 lines elided ↑ open up ↑
  88   89          { 0,    0xffffffffU,    0,      "ipsecesp_default_soft_bytes"},
  89   90          { 0,    0xffffffffU,    0,      "ipsecesp_default_hard_bytes"},
  90   91          { 0,    0xffffffffU,    24000,  "ipsecesp_default_soft_addtime"},
  91   92          { 0,    0xffffffffU,    28800,  "ipsecesp_default_hard_addtime"},
  92   93          { 0,    0xffffffffU,    0,      "ipsecesp_default_soft_usetime"},
  93   94          { 0,    0xffffffffU,    0,      "ipsecesp_default_hard_usetime"},
  94   95          { 0,    1,              0,      "ipsecesp_log_unknown_spi"},
  95   96          { 0,    2,              1,      "ipsecesp_padding_check"},
  96   97          { 0,    600,            20,     "ipsecesp_nat_keepalive_interval"},
  97   98  };
  98      -#define ipsecesp_debug  ipsecesp_params[0].ipsecesp_param_value
  99      -#define ipsecesp_age_interval ipsecesp_params[1].ipsecesp_param_value
 100      -#define ipsecesp_age_int_max    ipsecesp_params[1].ipsecesp_param_max
 101      -#define ipsecesp_reap_delay     ipsecesp_params[2].ipsecesp_param_value
 102      -#define ipsecesp_replay_size    ipsecesp_params[3].ipsecesp_param_value
 103      -#define ipsecesp_acquire_timeout        \
 104      -        ipsecesp_params[4].ipsecesp_param_value
 105      -#define ipsecesp_larval_timeout \
 106      -        ipsecesp_params[5].ipsecesp_param_value
 107      -#define ipsecesp_default_soft_bytes     \
 108      -        ipsecesp_params[6].ipsecesp_param_value
 109      -#define ipsecesp_default_hard_bytes     \
 110      -        ipsecesp_params[7].ipsecesp_param_value
 111      -#define ipsecesp_default_soft_addtime   \
 112      -        ipsecesp_params[8].ipsecesp_param_value
 113      -#define ipsecesp_default_hard_addtime   \
 114      -        ipsecesp_params[9].ipsecesp_param_value
 115      -#define ipsecesp_default_soft_usetime   \
 116      -        ipsecesp_params[10].ipsecesp_param_value
 117      -#define ipsecesp_default_hard_usetime   \
 118      -        ipsecesp_params[11].ipsecesp_param_value
 119      -#define ipsecesp_log_unknown_spi        \
 120      -        ipsecesp_params[12].ipsecesp_param_value
 121      -#define ipsecesp_padding_check  \
 122      -        ipsecesp_params[13].ipsecesp_param_value
 123   99  /* For ipsecesp_nat_keepalive_interval, see ipsecesp.h. */
 124  100  
 125  101  #define esp0dbg(a)      printf a
 126  102  /* NOTE:  != 0 instead of > 0 so lint doesn't complain. */
 127  103  #define esp1dbg(espstack, a)    if (espstack->ipsecesp_debug != 0) printf a
 128  104  #define esp2dbg(espstack, a)    if (espstack->ipsecesp_debug > 1) printf a
 129  105  #define esp3dbg(espstack, a)    if (espstack->ipsecesp_debug > 2) printf a
 130  106  
 131  107  static int ipsecesp_open(queue_t *, dev_t *, int, int, cred_t *);
 132  108  static int ipsecesp_close(queue_t *);
 133  109  static void ipsecesp_wput(queue_t *, mblk_t *);
 134  110  static void     *ipsecesp_stack_init(netstackid_t stackid, netstack_t *ns);
 135  111  static void     ipsecesp_stack_fini(netstackid_t stackid, void *arg);
 136      -static void esp_send_acquire(ipsacq_t *, mblk_t *, netstack_t *);
 137  112  
 138  113  static void esp_prepare_udp(netstack_t *, mblk_t *, ipha_t *);
 139  114  static void esp_outbound_finish(mblk_t *, ip_xmit_attr_t *);
 140  115  static void esp_inbound_restart(mblk_t *, ip_recv_attr_t *);
 141  116  
 142  117  static boolean_t esp_register_out(uint32_t, uint32_t, uint_t,
 143  118      ipsecesp_stack_t *, cred_t *);
 144  119  static boolean_t esp_strip_header(mblk_t *, boolean_t, uint32_t,
 145  120      kstat_named_t **, ipsecesp_stack_t *);
 146  121  static mblk_t *esp_submit_req_inbound(mblk_t *, ip_recv_attr_t *,
↓ open down ↓ 27 lines elided ↑ open up ↑
 174  149  /*
 175  150   * OTOH, this one is set at open/close, and I'm D_MTQPAIR for now.
 176  151   *
 177  152   * Question:    Do I need this, given that all instance's esps->esps_wq point
 178  153   *              to IP?
 179  154   *
 180  155   * Answer:      Yes, because I need to know which queue is BOUND to
 181  156   *              IPPROTO_ESP
 182  157   */
 183  158  
 184      -/*
 185      - * Stats.  This may eventually become a full-blown SNMP MIB once that spec
 186      - * stabilizes.
 187      - */
 188      -
 189      -typedef struct esp_kstats_s {
 190      -        kstat_named_t esp_stat_num_aalgs;
 191      -        kstat_named_t esp_stat_good_auth;
 192      -        kstat_named_t esp_stat_bad_auth;
 193      -        kstat_named_t esp_stat_bad_padding;
 194      -        kstat_named_t esp_stat_replay_failures;
 195      -        kstat_named_t esp_stat_replay_early_failures;
 196      -        kstat_named_t esp_stat_keysock_in;
 197      -        kstat_named_t esp_stat_out_requests;
 198      -        kstat_named_t esp_stat_acquire_requests;
 199      -        kstat_named_t esp_stat_bytes_expired;
 200      -        kstat_named_t esp_stat_out_discards;
 201      -        kstat_named_t esp_stat_crypto_sync;
 202      -        kstat_named_t esp_stat_crypto_async;
 203      -        kstat_named_t esp_stat_crypto_failures;
 204      -        kstat_named_t esp_stat_num_ealgs;
 205      -        kstat_named_t esp_stat_bad_decrypt;
 206      -        kstat_named_t esp_stat_sa_port_renumbers;
 207      -} esp_kstats_t;
 208      -
 209      -/*
 210      - * espstack->esp_kstats is equal to espstack->esp_ksp->ks_data if
 211      - * kstat_create_netstack for espstack->esp_ksp succeeds, but when it
 212      - * fails, it will be NULL. Note this is done for all stack instances,
 213      - * so it *could* fail. hence a non-NULL checking is done for
 214      - * ESP_BUMP_STAT and ESP_DEBUMP_STAT
 215      - */
 216      -#define ESP_BUMP_STAT(espstack, x)                                      \
 217      -do {                                                                    \
 218      -        if (espstack->esp_kstats != NULL)                               \
 219      -                (espstack->esp_kstats->esp_stat_ ## x).value.ui64++;    \
 220      -_NOTE(CONSTCOND)                                                        \
 221      -} while (0)
 222      -
 223      -#define ESP_DEBUMP_STAT(espstack, x)                                    \
 224      -do {                                                                    \
 225      -        if (espstack->esp_kstats != NULL)                               \
 226      -                (espstack->esp_kstats->esp_stat_ ## x).value.ui64--;    \
 227      -_NOTE(CONSTCOND)                                                        \
 228      -} while (0)
 229      -
 230  159  static int      esp_kstat_update(kstat_t *, int);
 231  160  
 232  161  static boolean_t
 233  162  esp_kstat_init(ipsecesp_stack_t *espstack, netstackid_t stackid)
 234  163  {
 235  164          espstack->esp_ksp = kstat_create_netstack("ipsecesp", 0, "esp_stat",
 236  165              "net", KSTAT_TYPE_NAMED,
 237  166              sizeof (esp_kstats_t) / sizeof (kstat_named_t),
 238  167              KSTAT_FLAG_PERSISTENT, stackid);
 239  168  
↓ open down ↓ 51 lines elided ↑ open up ↑
 291  220          ns = netstack_find_by_stackid(stackid);
 292  221          if (ns == NULL)
 293  222                  return (-1);
 294  223          ipss = ns->netstack_ipsec;
 295  224          if (ipss == NULL) {
 296  225                  netstack_rele(ns);
 297  226                  return (-1);
 298  227          }
 299  228          ekp = (esp_kstats_t *)kp->ks_data;
 300  229  
 301      -        mutex_enter(&ipss->ipsec_alg_lock);
      230 +        rw_enter(&ipss->ipsec_alg_lock, RW_READER);
 302  231          ekp->esp_stat_num_aalgs.value.ui64 =
 303  232              ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
 304  233          ekp->esp_stat_num_ealgs.value.ui64 =
 305  234              ipss->ipsec_nalgs[IPSEC_ALG_ENCR];
 306      -        mutex_exit(&ipss->ipsec_alg_lock);
      235 +        rw_exit(&ipss->ipsec_alg_lock);
 307  236  
 308  237          netstack_rele(ns);
 309  238          return (0);
 310  239  }
 311  240  
 312  241  #ifdef DEBUG
 313  242  /*
 314  243   * Debug routine, useful to see pre-encryption data.
 315  244   */
 316  245  static char *
↓ open down ↓ 179 lines elided ↑ open up ↑
 496  425                              espp->ipsecesp_param_name,
 497  426                              ipsecesp_param_get, ipsecesp_param_set,
 498  427                              (caddr_t)espp)) {
 499  428                                  nd_free(ndp);
 500  429                                  return (B_FALSE);
 501  430                          }
 502  431                  }
 503  432          }
 504  433          return (B_TRUE);
 505  434  }
      435 +
 506  436  /*
 507  437   * Initialize things for ESP for each stack instance
 508  438   */
 509  439  static void *
 510  440  ipsecesp_stack_init(netstackid_t stackid, netstack_t *ns)
 511  441  {
 512  442          ipsecesp_stack_t        *espstack;
 513  443          ipsecespparam_t         *espp;
 514  444  
 515  445          espstack = (ipsecesp_stack_t *)kmem_zalloc(sizeof (*espstack),
↓ open down ↓ 4 lines elided ↑ open up ↑
 520  450          espstack->ipsecesp_params = espp;
 521  451          bcopy(lcl_param_arr, espp, sizeof (lcl_param_arr));
 522  452  
 523  453          (void) ipsecesp_param_register(&espstack->ipsecesp_g_nd, espp,
 524  454              A_CNT(lcl_param_arr));
 525  455  
 526  456          (void) esp_kstat_init(espstack, stackid);
 527  457  
 528  458          espstack->esp_sadb.s_acquire_timeout =
 529  459              &espstack->ipsecesp_acquire_timeout;
 530      -        espstack->esp_sadb.s_acqfn = esp_send_acquire;
 531  460          sadbp_init("ESP", &espstack->esp_sadb, SADB_SATYPE_ESP, esp_hash_size,
 532  461              espstack->ipsecesp_netstack);
 533  462  
 534  463          mutex_init(&espstack->ipsecesp_param_lock, NULL, MUTEX_DEFAULT, 0);
 535  464  
 536  465          ip_drop_register(&espstack->esp_dropper, "IPsec ESP");
 537  466          return (espstack);
 538  467  }
 539  468  
 540  469  /*
↓ open down ↓ 10 lines elided ↑ open up ↑
 551  480   * Destroy things for ESP for one stack instance
 552  481   */
 553  482  static void
 554  483  ipsecesp_stack_fini(netstackid_t stackid, void *arg)
 555  484  {
 556  485          ipsecesp_stack_t *espstack = (ipsecesp_stack_t *)arg;
 557  486  
 558  487          if (espstack->esp_pfkey_q != NULL) {
 559  488                  (void) quntimeout(espstack->esp_pfkey_q, espstack->esp_event);
 560  489          }
 561      -        espstack->esp_sadb.s_acqfn = NULL;
 562  490          espstack->esp_sadb.s_acquire_timeout = NULL;
 563  491          sadbp_destroy(&espstack->esp_sadb, espstack->ipsecesp_netstack);
 564  492          ip_drop_unregister(&espstack->esp_dropper);
 565  493          mutex_destroy(&espstack->ipsecesp_param_lock);
 566  494          nd_free(&espstack->ipsecesp_g_nd);
 567  495  
 568  496          kmem_free(espstack->ipsecesp_params, sizeof (lcl_param_arr));
 569  497          espstack->ipsecesp_params = NULL;
 570  498          kstat_delete_netstack(espstack->esp_ksp, stackid);
 571  499          espstack->esp_ksp = NULL;
↓ open down ↓ 602 lines elided ↑ open up ↑
1174 1102                  ipha_t *ipha = (ipha_t *)data_mp->b_rptr;
1175 1103                  ipha->ipha_length = htons(ntohs(ipha->ipha_length) -
1176 1104                      ipsa->ipsa_mac_len);
1177 1105          }
1178 1106  
1179 1107          /* submit the request to the crypto framework */
1180 1108          return (esp_submit_req_inbound(data_mp, ira, ipsa,
1181 1109              (uint8_t *)esph - data_mp->b_rptr));
1182 1110  }
1183 1111  
1184      -/*
1185      - * Perform the really difficult work of inserting the proposed situation.
1186      - * Called while holding the algorithm lock.
1187      - */
1188      -static void
1189      -esp_insert_prop(sadb_prop_t *prop, ipsacq_t *acqrec, uint_t combs,
1190      -    netstack_t *ns)
1191      -{
1192      -        sadb_comb_t *comb = (sadb_comb_t *)(prop + 1);
1193      -        ipsec_action_t *ap;
1194      -        ipsec_prot_t *prot;
1195      -        ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
1196      -        ipsec_stack_t   *ipss = ns->netstack_ipsec;
1197      -
1198      -        ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
1199      -
1200      -        prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
1201      -        prop->sadb_prop_len = SADB_8TO64(sizeof (sadb_prop_t));
1202      -        *(uint32_t *)(&prop->sadb_prop_replay) = 0;     /* Quick zero-out! */
1203      -
1204      -        prop->sadb_prop_replay = espstack->ipsecesp_replay_size;
1205      -
1206      -        /*
1207      -         * Based upon algorithm properties, and what-not, prioritize a
1208      -         * proposal, based on the ordering of the ESP algorithms in the
1209      -         * alternatives in the policy rule or socket that was placed
1210      -         * in the acquire record.
1211      -         *
1212      -         * For each action in policy list
1213      -         *   Add combination.  If I've hit limit, return.
1214      -         */
1215      -
1216      -        for (ap = acqrec->ipsacq_act; ap != NULL;
1217      -            ap = ap->ipa_next) {
1218      -                ipsec_alginfo_t *ealg = NULL;
1219      -                ipsec_alginfo_t *aalg = NULL;
1220      -
1221      -                if (ap->ipa_act.ipa_type != IPSEC_POLICY_APPLY)
1222      -                        continue;
1223      -
1224      -                prot = &ap->ipa_act.ipa_apply;
1225      -
1226      -                if (!(prot->ipp_use_esp))
1227      -                        continue;
1228      -
1229      -                if (prot->ipp_esp_auth_alg != 0) {
1230      -                        aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
1231      -                            [prot->ipp_esp_auth_alg];
1232      -                        if (aalg == NULL || !ALG_VALID(aalg))
1233      -                                continue;
1234      -                }
1235      -
1236      -                ASSERT(prot->ipp_encr_alg > 0);
1237      -                ealg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
1238      -                    [prot->ipp_encr_alg];
1239      -                if (ealg == NULL || !ALG_VALID(ealg))
1240      -                        continue;
1241      -
1242      -                comb->sadb_comb_flags = 0;
1243      -                comb->sadb_comb_reserved = 0;
1244      -                comb->sadb_comb_encrypt = ealg->alg_id;
1245      -                comb->sadb_comb_encrypt_minbits =
1246      -                    MAX(prot->ipp_espe_minbits, ealg->alg_ef_minbits);
1247      -                comb->sadb_comb_encrypt_maxbits =
1248      -                    MIN(prot->ipp_espe_maxbits, ealg->alg_ef_maxbits);
1249      -
1250      -                if (aalg == NULL) {
1251      -                        comb->sadb_comb_auth = 0;
1252      -                        comb->sadb_comb_auth_minbits = 0;
1253      -                        comb->sadb_comb_auth_maxbits = 0;
1254      -                } else {
1255      -                        comb->sadb_comb_auth = aalg->alg_id;
1256      -                        comb->sadb_comb_auth_minbits =
1257      -                            MAX(prot->ipp_espa_minbits, aalg->alg_ef_minbits);
1258      -                        comb->sadb_comb_auth_maxbits =
1259      -                            MIN(prot->ipp_espa_maxbits, aalg->alg_ef_maxbits);
1260      -                }
1261      -
1262      -                /*
1263      -                 * The following may be based on algorithm
1264      -                 * properties, but in the meantime, we just pick
1265      -                 * some good, sensible numbers.  Key mgmt. can
1266      -                 * (and perhaps should) be the place to finalize
1267      -                 * such decisions.
1268      -                 */
1269      -
1270      -                /*
1271      -                 * No limits on allocations, since we really don't
1272      -                 * support that concept currently.
1273      -                 */
1274      -                comb->sadb_comb_soft_allocations = 0;
1275      -                comb->sadb_comb_hard_allocations = 0;
1276      -
1277      -                /*
1278      -                 * These may want to come from policy rule..
1279      -                 */
1280      -                comb->sadb_comb_soft_bytes =
1281      -                    espstack->ipsecesp_default_soft_bytes;
1282      -                comb->sadb_comb_hard_bytes =
1283      -                    espstack->ipsecesp_default_hard_bytes;
1284      -                comb->sadb_comb_soft_addtime =
1285      -                    espstack->ipsecesp_default_soft_addtime;
1286      -                comb->sadb_comb_hard_addtime =
1287      -                    espstack->ipsecesp_default_hard_addtime;
1288      -                comb->sadb_comb_soft_usetime =
1289      -                    espstack->ipsecesp_default_soft_usetime;
1290      -                comb->sadb_comb_hard_usetime =
1291      -                    espstack->ipsecesp_default_hard_usetime;
1292      -
1293      -                prop->sadb_prop_len += SADB_8TO64(sizeof (*comb));
1294      -                if (--combs == 0)
1295      -                        break;  /* out of space.. */
1296      -                comb++;
1297      -        }
1298      -}
1299      -
1300      -/*
1301      - * Prepare and actually send the SADB_ACQUIRE message to PF_KEY.
1302      - */
1303      -static void
1304      -esp_send_acquire(ipsacq_t *acqrec, mblk_t *extended, netstack_t *ns)
1305      -{
1306      -        uint_t combs;
1307      -        sadb_msg_t *samsg;
1308      -        sadb_prop_t *prop;
1309      -        mblk_t *pfkeymp, *msgmp;
1310      -        ipsecesp_stack_t *espstack = ns->netstack_ipsecesp;
1311      -        ipsec_stack_t   *ipss = ns->netstack_ipsec;
1312      -
1313      -        ESP_BUMP_STAT(espstack, acquire_requests);
1314      -
1315      -        if (espstack->esp_pfkey_q == NULL) {
1316      -                mutex_exit(&acqrec->ipsacq_lock);
1317      -                return;
1318      -        }
1319      -
1320      -        /* Set up ACQUIRE. */
1321      -        pfkeymp = sadb_setup_acquire(acqrec, SADB_SATYPE_ESP,
1322      -            ns->netstack_ipsec);
1323      -        if (pfkeymp == NULL) {
1324      -                esp0dbg(("sadb_setup_acquire failed.\n"));
1325      -                mutex_exit(&acqrec->ipsacq_lock);
1326      -                return;
1327      -        }
1328      -        ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
1329      -        combs = ipss->ipsec_nalgs[IPSEC_ALG_AUTH] *
1330      -            ipss->ipsec_nalgs[IPSEC_ALG_ENCR];
1331      -        msgmp = pfkeymp->b_cont;
1332      -        samsg = (sadb_msg_t *)(msgmp->b_rptr);
1333      -
1334      -        /* Insert proposal here. */
1335      -
1336      -        prop = (sadb_prop_t *)(((uint64_t *)samsg) + samsg->sadb_msg_len);
1337      -        esp_insert_prop(prop, acqrec, combs, ns);
1338      -        samsg->sadb_msg_len += prop->sadb_prop_len;
1339      -        msgmp->b_wptr += SADB_64TO8(samsg->sadb_msg_len);
1340      -
1341      -        mutex_exit(&ipss->ipsec_alg_lock);
1342      -
1343      -        /*
1344      -         * Must mutex_exit() before sending PF_KEY message up, in
1345      -         * order to avoid recursive mutex_enter() if there are no registered
1346      -         * listeners.
1347      -         *
1348      -         * Once I've sent the message, I'm cool anyway.
1349      -         */
1350      -        mutex_exit(&acqrec->ipsacq_lock);
1351      -        if (extended != NULL) {
1352      -                putnext(espstack->esp_pfkey_q, extended);
1353      -        }
1354      -        putnext(espstack->esp_pfkey_q, pfkeymp);
1355      -}
1356      -
1357 1112  /* XXX refactor me */
1358 1113  /*
1359 1114   * Handle the SADB_GETSPI message.  Create a larval SA.
1360 1115   */
1361 1116  static void
1362 1117  esp_getspi(mblk_t *mp, keysock_in_t *ksi, ipsecesp_stack_t *espstack)
1363 1118  {
1364 1119          ipsa_t *newbie, *target;
1365 1120          isaf_t *outbound, *inbound;
1366 1121          int rc, diagnostic;
↓ open down ↓ 1669 lines elided ↑ open up ↑
3036 2791                  if (sens_tsl != NULL) {
3037 2792                          sens_len = sadb_sens_len_from_label(sens_tsl);
3038 2793                          allocsize += sens_len;
3039 2794                  }
3040 2795          }
3041 2796  
3042 2797          /*
3043 2798           * Allocate the PF_KEY message that follows KEYSOCK_OUT.
3044 2799           */
3045 2800  
3046      -        mutex_enter(&ipss->ipsec_alg_lock);
     2801 +        rw_enter(&ipss->ipsec_alg_lock, RW_READER);
3047 2802          /*
3048 2803           * Fill SADB_REGISTER message's algorithm descriptors.  Hold
3049 2804           * down the lock while filling it.
3050 2805           *
3051 2806           * Return only valid algorithms, so the number of algorithms
3052 2807           * to send up may be less than the number of algorithm entries
3053 2808           * in the table.
3054 2809           */
3055 2810          authalgs = ipss->ipsec_alglists[IPSEC_ALG_AUTH];
3056 2811          for (num_aalgs = 0, i = 0; i < IPSEC_MAX_ALGS; i++)
↓ open down ↓ 8 lines elided ↑ open up ↑
3065 2820          for (num_ealgs = 0, i = 0; i < IPSEC_MAX_ALGS; i++)
3066 2821                  if (encralgs[i] != NULL && ALG_VALID(encralgs[i]))
3067 2822                          num_ealgs++;
3068 2823  
3069 2824          if (num_ealgs != 0) {
3070 2825                  allocsize += (num_ealgs * sizeof (*saalg));
3071 2826                  allocsize += sizeof (*sasupp_encr);
3072 2827          }
3073 2828          keysock_out_mp->b_cont = allocb(allocsize, BPRI_HI);
3074 2829          if (keysock_out_mp->b_cont == NULL) {
3075      -                mutex_exit(&ipss->ipsec_alg_lock);
     2830 +                rw_exit(&ipss->ipsec_alg_lock);
3076 2831                  freemsg(keysock_out_mp);
3077 2832                  return (B_FALSE);
3078 2833          }
3079 2834          pfkey_msg_mp = keysock_out_mp->b_cont;
3080 2835          pfkey_msg_mp->b_wptr += allocsize;
3081 2836  
3082 2837          nextext = (sadb_ext_t *)(pfkey_msg_mp->b_rptr + sizeof (*samsg));
3083 2838  
3084 2839          if (num_aalgs != 0) {
3085 2840                  sasupp_auth = (sadb_supported_t *)nextext;
↓ open down ↓ 73 lines elided ↑ open up ↑
3159 2914                                      "Missed ealg #%d.\n", i);
3160 2915                          }
3161 2916                  }
3162 2917  #endif /* DEBUG */
3163 2918                  nextext = (sadb_ext_t *)saalg;
3164 2919          }
3165 2920  
3166 2921          current_aalgs = num_aalgs;
3167 2922          current_ealgs = num_ealgs;
3168 2923  
3169      -        mutex_exit(&ipss->ipsec_alg_lock);
     2924 +        rw_exit(&ipss->ipsec_alg_lock);
3170 2925  
3171 2926          if (sens_tsl != NULL) {
3172 2927                  sens = (sadb_sens_t *)nextext;
3173 2928                  sadb_sens_from_label(sens, SADB_EXT_SENSITIVITY,
3174 2929                      sens_tsl, sens_len);
3175 2930  
3176 2931                  nextext = (sadb_ext_t *)(((uint8_t *)sens) + sens_len);
3177 2932          }
3178 2933  
3179 2934          /* Now fill the rest of the SADB_REGISTER message. */
↓ open down ↓ 504 lines elided ↑ open up ↑
3684 3439  
3685 3440          if ((*diagnostic = sadb_labelchk(ksi)) != 0)
3686 3441                  return (EINVAL);
3687 3442  
3688 3443          /*
3689 3444           * XXX Policy :  I'm not checking identities at this time,
3690 3445           * but if I did, I'd do them here, before I sent
3691 3446           * the weak key check up to the algorithm.
3692 3447           */
3693 3448  
3694      -        mutex_enter(&ipss->ipsec_alg_lock);
     3449 +        rw_enter(&ipss->ipsec_alg_lock, RW_READER);
3695 3450  
3696 3451          /*
3697 3452           * First locate the authentication algorithm.
3698 3453           */
3699 3454  #ifdef IPSEC_LATENCY_TEST
3700 3455          if (akey != NULL && assoc->sadb_sa_auth != SADB_AALG_NONE) {
3701 3456  #else
3702 3457          if (akey != NULL) {
3703 3458  #endif
3704 3459                  ipsec_alginfo_t *aalg;
3705 3460  
3706 3461                  aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
3707 3462                      [assoc->sadb_sa_auth];
3708 3463                  if (aalg == NULL || !ALG_VALID(aalg)) {
3709      -                        mutex_exit(&ipss->ipsec_alg_lock);
     3464 +                        rw_exit(&ipss->ipsec_alg_lock);
3710 3465                          esp1dbg(espstack, ("Couldn't find auth alg #%d.\n",
3711 3466                              assoc->sadb_sa_auth));
3712 3467                          *diagnostic = SADB_X_DIAGNOSTIC_BAD_AALG;
3713 3468                          return (EINVAL);
3714 3469                  }
3715 3470  
3716 3471                  /*
3717 3472                   * Sanity check key sizes.
3718 3473                   * Note: It's not possible to use SADB_AALG_NONE because
3719 3474                   * this auth_alg is not defined with ALG_FLAG_VALID. If this
3720 3475                   * ever changes, the same check for SADB_AALG_NONE and
3721 3476                   * a auth_key != NULL should be made here ( see below).
3722 3477                   */
3723 3478                  if (!ipsec_valid_key_size(akey->sadb_key_bits, aalg)) {
3724      -                        mutex_exit(&ipss->ipsec_alg_lock);
     3479 +                        rw_exit(&ipss->ipsec_alg_lock);
3725 3480                          *diagnostic = SADB_X_DIAGNOSTIC_BAD_AKEYBITS;
3726 3481                          return (EINVAL);
3727 3482                  }
3728 3483                  ASSERT(aalg->alg_mech_type != CRYPTO_MECHANISM_INVALID);
3729 3484  
3730 3485                  /* check key and fix parity if needed */
3731 3486                  if (ipsec_check_key(aalg->alg_mech_type, akey, B_TRUE,
3732 3487                      diagnostic) != 0) {
3733      -                        mutex_exit(&ipss->ipsec_alg_lock);
     3488 +                        rw_exit(&ipss->ipsec_alg_lock);
3734 3489                          return (EINVAL);
3735 3490                  }
3736 3491          }
3737 3492  
3738 3493          /*
3739 3494           * Then locate the encryption algorithm.
3740 3495           */
3741 3496          if (ekey != NULL) {
3742 3497                  uint_t keybits;
3743 3498                  ipsec_alginfo_t *ealg;
3744 3499  
3745 3500                  ealg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
3746 3501                      [assoc->sadb_sa_encrypt];
3747 3502                  if (ealg == NULL || !ALG_VALID(ealg)) {
3748      -                        mutex_exit(&ipss->ipsec_alg_lock);
     3503 +                        rw_exit(&ipss->ipsec_alg_lock);
3749 3504                          esp1dbg(espstack, ("Couldn't find encr alg #%d.\n",
3750 3505                              assoc->sadb_sa_encrypt));
3751 3506                          *diagnostic = SADB_X_DIAGNOSTIC_BAD_EALG;
3752 3507                          return (EINVAL);
3753 3508                  }
3754 3509  
3755 3510                  /*
3756 3511                   * Sanity check key sizes. If the encryption algorithm is
3757 3512                   * SADB_EALG_NULL but the encryption key is NOT
3758 3513                   * NULL then complain.
3759 3514                   *
3760 3515                   * The keying material includes salt bits if required by
3761 3516                   * algorithm and optionally the Initial IV, check the
3762 3517                   * length of whats left.
3763 3518                   */
3764 3519                  keybits = ekey->sadb_key_bits;
3765 3520                  keybits -= ekey->sadb_key_reserved;
3766 3521                  keybits -= SADB_8TO1(ealg->alg_saltlen);
3767 3522                  if ((assoc->sadb_sa_encrypt == SADB_EALG_NULL) ||
3768 3523                      (!ipsec_valid_key_size(keybits, ealg))) {
3769      -                        mutex_exit(&ipss->ipsec_alg_lock);
     3524 +                        rw_exit(&ipss->ipsec_alg_lock);
3770 3525                          *diagnostic = SADB_X_DIAGNOSTIC_BAD_EKEYBITS;
3771 3526                          return (EINVAL);
3772 3527                  }
3773 3528                  ASSERT(ealg->alg_mech_type != CRYPTO_MECHANISM_INVALID);
3774 3529  
3775 3530                  /* check key */
3776 3531                  if (ipsec_check_key(ealg->alg_mech_type, ekey, B_FALSE,
3777 3532                      diagnostic) != 0) {
3778      -                        mutex_exit(&ipss->ipsec_alg_lock);
     3533 +                        rw_exit(&ipss->ipsec_alg_lock);
3779 3534                          return (EINVAL);
3780 3535                  }
3781 3536          }
3782      -        mutex_exit(&ipss->ipsec_alg_lock);
     3537 +        rw_exit(&ipss->ipsec_alg_lock);
3783 3538  
3784 3539          return (esp_add_sa_finish(mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
3785 3540              diagnostic, espstack));
3786 3541  }
3787 3542  
3788 3543  /*
3789 3544   * Update a security association.  Updates come in two varieties.  The first
3790 3545   * is an update of lifetimes on a non-larval SA.  The second is an update of
3791 3546   * a larval SA, which ends up looking a lot more like an add.
3792 3547   */
↓ open down ↓ 404 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX