Harald Freudenberger
8 years ago
Signed-off-by: Harald Freudenberger <***@linux.vnet.ibm.com>
---
testcases/pkcs11/Makefile.am | 3 +-
testcases/pkcs11/sess_opstate.c | 266 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 268 insertions(+), 1 deletion(-)
create mode 100644 testcases/pkcs11/sess_opstate.c
diff --git a/testcases/pkcs11/Makefile.am b/testcases/pkcs11/Makefile.am
index a7488ad..04fe127 100644
--- a/testcases/pkcs11/Makefile.am
+++ b/testcases/pkcs11/Makefile.am
@@ -1,4 +1,4 @@
-noinst_PROGRAMS=hw_fn sess_mgmt_tests sess_bench attribute findobjects destroyobjects copyobjects generate_keypair gen_purpose getobjectsize
+noinst_PROGRAMS=hw_fn sess_mgmt_tests sess_bench sess_opstate attribute findobjects destroyobjects copyobjects generate_keypair gen_purpose getobjectsize
AM_CFLAGS=-I. -I../../usr/include/pkcs11 -I../include -I../common -I../../usr/lib/pkcs11/common -Wall
@@ -7,6 +7,7 @@ AM_LDFLAGS=-L../common -lc -ldl -lpthread -lcommon
hw_fn_SOURCES = hw_fn.c
sess_mgmt_tests_SOURCES = sess_mgmt.c
sess_bench_SOURCES = sess_perf.c
+sess_opstate_SOURCES = sess_opstate.c
attribute_SOURCES = attribute.c
findobjects_SOURCES = findobjects.c
destroyobjects_SOURCES = destroyobjects.c
diff --git a/testcases/pkcs11/sess_opstate.c b/testcases/pkcs11/sess_opstate.c
new file mode 100644
index 0000000..8ae0db4
--- /dev/null
+++ b/testcases/pkcs11/sess_opstate.c
@@ -0,0 +1,266 @@
+/*
+ * Testcase for
+ * C_GetOperationState / C_SetOperationState
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <time.h>
+
+#include "pkcs11types.h"
+#include "regress.h"
+#include "common.c"
+
+
+CK_BYTE_PTR alloc_random_buf(CK_SESSION_HANDLE sess, CK_LONG nbytes)
+{
+ CK_RV rc;
+ CK_BYTE_PTR ptr = malloc(nbytes);
+ if (ptr == NULL) {
+ testcase_error("malloc(%lu) failed", nbytes);
+ return NULL;
+ }
+ rc = funcs->C_GenerateRandom(sess, ptr, nbytes);
+ if (rc != CKR_OK) {
+ testcase_error("C_GenerateRandom() rc=%s", p11_get_ckr(rc));
+ free(ptr);
+ return NULL;
+ }
+ return ptr;
+}
+
+
+int sess_opstate_funcs(int loops)
+{
+ CK_SESSION_HANDLE s1, s2;
+ CK_SLOT_ID slot_id = SLOT_ID;
+ CK_ULONG flags;
+ CK_RV rc;
+ int i, counter, rbytes;
+ CK_BYTE *rdata = NULL;
+ CK_MECHANISM mech1 = {CKM_SHA256, 0, 0};
+ CK_MECHANISM mech2 = {CKM_SHA_1, 0, 0};
+ CK_ULONG r1hlen, r2hlen, hlen;
+ CK_BYTE r1hash[32], r2hash[32], hash[32];
+ CK_ULONG opstatelen;
+ CK_BYTE *opstate = NULL;
+
+ // open 2 sessions
+ flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
+ rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &s1);
+ if (rc != CKR_OK) {
+ testcase_error("C_OpenSession() rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &s2);
+ if (rc != CKR_OK) {
+ testcase_error("C_OpenSession() rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // init digest for both sessions
+ rc = funcs->C_DigestInit(s1, &mech1);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestInit rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ rc = funcs->C_DigestInit(s2, &mech1);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestInit rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // now loop over some digest updates
+ for (counter = 0; counter < loops; counter ++) {
+
+ // create some random data
+ rbytes = random() % sizeof(rdata);
+ rdata = alloc_random_buf(s1, rbytes);
+ if (!rdata) goto out;
+
+ // digest update on session 1
+ rc = funcs->C_DigestUpdate(s1, rdata, rbytes);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestUpdate rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // restore op state on session 2
+ if (opstate != NULL) {
+ rc = funcs->C_SetOperationState(s2, opstate, opstatelen, 0, 0);
+ if (rc != CKR_OK) {
+ testcase_error("C_SetOperationState rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ free(opstate);
+ opstate = NULL;
+ }
+
+ // digest update on session 2
+ rc = funcs->C_DigestUpdate(s2, rdata, rbytes);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestUpdate rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // fetch op state on session 2
+ opstatelen = 0;
+ rc = funcs->C_GetOperationState(s2, NULL, &opstatelen);
+ if (rc != CKR_OK) {
+ testcase_error("C_GetOperationState rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ opstate = malloc(opstatelen);
+ if (opstate == NULL) {
+ testcase_error("malloc(%lu) failed", opstatelen);
+ goto out;
+ }
+ rc = funcs->C_GetOperationState(s2, opstate, &opstatelen);
+ if (rc != CKR_OK) {
+ testcase_error("C_GetOperationState rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ free(rdata);
+ rdata = NULL;
+
+ // now do something different on session 2, but first
+ // we have to wipe out the started digest operation
+
+ hlen = sizeof(hash);
+ rc = funcs->C_DigestFinal(s2, hash, &hlen);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestFinal rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // so now let's do a digest init/update/finish
+ // to randomize the memory a little
+
+ rc = funcs->C_DigestInit(s2, &mech2);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestInit rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ for (i = 0; i < loops; i++) {
+ rbytes = random() % sizeof(rdata);
+ rdata = alloc_random_buf(s1, rbytes);
+ if (!rdata) goto out;
+ rc = funcs->C_DigestUpdate(s2, rdata, rbytes);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestUpdate rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ free(rdata);
+ rdata = NULL;
+ }
+ hlen = sizeof(hash);
+ rc = funcs->C_DigestFinal(s2, hash, &hlen);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestFinal rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ }
+
+ // restore op state on session 2
+ rc = funcs->C_SetOperationState(s2, opstate, opstatelen, 0, 0);
+ if (rc != CKR_OK) {
+ testcase_error("C_SetOperationState rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // digest finish
+ r1hlen = sizeof(r1hash);
+ rc = funcs->C_DigestFinal(s1, r1hash, &r1hlen);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestFinal rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ r2hlen = sizeof(r2hash);
+ rc = funcs->C_DigestFinal(s2, r2hash, &r2hlen);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestFinal rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // check both hashes
+ if (r1hlen != r2hlen) {
+ testcase_fail("hash length differ");
+ goto out;
+ }
+ if (memcmp(r1hash, r2hash, r1hlen) != 0) {
+ testcase_fail("hash values differs");
+ goto out;
+ }
+
+ testcase_pass("Get/SetOperationState digest test");
+
+out:
+ if (opstate) free(opstate);
+ if (rdata) free(rdata);
+ funcs->C_CloseAllSessions(slot_id);
+ return rc;
+}
+
+
+int main(int argc, char **argv)
+{
+ CK_C_INITIALIZE_ARGS cinit_args;
+ int rc, i, j, loops = 0;
+ CK_RV rv;
+
+ SLOT_ID = 0;
+ no_init = FALSE;
+
+ srandom(time(0));
+
+ for (i=0; i < argc; i++) {
+ if (strncmp(argv[i], "loops=", 6) == 0) {
+ sscanf(argv[i]+6, "%i", &loops);
+ for (j=i; j < argc; j++)
+ argv[j] = argv[j+1];
+ argc--;
+ }
+ }
+ if (loops < 1) loops = 100;
+
+ rc = do_ParseArgs(argc, argv);
+ if (rc != 1)
+ return rc;
+
+ printf("Using slot #%lu...\n\n", SLOT_ID );
+ printf("With option: no_init: %d\n", no_init);
+ printf("Running %d loops...\n", loops );
+
+ rc = do_GetFunctionList();
+ if (!rc) {
+ PRINT_ERR("ERROR do_GetFunctionList() Failed , rc = 0x%0x\n", rc);
+ return rc;
+ }
+
+ memset( &cinit_args, 0x0, sizeof(cinit_args) );
+ cinit_args.flags = CKF_OS_LOCKING_OK;
+
+ funcs->C_Initialize( &cinit_args );
+
+ {
+ CK_SESSION_HANDLE hsess = 0;
+
+ rc = funcs->C_GetFunctionStatus(hsess);
+ if (rc != CKR_FUNCTION_NOT_PARALLEL)
+ return rc;
+
+ rc = funcs->C_CancelFunction(hsess);
+ if (rc != CKR_FUNCTION_NOT_PARALLEL)
+ return rc;
+
+ }
+
+ rv = sess_opstate_funcs(loops);
+
+ /* make sure we return non-zero if rv is non-zero */
+ return ((rv==0) || (rv % 256) ? rv : -1);
+}
---
testcases/pkcs11/Makefile.am | 3 +-
testcases/pkcs11/sess_opstate.c | 266 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 268 insertions(+), 1 deletion(-)
create mode 100644 testcases/pkcs11/sess_opstate.c
diff --git a/testcases/pkcs11/Makefile.am b/testcases/pkcs11/Makefile.am
index a7488ad..04fe127 100644
--- a/testcases/pkcs11/Makefile.am
+++ b/testcases/pkcs11/Makefile.am
@@ -1,4 +1,4 @@
-noinst_PROGRAMS=hw_fn sess_mgmt_tests sess_bench attribute findobjects destroyobjects copyobjects generate_keypair gen_purpose getobjectsize
+noinst_PROGRAMS=hw_fn sess_mgmt_tests sess_bench sess_opstate attribute findobjects destroyobjects copyobjects generate_keypair gen_purpose getobjectsize
AM_CFLAGS=-I. -I../../usr/include/pkcs11 -I../include -I../common -I../../usr/lib/pkcs11/common -Wall
@@ -7,6 +7,7 @@ AM_LDFLAGS=-L../common -lc -ldl -lpthread -lcommon
hw_fn_SOURCES = hw_fn.c
sess_mgmt_tests_SOURCES = sess_mgmt.c
sess_bench_SOURCES = sess_perf.c
+sess_opstate_SOURCES = sess_opstate.c
attribute_SOURCES = attribute.c
findobjects_SOURCES = findobjects.c
destroyobjects_SOURCES = destroyobjects.c
diff --git a/testcases/pkcs11/sess_opstate.c b/testcases/pkcs11/sess_opstate.c
new file mode 100644
index 0000000..8ae0db4
--- /dev/null
+++ b/testcases/pkcs11/sess_opstate.c
@@ -0,0 +1,266 @@
+/*
+ * Testcase for
+ * C_GetOperationState / C_SetOperationState
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <time.h>
+
+#include "pkcs11types.h"
+#include "regress.h"
+#include "common.c"
+
+
+CK_BYTE_PTR alloc_random_buf(CK_SESSION_HANDLE sess, CK_LONG nbytes)
+{
+ CK_RV rc;
+ CK_BYTE_PTR ptr = malloc(nbytes);
+ if (ptr == NULL) {
+ testcase_error("malloc(%lu) failed", nbytes);
+ return NULL;
+ }
+ rc = funcs->C_GenerateRandom(sess, ptr, nbytes);
+ if (rc != CKR_OK) {
+ testcase_error("C_GenerateRandom() rc=%s", p11_get_ckr(rc));
+ free(ptr);
+ return NULL;
+ }
+ return ptr;
+}
+
+
+int sess_opstate_funcs(int loops)
+{
+ CK_SESSION_HANDLE s1, s2;
+ CK_SLOT_ID slot_id = SLOT_ID;
+ CK_ULONG flags;
+ CK_RV rc;
+ int i, counter, rbytes;
+ CK_BYTE *rdata = NULL;
+ CK_MECHANISM mech1 = {CKM_SHA256, 0, 0};
+ CK_MECHANISM mech2 = {CKM_SHA_1, 0, 0};
+ CK_ULONG r1hlen, r2hlen, hlen;
+ CK_BYTE r1hash[32], r2hash[32], hash[32];
+ CK_ULONG opstatelen;
+ CK_BYTE *opstate = NULL;
+
+ // open 2 sessions
+ flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
+ rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &s1);
+ if (rc != CKR_OK) {
+ testcase_error("C_OpenSession() rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &s2);
+ if (rc != CKR_OK) {
+ testcase_error("C_OpenSession() rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // init digest for both sessions
+ rc = funcs->C_DigestInit(s1, &mech1);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestInit rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ rc = funcs->C_DigestInit(s2, &mech1);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestInit rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // now loop over some digest updates
+ for (counter = 0; counter < loops; counter ++) {
+
+ // create some random data
+ rbytes = random() % sizeof(rdata);
+ rdata = alloc_random_buf(s1, rbytes);
+ if (!rdata) goto out;
+
+ // digest update on session 1
+ rc = funcs->C_DigestUpdate(s1, rdata, rbytes);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestUpdate rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // restore op state on session 2
+ if (opstate != NULL) {
+ rc = funcs->C_SetOperationState(s2, opstate, opstatelen, 0, 0);
+ if (rc != CKR_OK) {
+ testcase_error("C_SetOperationState rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ free(opstate);
+ opstate = NULL;
+ }
+
+ // digest update on session 2
+ rc = funcs->C_DigestUpdate(s2, rdata, rbytes);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestUpdate rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // fetch op state on session 2
+ opstatelen = 0;
+ rc = funcs->C_GetOperationState(s2, NULL, &opstatelen);
+ if (rc != CKR_OK) {
+ testcase_error("C_GetOperationState rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ opstate = malloc(opstatelen);
+ if (opstate == NULL) {
+ testcase_error("malloc(%lu) failed", opstatelen);
+ goto out;
+ }
+ rc = funcs->C_GetOperationState(s2, opstate, &opstatelen);
+ if (rc != CKR_OK) {
+ testcase_error("C_GetOperationState rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ free(rdata);
+ rdata = NULL;
+
+ // now do something different on session 2, but first
+ // we have to wipe out the started digest operation
+
+ hlen = sizeof(hash);
+ rc = funcs->C_DigestFinal(s2, hash, &hlen);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestFinal rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // so now let's do a digest init/update/finish
+ // to randomize the memory a little
+
+ rc = funcs->C_DigestInit(s2, &mech2);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestInit rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ for (i = 0; i < loops; i++) {
+ rbytes = random() % sizeof(rdata);
+ rdata = alloc_random_buf(s1, rbytes);
+ if (!rdata) goto out;
+ rc = funcs->C_DigestUpdate(s2, rdata, rbytes);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestUpdate rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ free(rdata);
+ rdata = NULL;
+ }
+ hlen = sizeof(hash);
+ rc = funcs->C_DigestFinal(s2, hash, &hlen);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestFinal rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ }
+
+ // restore op state on session 2
+ rc = funcs->C_SetOperationState(s2, opstate, opstatelen, 0, 0);
+ if (rc != CKR_OK) {
+ testcase_error("C_SetOperationState rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // digest finish
+ r1hlen = sizeof(r1hash);
+ rc = funcs->C_DigestFinal(s1, r1hash, &r1hlen);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestFinal rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+ r2hlen = sizeof(r2hash);
+ rc = funcs->C_DigestFinal(s2, r2hash, &r2hlen);
+ if (rc != CKR_OK) {
+ testcase_error("C_DigestFinal rc=%s", p11_get_ckr(rc));
+ goto out;
+ }
+
+ // check both hashes
+ if (r1hlen != r2hlen) {
+ testcase_fail("hash length differ");
+ goto out;
+ }
+ if (memcmp(r1hash, r2hash, r1hlen) != 0) {
+ testcase_fail("hash values differs");
+ goto out;
+ }
+
+ testcase_pass("Get/SetOperationState digest test");
+
+out:
+ if (opstate) free(opstate);
+ if (rdata) free(rdata);
+ funcs->C_CloseAllSessions(slot_id);
+ return rc;
+}
+
+
+int main(int argc, char **argv)
+{
+ CK_C_INITIALIZE_ARGS cinit_args;
+ int rc, i, j, loops = 0;
+ CK_RV rv;
+
+ SLOT_ID = 0;
+ no_init = FALSE;
+
+ srandom(time(0));
+
+ for (i=0; i < argc; i++) {
+ if (strncmp(argv[i], "loops=", 6) == 0) {
+ sscanf(argv[i]+6, "%i", &loops);
+ for (j=i; j < argc; j++)
+ argv[j] = argv[j+1];
+ argc--;
+ }
+ }
+ if (loops < 1) loops = 100;
+
+ rc = do_ParseArgs(argc, argv);
+ if (rc != 1)
+ return rc;
+
+ printf("Using slot #%lu...\n\n", SLOT_ID );
+ printf("With option: no_init: %d\n", no_init);
+ printf("Running %d loops...\n", loops );
+
+ rc = do_GetFunctionList();
+ if (!rc) {
+ PRINT_ERR("ERROR do_GetFunctionList() Failed , rc = 0x%0x\n", rc);
+ return rc;
+ }
+
+ memset( &cinit_args, 0x0, sizeof(cinit_args) );
+ cinit_args.flags = CKF_OS_LOCKING_OK;
+
+ funcs->C_Initialize( &cinit_args );
+
+ {
+ CK_SESSION_HANDLE hsess = 0;
+
+ rc = funcs->C_GetFunctionStatus(hsess);
+ if (rc != CKR_FUNCTION_NOT_PARALLEL)
+ return rc;
+
+ rc = funcs->C_CancelFunction(hsess);
+ if (rc != CKR_FUNCTION_NOT_PARALLEL)
+ return rc;
+
+ }
+
+ rv = sess_opstate_funcs(loops);
+
+ /* make sure we return non-zero if rv is non-zero */
+ return ((rv==0) || (rv % 256) ? rv : -1);
+}
--
2.7.4
2.7.4