Skip to content

Commit

Permalink
module: icp: rip out modhash. Replace the one user with AVL
Browse files Browse the repository at this point in the history
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes openzfs#12901
  • Loading branch information
nabijaczleweli authored and andrewc12 committed Sep 23, 2022
1 parent 0c7af52 commit bac54e9
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 1,271 deletions.
1 change: 0 additions & 1 deletion lib/libicp/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ KERNEL_C = \
io/aes.c \
io/sha2_mod.c \
io/skein_mod.c \
os/modhash.c \
core/kcf_sched.c \
core/kcf_prov_lib.c \
core/kcf_callprov.c \
Expand Down
1 change: 0 additions & 1 deletion module/icp/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ $(MODULE)-objs += spi/kcf_spi.o
$(MODULE)-objs += io/aes.o
$(MODULE)-objs += io/sha2_mod.o
$(MODULE)-objs += io/skein_mod.o
$(MODULE)-objs += os/modhash.o
$(MODULE)-objs += algs/modes/cbc.o
$(MODULE)-objs += algs/modes/ccm.o
$(MODULE)-objs += algs/modes/ctr.o
Expand Down
117 changes: 36 additions & 81 deletions module/icp/core/kcf_mech_tabs.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include <sys/crypto/common.h>
#include <sys/crypto/api.h>
#include <sys/crypto/impl.h>
#include <sys/modhash.h>

/* Cryptographic mechanisms tables and their access functions */

Expand Down Expand Up @@ -55,9 +54,6 @@
/*
* Locking conventions:
* --------------------
* A global mutex, kcf_mech_tabs_lock, serializes writes to the
* mechanism table via kcf_create_mech_entry().
*
* A mutex is associated with every entry of the tables.
* The mutex is acquired whenever the entry is accessed for
* 1) retrieving the mech_id (comparing the mech name)
Expand All @@ -72,9 +68,6 @@
* long enough to justify the cost of using rwlocks, so the per-mechanism
* entry mutex won't be very *hot*.
*
* When both kcf_mech_tabs_lock and a mech_entry mutex need to be held,
* kcf_mech_tabs_lock must always be acquired first.
*
*/

/* Mechanisms tables */
Expand Down Expand Up @@ -111,42 +104,22 @@ const kcf_mech_entry_tab_t kcf_mech_tabs_tab[KCF_LAST_OPSCLASS + 1] = {
{KCF_MAXMAC, kcf_mac_mechs_tab},
};

static kmutex_t kcf_mech_tabs_lock;
static avl_tree_t kcf_mech_hash;

static const int kcf_mech_hash_size = 256;
static mod_hash_t *kcf_mech_hash; /* mech name to id hash */

static crypto_mech_type_t
kcf_mech_hash_find(const char *mechname)
static int
kcf_mech_hash_compar(const void *lhs, const void *rhs)
{
mod_hash_val_t hv;
crypto_mech_type_t mt;

mt = CRYPTO_MECH_INVALID;
if (mod_hash_find(kcf_mech_hash, (mod_hash_key_t)mechname, &hv) == 0) {
mt = *(crypto_mech_type_t *)hv;
ASSERT(mt != CRYPTO_MECH_INVALID);
}

return (mt);
const kcf_mech_entry_t *l = lhs, *r = rhs;
int cmp = strncmp(l->me_name, r->me_name, CRYPTO_MAX_MECH_NAME);
return ((0 < cmp) - (cmp < 0));
}

void
kcf_destroy_mech_tabs(void)
{
int i, max;
kcf_ops_class_t class;
kcf_mech_entry_t *me_tab;

if (kcf_mech_hash)
mod_hash_destroy_hash(kcf_mech_hash);

mutex_destroy(&kcf_mech_tabs_lock);

for (class = KCF_FIRST_OPSCLASS; class <= KCF_LAST_OPSCLASS; class++) {
max = kcf_mech_tabs_tab[class].met_size;
me_tab = kcf_mech_tabs_tab[class].met_tab;
}
for (void *cookie = NULL; avl_destroy_nodes(&kcf_mech_hash, &cookie); )
;
avl_destroy(&kcf_mech_hash);
}

/*
Expand All @@ -161,24 +134,17 @@ kcf_init_mech_tabs(void)
kcf_ops_class_t class;
kcf_mech_entry_t *me_tab;

/* Initializes the mutex locks. */

