Document when a context must be initialized or not, when it must be
set up or not, and whether it needs a private key or a public key will
do.
The implementation is sometimes more liberal than the documentation,
accepting a non-set-up context as a context that can't perform the
requested information. This preserves backward compatibility.
For mbedtls_pk_parse_key and mbedtls_pk_parse_keyfile, the password is
optional. Clarify what this means: NULL is ok and means no password.
Validate parameters and test accordingly.
A 0-length buffer for the key is a legitimate edge case. Ensure that
it works, even with buf=NULL. Document the key and keylen parameters.
There are already test cases for parsing an empty buffer. A subsequent
commit will add tests for writing to an empty buffer.
The previous introduction of constant deprecation macros
in platform_util.h lead to failure of tests/scrips/check-names.sh
because the regular expressions in the latter choked on the brackets
in the part `__attribute__((deprecated))` of the definition of the
helper type `mbedtls_deprecated_{numeric|string}_constant_t`.
Postponing any further study and potential robustness improvements
in check-names.sh to another time, this commit circumvents this
problem by temporarily abbreviating `__attribute__((deprecated))`
as `MBEDTLS_DEPRECATED`, which doesn't lead to problems with
check-names.sh.
This commit introduces macros
* MBEDTLS_DEPRECATED_STRING_CONSTANT
* MBEDTLS_DEPRECATED_NUMERIC_CONSTANT
to platform_util.h which can be used to deprecate public macro constants.
Their definition is essentially taken from dhm.h where the
MBEDTLS_DEPRECATED_STRING_CONSTANT was used to deprecate
insecure hardcoded DHM primes.
Add inclusion to configration file in header files,
instead of relying on other header files to include
the configuration file. This issue resolves#1371
- Be specific about the constraints: be a readable/writable buffer of length
X, be an initialized context, be a context initialized and bound to a key...
- Always use full sentences with all the required pronouns.
It's better if the macro receives the condition as an expression rather than a
string - that way it can choose to use it as is or stringify it. Also, the
documentation states that the parameter is an expression, not a string.
The test framework for validation of parameters depends on the macro
MBEDTLS_PARAM_FAILED() being set to its default value when building the
library. So far the test framework attempted to define this macro but this was
the wrong place - this definition wouldn't be picked by the library.
Instead, a different approach is taken: skip those tests when the macro is
defined in config.h, as in that case we have no way to know if it will indeed
end up calling mbedtls_param_failed() as we need it to.
This commit was tested by manually ensuring that aes_invalid_params:
- passes (and is not skipped) in the default configuration
- is skipped when MBEDTLS_PARAM_FAILED() is defined in config.h
The previous prototype gave warnings are the strings produced by #cond and
__FILE__ are const, so we shouldn't implicitly cast them to non-const.
While at it modifying most example programs:
- include the header that has the function declaration, so that the definition
can be checked to match by the compiler
- fix whitespace
- make it work even if PLATFORM_C is not defined:
- CHECK_PARAMS is not documented as depending on PLATFORM_C and there is
no reason why it should
- so, remove the corresponding #if defined in each program...
- and add missing #defines for mbedtls_exit when needed
The result has been tested (make all test with -Werror) with the following
configurations:
- full with CHECK_PARAMS with PLATFORM_C
- full with CHECK_PARAMS without PLATFORM_C
- full without CHECK_PARAMS without PLATFORM_C
- full without CHECK_PARAMS with PLATFORM_C
Additionally, it has been manually tested that adding
mbedtls_aes_init( NULL );
near the normal call to mbedtls_aes_init() in programs/aes/aescrypt2.c has the
expected effect when running the program.
It was inconsistent between files: sometimes 3 arguments, sometimes one.
Align to 1 argument for the macro and 3 for the function, because:
- we don't need 3 arguments for the macro, it can add __FILE__ and __LINE__
in its expansion, while the function needs them as parameters to be correct;
- people who re-defined the macro should have flexibility, and 3 arguments
can give the impression they they don't have as much as they actually do;
- the design document has the macro with 1 argument, so let's stick to that.
The function called through the macro MBEDTLS_PARAM_FAILED() must be supplied by
users and makes no sense as a library function, apart from debug and test.
The SSL module accesses ECDH context members directly to print debug
information. This can't work with the new context, where we can't make
assumptions about the implementation of the context. This commit adds
new debug functions to complete the encapsulation of the ECDH context
and work around the problem.
We want to support alternative software implementations and we extend
the ECDH context to enable this. The actual functional change that makes
use of the new context is out of scope for this commit.
Changing the context breaks the API and therefore it has to be
excluded from the default configuration by a compile time flag.
We add the compile time flag to the module header instead of
`config.h`, because this is not a standalone feature, it only
enables adding new implementations in the future.
The new context features a union of the individual implementations
and a selector that chooses the implementation in use. An alternative
is to use an opaque context and function pointers, like for example the
PK module does it, but it is more dangerous, error prone and tedious to
implement.
We leave the group ID and the point format at the top level of the
structure, because they are very simple and adding an abstraction
layer around them away does not come with any obvious benefit.
Other alternatives considered:
- Using the module level replacement mechanism in the ECP module. This
would have made the use of the replacement feature more difficult and
the benefit limited.
- Replacing our Montgomery implementations with a new one directly. This
would have prevented using Montgomery curves across implementations.
(For example use implementation A for Curve448 and implementation B for
Curve22519.) Also it would have been inflexible and limited to
Montgomery curves.
- Encoding the implementation selector and the alternative context in
`mbedtls_ecp_point` somehow and rewriting `mbedtls_ecp_mul()` to
dispatch between implementations. This would have been a dangerous and
ugly hack, and very likely to break legacy applications.
- Same as above just with hardcoding the selector and using a compile
time option to make the selection. Rejected for the same reasons as
above.
- Using the PK module to provide to provide an entry point for
alternative implementations. Like most of the above options this
wouldn't have come with a new compile time option, but conceptually
would have been very out of place and would have meant much more work to
complete the abstraction around the context.
In retrospect:
- We could have used the group ID as the selector, but this would have
made the code less flexible and only marginally simpler. On the other
hand it would have allowed to get rid of the compile time option if a
tight integration of the alternative is possible. (It does not seem
possible at this point.)
- We could have used the same approach we do in this commit to the
`mbedtls_ecp_point` structure. Completing the abstraction around this
structure would have been a much bigger and much riskier code change
with increase in memory footprint, potential decrease in performance
and no immediate benefit.
In the future we want to support alternative ECDH implementations. We
can't make assumptions about the structure of the context they might
use, and therefore shouldn't access the members of
`mbedtls_ecdh_context`.
Currently the lifecycle of the context can't be done without direct
manipulation. This commit adds `mbedtls_ecdh_setup()` to complete
covering the context lifecycle with functions.
`mbedtls_ecp_tls_read_group()` both parses the group ID and loads the
group into the structure provided. We want to support alternative
implementations of ECDH in the future and for that we need to parse the
group ID without populating an `mbedtls_ecp_group` structure (because
alternative implementations might not use that).
This commit moves the part that parses the group ID to a new function.
There is no need to test the new function directly, because the tests
for `mbedtls_ecp_tls_read_group()` are already implicitly testing it.
There is no intended change in behaviour in this commit.
The sanity checking script tests/scripts/check-names.sh uses a
simple state machine paired with a sequence of `sed` commands to
extract enumeration constants from the code. This code, however,
doesn't work properly when using multiline comments in enumerations
such as recently done in the constants MBEDTLS_CIPHER_PSA_KEY_XXX.
This commit doesn't attempt to make check-names.sh more robust
but instead uses /* ... */ comment indicators in each comment line,
while silences check-names.sh.
Increasing the robustness of check-names.sh is instead tracked
in #2210.
For AEAD ciphers, the information contained in mbedtls_cipher_info
is not enough to deduce a PSA algorithm value of type psa_algorithm_t.
This is because mbedtls_cipher_info doesn't contain the AEAD tag
length, while values of type psa_algorithm_t do.
This commit adds the AEAD tag length as a separate parameter
to mbedtls_cipher_setup_psa(). For Non-AEAD ciphers, the value
must be 0.
This approach is preferred over passing psa_algorithm_t directly
in order to keep the changes in existing code using the cipher layer
small.
This commit implements the internal key slot management performed
by PSA-based cipher contexts. Specifically, `mbedtls_cipher_setkey()`
wraps the provided raw key material into a key slot, and
`mbedtls_cipher_free()` destroys that key slot.
This field determines whether a cipher context should
use an external implementation of the PSA Crypto API for
cryptographic operations, or Mbed TLS' own crypto library.
The commit also adds dummy implementations for the cipher API.
Revived from a previous PR by Gilles, see:
https://github.com/ARMmbed/mbedtls/pull/1293/files#diff-568ef321d275f2035b8b26a70ee9af0bR71
This will be useful in eliminating temporary stack buffers for transcoding the
signature: in order to do that in place we need to be able to make assumptions
about the size of the output buffer, which this macro will provide. (See next
commit.)
It's better for names in the API to describe the "what" (opaque keys) rather
than the "how" (using PSA), at least since we don't intend to have multiple
function doing the same "what" in different ways in the foreseeable future.
Unfortunately the can_do wrapper does not receive the key context as an
argument, so it cannot check psa_get_key_information(). Later we might want to
change our internal structures to fix this, but for now we'll just restrict
opaque PSA keys to be ECDSA keypairs, as this is the only thing we need for
now. It also simplifies testing a bit (no need to test each key type).
While at it, clarify who's responsible for destroying the underlying key. That
can't be us because some keys cannot be destroyed and we wouldn't know. So
let's leave that up to the caller.
This commit adds a field `psk_opaque` to the handshake parameter
struct `mbedtls_ssl_handshake_params` which indicates if the user
has configured the use of an opaque PSK.
This commit adds two public API functions
mbedtls_ssl_conf_psk_opaque()
mbedtls_ssl_set_hs_psk_opaque()
which allow to configure the use of opaque, PSA-maintained PSKs
at configuration time or run time.
In case of AEAD ciphers, the cipher mode (and not even the entire content
of mbedtls_cipher_info_t) doesn't uniquely determine a psa_algorithm_t
because it doesn't specify the AEAD tag length, which however is included
in psa_algorithm_t identifiers.
This commit adds a tag length value to mbedtls_psa_translate_cipher_mode()
to account for that ambiguity.
This commit adds the header file mbedtls/psa_util.h which contains
static utility functions `mbedtls_psa_xxx()` used in the integration
of PSA Crypto into Mbed TLS.
Warning: These functions are internal only and may change at any time.
Deprecate the module-specific XXX_HW_ACCEL_FAILED and
XXX_FEATURE_UNAVAILABLE errors, as alternative implementations should now
return `MBEDTLS_ERR_PLATFORM_HW_FAILED` and
`MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED`.
Context:
The macro `MBEDTLS_ECP_BUDGET()` is called before performing a
number of potentially time-consuming ECC operations. If restartable
ECC is enabled, it wraps a call to `mbedtls_ecp_check_budget()`
which in turn checks if the requested number of operations can be
performed without exceeding the maximum number of consecutive ECC
operations.
Issue:
The function `mbedtls_ecp_check_budget()` expects a the number
of requested operations to be given as a value of type `unsigned`,
while some calls of the wrapper macro `MBEDTLS_ECP_BUDGET()` use
expressions of type `size_t`.
This rightfully leads to warnings about implicit truncation
from `size_t` to `unsigned` on some compilers.
Fix:
This commit makes the truncation explicit by adding an explicit cast
to `unsigned` in the expansion of the `MBEDTLS_ECP_BUDGET()` macro.
Justification:
Functionally, the new version is equivalent to the previous code.
The warning about truncation can be discarded because, as can be
inferred from `ecp.h`, the number of requested operations is never
larger than 1000.
It turns out that in some environments MinGW esposes a non-conforming
(v)snprintf behavior despite the tests against the MSVC runtime pass.
Therefore it has been included in the "non-conforming" scope alongide
older MSVC rungime environments.
Previously, mbedtls_pkcs5_pbes2() was unconditionally declared
in `pkcs5.h` but defined as a stub returning
`MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE` in case
MBEDTLS_ASN1_PARSE_C was not defined.
In line with the previous commits, this commit removes declaration
and definition from both `pkcs5.h` and `pkcs5.c` in case
MBEDTLS_ASN1_PARSE_C is not defined.
Rename the PLATFORM HW error, to avoid ABI breakage with Mbed OS.
The value changed as well, as previous value was not in the range of
Mbed TLS low level error codes.
The previous comment in ecp.h that only functions that take a "restart
context" argument can restart was wrong due to ECDH and SSL functions.
Changing that criterion to "document says if can return IN PROGRESS".
This requires updating the documentation of the SSL functions to mention this
explicitly, but it's something we really ought to do anyway, a bit
embarrassing that this wasn't done already - callers need to know what
`MBEDTLS_ERR_SSL_xxx` error codes to special-case. Note that the documentation
of the relevant functions was in a suboptimal state, so it was improved in the
process - it could use some more improvement, but only the changes that helped
cleanly insert the info about the IN_PROGRESS part were done here.
Also, while updating the ecp.h comment, I noticed several functions in the
ECDH module were wrongfully documented as restartable, which is probably a
left-over from the days before `mbedtls_ecdh_enable_restart()` was introduced.
Fixing that as well, to make the criterion used in ecp.h correct.
When using a primality testing function the tolerable error rate depends
on the scheme in question, the required security strength and wether it
is used for key generation or parameter validation. To support all use
cases we need more flexibility than what the old API provides.
The FIPS 186-4 RSA key generation prescribes lower failure probability
in primality testing and this makes key generation slower. We enable the
caller to decide between compliance/security and performance.
This python script calculates the base two logarithm of the formulas in
HAC Fact 4.48 and was used to determine the breakpoints and number of
rounds:
def mrpkt_log_2(k, t):
if t <= k/9.0:
return 3*math.log(k,2)/2+t-math.log(t,2)/2+4-2*math.sqrt(t*k)
elif t <= k/4.0:
c1 = math.log(7.0*k/20,2)-5*t
c2 = math.log(1/7.0,2)+15*math.log(k,2)/4.0-k/2.0-2*t
c3 = math.log(12*k,2)-k/4.0-3*t
return max(c1, c2, c3)
else:
return math.log(1/7.0)+15*math.log(k,2)/4.0-k/2.0-2*t
The Cortex M4, M7 MCUs and the Cortex A CPUs support the ARM DSP
instructions, and especially the umaal instruction which greatly
speed up MULADDC code. In addition the patch switched the ASM
constraints to registers instead of memory, giving the opportunity
for the compiler to load them the best way.
The speed improvement is variable depending on the crypto operation
and the CPU. Here are the results on a Cortex M4, a Cortex M7 and a
Cortex A8. All tests have been done with GCC 6.3 using -O2. RSA uses a
RSA-4096 key. ECDSA uses a secp256r1 curve EC key pair.
+--------+--------+--------+
| M4 | M7 | A8 |
+----------------+--------+--------+--------+
| ECDSA signing | +6.3% | +7.9% | +4.1% |
+----------------+--------+--------+--------+
| RSA signing | +43.7% | +68.3% | +26.3% |
+----------------+--------+--------+--------+
| RSA encryption | +3.4% | +9.7% | +3.6% |
+----------------+--------+--------+--------+
| RSA decryption | +43.0% | +67.8% | +22.8% |
+----------------+--------+--------+--------+
I ran the whole testsuite on the Cortex A8 Linux environment, and it
all passes.
Remove the trailing whitespace from the inline assembly for AMD64 target, to
overcome a warning in Clang, which was objecting to the string literal
generated by the inline assembly being greater than 4096 characters specified
by the ISO C99 standard. (-Woverlength-strings)
This is a cosmetic change and doesn't change the logic of the code in any way.
This change only fixes the problem for AMD64 target, and leaves other targets as
they are.
Fixes#482.