Skip to content
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

Dispatch MAC operations through the driver interface #4247

Merged

Conversation

stevew817
Copy link
Contributor

Description

Builds on the specification from #3933 and prior art from #4151, #4157, #4229 and #4240. Supersedes #4049.

psa_mac_xxx APIs are now dispatched through the psa_driver_wrappers interface. There are a couple of to-be-done mentions in this PR, but they concern features that weren't present before this PR either. Namely:

  • Dispatch of opaque test driver calls on MAC (awaiting unified key storage format for an opaque test driver)
    • I added the boilerplate for these calls to make a future addition of this functionality less strenuous.
  • Dispatch of oneshot MAC operations (not implemented in PSA yet, related work has been staged in [Backport 2.x] Implement one-shot cipher #4182 which will need to be co-ordinated with this PR )
    • I added the boilerplate for the oneshot MAC functions to the psa_driver_wrappers layer to make a future addition of that API less strenuous

Status

READY

Requires Backporting

NO
(new functionality / internal refactoring)

Migrations

NO
(new functionality / internal refactoring)

Todos

  • Tests
  • Documentation

Steps to test or reproduce

Tested by existing test suites

@gilles-peskine-arm
Copy link
Contributor

CI failures on 29421f1 (several other jobs are failing with the same errors):

all.sh test_psa_crypto_config_no_driver

test_suite_psa_crypto ............................................. FAIL

all.sh test_full_cmake_clang on Ubuntu 16.04

/var/lib/build/library/psa_crypto.c:4040:37: error: missing field 'ctx' initializer [-Werror,-Wmissing-field-initializers]
    psa_hmac_internal_data backup = MBEDTLS_PSA_HMAC_OPERATION_INIT;
                                    ^
/var/lib/build/include/psa/crypto_builtin_mac.h:50:47: note: expanded from macro 'MBEDTLS_PSA_HMAC_OPERATION_INIT'
#define MBEDTLS_PSA_HMAC_OPERATION_INIT {0, {0}, {0}}
                                              ^
1 error generated.
library/CMakeFiles/mbedcrypto.dir/build.make:1238: recipe for target 'library/CMakeFiles/mbedcrypto.dir/psa_crypto.c.o' failed
make[2]: *** [library/CMakeFiles/mbedcrypto.dir/psa_crypto.c.o] Error 1
make[2]: *** Waiting for unfinished jobs....
CMakeFiles/Makefile2:400: recipe for target 'library/CMakeFiles/mbedcrypto.dir/all' failed
Makefile:138: recipe for target 'all' failed

all.sh test_clang_opt on FreeBSD

  CC    psa_crypto.c
psa_crypto.c:1536:1: warning: _Static_assert is a C11-specific feature [-Wc11-extensions]
static_assert( ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
^
/usr/include/assert.h:71:23: note: expanded from macro 'static_assert'
#define static_assert   _Static_assert
                        ^
psa_crypto.c:1538:1: warning: _Static_assert is a C11-specific feature [-Wc11-extensions]
static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
^
/usr/include/assert.h:71:23: note: expanded from macro 'static_assert'
#define static_assert   _Static_assert
                        ^
psa_crypto.c:1540:1: warning: _Static_assert is a C11-specific feature [-Wc11-extensions]
static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ) == 0,
^
/usr/include/assert.h:71:23: note: expanded from macro 'static_assert'
#define static_assert   _Static_assert
                        ^
psa_crypto.c:1804:13: warning: _Static_assert is a C11-specific feature [-Wc11-extensions]
            static_assert( sizeof( slot_number ) ==
            ^
/usr/include/assert.h:71:23: note: expanded from macro 'static_assert'
#define static_assert   _Static_assert
                        ^
psa_crypto.c:4040:37: error: missing field 'ctx' initializer [-Werror,-Wmissing-field-initializers]
    psa_hmac_internal_data backup = MBEDTLS_PSA_HMAC_OPERATION_INIT;
                                    ^
../include/psa/crypto_builtin_mac.h:50:47: note: expanded from macro 'MBEDTLS_PSA_HMAC_OPERATION_INIT'
#define MBEDTLS_PSA_HMAC_OPERATION_INIT {0, {0}, {0}}
                                              ^
4 warnings and 1 error generated.
make[1]: *** [Makefile:271: psa_crypto.o] Error 1
make: *** [Makefile:17: lib] Error 2

Visual Studio

         C:\builds\workspace\mbed-tls-pr-head_PR-4247-head\worktrees\tmp2z5y25t6\library\psa_crypto_mac.c(264): warning C4267: 'function' : conversion from 'size_t' to 'int', possible loss of data [C:\builds\workspace\mbed-tls-pr-head_PR-4247-head\worktrees\tmp2z5y25t6\cmake_solution\library\mbedcrypto.vcxproj]

@bensze01 bensze01 added HwDrivers needs-review Every commit must be reviewed by at least two team members, needs-reviewer This PR needs someone to pick it up for review labels Mar 23, 2021
@tom-daubney-arm tom-daubney-arm self-requested a review March 24, 2021 09:08
@ronald-cron-arm ronald-cron-arm self-requested a review March 24, 2021 14:20
@ronald-cron-arm ronald-cron-arm removed the needs-reviewer This PR needs someone to pick it up for review label Mar 24, 2021
Copy link
Contributor

@ronald-cron-arm ronald-cron-arm left a comment

Choose a reason for hiding this comment

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

Mostly looked at the final code organization to start with.
I think things would be better organized with a file for hmac, a file for cmac both exposing a MAC driver interface and finally the dispatch being kept in psa_crypto.c in *_internal functions (like for sign/verify hash). Eventually (not in this PR), the *_internal functions will be merged into psa_crypto_driver_wrappers.c when it is auto-generated. I don't think we are too far from that. What do you think?

operation->iv_required = 0;
operation->has_input = 0;
operation->is_sign = 0;
operation->ctx.mbedtls_ctx.alg = PSA_ALG_FULL_LENGTH_MAC( alg );
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 changing it this way and then back to just "operation->" when moving the code to psa_crypto_mac.c please just change the name of the operation argument to mac_operation for example and introduce the local variable "operation = &operation->ctx.mbedtls_ctx". That way the code movement later will be easier to check with"git show --color-moved".

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'll keep it in mind for future PRs

Copy link
Contributor

Choose a reason for hiding this comment

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

You have to rebase anyway thus please do it in this PR. Otherwise, I will have to check the code move line by line to be sure that nothing like below (line 2560) happened.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's quite a difference in workload between a rebase to resolve merge conflicts and a fairly extensive rewrite (what you're asking for). It sounds like you care deeply, so I guess I'll do it, but I don't really see the point.

Copy link
Contributor

Choose a reason for hiding this comment

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

The point is to facilitate review. Generally speaking, a commit should either do a single piece of refactoring or do a behavior change. Renaming identifiers and moving code are two different kinds of refactoring, so they shouldn't be done in the same commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

library/psa_crypto.c Outdated Show resolved Hide resolved
@stevew817
Copy link
Contributor Author

I don't think I'm on board with creating overarching _internal hooks for MAC inside psa_crypto.c. It needlessly clutters psa_crypto.c IMO.

The final goal would be (as indicated) to also substitute the internal HMAC API usage with calls to the overarching MAC dispatch, since currently an accelerator capable of performing HMAC will not be used for doing HKDF / PRF, and instead potential acceleration would go through the hash layer instead, which is sub-optimal.

I also assume that the end goal for PSA would be to build its own cipher-MAC (CMAC / CBC-MAC) codebase on top of the cipher API, since the current mbed TLS CMAC abstraction is needlessly complex, and relying on it requires fallback for accelerators which support AES but not AES-CMAC to implement the mbed TLS AES_ALT hooks in addition to the PSA Driver's cipher hooks.

Ergo, I'd rather make a case for keeping the MAC 'software driver' implementation grouped together in a single file, much the same as they were grouped together previously in the PSA Core psa_crypto.c.

@ronald-cron-arm
Copy link
Contributor

ronald-cron-arm commented Apr 1, 2021

I don't think I'm on board with creating overarching _internal hooks for MAC inside psa_crypto.c. It needlessly clutters psa_crypto.c IMO.

That would be temporary (as it is currently the case for psa_sign/verify_hash_internal()). Eventually the dispatch will be done in the driver wrappers. Saying that if you prefer we could probably even do it right now in the driver wrappers.

The final goal would be (as indicated) to also substitute the internal HMAC API usage with calls to the overarching MAC dispatch, since currently an accelerator capable of performing HMAC will not be used for doing HKDF / PRF, and instead potential acceleration would go through the hash layer instead, which is sub-optimal.

The path I see is to change the internal HMAC API to be the MAC driver API. Then the direct call to the HMAC driver would be changed to a call to the MAC driver wrappers APIs that would do the dispatch. No need for an generic MAC extra layer.

I also assume that the end goal for PSA would be to build its own cipher-MAC (CMAC / CBC-MAC) codebase on top of the cipher API, since the current mbed TLS CMAC abstraction is needlessly complex, and relying on it requires fallback for accelerators which support AES but not AES-CMAC to implement the mbed TLS AES_ALT hooks in addition to the PSA Driver's cipher hooks.

Ergo, I'd rather make a case for keeping the MAC 'software driver' implementation grouped together in a single file, much the same as they were grouped together previously in the PSA Core psa_crypto.c.

A generic MAC 'software driver' layer would make completely sense to me if there was a significant amount of shared code between HMAC and CMAC. But looking at the code in psa_crypto_mac.c I don't see that. That's why I am more in favour of having two separate MAC driver files, one for HMAC and one for CMAC.

@mpg mpg added the Community label Apr 8, 2021
@gabor-mezei-arm gabor-mezei-arm mentioned this pull request Apr 8, 2021
2 tasks
@stevew817
Copy link
Contributor Author

A generic MAC 'software driver' layer would make completely sense to me if there was a significant amount of shared code between HMAC and CMAC. But looking at the code in psa_crypto_mac.c I don't see that. That's why I am more in favour of having two separate MAC driver files, one for HMAC and one for CMAC.

But that means added logic in the driver_wrappers file for the fallback case, since suddenly it would be wrapping two different drivers. And if it does that for the fallback case, then why aren't the HW accelerator drivers allowed the same flexibility?
The fact that HMAC and CMAC are vastly differently implemented is abstracted away by the PSA 'MAC' interface. The driver wrappers do dispatch based on the PSA interface, not the implementation details of the underlying cryptographic libraries. Yes, at some point a call to the PSA MAC interface needs to be turned into either calling the Mbed TLS cipher interface for CMAC (and CBC-MAC if that ever makes it), and the Mbed TLS HMAC/MD interface for HMAC. IMO, psa_crypto_mac is exactly the right place for that conceptually, since the name indicates it contains the implementation for the 'mac' interface.

You could debate pulling out the respective implementations into psa_crypto_hmac and psa_crypto_cmac, and have psa_crypto_mac be the dispatch to those two, but IMO that brings little to the table other than needless fragmentation.

@gilles-peskine-arm
Copy link
Contributor

But that means added logic in the driver_wrappers file for the fallback case, since suddenly it would be wrapping two different drivers. And if it does that for the fallback case, then why aren't the HW accelerator drivers allowed the same flexibility?

Hardware accelerator drivers are allowed this flexibility, or at least will be when we finish implementing the driver interface. The dispatch takes the key type and algorithm into account. It's perfectly sensible to have an RSA driver that does both RSA signature and encryption, and an ECC driver that does both ECDSA and ECDH.

I don't have a strong feeling on what the code structure should be now, but it would make sense to me to group things related to block ciphers together (so including MAC, cipher and AEAD functionality), and things related to hashes together (hash, HMAC, KMAC when we get around to merging it, …), and things related to RSA (signature and encryption), etc.

@stevew817 stevew817 force-pushed the dispatch_mac_operations branch from 30d0452 to ca5124a Compare April 16, 2021 13:57
@stevew817
Copy link
Contributor Author

First force-push: the commit flow changes requested by @ronald-cron-arm . This is a force-push without any changes (i.e. the end result is identical to what was in 30d0452, just the way to get there is different).

@stevew817 stevew817 force-pushed the dispatch_mac_operations branch from ca5124a to 19e4243 Compare April 16, 2021 15:45
@stevew817
Copy link
Contributor Author

Second force-push: rebase to resolve merge conflicts with what has happened on upstream in the meantime.

Resolutions:

  • MAC dispatch added after AEAD dispatch in the wrapper files
  • crypto_builtin_mac.h integrated in crypto_builtin.h
  • Driver context declarations and PSA structure declarations (due to dependency of HMAC software driver operation structure on fully-qualified PSA hash structure): moved cipher into crypto_driver_contexts as well.

Previous state: https://github.com/stevew817/mbedtls/tree/dispatch_mac_operations_1

@ronald-cron-arm
Copy link
Contributor

Back on this, this morning. Regarding whether we should have a psa_crypto_mac.c or rather a psa_crypto_hmac.c and a psa_crypto_cmac.c or none of them and just psa_crypto_cipher.c and psa_crypto_hash.c (as mentioned by Gilles) I reckon there is more thinking to do. Let's forget about that aspect for this PR and stick with psa_crypto_mac.c.

In my review I am stuck with the re-organization of the operation and driver contexts definitions for mbedtls_psa_mac_operation_t to contain an psa_hash_operation_t structure. I am not sure what to think/do about that for the time being.

@stevew817
Copy link
Contributor Author

It's going to be a generic issue when multi-part algorithm implementations need to rely on other underlying multi-part primitives that already have a PSA implementation. It points to a certain hierarchy in the algorithms:

  • hash and cipher are 'basic' algorithms, with no dependency
  • The currently-supported MAC algorithms can be built using either hash or cipher
  • The currently-supported AEAD algorithms can be built using cipher

And since the built-with-cipher algorithms don't have a software implementation using PSA primitives yet (but rely on Mbed TLS' cipher module instead), they don't yet expose the same dependency as HMAC is showing now.

The reorganisation I did was what I thought to be the best way to go about fulfilling that dependency for the time being. Other approaches could be splitting them in e.g. crypto_builtin_primitive and crypto_builtin_composite files, basically saying that whatever ends up in primitive is not allowed to depend on other context structures, while those in composite can depend on what's provided by the ones in primitive.

Let me know which way you want to go, or if you have a better suggestion.

@ronald-cron-arm
Copy link
Contributor

I also think that introducing new headers seems a reasonable solution.

Currently (in development) we have crypto_builtin.h that defines the operation structures for Mbed TLS software-based PSA drivers, crypto_driver_contexts.h that includes crypto_builtin.h and defines the operation structures for hardware drivers linked to the library and finally crypto_struct.h that includes crypto_driver_contexts.h and define the PSA client operation structures. By the way, looking at those headers and the headers they include I can see that crypto_driver_contexts.h includes crypto.h which is probably a mistake.

We could introduce crypto_builtin_primitive.h, crypto_driver_contexts_primitive.h and crypto_struct_primitive.h where the operation structures for cipher and hash would be defined with the same inclusion structure as described above. Then crypto_builtin.h would include crypto_struct_primitive.h and crypto.h would include crypto_struct_primitive.h along with crypto_struct.h.

I don't feel the need to add a _composite suffix to the name of the existing headers but don't have a strong opinion about it.

