-
Notifications
You must be signed in to change notification settings - Fork 2.8k
PSA: example programs for HMAC and AEAD vs legacy #5436
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
Conversation
This is meant to highlight similarities and differences in the multi-part HMAC APIs. Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This is meant to highlight similarities and differences in the APIs. Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
5501e24 to
ecffd96
Compare
Existing example programs in this directory are already incompatible with that option, so this is probably acceptable here too. Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
programs/psa/aead_cipher_psa.c
Outdated
| : mode == MBEDTLS_MODE_CHACHAPOLY ? "ChachaPoly" | ||
| : "???"; | ||
|
|
||
| printf( "cipher: %s, %d, %s, %zu\n", ciph, key_bits, mode_str, tag_len ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CI says we're still testing with a version of mingw that doesn't support %zu. (And grep says we do use it but only in memory_buffer_alloc). We use MBEDTLS_PRINTF_SIZET instead which has a workaround for old mingw.
Also this should be mbedtls_printf, not printf.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also this should be
mbedtls_printf, notprintf.
I had a look at the other programs in programs/psa and they're using printf, so I decided to follow the flow. I'm happy to change to mbedtls_printf if you insist, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding zu, I'm inclined to just cast to unsigned there's really no risk of overflow here, and to a reader who it's already familiar with it MBEDTLS_PRINTF_SIZET may be a distraction. (We are casting to unsigned in other programs, and so far the only uses of MBEDTLS_PRINTF_SIZET are in the library.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a look at the other programs in programs/psa and they're using printf
That dates back from ARMmbed/mbed-crypto#74, which was motivated by the way we were trying to do crypto/tls separation at the time. I'm not sure that's the right decision today.
I do think it would be nicer to stick to standard functions in example code. On the other hand, this limits the code's portability. So the question is, to we care about being able to run sample program as-is on ultra-constrained or exotic platforms that lack e.g. printf or malloc or exit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think it would be nicer to stick to standard functions in example code.
I agree. Although it reduces the sample programs portability, I think it is more useful like that for users. As a user, reading the sample code I would definitely wonder what these mbedtls_ prefixed functions do in the background. I wouldn't be certain if some library functions depend on that behaviour and if I am allowed to use standard functions.
Users of that ultra-constrained or exotic platforms need to hook up their implementations in the platform abstraction layer anyway in the first place and that couple of find and replace to make the sample code work, would be a negligible effort.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keeping in mind that “exotic” platforms include not-that-ancient Windows, e.g. this discussion started with an error from using standard functionality on MinGW.
For these cases where we do care and the unportability is minor, we could define a standard name on platforms where it's missing. We don't do that in library code because it can be disruptive to invade the standard namespace (and this absolutely must not be done in a public header), but that's less of a concern in a sample program. For example, here, how about using PRIuPTR and defining it if it's unset and the implementation is MinGW?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tbh, I never understood why mbedtls_printf() and all were introduced in the example programs in the first place.
Most of the programs are mostly educational: the goal is mainly to read them, run them on you development platform if it helps understanding how they work (perhaps with some editing etc.), and perhaps copy-paste bits and pieces to you own program. I can't see why you'll need or want to run them as-is on an embedded device.
Some of the the programs are not just educational, but could also be used as actual utilities, for example the x509 ones. Even then, I'm not convinced running them as-is on embedded devices is a reasonable goal: these programs take command-line options, which hardly make sense in an embedded context, so at least some adaptation will be needed anyway.
Some other programs are for tests (ssl_xxx2.c) - this is perhaps the thing you're most likely to want to run on target, but you also have the issue of command-line options, currently the program depend on the sockets API, which I'd say is much more of a constraint the things from libc...
Anyway, at some point we might want to rationalize that, but I hope we can get this PR merged before that :)
For example, here, how about using PRIuPTR and defining it if it's unset and the implementation is MinGW?
I think that's a reasonable option, but in this case I think using "%u", (unsigned) size works just as well, and it's also what we already do in several other places.
Both functions use int. Using size_t results is a warning from MSVC. Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
|
@gilles-peskine-arm Thanks for taking a look. Sorry for not getting a clean CI before requesting a review. I'll wait for the CI results before requesting a re-review. (It's taking me more rounds than I expected to fully pass CI on these seemingly rather simple programs.) |
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
72a9fb6 to
aab5258
Compare
|
@gilles-peskine-arm Ok, I finally passed the CI, so this is ready for you to review again. @yanesca Do you intend to review this, or were you just commenting the |
|
@mpg I was just commenting, didn't intend to be a reviewer. |
programs/psa/aead_cipher_psa.c
Outdated
| psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT ); | ||
| psa_set_key_algorithm( &attributes, *alg ); | ||
| psa_set_key_type( &attributes, key_type ); | ||
| psa_set_key_bits( &attributes, key_bits ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't have to call set_key_bits when importing a key: this is automatically deduced from the imported data. (In theory there could be key types for which this is not true, but it's true for all of the currently defined types.) I don't know whether it's better to be explicit or terse here, given that this is an exampleprogram.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
- avoid hardcoded sizes when there's a macro for that - avoid mutable global variables - zeroize potentially-sensitive local buffer on exit Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Visual Studio and CMake didn't like having targets with the same name, albeit in different directories. Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
4f7eba5 to
12ec571
Compare
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
|
Passing CI again and ready for another round of review. |
gilles-peskine-arm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks mostly good, just some minor issues and some optional suggestions.
| /* Dummy key material - never do this in production! | ||
| * 32-byte is enough to all the key size supported by this program. */ | ||
| const unsigned char key_bytes[32] = { 0x2a }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not suggesting this for now, but for a follow-up: how about generating a random key instead? This would actually be good practice, and it would demonstrate how to generate a key (classic API: set up an entropy context, set up a DRBG, generate a byte string of a length matching the key size; PSA: call psa_generate_key).
key_ladder_demo has an example of using psa_import_key, so we wouldn't lose that. Or we could keep a static key in the HMAC programs, for variety.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree this would be a nice follow-up, though perhaps it could be its own example so as to not distract from the main purpose of comparing cipher APIs.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Used to print "cipher:" when it was the cipher part of a program that had both cipher and PSA. Now it doesn't really make sense. Align the output to match the PSA version of this program. Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
| const char *ciph = "???"; | ||
| mbedtls_cipher_type_t type = mbedtls_cipher_get_type( ctx ); | ||
| const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type( type ); | ||
| const char *ciph = mbedtls_cipher_info_get_name( info ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: this results in output like
AES-128-GCM, 128, GCM, 16
Either AES, 128, GCM, 16 or AES-128-GCM, 16 would make more sense.
tom-daubney-arm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I re-ran my 2nd review of this PR yesterday after the comments had come in from the other review.This all LGTM now. Thanks.
Description
Resolves #5208 "There are differences in how MD/Cipher and PSA represent information. Create two simple example programs showing the differences by performing the same operation with both APIs, with extensive comments."
Actually I didn't feel the need for that many comments, I thought just looking at the functions side by side is enough, with a summary comment at the top of the file. Reviewers are welcome to disagree of course.
Status
READY
Requires Backporting
NO
Steps to test or reproduce