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 <[email protected]>
> ---
>  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)



------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
Opencryptoki-tech mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opencryptoki-tech

Reply via email to