If you decide to try this re-organization, please do it as preparatory commits and then rebase the MAC delegation on top it and not as additional patches. The history will be easier to understand as we will avoid crypto_builtin_mac.h being introduced and then removed.

Copy link
Contributor

@ronald-cron-arm ronald-cron-arm left a comment

Choose a reason for hiding this comment

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

A few things I noticed before reaching the operation structure definitions issue.

include/psa/crypto_builtin.h Outdated Show resolved Hide resolved
include/psa/crypto_builtin.h Outdated Show resolved Hide resolved
library/psa_crypto_mac.c Outdated Show resolved Hide resolved
library/psa_crypto_mac.h Outdated Show resolved Hide resolved
library/psa_crypto_mac.h Outdated Show resolved Hide resolved
library/psa_crypto_mac.h Outdated Show resolved Hide resolved
library/psa_crypto_mac.h Outdated Show resolved Hide resolved
library/psa_crypto_mac.h Outdated Show resolved Hide resolved
library/psa_crypto_mac.h Outdated Show resolved Hide resolved
library/psa_crypto_mac.h Outdated Show resolved Hide resolved
@stevew817 stevew817 force-pushed the dispatch_mac_operations branch from 19e4243 to 08d356d Compare April 26, 2021 12:32
@stevew817
Copy link
Contributor Author

