Skip to content

Commit

Permalink
[crypto] introduce (nss)crypto_encrypt_and_signv
Browse files Browse the repository at this point in the history
and move crypto_encrypt_and_sign to use the v version.

Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
  • Loading branch information
fabbione committed Nov 15, 2016
1 parent 7721390 commit 1991f49
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 17 deletions.
14 changes: 12 additions & 2 deletions libknet/crypto.c
Expand Up @@ -21,8 +21,8 @@
*/

crypto_model_t modules_cmds[] = {
{ "nss", nsscrypto_init, nsscrypto_fini, nsscrypto_encrypt_and_sign, nsscrypto_authenticate_and_decrypt },
{ NULL, NULL, NULL, NULL, NULL },
{ "nss", nsscrypto_init, nsscrypto_fini, nsscrypto_encrypt_and_sign, nsscrypto_encrypt_and_signv, nsscrypto_authenticate_and_decrypt },
{ NULL, NULL, NULL, NULL, NULL, NULL },
};

static int get_model(const char *model)
Expand Down Expand Up @@ -51,6 +51,16 @@ int crypto_encrypt_and_sign (
return modules_cmds[knet_h->crypto_instance->model].crypt(knet_h, buf_in, buf_in_len, buf_out, buf_out_len);
}

int crypto_encrypt_and_signv (
knet_handle_t knet_h,
const struct iovec *iov,
int iovcnt,
unsigned char *buf_out,
ssize_t *buf_out_len)
{
return modules_cmds[knet_h->crypto_instance->model].cryptv(knet_h, iov, iovcnt, buf_out, buf_out_len);
}

