Mercurial > illumos > illumos-gate
changeset 3708:75f7822ae9dc
PSARC/2007/093 Crypto Context sharing between providers
6494834 support check for threshold when using hardware providers even for multi-part requests
line wrap: on
line diff
--- a/usr/src/cmd/mdb/common/modules/crypto/impl.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/cmd/mdb/common/modules/crypto/impl.c Fri Feb 23 11:55:36 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -162,17 +161,18 @@ (uintptr_t)mech_pointer, DCMD_ADDRSPEC, 0, NULL); } mdb_dec_indent(4); - mdb_printf("pd_map_mechnums:\n"); + mdb_printf("pd_mech_indx:\n"); mdb_inc_indent(8); for (i = 0; i < KCF_OPS_CLASSSIZE; i++) { for (j = 0; j < KCF_MAXMECHTAB; j++) { - mdb_printf("%llu ", - desc.pd_map_mechnums[i][j]); + if (desc.pd_mech_indx[i][j] == KCF_INVALID_INDX) + mdb_printf("N "); + else + mdb_printf("%u ", desc.pd_mech_indx[i][j]); } mdb_printf("\n"); } mdb_dec_indent(8); - mdb_printf("pd_stats:\t\t%p\n", desc.pd_stats); mdb_printf("pd_ks_data.ps_ops_total:\n", desc.pd_ks_data.ps_ops_total); pr_kstat_named(&desc.pd_ks_data.ps_ops_total); mdb_printf("pd_ks_data.ps_ops_passed:\n", @@ -216,8 +216,13 @@ mdb_printf("pd_resume_cv:\t\t%hd\n", desc.pd_resume_cv._opaque); mdb_printf("pd_remove_cv:\t\t%hd\n", desc.pd_remove_cv._opaque); - mdb_printf("pd_restricted:\t\t%s\n", - desc.pd_restricted == B_FALSE ? "B_FALSE" : "B_TRUE"); + mdb_printf("pd_flags:\t\t%s %s %s\n", + (desc.pd_flags & CRYPTO_HIDE_PROVIDER) ? + "CRYPTO_HIDE_PROVIDER" : " ", + (desc.pd_flags & KCF_LPROV_MEMBER) ? + "KCF_LPROV_MEMBER" : " ", + (desc.pd_flags & KCF_PROV_RESTRICTED) ? + "KCF_PROV_RESTRICTED" : " "); mdb_printf("pd_provider_list:\t%p\n", desc.pd_provider_list); return (DCMD_OK); }
--- a/usr/src/cmd/mdb/common/modules/crypto/spi.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/cmd/mdb/common/modules/crypto/spi.c Fri Feb 23 11:55:36 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -206,7 +205,7 @@ mdb_printf("cm_mech_number\t%lld\n", minfo.cm_mech_number); mdb_printf("cm_func_group_mask\t0x%x:\t<%b>\n", minfo.cm_func_group_mask, minfo.cm_func_group_mask, mech_bits); - if (minfo.cm_keysize_unit != CRYPTO_KEYSIZE_UNIT_IN_BITS) + if (minfo.cm_keysize_unit & CRYPTO_KEYSIZE_UNIT_IN_BYTES) unit = "bytes"; mdb_printf("cm_min_key_length\t%lu %s\n", minfo.cm_min_key_length, unit);
--- a/usr/src/common/crypto/arcfour/arcfour.h Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/common/crypto/arcfour/arcfour.h Fri Feb 23 11:55:36 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -34,6 +33,7 @@ #endif #include <sys/types.h> +#include <sys/crypto/common.h> #define ARCFOUR_MIN_KEY_BYTES 1 @@ -46,13 +46,7 @@ #define ARCFOUR_MIN_KEY_BITS (ARCFOUR_MIN_KEY_BYTES << 3) #define ARCFOUR_MAX_KEY_BITS (ARCFOUR_MAX_KEY_BYTES << 3) -typedef struct { - uchar_t i, j; -#ifdef sun4v - unsigned long long pad; -#endif /* sun4v */ - uchar_t arr[256]; -} ARCFour_key; +typedef arcfour_state_t ARCFour_key; void arcfour_key_init(ARCFour_key *key, uchar_t *keyval, int keyvallen); void arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len);
--- a/usr/src/common/crypto/arcfour/sun4u/arcfour_crypt_asm.s Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/common/crypto/arcfour/sun4u/arcfour_crypt_asm.s Fri Feb 23 11:55:36 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -61,14 +60,14 @@ save %sp,-144,%sp srl %i1, 3, %l7 - ldub [%i0], %g1 + ldub [%i0+256], %g1 orcc %l7, %g0, %g0 - ldub [%i0+1], %g2 + ldub [%i0+257], %g2 add %g1, 1, %o1 bz %icc, .Loop2 - add %i0, 2, %i5 + add %i0, 0, %i5 add %o1, 1, %g1 and %o1, 255, %o1 @@ -409,7 +408,7 @@ sub %g1, 2, %g1 and %g1, 255, %g1 - stb %g1, [%i0] + stb %g1, [%i0 + 256] or %o0, %g5, %o0 xor %o0, %o7, %o7 @@ -418,7 +417,7 @@ add %i3, 8, %i3 bnz %icc, .Loop2_1 - stb %g2, [%i0 + 1] + stb %g2, [%i0 + 257] ret restore %g0,%g0,%g0 @@ -460,9 +459,9 @@ bnz %icc, .Loop2_1 stb %o0, [%i3 - 1] - stb %g1, [%i0] + stb %g1, [%i0 + 256] - stb %g2, [%i0 + 1] + stb %g2, [%i0 + 257] ret restore %g0,%g0,%g0
--- a/usr/src/uts/common/crypto/api/kcf_cipher.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/api/kcf_cipher.c Fri Feb 23 11:55:36 2007 -0800 @@ -157,23 +157,62 @@ &lmech, key, tmpl, KCF_SWFP_RHNDL(crq)); } KCF_PROV_INCRSTATS(pd, error); + + goto done; + } + + /* Check if context sharing is possible */ + if (pd->pd_prov_type == CRYPTO_HW_PROVIDER && + key->ck_format == CRYPTO_KEY_RAW && + KCF_CAN_SHARE_OPSTATE(pd, mech->cm_type)) { + kcf_context_t *tctxp = (kcf_context_t *)ctx; + kcf_provider_desc_t *tpd = NULL; + crypto_mech_info_t *sinfo; + + if ((kcf_get_sw_prov(mech->cm_type, &tpd, &tctxp->kc_mech, + B_FALSE) == CRYPTO_SUCCESS)) { + int tlen; + + sinfo = &(KCF_TO_PROV_MECHINFO(tpd, mech->cm_type)); + /* + * key->ck_length from the consumer is always in bits. + * We convert it to be in the same unit registered by + * the provider in order to do a comparison. + */ + if (sinfo->cm_mech_flags & CRYPTO_KEYSIZE_UNIT_IN_BYTES) + tlen = key->ck_length >> 3; + else + tlen = key->ck_length; + /* + * Check if the software provider can support context + * sharing and support this key length. + */ + if ((sinfo->cm_mech_flags & CRYPTO_CAN_SHARE_OPSTATE) && + (tlen >= sinfo->cm_min_key_length) && + (tlen <= sinfo->cm_max_key_length)) { + ctx->cc_flags = CRYPTO_INIT_OPSTATE; + tctxp->kc_sw_prov_desc = tpd; + } else + KCF_PROV_REFRELE(tpd); + } + } + + if (func == CRYPTO_FG_ENCRYPT) { + KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT, sid, + mech, key, NULL, NULL, tmpl); } else { - if (func == CRYPTO_FG_ENCRYPT) { - KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT, sid, - mech, key, NULL, NULL, tmpl); - } else { - ASSERT(func == CRYPTO_FG_DECRYPT); - KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT, sid, - mech, key, NULL, NULL, tmpl); - } + ASSERT(func == CRYPTO_FG_DECRYPT); + KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_INIT, sid, + mech, key, NULL, NULL, tmpl); + } - error = kcf_submit_request(real_provider, ctx, crq, ¶ms, - B_FALSE); - } + error = kcf_submit_request(real_provider, ctx, crq, ¶ms, + B_FALSE); if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) KCF_PROV_REFRELE(real_provider); +done: if ((error == CRYPTO_SUCCESS) || (error == CRYPTO_QUEUED)) *ctxp = (crypto_context_t)ctx; else { @@ -457,12 +496,22 @@ error = KCF_PROV_ENCRYPT_UPDATE(pd, ctx, plaintext, ciphertext, NULL); KCF_PROV_INCRSTATS(pd, error); - } else { - KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE, - ctx->cc_session, NULL, NULL, plaintext, ciphertext, NULL); - error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); + return (error); } + /* Check if we should use a software provider for small jobs */ + if ((ctx->cc_flags & CRYPTO_USE_OPSTATE) && cr == NULL) { + if (plaintext->cd_length < kcf_ctx->kc_mech->me_threshold && + kcf_ctx->kc_sw_prov_desc != NULL && + KCF_IS_PROV_USABLE(kcf_ctx->kc_sw_prov_desc)) { + pd = kcf_ctx->kc_sw_prov_desc; + } + } + + KCF_WRAP_ENCRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE, + ctx->cc_session, NULL, NULL, plaintext, ciphertext, NULL); + error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); + return (error); } @@ -730,12 +779,22 @@ error = KCF_PROV_DECRYPT_UPDATE(pd, ctx, ciphertext, plaintext, NULL); KCF_PROV_INCRSTATS(pd, error); - } else { - KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE, - ctx->cc_session, NULL, NULL, ciphertext, plaintext, NULL); - error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); + return (error); } + /* Check if we should use a software provider for small jobs */ + if ((ctx->cc_flags & CRYPTO_USE_OPSTATE) && cr == NULL) { + if (ciphertext->cd_length < kcf_ctx->kc_mech->me_threshold && + kcf_ctx->kc_sw_prov_desc != NULL && + KCF_IS_PROV_USABLE(kcf_ctx->kc_sw_prov_desc)) { + pd = kcf_ctx->kc_sw_prov_desc; + } + } + + KCF_WRAP_DECRYPT_OPS_PARAMS(¶ms, KCF_OP_UPDATE, + ctx->cc_session, NULL, NULL, ciphertext, plaintext, NULL); + error = kcf_submit_request(pd, ctx, cr, ¶ms, B_FALSE); + return (error); } @@ -810,7 +869,6 @@ return (CRYPTO_INVALID_CONTEXT); } - /* The fast path for SW providers. */ if (CHECK_FASTPATH(cr, pd)) { error = KCF_PROV_ENCRYPT(pd, ctx, plaintext, @@ -846,7 +904,6 @@ return (CRYPTO_INVALID_CONTEXT); } - /* The fast path for SW providers. */ if (CHECK_FASTPATH(cr, pd)) { error = KCF_PROV_DECRYPT(pd, ctx, ciphertext,
--- a/usr/src/uts/common/crypto/api/kcf_ctxops.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/api/kcf_ctxops.c Fri Feb 23 11:55:36 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -79,12 +78,9 @@ { int error; kcf_mech_entry_t *me; - kcf_prov_mech_desc_t *pm; kcf_provider_desc_t *pd; kcf_ctx_template_t *ctx_tmpl; crypto_mechanism_t prov_mech; - kcf_ops_class_t class; - int index; /* A few args validation */ @@ -94,24 +90,9 @@ if (mech == NULL) return (CRYPTO_MECHANISM_INVALID); - if (kcf_get_mech_entry(mech->cm_type, &me) != KCF_SUCCESS) { - /* error is one of the KCF_INVALID_MECH_XXX's */ - return (CRYPTO_MECHANISM_INVALID); - } - - /* - * Get the software provider for the mech. - * Lock the mech_entry until we grab the 'pd' - */ - mutex_enter(&me->me_mutex); - - if (((pm = me->me_sw_prov) == NULL) || - ((pd = pm->pm_prov_desc) == NULL)) { - mutex_exit(&me->me_mutex); - return (CRYPTO_MECH_NOT_SUPPORTED); - } - KCF_PROV_REFHOLD(pd); - mutex_exit(&me->me_mutex); + error = kcf_get_sw_prov(mech->cm_type, &pd, &me, B_TRUE); + if (error != CRYPTO_SUCCESS) + return (error); if ((ctx_tmpl = (kcf_ctx_template_t *)kmem_alloc( sizeof (kcf_ctx_template_t), kmflag)) == NULL) { @@ -120,9 +101,7 @@ } /* Pass a mechtype that the provider understands */ - class = KCF_MECH2CLASS(mech->cm_type); - index = KCF_MECH2INDEX(mech->cm_type); - prov_mech.cm_type = pd->pd_map_mechnums[class][index]; + prov_mech.cm_type = KCF_TO_PROV_MECHNUM(pd, mech->cm_type); prov_mech.cm_param = mech->cm_param; prov_mech.cm_param_len = mech->cm_param_len;
--- a/usr/src/uts/common/crypto/api/kcf_miscapi.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/api/kcf_miscapi.c Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -616,8 +616,8 @@ crypto_func_group_t fg = pmd->pm_mech_info.cm_func_group_mask; /* min/max key sizes */ - mech_info->mi_keysize_unit = - pmd->pm_mech_info.cm_keysize_unit; + mech_info->mi_keysize_unit = pmd->pm_mech_info.cm_mech_flags & + (CRYPTO_KEYSIZE_UNIT_IN_BITS | CRYPTO_KEYSIZE_UNIT_IN_BYTES); mech_info->mi_min_key_size = (size_t)pmd->pm_mech_info.cm_min_key_length; mech_info->mi_max_key_size =
--- a/usr/src/uts/common/crypto/api/kcf_random.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/api/kcf_random.c Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -200,7 +200,8 @@ { kcf_provider_desc_t *pd = NULL; - if (kcf_get_sw_prov(rngmech_type, &pd, B_FALSE) == CRYPTO_SUCCESS) { + if (kcf_get_sw_prov(rngmech_type, &pd, NULL, B_FALSE) == + CRYPTO_SUCCESS) { (void) KCF_PROV_SEED_RANDOM(pd, pd->pd_sid, buf, len, entropy_est, flags, NULL); KCF_PROV_REFRELE(pd);
--- a/usr/src/uts/common/crypto/core/kcf.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/core/kcf.c Fri Feb 23 11:55:36 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -260,12 +259,9 @@ error = 0; } - pd->pd_restricted = - (rkda->da_u.result.status == ELFSIGN_RESTRICTED); - - if (pd->pd_restricted) { - KCF_FRMWRK_DEBUG(2, - ("provider is restricted\n")); + if (rkda->da_u.result.status == ELFSIGN_RESTRICTED) { + pd->pd_flags |= KCF_PROV_RESTRICTED; + KCF_FRMWRK_DEBUG(2, ("provider is restricted\n")); } if (rkda != kda)
--- a/usr/src/uts/common/crypto/core/kcf_callprov.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/core/kcf_callprov.c Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -183,7 +183,8 @@ ASSERT(provider->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); - if (call_restrict && provider->pd_restricted) { + if (call_restrict && + (provider->pd_flags & KCF_PROV_RESTRICTED)) { p = p->pl_next; continue; } @@ -195,21 +196,11 @@ /* provider does second mech */ if (mech_type_2 != CRYPTO_MECH_INVALID) { - crypto_mech_type_t mech_type; int i; - /* convert from kef to provider's number */ - mech_type = provider->pd_map_mechnums - [KCF_MECH2CLASS(mech_type_2)] - [KCF_MECH2INDEX(mech_type_2)]; - - for (i = 0; i < provider->pd_mech_list_count; - i++) { - if (provider->pd_mechanisms[i] - .cm_mech_number == mech_type) - break; - } - if (i == provider->pd_mech_list_count) { + i = KCF_TO_PROV_MECH_INDX(provider, + mech_type_2); + if (i == KCF_INVALID_INDX) { p = p->pl_next; continue; } @@ -247,7 +238,7 @@ } else { if (!KCF_IS_PROV_USABLE(old) || - (call_restrict && old->pd_restricted)) { + (call_restrict && (old->pd_flags & KCF_PROV_RESTRICTED))) { real_pd = NULL; rv = CRYPTO_DEVICE_ERROR; goto out; @@ -315,7 +306,8 @@ ASSERT(provider->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); - if (call_restrict && provider->pd_restricted) { + if (call_restrict && + (provider->pd_flags & KCF_PROV_RESTRICTED)) { p = p->pl_next; continue; } @@ -357,7 +349,7 @@ } else { if (!KCF_IS_PROV_USABLE(old) || - (call_restrict && old->pd_restricted)) { + (call_restrict && (old->pd_flags & KCF_PROV_RESTRICTED))) { real_pd = NULL; rv = CRYPTO_DEVICE_ERROR; goto out; @@ -468,7 +460,7 @@ */ if ((prov_chain != NULL) && ((data_size == 0) || (me->me_threshold == 0) || - (data_size > me->me_threshold) || + (data_size >= me->me_threshold) || ((mdesc = me->me_sw_prov) == NULL) || (!IS_FG_SUPPORTED(mdesc, fg)) || (!KCF_IS_PROV_USABLE(mdesc->pm_prov_desc)))) { @@ -488,7 +480,8 @@ if (!IS_FG_SUPPORTED(prov_chain, fg) || !KCF_IS_PROV_USABLE(pd) || IS_PROVIDER_TRIED(pd, triedl) || - (call_restrict && pd->pd_restricted)) { + (call_restrict && + (pd->pd_flags & KCF_PROV_RESTRICTED))) { prov_chain = prov_chain->pm_next; continue; } @@ -511,7 +504,7 @@ if (!IS_FG_SUPPORTED(mdesc, fg) || !KCF_IS_PROV_USABLE(pd) || IS_PROVIDER_TRIED(pd, triedl) || - (call_restrict && pd->pd_restricted)) + (call_restrict && (pd->pd_flags & KCF_PROV_RESTRICTED))) pd = NULL; } @@ -574,7 +567,7 @@ */ if ((prov_chain != NULL) && ((data_size == 0) || (me->me_threshold == 0) || - (data_size > me->me_threshold) || + (data_size >= me->me_threshold) || ((mdesc = me->me_sw_prov) == NULL) || (!IS_FG_SUPPORTED(mdesc, fg1)) || (!KCF_IS_PROV_USABLE(mdesc->pm_prov_desc)))) { @@ -593,7 +586,8 @@ if (!IS_FG_SUPPORTED(prov_chain, fg1) || !KCF_IS_PROV_USABLE(pd) || IS_PROVIDER_TRIED(pd, triedl) || - (call_restrict && pd->pd_restricted)) { + (call_restrict && + (pd->pd_flags & KCF_PROV_RESTRICTED))) { prov_chain = prov_chain->pm_next; continue; } @@ -638,7 +632,7 @@ if (!IS_FG_SUPPORTED(mdesc, fg1) || !KCF_IS_PROV_USABLE(pd) || IS_PROVIDER_TRIED(pd, triedl) || - (call_restrict && pd->pd_restricted)) + (call_restrict && (pd->pd_flags & KCF_PROV_RESTRICTED))) pd = NULL; else { /* See if pd can do me2 too */
--- a/usr/src/uts/common/crypto/core/kcf_cryptoadm.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/core/kcf_cryptoadm.c Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -364,7 +364,7 @@ switch (direction) { case CRYPTO_MECH_ADDED: - (void) kcf_add_mech_provider(mi, provider, &pmd); + (void) kcf_add_mech_provider(j, provider, &pmd); break; case CRYPTO_MECH_REMOVED:
--- a/usr/src/uts/common/crypto/core/kcf_mech_tabs.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/core/kcf_mech_tabs.c Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -341,7 +341,7 @@ * kcf_add_mech_provider() * * Arguments: - * . A pointer to the mechanism info + * . An index in to the provider mechanism array * . A pointer to the provider descriptor * . A storage for the kcf_prov_mech_desc_t the entry was added at. * @@ -357,11 +357,12 @@ * KCF_MECH_TAB_FULL otherwise. */ int -kcf_add_mech_provider(crypto_mech_info_t *mech_info, +kcf_add_mech_provider(short mech_indx, kcf_provider_desc_t *prov_desc, kcf_prov_mech_desc_t **pmdpp) { int error; kcf_mech_entry_t *mech_entry; + crypto_mech_info_t *mech_info; crypto_mech_type_t kcf_mech_type, mt; kcf_prov_mech_desc_t *prov_mech, *prov_mech2; crypto_func_group_t simple_fg_mask, dual_fg_mask; @@ -372,6 +373,7 @@ ASSERT(prov_desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); + mech_info = &prov_desc->pd_mechanisms[mech_indx]; /* * Do not use the provider for the mechanism if * policy does not allow it. @@ -434,8 +436,9 @@ prov_mech = kmem_zalloc(sizeof (kcf_prov_mech_desc_t), KM_SLEEP); bcopy(mech_info, &prov_mech->pm_mech_info, sizeof (crypto_mech_info_t)); prov_mech->pm_prov_desc = prov_desc; - prov_desc->pd_map_mechnums[KCF_MECH2CLASS(kcf_mech_type)] - [KCF_MECH2INDEX(kcf_mech_type)] = mech_info->cm_mech_number; + prov_desc->pd_mech_indx[KCF_MECH2CLASS(kcf_mech_type)] + [KCF_MECH2INDEX(kcf_mech_type)] = mech_indx; + KCF_PROV_REFHOLD(prov_desc); KCF_PROV_IREFHOLD(prov_desc);
--- a/usr/src/uts/common/crypto/core/kcf_prov_tabs.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/core/kcf_prov_tabs.c Fri Feb 23 11:55:36 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -290,6 +289,7 @@ kcf_provider_desc_t * kcf_alloc_provider_desc(crypto_provider_info_t *info) { + int i, j; kcf_provider_desc_t *desc; uint_t mech_list_count = info->pi_mech_list_count; crypto_ops_t *src_ops = info->pi_ops_vector; @@ -329,8 +329,12 @@ } desc->pd_mech_list_count = mech_list_count; - desc->pd_mechanisms = kmem_alloc(sizeof (crypto_mech_info_t) * + desc->pd_mechanisms = kmem_zalloc(sizeof (crypto_mech_info_t) * mech_list_count, KM_SLEEP); + for (i = 0; i < KCF_OPS_CLASSSIZE; i++) + for (j = 0; j < KCF_MAXMECHTAB; j++) + desc->pd_mech_indx[i][j] = KCF_INVALID_INDX; + desc->pd_prov_id = KCF_PROVID_INVALID; desc->pd_state = KCF_PROV_ALLOCATED; @@ -756,14 +760,15 @@ * Returns in the location pointed to by pd a pointer to the descriptor * for the software provider for the specified mechanism. * The provider descriptor is returned held and it is the caller's - * responsibility to release it when done. + * responsibility to release it when done. The mechanism entry + * is returned if the optional argument mep is non NULL. * * Returns one of the CRYPTO_ * error codes on failure, and * CRYPTO_SUCCESS on success. */ int kcf_get_sw_prov(crypto_mech_type_t mech_type, kcf_provider_desc_t **pd, - boolean_t log_warn) + kcf_mech_entry_t **mep, boolean_t log_warn) { kcf_mech_entry_t *me; @@ -771,10 +776,14 @@ if (kcf_get_mech_entry(mech_type, &me) != KCF_SUCCESS) return (CRYPTO_MECHANISM_INVALID); - /* get a software provider for this mechanism */ + /* + * Get the software provider for this mechanism. + * Lock the mech_entry until we grab the 'pd'. + */ mutex_enter(&me->me_mutex); - if (me->me_sw_prov == NULL) { + if (me->me_sw_prov == NULL || + (*pd = me->me_sw_prov->pm_prov_desc) == NULL) { /* no SW provider for this mechanism */ if (log_warn) cmn_err(CE_WARN, "no SW provider for \"%s\"\n", @@ -783,10 +792,12 @@ return (CRYPTO_MECH_NOT_SUPPORTED); } - *pd = me->me_sw_prov->pm_prov_desc; KCF_PROV_REFHOLD(*pd); mutex_exit(&me->me_mutex); + if (mep != NULL) + *mep = me; + return (CRYPTO_SUCCESS); }
--- a/usr/src/uts/common/crypto/core/kcf_sched.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/core/kcf_sched.c Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -124,12 +124,16 @@ kcf_ctx->kc_secondctx = NULL; KCF_PROV_REFHOLD(pd); kcf_ctx->kc_prov_desc = pd; + kcf_ctx->kc_sw_prov_desc = NULL; + kcf_ctx->kc_mech = NULL; ctx = &kcf_ctx->kc_glbl_ctx; ctx->cc_provider = pd->pd_prov_handle; ctx->cc_session = sid; ctx->cc_provider_private = NULL; ctx->cc_framework_private = (void *)kcf_ctx; + ctx->cc_flags = 0; + ctx->cc_opstate = NULL; return (ctx); } @@ -825,6 +829,12 @@ /* kcf_ctx->kc_prov_desc has a hold on pd */ KCF_PROV_REFRELE(kcf_ctx->kc_prov_desc); + /* check if this context is shared with a software provider */ + if ((gctx->cc_flags & CRYPTO_INIT_OPSTATE) && + kcf_ctx->kc_sw_prov_desc != NULL) { + KCF_PROV_REFRELE(kcf_ctx->kc_sw_prov_desc); + } + kmem_cache_free(kcf_context_cache, kcf_ctx); }
--- a/usr/src/uts/common/crypto/io/arcfour.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/io/arcfour.c Fri Feb 23 11:55:36 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -70,7 +69,7 @@ CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC, ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS, - CRYPTO_KEYSIZE_UNIT_IN_BITS} + CRYPTO_KEYSIZE_UNIT_IN_BITS | CRYPTO_CAN_SHARE_OPSTATE} }; static void rc4_provider_status(crypto_provider_handle_t, uint_t *); @@ -287,7 +286,10 @@ ASSERT(ctx->cc_provider_private != NULL); - key = ctx->cc_provider_private; + if ((ctx->cc_flags & CRYPTO_USE_OPSTATE) && ctx->cc_opstate != NULL) + key = ctx->cc_opstate; + else + key = ctx->cc_provider_private; /* Simple case: in-line encipherment */ @@ -527,10 +529,10 @@ crypto_data_t *output, crypto_spi_ctx_template_t template, crypto_req_handle_t req) { - crypto_ctx_t ctx; int ret; + bzero(&ctx, sizeof (crypto_ctx_t)); ret = rc4_common_init(&ctx, mechanism, key, template, req); if (ret != CRYPTO_SUCCESS)
--- a/usr/src/uts/common/crypto/io/crypto.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/io/crypto.c Fri Feb 23 11:55:36 2007 -0800 @@ -2236,14 +2236,10 @@ crypto_mechanism_t *umech, crypto_mechanism_t *kmech, int mode, int *error) { crypto_mech_type_t provider_mech_type; - kcf_ops_class_t class; - int index; int rv; /* get the provider's mech number */ - class = KCF_MECH2CLASS(umech->cm_type); - index = KCF_MECH2INDEX(umech->cm_type); - provider_mech_type = pd->pd_map_mechnums[class][index]; + provider_mech_type = KCF_TO_PROV_MECHNUM(pd, umech->cm_type); kmech->cm_param = NULL; kmech->cm_param_len = 0; @@ -2272,14 +2268,10 @@ crypto_mechanism_t *kmech, crypto_mechanism_t *umech, int mode, int *error) { crypto_mech_type_t provider_mech_type; - kcf_ops_class_t class; - int index; int rv; /* get the provider's mech number */ - class = KCF_MECH2CLASS(umech->cm_type); - index = KCF_MECH2INDEX(umech->cm_type); - provider_mech_type = pd->pd_map_mechnums[class][index]; + provider_mech_type = KCF_TO_PROV_MECHNUM(pd, umech->cm_type); kmech->cm_type = provider_mech_type; rv = KCF_PROV_COPYOUT_MECH(pd, kmech, umech, error, mode); @@ -2297,17 +2289,13 @@ crypto_mechanism_t *mech) { crypto_mech_type_t provider_mech_type; - kcf_ops_class_t class; - int index; if (allocated_by_crypto_module) { if (mech->cm_param != NULL) kmem_free(mech->cm_param, mech->cm_param_len); } else { /* get the provider's mech number */ - class = KCF_MECH2CLASS(mech->cm_type); - index = KCF_MECH2INDEX(mech->cm_type); - provider_mech_type = pd->pd_map_mechnums[class][index]; + provider_mech_type = KCF_TO_PROV_MECHNUM(pd, mech->cm_type); if (mech->cm_param != NULL && mech->cm_param_len != 0) { mech->cm_type = provider_mech_type;
--- a/usr/src/uts/common/crypto/io/dprov.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/io/dprov.c Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -465,7 +465,7 @@ CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC, ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS, - CRYPTO_KEYSIZE_UNIT_IN_BITS}, + CRYPTO_KEYSIZE_UNIT_IN_BITS | CRYPTO_CAN_SHARE_OPSTATE}, /* RSA_PKCS */ {SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE, CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | @@ -5384,6 +5384,14 @@ error = crypto_decrypt_init_prov(pd, 0, &mech, keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL); + if (ctx->cc_flags & CRYPTO_INIT_OPSTATE) { + crypto_ctx_t *lctx = + (crypto_ctx_t *)(DPROV_CTX_SINGLE(ctx)); + + ctx->cc_opstate = lctx->cc_provider_private; + ctx->cc_flags |= CRYPTO_USE_OPSTATE; + } + /* release provider reference */ KCF_PROV_REFRELE(pd); break; @@ -5411,12 +5419,16 @@ break; case DPROV_REQ_ENCRYPT_UPDATE: + ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) || + (ctx->cc_flags & CRYPTO_USE_OPSTATE)); error = crypto_encrypt_update(DPROV_CTX_SINGLE(ctx), taskq_req->dr_cipher_req.dr_plaintext, taskq_req->dr_cipher_req.dr_ciphertext, NULL); break; case DPROV_REQ_DECRYPT_UPDATE: + ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) || + (ctx->cc_flags & CRYPTO_USE_OPSTATE)); error = crypto_decrypt_update(DPROV_CTX_SINGLE(ctx), taskq_req->dr_cipher_req.dr_ciphertext, taskq_req->dr_cipher_req.dr_plaintext, NULL); @@ -7608,7 +7620,7 @@ } } - rv = kcf_get_sw_prov(kcf_mech_type, pd, B_TRUE); + rv = kcf_get_sw_prov(kcf_mech_type, pd, NULL, B_TRUE); if (rv == CRYPTO_SUCCESS) *provider_mech_type = kcf_mech_type;
--- a/usr/src/uts/common/crypto/spi/kcf_spi.c Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/crypto/spi/kcf_spi.c Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -716,12 +716,6 @@ (void) strncpy(rand_mi->cm_mech_name, SUN_RANDOM, CRYPTO_MAX_MECH_NAME); rand_mi->cm_func_group_mask = CRYPTO_FG_RANDOM; - /* - * What we really need here is a - * CRYPTO_KEYSIZE_NOT_APPLICABLE. We make do with the - * following for now. - */ - rand_mi->cm_keysize_unit = CRYPTO_KEYSIZE_UNIT_IN_BITS; } else { ASSERT(info->pi_mechanisms != NULL); bcopy(info->pi_mechanisms, desc->pd_mechanisms, @@ -736,13 +730,13 @@ for (mech_idx = 0; mech_idx < desc->pd_mech_list_count; mech_idx++) { crypto_mech_info_t *mi = &desc->pd_mechanisms[mech_idx]; - if (mi->cm_keysize_unit != CRYPTO_KEYSIZE_UNIT_IN_BITS && - mi->cm_keysize_unit != CRYPTO_KEYSIZE_UNIT_IN_BYTES) { + if ((mi->cm_mech_flags & CRYPTO_KEYSIZE_UNIT_IN_BITS) && + (mi->cm_mech_flags & CRYPTO_KEYSIZE_UNIT_IN_BYTES)) { err = CRYPTO_ARGUMENTS_BAD; break; } - if (kcf_add_mech_provider(mi, desc, &pmd) != KCF_SUCCESS) + if (kcf_add_mech_provider(mech_idx, desc, &pmd) != KCF_SUCCESS) break; if (pmd == NULL)
--- a/usr/src/uts/common/sys/crypto/common.h Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/sys/crypto/common.h Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -67,13 +67,21 @@ #endif /* _SYSCALL32 */ /* - * The measurement unit flag for a mechanism's minimum or maximum key size. + * The measurement unit bit flag for a mechanism's minimum or maximum key size. * The unit are mechanism dependant. It can be in bits or in bytes. */ typedef uint32_t crypto_keysize_unit_t; +/* + * The following bit flags are valid in cm_mech_flags field in + * the crypto_mech_info_t structure of the SPI. + * + * Only the first two bit flags are valid in mi_keysize_unit + * field in the crypto_mechanism_info_t structure of the API. + */ #define CRYPTO_KEYSIZE_UNIT_IN_BITS 0x00000001 #define CRYPTO_KEYSIZE_UNIT_IN_BYTES 0x00000002 +#define CRYPTO_CAN_SHARE_OPSTATE 0x00000004 /* supports sharing */ /* Mechanisms supported out-of-the-box */ @@ -110,6 +118,13 @@ #define SUN_CKM_SHA384_RSA_PKCS "CKM_SHA384_RSA_PKCS" #define SUN_CKM_SHA512_RSA_PKCS "CKM_SHA512_RSA_PKCS" +/* Shared operation context format for CKM_RC4 */ +typedef struct { + uchar_t arr[256]; + uchar_t i, j; + uint64_t pad; /* For 64-bit alignment */ +} arcfour_state_t; + /* Data arguments of cryptographic operations */
--- a/usr/src/uts/common/sys/crypto/impl.h Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/sys/crypto/impl.h Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -155,11 +155,9 @@ (pd)->pd_state == KCF_PROV_BUSY) #define KCF_IS_PROV_REMOVED(pd) ((pd)->pd_state >= KCF_PROV_REMOVED) -/* - * Internal flag set to indicate if a provider is a member of - * a logical provider. - */ -#define KCF_LPROV_MEMBER 0x80000000 +/* Internal flags valid for pd_flags field */ +#define KCF_PROV_RESTRICTED 0x40000000 +#define KCF_LPROV_MEMBER 0x80000000 /* is member of a logical provider */ /* * A provider descriptor structure. There is one such structure per @@ -167,67 +165,64 @@ * freed when the provider unregisters. * * pd_prov_type: Provider type, hardware or software + * pd_sid: Session ID of the provider used by kernel clients. + * This is valid only for session-oriented providers. + * pd_refcnt: Reference counter to this provider descriptor + * pd_irefcnt: References held by the framework internal structs + * pd_lock: lock protects pd_state and pd_provider_list + * pd_state: State value of the provider + * pd_provider_list: Used to cross-reference logical providers and their + * members. Not used for software providers. + * pd_resume_cv: cv to wait for state to change from KCF_PROV_BUSY * pd_prov_handle: Provider handle specified by provider - * pd_kcf_prov_handle: KCF-private handle assigned by KCF - * pd_prov_id: Identification # assigned by KCF to provider - * pd_description: Provider description string * pd_ops_vector: The ops vector specified by Provider + * pd_mech_indx: Lookup table which maps a core framework mechanism + * number to an index in pd_mechanisms array + * pd_mechanisms: Array of mechanisms supported by the provider, specified + * by the provider during registration + * pd_sched_info: Scheduling information associated with the provider * pd_mech_list_count: The number of entries in pi_mechanisms, specified * by the provider during registration - * pd_mechanisms: Mechanisms supported by the provider, specified - * by the provider during registration - * pd_map_mechnums: Lookup table which maps a core framework mechanism - * number to a number understood by this provider - * pd_ks_data: kstat data - * pd_kstat: kstat associated with the provider - * pd_sched_info: Scheduling information associated with the provider - * pd_refcnt: Reference counter to this provider descriptor - * pd_irefcnt: References held by the framework internal structs * pd_name: Device name or module name * pd_instance: Device instance * pd_module_id: Module ID returned by modload * pd_mctlp: Pointer to modctl structure for this provider - * pd_sid: Session ID of the provider used by kernel clients. - * This is valid only for session-oriented providers. - * pd_lock: lock protects pd_state and pd_real_provider_list - * pd_state: State value of the provider - * pd_resume_cv: cv to wait for state to change from KCF_PROV_BUSY * pd_remove_cv: cv to wait on while the provider queue drains - * pd_restricted: true if this is an export restricted provider - * pd_provider_list: Used to cross-reference logical providers and their - * members. Not used for software providers. + * pd_description: Provider description string * pd_flags Could be CRYPTO_HIDE_PROVIDER from pi_flags - * or KCF_LPROV_MEMBER set internally. + * or KCF_LPROV_MEMBER, KCF_PROV_RESTRICTED set internally. + * pd_kcf_prov_handle: KCF-private handle assigned by KCF + * pd_prov_id: Identification # assigned by KCF to provider + * pd_kstat: kstat associated with the provider + * pd_ks_data: kstat data */ typedef struct kcf_provider_desc { crypto_provider_type_t pd_prov_type; - crypto_provider_handle_t pd_prov_handle; - crypto_kcf_provider_handle_t pd_kcf_prov_handle; - crypto_provider_id_t pd_prov_id; - char *pd_description; - crypto_ops_t *pd_ops_vector; - uint_t pd_mech_list_count; - crypto_mech_info_t *pd_mechanisms; - crypto_mech_type_t pd_map_mechnums[KCF_OPS_CLASSSIZE]\ - [KCF_MAXMECHTAB]; - kcf_stats_t *pd_stats; - kcf_prov_stats_t pd_ks_data; - kstat_t *pd_kstat; - kcf_sched_info_t pd_sched_info; + crypto_session_id_t pd_sid; uint_t pd_refcnt; uint_t pd_irefcnt; + kmutex_t pd_lock; + kcf_prov_state_t pd_state; + struct kcf_provider_list *pd_provider_list; + kcondvar_t pd_resume_cv; + crypto_provider_handle_t pd_prov_handle; + crypto_ops_t *pd_ops_vector; + ushort_t pd_mech_indx[KCF_OPS_CLASSSIZE]\ + [KCF_MAXMECHTAB]; + crypto_mech_info_t *pd_mechanisms; + kcf_sched_info_t pd_sched_info; + uint_t pd_mech_list_count; char *pd_name; uint_t pd_instance; int pd_module_id; struct modctl *pd_mctlp; - crypto_session_id_t pd_sid; - kmutex_t pd_lock; - kcf_prov_state_t pd_state; - kcondvar_t pd_resume_cv; kcondvar_t pd_remove_cv; - boolean_t pd_restricted; - struct kcf_provider_list *pd_provider_list; + char *pd_description; uint_t pd_flags; + crypto_kcf_provider_handle_t pd_kcf_prov_handle; + crypto_provider_id_t pd_prov_id; + kstat_t *pd_kstat; + kcf_prov_stats_t pd_ks_data; } kcf_provider_desc_t; /* useful for making a list of providers */ @@ -442,6 +437,20 @@ #define KCF_MECH2INDEX(mech_type) ((int)(mech_type)) +#define KCF_TO_PROV_MECH_INDX(pd, mech_type) \ + ((pd)->pd_mech_indx[KCF_MECH2CLASS(mech_type)] \ + [KCF_MECH2INDEX(mech_type)]) + +#define KCF_TO_PROV_MECHINFO(pd, mech_type) \ + ((pd)->pd_mechanisms[KCF_TO_PROV_MECH_INDX(pd, mech_type)]) + +#define KCF_TO_PROV_MECHNUM(pd, mech_type) \ + (KCF_TO_PROV_MECHINFO(pd, mech_type).cm_mech_number) + +#define KCF_CAN_SHARE_OPSTATE(pd, mech_type) \ + ((KCF_TO_PROV_MECHINFO(pd, mech_type).cm_mech_flags) & \ + CRYPTO_CAN_SHARE_OPSTATE) + /* ps_refcnt is protected by cm_lock in the crypto_minor structure */ typedef struct crypto_provider_session { struct crypto_provider_session *ps_next; @@ -500,6 +509,7 @@ #define KCF_INVALID_MECH_NAME 0x2 /* invalid mechanism name */ #define KCF_INVALID_MECH_CLASS 0x3 /* invalid mechanism class */ #define KCF_MECH_TAB_FULL 0x4 /* Need more room in the mech tabs. */ +#define KCF_INVALID_INDX ((ushort_t)-1) /* * kCF internal mechanism and function group for tracking RNG providers. @@ -1240,7 +1250,7 @@ int crypto_build_permitted_mech_names(kcf_provider_desc_t *, crypto_mech_name_t **, uint_t *, int); extern void kcf_init_mech_tabs(void); -extern int kcf_add_mech_provider(crypto_mech_info_t *, kcf_provider_desc_t *, +extern int kcf_add_mech_provider(short, kcf_provider_desc_t *, kcf_prov_mech_desc_t **); extern void kcf_remove_mech_provider(char *, kcf_provider_desc_t *); extern int kcf_get_mech_entry(crypto_mech_type_t, kcf_mech_entry_t **); @@ -1274,7 +1284,7 @@ extern void kcf_free_provider_tab(uint_t, kcf_provider_desc_t **); extern kcf_provider_desc_t *kcf_prov_tab_lookup(crypto_provider_id_t); extern int kcf_get_sw_prov(crypto_mech_type_t, kcf_provider_desc_t **, - boolean_t); + kcf_mech_entry_t **, boolean_t); /* Access to the policy table */ extern boolean_t is_mech_disabled(kcf_provider_desc_t *, crypto_mech_name_t);
--- a/usr/src/uts/common/sys/crypto/ops_impl.h Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/sys/crypto/ops_impl.h Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -563,8 +563,7 @@ #define KCF_SET_PROVIDER_MECHNUM(fmtype, pd, mechp) \ (mechp)->cm_type = \ - (pd)->pd_map_mechnums[KCF_MECH2CLASS(fmtype)] \ - [KCF_MECH2INDEX(fmtype)]; + KCF_TO_PROV_MECHNUM(pd, fmtype); #ifdef __cplusplus }
--- a/usr/src/uts/common/sys/crypto/sched_impl.h Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/sys/crypto/sched_impl.h Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -302,6 +302,8 @@ kcf_areq_node_t *kc_req_chain_last; boolean_t kc_need_signal; /* Initialized to B_FALSE */ kcf_provider_desc_t *kc_prov_desc; /* Prov. descriptor */ + kcf_provider_desc_t *kc_sw_prov_desc; /* Prov. descriptor */ + kcf_mech_entry_t *kc_mech; struct kcf_context *kc_secondctx; /* for dual contexts */ } kcf_context_t;
--- a/usr/src/uts/common/sys/crypto/spi.h Fri Feb 23 09:48:45 2007 -0800 +++ b/usr/src/uts/common/sys/crypto/spi.h Fri Feb 23 11:55:36 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -71,6 +71,10 @@ */ typedef void *crypto_req_handle_t; +/* Values for cc_flags field */ +#define CRYPTO_INIT_OPSTATE 0x00000001 /* allocate and init cc_opstate */ +#define CRYPTO_USE_OPSTATE 0x00000002 /* .. start using it as context */ + /* * The context structure is passed from the kernel to a provider. * It contains the information needed to process a multi-part or @@ -86,6 +90,8 @@ crypto_session_id_t cc_session; void *cc_provider_private; /* owned by provider */ void *cc_framework_private; /* owned by framework */ + uint32_t cc_flags; /* flags */ + void *cc_opstate; /* state */ } crypto_ctx_t; /* @@ -617,9 +623,12 @@ crypto_func_group_t cm_func_group_mask; ssize_t cm_min_key_length; ssize_t cm_max_key_length; - crypto_keysize_unit_t cm_keysize_unit; /* for cm_xxx_key_length */ + uint32_t cm_mech_flags; } crypto_mech_info_t; +/* Alias the old name to the new name for compatibility. */ +#define cm_keysize_unit cm_mech_flags + /* * crypto_kcf_provider_handle_t is a handle allocated by the kernel. * It is returned after the provider registers with @@ -674,7 +683,8 @@ /* hidden providers can only be accessed via a logical provider */ #define CRYPTO_HIDE_PROVIDER 0x00000001 -#define CRYPTO_PIFLAGS_UNAVAILABLE 0x80000000 +#define CRYPTO_PIFLAGS_RESERVED2 0x40000000 +#define CRYPTO_PIFLAGS_RESERVED1 0x80000000 /* * Provider status passed by a provider to crypto_provider_notification(9F)