Rebased with the fundamental header changes as prep work as requested.

Steps:

  • Started from latest development
  • Issued 4 commits with changes to how the inclusion chain for crypto_struct.h is set up. Contexts for multi-part 'primitive' operations are now in _primitives.h files, and boilerplate for the corresponding _composites.h has also been added. The gist being that contexts from _composites can reference whatever is in _primitives.
  • Cherry-picked all commits from the previous state of the PR (which is now accessible here: https://github.com/stevew817/mbedtls/tree/dispatch_mac_operations_2) one by one and in order.
    • Reworked the first commit with the already-given review feedback (since I was rebasing anyway) and a small change from upstream (PSA_CRYPTO_TEST_DRIVER_LIFETIME became PSA_CRYPTO_TEST_DRIVER_LOCATION).
    • Reworked the first two commits to account for the change in how the header inclusion is done

Copy link
Contributor

@ronald-cron-arm ronald-cron-arm left a comment

Choose a reason for hiding this comment

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

Thanks for the changes. I've done a complete review this time. I've been able to leverage the commit history to ease the review, thank you for that. It was not really easy with the three "Migrate ..." commits though, as they both move and modify code. It looks overall good to me but for two things:

  1. We miss a test_driver_mac.c (one as simple as test_driver_aead.c is enough) and corresponding tests in test_suite_psa_crypto_driver_wrappers.
  2. The HMAC internal interface is so close to be just a MAC PSA driver interface that is a bit of a pity not to switch to it.

include/psa/crypto_struct.h Outdated Show resolved Hide resolved
library/psa_crypto.c Outdated Show resolved Hide resolved
library/psa_crypto_mac.c Outdated Show resolved Hide resolved
library/psa_crypto_mac.c Outdated Show resolved Hide resolved
library/psa_crypto.c Show resolved Hide resolved
library/psa_crypto_mac.c Outdated Show resolved Hide resolved
library/psa_crypto_mac.c Outdated Show resolved Hide resolved
include/psa/crypto_builtin_composites.h Outdated Show resolved Hide resolved
@@ -23,15 +23,93 @@

#include <psa/crypto.h>

/** Internal API for starting an HMAC operation, using PSA hash primitives.
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems we are quite close for this interface to be the MAC PSA driver interface (but for clone). Thus, what about to do it ? For sign setup the API would be:

psa_status_t mbedtls_psa_hmac_sign_setup(
    mbedtls_psa_hmac_operation_t *operation,
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer, size_t key_buffer_size,
    psa_algorithm_t alg )

Then in psa_crypto.c instead of calling this HMAC PSA driver interface, call the driver wrapper interface and you get acceleration support if any.

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 thought about that while I was doing the original work, and then decided against doing it here because it would be a pretty invasive change. Doing it for HKDF is pretty straight-forward, but the way TLS 1.2 PRF is implemented requires being able to copy the HMAC context, and the PSA MAC API did not provide for that functionality. Meaning that on driver-accelerated (H)MAC, we don't currently have a way to copy the context structure, so for TLS 1.2 PRF it would regardless have meant that we need to stick to a pure-software implementation on top of PSA hash.

And given that outcome, I believe it doesn't make sense to do it for HKDF either. Meaning that if the need is gone, it doesn't quite make sense to put in the work either.

The alternative would be to move HKDF onto the MAC API, and move TLS 1.2 PRF directly onto the hash API (without mentioning HMAC). Is that preferable?

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 did end up converting the calls to the internal HMAC interface to regular MAC calls, see the last two commits
f9cc658 (converting HKDF) and 1878c0d (converting TLS 1.2 PRF and making the HMAC implementation static to the MAC driver).

The downside is that the context structure for TLS 1.2 PRF key derivation now contains the secret instead of the hashed secret. I don't consider this a risk, since an attacker can do as much with the hashed secret as with the actual secret. It also opens up a path for doing these operations with actual key as secret input instead of plaintext buffers, which would be good for eventually supporting e.g. an HKDF operation on an opaque key in an accelerator which only supports HMAC, or for storing the TLS 1.2 PRF secret as an opaque key.

If you don't like these, give the feedback and I can just drop them (these two commits) from the PR, in which case 562247a contains all other changes you requested (besides unification of HMAC with MAC API).

include/psa/crypto_builtin_composites.h Outdated Show resolved Hide resolved
@stevew817 stevew817 force-pushed the dispatch_mac_operations branch from 08d356d to 197e0f8 Compare April 29, 2021 19:32
@stevew817
Copy link
Contributor Author

Changes:

  • force-pushed 197e0f8 with a clean diff to account for the non-compiling intermediate commits
  • Added commits for review feedback by @ronald-cron-arm
  • Special attention to the last two commits. They show a way to migrate the PSA Crypto core out of using an internal HMAC API and instead leveraging the actual MAC API, which would allow for accelerating those operations. Doing those changes would also create a path forward to eventually allow doing HKDF / TLS 1.2 PRF with key handles instead of raw key material, which would open up for doing HKDF / TLS 1.2 PRF with opaque key material.
    However, these changes are also a bit more extensive than what this PR should have in scope. If they're too much, I will drop them from the PR, and then commit 562247a would be a good state to merge, IMO.

@stevew817
Copy link
Contributor Author

Thanks @ronald-cron-arm, fixed now.

Copy link
Contributor

@ronald-cron-arm ronald-cron-arm left a comment

Choose a reason for hiding this comment

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

Almost ok on my side, just some "mbedtls_" prefix missing in the test code and small improvement suggestions.

tests/include/test/drivers/mac.h Outdated Show resolved Hide resolved
tests/include/test/drivers/mac.h Outdated Show resolved Hide resolved
tests/include/test/drivers/mac.h Outdated Show resolved Hide resolved
tests/include/test/drivers/mac.h Outdated Show resolved Hide resolved
tests/src/drivers/test_driver_mac.c Outdated Show resolved Hide resolved
library/psa_crypto.c Outdated Show resolved Hide resolved
library/psa_crypto.c Outdated Show resolved Hide resolved
library/psa_crypto.c Show resolved Hide resolved
stevew817 added 7 commits May 10, 2021 11:29
It makes sense to do the length checking in the core rather than expect
each driver to deal with it themselves. This puts the onus on the core to
dictate which algorithm/key combinations are valid before calling a driver.

Additionally, this commit also updates the psa_mac_sign_finish function
to better deal with output buffer sanitation, as per the review comments
on Mbed-TLS#4247.

Signed-off-by: Steven Cooreman <[email protected]>
The PSA core checks the key type and algorithm combination before
calling the driver, so the driver doesn't have to do this once more.

The PSA core will also not start an operation with a requested length
which is larger than the full MAC output size, so the output length check
in the driver isn't needed as long as the driver returns an error on
mac_setup if it doesn't support the underlying hash algorithm.

Signed-off-by: Steven Cooreman <[email protected]>
@stevew817 stevew817 force-pushed the dispatch_mac_operations branch from eaa8d4e to ae3ec52 Compare May 10, 2021 09:29
@stevew817
Copy link
Contributor Author

I believe I addressed all of your feedback, @ronald-cron-arm , with the exception of the zero-check which I believe makes sense to leave there as a note for static analysers.

Copy link
Contributor

@ronald-cron-arm ronald-cron-arm left a comment

Choose a reason for hiding this comment

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

Thanks for all your good work on this PR. LGTM.

Copy link
Contributor

@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.

Looks almost good to me.


status = psa_mac_finish_internal( operation, mac, mac_size );
/* Sanity checks on output buffer length. */
if( mac_size == 0 || mac_size < operation->mac_size )
Copy link
Contributor

Choose a reason for hiding this comment

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

As Ronald noted in https://github.com/ARMmbed/mbedtls/pull/4247/files#r629107039, it's surprising to check for mac_size == 0 when we know that it would imply mac_size < operation->mac_size since the operation setup guarantees that operation->mac_size > 0. You make a good point that this avoids false positives from static analyzers about cases that can only happen if mac_size == 0. However, it still warrants a comment, otherwise the next person who works on the code might decide to remove this apparently superfluous check.

How about changing the code to this?

/* Sanity check. This will guarantee that mac_size != 0 (and so mac != NULL) once all the error checks are done. */
if( operation->mac_size == 0 )
    return( PSA_ERROR_BAD_STATE );
if( mac_size < operation->mac_size )
    return( PSA_ERROR_BUFFER_TOO_SMALL );

A static analyzer should be just as happy, a compiler will only have a couple of instructions more to generate, this adds a bit of robustness, and the code looks less surprising.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

return( mac_setup( operation, attributes, key_buffer, key_buffer_size, alg,
1 ) );
return( mac_setup( operation,
attributes, key_buffer, key_buffer_size, alg ) );
}

static psa_status_t mac_verify_setup(
Copy link
Contributor

Choose a reason for hiding this comment

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

mac_verify_setup and mac_sign_setup are now identical. Why not call mac_setup directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

stevew817 added 2 commits May 11, 2021 11:09
Since a valid mac operation context would guarantee that the stored
mac size is >= 4, it wasn't immediately obvious that the zero-length
check is meant for static analyzers and a bit of robustness.

Signed-off-by: Steven Cooreman <[email protected]>
Since they became equivalent after moving the is_sign checking back to
the PSA core, they're now redundant, and the generic mac_setup function
can just be called directly.

Signed-off-by: Steven Cooreman <[email protected]>
Copy link
Contributor

@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.

Thanks for the update, looks good to me!

We're having some trouble with the CI, so you can ignore the massive failures. Once this is resolved we'll trigger new builds.

@gilles-peskine-arm gilles-peskine-arm added the needs-ci Needs to pass CI tests label May 11, 2021
@stevew817 stevew817 removed the needs-review Every commit must be reviewed by at least two team members, label May 11, 2021
@ronald-cron-arm ronald-cron-arm merged commit eb3e463 into Mbed-TLS:development May 11, 2021
@ronald-cron-arm
Copy link
Contributor

@stevew817 Forgot about it before to merge again, please create the backport to development_2.x.

stevew817 added a commit to stevew817/mbedtls that referenced this pull request May 11, 2021
It makes sense to do the length checking in the core rather than expect
each driver to deal with it themselves. This puts the onus on the core to
dictate which algorithm/key combinations are valid before calling a driver.

Additionally, this commit also updates the psa_mac_sign_finish function
to better deal with output buffer sanitation, as per the review comments
on Mbed-TLS#4247.

Signed-off-by: Steven Cooreman <[email protected]>
ronald-cron-arm pushed a commit to ronald-cron-arm/mbedtls that referenced this pull request Jun 30, 2021
It makes sense to do the length checking in the core rather than expect
each driver to deal with it themselves. This puts the onus on the core to
dictate which algorithm/key combinations are valid before calling a driver.

Additionally, this commit also updates the psa_mac_sign_finish function
to better deal with output buffer sanitation, as per the review comments
on Mbed-TLS#4247.

Signed-off-by: Steven Cooreman <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-ci Needs to pass CI tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants