summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiloslav Trmač <mitr@redhat.com>2010-08-16 22:50:56 +0200
committerMiloslav Trmač <mitr@redhat.com>2010-08-24 23:49:09 +0200
commit7017a63132bc03462ba75e399c083e00f4e19573 (patch)
treeba790f1e3e542492640e6bf63ad1f3d6f62153e3
parente536df1a394cf653ecc5964ece0551b0259abeb4 (diff)
downloadcryptodev-linux-7017a63132bc03462ba75e399c083e00f4e19573.tar.gz
cryptodev-linux-7017a63132bc03462ba75e399c083e00f4e19573.tar.xz
cryptodev-linux-7017a63132bc03462ba75e399c083e00f4e19573.zip
Convert *_SESSION_*
-rw-r--r--examples/ncr.c218
-rw-r--r--examples/pk.c334
-rw-r--r--examples/speed.c48
-rw-r--r--ncr-int.h42
-rw-r--r--ncr-pk.c150
-rw-r--r--ncr-pk.h15
-rw-r--r--ncr-sessions.c514
-rw-r--r--ncr.c117
-rw-r--r--ncr.h112
-rw-r--r--utils.c37
10 files changed, 937 insertions, 650 deletions
diff --git a/examples/ncr.c b/examples/ncr.c
index 49f5e38..facecd8 100644
--- a/examples/ncr.c
+++ b/examples/ncr.c
@@ -843,8 +843,18 @@ test_ncr_aes(int cfd)
} kimport;
uint8_t data[KEY_DATA_SIZE];
int i, j;
- struct ncr_session_once_op_st nop;
- int data_size;
+ struct __attribute__((packed)) {
+ struct ncr_session_once f;
+ struct nlattr algo_head ALIGN_NL;
+ uint32_t algo ALIGN_NL;
+ struct nlattr key_head ALIGN_NL;
+ uint32_t key ALIGN_NL;
+ struct nlattr input_head ALIGN_NL;
+ struct ncr_session_input_data input ALIGN_NL;
+ struct nlattr output_head ALIGN_NL;
+ struct ncr_session_output_buffer output ALIGN_NL;
+ } op;
+ size_t data_size;
/* convert it to key */
key = ioctl(cfd, NCRIO_KEY_INIT);
@@ -881,23 +891,30 @@ test_ncr_aes(int cfd)
}
/* encrypt */
- memset(&nop, 0, sizeof(nop));
- nop.init.algorithm = NCR_ALG_AES_ECB;
- nop.init.key = key;
- nop.init.op = NCR_OP_ENCRYPT;
- nop.op.data.udata.input = (void*)aes_vectors[i].plaintext;
- nop.op.data.udata.input_size = 16;
- nop.op.data.udata.output = data;
- nop.op.data.udata.output_size = sizeof(data);
- nop.op.type = NCR_DIRECT_DATA;
-
- if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ memset(&op.f, 0, sizeof(op.f));
+ op.f.input_size = sizeof(op);
+ op.f.op = NCR_OP_ENCRYPT;
+ op.algo_head.nla_len = NLA_HDRLEN + sizeof(op.algo);
+ op.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ op.algo = NCR_ALG_AES_ECB;
+ op.key_head.nla_len = NLA_HDRLEN + sizeof(op.key);
+ op.key_head.nla_type = NCR_ATTR_KEY;
+ op.key = key;
+ op.input_head.nla_len = NLA_HDRLEN + sizeof(op.input);
+ op.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA;
+ op.input.data = aes_vectors[i].plaintext;
+ op.input.data_size = 16;
+ op.output_head.nla_len = NLA_HDRLEN + sizeof(op.output);
+ op.output_head.nla_type = NCR_ATTR_UPDATE_OUTPUT_BUFFER;
+ op.output.buffer = data;
+ op.output.buffer_size = sizeof(data);
+ op.output.result_size_ptr = &data_size;
+
+ if (ioctl(cfd, NCRIO_SESSION_ONCE, &op)) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_ONCE)");
return 1;
}
-
- data_size = nop.op.data.udata.output_size;
/* verify */
if (data_size != 16 || memcmp(data, aes_vectors[i].ciphertext, 16) != 0) {
@@ -944,24 +961,30 @@ test_ncr_aes(int cfd)
}
/* decrypt */
- memset(&nop, 0, sizeof(nop));
- nop.init.algorithm = NCR_ALG_AES_ECB;
- nop.init.key = key;
- nop.init.op = NCR_OP_DECRYPT;
- nop.op.data.udata.input = (void*)aes_vectors[i].ciphertext;
- nop.op.data.udata.input_size = 16;
- nop.op.data.udata.output = data;
- nop.op.data.udata.output_size = sizeof(data);
- nop.op.type = NCR_DIRECT_DATA;
-
- if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ memset(&op.f, 0, sizeof(op.f));
+ op.f.input_size = sizeof(op);
+ op.f.op = NCR_OP_DECRYPT;
+ op.algo_head.nla_len = NLA_HDRLEN + sizeof(op.algo);
+ op.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ op.algo = NCR_ALG_AES_ECB;
+ op.key_head.nla_len = NLA_HDRLEN + sizeof(op.key);
+ op.key_head.nla_type = NCR_ATTR_KEY;
+ op.key = key;
+ op.input_head.nla_len = NLA_HDRLEN + sizeof(op.input);
+ op.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA;
+ op.input.data = aes_vectors[i].ciphertext;
+ op.input.data_size = 16;
+ op.output_head.nla_len = NLA_HDRLEN + sizeof(op.output);
+ op.output_head.nla_type = NCR_ATTR_UPDATE_OUTPUT_BUFFER;
+ op.output.buffer = data;
+ op.output.buffer_size = sizeof(data);
+ op.output.result_size_ptr = &data_size;
+
+ if (ioctl(cfd, NCRIO_SESSION_ONCE, &op)) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_ONCE)");
return 1;
}
-
- data_size = nop.op.data.udata.output_size;
-
if (data_size != 16 || memcmp(data, aes_vectors[i].plaintext, 16) != 0) {
fprintf(stderr, "AES test vector %d failed!\n", i);
@@ -1084,8 +1107,19 @@ test_ncr_hash(int cfd)
uint32_t flags ALIGN_NL;
} kimport;
uint8_t data[HASH_DATA_SIZE];
- int i, j, data_size;
- struct ncr_session_once_op_st nop;
+ int i, j;
+ size_t data_size;
+ struct __attribute__((packed)) {
+ struct ncr_session_once f;
+ struct nlattr algo_head ALIGN_NL;
+ uint32_t algo ALIGN_NL;
+ struct nlattr key_head ALIGN_NL;
+ uint32_t key ALIGN_NL;
+ struct nlattr input_head ALIGN_NL;
+ struct ncr_session_input_data input ALIGN_NL;
+ struct nlattr output_head ALIGN_NL;
+ struct ncr_session_output_buffer output ALIGN_NL;
+ } op;
/* convert it to key */
key = ioctl(cfd, NCRIO_KEY_INIT);
@@ -1130,26 +1164,30 @@ test_ncr_hash(int cfd)
}
}
- /* encrypt */
- memset(&nop, 0, sizeof(nop));
- nop.init.algorithm = hash_vectors[i].algorithm;
- if (hash_vectors[i].key != NULL)
- nop.init.key = key;
- nop.init.op = hash_vectors[i].op;
- nop.op.data.udata.input = (void*)hash_vectors[i].plaintext;
- nop.op.data.udata.input_size = hash_vectors[i].plaintext_size;
- nop.op.data.udata.output = data;
- nop.op.data.udata.output_size = sizeof(data);
- nop.op.type = NCR_DIRECT_DATA;
-
- if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ memset(&op.f, 0, sizeof(op.f));
+ op.f.input_size = sizeof(op);
+ op.f.op = hash_vectors[i].op;
+ op.algo_head.nla_len = NLA_HDRLEN + sizeof(op.algo);
+ op.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ op.algo = hash_vectors[i].algorithm;
+ op.key_head.nla_len = NLA_HDRLEN + sizeof(op.key);
+ op.key_head.nla_type = NCR_ATTR_KEY;
+ op.key = hash_vectors[i].key != NULL ? key : NCR_KEY_INVALID;
+ op.input_head.nla_len = NLA_HDRLEN + sizeof(op.input);
+ op.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA;
+ op.input.data = hash_vectors[i].plaintext;
+ op.input.data_size = hash_vectors[i].plaintext_size;
+ op.output_head.nla_len = NLA_HDRLEN + sizeof(op.output);
+ op.output_head.nla_type = NCR_ATTR_FINAL_OUTPUT_BUFFER;
+ op.output.buffer = data;
+ op.output.buffer_size = sizeof(data);
+ op.output.result_size_ptr = &data_size;
+
+ if (ioctl(cfd, NCRIO_SESSION_ONCE, &op)) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_ONCE)");
return 1;
}
-
- data_size = nop.op.data.udata.output_size;
-
if (data_size != hash_vectors[i].output_size ||
memcmp(data, hash_vectors[i].output, hash_vectors[i].output_size) != 0) {
@@ -1178,6 +1216,7 @@ static int
test_ncr_hash_key(int cfd)
{
ncr_key_t key;
+ ncr_session_t ses;
struct __attribute__((packed)) {
struct ncr_key_import f;
struct nlattr id_head ALIGN_NL;
@@ -1190,9 +1229,28 @@ test_ncr_hash_key(int cfd)
uint32_t flags ALIGN_NL;
} kimport;
uint8_t data[HASH_DATA_SIZE];
- int j, data_size;
- struct ncr_session_op_st op;
- struct ncr_session_st op_init;
+ int j;
+ size_t data_size;
+ struct __attribute__((packed)) {
+ struct ncr_session_init f;
+ struct nlattr algo_head ALIGN_NL;
+ uint32_t algo ALIGN_NL;
+ } op_init;
+ struct __attribute__((packed)) {
+ struct ncr_session_update f;
+ struct nlattr data_head ALIGN_NL;
+ struct ncr_session_input_data data ALIGN_NL;
+ } op_up_data;
+ struct __attribute__((packed)) {
+ struct ncr_session_update f;
+ struct nlattr key_head ALIGN_NL;
+ uint32_t key;
+ } op_up_key;
+ struct __attribute__((packed)) {
+ struct ncr_session_final f;
+ struct nlattr output_head ALIGN_NL;
+ struct ncr_session_output_buffer output ALIGN_NL;
+ } op_final;
const uint8_t *output = (void*)"\xe2\xd7\x2c\x2e\x14\xad\x97\xc8\xd2\xdb\xce\xd8\xb3\x52\x9f\x1c\xb3\x2c\x5c\xec";
/* convert it to key */
@@ -1230,58 +1288,62 @@ test_ncr_hash_key(int cfd)
return 1;
}
- /* encrypt */
- memset(&op_init, 0, sizeof(op_init));
- op_init.algorithm = hash_vectors[0].algorithm;
- op_init.op = hash_vectors[0].op;
+ memset(&op_init.f, 0, sizeof(op_init.f));
+ op_init.f.input_size = sizeof(op_init);
+ op_init.f.op = hash_vectors[0].op;
+ op_init.algo_head.nla_len = NLA_HDRLEN + sizeof(op_init.algo);
+ op_init.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ op_init.algo = hash_vectors[0].algorithm;
- if (ioctl(cfd, NCRIO_SESSION_INIT, &op_init)) {
+ ses = ioctl(cfd, NCRIO_SESSION_INIT, &op_init);
+ if (ses < 0) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_INIT)");
return 1;
}
- memset(&op, 0, sizeof(op));
- op.ses = op_init.ses;
- op.data.udata.input = (void*)hash_vectors[0].plaintext;
- op.data.udata.input_size = hash_vectors[0].plaintext_size;
- op.data.udata.output = NULL;
- op.data.udata.output_size = 0;
- op.type = NCR_DIRECT_DATA;
+ memset(&op_up_data.f, 0, sizeof(op_up_data.f));
+ op_up_data.f.input_size = sizeof(op_up_data);
+ op_up_data.f.ses = ses;
+ op_up_data.data_head.nla_len = NLA_HDRLEN + sizeof(op_up_data.data);
+ op_up_data.data_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA;
+ op_up_data.data.data = hash_vectors[0].plaintext;
+ op_up_data.data.data_size = hash_vectors[0].plaintext_size;
- if (ioctl(cfd, NCRIO_SESSION_UPDATE, &op)) {
+ if (ioctl(cfd, NCRIO_SESSION_UPDATE, &op_up_data)) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_UPDATE)");
return 1;
}
- memset(&op, 0, sizeof(op));
- op.ses = op_init.ses;
- op.data.kdata.input = key;
- op.data.kdata.output = NULL;
- op.data.kdata.output_size = 0;
- op.type = NCR_KEY_DATA;
+ memset(&op_up_key.f, 0, sizeof(op_up_key.f));
+ op_up_key.f.input_size = sizeof(op_up_key);
+ op_up_key.f.ses = ses;
+ op_up_key.key_head.nla_len = NLA_HDRLEN + sizeof(op_up_key.key);
+ op_up_key.key_head.nla_type = NCR_ATTR_UPDATE_INPUT_KEY_AS_DATA;
+ op_up_key.key = key;
- if (ioctl(cfd, NCRIO_SESSION_UPDATE, &op)) {
+ if (ioctl(cfd, NCRIO_SESSION_UPDATE, &op_up_key)) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_UPDATE)");
return 1;
}
- op.data.udata.input = NULL;
- op.data.udata.input_size = 0;
- op.data.udata.output = data;
- op.data.udata.output_size = sizeof(data);
- op.type = NCR_DIRECT_DATA;
+ memset(&op_final.f, 0, sizeof(op_final.f));
+ op_final.f.input_size = sizeof(op_final);
+ op_final.f.ses = ses;
+ op_final.output_head.nla_len = NLA_HDRLEN + sizeof(op_final.output);
+ op_final.output_head.nla_type = NCR_ATTR_FINAL_OUTPUT_BUFFER;
+ op_final.output.buffer = data;
+ op_final.output.buffer_size = sizeof(data);
+ op_final.output.result_size_ptr = &data_size;
- if (ioctl(cfd, NCRIO_SESSION_FINAL, &op)) {
+ if (ioctl(cfd, NCRIO_SESSION_FINAL, &op_final)) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_FINAL)");
return 1;
}
- data_size = op.data.udata.output_size;
-
if (data_size != hash_vectors[0].output_size ||
memcmp(data, output, hash_vectors[0].output_size) != 0) {
diff --git a/examples/pk.c b/examples/pk.c
index ac95820..8645fd4 100644
--- a/examples/pk.c
+++ b/examples/pk.c
@@ -794,10 +794,24 @@ test_ncr_wrap_key3(int cfd)
static int rsa_key_encrypt(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int oaep)
{
- struct ncr_session_once_op_st nop;
+ struct __attribute__((packed)) {
+ struct ncr_session_once f;
+ struct nlattr algo_head ALIGN_NL;
+ uint32_t algo ALIGN_NL;
+ struct nlattr key_head ALIGN_NL;
+ uint32_t key ALIGN_NL;
+ struct nlattr rsa_head ALIGN_NL;
+ uint32_t rsa ALIGN_NL;
+ struct nlattr oaep_hash_head ALIGN_NL;
+ uint32_t oaep_hash ALIGN_NL;
+ struct nlattr input_head ALIGN_NL;
+ struct ncr_session_input_data input ALIGN_NL;
+ struct nlattr output_head ALIGN_NL;
+ struct ncr_session_output_buffer output ALIGN_NL;
+ } op;
uint8_t data[DATA_SIZE];
uint8_t vdata[RSA_ENCRYPT_SIZE];
- int enc_size;
+ size_t enc_size, dec_size;
fprintf(stdout, "Tests on RSA (%s) key encryption:", (oaep!=0)?"OAEP":"PKCS V1.5");
fflush(stdout);
@@ -806,55 +820,79 @@ static int rsa_key_encrypt(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int oae
memcpy(vdata, data, sizeof(vdata));
/* do encryption */
- memset(&nop, 0, sizeof(nop));
- nop.init.algorithm = NCR_ALG_RSA;
- nop.init.key = pubkey;
+ memset(&op.f, 0, sizeof(op.f));
+ op.f.input_size = sizeof(op);
+ op.f.op = NCR_OP_ENCRYPT;
+ op.algo_head.nla_len = NLA_HDRLEN + sizeof(op.algo);
+ op.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ op.algo = NCR_ALG_RSA;
+ op.key_head.nla_len = NLA_HDRLEN + sizeof(op.key);
+ op.key_head.nla_type = NCR_ATTR_KEY;
+ op.key = pubkey;
+ op.rsa_head.nla_len = NLA_HDRLEN + sizeof(op.rsa);
+ op.rsa_head.nla_type = NCR_ATTR_RSA_ENCODING_METHOD;
if (oaep) {
- nop.init.params.params.rsa.type = RSA_PKCS1_OAEP;
- nop.init.params.params.rsa.oaep_hash = NCR_ALG_SHA1;
+ op.rsa = RSA_PKCS1_OAEP;
} else {
- nop.init.params.params.rsa.type = RSA_PKCS1_V1_5;
+ op.rsa = RSA_PKCS1_V1_5;
}
- nop.init.op = NCR_OP_ENCRYPT;
- nop.op.data.udata.input = data;
- nop.op.data.udata.input_size = RSA_ENCRYPT_SIZE;
- nop.op.data.udata.output = data;
- nop.op.data.udata.output_size = sizeof(data);
- nop.op.type = NCR_DIRECT_DATA;
-
- if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ op.oaep_hash_head.nla_len = NLA_HDRLEN + sizeof(op.oaep_hash);
+ op.oaep_hash_head.nla_type = NCR_ATTR_RSA_OAEP_HASH_ALGORITHM;
+ op.oaep_hash = NCR_ALG_SHA1; /* Ignored if not using OAEP */
+ op.input_head.nla_len = NLA_HDRLEN + sizeof(op.input);
+ op.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA;
+ op.input.data = data;
+ op.input.data_size = RSA_ENCRYPT_SIZE;
+ op.output_head.nla_len = NLA_HDRLEN + sizeof(op.output);
+ op.output_head.nla_type = NCR_ATTR_UPDATE_OUTPUT_BUFFER;
+ op.output.buffer = data;
+ op.output.buffer_size = sizeof(data);
+ op.output.result_size_ptr = &enc_size;
+
+ if (ioctl(cfd, NCRIO_SESSION_ONCE, &op)) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_ONCE)");
return 1;
}
-
- enc_size = nop.op.data.udata.output_size;
/* decrypt data */
- memset(&nop, 0, sizeof(nop));
- nop.init.algorithm = NCR_ALG_RSA;
- nop.init.key = privkey;
- nop.init.op = NCR_OP_DECRYPT;
+ memset(&op.f, 0, sizeof(op.f));
+ op.f.input_size = sizeof(op);
+ op.f.op = NCR_OP_DECRYPT;
+ op.algo_head.nla_len = NLA_HDRLEN + sizeof(op.algo);
+ op.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ op.algo = NCR_ALG_RSA;
+ op.key_head.nla_len = NLA_HDRLEN + sizeof(op.key);
+ op.key_head.nla_type = NCR_ATTR_KEY;
+ op.key = privkey;
+ op.rsa_head.nla_len = NLA_HDRLEN + sizeof(op.rsa);
+ op.rsa_head.nla_type = NCR_ATTR_RSA_ENCODING_METHOD;
if (oaep) {
- nop.init.params.params.rsa.type = RSA_PKCS1_OAEP;
- nop.init.params.params.rsa.oaep_hash = NCR_ALG_SHA1;
+ op.rsa = RSA_PKCS1_OAEP;
} else {
- nop.init.params.params.rsa.type = RSA_PKCS1_V1_5;
+ op.rsa = RSA_PKCS1_V1_5;
}
- nop.op.data.udata.input = data;
- nop.op.data.udata.input_size = enc_size;
- nop.op.data.udata.output = data;
- nop.op.data.udata.output_size = sizeof(data);
- nop.op.type = NCR_DIRECT_DATA;
-
-
- if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ op.oaep_hash_head.nla_len = NLA_HDRLEN + sizeof(op.oaep_hash);
+ op.oaep_hash_head.nla_type = NCR_ATTR_RSA_OAEP_HASH_ALGORITHM;
+ op.oaep_hash = NCR_ALG_SHA1; /* Ignored if not using OAEP */
+ op.input_head.nla_len = NLA_HDRLEN + sizeof(op.input);
+ op.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA;
+ op.input.data = data;
+ op.input.data_size = enc_size;
+ op.output_head.nla_len = NLA_HDRLEN + sizeof(op.output);
+ op.output_head.nla_type = NCR_ATTR_UPDATE_OUTPUT_BUFFER;
+ op.output.buffer = data;
+ op.output.buffer_size = sizeof(data);
+ op.output.result_size_ptr = &dec_size;
+
+ if (ioctl(cfd, NCRIO_SESSION_ONCE, &op)) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_ONCE)");
return 1;
}
- if (memcmp(vdata, data, sizeof(vdata)) != 0) {
+ if (dec_size != sizeof(vdata)
+ || memcmp(vdata, data, sizeof(vdata)) != 0) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
fprintf(stderr, "Decrypted data do not match!\n");
return 1;
@@ -870,61 +908,113 @@ static int rsa_key_encrypt(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int oae
static int rsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int pss)
{
- struct ncr_session_once_op_st nop;
+ struct __attribute__((packed)) {
+ struct ncr_session_once f;
+ struct nlattr algo_head ALIGN_NL;
+ uint32_t algo ALIGN_NL;
+ struct nlattr key_head ALIGN_NL;
+ uint32_t key ALIGN_NL;
+ struct nlattr rsa_head ALIGN_NL;
+ uint32_t rsa ALIGN_NL;
+ struct nlattr sign_hash_head ALIGN_NL;
+ uint32_t sign_hash ALIGN_NL;
+ struct nlattr input_head ALIGN_NL;
+ struct ncr_session_input_data input ALIGN_NL;
+ struct nlattr signature_head ALIGN_NL;
+ struct ncr_session_output_buffer signature ALIGN_NL;
+ } ksign;
+ struct __attribute__((packed)) {
+ struct ncr_session_once f;
+ struct nlattr algo_head ALIGN_NL;
+ uint32_t algo ALIGN_NL;
+ struct nlattr key_head ALIGN_NL;
+ uint32_t key ALIGN_NL;
+ struct nlattr rsa_head ALIGN_NL;
+ uint32_t rsa ALIGN_NL;
+ struct nlattr sign_hash_head ALIGN_NL;
+ uint32_t sign_hash ALIGN_NL;
+ struct nlattr input_head ALIGN_NL;
+ struct ncr_session_input_data input ALIGN_NL;
+ struct nlattr signature_head ALIGN_NL;
+ struct ncr_session_input_data signature ALIGN_NL;
+ } kverify;
uint8_t data[DATA_SIZE];
uint8_t sig[DATA_SIZE];
- int sig_size;
+ size_t sig_size;
+ int ret;
fprintf(stdout, "Tests on RSA (%s) key signature:", (pss!=0)?"PSS":"PKCS V1.5");
fflush(stdout);
memset(data, 0x3, sizeof(data));
- /* sign datad */
- memset(&nop, 0, sizeof(nop));
- nop.init.algorithm = NCR_ALG_RSA;
- nop.init.key = privkey;
- nop.init.params.params.rsa.type = (pss!=0)?RSA_PKCS1_PSS:RSA_PKCS1_V1_5;
- nop.init.params.params.rsa.sign_hash = NCR_ALG_SHA1;
-
- nop.init.op = NCR_OP_SIGN;
- nop.op.data.udata.input = data;
- nop.op.data.udata.input_size = DATA_TO_SIGN;
- nop.op.data.udata.output = sig;
- nop.op.data.udata.output_size = sizeof(sig);
- nop.op.type = NCR_DIRECT_DATA;
-
- if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ /* sign data */
+ memset(&ksign.f, 0, sizeof(ksign.f));
+ ksign.f.input_size = sizeof(ksign);
+ ksign.f.op = NCR_OP_SIGN;
+ ksign.algo_head.nla_len = NLA_HDRLEN + sizeof(ksign.algo);
+ ksign.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ ksign.algo = NCR_ALG_RSA;
+ ksign.key_head.nla_len = NLA_HDRLEN + sizeof(ksign.key);
+ ksign.key_head.nla_type = NCR_ATTR_KEY;
+ ksign.key = privkey;
+ ksign.rsa_head.nla_len = NLA_HDRLEN + sizeof(ksign.rsa);
+ ksign.rsa_head.nla_type = NCR_ATTR_RSA_ENCODING_METHOD;
+ ksign.rsa = (pss != 0) ? RSA_PKCS1_PSS : RSA_PKCS1_V1_5;
+ ksign.sign_hash_head.nla_len = NLA_HDRLEN + sizeof(ksign.sign_hash);
+ ksign.sign_hash_head.nla_type = NCR_ATTR_SIGNATURE_HASH_ALGORITHM;
+ ksign.sign_hash = NCR_ALG_SHA1;
+ ksign.input_head.nla_len = NLA_HDRLEN + sizeof(ksign.input);
+ ksign.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA;
+ ksign.input.data = data;
+ ksign.input.data_size = DATA_TO_SIGN;
+ ksign.signature_head.nla_len = NLA_HDRLEN + sizeof(ksign.signature);
+ ksign.signature_head.nla_type = NCR_ATTR_FINAL_OUTPUT_BUFFER;
+ ksign.signature.buffer = sig;
+ ksign.signature.buffer_size = sizeof(sig);
+ ksign.signature.result_size_ptr = &sig_size;
+
+ if (ioctl(cfd, NCRIO_SESSION_ONCE, &ksign)) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_ONCE)");
return 1;
}
-
- sig_size = nop.op.data.udata.output_size;
/* verify signature */
- memset(&nop, 0, sizeof(nop));
- nop.init.algorithm = NCR_ALG_RSA;
- nop.init.key = pubkey;
- nop.init.params.params.rsa.type = (pss!=0)?RSA_PKCS1_PSS:RSA_PKCS1_V1_5;
- nop.init.params.params.rsa.sign_hash = NCR_ALG_SHA1;
-
memset(data, 0x3, sizeof(data));
- nop.init.op = NCR_OP_VERIFY;
- nop.op.data.udata.input = data;
- nop.op.data.udata.input_size = DATA_TO_SIGN;
- nop.op.data.udata.output = sig;
- nop.op.data.udata.output_size = sig_size;
- nop.op.type = NCR_DIRECT_DATA;
-
- if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ memset(&kverify.f, 0, sizeof(kverify.f));
+ kverify.f.input_size = sizeof(kverify);
+ kverify.f.op = NCR_OP_VERIFY;
+ kverify.algo_head.nla_len = NLA_HDRLEN + sizeof(kverify.algo);
+ kverify.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ kverify.algo = NCR_ALG_RSA;
+ kverify.key_head.nla_len = NLA_HDRLEN + sizeof(kverify.key);
+ kverify.key_head.nla_type = NCR_ATTR_KEY;
+ kverify.key = pubkey;
+ kverify.rsa_head.nla_len = NLA_HDRLEN + sizeof(kverify.rsa);
+ kverify.rsa_head.nla_type = NCR_ATTR_RSA_ENCODING_METHOD;
+ kverify.rsa = (pss != 0) ? RSA_PKCS1_PSS : RSA_PKCS1_V1_5;
+ kverify.sign_hash_head.nla_len = NLA_HDRLEN + sizeof(kverify.sign_hash);
+ kverify.sign_hash_head.nla_type = NCR_ATTR_SIGNATURE_HASH_ALGORITHM;
+ kverify.sign_hash = NCR_ALG_SHA1;
+ kverify.input_head.nla_len = NLA_HDRLEN + sizeof(kverify.input);
+ kverify.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA;
+ kverify.input.data = data;
+ kverify.input.data_size = DATA_TO_SIGN;
+ kverify.signature_head.nla_len = NLA_HDRLEN + sizeof(kverify.signature);
+ kverify.signature_head.nla_type = NCR_ATTR_FINAL_INPUT_DATA;
+ kverify.signature.data = sig;
+ kverify.signature.data_size = sig_size;
+
+ ret = ioctl(cfd, NCRIO_SESSION_ONCE, &kverify);
+ if (ret < 0) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_ONCE)");
return 1;
}
- if (nop.op.err == NCR_SUCCESS)
+ if (ret)
fprintf(stdout, " Success\n");
else {
fprintf(stdout, " Verification Failed!\n");
@@ -937,57 +1027,101 @@ static int rsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int
static int dsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey)
{
- struct ncr_session_once_op_st nop;
+ struct __attribute__((packed)) {
+ struct ncr_session_once f;
+ struct nlattr algo_head ALIGN_NL;
+ uint32_t algo ALIGN_NL;
+ struct nlattr key_head ALIGN_NL;
+ uint32_t key ALIGN_NL;
+ struct nlattr sign_hash_head ALIGN_NL;
+ uint32_t sign_hash ALIGN_NL;
+ struct nlattr input_head ALIGN_NL;
+ struct ncr_session_input_data input ALIGN_NL;
+ struct nlattr signature_head ALIGN_NL;
+ struct ncr_session_output_buffer signature ALIGN_NL;
+ } ksign;
+ struct __attribute__((packed)) {
+ struct ncr_session_once f;
+ struct nlattr algo_head ALIGN_NL;
+ uint32_t algo ALIGN_NL;
+ struct nlattr key_head ALIGN_NL;
+ uint32_t key ALIGN_NL;
+ struct nlattr sign_hash_head ALIGN_NL;
+ uint32_t sign_hash ALIGN_NL;
+ struct nlattr input_head ALIGN_NL;
+ struct ncr_session_input_data input ALIGN_NL;
+ struct nlattr signature_head ALIGN_NL;
+ struct ncr_session_input_data signature ALIGN_NL;
+ } kverify;
uint8_t data[DATA_SIZE];
uint8_t sig[DATA_SIZE];
- int sig_size;
+ size_t sig_size;
+ int ret;
fprintf(stdout, "Tests on DSA key signature:");
fflush(stdout);
memset(data, 0x3, sizeof(data));
- /* sign datad */
- memset(&nop, 0, sizeof(nop));
- nop.init.algorithm = NCR_ALG_DSA;
- nop.init.key = privkey;
- nop.init.params.params.dsa.sign_hash = NCR_ALG_SHA1;
-
- nop.init.op = NCR_OP_SIGN;
- nop.op.data.udata.input = data;
- nop.op.data.udata.input_size = DATA_TO_SIGN;
- nop.op.data.udata.output = sig;
- nop.op.data.udata.output_size = sizeof(sig);
- nop.op.type = NCR_DIRECT_DATA;
-
- if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ /* sign data */
+ memset(&ksign.f, 0, sizeof(ksign.f));
+ ksign.f.input_size = sizeof(ksign);
+ ksign.f.op = NCR_OP_SIGN;
+ ksign.algo_head.nla_len = NLA_HDRLEN + sizeof(ksign.algo);
+ ksign.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ ksign.algo = NCR_ALG_DSA;
+ ksign.key_head.nla_len = NLA_HDRLEN + sizeof(ksign.key);
+ ksign.key_head.nla_type = NCR_ATTR_KEY;
+ ksign.key = privkey;
+ ksign.sign_hash_head.nla_len = NLA_HDRLEN + sizeof(ksign.sign_hash);
+ ksign.sign_hash_head.nla_type = NCR_ATTR_SIGNATURE_HASH_ALGORITHM;
+ ksign.sign_hash = NCR_ALG_SHA1;
+ ksign.input_head.nla_len = NLA_HDRLEN + sizeof(ksign.input);
+ ksign.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA;
+ ksign.input.data = data;
+ ksign.input.data_size = DATA_TO_SIGN;
+ ksign.signature_head.nla_len = NLA_HDRLEN + sizeof(ksign.signature);
+ ksign.signature_head.nla_type = NCR_ATTR_FINAL_OUTPUT_BUFFER;
+ ksign.signature.buffer = sig;
+ ksign.signature.buffer_size = sizeof(sig);
+ ksign.signature.result_size_ptr = &sig_size;
+
+ if (ioctl(cfd, NCRIO_SESSION_ONCE, &ksign)) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_ONCE)");
return 1;
}
-
- sig_size = nop.op.data.udata.output_size;
/* verify signature */
- memset(&nop, 0, sizeof(nop));
- nop.init.algorithm = NCR_ALG_DSA;
- nop.init.key = pubkey;
- nop.init.params.params.dsa.sign_hash = NCR_ALG_SHA1;
-
- nop.init.op = NCR_OP_VERIFY;
- nop.op.data.udata.input = data;
- nop.op.data.udata.input_size = DATA_TO_SIGN;
- nop.op.data.udata.output = sig;
- nop.op.data.udata.output_size = sizeof(sig);
- nop.op.type = NCR_DIRECT_DATA;
-
- if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ memset(&kverify.f, 0, sizeof(kverify.f));
+ kverify.f.input_size = sizeof(kverify);
+ kverify.f.op = NCR_OP_VERIFY;
+ kverify.algo_head.nla_len = NLA_HDRLEN + sizeof(kverify.algo);
+ kverify.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ kverify.algo = NCR_ALG_DSA;
+ kverify.key_head.nla_len = NLA_HDRLEN + sizeof(kverify.key);
+ kverify.key_head.nla_type = NCR_ATTR_KEY;
+ kverify.key = pubkey;
+ kverify.sign_hash_head.nla_len = NLA_HDRLEN + sizeof(kverify.sign_hash);
+ kverify.sign_hash_head.nla_type = NCR_ATTR_SIGNATURE_HASH_ALGORITHM;
+ kverify.sign_hash = NCR_ALG_SHA1;
+ kverify.input_head.nla_len = NLA_HDRLEN + sizeof(kverify.input);
+ kverify.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA;
+ kverify.input.data = data;
+ kverify.input.data_size = DATA_TO_SIGN;
+ kverify.signature_head.nla_len = NLA_HDRLEN + sizeof(kverify.signature);
+ kverify.signature_head.nla_type = NCR_ATTR_FINAL_INPUT_DATA;
+ kverify.signature.data = sig;
+ kverify.signature.data_size = sizeof(sig);
+
+ ret = ioctl(cfd, NCRIO_SESSION_ONCE, &kverify);
+ if (ret < 0) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_ONCE)");
return 1;
}
- if (nop.op.err == NCR_SUCCESS)
+ if (ret)
fprintf(stdout, " Success\n");
else {
fprintf(stdout, " Verification Failed!\n");
diff --git a/examples/speed.c b/examples/speed.c
index 9c2e8b8..a75009e 100644
--- a/examples/speed.c
+++ b/examples/speed.c
@@ -88,7 +88,18 @@ int encrypt_data_ncr_direct(int cfd, int algo, int chunksize)
struct nlattr bits_head ALIGN_NL;
uint32_t bits ALIGN_NL;
} kgen;
- struct ncr_session_once_op_st nop;
+ struct __attribute__((packed)) {
+ struct ncr_session_once f;
+ struct nlattr algo_head ALIGN_NL;
+ uint32_t algo ALIGN_NL;
+ struct nlattr key_head ALIGN_NL;
+ uint32_t key ALIGN_NL;
+ struct nlattr input_head ALIGN_NL;
+ struct ncr_session_input_data input ALIGN_NL;
+ struct nlattr output_head ALIGN_NL;
+ struct ncr_session_output_buffer output ALIGN_NL;
+ struct nlattr iv_head ALIGN_NL;
+ } op;
key = ioctl(cfd, NCRIO_KEY_INIT);
if (key == -1) {
@@ -127,17 +138,30 @@ int encrypt_data_ncr_direct(int cfd, int algo, int chunksize)
gettimeofday(&start, NULL);
do {
- memset(&nop, 0, sizeof(nop));
- nop.init.algorithm = algo;
- nop.init.key = key;
- nop.init.op = NCR_OP_ENCRYPT;
- nop.op.data.udata.input = buffer;
- nop.op.data.udata.input_size = chunksize;
- nop.op.data.udata.output = buffer;
- nop.op.data.udata.output_size = chunksize;
- nop.op.type = NCR_DIRECT_DATA;
-
- if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ size_t output_size;
+
+ memset(&op.f, 0, sizeof(op.f));
+ op.f.input_size = sizeof(op);
+ op.f.op = NCR_OP_ENCRYPT;
+ op.algo_head.nla_len = NLA_HDRLEN + sizeof(op.algo);
+ op.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ op.algo = algo;
+ op.key_head.nla_len = NLA_HDRLEN + sizeof(op.key);
+ op.key_head.nla_type = NCR_ATTR_KEY;
+ op.key = key;
+ op.input_head.nla_len = NLA_HDRLEN + sizeof(op.input);
+ op.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA;
+ op.input.data = buffer;
+ op.input.data_size = chunksize;
+ op.output_head.nla_len = NLA_HDRLEN + sizeof(op.output);
+ op.output_head.nla_type = NCR_ATTR_UPDATE_OUTPUT_BUFFER;
+ op.output.buffer = buffer;
+ op.output.buffer_size = chunksize;
+ op.output.result_size_ptr = &output_size;
+ op.iv_head.nla_len = NLA_HDRLEN + 0;
+ op.iv_head.nla_type = NCR_ATTR_IV;
+
+ if (ioctl(cfd, NCRIO_SESSION_ONCE, &op)) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
perror("ioctl(NCRIO_SESSION_ONCE)");
return 1;
diff --git a/ncr-int.h b/ncr-int.h
index b8f1250..669c1a2 100644
--- a/ncr-int.h
+++ b/ncr-int.h
@@ -1,6 +1,7 @@
#ifndef NCR_INT_H
# define NCR_INT_H
+#include <linux/compat.h>
#include <linux/idr.h>
#include <linux/mutex.h>
#include "ncr.h"
@@ -170,10 +171,18 @@ void _ncr_sessions_item_put( struct session_item_st* item);
struct session_item_st* ncr_sessions_item_get(struct ncr_lists *lst, ncr_session_t desc);
void ncr_sessions_list_deinit(struct ncr_lists *lst);
-int ncr_session_init(struct ncr_lists* lists, void __user* arg);
-int ncr_session_update(struct ncr_lists* lists, void __user* arg);
-int ncr_session_final(struct ncr_lists* lists, void __user* arg);
-int ncr_session_once(struct ncr_lists* lists, void __user* arg);
+int ncr_session_init(struct ncr_lists *lists,
+ const struct ncr_session_init *session,
+ struct nlattr *tb[]);
+int ncr_session_update(struct ncr_lists *lists,
+ const struct ncr_session_update *op, struct nlattr *tb[],
+ int compat);
+int ncr_session_final(struct ncr_lists *lists,
+ const struct ncr_session_final *op, struct nlattr *tb[],
+ int compat);
+int ncr_session_once(struct ncr_lists *lists,
+ const struct ncr_session_once *once, struct nlattr *tb[],
+ int compat);
/* master key */
extern struct key_item_st master_key;
@@ -189,7 +198,30 @@ int key_to_storage_data( uint8_t** data, size_t * data_size, const struct key_it
const struct algo_properties_st *_ncr_algo_to_properties(ncr_algorithm_t algo);
const struct algo_properties_st *_ncr_nla_to_properties(const struct nlattr *nla);
-const struct algo_properties_st *ncr_key_params_get_sign_hash(const struct algo_properties_st *algo, struct ncr_key_params_st * params);
int _ncr_key_get_sec_level(struct key_item_st* item);
+/* CONFIG_COMPAT handling */
+
+#ifdef CONFIG_COMPAT
+struct compat_ncr_session_input_data {
+ compat_uptr_t data;
+ compat_size_t data_size;
+};
+
+struct compat_ncr_session_output_buffer {
+ compat_uptr_t buffer;
+ compat_size_t buffer_size;
+ compat_uptr_t result_size_ptr;
+};
+#endif
+
+int ncr_session_input_data_from_nla(struct ncr_session_input_data *dest,
+ const struct nlattr *nla, int compat);
+
+int ncr_session_output_buffer_from_nla(struct ncr_session_output_buffer *dest,
+ const struct nlattr *nla, int compat);
+
+int ncr_session_output_buffer_set_size(const struct ncr_session_output_buffer *dest,
+ size_t size, int compat);
+
#endif
diff --git a/ncr-pk.c b/ncr-pk.c
index c96f494..ed904d6 100644
--- a/ncr-pk.c
+++ b/ncr-pk.c
@@ -337,25 +337,6 @@ fail:
return 0;
}
-const struct algo_properties_st *ncr_key_params_get_sign_hash(
- const struct algo_properties_st *algo,
- struct ncr_key_params_st * params)
-{
- ncr_algorithm_t id;
-
- switch(algo->algo) {
- case NCR_ALG_RSA:
- id = params->params.rsa.sign_hash;
- break;
- case NCR_ALG_DSA:
- id = params->params.dsa.sign_hash;
- break;
- default:
- return ERR_PTR(-EINVAL);
- }
- return _ncr_algo_to_properties(id);
-}
-
/* Encryption/Decryption
*/
@@ -368,9 +349,12 @@ void ncr_pk_cipher_deinit(struct ncr_pk_ctx* ctx)
}
int ncr_pk_cipher_init(const struct algo_properties_st *algo,
- struct ncr_pk_ctx* ctx, struct ncr_key_params_st* params,
- struct key_item_st *key, const struct algo_properties_st *sign_hash)
+ struct ncr_pk_ctx* ctx, struct nlattr *tb[],
+ struct key_item_st *key,
+ const struct algo_properties_st *sign_hash)
{
+ const struct nlattr *nla;
+
memset(ctx, 0, sizeof(*ctx));
if (key->algorithm != algo) {
@@ -381,26 +365,38 @@ int ncr_pk_cipher_init(const struct algo_properties_st *algo,
ctx->algorithm = algo;
ctx->key = key;
ctx->sign_hash = sign_hash;
+ ctx->salt_len = 0;
switch(algo->algo) {
case NCR_ALG_RSA:
- if (params->params.rsa.type == RSA_PKCS1_V1_5)
+ nla = tb[NCR_ATTR_RSA_ENCODING_METHOD];
+ if (nla == NULL) {
+ err();
+ return -EINVAL;
+ }
+ switch (nla_get_u32(nla)) {
+ case RSA_PKCS1_V1_5:
ctx->type = LTC_LTC_PKCS_1_V1_5;
- else if (params->params.rsa.type == RSA_PKCS1_OAEP) {
+ break;
+ case RSA_PKCS1_OAEP:
ctx->type = LTC_LTC_PKCS_1_OAEP;
- ctx->oaep_hash = _ncr_algo_to_properties(params->params.rsa.oaep_hash);
+ nla = tb[NCR_ATTR_RSA_OAEP_HASH_ALGORITHM];
+ ctx->oaep_hash = _ncr_nla_to_properties(nla);
if (ctx->oaep_hash == NULL) {
err();
return -EINVAL;
}
- } else if (params->params.rsa.type == RSA_PKCS1_PSS) {
+ break;
+ case RSA_PKCS1_PSS:
ctx->type = LTC_LTC_PKCS_1_PSS;
- } else {
+ nla = tb[NCR_ATTR_RSA_PSS_SALT_LENGTH];
+ if (nla != NULL)
+ ctx->salt_len = nla_get_u32(nla);
+ break;
+ default:
err();
return -EINVAL;
}
-
- ctx->salt_len = params->params.rsa.pss_salt;
break;
case NCR_ALG_DSA:
break;
@@ -543,30 +539,11 @@ fail:
return ret;
}
-int ncr_pk_cipher_sign(const struct ncr_pk_ctx* ctx,
- const struct scatterlist* isg, unsigned int isg_cnt, size_t isg_size,
- struct scatterlist *osg, unsigned int osg_cnt, size_t* osg_size)
+int ncr_pk_cipher_sign(const struct ncr_pk_ctx *ctx, const void *hash,
+ size_t hash_size, void *sig, size_t *sig_size)
{
-int cret, ret;
-unsigned long osize = *osg_size;
-uint8_t* tmp;
-void * input, *output;
-
- tmp = kmalloc(isg_size + *osg_size, GFP_KERNEL);
- if (tmp == NULL) {
- err();
- return -ENOMEM;
- }
-
- input = tmp;
- output = &tmp[isg_size];
-
- ret = sg_copy_to_buffer((struct scatterlist*)isg, isg_cnt, input, isg_size);
- if (ret != isg_size) {
- err();
- ret = -EINVAL;
- goto fail;
- }
+ int cret;
+ unsigned long osize = *sig_size;
switch(ctx->algorithm->algo) {
case NCR_ALG_RSA:
@@ -574,63 +551,35 @@ void * input, *output;
err();
return -EINVAL;
}
- cret = rsa_sign_hash_ex( input, isg_size, output, &osize,
+ cret = rsa_sign_hash_ex(hash, hash_size, sig, &osize,
ctx->type, ctx->sign_hash, ctx->salt_len, &ctx->key->key.pk.rsa);
if (cret != CRYPT_OK) {
err();
return _ncr_tomerr(cret);
}
- *osg_size = osize;
+ *sig_size = osize;
break;
case NCR_ALG_DSA:
- cret = dsa_sign_hash( input, isg_size, output, &osize,
+ cret = dsa_sign_hash(hash, hash_size, sig, &osize,
&ctx->key->key.pk.dsa);
if (cret != CRYPT_OK) {
err();
return _ncr_tomerr(cret);
}
- *osg_size = osize;
+ *sig_size = osize;
break;
default:
err();
- ret = -EINVAL;
- goto fail;
- }
-
- ret = sg_copy_from_buffer(osg, osg_cnt, output, *osg_size);
- if (ret != *osg_size) {
- err();
- ret = -EINVAL;
- goto fail;
+ return -EINVAL;
}
- ret = 0;
-fail:
- kfree(tmp);
-
- return ret;
+ return 0;
}
-int ncr_pk_cipher_verify(const struct ncr_pk_ctx* ctx,
- const struct scatterlist* sign_sg, unsigned int sign_sg_cnt, size_t sign_sg_size,
- const void* hash, size_t hash_size, ncr_error_t* err)
+int ncr_pk_cipher_verify(const struct ncr_pk_ctx* ctx, const void *sig,
+ size_t sig_size, const void *hash, size_t hash_size)
{
-int cret, ret;
-int stat = 0;
-uint8_t* sig;
-
- sig = kmalloc(sign_sg_size, GFP_KERNEL);
- if (sig == NULL) {
- err();
- return -ENOMEM;
- }
-
- ret = sg_copy_to_buffer((struct scatterlist*)sign_sg, sign_sg_cnt, sig, sign_sg_size);
- if (ret != sign_sg_size) {
- err();
- ret = -EINVAL;
- goto fail;
- }
+ int cret, ret, stat;
switch(ctx->algorithm->algo) {
case NCR_ALG_RSA:
@@ -638,35 +587,28 @@ uint8_t* sig;
err();
return -EINVAL;
}
- cret = rsa_verify_hash_ex( sig, sign_sg_size,
- hash, hash_size, ctx->type, ctx->sign_hash,
- ctx->salt_len, &stat, &ctx->key->key.pk.rsa);
+ cret = rsa_verify_hash_ex(sig, sig_size, hash,
+ hash_size, ctx->type,
+ ctx->sign_hash, ctx->salt_len,
+ &stat, &ctx->key->key.pk.rsa);
if (cret != CRYPT_OK) {
err();
ret = _ncr_tomerr(cret);
goto fail;
}
- if (stat == 1)
- *err = 0;
- else
- *err = NCR_VERIFICATION_FAILED;
-
+ ret = (stat == 1);
break;
case NCR_ALG_DSA:
- cret = dsa_verify_hash( sig, sign_sg_size,
- hash, hash_size, &stat, &ctx->key->key.pk.dsa);
+ cret = dsa_verify_hash(sig, sig_size, hash, hash_size,
+ &stat, &ctx->key->key.pk.dsa);
if (cret != CRYPT_OK) {
err();
ret = _ncr_tomerr(cret);
goto fail;
}
- if (stat == 1)
- *err = 0;
- else
- *err = NCR_VERIFICATION_FAILED;
-
+ ret = (stat == 1);
break;
default:
err();
@@ -674,9 +616,7 @@ uint8_t* sig;
goto fail;
}
- ret = 0;
fail:
- kfree(sig);
return ret;
}
diff --git a/ncr-pk.h b/ncr-pk.h
index ba35e45..fb9aba5 100644
--- a/ncr-pk.h
+++ b/ncr-pk.h
@@ -28,8 +28,9 @@ int ncr_pk_unpack( struct key_item_st * key, const void * packed, size_t packed_
/* encryption/decryption */
int ncr_pk_cipher_init(const struct algo_properties_st *algo,
- struct ncr_pk_ctx* ctx, struct ncr_key_params_st* params,
- struct key_item_st *key, const struct algo_properties_st *sign_hash);
+ struct ncr_pk_ctx* ctx, struct nlattr *tb[],
+ struct key_item_st *key,
+ const struct algo_properties_st *sign_hash);
void ncr_pk_cipher_deinit(struct ncr_pk_ctx* ctx);
int ncr_pk_cipher_encrypt(const struct ncr_pk_ctx* ctx,
@@ -40,13 +41,11 @@ int ncr_pk_cipher_decrypt(const struct ncr_pk_ctx* ctx,
const struct scatterlist* isg, unsigned int isg_cnt, size_t isg_size,
struct scatterlist *osg, unsigned int osg_cnt, size_t* osg_size);
-int ncr_pk_cipher_sign(const struct ncr_pk_ctx* ctx,
- const struct scatterlist* isg, unsigned int isg_cnt, size_t isg_size,
- struct scatterlist *osg, unsigned int osg_cnt, size_t* osg_size);
+int ncr_pk_cipher_sign(const struct ncr_pk_ctx *ctx, const void *hash,
+ size_t hash_size, void *sig, size_t *sig_size);
-int ncr_pk_cipher_verify(const struct ncr_pk_ctx* ctx,
- const struct scatterlist* sign_sg, unsigned int sign_sg_cnt, size_t sign_sg_size,
- const void* hash, size_t hash_size, ncr_error_t* err);
+int ncr_pk_cipher_verify(const struct ncr_pk_ctx* ctx, const void *sig,
+ size_t sig_size, const void *hash, size_t hash_size);
int _ncr_tomerr(int err);
diff --git a/ncr-sessions.c b/ncr-sessions.c
index 320a061..8f3e721 100644
--- a/ncr-sessions.c
+++ b/ncr-sessions.c
@@ -31,7 +31,8 @@
#include <linux/scatterlist.h>
#include <net/netlink.h>
-static int _ncr_session_update_key(struct ncr_lists* lists, struct ncr_session_op_st* op);
+static int _ncr_session_update_key(struct ncr_lists *lists, ncr_session_t ses,
+ struct nlattr *tb[]);
static void _ncr_session_remove(struct ncr_lists *lst, ncr_session_t desc);
static int session_list_deinit_fn(int id, void *item, void *unused)
@@ -222,8 +223,28 @@ const struct algo_properties_st *_ncr_nla_to_properties(const struct nlattr *nla
return _ncr_algo_to_properties(nla_get_u32(nla));
}
-static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* session)
+static int key_item_get_nla_read(struct key_item_st **st,
+ struct ncr_lists *lists,
+ const struct nlattr *nla)
{
+ int ret;
+
+ if (nla == NULL) {
+ err();
+ return -EINVAL;
+ }
+ ret = ncr_key_item_get_read(st, lists, nla_get_u32(nla));
+ if (ret < 0) {
+ err();
+ return ret;
+ }
+ return ret;
+}
+
+static int _ncr_session_init(struct ncr_lists *lists, ncr_crypto_op_t op,
+ struct nlattr *tb[])
+{
+ const struct nlattr *nla;
struct session_item_st* ns = NULL;
int ret;
const struct algo_properties_st *sign_hash;
@@ -234,15 +255,15 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
return -ENOMEM;
}
- ns->op = session->op;
- ns->algorithm = _ncr_algo_to_properties(session->algorithm);
+ ns->op = op;
+ ns->algorithm = _ncr_nla_to_properties(tb[NCR_ATTR_ALGORITHM]);
if (ns->algorithm == NULL) {
err();
ret = -EINVAL;
goto fail;
}
- switch(session->op) {
+ switch(op) {
case NCR_OP_ENCRYPT:
case NCR_OP_DECRYPT:
if (!ns->algorithm->can_encrypt) {
@@ -252,7 +273,8 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
}
/* read key */
- ret = ncr_key_item_get_read( &ns->key, lists, session->key);
+ ret = key_item_get_nla_read(&ns->key, lists,
+ tb[NCR_ATTR_KEY]);
if (ret < 0) {
err();
goto fail;
@@ -269,7 +291,7 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
if (ns->key->type == NCR_KEY_TYPE_SECRET) {
int keysize = ns->key->key.secret.size;
- if (session->algorithm == NCR_ALG_NULL)
+ if (ns->algorithm->algo == NCR_ALG_NULL)
keysize = 0;
if (ns->algorithm->kstr == NULL) {
@@ -286,16 +308,19 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
}
if (ns->algorithm->needs_iv) {
- if (session->params.params.cipher.iv_size > sizeof(session->params.params.cipher.iv)) {
+ nla = tb[NCR_ATTR_IV];
+ if (nla == NULL) {
err();
ret = -EINVAL;
goto fail;
}
- cryptodev_cipher_set_iv(&ns->cipher, session->params.params.cipher.iv, session->params.params.cipher.iv_size);
+ cryptodev_cipher_set_iv(&ns->cipher,
+ nla_data(nla),
+ nla_len(nla));
}
} else if (ns->key->type == NCR_KEY_TYPE_PRIVATE || ns->key->type == NCR_KEY_TYPE_PUBLIC) {
ret = ncr_pk_cipher_init(ns->algorithm, &ns->pk,
- &session->params, ns->key, NULL);
+ tb, ns->key, NULL);
if (ret < 0) {
err();
goto fail;
@@ -330,7 +355,8 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
} else {
/* read key */
- ret = ncr_key_item_get_read( &ns->key, lists, session->key);
+ ret = key_item_get_nla_read(&ns->key, lists,
+ tb[NCR_ATTR_KEY]);
if (ret < 0) {
err();
goto fail;
@@ -359,10 +385,11 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
}
} else if (ns->algorithm->is_pk && (ns->key->type == NCR_KEY_TYPE_PRIVATE || ns->key->type == NCR_KEY_TYPE_PUBLIC)) {
- sign_hash = ncr_key_params_get_sign_hash(ns->key->algorithm, &session->params);
- if (IS_ERR(sign_hash)) {
+ nla = tb[NCR_ATTR_SIGNATURE_HASH_ALGORITHM];
+ sign_hash = _ncr_nla_to_properties(nla);
+ if (sign_hash == NULL) {
err();
- ret = PTR_ERR(sign_hash);
+ ret = -EINVAL;
goto fail;
}
@@ -379,7 +406,7 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
}
ret = ncr_pk_cipher_init(ns->algorithm, &ns->pk,
- &session->params, ns->key, sign_hash);
+ tb, ns->key, sign_hash);
if (ret < 0) {
err();
goto fail;
@@ -404,8 +431,7 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
goto fail;
}
- ret = 0;
- session->ses = ns->desc;
+ ret = ns->desc;
fail:
if (ret < 0) {
@@ -416,29 +442,11 @@ fail:
return ret;
}
-int ncr_session_init(struct ncr_lists* lists, void __user* arg)
+int ncr_session_init(struct ncr_lists *lists,
+ const struct ncr_session_init *session,
+ struct nlattr *tb[])
{
- struct ncr_session_st session;
- int ret;
-
- if (unlikely(copy_from_user(&session, arg, sizeof(session)))) {
- err();
- return -EFAULT;
- }
-
- ret = _ncr_session_init(lists, &session);
- if (unlikely(ret)) {
- err();
- return ret;
- }
-
- ret = copy_to_user( arg, &session, sizeof(session));
- if (unlikely(ret)) {
- err();
- _ncr_session_remove(lists, session.ses);
- return -EFAULT;
- }
- return ret;
+ return _ncr_session_init(lists, session->op, tb);
}
static int _ncr_session_encrypt(struct session_item_st* sess, const struct scatterlist* input, unsigned input_cnt,
@@ -542,66 +550,64 @@ static int _ncr_session_grow_pages(struct session_item_st *ses, int pagecount)
return 0;
}
-/* Only the output buffer is given as scatterlist */
-static int get_userbuf1(struct session_item_st* ses,
- void __user * udata, size_t udata_size, struct scatterlist **dst_sg, unsigned *dst_cnt)
+/* Make NCR_ATTR_UPDATE_INPUT_DATA and NCR_ATTR_UPDATE_OUTPUT_BUFFER available
+ in scatterlists */
+static int get_userbuf2(struct session_item_st *ses, struct nlattr *tb[],
+ struct scatterlist **src_sg, unsigned *src_cnt,
+ size_t *src_size, struct ncr_session_output_buffer *dst,
+ struct scatterlist **dst_sg, unsigned *dst_cnt,
+ int compat)
{
- int pagecount = 0;
-
- if (unlikely(udata == NULL)) {
- err();
- return -EINVAL;
- }
+ const struct nlattr *src_nla, *dst_nla;
+ struct ncr_session_input_data src;
+ int src_pagecount, dst_pagecount = 0, pagecount, write_src = 1, ret;
+ size_t input_size;
- pagecount = PAGECOUNT(udata, udata_size);
- _ncr_session_grow_pages(ses, pagecount);
+ src_nla = tb[NCR_ATTR_UPDATE_INPUT_DATA];
+ dst_nla = tb[NCR_ATTR_UPDATE_OUTPUT_BUFFER];
- if (__get_userbuf(udata, udata_size, 1,
- pagecount, ses->pages, ses->sg)) {
+ ret = ncr_session_input_data_from_nla(&src, src_nla, compat);
+ if (unlikely(ret != 0)) {
err();
- return -EINVAL;
+ return ret;
}
- (*dst_sg) = ses->sg;
- *dst_cnt = pagecount;
+ *src_size = src.data_size;
- ses->available_pages = pagecount;
-
- return 0;
-}
-
-/* make op->data.udata.input and op->data.udata.output available in scatterlists */
-static int get_userbuf2(struct session_item_st* ses,
- struct ncr_session_op_st* op, struct scatterlist **src_sg,
- unsigned *src_cnt, struct scatterlist **dst_sg, unsigned *dst_cnt)
-{
- int src_pagecount, dst_pagecount = 0, pagecount, write_src = 1;
- size_t input_size = op->data.udata.input_size;
-
- if (unlikely(op->data.udata.input == NULL)) {
- err();
- return -EINVAL;
+ if (dst_nla != NULL) {
+ ret = ncr_session_output_buffer_from_nla(dst, dst_nla, compat);
+ if (unlikely(ret != 0)) {
+ err();
+ return ret;
+ }
}
- src_pagecount = PAGECOUNT(op->data.udata.input, input_size);
+ input_size = src.data_size;
+ src_pagecount = PAGECOUNT(src.data, input_size);
- if (op->data.udata.input != op->data.udata.output) { /* non-in-situ transformation */
+ if (dst_nla == NULL || src.data != dst->buffer) { /* non-in-situ transformation */
write_src = 0;
- if (op->data.udata.output != NULL) {
- dst_pagecount = PAGECOUNT(op->data.udata.output, op->data.udata.output_size);
+ if (dst_nla != NULL) {
+ dst_pagecount = PAGECOUNT(dst->buffer,
+ dst->buffer_size);
} else {
dst_pagecount = 0;
}
} else {
- src_pagecount = max((int)(PAGECOUNT(op->data.udata.output, op->data.udata.output_size)),
- src_pagecount);
- input_size = max(input_size, (size_t)op->data.udata.output_size);
+ src_pagecount = max((int)(PAGECOUNT(dst->buffer,
+ dst->buffer_size)),
+ src_pagecount);
+ input_size = max(input_size, dst->buffer_size);
}
pagecount = src_pagecount + dst_pagecount;
- _ncr_session_grow_pages(ses, pagecount);
+ ret = _ncr_session_grow_pages(ses, pagecount);
+ if (ret != 0) {
+ err();
+ return ret;
+ }
- if (__get_userbuf(op->data.udata.input, input_size, write_src,
- src_pagecount, ses->pages, ses->sg)) {
+ if (__get_userbuf((void __user *)src.data, input_size, write_src,
+ src_pagecount, ses->pages, ses->sg)) {
err();
printk("write: %d\n", write_src);
return -EINVAL;
@@ -613,14 +619,15 @@ static int get_userbuf2(struct session_item_st* ses,
*dst_cnt = dst_pagecount;
(*dst_sg) = ses->sg + src_pagecount;
- if (__get_userbuf(op->data.udata.output, op->data.udata.output_size, 1, dst_pagecount,
- ses->pages + src_pagecount, *dst_sg)) {
+ if (__get_userbuf(dst->buffer, dst->buffer_size, 1,
+ dst_pagecount, ses->pages + src_pagecount,
+ *dst_sg)) {
err();
release_user_pages(ses->pages, src_pagecount);
return -EINVAL;
}
} else {
- if (op->data.udata.output != NULL) {
+ if (dst_nla != NULL) {
*dst_cnt = src_pagecount;
(*dst_sg) = (*src_sg);
} else {
@@ -635,16 +642,18 @@ static int get_userbuf2(struct session_item_st* ses,
}
/* Called when userspace buffers are used */
-static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op)
+static int _ncr_session_update(struct ncr_lists *lists, ncr_session_t ses,
+ struct nlattr *tb[], int compat)
{
int ret;
struct session_item_st* sess;
- struct scatterlist *isg;
- struct scatterlist *osg;
+ struct scatterlist *isg = NULL;
+ struct scatterlist *osg = NULL;
unsigned osg_cnt=0, isg_cnt=0;
- size_t isg_size, osg_size;
+ size_t isg_size = 0, osg_size;
+ struct ncr_session_output_buffer out;
- sess = ncr_sessions_item_get(lists, op->ses);
+ sess = ncr_sessions_item_get(lists, ses);
if (sess == NULL) {
err();
return -EINVAL;
@@ -656,13 +665,12 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
return -ERESTARTSYS;
}
- ret = get_userbuf2(sess, op, &isg, &isg_cnt, &osg, &osg_cnt);
+ ret = get_userbuf2(sess, tb, &isg, &isg_cnt, &isg_size, &out, &osg,
+ &osg_cnt, compat);
if (ret < 0) {
err();
goto fail;
}
- isg_size = op->data.udata.input_size;
- osg_size = op->data.udata.output_size;
switch(sess->op) {
case NCR_OP_ENCRYPT:
@@ -672,6 +680,7 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
goto fail;
}
+ osg_size = out.buffer_size;
if (osg_size < isg_size) {
err();
ret = -EINVAL;
@@ -684,8 +693,13 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
err();
goto fail;
}
- op->data.udata.output_size = osg_size;
-
+
+ ret = ncr_session_output_buffer_set_size(&out, osg_size,
+ compat);
+ if (ret != 0) {
+ err();
+ goto fail;
+ }
break;
case NCR_OP_DECRYPT:
if (osg == NULL) {
@@ -694,6 +708,7 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
goto fail;
}
+ osg_size = out.buffer_size;
if (osg_size < isg_size) {
err();
ret = -EINVAL;
@@ -706,8 +721,13 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
err();
goto fail;
}
- op->data.udata.output_size = osg_size;
+ ret = ncr_session_output_buffer_set_size(&out, osg_size,
+ compat);
+ if (ret != 0) {
+ err();
+ goto fail;
+ }
break;
case NCR_OP_SIGN:
@@ -737,40 +757,34 @@ fail:
return ret;
}
-static int try_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op)
+static int try_session_update(struct ncr_lists *lists, ncr_session_t ses,
+ struct nlattr *tb[], int compat)
{
- if (op->type == NCR_KEY_DATA) {
- if (op->data.kdata.input != NCR_KEY_INVALID)
- return _ncr_session_update_key(lists, op);
- } else if (op->type == NCR_DIRECT_DATA) {
- if (op->data.udata.input != NULL)
- return _ncr_session_update(lists, op);
- }
+ if (tb[NCR_ATTR_UPDATE_INPUT_KEY_AS_DATA] != NULL)
+ return _ncr_session_update_key(lists, ses, tb);
+ else if (tb[NCR_ATTR_UPDATE_INPUT_DATA] != NULL)
+ return _ncr_session_update(lists, ses, tb, compat);
return 0;
}
-static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* op)
+static int _ncr_session_final(struct ncr_lists *lists, ncr_session_t ses,
+ struct nlattr *tb[], int compat)
{
+ const struct nlattr *nla;
int ret;
struct session_item_st* sess;
int digest_size;
uint8_t digest[NCR_HASH_MAX_OUTPUT_SIZE];
- uint8_t vdigest[NCR_HASH_MAX_OUTPUT_SIZE];
- struct scatterlist *osg;
- unsigned osg_cnt=0;
- size_t osg_size = 0;
- size_t orig_osg_size;
- void __user * udata = NULL;
- size_t *udata_size;
-
- sess = ncr_sessions_item_get(lists, op->ses);
+ void *buffer = NULL;
+
+ sess = ncr_sessions_item_get(lists, ses);
if (sess == NULL) {
err();
return -EINVAL;
}
- ret = try_session_update(lists, op);
+ ret = try_session_update(lists, ses, tb, compat);
if (ret < 0) {
err();
_ncr_sessions_item_put(sess);
@@ -782,129 +796,138 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st*
_ncr_sessions_item_put(sess);
return -ERESTARTSYS;
}
-
- if (op->type == NCR_DIRECT_DATA) {
- udata = op->data.udata.output;
- udata_size = &op->data.udata.output_size;
- } else if (op->type == NCR_KEY_DATA) {
- udata = op->data.kdata.output;
- udata_size = &op->data.kdata.output_size;
- } else {
- err();
- ret = -EINVAL;
- goto fail;
- }
switch(sess->op) {
- case NCR_OP_ENCRYPT:
- case NCR_OP_DECRYPT:
- break;
- case NCR_OP_VERIFY:
- ret = get_userbuf1(sess, udata, *udata_size, &osg, &osg_cnt);
+ case NCR_OP_ENCRYPT:
+ case NCR_OP_DECRYPT:
+ break;
+ case NCR_OP_VERIFY: {
+ struct ncr_session_input_data src;
+
+ nla = tb[NCR_ATTR_FINAL_INPUT_DATA];
+ ret = ncr_session_input_data_from_nla(&src, nla, compat);
+ if (unlikely(ret != 0)) {
+ err();
+ goto fail;
+ }
+
+ buffer = kmalloc(src.data_size, GFP_KERNEL);
+ if (buffer == NULL) {
+ err();
+ ret = -ENOMEM;
+ goto fail;
+ }
+ if (unlikely(copy_from_user(buffer, src.data, src.data_size))) {
+ err();
+ ret = -EFAULT;
+ goto fail;
+ }
+
+ digest_size = sess->hash.digestsize;
+ if (digest_size == 0 || sizeof(digest) < digest_size) {
+ err();
+ ret = -EINVAL;
+ goto fail;
+ }
+ ret = cryptodev_hash_final(&sess->hash, digest);
+ if (ret < 0) {
+ err();
+ goto fail;
+ }
+
+ if (!sess->algorithm->is_pk)
+ ret = (digest_size == src.data_size
+ && memcmp(buffer, digest, digest_size) == 0);
+ else {
+ ret = ncr_pk_cipher_verify(&sess->pk, buffer,
+ src.data_size, digest,
+ digest_size);
if (ret < 0) {
err();
goto fail;
}
- orig_osg_size = osg_size = *udata_size;
+ }
+ break;
+ }
- digest_size = sess->hash.digestsize;
- if (digest_size == 0 || sizeof(digest) < digest_size) {
- err();
- ret = -EINVAL;
- goto fail;
- }
- ret = cryptodev_hash_final(&sess->hash, digest);
- if (ret < 0) {
+ case NCR_OP_SIGN: {
+ struct ncr_session_output_buffer dst;
+ size_t output_size;
+
+ nla = tb[NCR_ATTR_FINAL_OUTPUT_BUFFER];
+ ret = ncr_session_output_buffer_from_nla(&dst, nla, compat);
+ if (unlikely(ret != 0)) {
+ err();
+ goto fail;
+ }
+
+ digest_size = sess->hash.digestsize;
+ if (digest_size == 0) {
+ err();
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ ret = cryptodev_hash_final(&sess->hash, digest);
+ if (ret < 0) {
+ err();
+ goto fail;
+ }
+
+ cryptodev_hash_deinit(&sess->hash);
+
+ if (!sess->algorithm->is_pk) {
+ if (dst.buffer_size < digest_size) {
err();
+ ret = -ERANGE;
goto fail;
}
-
- if (sess->algorithm->is_hmac) {
- ret = sg_copy_to_buffer(osg, osg_cnt, vdigest, digest_size);
- if (ret != digest_size) {
- err();
- ret = -EINVAL;
- goto fail;
- }
-
- if (digest_size != osg_size ||
- memcmp(vdigest, digest, digest_size) != 0) {
-
- op->err = NCR_VERIFICATION_FAILED;
- } else {
- op->err = NCR_SUCCESS;
- }
- } else {
- /* PK signature */
- ret = ncr_pk_cipher_verify(&sess->pk, osg, osg_cnt, osg_size,
- digest, digest_size, &op->err);
- if (ret < 0) {
- err();
- goto fail;
- }
- }
- break;
-
- case NCR_OP_SIGN:
- ret = get_userbuf1(sess, udata, *udata_size, &osg, &osg_cnt);
- if (ret < 0) {
+ if (unlikely(copy_to_user(dst.buffer, digest,
+ digest_size))) {
err();
+ ret = -EFAULT;
goto fail;
}
- orig_osg_size = osg_size = *udata_size;
-
- digest_size = sess->hash.digestsize;
- if (digest_size == 0 || osg_size < digest_size) {
+ output_size = digest_size;
+ } else {
+ output_size = dst.buffer_size;
+ buffer = kmalloc(output_size, GFP_KERNEL);
+ if (buffer == NULL) {
err();
- ret = -EINVAL;
+ ret = -ENOMEM;
goto fail;
}
-
- ret = cryptodev_hash_final(&sess->hash, digest);
+ ret = ncr_pk_cipher_sign(&sess->pk, digest, digest_size,
+ buffer, &output_size);
if (ret < 0) {
err();
goto fail;
}
-
- ret = sg_copy_from_buffer(osg, osg_cnt, digest, digest_size);
- if (ret != digest_size) {
+ if (unlikely(copy_to_user(dst.buffer, buffer,
+ output_size))) {
err();
- ret = -EINVAL;
+ ret = -EFAULT;
goto fail;
}
- osg_size = digest_size;
-
- cryptodev_hash_deinit(&sess->hash);
+ }
- if (sess->algorithm->is_pk) {
- /* PK signature */
-
- ret = ncr_pk_cipher_sign(&sess->pk, osg, osg_cnt, osg_size,
- osg, osg_cnt, &orig_osg_size);
- if (ret < 0) {
- err();
- goto fail;
- }
- osg_size = orig_osg_size;
- }
- break;
- default:
+ ret = ncr_session_output_buffer_set_size(&dst, output_size,
+ compat);
+ if (ret != 0) {
err();
- ret = -EINVAL;
goto fail;
+ }
+ break;
+ }
+ default:
+ err();
+ ret = -EINVAL;
+ goto fail;
}
-
- if (osg_size > 0)
- *udata_size = osg_size;
-
- ret = 0;
fail:
- if (sess->available_pages) {
- release_user_pages(sess->pages, sess->available_pages);
- sess->available_pages = 0;
- }
mutex_unlock(&sess->mem_mutex);
+ kfree(buffer);
cryptodev_hash_deinit(&sess->hash);
if (sess->algorithm->is_symmetric) {
@@ -914,27 +937,28 @@ fail:
}
_ncr_sessions_item_put(sess);
- _ncr_session_remove(lists, op->ses);
+ _ncr_session_remove(lists, ses);
return ret;
}
/* Direct with key: Allows to hash a key */
-/* Called when userspace buffers are used */
-static int _ncr_session_update_key(struct ncr_lists* lists, struct ncr_session_op_st* op)
+static int _ncr_session_update_key(struct ncr_lists *lists, ncr_session_t ses,
+ struct nlattr *tb[])
{
int ret;
struct session_item_st* sess;
struct key_item_st* key = NULL;
- sess = ncr_sessions_item_get(lists, op->ses);
+ sess = ncr_sessions_item_get(lists, ses);
if (sess == NULL) {
err();
return -EINVAL;
}
/* read key */
- ret = ncr_key_item_get_read( &key, lists, op->data.kdata.input);
+ ret = key_item_get_nla_read(&key, lists,
+ tb[NCR_ATTR_UPDATE_INPUT_KEY_AS_DATA]);
if (ret < 0) {
err();
goto fail;
@@ -976,20 +1000,16 @@ fail:
return ret;
}
-int ncr_session_update(struct ncr_lists* lists, void __user* arg)
+int ncr_session_update(struct ncr_lists *lists,
+ const struct ncr_session_update *op, struct nlattr *tb[],
+ int compat)
{
- struct ncr_session_op_st op;
int ret;
- if (unlikely(copy_from_user( &op, arg, sizeof(op)))) {
- err();
- return -EFAULT;
- }
-
- if (op.type == NCR_DIRECT_DATA)
- ret = _ncr_session_update(lists, &op);
- else if (op.type == NCR_KEY_DATA)
- ret = _ncr_session_update_key(lists, &op);
+ if (tb[NCR_ATTR_UPDATE_INPUT_DATA] != NULL)
+ ret = _ncr_session_update(lists, op->ses, tb, compat);
+ else if (tb[NCR_ATTR_UPDATE_INPUT_KEY_AS_DATA] != NULL)
+ ret = _ncr_session_update_key(lists, op->ses, tb);
else
ret = -EINVAL;
@@ -998,61 +1018,33 @@ int ncr_session_update(struct ncr_lists* lists, void __user* arg)
return ret;
}
- if (unlikely(copy_to_user(arg, &op, sizeof(op)))) {
- err();
- return -EFAULT;
- }
-
return 0;
}
-int ncr_session_final(struct ncr_lists* lists, void __user* arg)
+int ncr_session_final(struct ncr_lists *lists,
+ const struct ncr_session_final *op, struct nlattr *tb[],
+ int compat)
{
- struct ncr_session_op_st op;
- int ret;
-
- if (unlikely(copy_from_user(&op, arg, sizeof(op)))) {
- err();
- return -EFAULT;
- }
-
- ret = _ncr_session_final(lists, &op);
- if (unlikely(ret)) {
- err();
- return ret;
- }
-
- if (unlikely(copy_to_user(arg, &op, sizeof(op)))) {
- err();
- return -EFAULT;
- }
- return 0;
+ return _ncr_session_final(lists, op->ses, tb, compat);
}
-int ncr_session_once(struct ncr_lists* lists, void __user* arg)
+int ncr_session_once(struct ncr_lists *lists,
+ const struct ncr_session_once *once, struct nlattr *tb[],
+ int compat)
{
- struct ncr_session_once_op_st kop;
int ret;
- if (unlikely(copy_from_user(&kop, arg, sizeof(kop)))) {
- err();
- return -EFAULT;
- }
-
- ret = _ncr_session_init(lists, &kop.init);
+ ret = _ncr_session_init(lists, once->op, tb);
if (ret < 0) {
err();
return ret;
}
- kop.op.ses = kop.init.ses;
- ret = _ncr_session_final(lists, &kop.op);
+ ret = _ncr_session_final(lists, ret, tb, compat);
if (ret < 0) {
err();
return ret;
}
- if (unlikely(copy_to_user(arg, &kop, sizeof(kop))))
- return -EFAULT;
- return 0;
+ return ret;
}
diff --git a/ncr.c b/ncr.c
index 1bee991..54047cb 100644
--- a/ncr.c
+++ b/ncr.c
@@ -32,6 +32,7 @@
#include <linux/scatterlist.h>
#include <linux/cred.h>
#include <linux/capability.h>
+#include <net/netlink.h>
#include "ncr.h"
#include "ncr-int.h"
#include "utils.h"
@@ -129,7 +130,7 @@ ncr_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_)
BUG();
switch (cmd) {
-#define CASE_NO_OUTPUT(LABEL, STRUCT, FUNCTION) \
+#define CASE_(LABEL, STRUCT, FUNCTION, ARGS) \
case (LABEL): { \
struct STRUCT data; \
\
@@ -138,9 +139,13 @@ ncr_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_)
err(); \
return PTR_ERR(attr_buf); \
} \
- ret = (FUNCTION)(lst, &data, tb); \
+ ret = (FUNCTION)ARGS; \
break; \
}
+#define CASE_NO_OUTPUT(LABEL, STRUCT, FUNCTION) \
+ CASE_(LABEL, STRUCT, FUNCTION, (lst, &data, tb))
+#define CASE_NO_OUTPUT_COMPAT(LABEL, STRUCT, FUNCTION) \
+ CASE_(LABEL, STRUCT, FUNCTION, (lst, &data, tb, 0))
case NCRIO_KEY_INIT:
return ncr_key_init(lst);
@@ -184,20 +189,21 @@ ncr_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_)
ncr_key_storage_wrap);
CASE_NO_OUTPUT(NCRIO_KEY_STORAGE_UNWRAP, ncr_key_storage_unwrap,
ncr_key_storage_unwrap);
- case NCRIO_SESSION_INIT:
- return ncr_session_init(lst, arg);
- case NCRIO_SESSION_UPDATE:
- return ncr_session_update(lst, arg);
- case NCRIO_SESSION_FINAL:
- return ncr_session_final(lst, arg);
- case NCRIO_SESSION_ONCE:
- return ncr_session_once(lst, arg);
+ CASE_NO_OUTPUT(NCRIO_SESSION_INIT, ncr_session_init, ncr_session_init);
+ CASE_NO_OUTPUT_COMPAT(NCRIO_SESSION_UPDATE, ncr_session_update,
+ ncr_session_update);
+ CASE_NO_OUTPUT_COMPAT(NCRIO_SESSION_FINAL, ncr_session_final,
+ ncr_session_final);
+ CASE_NO_OUTPUT_COMPAT(NCRIO_SESSION_ONCE, ncr_session_once,
+ ncr_session_once);
case NCRIO_MASTER_KEY_SET:
return ncr_master_key_set(arg);
default:
return -EINVAL;
+#undef CASE_
#undef CASE_NO_OUTPUT
+#undef CASE_NO_OUTPUT_COMPAT
}
kfree(attr_buf);
return ret;
@@ -330,6 +336,7 @@ ncr_compat_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_)
case NCRIO_KEY_DERIVE:
case NCRIO_KEY_GET_INFO:
case NCRIO_KEY_DEINIT:
+ case NCRIO_SESSION_INIT:
return ncr_ioctl(lst, cmd, arg_);
#define CASE_NO_OUTPUT(LABEL, STRUCT, FUNCTION) \
@@ -347,6 +354,19 @@ ncr_compat_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_)
break; \
}
+#define CASE_COMPAT_ONLY(LABEL, STRUCT, FUNCTION) \
+ case (LABEL): { \
+ struct STRUCT data; \
+ \
+ attr_buf = NCR_GET_INPUT_ARGS_NO_OUTPUT(&data, tb, arg); \
+ if (IS_ERR(attr_buf)) { \
+ err(); \
+ return PTR_ERR(attr_buf); \
+ } \
+ ret = (FUNCTION)(lst, &data, tb, 1); \
+ break; \
+ }
+
CASE_NO_OUTPUT(COMPAT_NCRIO_KEY_EXPORT, ncr_key_export, ncr_key_export);
CASE_NO_OUTPUT(COMPAT_NCRIO_KEY_IMPORT, ncr_key_import, ncr_key_import);
CASE_NO_OUTPUT(COMPAT_NCRIO_KEY_WRAP, ncr_key_wrap, ncr_key_wrap);
@@ -355,11 +375,88 @@ ncr_compat_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_)
ncr_key_storage_wrap);
CASE_NO_OUTPUT(COMPAT_NCRIO_KEY_STORAGE_UNWRAP, ncr_key_storage_unwrap,
ncr_key_storage_unwrap);
+ CASE_COMPAT_ONLY(NCRIO_SESSION_UPDATE, ncr_session_update,
+ ncr_session_update);
+ CASE_COMPAT_ONLY(NCRIO_SESSION_FINAL, ncr_session_final,
+ ncr_session_final);
+ CASE_COMPAT_ONLY(NCRIO_SESSION_ONCE, ncr_session_once,
+ ncr_session_once);
default:
return -EINVAL;
#undef CASE_NO_OUTPUT
+#undef CASE_COMPAT_ONLY
}
kfree(attr_buf);
return ret;
}
#endif
+
+int ncr_session_input_data_from_nla(struct ncr_session_input_data *dest,
+ const struct nlattr *nla, int compat)
+{
+ if (unlikely(nla == NULL))
+ return -EINVAL;
+#ifdef CONFIG_COMPAT
+ if (!compat) {
+#endif
+ if (unlikely(nla_len(nla) < sizeof(dest)))
+ return -ERANGE; /* nla_validate would return -ERANGE. */
+ memcpy(dest, nla_data(nla), sizeof(*dest));
+#ifdef CONFIG_COMPAT
+ } else {
+ struct compat_ncr_session_input_data old;
+
+ if (unlikely(nla_len(nla) < sizeof(old)))
+ return -ERANGE;
+ memcpy(&old, nla_data(nla), sizeof(old));
+ dest->data = compat_ptr(old.data);
+ dest->data_size = old.data_size;
+ }
+#endif
+ return 0;
+}
+
+int ncr_session_output_buffer_from_nla(struct ncr_session_output_buffer *dest,
+ const struct nlattr *nla, int compat)
+{
+ if (unlikely(nla == NULL))
+ return -EINVAL;
+#ifdef CONFIG_COMPAT
+ if (!compat) {
+#endif
+ if (unlikely(nla_len(nla) < sizeof(dest)))
+ return -ERANGE; /* nla_validate would return -ERANGE. */
+ memcpy(dest, nla_data(nla), sizeof(*dest));
+#ifdef CONFIG_COMPAT
+ } else {
+ struct compat_ncr_session_output_buffer old;
+
+ if (unlikely(nla_len(nla) < sizeof(old)))
+ return -ERANGE;
+ memcpy(&old, nla_data(nla), sizeof(old));
+ dest->buffer = compat_ptr(old.buffer);
+ dest->buffer_size = old.buffer_size;
+ dest->result_size_ptr = compat_ptr(old.result_size_ptr);
+ }
+#endif
+ return 0;
+}
+
+
+int ncr_session_output_buffer_set_size(const struct ncr_session_output_buffer *dest,
+ size_t size, int compat)
+{
+#ifdef CONFIG_COMPAT
+ if (!compat)
+#endif
+ return put_user(size, dest->result_size_ptr);
+#ifdef CONFIG_COMPAT
+ else {
+ compat_size_t old;
+
+ old = size;
+ return put_user(old,
+ (compat_size_t __user *)dest->result_size_ptr);
+ }
+#endif
+}
diff --git a/ncr.h b/ncr.h
index 46cf8cb..f1db01f 100644
--- a/ncr.h
+++ b/ncr.h
@@ -33,7 +33,16 @@ enum {
/* FIXME: Use NLA_STRING for this, later */
NCR_ATTR_ALGORITHM, /* NLA_U32 - ncr_algorithm_t */
NCR_ATTR_DERIVATION_ALGORITHM, /* NLA_U32 - ncr_algorithm_t */
+ NCR_ATTR_SIGNATURE_HASH_ALGORITHM, /* NLA_U32 - ncr_algorithm_t */
NCR_ATTR_WRAPPING_ALGORITHM, /* NLA_U32 - ncr_wrap_algorithm_t */
+ NCR_ATTR_UPDATE_INPUT_DATA, /* NLA_BINARY - ncr_session_input_data */
+ /* NLA_BINARY - ncr_session_output_buffer */
+ NCR_ATTR_UPDATE_OUTPUT_BUFFER,
+ NCR_ATTR_UPDATE_INPUT_KEY_AS_DATA, /* NLA_U32 - ncr_key_t */
+ NCR_ATTR_FINAL_INPUT_DATA, /* NLA_BINARY - ncr_session_input_data */
+ /* NLA_BINARY - ncr_session_output_buffer */
+ NCR_ATTR_FINAL_OUTPUT_BUFFER,
+ NCR_ATTR_KEY, /* NLA_U32 - ncr_key_t */
NCR_ATTR_KEY_FLAGS, /* NLA_U32 - NCR_KEY_FLAG_* */
NCR_ATTR_KEY_ID, /* NLA_BINARY */
NCR_ATTR_KEY_TYPE, /* NLA_U32 - ncr_key_type_t */
@@ -41,6 +50,9 @@ enum {
NCR_ATTR_SECRET_KEY_BITS, /* NLA_U32 */
NCR_ATTR_RSA_MODULUS_BITS, /* NLA_U32 */
NCR_ATTR_RSA_E, /* NLA_BINARY */
+ NCR_ATTR_RSA_ENCODING_METHOD, /* NLA_U32 - ncr_rsa_type_t */
+ NCR_ATTR_RSA_OAEP_HASH_ALGORITHM, /* NLA_U32 - ncr_algorithm_t */
+ NCR_ATTR_RSA_PSS_SALT_LENGTH, /* NLA_U32 */
NCR_ATTR_DSA_P_BITS, /* NLA_U32 */
NCR_ATTR_DSA_Q_BITS, /* NLA_U32 */
NCR_ATTR_DH_PRIME, /* NLA_BINARY */
@@ -142,29 +154,6 @@ typedef enum {
RSA_PKCS1_PSS, /* for signatures only */
} ncr_rsa_type_t;
-/* used in encryption
- */
-struct ncr_key_params_st {
- /* this structure always corresponds to a key. Hence the
- * parameters of the union selected are based on the corresponding
- * key */
- union {
- struct {
- __u8 iv[NCR_CIPHER_MAX_BLOCK_LEN];
- __kernel_size_t iv_size;
- } cipher;
- struct {
- ncr_rsa_type_t type;
- ncr_algorithm_t oaep_hash; /* for OAEP */
- ncr_algorithm_t sign_hash; /* for signatures */
- unsigned int pss_salt; /* PSS signatures */
- } rsa;
- struct {
- ncr_algorithm_t sign_hash; /* for signatures */
- } dsa;
- } params;
-};
-
typedef enum {
NCR_DERIVE_DH=1,
} ncr_derive_t;
@@ -283,65 +272,46 @@ typedef enum {
typedef __s32 ncr_session_t;
#define NCR_SESSION_INVALID ((ncr_session_t)-1)
-/* input of CIOCGSESSION */
-struct ncr_session_st {
- /* input */
- ncr_algorithm_t algorithm;
-
- ncr_key_t key;
- struct ncr_key_params_st params;
- ncr_crypto_op_t op;
-
- /* output */
- ncr_session_t ses; /* session identifier */
+struct ncr_session_input_data {
+ const void __user *data;
+ __kernel_size_t data_size;
};
-typedef enum {
- NCR_SUCCESS = 0,
- NCR_ERROR_GENERIC = -1,
- NCR_VERIFICATION_FAILED = -2,
-} ncr_error_t;
+struct ncr_session_output_buffer {
+ void __user *buffer;
+ __kernel_size_t buffer_size;
+ __kernel_size_t __user *result_size_ptr;
+};
-typedef enum {
- NCR_KEY_DATA,
- NCR_DIRECT_DATA,
-} ncr_data_type_t;
+struct ncr_session_init {
+ __u32 input_size, output_size;
+ __u32 op; /* ncr_crypto_op_t */
+ __NL_ATTRIBUTES;
+};
-struct ncr_session_op_st {
- /* input */
+struct ncr_session_update {
+ __u32 input_size, output_size;
ncr_session_t ses;
+ __NL_ATTRIBUTES;
+};
- union {
- struct {
- ncr_key_t input;
- void __user * output; /* when verifying signature this is
- * the place of the signature.
- */
- __kernel_size_t output_size;
- } kdata; /* NCR_KEY_DATA */
- struct {
- void __user * input;
- __kernel_size_t input_size;
- void __user * output;
- __kernel_size_t output_size;
- } udata; /* NCR_DIRECT_DATA */
- } data;
- ncr_data_type_t type;
-
- /* output of verification */
- ncr_error_t err;
+struct ncr_session_final {
+ __u32 input_size, output_size;
+ ncr_session_t ses;
+ __NL_ATTRIBUTES;
};
-struct ncr_session_once_op_st {
- struct ncr_session_st init;
- struct ncr_session_op_st op;
+struct ncr_session_once {
+ __u32 input_size, output_size;
+ ncr_crypto_op_t op;
+ __NL_ATTRIBUTES;
};
-#define NCRIO_SESSION_INIT _IOR ('c', 300, struct ncr_session_st)
-#define NCRIO_SESSION_UPDATE _IOWR ('c', 301, struct ncr_session_op_st)
-#define NCRIO_SESSION_FINAL _IOWR ('c', 302, struct ncr_session_op_st)
+#define NCRIO_SESSION_INIT _IOWR('c', 300, struct ncr_session_init)
+#define NCRIO_SESSION_UPDATE _IOWR('c', 301, struct ncr_session_update)
+#define NCRIO_SESSION_FINAL _IOWR('c', 302, struct ncr_session_final)
/* everything in one call */
-#define NCRIO_SESSION_ONCE _IOWR ('c', 303, struct ncr_session_once_op_st)
+#define NCRIO_SESSION_ONCE _IOWR('c', 303, struct ncr_session_once)
#endif
diff --git a/utils.c b/utils.c
index 1ae66fc..8118a1d 100644
--- a/utils.c
+++ b/utils.c
@@ -28,10 +28,44 @@
#include "ncr-int.h"
#include "utils.h"
+#ifdef CONFIG_COMPAT
+/* max() is too clever for compile-time constants */
+#define CONST_MAX(A, B) ((A) > (B) ? (A) : (B))
+
+#define MAX_SESSION_INPUT_DATA_SIZE \
+ (CONST_MAX(sizeof(struct ncr_session_input_data), \
+ sizeof(struct compat_ncr_session_input_data)))
+#define MAX_SESSION_OUTPUT_BUFFER_SIZE \
+ (CONST_MAX(sizeof(struct ncr_session_output_buffer), \
+ sizeof(struct compat_ncr_session_output_buffer)))
+
+#else /* !CONFIG_COMPAT */
+
+#define MAX_SESSION_INPUT_DATA_SIZE (sizeof(struct ncr_session_input_data))
+#define MAX_SESSION_OUTPUT_BUFFER_SIZE \
+ (sizeof(struct ncr_session_output_buffer))
+
+#endif /* !CONFIG_COMPAT */
+
static const struct nla_policy ncr_attr_policy[NCR_ATTR_MAX + 1] = {
[NCR_ATTR_ALGORITHM] = { NLA_U32, 0 },
[NCR_ATTR_DERIVATION_ALGORITHM] = { NLA_U32, 0 },
+ [NCR_ATTR_SIGNATURE_HASH_ALGORITHM] = { NLA_U32, 0 },
[NCR_ATTR_WRAPPING_ALGORITHM] = { NLA_U32, 0 },
+ [NCR_ATTR_UPDATE_INPUT_DATA] = {
+ NLA_BINARY, MAX_SESSION_INPUT_DATA_SIZE
+ },
+ [NCR_ATTR_UPDATE_OUTPUT_BUFFER] = {
+ NLA_BINARY, MAX_SESSION_OUTPUT_BUFFER_SIZE
+ },
+ [NCR_ATTR_UPDATE_INPUT_KEY_AS_DATA] = { NLA_U32, 0 },
+ [NCR_ATTR_FINAL_INPUT_DATA] = {
+ NLA_BINARY, MAX_SESSION_INPUT_DATA_SIZE
+ },
+ [NCR_ATTR_FINAL_OUTPUT_BUFFER] = {
+ NLA_BINARY, MAX_SESSION_OUTPUT_BUFFER_SIZE
+ },
+ [NCR_ATTR_KEY] = { NLA_U32, 0 },
[NCR_ATTR_KEY_FLAGS] = { NLA_U32, 0 },
[NCR_ATTR_KEY_ID] = { NLA_BINARY, 0 },
[NCR_ATTR_KEY_TYPE] = { NLA_U32, 0 },
@@ -39,6 +73,9 @@ static const struct nla_policy ncr_attr_policy[NCR_ATTR_MAX + 1] = {
[NCR_ATTR_SECRET_KEY_BITS] = { NLA_U32, 0 },
[NCR_ATTR_RSA_MODULUS_BITS] = { NLA_U32, 0 },
[NCR_ATTR_RSA_E] = { NLA_BINARY, 0 },
+ [NCR_ATTR_RSA_ENCODING_METHOD] = { NLA_U32, 0 },
+ [NCR_ATTR_RSA_OAEP_HASH_ALGORITHM] = { NLA_U32, 0 },
+ [NCR_ATTR_RSA_PSS_SALT_LENGTH] = { NLA_U32, 0 },
[NCR_ATTR_DSA_P_BITS] = { NLA_U32, 0 },
[NCR_ATTR_DSA_Q_BITS] = { NLA_U32, 0 },
[NCR_ATTR_DH_PRIME] = { NLA_BINARY, 0 },