Print this page
8529 Extended and regular SADB_ACQUIREs should share address extension code
Portions contributed by: Bayard Bell <buffer.g.overflow@gmail.com>

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.
       25 + * Copyright (c) 2017 Joyent, Inc.
  24   26   */
  25   27  
  26   28  #include <sys/types.h>
  27   29  #include <sys/stream.h>
  28   30  #include <sys/stropts.h>
  29   31  #include <sys/errno.h>
  30   32  #include <sys/strlog.h>
  31   33  #include <sys/tihdr.h>
  32   34  #include <sys/socket.h>
  33   35  #include <sys/ddi.h>
↓ open down ↓ 54 lines elided ↑ open up ↑
  88   90          { 0,    0xffffffffU,    0,      "ipsecesp_default_soft_bytes"},
  89   91          { 0,    0xffffffffU,    0,      "ipsecesp_default_hard_bytes"},
  90   92          { 0,    0xffffffffU,    24000,  "ipsecesp_default_soft_addtime"},
  91   93          { 0,    0xffffffffU,    28800,  "ipsecesp_default_hard_addtime"},
  92   94          { 0,    0xffffffffU,    0,      "ipsecesp_default_soft_usetime"},
  93   95          { 0,    0xffffffffU,    0,      "ipsecesp_default_hard_usetime"},
  94   96          { 0,    1,              0,      "ipsecesp_log_unknown_spi"},
  95   97          { 0,    2,              1,      "ipsecesp_padding_check"},
  96   98          { 0,    600,            20,     "ipsecesp_nat_keepalive_interval"},
  97   99  };
  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  100  /* For ipsecesp_nat_keepalive_interval, see ipsecesp.h. */
 124  101  
 125  102  #define esp0dbg(a)      printf a
 126  103  /* NOTE:  != 0 instead of > 0 so lint doesn't complain. */
 127  104  #define esp1dbg(espstack, a)    if (espstack->ipsecesp_debug != 0) printf a
 128  105  #define esp2dbg(espstack, a)    if (espstack->ipsecesp_debug > 1) printf a
 129  106  #define esp3dbg(espstack, a)    if (espstack->ipsecesp_debug > 2) printf a
 130  107  
 131  108  static int ipsecesp_open(queue_t *, dev_t *, int, int, cred_t *);
 132  109  static int ipsecesp_close(queue_t *);
 133  110  static void ipsecesp_wput(queue_t *, mblk_t *);
 134  111  static void     *ipsecesp_stack_init(netstackid_t stackid, netstack_t *ns);
 135  112  static void     ipsecesp_stack_fini(netstackid_t stackid, void *arg);
 136      -static void esp_send_acquire(ipsacq_t *, mblk_t *, netstack_t *);
 137  113  
 138  114  static void esp_prepare_udp(netstack_t *, mblk_t *, ipha_t *);
 139  115  static void esp_outbound_finish(mblk_t *, ip_xmit_attr_t *);
 140  116  static void esp_inbound_restart(mblk_t *, ip_recv_attr_t *);
 141  117  
 142  118  static boolean_t esp_register_out(uint32_t, uint32_t, uint_t,
 143  119      ipsecesp_stack_t *, cred_t *);
 144  120  static boolean_t esp_strip_header(mblk_t *, boolean_t, uint32_t,
 145  121      kstat_named_t **, ipsecesp_stack_t *);
 146  122  static mblk_t *esp_submit_req_inbound(mblk_t *, ip_recv_attr_t *,
↓ open down ↓ 27 lines elided ↑ open up ↑
 174  150  /*
 175  151   * OTOH, this one is set at open/close, and I'm D_MTQPAIR for now.
 176  152   *
 177  153   * Question:    Do I need this, given that all instance's esps->esps_wq point
 178  154   *              to IP?
 179  155   *
 180  156   * Answer:      Yes, because I need to know which queue is BOUND to
 181  157   *              IPPROTO_ESP
 182  158   */
 183  159  
 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  160  static int      esp_kstat_update(kstat_t *, int);
 231  161  
 232  162  static boolean_t
 233  163  esp_kstat_init(ipsecesp_stack_t *espstack, netstackid_t stackid)
 234  164  {
 235  165          espstack->esp_ksp = kstat_create_netstack("ipsecesp", 0, "esp_stat",
 236  166              "net", KSTAT_TYPE_NAMED,
 237  167              sizeof (esp_kstats_t) / sizeof (kstat_named_t),
 238  168              KSTAT_FLAG_PERSISTENT, stackid);
 239  169  
↓ open down ↓ 256 lines elided ↑ open up ↑
 496  426                              espp->ipsecesp_param_name,
 497  427                              ipsecesp_param_get, ipsecesp_param_set,
 498  428                              (caddr_t)espp)) {
 499  429                                  nd_free(ndp);
 500  430                                  return (B_FALSE);
 501  431                          }
 502  432                  }
 503  433          }
 504  434          return (B_TRUE);
 505  435  }
      436 +
 506  437  /*
 507  438   * Initialize things for ESP for each stack instance
 508  439   */
 509  440  static void *
 510  441  ipsecesp_stack_init(netstackid_t stackid, netstack_t *ns)
 511  442  {
 512  443          ipsecesp_stack_t        *espstack;
 513  444          ipsecespparam_t         *espp;
 514  445  
 515  446          espstack = (ipsecesp_stack_t *)kmem_zalloc(sizeof (*espstack),
↓ open down ↓ 4 lines elided ↑ open up ↑
 520  451          espstack->ipsecesp_params = espp;
 521  452          bcopy(lcl_param_arr, espp, sizeof (lcl_param_arr));
 522  453  
 523  454          (void) ipsecesp_param_register(&espstack->ipsecesp_g_nd, espp,
 524  455              A_CNT(lcl_param_arr));
 525  456  
 526  457          (void) esp_kstat_init(espstack, stackid);
 527  458  
 528  459          espstack->esp_sadb.s_acquire_timeout =
 529  460              &espstack->ipsecesp_acquire_timeout;
 530      -        espstack->esp_sadb.s_acqfn = esp_send_acquire;
 531  461          sadbp_init("ESP", &espstack->esp_sadb, SADB_SATYPE_ESP, esp_hash_size,
 532  462              espstack->ipsecesp_netstack);
 533  463  
 534  464          mutex_init(&espstack->ipsecesp_param_lock, NULL, MUTEX_DEFAULT, 0);
 535  465  
 536  466          ip_drop_register(&espstack->esp_dropper, "IPsec ESP");
 537  467          return (espstack);
 538  468  }
 539  469  
 540  470  /*
↓ open down ↓ 10 lines elided ↑ open up ↑
 551  481   * Destroy things for ESP for one stack instance
 552  482   */
 553  483  static void
 554  484  ipsecesp_stack_fini(netstackid_t stackid, void *arg)
 555  485  {
 556  486          ipsecesp_stack_t *espstack = (ipsecesp_stack_t *)arg;
 557  487  
 558  488          if (espstack->esp_pfkey_q != NULL) {
 559  489                  (void) quntimeout(espstack->esp_pfkey_q, espstack->esp_event);
 560  490          }
 561      -        espstack->esp_sadb.s_acqfn = NULL;
 562  491          espstack->esp_sadb.s_acquire_timeout = NULL;
 563  492          sadbp_destroy(&espstack->esp_sadb, espstack->ipsecesp_netstack);
 564  493          ip_drop_unregister(&espstack->esp_dropper);
 565  494          mutex_destroy(&espstack->ipsecesp_param_lock);
 566  495          nd_free(&espstack->ipsecesp_g_nd);
 567  496  
 568  497          kmem_free(espstack->ipsecesp_params, sizeof (lcl_param_arr));
 569  498          espstack->ipsecesp_params = NULL;
 570  499          kstat_delete_netstack(espstack->esp_ksp, stackid);
 571  500          espstack->esp_ksp = NULL;
↓ open down ↓ 602 lines elided ↑ open up ↑
1174 1103                  ipha_t *ipha = (ipha_t *)data_mp->b_rptr;
1175 1104                  ipha->ipha_length = htons(ntohs(ipha->ipha_length) -
1176 1105                      ipsa->ipsa_mac_len);
1177 1106          }
1178 1107  
1179 1108          /* submit the request to the crypto framework */
1180 1109          return (esp_submit_req_inbound(data_mp, ira, ipsa,
1181 1110              (uint8_t *)esph - data_mp->b_rptr));
1182 1111  }
1183 1112  
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(RW_READ_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(RW_READ_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      -        rw_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 1113  /* XXX refactor me */
1358 1114  /*
1359 1115   * Handle the SADB_GETSPI message.  Create a larval SA.
1360 1116   */
1361 1117  static void
1362 1118  esp_getspi(mblk_t *mp, keysock_in_t *ksi, ipsecesp_stack_t *espstack)
1363 1119  {
1364 1120          ipsa_t *newbie, *target;
1365 1121          isaf_t *outbound, *inbound;
1366 1122          int rc, diagnostic;
↓ open down ↓ 437 lines elided ↑ open up ↑
1804 1560          IP_ESP_BUMP_STAT(ipss, in_discards);
1805 1561          ip_drop_packet(mp, B_TRUE, ira->ira_ill,
1806 1562              DROPPER(ipss, ipds_esp_bad_auth),
1807 1563              &espstack->esp_dropper);
1808 1564  }
1809 1565  
1810 1566  
1811 1567  /*
1812 1568   * Invoked for outbound packets after ESP processing. If the packet
1813 1569   * also requires AH, performs the AH SA selection and AH processing.
1814      - * Returns B_TRUE if the AH processing was not needed or if it was
1815      - * performed successfully. Returns B_FALSE and consumes the passed mblk
1816      - * if AH processing was required but could not be performed.
1817 1570   *
1818      - * Returns data_mp unless data_mp was consumed/queued.
     1571 + * Returns data_mp (possibly with AH added) unless data_mp was consumed
     1572 + * due to an error, or queued due to async. crypto or an ACQUIRE trigger.
1819 1573   */
1820 1574  static mblk_t *
1821 1575  esp_do_outbound_ah(mblk_t *data_mp, ip_xmit_attr_t *ixa)
1822 1576  {
1823 1577          ipsec_action_t *ap;
1824 1578  
1825 1579          ap = ixa->ixa_ipsec_action;
1826 1580          if (ap == NULL) {
1827 1581                  ipsec_policy_t *pp = ixa->ixa_ipsec_policy;
1828 1582                  ap = pp->ipsp_act;
↓ open down ↓ 2368 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX