-
Notifications
You must be signed in to change notification settings - Fork 96
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
Multipart AEAD buffer output sizes #102
Conversation
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.
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.
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.
include/psa/crypto_sizes.h
Outdated
*/ | ||
#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \ | ||
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \ | ||
(plaintext_length) - PSA_AEAD_TAG_LENGTH(alg) : \ |
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.
copy paste bug? - plaintext_length
-> ciphertext_length
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 like a pre-existing bug. Good to add a commit to fix that.
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.
Fixed, and I modified the AEAD tests to use this macro.
include/psa/crypto_sizes.h
Outdated
* 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 : \ |
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.
- parameter mismatch:
plaintext_length
->input_length
- Result for AEAD on block cipher is not rounded, but scaled. Presume missing
( ... ) * PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE
include/psa/crypto_sizes.h
Outdated
#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)) |
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.
parameter mismatch: plaintext_length
-> input_length
include/psa/crypto_sizes.h
Outdated
/** 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 |
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.
Just double checking that you intended to refer to the finishing function here, or should this be psa_aead_update()
?
include/psa/crypto_sizes.h
Outdated
*/ | ||
#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \ | ||
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \ | ||
(plaintext_length) - PSA_AEAD_TAG_LENGTH(alg) : \ |
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 like a pre-existing bug. Good to add a commit to fix that.
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.
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."?
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? |
CI failure is ABI job (known to fail until Mbed-TLS/mbedtls#2636 lands in the development branch) and |
psa_aead_verify
. It needs it as much aspsa_aead_finish
.Out of scope: testing the new algorithms beyond smoke tests; testing the new macros; testing multipart AEAD.