From b03bc43f22e4ad7e7107e855da14dd71f12d2ba2 Mon Sep 17 00:00:00 2001 From: Andrzej Kurek Date: Tue, 23 Jan 2018 06:25:32 -0500 Subject: [PATCH] pkcs11_client tests - hardcoded signature verification Add review fixes - naming changes, importing a signature instead of generating it. --- include/mbedtls/ecdsa.h | 12 +- library/ecdsa.c | 10 +- library/pkcs11_client.c | 13 +- tests/suites/test_suite_pkcs11_client.data | 10 +- .../suites/test_suite_pkcs11_client.function | 166 ++++++++---------- 5 files changed, 108 insertions(+), 103 deletions(-) diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h index ed88c8a3f..bff30fcad 100644 --- a/include/mbedtls/ecdsa.h +++ b/include/mbedtls/ecdsa.h @@ -240,12 +240,13 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, * of {r,s} * * \param sig Signature to be converted - * \param ssize Size of the passed buffer + * \param ssize Size of the signature * \param byte_len Length of a single number of the signature - * \param buf Buffer pointer - * \param slen Size of the written signature + * \param buf Buffer pointer for the converted signature + * \param bufsize Size of the passed buffer + * \param buflen Size of the signature written to the buffer * - * \note The size of the buffer \c ssize should be at least + * \note The size of the buffer \c bufsize should be at least * 2*byte_len bytes long, otherwise this function will * return an error. * @@ -255,7 +256,8 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, */ int mbedtls_ecdsa_signature_to_raw( const unsigned char *sig, size_t ssize, uint16_t byte_len, - unsigned char *buf, size_t* slen ); + unsigned char *buf, size_t bufsize, + size_t* buflen ); /** * \brief Convert a signature from numbers to ASN.1 * diff --git a/library/ecdsa.c b/library/ecdsa.c index 645fbb52e..0f33b83ce 100644 --- a/library/ecdsa.c +++ b/library/ecdsa.c @@ -289,9 +289,13 @@ cleanup: /* * Convert a signature to a raw concatenation of {r, s} */ +/*int mbedtls_ecdsa_signature_to_raw( const unsigned char *sig, + size_t ssize, uint16_t byte_len, + unsigned char *buf, size_t* slen )*/ int mbedtls_ecdsa_signature_to_raw( const unsigned char *sig, size_t ssize, uint16_t byte_len, - unsigned char *buf, size_t* slen ) + unsigned char *buf, size_t bufsize, + size_t* buflen ) { int ret; unsigned char *p = (unsigned char *) sig; @@ -299,7 +303,7 @@ int mbedtls_ecdsa_signature_to_raw( const unsigned char *sig, size_t len; mbedtls_mpi r, s; - if( 2 * byte_len > ssize ) + if( 2 * byte_len > bufsize ) { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } @@ -339,7 +343,7 @@ int mbedtls_ecdsa_signature_to_raw( const unsigned char *sig, ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; goto cleanup; } - *slen = 2*byte_len; + *buflen = 2*byte_len; cleanup: mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s ); diff --git a/library/pkcs11_client.c b/library/pkcs11_client.c index 70cc0de9a..1e03ef192 100644 --- a/library/pkcs11_client.c +++ b/library/pkcs11_client.c @@ -239,7 +239,7 @@ static int pkcs11_verify( void *ctx_arg, mbedtls_pk_pkcs11_context_t *ctx = ctx_arg; CK_RV rv; CK_MECHANISM mechanism = {0, NULL_PTR, 0}; - unsigned char *decoded_sig = NULL_PTR; + unsigned char *decoded_sig = NULL; size_t decoded_sig_len; /* This function takes size_t arguments but the underlying layer @@ -286,9 +286,14 @@ static int pkcs11_verify( void *ctx_arg, if( mechanism.mechanism == CKM_ECDSA ) { uint16_t byte_len = ( ( ctx->bit_length + 7 ) / 8 ); - decoded_sig = malloc( 2 * byte_len ); + decoded_sig = mbedtls_calloc( 1, 2 * byte_len ); + if( decoded_sig == NULL ) + { + return( MBEDTLS_ERR_PK_ALLOC_FAILED ); + } if( mbedtls_ecdsa_signature_to_raw( sig, sig_len, byte_len, - decoded_sig, &decoded_sig_len ) != 0 ) + decoded_sig, 2 * byte_len, + &decoded_sig_len ) != 0 ) { rv = CKR_GENERAL_ERROR; goto exit; @@ -303,7 +308,7 @@ static int pkcs11_verify( void *ctx_arg, goto exit; exit: - free(decoded_sig); + mbedtls_free(decoded_sig); return( pkcs11_err_to_mbedtls_pk_err( rv ) ); } diff --git a/tests/suites/test_suite_pkcs11_client.data b/tests/suites/test_suite_pkcs11_client.data index 33a75c36a..17930235f 100644 --- a/tests/suites/test_suite_pkcs11_client.data +++ b/tests/suites/test_suite_pkcs11_client.data @@ -6,10 +6,14 @@ PKCS#11 ECDSA generate and sign depends_on:MBEDTLS_PK_C:MBEDTLS_ECDSA_C pk_generate_sign:MBEDTLS_PK_ECDSA -PKCS#11 ECDSA generate, sign and verify with Cryptoki +PKCS#11 ECDSA import, sign and verify with Cryptoki depends_on:MBEDTLS_PK_C:MBEDTLS_ECDSA_C -pk_signX_verifyX:MBEDTLS_PK_ECDSA +pk_import_sign_verify:"data_files/server3.key" PKCS#11 ECDSA import, sign with MbedTLS and verify with Cryptoki depends_on:MBEDTLS_PK_C:MBEDTLS_ECDSA_C -pk_import_signI_verifyX:"data_files/server3.key" +pk_import_verify_signed:"data_files/server3.key" + +PKCS#11 ECDSA verify a hardcoded signature with Cryptoki +depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED +pk_ecdsa_hardcoded_verify:MBEDTLS_PK_ECDSA:MBEDTLS_ECP_DP_SECP192R1:"046FDD3028FA94A863CD4F78DBFF8B3AA561FC6D9CCBBCA88E0AE6FA437F5415F957542D0717FF8B84562DAE99872EF841":"546869732073686F756C64206265207468652068617368206F662061206D6573736167652E00":"30350218185B2A7FB5CD9C9A8488B119B68B47D6EC833509CE9FA1FF021900FB7D259A744A2348BD45D241A39DC915B81CC2084100FA24":0 diff --git a/tests/suites/test_suite_pkcs11_client.function b/tests/suites/test_suite_pkcs11_client.function index e14996b78..1a123bf35 100644 --- a/tests/suites/test_suite_pkcs11_client.function +++ b/tests/suites/test_suite_pkcs11_client.function @@ -325,9 +325,9 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_PK_C:MBEDTLS_SHA256_C */ -void pk_signX_verifyX( int key_type ) +void pk_import_sign_verify( char *file ) { - /* Sign with cryptoki, convert to mbedTLS format and save, + /* Sign with cryptoki, convert to mbedTLS format and save, verify by cryptoki with a conversion to a raw, concatenated format by the engine. */ mbedtls_pk_context pkcs11_ctx; @@ -336,106 +336,34 @@ void pk_signX_verifyX( int key_type ) CK_OBJECT_HANDLE hPublicKey = CK_INVALID_HANDLE; CK_OBJECT_HANDLE hPrivateKey = CK_INVALID_HANDLE; unsigned char hash_value[32] = "Fake hash, it doesn't matter...."; - unsigned char sig_buffer[RSA_KEY_SIZE_BYTES]; + unsigned char sig_buffer[4096]; size_t sig_length = sizeof( sig_buffer ); mbedtls_pk_init( &pkcs11_ctx ); mbedtls_pk_init( &transparent_ctx ); - /* Initialize cryptoki and generate a key in the token */ + /* Read a transparent key */ + TEST_ASSERT( mbedtls_pk_parse_keyfile( &transparent_ctx, file, NULL ) == 0 ); + + /* Initialize cryptoki and import the key into the token */ hSession = pkcs11_init( ); TEST_ASSERT( hSession != CK_INVALID_HANDLE ); - CK_ASSERT( pkcs11_generate_key( key_type, - hSession, - &hPublicKey, &hPrivateKey ) ); + TEST_ASSERT( mbedtls_pk_import_to_pkcs11( &transparent_ctx, + MBEDTLS_PK_FLAG_SIGN | + MBEDTLS_PK_FLAG_VERIFY, + hSession, + &hPublicKey, + &hPrivateKey ) == 0 ); TEST_ASSERT( hPublicKey != CK_INVALID_HANDLE ); TEST_ASSERT( hPrivateKey != CK_INVALID_HANDLE ); - - /* Prepare the mbed TLS contexts */ - TEST_ASSERT( mbedtls_pk_setup( &transparent_ctx, - mbedtls_pk_info_from_type( key_type ) ) == 0 ); TEST_ASSERT( mbedtls_pk_setup_pkcs11( &pkcs11_ctx, hSession, hPublicKey, hPrivateKey ) == 0 ); - /* Retrieve the public key from the token */ - switch( key_type ) - { -#if defined(MBEDTLS_RSA_C) - case MBEDTLS_PK_RSA: - { - unsigned char n_buffer[RSA_KEY_SIZE_BYTES]; - unsigned char e_buffer[RSA_KEY_SIZE_BYTES]; - CK_ATTRIBUTE public_attributes[] = { - {CKA_MODULUS, n_buffer, sizeof( n_buffer )}, - {CKA_PUBLIC_EXPONENT, e_buffer, sizeof( e_buffer )}, - }; - CK_ULONG *n_length = &public_attributes[0].ulValueLen; - CK_ULONG *e_length = &public_attributes[1].ulValueLen; - mbedtls_rsa_context *rsa_ctx = mbedtls_pk_rsa( transparent_ctx ); - - CK_ASSERT( C_GetAttributeValue( hSession, hPublicKey, - public_attributes, ARRAY_LENGTH( public_attributes ) ) ); - TEST_ASSERT( mbedtls_mpi_read_binary( &rsa_ctx->N, - n_buffer, *n_length ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_binary( &rsa_ctx->E, - e_buffer, *e_length ) == 0 ); - rsa_ctx->len = mbedtls_mpi_size( &rsa_ctx->N ); - } - break; -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECDSA_C) - case MBEDTLS_PK_ECDSA: - { - unsigned char ecParams[16]; - unsigned char ecPoint[128]; - CK_ATTRIBUTE public_attributes[] = { - {CKA_EC_PARAMS, ecParams, sizeof( ecParams )}, - {CKA_EC_POINT, ecPoint, sizeof( ecPoint )}, - }; - mbedtls_ecp_keypair *ecp_ctx = mbedtls_pk_ec( transparent_ctx ); - - CK_ASSERT( C_GetAttributeValue( hSession, hPublicKey, - public_attributes, ARRAY_LENGTH( public_attributes ) ) ); - // TODO: lift out a function or two from pkparse.c - // * pk_get_ecparams followed by pk_use_ecparams for ecParams? - // * Some code from pk_group_from_specified to read an octet string for ecPoint? - { - mbedtls_asn1_buf params_asn1; - CK_ULONG ecParams_length = public_attributes[0].ulValueLen; - mbedtls_ecp_group_id grp_id; - params_asn1.tag = ecParams[0]; - params_asn1.len = ecParams[1]; - params_asn1.p = ecParams + 2; - TEST_ASSERT( ecParams_length == 2 + params_asn1.len ); - TEST_ASSERT( mbedtls_oid_get_ec_grp( ¶ms_asn1, &grp_id ) == 0 ); - TEST_ASSERT( mbedtls_ecp_group_load( &ecp_ctx->grp, grp_id ) == 0 ); - } - { - unsigned char *p = ecPoint; - size_t len; - CK_ULONG ecPoint_length = public_attributes[1].ulValueLen; - TEST_ASSERT( mbedtls_asn1_get_tag( &p, - ecPoint + ecPoint_length, - &len, - MBEDTLS_ASN1_OCTET_STRING ) == 0 ); - TEST_ASSERT( mbedtls_ecp_point_read_binary( &ecp_ctx->grp, - &ecp_ctx->Q, - p, len ) == 0 ); - } - } - break; -#endif /* MBEDTLS_ECDSA_C */ - - default: - TEST_ASSERT( !"Unsupported key type in test data" ); - break; - } - - /* Sign with the token and verify in software */ + /* Sign with the token and verify with cryptoki */ + TEST_ASSERT( sizeof( sig_buffer ) >= mbedtls_pk_signature_size( &pkcs11_ctx ) ); TEST_ASSERT( mbedtls_pk_sign( &pkcs11_ctx, MBEDTLS_MD_SHA256, hash_value, 32, sig_buffer, &sig_length, @@ -457,7 +385,7 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_PK_C:MBEDTLS_SHA256_C */ -void pk_import_signI_verifyX( char *file ) +void pk_import_verify_signed( char *file ) { /* Sign with mbedTLS, verify by cryptoki with a conversion to a raw, concatenated format by the engine. */ @@ -514,3 +442,65 @@ exit: mbedtls_pk_free( &transparent_ctx ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_C */ +void pk_ecdsa_hardcoded_verify( int type, int id, char *key_str, + char *hash_str, char * sig_str, int ret ) +{ + mbedtls_pk_context transparent_ctx; + mbedtls_ecp_keypair *eckey; + unsigned char hash[100], sig[500], key[500]; + size_t hash_len, sig_len, key_len; + + mbedtls_pk_context pkcs11_ctx; + CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; + CK_OBJECT_HANDLE hPublicKey = CK_INVALID_HANDLE; + CK_OBJECT_HANDLE hPrivateKey = CK_INVALID_HANDLE; + + mbedtls_pk_init( &transparent_ctx ); + + memset( hash, 0, sizeof( hash ) ); hash_len = unhexify(hash, hash_str); + memset( sig, 0, sizeof( sig ) ); sig_len = unhexify(sig, sig_str); + memset( key, 0, sizeof( key ) ); key_len = unhexify(key, key_str); + + TEST_ASSERT( mbedtls_pk_setup( &transparent_ctx, mbedtls_pk_info_from_type( type ) ) == 0 ); + + TEST_ASSERT( mbedtls_pk_can_do( &transparent_ctx, MBEDTLS_PK_ECDSA ) ); + eckey = mbedtls_pk_ec( transparent_ctx ); + + TEST_ASSERT( mbedtls_ecp_group_load( &eckey->grp, id ) == 0 ); + TEST_ASSERT( mbedtls_ecp_point_read_binary( &eckey->grp, &eckey->Q, + key, key_len ) == 0 ); + + // PKCS11 part + mbedtls_pk_init( &pkcs11_ctx ); + + /* Initialize cryptoki and import the key into the token */ + hSession = pkcs11_init( ); + TEST_ASSERT( hSession != CK_INVALID_HANDLE ); + TEST_ASSERT( mbedtls_pk_import_to_pkcs11( &transparent_ctx, + MBEDTLS_PK_FLAG_SIGN | + MBEDTLS_PK_FLAG_VERIFY, + hSession, + &hPublicKey, + &hPrivateKey ) == 0 ); + TEST_ASSERT( hPublicKey != CK_INVALID_HANDLE ); + TEST_ASSERT( hPrivateKey != CK_INVALID_HANDLE ); + TEST_ASSERT( mbedtls_pk_setup_pkcs11( &pkcs11_ctx, + hSession, + hPublicKey, + hPrivateKey ) == 0 ); + TEST_ASSERT( mbedtls_pk_verify( &pkcs11_ctx, MBEDTLS_MD_NONE, + hash, hash_len, sig, sig_len ) == ret ); + +exit: + if( hPublicKey != CK_INVALID_HANDLE ) + C_DestroyObject( hSession, hPublicKey ); + if( hPrivateKey != CK_INVALID_HANDLE ) + C_DestroyObject( hSession, hPrivateKey ); + C_CloseSession( hSession ); + C_Finalize( NULL_PTR ); + mbedtls_pk_free( &pkcs11_ctx ); + mbedtls_pk_free( &transparent_ctx ); +} +/* END_CASE */