int crypto_authenticate_and_decrypt (
knet_handle_t knet_h,
const unsigned char *buf_in,
Expand Down
14 changes: 13 additions & 1 deletion libknet/crypto.h
Expand Up @@ -26,6 +26,11 @@ typedef struct {
const ssize_t buf_in_len,
unsigned char *buf_out,
ssize_t *buf_out_len);
int (*cryptv) (knet_handle_t knet_h,
const struct iovec *iov,
int iovcnt,
unsigned char *buf_out,
ssize_t *buf_out_len);
int (*decrypt) (knet_handle_t knet_h,
const unsigned char *buf_in,
const ssize_t buf_in_len,
Expand All @@ -44,7 +49,14 @@ int crypto_encrypt_and_sign (
knet_handle_t knet_h,
const unsigned char *buf_in,
const ssize_t buf_in_len,
unsigned char *buf_out,
unsigned char *buf_out,
ssize_t *buf_out_len);

int crypto_encrypt_and_signv (
knet_handle_t knet_h,
const struct iovec *iov,
int iovcnt,
unsigned char *buf_out,
ssize_t *buf_out_len);

int crypto_init(
Expand Down
65 changes: 53 additions & 12 deletions libknet/nsscrypto.c
Expand Up @@ -189,20 +189,21 @@ static int init_nss_crypto(knet_handle_t knet_h)

static int encrypt_nss(
knet_handle_t knet_h,
const unsigned char *buf_in,
const ssize_t buf_in_len,
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;
PK11Context* crypt_context = NULL;
SECItem crypt_param;
SECItem *nss_sec_param = NULL;
int tmp1_outlen = 0;
int tmp_outlen = 0, tmp1_outlen = 0;
unsigned int tmp2_outlen = 0;
unsigned char *salt = buf_out;
unsigned char *data = buf_out + SALT_SIZE;
int err = -1;
int i;

if (PK11_GenerateRandom (salt, SALT_SIZE) != SECSuccess) {
log_err(knet_h, KNET_SUB_NSSCRYPTO, "Failure to generate a random number %d",
Expand Down Expand Up @@ -236,14 +237,17 @@ static int encrypt_nss(
goto out;
}

if (PK11_CipherOp(crypt_context, data,
&tmp1_outlen,
KNET_DATABUFSIZE_CRYPT,
(unsigned char *)buf_in, buf_in_len) != SECSuccess) {
log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CipherOp failed (encrypt) crypt_type=%d (err %d)",
(int)cipher_to_nss[instance->crypto_cipher_type],
PR_GetError());
goto out;
for (i=0; i<iovcnt; i++) {
if (PK11_CipherOp(crypt_context, data,
&tmp_outlen,
KNET_DATABUFSIZE_CRYPT,
(unsigned char *)iov[i].iov_base, iov[i].iov_len) != SECSuccess) {
log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CipherOp failed (encrypt) crypt_type=%d (err %d)",
(int)cipher_to_nss[instance->crypto_cipher_type],
PR_GetError());
goto out;
}
tmp1_outlen = tmp1_outlen + tmp_outlen;
}

if (PK11_DigestFinal(crypt_context, data + tmp1_outlen,
Expand Down Expand Up @@ -536,9 +540,14 @@ int nsscrypto_encrypt_and_sign (
ssize_t *buf_out_len)
{
struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
struct iovec iov_in;

memset(&iov_in, 0, sizeof(iov_in));
iov_in.iov_base = (unsigned char *)buf_in;
iov_in.iov_len = buf_in_len;

if (cipher_to_nss[instance->crypto_cipher_type]) {
if (encrypt_nss(knet_h, buf_in, buf_in_len, buf_out, buf_out_len) < 0) {
if (encrypt_nss(knet_h, &iov_in, 1, buf_out, buf_out_len) < 0) {
return -1;
}
} else {
Expand All @@ -556,6 +565,38 @@ int nsscrypto_encrypt_and_sign (
return 0;
}

int nsscrypto_encrypt_and_signv (
knet_handle_t knet_h,
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;
int i;

if (cipher_to_nss[instance->crypto_cipher_type]) {
if (encrypt_nss(knet_h, iov, iovcnt, buf_out, buf_out_len) < 0) {
return -1;
}
} else {
*buf_out_len = 0;
for (i=0; i<iovcnt; i++) {
memmove(buf_out + *buf_out_len, iov[i].iov_base, iov[i].iov_len);
*buf_out_len = *buf_out_len + iov[i].iov_len;
}
}

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) {
return -1;
}
*buf_out_len = *buf_out_len + hash_len[instance->crypto_hash_type];
}

return 0;
}

int nsscrypto_authenticate_and_decrypt (
knet_handle_t knet_h,
const unsigned char *buf_in,
Expand Down
9 changes: 8 additions & 1 deletion libknet/nsscrypto.h
Expand Up @@ -24,7 +24,14 @@ int nsscrypto_encrypt_and_sign (
knet_handle_t knet_h,
const unsigned char *buf_in,
const ssize_t buf_in_len,
unsigned char *buf_out,
unsigned char *buf_out,
ssize_t *buf_out_len);

int nsscrypto_encrypt_and_signv (
knet_handle_t knet_h,
const struct iovec *iov,
int iovcnt,
unsigned char *buf_out,
ssize_t *buf_out_len);

int nsscrypto_init(
Expand Down
128 changes: 127 additions & 1 deletion libknet/tests/fun_crypto_benchmark.c
Expand Up @@ -33,6 +33,8 @@ static void test(void)
int loops;
struct timespec clock_start, clock_end;
unsigned long long time_diff;
struct iovec iov_in;
struct iovec iov_multi[4];

memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));

Expand Down Expand Up @@ -122,7 +124,131 @@ static void test(void)

timespec_diff(clock_start, clock_end, &time_diff);

printf("Execution of 1000000 loops: %llu/ns\n", time_diff);
printf("Execution of 1000000 loops (buf_in api): %llu/ns\n", time_diff);

if (clock_gettime(CLOCK_MONOTONIC, &clock_start) != 0) {
printf("Unable to get start time!\n");
knet_handle_free(knet_h);
flush_logs(logfds[0], stdout);
close_logpipes(logfds);
exit(FAIL);
}

memset(buf1, 0, sizeof(buf1));
strcpy(buf1, "Encrypt me!");

for (loops=0; loops<1000000; loops++) {
memset(buf2, 0, sizeof(buf2));
memset(buf3, 0, sizeof(buf3));
memset(&iov_in, 0, sizeof(iov_in));

iov_in.iov_base = (unsigned char *)buf1;
iov_in.iov_len = strlen(buf1)+1;

if (crypto_encrypt_and_signv(knet_h, &iov_in, 1, (unsigned char *)buf2, &outbuf_len) < 0) {
printf("Unable to crypt and sign!\n");
knet_handle_free(knet_h);
flush_logs(logfds[0], stdout);
close_logpipes(logfds);
exit(FAIL);
}

if (crypto_authenticate_and_decrypt(knet_h, (unsigned char *)buf2, outbuf_len, (unsigned char *)buf3, &outbuf_len) < 0) {
printf("Unable to auth and decrypt!\n");
knet_handle_free(knet_h);
flush_logs(logfds[0], stdout);
close_logpipes(logfds);
exit(FAIL);
}


if (memcmp(buf1, buf3, outbuf_len)) {
printf("Crypt / Descrypt produced two different data set!\n");
knet_handle_free(knet_h);
flush_logs(logfds[0], stdout);
close_logpipes(logfds);
exit(FAIL);
}
}

if (clock_gettime(CLOCK_MONOTONIC, &clock_end) != 0) {
printf("Unable to get end time!\n");
knet_handle_free(knet_h);
flush_logs(logfds[0], stdout);
close_logpipes(logfds);
exit(FAIL);
}

timespec_diff(clock_start, clock_end, &time_diff);

printf("Execution of 1000000 loops (iov_in api): %llu/ns\n", time_diff);

if (clock_gettime(CLOCK_MONOTONIC, &clock_start) != 0) {
printf("Unable to get start time!\n");
knet_handle_free(knet_h);
flush_logs(logfds[0], stdout);
close_logpipes(logfds);
exit(FAIL);
}

memset(buf1, 0, sizeof(buf1));
strcpy(buf1, "Encrypt me!");

for (loops=0; loops<1000000; loops++) {
memset(buf2, 0, sizeof(buf2));
memset(buf3, 0, sizeof(buf3));
memset(&iov_multi, 0, sizeof(iov_multi));

/*
* "Encrypt me!\n" = 12 bytes
*/

iov_multi[0].iov_base = (unsigned char *)buf1;
iov_multi[0].iov_len = 3;
iov_multi[1].iov_base = (unsigned char *)buf1 + 3;
iov_multi[1].iov_len = 3;
iov_multi[2].iov_base = (unsigned char *)buf1 + 6;
iov_multi[2].iov_len = 3;
iov_multi[3].iov_base = (unsigned char *)buf1 + 9;
iov_multi[3].iov_len = 3;

if (crypto_encrypt_and_signv(knet_h, iov_multi, 4, (unsigned char *)buf2, &outbuf_len) < 0) {
printf("Unable to crypt and sign!\n");
knet_handle_free(knet_h);
flush_logs(logfds[0], stdout);
close_logpipes(logfds);
exit(FAIL);
}

if (crypto_authenticate_and_decrypt(knet_h, (unsigned char *)buf2, outbuf_len, (unsigned char *)buf3, &outbuf_len) < 0) {
printf("Unable to auth and decrypt!\n");
knet_handle_free(knet_h);
flush_logs(logfds[0], stdout);
close_logpipes(logfds);
exit(FAIL);
}


if (memcmp(buf1, buf3, outbuf_len)) {
printf("Crypt / Descrypt produced two different data set!\n");
knet_handle_free(knet_h);
flush_logs(logfds[0], stdout);
close_logpipes(logfds);
exit(FAIL);
}
}

if (clock_gettime(CLOCK_MONOTONIC, &clock_end) != 0) {
printf("Unable to get end time!\n");
knet_handle_free(knet_h);
flush_logs(logfds[0], stdout);
close_logpipes(logfds);
exit(FAIL);
}

timespec_diff(clock_start, clock_end, &time_diff);

printf("Execution of 1000000 loops (iov_in multi api): %llu/ns\n", time_diff);

printf("Shutdown crypto\n");

Expand Down

0 comments on commit 1991f49

Please sign in to comment.