Skip to content

Unsupported feature support #162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 19 commits into from

Conversation

RonEld
Copy link
Contributor

@RonEld RonEld commented Jul 9, 2019

This PR adds support for MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED in tests and applications.
This supersedes the crypto part of Mbed-TLS/mbedtls#2124

@RonEld RonEld added the enhancement New feature or request label Jul 9, 2019
@RonEld RonEld force-pushed the unsupported_feature branch 2 times, most recently from e6d54dd to e38049c Compare July 9, 2019 13:43
@RonEld RonEld changed the title Unsupported feature support WIP: Unsupported feature support Jul 10, 2019
@RonEld RonEld force-pushed the unsupported_feature branch 5 times, most recently from 53e6745 to 7cb3492 Compare July 14, 2019 07:34
@RonEld
Copy link
Contributor Author

RonEld commented Jul 14, 2019

The CI failure is because the changes in platform.h and in helpers.function related to inclusion of platform.h should be merged to the TLs repository as well. (This is done in Mbed-TLS/mbedtls#2124)

@RonEld RonEld changed the title WIP: Unsupported feature support Unsupported feature support Jul 14, 2019
@RonEld RonEld force-pushed the unsupported_feature branch from 7cb3492 to beb3b88 Compare September 9, 2019 15:08
@RonEld
Copy link
Contributor Author

RonEld commented Sep 9, 2019

I have rebased to resolved conflicts, fixed a bug in the tests, and added support to new tests

@RonEld RonEld force-pushed the unsupported_feature branch from 824f645 to 76b0956 Compare September 10, 2019 07:26
library/aria.c Outdated
if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED )
{
if( verbose )
mbedtls_printf( "skipped\n" );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit funny. What's the point of an ARIA self-test if even ECB isn't supported? I understand that mechanically we want to check for this error and skip, but I can't imagine a valid use case. No change requested here, just an odd observation.

I guess some hardware might not expose ECB, but may expose other modes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but we can't predict when a platform will return this error, and we allow returning this error for any crypto operation

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A platform could support a cipher in only one direction. This is most common in the encrypt direction, which is all you need for many modern AEAD modes (e.g. CCM, GCM). This could also be in the decrypt direction only for an accelerator that's only ever meant for CBC decryption, but that's a lot rarer.

mbedtls_printf( "skipped\n" );
continue;
}
else ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest to put ASSERT on a new line and to enclose with {} explicitly, in case the macro ever goes multi-line this is easier to maintain

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED )
{
ret = MBEDTLS_ERR_PK_INVALID_PUBKEY |
MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can these be or'd together like this? Do users use them as bitfields?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Or here is basically the high level and the low level. If I remember correct, the MBEDTLS_ERR_PK_INVALID_PUBKEY is still used in caller functions

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In principle, yes: an error code from a “high-level” module of Mbed TLS can be either a high-level error code, or a bitwise-or of a high-level error code and a low-level error code. See error.h.

In practice, I've seen bugs before from code expecting a high-level error code and getting one bitwise-ored with a low-level error code. So I wouldn't be surprised if this broke some existing code. We need to document this change clearly and in a way that people will find. This used to be reasonable code (abbreviated), but no longer is:

switch (mbedtls_pk_parse_key(…)) {
    case 0: do stuff; break;
    case MBEDTLS_ERR_PK_INVALID_PUBKEY: /*algorithm not supported, try the next key*/ continue;
    default: printf("Fatal error parsing key. Giving up.\n"); exit(1);
}

*/
if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE )
if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be (ret & MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED) if ret is a bitfield now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably. But I f remember correct, when I tested this, in this specific branch, it was always MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. But better to check the low leverl error

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this is needed. The low level driver could return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED, which in this case it is returned from pk_get_ecpubkey(). In this check, if it is unsupported, we modify the code to MBEDTLS_ERR_PK_KEY_INVALID_FORMAT | MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED

test_fail( #TEST, __LINE__, __FILE__ ); \
goto exit; \
} \

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't add this newline

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

do { \
if( ! (TEST) ) \
{ \
set_test_result( #TEST, __LINE__, __FILE__, TEST_RESULT_FAILED ); \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not keep using test_fail() and test_skip()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in order not to duplicate code.
I believe this came from this comment

@@ -423,17 +461,11 @@ jmp_buf jmp_tmp;
/*----------------------------------------------------------------------------*/
/* Helper Functions */

void test_fail( const char *test, int line_no, const char* filename )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of deleting test_fail, we could have it be a static function that calls set_test_result()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initially set_test_result() was static, but this caused compilation warnings, as declared functions that are not used, in modules that are configured out. The linker probably doesn't remove static functions.
In addition, since I thought putting one single function would make it cleaner

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function would have to be non-static.

This has nothing to do with the linker. It's because we compile with -Wunused-function.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should think of putting such functions into a separate .c file — #250.

@Patater Patater added needs: ci Needs a passing full CI run needs: review The pull request is ready for review. This generally means that it has no known issues. labels Sep 10, 2019
@Patater
Copy link
Contributor

Patater commented Sep 10, 2019

Needs to pass CI

Copy link
Collaborator

@gilles-peskine-arm gilles-peskine-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs some documentation to explain how to write an alternative implementation that doesn't implement everything. Preferably in Mbed Crypto and not in a knowledge base article that languishes unpublished for countless months.

There are incompatible changes: some functions now return different error codes. This needs to be clearly explained in release notes. We currently don't have a changelog for Mbed Crypto, which is a pity.

if( ret != 0 ) \
if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ) \
{ \
mbedtls_printf( "Feature Not Supported. Skipping.\n" ); \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cosmetic: “Feature not supported. Skipping.”

@@ -458,7 +477,21 @@ int main( int argc, char *argv[] )

memset( buf, 0, sizeof( buf ) );
memset( tmp, 0, sizeof( tmp ) );
mbedtls_aes_setkey_enc( &aes, tmp, keysize );
ret = mbedtls_aes_setkey_enc( &aes, tmp, keysize );
if( ret != 0 )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a lot of boilerplate here. Please make an auxiliary function, maybe with some wrapper macros.

Copy link
Contributor Author

@RonEld RonEld Sep 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's done in Mbed-TLS/mbedtls#2124 . Should I cherry-pick the changes there, or will it be merged to this repository?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't introduce new code that would change when Mbed-TLS/mbedtls#2124 finds its way into Mbed Crypto. Make the same changes to helpers.function here.

TIME_PUBLIC( title, "sign",
ret = mbedtls_ecdsa_write_signature( &ecdsa, MBEDTLS_MD_SHA256, buf, curve_info->bit_size,
tmp, &sig_len, myrand, NULL ) );
CHECK_AND_BREAK( mbedtls_ecdsa_write_signature( &ecdsa, MBEDTLS_MD_SHA256, buf, curve_info->bit_size,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking here leaves ecdsa unfreed. I think it's high time to split this code into auxiliary functions, and react to errors with goto exit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking here leaves ecdsa unfreed.

No it won't. THe break is done within the loop inside TIME_PUBLIC macro., going to next line in this code, which frees the context

library/aes.c Outdated
* MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't reviewed the self-test changes (commit "Skip self tests if feature unsupported"). That's a lot of new boilerplate code. Strongly consider defining at least a helper macro in platform.h.

@@ -235,7 +235,6 @@ void blowfish_encrypt_cbc( data_t * key_str, data_t * iv_str,
output ), cbc_result );
if( cbc_result == 0 )
{

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commit "Adjust symmetric tests to TEST_ASSERT_RET" does not do that at all. Please fix the commit description. Furthermore that commit does several unrelated things, so it should be split.

@@ -545,7 +546,18 @@ static int pk_get_rsapubkey( unsigned char **p,

if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0,
NULL, 0, NULL, 0 ) ) != 0 )
return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
{
if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit lost. When would a function from the rsa module return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED vs MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED | MBEDTLS_ERR_RSA_xxx?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would there be two low level errors? I don't see a place whereMBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED | MBEDTLS_ERR_RSA_xxx is returned.
The previous behavior was returning MBEDTLS_ERR_PK_INVALID_PUBKEY for any failure, now, in case of MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED returned by the rsa module, we still return MBEDTLS_ERR_PK_INVALID_PUBKEY but we also add the low level MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED

@@ -1057,9 +1057,6 @@ void mbedtls_ecp_gen_key( int id )
TEST_ASSERT_RET( mbedtls_ecp_gen_key( id, &key, &rnd_pseudo_rand,
&rnd_info ), 0 );

TEST_ASSERT_RET( mbedtls_ecp_check_pubkey( &key.grp, &key.Q ), 0 );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have these two lines been removed? It doesn't seem to have anything to do with "Adjust pk tests to TEST_ASSERT_RET".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably rebase error. I'll add them

library/aria.c Outdated
if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED )
{
if( verbose )
mbedtls_printf( "skipped\n" );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A platform could support a cipher in only one direction. This is most common in the encrypt direction, which is all you need for many modern AEAD modes (e.g. CCM, GCM). This could also be in the decrypt direction only for an accelerator that's only ever meant for CBC decryption, but that's a lot rarer.

* It receives an expected return code and:
* - If the underlying alternative implementation does not support the feature,
* by returning MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED, the test is skipped.
* - If and fails in case the expression
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar is mistake and I'm not even sure what you were trying to say.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it's a rebase error, I'll fix

*
* \param TEST The test expression to be tested.
* \param EXP_RET The expected return code from the function
*/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document when this function jumps (as is done for TEST_ASSERT).

@RonEld
Copy link
Contributor Author

RonEld commented Sep 11, 2019

All the failed CI tests are in the tls testing

@Patater
Copy link
Contributor

Patater commented Sep 11, 2019

All the failed CI tests are in the tls testing

Which means if we merge this, TLS tests will start failing when they update their submodule. The TLS tests should be passing before merge, or we need to understand how to make them pass again when the submodule is updated.

@RonEld
Copy link
Contributor Author

RonEld commented Sep 11, 2019

@Patater
I guess Mbed-TLS/mbedtls#2124 should be merged before this PR then, updating the TLS PR with this branch as the submodule

@RonEld
Copy link
Contributor Author

RonEld commented Sep 12, 2019

Which means if we merge this, TLS tests will start failing when they update their submodule. The TLS tests should be passing before merge, or we need to understand how to make them pass again when the submodule is updated.

Since now the CI in Mbed-TLS/mbedtls#2124 pass, I believe that once that PR will be merged, the TLS tests owuld pass here as well

@RonEld RonEld mentioned this pull request Sep 24, 2019
@gilles-peskine-arm
Copy link
Collaborator

Relabeling as "needs: work" because there are merge conflicts. Let's arrange a time when we're available for review soon after this has been rebased, or agree to include a merge commit.

@Patater
Copy link
Contributor

Patater commented Oct 29, 2019

Rebase please, early and often. Each rebase individually will be easier than a giant rebase later. Yes, we don't have a way to view diffs between previous versions of your patchset easily, but that's a GitHub limitation and only an inconvenience during review. History is easier to work with when we don't have upstream to downstream merge commits in short-term branches, the sorts PRs are from, as that e.g. breaks --first-parent from being useful, among other things. Let's not inconvenience folks using the permanent record for the short term sake of review convenience.

@gilles-peskine-arm gilles-peskine-arm added the needs: work The pull request needs rework before it can be merged. label Oct 31, 2019
@RonEld RonEld force-pushed the unsupported_feature branch 4 times, most recently from 16b47fa to 026eacf Compare October 31, 2019 15:29
Ron Eldor added 19 commits December 29, 2019 16:34
Adjust the tests to the new unsupported feature error,
skipping test if unsupported.
Skip test in self test, to the next test, when a function returns
`MBEDTLS_PLATFORM_FEATURE_UNSUPPORTED`, and result in success.
1. Return error in `crypt_and_hash` in case `mbedtls_cipher_finish()` fails.
2. Support the `MBEDTLS_PLATFORM_FEATURE_UNSUPPORTED` in the benchmark
application, to be skipped.
Remove redundant extra lines in the aes and blowfish test functions.
Have the wrapper code for chachapoly functionality return
the error code of the underlying function, instead of a generic
`MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA`.
Check error codes of `mbedtls_xtea_crypt_ecb`
and clean data in case of failure.
1. Change `TEST_ASSERT` to `TEST_ASSERT_RET` in all the pk tests.
2. Have the pk modules return error code of underlying pk functions.
Add an error for Feature Unsupported to be returned to the host,
and to be skipped.
Use lccal buffer for plaintext, to support different platforms,
that can't access Flash, but only RAM.
Include `platform.h` even if `MBEDTLS_PLATFORM_C` is undefined,
to include the feature unsupported  error.
Change `TEST_ASSERT` to `TEST_ASSERT_RET` to new `ecdh` tests.
Remove `static` type for `set_test_result` to avoid
compilation warnings when this function is not being used.
1. Change `test_fail` to `set_test_result`.
2. Add define of `mbedtls_snprintf` in `benchmark`
in case platform is not defined.
Remove redundant newline, and put `ASSERT` macro in a new code block.
1. Change typo in log.
2. Create a macro for the symmetric set key functionality.
3. Check for Feature not supported error in des key setting.
Remove redundant extra lines in the benchmark application.
Add `CHECK_AND_BREAK` for the tests that run inside a timing loop,
and add declaration of `mbedtls_snprintf` in case platform doesn't exist.
1. Change log for skipped test as it is not only for platform unsupported.
2. Remove unentered else statement.
3. Remove redundant `exit` label.
4. Revert the changes in the invalid param tests in the pk layer.
5. Update `TEST_ASSERT_RET` description.
Add helper macros for skipping self tests in case the returned error
is `MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED`,
since htese checks are very similar in all tests.
@RonEld RonEld force-pushed the unsupported_feature branch from 026eacf to 06aeaf6 Compare December 29, 2019 14:36
@RonEld
Copy link
Contributor Author

RonEld commented Dec 31, 2019

All the failed tests are due to missing declaration of MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED. only on Mbed builds, probably because this definition is in a header file that wasn't imported yet to Mbed OS

@gilles-peskine-arm
Copy link
Collaborator

Mbed Crypto has been merged back into Mbed TLS. Due to the nature of this pull request, it does not make sense to apply it to Mbed Crypto separately. Please bring these changes back into Mbed-TLS/mbedtls#2124 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request needs: ci Needs a passing full CI run needs: review The pull request is ready for review. This generally means that it has no known issues. needs: work The pull request needs rework before it can be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants