3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <sys/param.h>
26 #include <sys/types.h>
27 #include <sys/stream.h>
28 #include <sys/strsubr.h>
29 #include <sys/strsun.h>
30 #include <sys/stropts.h>
31 #include <sys/zone.h>
32 #include <sys/vnode.h>
33 #include <sys/sysmacros.h>
34 #define _SUN_TPI_VERSION 2
35 #include <sys/tihdr.h>
36 #include <sys/ddi.h>
37 #include <sys/sunddi.h>
38 #include <sys/mkdev.h>
39 #include <sys/debug.h>
40 #include <sys/kmem.h>
41 #include <sys/cmn_err.h>
42 #include <sys/suntpi.h>
2251 SPD_ATTR_ENCR_INCRBITS
2252 };
2253
2254 #define ATTRPERALG 6 /* fixed attributes per algs */
2255
2256 void
2257 spdsock_alglist(queue_t *q, mblk_t *mp)
2258 {
2259 uint_t algtype;
2260 uint_t algidx;
2261 uint_t algcount;
2262 uint_t size;
2263 mblk_t *m;
2264 uint8_t *cur;
2265 spd_msg_t *msg;
2266 struct spd_ext_actions *act;
2267 struct spd_attribute *attr;
2268 spdsock_t *ss = (spdsock_t *)q->q_ptr;
2269 ipsec_stack_t *ipss = ss->spdsock_spds->spds_netstack->netstack_ipsec;
2270
2271 mutex_enter(&ipss->ipsec_alg_lock);
2272 /*
2273 * The SPD client expects to receive separate entries for
2274 * AH authentication and ESP authentication supported algorithms.
2275 *
2276 * Don't return the "any" algorithms, if defined, as no
2277 * kernel policies can be set for these algorithms.
2278 */
2279 algcount = 2 * ipss->ipsec_nalgs[IPSEC_ALG_AUTH] +
2280 ipss->ipsec_nalgs[IPSEC_ALG_ENCR];
2281
2282 if (ipss->ipsec_alglists[IPSEC_ALG_AUTH][SADB_AALG_NONE] != NULL)
2283 algcount--;
2284 if (ipss->ipsec_alglists[IPSEC_ALG_ENCR][SADB_EALG_NONE] != NULL)
2285 algcount--;
2286
2287 /*
2288 * For each algorithm, we encode:
2289 * ALG / MINBITS / MAXBITS / DEFBITS / INCRBITS / {END, NEXT}
2290 */
2291
2292 size = sizeof (spd_msg_t) + sizeof (struct spd_ext_actions) +
2293 ATTRPERALG * sizeof (struct spd_attribute) * algcount;
2294
2295 ASSERT(ALIGNED64(size));
2296
2297 m = allocb(size, BPRI_HI);
2298 if (m == NULL) {
2299 mutex_exit(&ipss->ipsec_alg_lock);
2300 spdsock_error(q, mp, ENOMEM, 0);
2301 return;
2302 }
2303
2304 m->b_wptr = m->b_rptr + size;
2305 cur = m->b_rptr;
2306
2307 msg = (spd_msg_t *)cur;
2308 bcopy(mp->b_rptr, cur, sizeof (*msg));
2309
2310 msg->spd_msg_len = SPD_8TO64(size);
2311 msg->spd_msg_errno = 0;
2312 msg->spd_msg_diagnostic = 0;
2313
2314 cur += sizeof (*msg);
2315
2316 act = (struct spd_ext_actions *)cur;
2317 cur += sizeof (*act);
2318
2319 act->spd_actions_len = SPD_8TO64(size - sizeof (spd_msg_t));
2350 ipss->ipsec_alglists[algtype][algid];
2351 uint_t minbits = alg->alg_minbits;
2352 uint_t maxbits = alg->alg_maxbits;
2353 uint_t defbits = alg->alg_default_bits;
2354 uint_t incr = alg->alg_increment;
2355
2356 if (algtype == IPSEC_ALG_AUTH) {
2357 if (algid == SADB_AALG_NONE)
2358 continue;
2359 EMITALGATTRS(SPDSOCK_AH_AUTH);
2360 EMITALGATTRS(SPDSOCK_ESP_AUTH);
2361 } else {
2362 if (algid == SADB_EALG_NONE)
2363 continue;
2364 ASSERT(algtype == IPSEC_ALG_ENCR);
2365 EMITALGATTRS(SPDSOCK_ESP_ENCR);
2366 }
2367 }
2368 }
2369
2370 mutex_exit(&ipss->ipsec_alg_lock);
2371
2372 #undef EMITALGATTRS
2373 #undef EMIT
2374 #undef ATTRPERALG
2375
2376 attr--;
2377 attr->spd_attr_tag = SPD_ATTR_END;
2378
2379 freemsg(mp);
2380 qreply(q, m);
2381 }
2382
2383 /*
2384 * Process a SPD_DUMPALGS request.
2385 */
2386
2387 #define ATTRPERALG 9 /* fixed attributes per algs */
2388
2389 void
2390 spdsock_dumpalgs(queue_t *q, mblk_t *mp)
2391 {
2392 uint_t algtype;
2393 uint_t algidx;
2394 uint_t size;
2395 mblk_t *m;
2396 uint8_t *cur;
2397 spd_msg_t *msg;
2398 struct spd_ext_actions *act;
2399 struct spd_attribute *attr;
2400 ipsec_alginfo_t *alg;
2401 uint_t algid;
2402 uint_t i;
2403 uint_t alg_size;
2404 spdsock_t *ss = (spdsock_t *)q->q_ptr;
2405 ipsec_stack_t *ipss = ss->spdsock_spds->spds_netstack->netstack_ipsec;
2406
2407 mutex_enter(&ipss->ipsec_alg_lock);
2408
2409 /*
2410 * For each algorithm, we encode:
2411 * ALG / MINBITS / MAXBITS / DEFBITS / INCRBITS / {END, NEXT}
2412 *
2413 * ALG_ID / ALG_PROTO / ALG_INCRBITS / ALG_NKEYSIZES / ALG_KEYSIZE*
2414 * ALG_NBLOCKSIZES / ALG_BLOCKSIZE* / ALG_NPARAMS / ALG_PARAMS* /
2415 * ALG_MECHNAME / ALG_FLAGS / {END, NEXT}
2416 */
2417
2418 /*
2419 * Compute the size of the SPD message.
2420 */
2421 size = sizeof (spd_msg_t) + sizeof (struct spd_ext_actions);
2422
2423 for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
2424 for (algidx = 0; algidx < ipss->ipsec_nalgs[algtype];
2425 algidx++) {
2426 algid = ipss->ipsec_sortlist[algtype][algidx];
2427 alg = ipss->ipsec_alglists[algtype][algid];
2428 alg_size = sizeof (struct spd_attribute) *
2429 (ATTRPERALG + alg->alg_nkey_sizes +
2430 alg->alg_nblock_sizes + alg->alg_nparams) +
2431 CRYPTO_MAX_MECH_NAME;
2432 size += alg_size;
2433 }
2434 }
2435
2436 ASSERT(ALIGNED64(size));
2437
2438 m = allocb(size, BPRI_HI);
2439 if (m == NULL) {
2440 mutex_exit(&ipss->ipsec_alg_lock);
2441 spdsock_error(q, mp, ENOMEM, 0);
2442 return;
2443 }
2444
2445 m->b_wptr = m->b_rptr + size;
2446 cur = m->b_rptr;
2447
2448 msg = (spd_msg_t *)cur;
2449 bcopy(mp->b_rptr, cur, sizeof (*msg));
2450
2451 msg->spd_msg_len = SPD_8TO64(size);
2452 msg->spd_msg_errno = 0;
2453 msg->spd_msg_type = SPD_ALGLIST;
2454
2455 msg->spd_msg_diagnostic = 0;
2456
2457 cur += sizeof (*msg);
2458
2459 act = (struct spd_ext_actions *)cur;
2460 cur += sizeof (*act);
2461
2462 act->spd_actions_len = SPD_8TO64(size - sizeof (spd_msg_t));
2463 act->spd_actions_exttype = SPD_EXT_ACTION;
2464 act->spd_actions_count = ipss->ipsec_nalgs[IPSEC_ALG_AUTH] +
2465 ipss->ipsec_nalgs[IPSEC_ALG_ENCR];
2466 act->spd_actions_reserved = 0;
2467
2468 /*
2469 * If there aren't any algorithms registered, return an empty message.
2470 * spdsock_get_ext() knows how to deal with this.
2471 */
2472 if (act->spd_actions_count == 0) {
2473 act->spd_actions_len = 0;
2474 mutex_exit(&ipss->ipsec_alg_lock);
2475 goto error;
2476 }
2477
2478 attr = (struct spd_attribute *)cur;
2479
2480 #define EMIT(tag, value) { \
2481 attr->spd_attr_tag = (tag); \
2482 attr->spd_attr_value = (value); \
2483 attr++; \
2484 }
2485
2486 for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
2487 for (algidx = 0; algidx < ipss->ipsec_nalgs[algtype];
2488 algidx++) {
2489
2490 algid = ipss->ipsec_sortlist[algtype][algidx];
2491 alg = ipss->ipsec_alglists[algtype][algid];
2492
2493 /*
2494 * If you change the number of EMIT's here, change
2506 for (i = 0; i < alg->alg_nblock_sizes; i++)
2507 EMIT(SPD_ATTR_ALG_BLOCKSIZE,
2508 alg->alg_block_sizes[i]);
2509
2510 EMIT(SPD_ATTR_ALG_NPARAMS, alg->alg_nparams);
2511 for (i = 0; i < alg->alg_nparams; i++)
2512 EMIT(SPD_ATTR_ALG_PARAMS,
2513 alg->alg_params[i]);
2514
2515 EMIT(SPD_ATTR_ALG_FLAGS, alg->alg_flags);
2516
2517 EMIT(SPD_ATTR_ALG_MECHNAME, CRYPTO_MAX_MECH_NAME);
2518 bcopy(alg->alg_mech_name, attr, CRYPTO_MAX_MECH_NAME);
2519 attr = (struct spd_attribute *)((char *)attr +
2520 CRYPTO_MAX_MECH_NAME);
2521
2522 EMIT(SPD_ATTR_NEXT, 0);
2523 }
2524 }
2525
2526 mutex_exit(&ipss->ipsec_alg_lock);
2527
2528 #undef EMITALGATTRS
2529 #undef EMIT
2530 #undef ATTRPERALG
2531
2532 attr--;
2533 attr->spd_attr_tag = SPD_ATTR_END;
2534
2535 error:
2536 freemsg(mp);
2537 qreply(q, m);
2538 }
2539
2540 /*
2541 * Do the actual work of processing an SPD_UPDATEALGS request. Can
2542 * be invoked either once IPsec is loaded on a cached request, or
2543 * when a request is received while IPsec is loaded.
2544 */
2545 static int
2546 spdsock_do_updatealg(spd_ext_t *extv[], spd_stack_t *spds)
3667 if (alg->alg_id == SADB_EALG_NULL) {
3668 alg->alg_mech_type = CRYPTO_MECHANISM_INVALID;
3669 alg->alg_flags |= ALG_FLAG_VALID;
3670 continue;
3671 }
3672
3673 for (mech_idx = 0; mech_idx < mech_count; mech_idx++) {
3674 if (strncmp(alg->alg_mech_name, mechs[mech_idx],
3675 CRYPTO_MAX_MECH_NAME) == 0) {
3676 mt = crypto_mech2id(alg->alg_mech_name);
3677 ASSERT(mt != CRYPTO_MECHANISM_INVALID);
3678 algflags = ALG_FLAG_VALID;
3679 break;
3680 }
3681 }
3682 alg->alg_mech_type = mt;
3683 alg->alg_flags |= algflags;
3684 }
3685 }
3686
3687 mutex_enter(&ipss->ipsec_alg_lock);
3688
3689 /*
3690 * For each algorithm currently defined, check if it is
3691 * present in the new tables created from the SPD_UPDATEALGS
3692 * message received from user-space.
3693 * Delete the algorithm entries that are currently defined
3694 * but not part of the new tables.
3695 */
3696 for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
3697 nalgs = ipss->ipsec_nalgs[algtype];
3698 for (algidx = 0; algidx < nalgs; algidx++) {
3699 algid = ipss->ipsec_sortlist[algtype][algidx];
3700 if (spds->spds_algs[algtype][algid] == NULL)
3701 ipsec_alg_unreg(algtype, algid, ns);
3702 }
3703 }
3704
3705 /*
3706 * For each algorithm we just received, check if it is
3707 * present in the currently defined tables. If it is, swap
3723 */
3724 ipsec_alg_reg(algtype, alg, ns);
3725 } else {
3726 /*
3727 * Algorithm is already in the table. Swap
3728 * the existing entry with the new one.
3729 */
3730 ipsec_alg_fix_min_max(alg, algtype, ns);
3731 ipss->ipsec_alglists[algtype][algid] = alg;
3732 ipsec_alg_free(oalg);
3733 }
3734 spds->spds_algs[algtype][algid] = NULL;
3735 }
3736 }
3737
3738 for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
3739 ipss->ipsec_algs_exec_mode[algtype] =
3740 spds->spds_algs_exec_mode[algtype];
3741 }
3742
3743 mutex_exit(&ipss->ipsec_alg_lock);
3744
3745 crypto_free_mech_list(mechs, mech_count);
3746
3747 ipsecah_algs_changed(ns);
3748 ipsecesp_algs_changed(ns);
3749 }
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 #include <sys/param.h>
27 #include <sys/types.h>
28 #include <sys/stream.h>
29 #include <sys/strsubr.h>
30 #include <sys/strsun.h>
31 #include <sys/stropts.h>
32 #include <sys/zone.h>
33 #include <sys/vnode.h>
34 #include <sys/sysmacros.h>
35 #define _SUN_TPI_VERSION 2
36 #include <sys/tihdr.h>
37 #include <sys/ddi.h>
38 #include <sys/sunddi.h>
39 #include <sys/mkdev.h>
40 #include <sys/debug.h>
41 #include <sys/kmem.h>
42 #include <sys/cmn_err.h>
43 #include <sys/suntpi.h>
2252 SPD_ATTR_ENCR_INCRBITS
2253 };
2254
2255 #define ATTRPERALG 6 /* fixed attributes per algs */
2256
2257 void
2258 spdsock_alglist(queue_t *q, mblk_t *mp)
2259 {
2260 uint_t algtype;
2261 uint_t algidx;
2262 uint_t algcount;
2263 uint_t size;
2264 mblk_t *m;
2265 uint8_t *cur;
2266 spd_msg_t *msg;
2267 struct spd_ext_actions *act;
2268 struct spd_attribute *attr;
2269 spdsock_t *ss = (spdsock_t *)q->q_ptr;
2270 ipsec_stack_t *ipss = ss->spdsock_spds->spds_netstack->netstack_ipsec;
2271
2272 rw_enter(&ipss->ipsec_alg_lock, RW_READER);
2273 /*
2274 * The SPD client expects to receive separate entries for
2275 * AH authentication and ESP authentication supported algorithms.
2276 *
2277 * Don't return the "any" algorithms, if defined, as no
2278 * kernel policies can be set for these algorithms.
2279 */
2280 algcount = 2 * ipss->ipsec_nalgs[IPSEC_ALG_AUTH] +
2281 ipss->ipsec_nalgs[IPSEC_ALG_ENCR];
2282
2283 if (ipss->ipsec_alglists[IPSEC_ALG_AUTH][SADB_AALG_NONE] != NULL)
2284 algcount--;
2285 if (ipss->ipsec_alglists[IPSEC_ALG_ENCR][SADB_EALG_NONE] != NULL)
2286 algcount--;
2287
2288 /*
2289 * For each algorithm, we encode:
2290 * ALG / MINBITS / MAXBITS / DEFBITS / INCRBITS / {END, NEXT}
2291 */
2292
2293 size = sizeof (spd_msg_t) + sizeof (struct spd_ext_actions) +
2294 ATTRPERALG * sizeof (struct spd_attribute) * algcount;
2295
2296 ASSERT(ALIGNED64(size));
2297
2298 m = allocb(size, BPRI_HI);
2299 if (m == NULL) {
2300 rw_exit(&ipss->ipsec_alg_lock);
2301 spdsock_error(q, mp, ENOMEM, 0);
2302 return;
2303 }
2304
2305 m->b_wptr = m->b_rptr + size;
2306 cur = m->b_rptr;
2307
2308 msg = (spd_msg_t *)cur;
2309 bcopy(mp->b_rptr, cur, sizeof (*msg));
2310
2311 msg->spd_msg_len = SPD_8TO64(size);
2312 msg->spd_msg_errno = 0;
2313 msg->spd_msg_diagnostic = 0;
2314
2315 cur += sizeof (*msg);
2316
2317 act = (struct spd_ext_actions *)cur;
2318 cur += sizeof (*act);
2319
2320 act->spd_actions_len = SPD_8TO64(size - sizeof (spd_msg_t));
2351 ipss->ipsec_alglists[algtype][algid];
2352 uint_t minbits = alg->alg_minbits;
2353 uint_t maxbits = alg->alg_maxbits;
2354 uint_t defbits = alg->alg_default_bits;
2355 uint_t incr = alg->alg_increment;
2356
2357 if (algtype == IPSEC_ALG_AUTH) {
2358 if (algid == SADB_AALG_NONE)
2359 continue;
2360 EMITALGATTRS(SPDSOCK_AH_AUTH);
2361 EMITALGATTRS(SPDSOCK_ESP_AUTH);
2362 } else {
2363 if (algid == SADB_EALG_NONE)
2364 continue;
2365 ASSERT(algtype == IPSEC_ALG_ENCR);
2366 EMITALGATTRS(SPDSOCK_ESP_ENCR);
2367 }
2368 }
2369 }
2370
2371 rw_exit(&ipss->ipsec_alg_lock);
2372
2373 #undef EMITALGATTRS
2374 #undef EMIT
2375 #undef ATTRPERALG
2376
2377 attr--;
2378 attr->spd_attr_tag = SPD_ATTR_END;
2379
2380 freemsg(mp);
2381 qreply(q, m);
2382 }
2383
2384 /*
2385 * Process a SPD_DUMPALGS request.
2386 */
2387
2388 #define ATTRPERALG 9 /* fixed attributes per algs */
2389
2390 void
2391 spdsock_dumpalgs(queue_t *q, mblk_t *mp)
2392 {
2393 uint_t algtype;
2394 uint_t algidx;
2395 uint_t size;
2396 mblk_t *m;
2397 uint8_t *cur;
2398 spd_msg_t *msg;
2399 struct spd_ext_actions *act;
2400 struct spd_attribute *attr;
2401 ipsec_alginfo_t *alg;
2402 uint_t algid;
2403 uint_t i;
2404 uint_t alg_size;
2405 spdsock_t *ss = (spdsock_t *)q->q_ptr;
2406 ipsec_stack_t *ipss = ss->spdsock_spds->spds_netstack->netstack_ipsec;
2407
2408 rw_enter(&ipss->ipsec_alg_lock, RW_READER);
2409
2410 /*
2411 * For each algorithm, we encode:
2412 * ALG / MINBITS / MAXBITS / DEFBITS / INCRBITS / {END, NEXT}
2413 *
2414 * ALG_ID / ALG_PROTO / ALG_INCRBITS / ALG_NKEYSIZES / ALG_KEYSIZE*
2415 * ALG_NBLOCKSIZES / ALG_BLOCKSIZE* / ALG_NPARAMS / ALG_PARAMS* /
2416 * ALG_MECHNAME / ALG_FLAGS / {END, NEXT}
2417 */
2418
2419 /*
2420 * Compute the size of the SPD message.
2421 */
2422 size = sizeof (spd_msg_t) + sizeof (struct spd_ext_actions);
2423
2424 for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
2425 for (algidx = 0; algidx < ipss->ipsec_nalgs[algtype];
2426 algidx++) {
2427 algid = ipss->ipsec_sortlist[algtype][algidx];
2428 alg = ipss->ipsec_alglists[algtype][algid];
2429 alg_size = sizeof (struct spd_attribute) *
2430 (ATTRPERALG + alg->alg_nkey_sizes +
2431 alg->alg_nblock_sizes + alg->alg_nparams) +
2432 CRYPTO_MAX_MECH_NAME;
2433 size += alg_size;
2434 }
2435 }
2436
2437 ASSERT(ALIGNED64(size));
2438
2439 m = allocb(size, BPRI_HI);
2440 if (m == NULL) {
2441 rw_exit(&ipss->ipsec_alg_lock);
2442 spdsock_error(q, mp, ENOMEM, 0);
2443 return;
2444 }
2445
2446 m->b_wptr = m->b_rptr + size;
2447 cur = m->b_rptr;
2448
2449 msg = (spd_msg_t *)cur;
2450 bcopy(mp->b_rptr, cur, sizeof (*msg));
2451
2452 msg->spd_msg_len = SPD_8TO64(size);
2453 msg->spd_msg_errno = 0;
2454 msg->spd_msg_type = SPD_ALGLIST;
2455
2456 msg->spd_msg_diagnostic = 0;
2457
2458 cur += sizeof (*msg);
2459
2460 act = (struct spd_ext_actions *)cur;
2461 cur += sizeof (*act);
2462
2463 act->spd_actions_len = SPD_8TO64(size - sizeof (spd_msg_t));
2464 act->spd_actions_exttype = SPD_EXT_ACTION;
2465 act->spd_actions_count = ipss->ipsec_nalgs[IPSEC_ALG_AUTH] +
2466 ipss->ipsec_nalgs[IPSEC_ALG_ENCR];
2467 act->spd_actions_reserved = 0;
2468
2469 /*
2470 * If there aren't any algorithms registered, return an empty message.
2471 * spdsock_get_ext() knows how to deal with this.
2472 */
2473 if (act->spd_actions_count == 0) {
2474 act->spd_actions_len = 0;
2475 rw_exit(&ipss->ipsec_alg_lock);
2476 goto error;
2477 }
2478
2479 attr = (struct spd_attribute *)cur;
2480
2481 #define EMIT(tag, value) { \
2482 attr->spd_attr_tag = (tag); \
2483 attr->spd_attr_value = (value); \
2484 attr++; \
2485 }
2486
2487 for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
2488 for (algidx = 0; algidx < ipss->ipsec_nalgs[algtype];
2489 algidx++) {
2490
2491 algid = ipss->ipsec_sortlist[algtype][algidx];
2492 alg = ipss->ipsec_alglists[algtype][algid];
2493
2494 /*
2495 * If you change the number of EMIT's here, change
2507 for (i = 0; i < alg->alg_nblock_sizes; i++)
2508 EMIT(SPD_ATTR_ALG_BLOCKSIZE,
2509 alg->alg_block_sizes[i]);
2510
2511 EMIT(SPD_ATTR_ALG_NPARAMS, alg->alg_nparams);
2512 for (i = 0; i < alg->alg_nparams; i++)
2513 EMIT(SPD_ATTR_ALG_PARAMS,
2514 alg->alg_params[i]);
2515
2516 EMIT(SPD_ATTR_ALG_FLAGS, alg->alg_flags);
2517
2518 EMIT(SPD_ATTR_ALG_MECHNAME, CRYPTO_MAX_MECH_NAME);
2519 bcopy(alg->alg_mech_name, attr, CRYPTO_MAX_MECH_NAME);
2520 attr = (struct spd_attribute *)((char *)attr +
2521 CRYPTO_MAX_MECH_NAME);
2522
2523 EMIT(SPD_ATTR_NEXT, 0);
2524 }
2525 }
2526
2527 rw_exit(&ipss->ipsec_alg_lock);
2528
2529 #undef EMITALGATTRS
2530 #undef EMIT
2531 #undef ATTRPERALG
2532
2533 attr--;
2534 attr->spd_attr_tag = SPD_ATTR_END;
2535
2536 error:
2537 freemsg(mp);
2538 qreply(q, m);
2539 }
2540
2541 /*
2542 * Do the actual work of processing an SPD_UPDATEALGS request. Can
2543 * be invoked either once IPsec is loaded on a cached request, or
2544 * when a request is received while IPsec is loaded.
2545 */
2546 static int
2547 spdsock_do_updatealg(spd_ext_t *extv[], spd_stack_t *spds)
3668 if (alg->alg_id == SADB_EALG_NULL) {
3669 alg->alg_mech_type = CRYPTO_MECHANISM_INVALID;
3670 alg->alg_flags |= ALG_FLAG_VALID;
3671 continue;
3672 }
3673
3674 for (mech_idx = 0; mech_idx < mech_count; mech_idx++) {
3675 if (strncmp(alg->alg_mech_name, mechs[mech_idx],
3676 CRYPTO_MAX_MECH_NAME) == 0) {
3677 mt = crypto_mech2id(alg->alg_mech_name);
3678 ASSERT(mt != CRYPTO_MECHANISM_INVALID);
3679 algflags = ALG_FLAG_VALID;
3680 break;
3681 }
3682 }
3683 alg->alg_mech_type = mt;
3684 alg->alg_flags |= algflags;
3685 }
3686 }
3687
3688 rw_enter(&ipss->ipsec_alg_lock, RW_WRITER);
3689
3690 /*
3691 * For each algorithm currently defined, check if it is
3692 * present in the new tables created from the SPD_UPDATEALGS
3693 * message received from user-space.
3694 * Delete the algorithm entries that are currently defined
3695 * but not part of the new tables.
3696 */
3697 for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
3698 nalgs = ipss->ipsec_nalgs[algtype];
3699 for (algidx = 0; algidx < nalgs; algidx++) {
3700 algid = ipss->ipsec_sortlist[algtype][algidx];
3701 if (spds->spds_algs[algtype][algid] == NULL)
3702 ipsec_alg_unreg(algtype, algid, ns);
3703 }
3704 }
3705
3706 /*
3707 * For each algorithm we just received, check if it is
3708 * present in the currently defined tables. If it is, swap
3724 */
3725 ipsec_alg_reg(algtype, alg, ns);
3726 } else {
3727 /*
3728 * Algorithm is already in the table. Swap
3729 * the existing entry with the new one.
3730 */
3731 ipsec_alg_fix_min_max(alg, algtype, ns);
3732 ipss->ipsec_alglists[algtype][algid] = alg;
3733 ipsec_alg_free(oalg);
3734 }
3735 spds->spds_algs[algtype][algid] = NULL;
3736 }
3737 }
3738
3739 for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype++) {
3740 ipss->ipsec_algs_exec_mode[algtype] =
3741 spds->spds_algs_exec_mode[algtype];
3742 }
3743
3744 rw_exit(&ipss->ipsec_alg_lock);
3745
3746 crypto_free_mech_list(mechs, mech_count);
3747
3748 ipsecah_algs_changed(ns);
3749 ipsecesp_algs_changed(ns);
3750 }
|