Skip to content

Multipart AEAD buffer output sizes #102

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

Merged

Conversation

gilles-peskine-arm
Copy link
Collaborator

  • Allow delayed output in AEAD for all algorithms. Although CCM and GCM allow the data to be encrypted or decrypted as a stream cipher, some hardware implementations can only process a full block at a time apart from the last block. Fix ARMmbed/psa-crypto#130
  • Add output buffer parameter for psa_aead_verify. It needs it as much as psa_aead_finish.
  • Add buffer size macros for multipart AEAD functions.
  • Add a flag for built-from-block-cipher in AEAD algorithm encoding.
  • Declare and implement ChaCha20 and ChaCha20-Poly1305 algorithms.

Out of scope: testing the new algorithms beyond smoke tests; testing the new macros; testing multipart AEAD.

Make it easy to distinguish generic constructions on top of block
ciphers, such as CCM or GCM, from specialized algorithms such as
Chacha20-Poly1305.
Group PSA_AEAD_DECRYPT_OUTPUT_SIZE with PSA_AEAD_ENCRYPT_OUTPUT_SIZE.
Like psa_aead_finish(), psa_aead_verify() needs to produce output from
the last partial block of input if psa_aead_update() cannot produce
output byte by byte.
New macros PSA_AEAD_UPDATE_OUTPUT_SIZE, PSA_AEAD_FINISH_OUTPUT_SIZE
and PSA_AEAD_VERIFY_OUTPUT_SIZE to determine the output buffer sizes
for psa_aead_update(), psa_aead_finish() and psa_aead_verify().
Don't hard-code an IV in cipher test functions. It restricts what can
be used as test data.
Recognize MBEDTLS_ERR_PLATFORM_xxx in mbedtls_to_psa_error().
Make it a little easier to add ChaCha20-Poly1305.

This also fixes the error code in case mbedtls_gcm_setkey() fails with
a status that doesn't map to INVALID_ARGUMENT.
Declare algorithms for ChaCha20 and ChaCha20-Poly1305, and a
corresponding (common) key type.

Don't declare Poly1305 as a separate algorithm because it's a one-time
authenticator, not a MAC, so the API isn't suitable for it (no way to
use a nonce).
Smoke tests: test data for ChaCha20 calculated with PyCryptodome; test
vector from RFC 7539 for ChaCha20-Poly1305.
Do not require finish() to have empty output for any algorithm. Some
hardware does not support immediate stream processing.
@gilles-peskine-arm gilles-peskine-arm added bug Something isn't working enhancement New feature or request needs: review The pull request is ready for review. This generally means that it has no known issues. api-spec Issue or PR about the PSA specifications labels May 6, 2019
Copy link
Contributor

@athoelke athoelke left a comment

Choose a reason for hiding this comment

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

overall approach looks sound, still need to double check the buffer computation logic but on first viewing it is broadly correct.

However, there are a few problems - see individual comments.

*/
#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \
(plaintext_length) - PSA_AEAD_TAG_LENGTH(alg) : \
Copy link
Contributor

Choose a reason for hiding this comment

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

copy paste bug? - plaintext_length -> ciphertext_length

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like a pre-existing bug. Good to add a commit to fix that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed, and I modified the AEAD tests to use this macro.

* implementation to delay the output until it has a full block. */
#define PSA_AEAD_UPDATE_OUTPUT_SIZE(alg, input_length) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
((plaintext_length) + PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE - 1) / PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. parameter mismatch: plaintext_length -> input_length
  2. Result for AEAD on block cipher is not rounded, but scaled. Presume missing ( ... ) * PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE

#define PSA_AEAD_UPDATE_OUTPUT_SIZE(alg, input_length) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
((plaintext_length) + PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE - 1) / PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
(plaintext_length))
Copy link
Contributor

Choose a reason for hiding this comment

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

parameter mismatch: plaintext_length -> input_length

/** A sufficient output buffer size for psa_aead_update().
*
* If the size of the output buffer is at least this large, it is
* guaranteed that psa_aead_finish() will not fail due to an
Copy link
Contributor

Choose a reason for hiding this comment

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

Just double checking that you intended to refer to the finishing function here, or should this be psa_aead_update()?

*/
#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \
(plaintext_length) - PSA_AEAD_TAG_LENGTH(alg) : \
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like a pre-existing bug. Good to add a commit to fix that.

Copy link
Contributor

@Patater Patater left a comment

Choose a reason for hiding this comment

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

Do we need a new error code returned from any of the AEAD functions in order to indicate "The hardware is busy/delayed right now and isn't ready to return anything yet. Try again later."?

@gilles-peskine-arm
Copy link
Collaborator Author

Do we need a new error code returned from any of the AEAD functions in order to indicate "The hardware is busy/delayed right now

No. The API is fully synchronous. If the hardware is busy, the call blocks.

All calls consume all the input (or fail). What's implementation-defined is only how whether the output at each stage is the maximum that can be mathematically calculated or not. Is this something that needs to be clarified in the documentation of specific functions?

@gilles-peskine-arm gilles-peskine-arm added this to the api-1.0-beta-3 milestone May 15, 2019
@gilles-peskine-arm gilles-peskine-arm added needs: ci Needs a passing full CI run and removed needs: review The pull request is ready for review. This generally means that it has no known issues. labels May 15, 2019
@Patater
Copy link
Contributor

Patater commented May 16, 2019

CI failure is ABI job (known to fail until Mbed-TLS/mbedtls#2636 lands in the development branch) and USE_PSA_CRYPTO, which doesn't work on the API branch.

@Patater Patater merged commit 16ab391 into ARMmbed:psa-api-1.0-beta May 16, 2019
@Patater Patater removed the needs: ci Needs a passing full CI run label May 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-spec Issue or PR about the PSA specifications bug Something isn't working enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants