Re: [Opencryptoki-tech] [PATCH 2/2] Improvement on digest testcase
Brought to you by:
ebarretto
From: Joy M. L. <jml...@li...> - 2014-08-21 21:48:25
|
I agree that it is a good idea to include a few variable-length, generated digest testcases. But lets make the variable length a part of the test suite rather than something tester must input to run them. regards, Joy On Mon, 2014-08-04 at 16:11 +0200, Harald Freudenberger wrote: > Improvement on the digest testcase: 2 new testcases with > generated variable input data. do_DigestVar() for single > digest with variable data size and do_DigestUpdateVar() for > multipart digest with var data size. There comes a new > command line parameter with this change: > -datasize <size> with size may be a number optional > followed by k or m for kilobyte or megabyte. If this > parameter is not given, default is BIG_REQUEST which is > currently 4k. > > Signed-off-by: Harald Freudenberger <fr...@li...> > --- > testcases/crypto/digest_func.c | 281 +++++++++++++++++++++++++++++++++++++++- > 1 file changed, 280 insertions(+), 1 deletion(-) > > diff --git a/testcases/crypto/digest_func.c b/testcases/crypto/digest_func.c > index cfa4427..d5ba9d9 100644 > --- a/testcases/crypto/digest_func.c > +++ b/testcases/crypto/digest_func.c > @@ -11,6 +11,11 @@ > #include "common.c" > > #define MAX_HASH_LEN 512 > +#define MIN_DATA_SIZE 32 > + > +// holds value of the -datasize argument if given > +static unsigned data_size = 0; > + > > /** Tests messge digest with published test vectors. **/ > CK_RV do_Digest(struct digest_test_suite_info *tsuite) > @@ -110,6 +115,101 @@ testcase_cleanup: > return rc; > } > > +/** same as do_Digest() but with variable generated input data **/ > +CK_RV do_DigestVar(struct digest_test_suite_info *tsuite, size_t datasize) > +{ > + int i, j; > + CK_BYTE *data; > + CK_ULONG data_len; > + CK_BYTE actual[MAX_HASH_SIZE]; > + CK_ULONG actual_len; > + CK_MECHANISM mech; > + > + CK_SESSION_HANDLE session; > + CK_SLOT_ID slot_id = SLOT_ID; > + CK_ULONG flags; > + CK_RV rc; > + > + // begin test suite > + testsuite_begin("%s Digest with %u bytes", tsuite->name, (unsigned)datasize); > + testcase_rw_session(); > + > + // allocate buffers > + if (datasize < MIN_DATA_SIZE) datasize = MIN_DATA_SIZE; > + data = (CK_BYTE*) malloc(datasize); > + if (!data) { > + fprintf(stderr, "Memory Allocation Error, aborting test run !!!\n"); > + exit(1); > + } > + > + // skip test if mech is not supported with this slot > + if (! mech_supported(slot_id, tsuite->mech.mechanism)){ > + testsuite_skip(tsuite->tvcount, > + "mechanism %s is not supported with slot %ld", > + tsuite->name, slot_id); > + goto testcase_cleanup; > + } > + > + // iterate over test vectors > + for(i = 0; i < tsuite->tvcount; i++){ > + > + /** begin test **/ > + testcase_begin("Starting %s Digest with test vector %d.", > + tsuite->name, i); > + > + rc = CKR_OK; // set rc > + > + // clear buffers > + memset(actual, 0, sizeof(actual)); > + > + // set up data buffer > + data_len = datasize; > + for (j=0; j < data_len; j++) > + data[i] = (CK_BYTE) j; > + > + // get mech > + mech = tsuite->mech; > + > + // initialize single digest > + rc = funcs->C_DigestInit(session, &mech); > + if (rc != CKR_OK) { > + testcase_error("C_DigestInit rc=%s", p11_get_ckr(rc)); > + goto testcase_cleanup; > + } > + > + actual_len = sizeof(actual); // set digest buffer size > + > + // do single digest > + rc = funcs->C_Digest(session, data, data_len, actual, &actual_len); > + if (rc != CKR_OK) { > + testcase_error("C_Digest rc=%s", p11_get_ckr(rc)); > + goto testcase_cleanup; > + } > + > + // compare digest results with expected results > + testcase_new_assertion(); > + > + // if hash was sucessful generated that's all we expect here > + if (actual_len != tsuite->tv[i].hash_len) { > + testcase_fail("hashed data length does not match test vector's" > + " hashed data length.\nexpected length=%ld, found " > + "length=%ld.", > + tsuite->tv[i].hash_len, actual_len); > + } else { > + testcase_pass("%s Digest with test vector %d and %u bytes of data passed.", > + tsuite->name, i, (unsigned)datasize); > + } > + } > + > +testcase_cleanup: > + rc = funcs->C_CloseAllSessions(slot_id); > + if (rc != CKR_OK) { > + testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc)); > + } > + free(data); > + return rc; > +} > + > /** Tests multipart message digest with published test vectors. **/ > CK_RV do_DigestUpdate(struct digest_test_suite_info *tsuite) > { > @@ -220,6 +320,115 @@ testcase_cleanup: > return rc; > } > > +/** same as do_DigestUpdate() but with variable generated input data **/ > +CK_RV do_DigestUpdateVar(struct digest_test_suite_info *tsuite, size_t datasize) > +{ > + int i, j; > + CK_BYTE *data; > + CK_ULONG data_len, data_done; > + CK_BYTE actual[MAX_HASH_SIZE]; > + CK_ULONG actual_len; > + CK_MECHANISM mech; > + > + CK_SESSION_HANDLE session; > + CK_SLOT_ID slot_id = SLOT_ID; > + CK_ULONG flags; > + CK_RV rc; > + > + // begin test > + testsuite_begin("Starting %s Multipart Digest with %u bytes", > + tsuite->name, (unsigned)datasize); > + testcase_rw_session(); > + > + // allocate buffers > + if (datasize < MIN_DATA_SIZE) datasize = MIN_DATA_SIZE; > + data = (CK_BYTE*) malloc(datasize); > + if (!data) { > + fprintf(stderr, "Memory Allocation Error, aborting test run !!!\n"); > + exit(1); > + } > + > + // skip test if mech is not supported with this slot > + if (! mech_supported(slot_id, tsuite->mech.mechanism)){ > + testsuite_skip(tsuite->tvcount, > + "mechanism %s is not supported with slot %ld", > + tsuite->name, slot_id); > + goto testcase_cleanup; > + } > + > + // iterate over test vectors > + for(i = 0; i < tsuite->tvcount; i++){ > + > + // begin test > + testcase_begin("Starting %s Multipart Digest with test vector %d.", > + tsuite->name, i); > + > + rc = CKR_OK; // set rc > + > + // clear buffers > + memset(actual, 0, sizeof(actual)); > + > + // set up data buffer > + data_done = 0; > + data_len = datasize; > + for (j=0; j < data_len; j++) > + data[i] = (CK_BYTE) j; > + > + // get mechanism > + mech = tsuite->mech; > + > + // initialize multipart digest > + rc = funcs->C_DigestInit(session, &mech); > + if (rc != CKR_OK) { > + testcase_error("C_DigestInit rc=%s", p11_get_ckr(rc)); > + goto testcase_cleanup; > + } > + > + actual_len = sizeof(actual); > + > + // do multipart digest > + while (data_done < data_len) { > + CK_ULONG len = data_len - data_done; > + if (len >= DIGEST_UPDATE_JUNK_SIZE) > + len = DIGEST_UPDATE_JUNK_SIZE; > + rc = funcs->C_DigestUpdate(session, data + data_done, len); > + if (rc != CKR_OK) { > + testcase_error("C_DigestUpdate rc=%s", p11_get_ckr(rc)); > + goto testcase_cleanup; > + } > + data_done += len; > + } > + > + // finalize multipart digest > + rc = funcs->C_DigestFinal(session, actual, &actual_len); > + if (rc != CKR_OK) { > + testcase_error("C_DigestFinal rc=%s", p11_get_ckr(rc)); > + goto testcase_cleanup; > + } > + > + // compare digest results with expected results > + testcase_new_assertion(); > + > + // if hash was sucessful generated that's all we expect here > + if (actual_len != tsuite->tv[i].hash_len) { > + testcase_fail("hashed multipart data length does not " > + "match test vector's hashed data length.\n"); > + } else { > + testcase_pass("%s Multipart Digest with test vector " > + "%d and %u bytes of data passed.", > + tsuite->name, i, (unsigned)datasize); > + } > + } > + > +testcase_cleanup: > + rc = funcs->C_CloseAllSessions(slot_id); > + if (rc != CKR_OK) { > + testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc)); > + } > + free(data); > + return rc; > +} > + > /** Tests signature verification with published test vectors. **/ > CK_RV do_SignVerify_HMAC(struct HMAC_TEST_SUITE_INFO *tsuite){ > > @@ -572,9 +781,14 @@ testcase_cleanup: > } > > CK_RV digest_funcs() { > - CK_RV rc; > + CK_RV rc = CKR_OK; > int i; > > + // set default data size for variable data tests > + // if no value is given on the command line > + if (data_size == 0) > + data_size = BIG_REQUEST; > + > /** Digest tests **/ > for (i = 0; i < NUM_DIGEST_TEST_SUITES; i++){ > rc = do_Digest(&digest_test_suites[i]); > @@ -583,6 +797,14 @@ CK_RV digest_funcs() { > } > } > > + /** Digest tests with variable data size **/ > + for (i = 0; i < NUM_DIGEST_TEST_SUITES; i++){ > + rc = do_DigestVar(&digest_test_suites[i], data_size); > + if (rc && !no_stop) { > + return rc; > + } > + } > + > /** Multipart Digest tests **/ > for (i = 0; i < NUM_DIGEST_TEST_SUITES; i++){ > rc = do_DigestUpdate(&digest_test_suites[i]); > @@ -590,6 +812,15 @@ CK_RV digest_funcs() { > return rc; > } > } > + > + /** Multipart Digest tests with variable data data size **/ > + for (i = 0; i < NUM_DIGEST_TEST_SUITES; i++){ > + rc = do_DigestUpdateVar(&digest_test_suites[i], data_size); > + if (rc && !no_stop) { > + return rc; > + } > + } > + > /** HMAC tests **/ > for(i = 0; i < NUM_OF_HMAC_TEST_SUITES; i++){ > rc = do_SignVerify_HMAC(&hmac_test_suites[i]); > @@ -614,6 +845,51 @@ CK_RV digest_funcs() { > return rc; > } > > +/* > + * Process arguments which are only local to this testcase > + * and not recognized by do_ParseArgs from common.c. > + * This function manipulates argv and argc (which is valid > + * according to Posix) to hide the processed arguments and > + * thus should be called before do_ParseArgs() is invoked. > + */ > +static int do_ParseLocalArgs(int *argc, char **argv) > +{ > + char c; > + int i, j; > + > + for (i=1; i < *argc; i++) { > + if (strcmp(argv[i], "-datasize") == 0) { > + if (i+1 >= *argc) { > + fprintf (stderr, "Wrong/missing argument for '-datasize'\n"); > + return -1; > + } > + j = strlen(argv[i+1]); > + if (j < 1) { > + fprintf (stderr, "Wrong/missing numerical value for 'datasize'\n"); > + return -1; > + } > + c = argv[i+1][j-1]; > + j = atoi(argv[i+1]); > + if (j < 1) { > + fprintf (stderr, "Wrong/missing numerical value for 'datasize'\n"); > + return -1; > + } > + data_size = j; > + if (c == 'k' || c == 'K') > + data_size *= 1024; > + if (c == 'm' || c == 'M') > + data_size *= 1024*1024; > + // remove argv[i] and argv[i+1] (thats "-datasize <size>") from argv > + for (j=i; j+2 < *argc; j++) > + argv[j] = argv[j+2]; > + *argc -= 2; > + i--; > + } > + > + } > + return 0; > +} > + > int main(int argc, char **argv) > { > CK_C_INITIALIZE_ARGS cinit_args; > @@ -625,6 +901,9 @@ int main(int argc, char **argv) > no_init = FALSE; > no_stop = FALSE; > > + rc = do_ParseLocalArgs(&argc, argv); > + if ( rc < 0) > + return rc; > > rc = do_ParseArgs(argc, argv); > if ( rc != 1) |