Skip to content

Commit

Permalink
[crypto] add support for live reconfiguration
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 Jul 8, 2020
1 parent d51e047 commit b707ad0
Show file tree
Hide file tree
Showing 20 changed files with 1,640 additions and 126 deletions.
132 changes: 108 additions & 24 deletions libknet/crypto.c
Original file line number Diff line number Diff line change
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,92 @@ 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;
int multiple_configs = 0;
uint8_t log_level = KNET_LOG_ERR;

for (i = 1; i <= KNET_MAX_CRYPTO_INSTANCES; i++) {
if (knet_h->crypto_instance[i]) {
multiple_configs++;
}
}

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

if (multiple_configs > 1) {
log_level = KNET_LOG_DEBUG;
}

if (knet_h->crypto_in_use_config) {
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, log_level);
} else {
err = -1;
}

/*
* 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]) {
log_debug(knet_h, KNET_SUB_CRYPTO, "Alternative crypto configuration found, attempting to decrypt with config %u", 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, KNET_LOG_ERR);
if (!err) {
errno = 0; /* clear errno from previous failures */
return err;
}
log_debug(knet_h, KNET_SUB_CRYPTO, "Packet failed to decrypt with crypto config %u", i);
}
}
}
return err;
}

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

knet_h->crypto_in_use_config = config_num;

if (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;
} else {
knet_h->sec_block_size = 0;
knet_h->sec_hash_size = 0;
knet_h->sec_salt_size = 0;
}

force_pmtud_run(knet_h, KNET_SUB_CRYPTO, 1);

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,17 +227,16 @@ 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;

log_debug(knet_h, KNET_SUB_CRYPTO, "Hash size: %zu salt size: %zu block size: %zu",
knet_h->sec_hash_size,
knet_h->sec_salt_size,
knet_h->sec_block_size);
knet_h->crypto_instance[config_num] = new;

if (current) {
/*
* if we are replacing the current config, we need to enable it right away
*/
if (knet_h->crypto_in_use_config == config_num) {
crypto_use_config(knet_h, config_num);
}

if (crypto_modules_cmds[current->model].ops->fini != NULL) {
crypto_modules_cmds[current->model].ops->fini(knet_h, current);
}
Expand All @@ -180,10 +253,24 @@ 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;
}
}

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 +279,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 > KNET_MAX_CRYPTO_INSTANCES) {
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
Original file line number Diff line number Diff line change
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
8 changes: 6 additions & 2 deletions libknet/crypto_model.h
Original file line number Diff line number Diff line change
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,20 +32,24 @@ 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,
ssize_t *buf_out_len);
ssize_t *buf_out_len,
uint8_t log_level);
} crypto_ops_t;

typedef struct {
Expand Down

0 comments on commit b707ad0

Please sign in to comment.