mutex_init(&kcf_mech_tabs_lock, NULL, MUTEX_DEFAULT, NULL);

/* Then the pre-defined mechanism entries */

kcf_mech_hash = mod_hash_create_strhash_nodtr("kcf mech2id hash",
kcf_mech_hash_size, mod_hash_null_valdtor);
avl_create(&kcf_mech_hash, kcf_mech_hash_compar,
sizeof (kcf_mech_entry_t), offsetof(kcf_mech_entry_t, me_node));

for (class = KCF_FIRST_OPSCLASS; class <= KCF_LAST_OPSCLASS; class++) {
int max = kcf_mech_tabs_tab[class].met_size;
me_tab = kcf_mech_tabs_tab[class].met_tab;
for (int i = 0; i < max; i++) {
if (me_tab[i].me_name[0] != 0) {
me_tab[i].me_mechid = KCF_MECHID(class, i);
(void) mod_hash_insert(kcf_mech_hash,
(mod_hash_key_t)me_tab[i].me_name,
(mod_hash_val_t)&(me_tab[i].me_mechid));
avl_add(&kcf_mech_hash, &me_tab[i]);
}
}
}
Expand Down Expand Up @@ -213,10 +179,6 @@ kcf_init_mech_tabs(void)
static int
kcf_create_mech_entry(kcf_ops_class_t class, const char *mechname)
{
crypto_mech_type_t mt;
kcf_mech_entry_t *me_tab;
int i = 0, size;

if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS))
return (KCF_INVALID_MECH_CLASS);

Expand All @@ -226,41 +188,28 @@ kcf_create_mech_entry(kcf_ops_class_t class, const char *mechname)
* First check if the mechanism is already in one of the tables.
* The mech_entry could be in another class.
*/
mutex_enter(&kcf_mech_tabs_lock);
mt = kcf_mech_hash_find(mechname);
if (mt != CRYPTO_MECH_INVALID) {
/* Nothing to do, regardless the suggested class. */
mutex_exit(&kcf_mech_tabs_lock);
avl_index_t where = 0;
kcf_mech_entry_t tmptab;
strlcpy(tmptab.me_name, mechname, CRYPTO_MAX_MECH_NAME);
if (avl_find(&kcf_mech_hash, &tmptab, &where) != NULL)
return (KCF_SUCCESS);
}
/* Now take the next unused mech entry in the class's tab */
me_tab = kcf_mech_tabs_tab[class].met_tab;
size = kcf_mech_tabs_tab[class].met_size;
kcf_mech_entry_t *me_tab = kcf_mech_tabs_tab[class].met_tab;
int size = kcf_mech_tabs_tab[class].met_size;

while (i < size) {
for (int i = 0; i < size; ++i)
if (me_tab[i].me_name[0] == 0) {
/* Found an empty spot */
(void) strlcpy(me_tab[i].me_name, mechname,
strlcpy(me_tab[i].me_name, mechname,
CRYPTO_MAX_MECH_NAME);
me_tab[i].me_name[CRYPTO_MAX_MECH_NAME-1] = '\0';
me_tab[i].me_mechid = KCF_MECHID(class, i);

/* Add the new mechanism to the hash table */
(void) mod_hash_insert(kcf_mech_hash,
(mod_hash_key_t)me_tab[i].me_name,
(mod_hash_val_t)&(me_tab[i].me_mechid));
break;
avl_insert(&kcf_mech_hash, &me_tab[i], where);
return (KCF_SUCCESS);
}
i++;
}

mutex_exit(&kcf_mech_tabs_lock);

if (i == size) {
return (KCF_MECH_TAB_FULL);
}

return (KCF_SUCCESS);
return (KCF_MECH_TAB_FULL);
}

/*
Expand Down Expand Up @@ -299,7 +248,7 @@ kcf_add_mech_provider(short mech_indx,
* Find the class corresponding to the function group flag of
* the mechanism.
*/
kcf_mech_type = kcf_mech_hash_find(mech_info->cm_mech_name);
kcf_mech_type = crypto_mech2id(mech_info->cm_mech_name);
if (kcf_mech_type == CRYPTO_MECH_INVALID) {
crypto_func_group_t fg = mech_info->cm_func_group_mask;
kcf_ops_class_t class;
Expand All @@ -325,7 +274,7 @@ kcf_add_mech_provider(short mech_indx,
return (error);
}
/* get the KCF mech type that was assigned to the mechanism */
kcf_mech_type = kcf_mech_hash_find(mech_info->cm_mech_name);
kcf_mech_type = crypto_mech2id(mech_info->cm_mech_name);
ASSERT(kcf_mech_type != CRYPTO_MECH_INVALID);
}

Expand Down Expand Up @@ -398,7 +347,7 @@ kcf_remove_mech_provider(const char *mech_name, kcf_provider_desc_t *prov_desc)
kcf_mech_entry_t *mech_entry;

/* get the KCF mech type that was assigned to the mechanism */
if ((mech_type = kcf_mech_hash_find(mech_name)) ==
if ((mech_type = crypto_mech2id(mech_name)) ==
CRYPTO_MECH_INVALID) {
/*
* Provider was not allowed for this mech due to policy or
Expand Down Expand Up @@ -484,9 +433,7 @@ kcf_get_mech_entry(crypto_mech_type_t mech_type, kcf_mech_entry_t **mep)
* Description:
* Walks the mechanisms tables, looking for an entry that matches the
* mechname. Once it find it, it builds the 64-bit mech_type and returns
* it. If there are no providers for the mechanism,
* but there is an unloaded provider, this routine will attempt
* to load it.
* it.
*
* Context:
* Process and interruption.
Expand All @@ -504,7 +451,15 @@ kcf_get_mech_entry(crypto_mech_type_t mech_type, kcf_mech_entry_t **mep)
crypto_mech_type_t
crypto_mech2id(const char *mechname)
{
return (kcf_mech_hash_find(mechname));
kcf_mech_entry_t tmptab, *found;
strlcpy(tmptab.me_name, mechname, CRYPTO_MAX_MECH_NAME);

if ((found = avl_find(&kcf_mech_hash, &tmptab, NULL))) {
ASSERT(found->me_mechid != CRYPTO_MECH_INVALID);
return (found->me_mechid);
}

return (CRYPTO_MECH_INVALID);
}

#if defined(_KERNEL)
Expand Down
5 changes: 0 additions & 5 deletions module/icp/illumos-crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
#include <sys/crypto/api.h>
#include <sys/crypto/impl.h>
#include <sys/crypto/sched_impl.h>
#include <sys/modhash_impl.h>
#include <sys/crypto/icp.h>

/*
Expand Down Expand Up @@ -111,16 +110,12 @@ icp_fini(void)
kcf_sched_destroy();
kcf_prov_tab_destroy();
kcf_destroy_mech_tabs();
mod_hash_fini();
}

/* roughly equivalent to kcf.c: _init() */
int __init
icp_init(void)
{
/* initialize the mod hash module */
mod_hash_init();

/* initialize the mechanisms tables supported out-of-the-box */
kcf_init_mech_tabs();

Expand Down
4 changes: 3 additions & 1 deletion module/icp/include/sys/crypto/impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <sys/crypto/common.h>
#include <sys/crypto/api.h>
#include <sys/crypto/spi.h>
#include <sys/avl.h>

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -245,6 +246,7 @@ typedef struct kcf_mech_entry {
crypto_mech_name_t me_name; /* mechanism name */
crypto_mech_type_t me_mechid; /* Internal id for mechanism */
kcf_prov_mech_desc_t *me_sw_prov; /* provider */
avl_node_t me_node;
} kcf_mech_entry_t;

/*
Expand Down Expand Up @@ -300,7 +302,7 @@ extern const kcf_mech_entry_tab_t kcf_mech_tabs_tab[];

#define KCF_MECH2CLASS(mech_type) ((kcf_ops_class_t)((mech_type) >> 32))

#define KCF_MECH2INDEX(mech_type) ((int)(mech_type))
#define KCF_MECH2INDEX(mech_type) ((int)((mech_type) & 0xFFFFFFFF))

#define KCF_TO_PROV_MECH_INDX(pd, mech_type) \
((pd)->pd_mech_indx[KCF_MECH2CLASS(mech_type)] \
Expand Down
Loading

0 comments on commit bac54e9

Please sign in to comment.