Skip to content

Commit

Permalink
[crypto] add ability to have multiple crypto configurations at runtime
Browse files Browse the repository at this point in the history
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
  • Loading branch information
fabbione committed Nov 4, 2019
1 parent 1b46617 commit 81a7efa
Show file tree
Hide file tree
Showing 17 changed files with 992 additions and 79 deletions.
110 changes: 91 additions & 19 deletions libknet/crypto.c
Expand Up @@ -53,7 +53,7 @@ int crypto_encrypt_and_sign (
unsigned char *buf_out,
ssize_t *buf_out_len)
{
return crypto_modules_cmds[knet_h->crypto_instance->model].ops->crypt(knet_h, buf_in, buf_in_len, buf_out, buf_out_len);
return crypto_modules_cmds[knet_h->crypto_instance[knet_h->crypto_in_use_config]->model].ops->crypt(knet_h, knet_h->crypto_instance[knet_h->crypto_in_use_config], buf_in, buf_in_len, buf_out, buf_out_len);
}

int crypto_encrypt_and_signv (
Expand All @@ -63,7 +63,7 @@ int crypto_encrypt_and_signv (
unsigned char *buf_out,
ssize_t *buf_out_len)
{
return crypto_modules_cmds[knet_h->crypto_instance->model].ops->cryptv(knet_h, iov_in, iovcnt_in, buf_out, buf_out_len);
return crypto_modules_cmds[knet_h->crypto_instance[knet_h->crypto_in_use_config]->model].ops->cryptv(knet_h, knet_h->crypto_instance[knet_h->crypto_in_use_config], iov_in, iovcnt_in, buf_out, buf_out_len);
}

int crypto_authenticate_and_decrypt (
Expand All @@ -73,18 +73,65 @@ int crypto_authenticate_and_decrypt (
unsigned char *buf_out,
ssize_t *buf_out_len)
{
return crypto_modules_cmds[knet_h->crypto_instance->model].ops->decrypt(knet_h, buf_in, buf_in_len, buf_out, buf_out_len);
int i, err = 0;

/*
* attempt to decrypt first with the in-use config
* to avoid excessive performance hit.
*/

err = crypto_modules_cmds[knet_h->crypto_instance[knet_h->crypto_in_use_config]->model].ops->decrypt(knet_h, knet_h->crypto_instance[knet_h->crypto_in_use_config], buf_in, buf_in_len, buf_out, buf_out_len);

/*
* if we fail, try to use the other configurations
*/
if (err) {
for (i = 1; i <= KNET_MAX_CRYPTO_INSTANCES; i++) {
/*
* in-use config was already attempted
*/
if (i == knet_h->crypto_in_use_config) {
continue;
}
if (knet_h->crypto_instance[i]) {
err = crypto_modules_cmds[knet_h->crypto_instance[i]->model].ops->decrypt(knet_h, knet_h->crypto_instance[i], buf_in, buf_in_len, buf_out, buf_out_len);
if (!err) {
errno = 0; /* clear errno from previous failures */
return err;
}
}
}
}
return err;
}

int crypto_use_config(
knet_handle_t knet_h,
uint8_t config_num)
{
if (!knet_h->crypto_instance[config_num]) {
errno = EINVAL;
return -1;
}

knet_h->crypto_in_use_config = config_num;
knet_h->sec_block_size = knet_h->crypto_instance[config_num]->sec_block_size;
knet_h->sec_hash_size = knet_h->crypto_instance[config_num]->sec_hash_size;
knet_h->sec_salt_size = knet_h->crypto_instance[config_num]->sec_salt_size;

return 0;
}

int crypto_init(
knet_handle_t knet_h,
struct knet_handle_crypto_cfg *knet_handle_crypto_cfg)
struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
uint8_t config_num)
{
int err = 0, savederrno = 0;
int model = 0;
struct crypto_instance *current = NULL, *new = NULL;

current = knet_h->crypto_instance;
current = knet_h->crypto_instance[config_num];

model = crypto_get_model(knet_handle_crypto_cfg->crypto_model);
if (model < 0) {
Expand Down Expand Up @@ -153,10 +200,18 @@ int crypto_init(

out:
if (!err) {
knet_h->crypto_instance = new;
knet_h->sec_block_size = new->sec_block_size;
knet_h->sec_hash_size = new->sec_hash_size;
knet_h->sec_salt_size = new->sec_salt_size;
knet_h->crypto_instance[config_num] = new;
if ((!knet_h->crypto_in_use_config) || (knet_h->crypto_in_use_config == config_num)) {
knet_h->sec_block_size = new->sec_block_size;
knet_h->sec_hash_size = new->sec_hash_size;
knet_h->sec_salt_size = new->sec_salt_size;
}
/*
* set default config only at first crypto init
*/
if (!knet_h->crypto_in_use_config) {
knet_h->crypto_in_use_config = config_num;
}

log_debug(knet_h, KNET_SUB_CRYPTO, "Hash size: %zu salt size: %zu block size: %zu",
knet_h->sec_hash_size,
Expand All @@ -180,10 +235,30 @@ int crypto_init(
return err;
}

static void crypto_fini_config(
knet_handle_t knet_h,
uint8_t config_num)
{
if (knet_h->crypto_instance[config_num]) {
if (crypto_modules_cmds[knet_h->crypto_instance[config_num]->model].ops->fini != NULL) {
crypto_modules_cmds[knet_h->crypto_instance[config_num]->model].ops->fini(knet_h, knet_h->crypto_instance[config_num]);
}
free(knet_h->crypto_instance[config_num]);
knet_h->crypto_instance[config_num] = NULL;
if (knet_h->crypto_in_use_config == config_num) {
knet_h->crypto_in_use_config = 0;
knet_h->sec_block_size = 0;
knet_h->sec_hash_size = 0;
knet_h->sec_salt_size = 0;
}
}
}

void crypto_fini(
knet_handle_t knet_h)
knet_handle_t knet_h,
uint8_t config_num)
{
int savederrno = 0;
int savederrno = 0, i;

savederrno = pthread_rwlock_wrlock(&shlib_rwlock);
if (savederrno) {
Expand All @@ -192,15 +267,12 @@ void crypto_fini(
return;
}

if (knet_h->crypto_instance) {
if (crypto_modules_cmds[knet_h->crypto_instance->model].ops->fini != NULL) {
crypto_modules_cmds[knet_h->crypto_instance->model].ops->fini(knet_h, knet_h->crypto_instance);
if (!config_num) {
for (i = 1; i <= KNET_MAX_CRYPTO_INSTANCES; i++) {
crypto_fini_config(knet_h, i);
}
free(knet_h->crypto_instance);
knet_h->sec_block_size = 0;
knet_h->sec_hash_size = 0;
knet_h->sec_salt_size = 0;
knet_h->crypto_instance = NULL;
} else {
crypto_fini_config(knet_h, config_num);
}

pthread_rwlock_unlock(&shlib_rwlock);
Expand Down
10 changes: 8 additions & 2 deletions libknet/crypto.h
Expand Up @@ -32,11 +32,17 @@ int crypto_encrypt_and_signv (
unsigned char *buf_out,
ssize_t *buf_out_len);

int crypto_use_config (
knet_handle_t knet_h,
uint8_t config_num);

int crypto_init(
knet_handle_t knet_h,
struct knet_handle_crypto_cfg *knet_handle_crypto_cfg);
struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
uint8_t config_num);

void crypto_fini(
knet_handle_t knet_h);
knet_handle_t knet_h,
uint8_t config_num);

#endif
5 changes: 4 additions & 1 deletion libknet/crypto_model.h
Expand Up @@ -19,7 +19,7 @@ struct crypto_instance {
size_t sec_salt_size;
};

#define KNET_CRYPTO_MODEL_ABI 3
#define KNET_CRYPTO_MODEL_ABI 4

/*
* see compress_model.h for explanation of the various lib related functions
Expand All @@ -32,16 +32,19 @@ typedef struct {
void (*fini) (knet_handle_t knet_h,
struct crypto_instance *crypto_instance);
int (*crypt) (knet_handle_t knet_h,
struct crypto_instance *crypto_instance,
const unsigned char *buf_in,
const ssize_t buf_in_len,
unsigned char *buf_out,
ssize_t *buf_out_len);
int (*cryptv) (knet_handle_t knet_h,
struct crypto_instance *crypto_instance,
const struct iovec *iov_in,
int iovcnt_in,
unsigned char *buf_out,
ssize_t *buf_out_len);
int (*decrypt) (knet_handle_t knet_h,
struct crypto_instance *crypto_instance,
const unsigned char *buf_in,
const ssize_t buf_in_len,
unsigned char *buf_out,
Expand Down
26 changes: 16 additions & 10 deletions libknet/crypto_nss.c
Expand Up @@ -344,12 +344,13 @@ static int init_nss_crypto(knet_handle_t knet_h, struct crypto_instance *crypto_

static int encrypt_nss(
knet_handle_t knet_h,
struct crypto_instance *crypto_instance,
const struct iovec *iov,
int iovcnt,
unsigned char *buf_out,
ssize_t *buf_out_len)
{
struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
struct nsscrypto_instance *instance = crypto_instance->model_instance;
PK11Context* crypt_context = NULL;
SECItem crypt_param;
SECItem *nss_sec_param = NULL;
Expand Down Expand Up @@ -431,12 +432,13 @@ static int encrypt_nss(

static int decrypt_nss (
knet_handle_t knet_h,
struct crypto_instance *crypto_instance,
const unsigned char *buf_in,
const ssize_t buf_in_len,
unsigned char *buf_out,
ssize_t *buf_out_len)
{
struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
struct nsscrypto_instance *instance = crypto_instance->model_instance;
PK11Context* decrypt_context = NULL;
SECItem decrypt_param;
int tmp1_outlen = 0;
Expand Down Expand Up @@ -533,11 +535,12 @@ static int init_nss_hash(knet_handle_t knet_h, struct crypto_instance *crypto_in

static int calculate_nss_hash(
knet_handle_t knet_h,
struct crypto_instance *crypto_instance,
const unsigned char *buf,
const size_t buf_len,
unsigned char *hash)
{
struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
struct nsscrypto_instance *instance = crypto_instance->model_instance;
PK11Context* hash_context = NULL;
SECItem hash_param;
unsigned int hash_tmp_outlen = 0;
Expand Down Expand Up @@ -636,16 +639,17 @@ static int init_nss(knet_handle_t knet_h, struct crypto_instance *crypto_instanc

static int nsscrypto_encrypt_and_signv (
knet_handle_t knet_h,
struct crypto_instance *crypto_instance,
const struct iovec *iov_in,
int iovcnt_in,
unsigned char *buf_out,
ssize_t *buf_out_len)
{
struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
struct nsscrypto_instance *instance = crypto_instance->model_instance;
int i;

if (cipher_to_nss[instance->crypto_cipher_type]) {
if (encrypt_nss(knet_h, iov_in, iovcnt_in, buf_out, buf_out_len) < 0) {
if (encrypt_nss(knet_h, crypto_instance, iov_in, iovcnt_in, buf_out, buf_out_len) < 0) {
return -1;
}
} else {
Expand All @@ -657,7 +661,7 @@ static int nsscrypto_encrypt_and_signv (
}

if (hash_to_nss[instance->crypto_hash_type]) {
if (calculate_nss_hash(knet_h, buf_out, *buf_out_len, buf_out + *buf_out_len) < 0) {
if (calculate_nss_hash(knet_h, crypto_instance, buf_out, *buf_out_len, buf_out + *buf_out_len) < 0) {
return -1;
}
*buf_out_len = *buf_out_len + nsshash_len[instance->crypto_hash_type];
Expand All @@ -668,6 +672,7 @@ static int nsscrypto_encrypt_and_signv (

static int nsscrypto_encrypt_and_sign (
knet_handle_t knet_h,
struct crypto_instance *crypto_instance,
const unsigned char *buf_in,
const ssize_t buf_in_len,
unsigned char *buf_out,
Expand All @@ -679,17 +684,18 @@ static int nsscrypto_encrypt_and_sign (
iov_in.iov_base = (unsigned char *)buf_in;
iov_in.iov_len = buf_in_len;

return nsscrypto_encrypt_and_signv(knet_h, &iov_in, 1, buf_out, buf_out_len);
return nsscrypto_encrypt_and_signv(knet_h, crypto_instance, &iov_in, 1, buf_out, buf_out_len);
}

static int nsscrypto_authenticate_and_decrypt (
knet_handle_t knet_h,
struct crypto_instance *crypto_instance,
const unsigned char *buf_in,
const ssize_t buf_in_len,
unsigned char *buf_out,
ssize_t *buf_out_len)
{
struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
struct nsscrypto_instance *instance = crypto_instance->model_instance;
ssize_t temp_len = buf_in_len;

if (hash_to_nss[instance->crypto_hash_type]) {
Expand All @@ -701,7 +707,7 @@ static int nsscrypto_authenticate_and_decrypt (
return -1;
}

if (calculate_nss_hash(knet_h, buf_in, temp_buf_len, tmp_hash) < 0) {
if (calculate_nss_hash(knet_h, crypto_instance, buf_in, temp_buf_len, tmp_hash) < 0) {
return -1;
}

Expand All @@ -715,7 +721,7 @@ static int nsscrypto_authenticate_and_decrypt (
}

if (cipher_to_nss[instance->crypto_cipher_type]) {
if (decrypt_nss(knet_h, buf_in, temp_len, buf_out, buf_out_len) < 0) {
if (decrypt_nss(knet_h, crypto_instance, buf_in, temp_len, buf_out, buf_out_len) < 0) {
return -1;
}
} else {
Expand Down

0 comments on commit 81a7efa

Please sign in to comment.