-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Make mbedtls_aes_context be shallow-copyable #2147
Comments
Hi @jethrogb, thank you for your detailed and comprehensible report, which shows that shallow copies of I am not aware of any use of shallow-copying in the library, but neither of any documentation that would explicitly forbid it. So we should either (a) add documentation stating that they are forbidden, (b) add a dedicated copy function, or (c) rewrite the context to support shallow copies. In general I think that shallow-copying of structures containing references is a dangerous thing to do; one should really use dedicated move- or copy-routines. Ping @gilles-peskine-arm. Kind regards, |
ARM Internal Ref: IOTSSL-2608 |
We don't require alternative implementations to make their contexts copyable. Therefore the library doesn't guarantee in general that you can take a copy of a context and use it. This is mostly relevant in that you can't reliably make a copy of a context and use the copy independently of the original. But it also means that you can't reliably move a context in memory. If you know that you aren't using an alternative implementation, then you can inspect the context type and figure out that most contexts are movable and copyable. The AES context, however, is not movable due to the embedded pointer. We can't change the context type without breaking compatibility with code that makes assumptions on the context, which by our compatibility policy means waiting for a new major release of Mbed TLS. So our options are limited. I'd like to make the library more robust, even if we don't officially say that it's ok to move a context — as you say we don't officially say that it isn't ok either. But your proposal is problematic because it breaks compatibility with the semantics of the context type. The library code uses |
Thanks for your input. Let me try to provide some more context.
This type of moving/copying is pretty common when using MbedTLS with another language such as C++ or Rust. C++ has the ability to run arbitrary code on move, but Rust does not. In general moving/inline allocation is preferred since you're avoiding extraneous heap allocations.
NB. A lot of contexts are not copyable because they contain pointers to allocated memory that will be freed on I just remembered that a
Is this policy spelled out somewhere? It's never clear to me if there are any parts that are considered "internal" vs. "Public API". Is it within the policy to make things break when adding a (default-undefined) |
Regarding compatibility: our compatibility policy only applies to the default For the default configuration, we're pretty conservative about what we consider to be internal. For types, we don't change the layout of a type unless it's declared in an We can make a new compile-time option, but we tend not to like that because it adds to our testing burden. Option combinations grow exponentially with the number of options, and it's difficult to ensure that we're testing all “interesting” combinations. |
Revisiting this now that we have a firm plan for Mbed TLS 3.0 — releasing in June 2021. One of the things we're changing in Mbed TLS 3.0 is that the layout of data structures such as Additionally we need to establish the requirement on alternative implementations to not have the same problem, namely: it must be possible to move a data structure which is the context of an alternative implementation. This additional requirement is purely documentation and testing. At least the documentation part should be done in 3.0. This applies to all alt contexts, not just AES. Thus, here is the definition of done for this task:
|
Labeling as "size:S" based on the minimal amount of work we need to do for 3.0 (add documentation, one small code change + one issue for later, or create two issues for later). Obviously systematic testing of all alt-able contexts would be a larger size. |
Replace RK pointer in AES context with a buffer offset, to allow shallow copying. Fixes Mbed-TLS#2147. Signed-off-by: Werner Lewis <werner.lewis@arm.com>
Replace RK pointer in AES context with a buffer offset, to allow shallow copying. Fixes Mbed-TLS#2147. Signed-off-by: Werner Lewis <werner.lewis@arm.com>
Replace RK pointer in AES context with a buffer offset, to allow shallow copying. Fixes Mbed-TLS#2147. Signed-off-by: Werner Lewis <werner.lewis@arm.com>
Replace RK pointer in AES context with a buffer offset, to allow shallow copying. Fixes Mbed-TLS#2147. Signed-off-by: Werner Lewis <werner.lewis@arm.com>
Issue originally raised with title: Arbitrary stack read in AES code
Originally reported to support.mbedtls@arm.com on February 12 2018, but never got a response.
mbedtls_aes_setkey_enc
stores a pointer to somewhere inside the (then-current) location ofmbedtls_aes_context
in the samembedtls_aes_context
. When changing the address of thembedtls_aes_context
, for example by returning it from a function, the address is no longer valid. As a result, the encryption/decryption functions read arbitrary memory instead of the intended round key, ultimately returning bogus output. The sample C program below demonstrates the problem, at least on my platform. You might need to replacegethostbyname
by another function that uses the stack to see the issue.The same applies to
mbedtls_ctr_drbg_context
since it stores anmbedtls_aes_context
inline.I have not found any documentation that states contexts should not be moved in memory, and I've also not encountered any other types that behave badly when that's done (such moving is very common in my codebase).
The pointer in question is
rk
, which is required only whenMBEDTLS_PADLOCK_ALIGN16
is defined. Aligned memory can't be guaranteed when moving the context. My recommended solution would be to specifically allocate aligned memory only whenMBEDTLS_PADLOCK_ALIGN16
is defined and store that pointer, and in other cases just use an inline array directly.I think the potential for actual information leakage resulting from the invalid memory reads is low, since the memory is mixed in as part of the AES algorithm.
The text was updated successfully, but these errors were encountered: