Now when operation holds pointer to dynamically allocated buffer for password key we can't do copy of the operation object in test instead we need to re-initialize operation object after error.
Signed-off-by: Przemek Stekiel <przemyslaw.stekiel@mobica.com>
When x is the most negative value of a two's complement type,
`(unsigned_type)(-x)` has undefined behavior, whereas `-(unsigned_type)x`
has well-defined behavior and does what was intended.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
The bignum module does not officially support "negative zero" (an
mbedtls_mpi object with s=-1 and all limbs zero). However, we have a
history of bugs where a function that should produce an official
zero (with s=1), produces a negative zero in some circumstances. So it's
good to check that the bignum functions are robust when passed a negative
zero as input. And for that, we need a way to construct a negative zero
from test case arguments.
There are checks that functions don't produce negative zeros as output in
the test suite. Skip those checks if there's a negative zero input: we
don't want functions to _create_ negative zeros, but we don't mind if
they _propagate_ negative zeros.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
The already existing "x509_csr_check()" function is extended in order
to support/test also CSR's extensions. The test is performed by
adding an extended key usage.
Signed-off-by: Valerio Setti <vsetti@baylibre.com>
Fix error in memory allocation in test code, which was triggering an
error in test_memory_buffer_allocator.
Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
A core MPI must have at least 1 limb. We can no longer test with 0 limbs,
and we don't need to anyway, so don't try.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Instead of corrupting the public key part of the message,
corrupt the proof part. A proof is conceptually similar to a signature,
and changing anything in it should make it invalid with
a high probability.
Also, instead of shifting data, perform a bitflip.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
For the benefit of auto-formatting tools, move from the '$placeholder'
templating syntax to a new syntax of the form:
__MBEDTLS_TEST_TEMPLATE__PLACEHOLDER
This change allows the test code template to be almost entirely valid C.
Signed-off-by: David Horstmann <david.horstmann@arm.com>
Windows tests are failing pkcs7 verification due to differnt line
endings. Therefore, add make instuctions for building the data
files with Windows EOF instead. As a result, regenerate other data
files so that verification works.
Add these CRLF EOF files to the exception in check_files to ignore
the line endings.
Signed-off-by: Nick Child <nick.child@ibm.com>
Legacy Bignum is excluded as it doesn't get regular extensions like new
ones.
Each slot uses comments of their respective filetype. Since .data files
don't have a syntax for comments, dummy test cases are used. (These test
cases will never be executed and no noise will be added to tests.)
Signed-off-by: Janos Follath <janos.follath@arm.com>
I ran into a sequence where the assertion `stats[8] > 0` failed for the
range 1..272 with 100 iterations.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Turn mpi_fill_random_internal() into mbedtls_mpi_core_fill_random(). It
had basically the right code except for how X is passed to the function.
Write unit tests.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This patch updates the tests `mpi_mod_raw_cond_swap()` &
`mpi_mod_raw_cond_assign()` to use a non-zero modulus
when invoking `mbedtls_mpi_mod_modulus_setup()`
Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
This patch addresses more review comments, and fixes
a circular depedency in the `mbedtls_mpi_mod_modulus_setup()`.
Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
This patch addresses review comments with regards to style of
`mbedtls_mpi_mod_modulus_setup/free()`.
It also removes a test check which was triggering a use-after-free.
Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
This patch updates the `mpi_mod_setup()` test suite
to check for incosistencies in the montgomery constant
data's lifecycle.
Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
This patch moves the following tests to test_suite_bignum_core:
* `mbedtls_mpi_core_get_mont_r2_unsafe_neg()`
* `mbedtls_mpi_core_get_mont_r2_unsafe()`
Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
This patch adds the test for the method calculating the RR. The input/expected
data are generated manually using the following Python3 snippet:
~~~~~
import math
title="mpi_get_montgomery_constant_unsafe"
tt = title + " #{}"
in_data = [ "0f", ... ]
def limb_no(number, bil=64):
return int(math.ceil(int.bit_length(number)/(bil * 1.0)))
def calc_rr(number, bil=64 ):
return '{:x}'.format(pow(pow(2, limb_no(number, bil) * bil), 2, number))
def calc_rr_str(number, prefix=""):
rr64 = calc_rr(number)
rr32 = calc_rr(number, bil=32)
return '{}:"{:x}":"{}":"{}"'.format(prefix,number, rr32, rr64)
print("\n\n".join(["{}\n{}".format(tt.format(in_data.index(v)+1), calc_rr_str(int(v,base=16), title)) for v in in_data]))
~~~~~
Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
Introduce and use
MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED to
guard TLS code (both 1.2 and 1.3) specific
to handshakes involving PSKs.
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
Introduce and use
MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED to
guard TLS code (both TLS 1.2 and 1.3) specific
to handshakes involving certificates.
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
Use MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
instead of MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED to guard
code specific to the TLS 1.3 ephemeral key exchange mode.
Use it also for the dependencies of TLS 1.3 only tests
relying on ephemeral key exchange mode, but for
tests in tls13-kex-modes.sh where the change is done
later using all
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_.*ENABLED macros.
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
Although our build scripts support that, it's annoying, because it makes
"test_suite_XXX" ambiguous between "all the data for
test_suite_XXX.function" and "just test_suite_XXX.data".
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Align the name of the bignum test suite with the source module (which was
renamed from mpi.c to bignum.c in the PolarSSL 1.x days). This also brings
it into line with the test suites for the low-level bignum interfaces.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Test cases for mpi_core_add_if, mpi_core_mla, mpi_core_sub,
mpi_core_montmul are not copied into new files, these are generated in
subsequent commits.
Signed-off-by: Werner Lewis <werner.lewis@arm.com>
ASSERT_ALLOC calculates the size itself, and the parameter indicates number of elements.
```
mbedtls_calloc( sizeof( *( pointer ) ), ( length ) );
```
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
Most of the tests (including those using endpoint_init functions) parse
certificates that require MBEDTLS_SHA256_C to be present.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
Since https://github.com/Mbed-TLS/mbedtls/pull/6141 it can "fall back"
to PSA when MD is not available (but will use MD if available, to
preserve backwards compatibility).
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This has been the case since
https://github.com/Mbed-TLS/mbedtls/pull/6065 which forgot to update the
documentation, and also is_builtin_calling_md(), so update those.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Break down the DER-encoded ASN.1 test data into its structure in a
comment and explain it, to make it easier to understand where the data
came from and how it is corrupted.
Signed-off-by: David Horstmann <david.horstmann@arm.com>
The second argument is the number of elements of the type the first
argument is pointing to, so we shouldn't be using sizeof there.
This was resulting in overly large allocations.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
The test data was invalid because it had the extra 4-byte prefix for HSS.
Regenerate it (which produces completely new signatures since it is
randomized).
Rearrange the reproduction instructions for the second test case so that it
shows more clearly how to generate a second signature with the same private
key.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Remove SHA256 dependencies from tests, fix incorrect boolean logic in
check_config, and change depends_hashes.pl to disable LMS in one test
Signed-off-by: Raef Coles <raef.coles@arm.com>
We're not strictly required to abort, but at least to leave the context
is an invalid state. For "late" functions like input() and output(),
calling abort() is the easiest way to do that. Do it systematically for
input() and output() by using a wrapper. psa_pake_get_implicit_key() was
already doing it. For "early" function, we can just leave the operation
in its current state which is already invalid.
Restore previous tests about that. Not adding systematic tests, though,
just test the two functions that are the most important, and more likely
to return errors.
Since we now abort in more cases, we need to make sure we don't
invalidate the operation that's going to be re-used later in the test.
For that reason, use a copy of the operation for calls to input() and
output() that are expected to return errors.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Also, the error code changed from INSUFFICIENT_MEMORY to INVALID_DATA.
Temporarily remove a test about aborting the operation on error.
Auto-abort will be re-introduced in the next commit in a more systematic
way.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Test functions must now take a char* argument rather than data_t*. This does
not affect existing test data.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Introduce a unit test to test mbedtls_x509_get_name() and add a testcase
with a corrupt DER-encoded name that causes mbedtls_x509_get_name() to
have to cleanup things it is allocated. If it fails to do this, a memory
leak is detected under Asan builds.
Signed-off-by: David Horstmann <david.horstmann@arm.com>
The format used by the mbedtls_ecjpake_xxx() APIs and that defined by
the PSA Crypto PAKE extension are quite different; the former is
tailored to the needs of TLS while the later is quite generic and plain.
Previously we only addressed some part of this impedance mismatch: the
different number of I/O rounds, but failed to address the part where the
legacy API adds some extras (length bytes, ECParameters) that shouldn't
be present in the PSA Crypto version. See comments in the code.
Add some length testing as well; would have caught the issue.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Use mbedtls_test_read_mpi_core() to read the test data. Among other
benefits, X and Y are now allocated to their exact size, so analyzers (Asan,
Valgrind, Coverity, ...) have a chance of complaining if the tested function
overflows the buffer.
Remove TEST_CF_PUBLIC calls which are no longer necessary.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
The length in bytes is used with the 'len' prefix and
the length in limbs is used with the 'limbs' prefix.
Signed-off-by: Gabor Mezei <gabor.mezei@arm.com>
As a public header, it should no longer include common.h, just use
build_info.h which is what we actually need anyway.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Initializing return status variables to CORRUPTION_DETECTED is a second line
of defense in library code in case there's a code path where we forget to
assign to the variable. This isn't useful in test code. In any case, here,
we might as well define the variable at the point of use.
This fixes a build error in configurations with MBEDTLS_ERROR_C and
MBEDTLS_PSA_CRYPTO_C both disabled, because then mbedtls/error.h isn't
included so MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED isn't defined.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
We used to include platform.h only when MBEDTLS_PLATFORM_C was enabled, and
to define ad hoc replacements for mbedtls_xxx functions on a case-by-case
basis when MBEDTLS_PLATFORM_C was disabled. The only reason for this
complication was to allow building individual source modules without copying
platform.h. This is not something we support or recommend anymore, so get
rid of the complication: include platform.h unconditionally.
There should be no change in behavior since just including the header should
not change the behavior of a program.
This commit replaces most occurrences of conditional inclusion of
platform.h, using the following code:
```
perl -i -0777 -pe 's!#if.*\n#include "mbedtls/platform.h"\n(#else.*\n(#define (mbedtls|MBEDTLS)_.*\n|#include <(stdarg|stddef|stdio|stdlib|string|time)\.h>\n)*)?#endif.*!#include "mbedtls/platform.h"!mg' $(git grep -l '#include "mbedtls/platform.h"')
```
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
In response to feedback[1], we can reuse much of the functions in
similar test cases by specifying some additional parameters.
Specifically, test cases which probe the functionality of
`mbedtls_pkcs7_parse_der` have all been merged into one test function.
Additionally, all test cases which examine the
`mbedtls_pkcs7_signed_data_verify` and `mbedtls_pkcs7_signed_hash_verify`
functions have been merged into two test functions (one for single and one
for multiple signers).
[1] https://github.com/Mbed-TLS/mbedtls/pull/3431#discussion_r953686780
Signed-off-by: Nick Child <nick.child@ibm.com>
Make `mbedtls_pkcs7_signed_hash_verify` loop over all signatures in the
PKCS7 structure and return success if any of them verify successfully.
Signed-off-by: Nick Child <nick.child@ibm.com>
Rather than only parsing/verifying one SignerInfo in the SignerInfos
field of the PKCS7 stucture, allow the ability to parse and verify more
than one signature. Verification will return success if any of the signatures
produce a match.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Nick Child <nick.child@ibm.com>
Fixes include removing PEM dependency for greater
coverage when PEM config is not set and defining
test dependencies at the appropriate level.
Signed-off-by: Nick Child <nick.child@ibm.com>
CI was failing due to the return value of mbedtls_md being ignored.
If this function does fail, return early and propogate the md error.
Signed-off-by: Nick Child <nick.child@ibm.com>
OpenSSL provides APIs to generate only the signted data
format PKCS7 i.e. without content type OID. This patch
adds support to parse the data correctly even if formatted
only as signed data
Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
PKCS7 signing format is used by OpenPOWER Key Management, which is
using mbedtls as its crypto library.
This patch adds the limited support of pkcs7 parser and verification
to the mbedtls. The limitations are:
* Only signed data is supported.
* CRLs are not currently handled.
* Single signer is supported.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Eric Richter <erichte@linux.ibm.com>
Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
Especially for a sequence of similar lines of test code, or where the result of
an expression is being compared to a short integer (especially 0 or 1).
Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
Spec values are now always used for test data, and conversion to
internal representation is done in the test function.
Signed-off-by: Werner Lewis <werner.lewis@arm.com>
The unit tests were created by capturing runs of the existing function during
execution of existing unit tests.
Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
The test cases use the following MPI values:
0 1 fffe ffffffff 100000000 20000000000000 ffffffffffffffff
10000000000000000 1234567890abcdef0 fffffffffffffffffefefefefefefefe
100000000000000000000000000000000 1234567890abcdef01234567890abcdef0
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0
4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b
and the following scalars. The .data files include two sets of results (final
accumulator and carry) for the cases sizeof(mbedtls_mpi_uint) == 4 or 8.
0 3 fe ff ffff 10000 ffffffff 100000000 7f7f7f7f7f7f7f7f 8000000000000000
fffffffffffffffe
The lines in the .data file were generated by the following script
#!/usr/bin/env perl
#
# mpi-test-core-mla.pl - generate/run MPI tests in Perl for mbedtls_mpi_core_mla()
#
use strict;
use warnings;
use Math::BigInt;
use sort 'stable';
my @mla_mpis = qw(
0 1 fffe ffffffff 100000000 20000000000000 ffffffffffffffff
10000000000000000 1234567890abcdef0 fffffffffffffffffefefefefefefefe
100000000000000000000000000000000 1234567890abcdef01234567890abcdef0
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0
4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b
);
my @mla_scalars = qw(
0 3 fe ff ffff 10000 ffffffff 100000000 7f7f7f7f7f7f7f7f 8000000000000000
fffffffffffffffe
);
my @mla_full_mpis = qw(
0 1 3 f fe ff 100 ff00 fffe ffff 10000
fffffffe ffffffff 100000000 1f7f7f7f7f7f7f
8000000000000000 fefefefefefefefe fffffffffffffffe ffffffffffffffff
10000000000000000 1234567890abcdef0
fffffffffffffffffefefefefefefefe fffffffffffffffffffffffffffffffe ffffffffffffffffffffffffffffffff
100000000000000000000000000000000 1234567890abcdef01234567890abcdef0
fffffffffffffffffffffffffffffffffffffffffffffffffefefefefefefefe
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
10000000000000000000000000000000000000000000000000000000000000000
1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0
4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b
);
my @mla_full_scalars = qw(
0 1 3 f fe ff 100 ff00 fffe ffff 10000
fffffffe ffffffff 100000000
8000000000000000 fefefefefefefefe fffffffffffffffe ffffffffffffffff
);
generate_tests();
sub generate_tests {
generate_mbedtls_mpi_core_mla();
}
sub generate_mbedtls_mpi_core_mla {
my $sub_name = (caller(0))[3]; # e.g. main::generate_mbedtls_mpi_sub_mpi
my ($ignore, $test_name) = split("main::generate_", $sub_name);
my @cases = ();
for my $ah (@mla_mpis) {
for my $bh (@mla_mpis) {
for my $ch (@mla_scalars) {
# a += b * c (c is scalar)
# a_len >= b_len. need carry out.
my $a = Math::BigInt->from_hex($ah);
my $b = Math::BigInt->from_hex($bh);
my $c = Math::BigInt->from_hex($ch);
my $max = ($a > $b) ? $a : $b;
my $bound4 = bound_mpi4($max);
my $bound8 = bound_mpi8($max);
my $r = $a + $b * $c;
my ($r4, $cy4) = ($r->copy(), 0);
my ($r8, $cy8) = ($r->copy(), 0);
($cy4, $r4) = $r4->bdiv($bound4);
($cy8, $r8) = $r8->bdiv($bound8);
my $rh4 = $r4->to_hex();
my $rh8 = $r8->to_hex();
my $cyh4 = $cy4->to_hex();
my $cyh8 = $cy8->to_hex();
# If the scalar c is too big for 1 x 4-byte MPI, we can only run this test on a system with 8-byte MPIs
my $depends = mpi4s($c) > 1 ? "MBEDTLS_HAVE_INT64" : "";
my $desc = "$test_name #NUMBER: 0x$ah + 0x$bh * 0x$ch = (0x$rh4, carry 0x$cyh4)/(0x$rh8, carry 0x$cyh8)EXPLAIN";
my $case = output($test_name, str($ah), str($bh), str($ch), str($rh4), str($cyh4), str($rh8), str($cyh8));
push(@cases, [$case, $desc, $depends]);
}
}
}
output_cases(" (for when sizeof(mbedtls_mpi_uint) == 4/8)", @cases);
}
sub output_cases {
my ($explain, @cases) = @_;
my $count = 1;
for my $c (@cases) {
my ($case, $desc, $dep) = @$c;
$desc =~ s/NUMBER/$count/; $count++;
if (defined($explain) && $desc =~ /EXPLAIN/) {
$desc =~ s/EXPLAIN/$explain/;
$explain = "";
}
my $depends = "";
$depends = "depends_on:$dep\n" if defined($dep) && length($dep);
print <<EOF;
$desc
$depends$case
EOF
}
}
# The first number (a power of 2) that won't fit in the number of MPIs
# needed for the given number
sub bound_mpi4 {
my $one = Math::BigInt->new(1); # blsft modifies caller
return $one->blsft(bits_mpi4($_[0]));
}
sub bound_mpi8 {
my $one = Math::BigInt->new(1); # blsft modifies caller
return $one->blsft(bits_mpi8($_[0]));
}
# How many bits (a multiple of 32) needed to store the specified number
# when using 4-byte MPIs
sub bits_mpi4 {
return 32 * mpi4s($_[0]);
}
# How many bits (a multiple of 64) needed to store the specified number
# when using 8-byte MPIs
sub bits_mpi8 {
return 64 * mpi8s($_[0]);
}
# How many 4-byte MPIs needed to store the specified number
sub mpi4s {
my ($n) = @_;
my $h = $n->to_hex();
return int((length($h) + 7) / 8);
}
# How many 8-byte MPIs needed to store the specified number
sub mpi8s {
my ($n) = @_;
my $h = $n->to_hex();
return int((length($h) + 15) / 16);
}
sub output {
#run_test(@_);
return join(":", @_);
}
sub str {
return '"' . $_[0] . '"';
}
Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
The test cases use the following MPI values.
The .data file includes two results, for the cases when
sizeof(mbedtls_mpi_uint) == 4 or 8.
0 1 3 f fe ff 100 ff00 fffe ffff 10000
fffffffe ffffffff 100000000 1f7f7f7f7f7f7f
8000000000000000 fefefefefefefefe fffffffffffffffe ffffffffffffffff
10000000000000000 1234567890abcdef0
fffffffffffffffffefefefefefefefe fffffffffffffffffffffffffffffffe
ffffffffffffffffffffffffffffffff 100000000000000000000000000000000
1234567890abcdef01234567890abcdef0
fffffffffffffffffffffffffffffffffffffffffffffffffefefefefefefefe
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
10000000000000000000000000000000000000000000000000000000000000000
1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0
4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b
The lines in the .data file were generated by the following script
#!/usr/bin/env perl
#
# mpi-test-core-sub.pl - generate/run MPI tests in Perl for mbedtls_mpi_core_sub()
#
use strict;
use warnings;
use Math::BigInt;
use sort 'stable';
my @sub_mpis = qw(
0 1 3 f fe ff 100 ff00 fffe ffff 10000
fffffffe ffffffff 100000000 1f7f7f7f7f7f7f
8000000000000000 fefefefefefefefe fffffffffffffffe ffffffffffffffff
10000000000000000 1234567890abcdef0
fffffffffffffffffefefefefefefefe fffffffffffffffffffffffffffffffe ffffffffffffffffffffffffffffffff
100000000000000000000000000000000 1234567890abcdef01234567890abcdef0
fffffffffffffffffffffffffffffffffffffffffffffffffefefefefefefefe
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
10000000000000000000000000000000000000000000000000000000000000000
1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0
4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b
);
generate_tests();
sub generate_tests {
generate_mbedtls_mpi_core_sub();
}
sub generate_mbedtls_mpi_core_sub {
my $sub_name = (caller(0))[3]; # e.g. main::generate_mbedtls_mpi_sub_mpi
my ($ignore, $test_name) = split("main::generate_", $sub_name);
my @cases = ();
for my $ah (@sub_mpis) {
for my $bh (@sub_mpis) {
my $a = Math::BigInt->from_hex($ah);
my $b = Math::BigInt->from_hex($bh);
my ($rh4, $rh8, $carry);
if ($a >= $b) {
my $r = $a - $b;
$rh4 = $rh8 = $r->to_hex();
$carry = 0;
} else {
my $r4 = bound_mpi4($b) + $a - $b;
my $r8 = bound_mpi8($b) + $a - $b;
$rh4 = $r4->to_hex();
$rh8 = $r8->to_hex();
$carry = 1;
}
my $desc = "$test_name #NUMBER: 0x$ah - 0x$bh = 0x$rh4/${rh8}EXPLAIN, carry ${carry}";
my $case = output($test_name, str($ah), str($bh), str($rh4), str($rh8), $carry);
push(@cases, [$case, $desc]);
}
}
output_cases(" (for when sizeof(mbedtls_mpi_uint) == 4/8)", @cases);
}
sub output_cases {
my ($explain, @cases) = @_;
my $count = 1;
for my $c (@cases) {
my ($case, $desc, $dep) = @$c;
$desc =~ s/NUMBER/$count/; $count++;
if (defined($explain) && $desc =~ /EXPLAIN/) {
$desc =~ s/EXPLAIN/$explain/;
$explain = "";
}
my $depends = "";
$depends = "depends_on:$dep\n" if defined($dep) && length($dep);
print <<EOF;
$desc
$depends$case
EOF
}
}
# The first number (a power of 2) that won't fit in the number of MPIs
# needed for the given number
sub bound_mpi4 {
my $one = Math::BigInt->new(1); # blsft modifies caller
return $one->blsft(bits_mpi4($_[0]));
}
sub bound_mpi8 {
my $one = Math::BigInt->new(1); # blsft modifies caller
return $one->blsft(bits_mpi8($_[0]));
}
# How many bits (a multiple of 32) needed to store the specified number
# when using 4-byte MPIs
sub bits_mpi4 {
return 32 * mpi4s($_[0]);
}
# How many bits (a multiple of 64) needed to store the specified number
# when using 8-byte MPIs
sub bits_mpi8 {
return 64 * mpi8s($_[0]);
}
# How many 4-byte MPIs needed to store the specified number
sub mpi4s {
my ($n) = @_;
my $h = $n->to_hex();
return int((length($h) + 7) / 8);
}
# How many 8-byte MPIs needed to store the specified number
sub mpi8s {
my ($n) = @_;
my $h = $n->to_hex();
return int((length($h) + 15) / 16);
}
sub output {
return join(":", @_);
}
sub str {
return '"' . $_[0] . '"';
}
Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
The test cases use the following MPI values.
The .data file only includes those (a, b) values where a <= b, and gives the
sum unconditionally; the test code exercises a >= b and cond == 0 using these
values. The .data file gives two values for the carry out, which are for when
sizeof(mbedtls_mpi_uint) == 4 or 8.
0 1 3 f fe ff 100 ff00 fffe ffff 10000
fffffffe ffffffff 100000000 1f7f7f7f7f7f7f
8000000000000000 fefefefefefefefe fffffffffffffffe ffffffffffffffff
10000000000000000 1234567890abcdef0
fffffffffffffffffefefefefefefefe fffffffffffffffffffffffffffffffe
ffffffffffffffffffffffffffffffff 100000000000000000000000000000000
1234567890abcdef01234567890abcdef0
fffffffffffffffffffffffffffffffffffffffffffffffffefefefefefefefe
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
10000000000000000000000000000000000000000000000000000000000000000
1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0
4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b
The lines in the .data file were generated by the following script
```
#!/usr/bin/env perl
#
# mpi-test-core-add-if.pl - generate MPI tests in Perl for mbedtls_mpi_core_add_if()
#
use strict;
use warnings;
use Math::BigInt;
use sort 'stable';
my @add_mpis = qw(
0 1 3 f fe ff 100 ff00 fffe ffff 10000
fffffffe ffffffff 100000000 1f7f7f7f7f7f7f
8000000000000000 fefefefefefefefe fffffffffffffffe ffffffffffffffff
10000000000000000 1234567890abcdef0
fffffffffffffffffefefefefefefefe fffffffffffffffffffffffffffffffe ffffffffffffffffffffffffffffffff
100000000000000000000000000000000 1234567890abcdef01234567890abcdef0
fffffffffffffffffffffffffffffffffffffffffffffffffefefefefefefefe
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
10000000000000000000000000000000000000000000000000000000000000000
1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0
4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b
);
generate_tests();
sub generate_tests {
generate_mbedtls_mpi_core_add_if();
}
sub generate_mbedtls_mpi_core_add_if {
my $sub_name = (caller(0))[3]; # e.g. main::generate_mbedtls_mpi_add_mpi
my ($ignore, $test_name) = split("main::generate_", $sub_name);
my @cases = ();
for my $ah (@add_mpis) {
for my $bh (@add_mpis) {
my $a = Math::BigInt->from_hex($ah);
my $b = Math::BigInt->from_hex($bh);
next if $a > $b; # don't need to repeat test cases
# $b is the larger (or equal) of the two numbers. That's the number of limbs
# we'll be using.
my $bound4 = bound_mpi4($b);
my $bound8 = bound_mpi8($b);
my $r = $a + $b;
my ($r4, $carry4) = ($r->copy(), 0);
my ($r8, $carry8) = ($r->copy(), 0);
($carry4, $r4) = $r4->bdiv($bound4);
($carry8, $r8) = $r8->bdiv($bound8);
my $rh4 = $r4->to_hex();
my $rh8 = $r8->to_hex();
my $desc = "$test_name #NUMBER: 0x$ah + 0x$bh = (0x$rh4, carry $carry4)/(0x$rh8, carry $carry8)EXPLAIN";
my $case = output($test_name, str($ah), str($bh), str($rh4), $carry4, str($rh8), $carry8);
push(@cases, [$case, $desc]);
}
}
output_cases(" (for when sizeof(mbedtls_mpi_uint) == 4/8)", @cases);
}
sub output_cases {
my ($explain, @cases) = @_;
my $count = 1;
for my $c (@cases) {
my ($case, $desc, $dep) = @$c;
$desc =~ s/NUMBER/$count/; $count++;
if (defined($explain) && $desc =~ /EXPLAIN/) {
$desc =~ s/EXPLAIN/$explain/;
$explain = "";
}
my $depends = "";
$depends = "depends_on:$dep\n" if defined($dep) && length($dep);
print <<EOF;
$desc
$depends$case
EOF
}
}
# The first number (a power of 2) that won't fit in the number of MPIs
# needed for the given number
sub bound_mpi4 {
my $one = Math::BigInt->new(1); # blsft modifies caller
return $one->blsft(bits_mpi4($_[0]));
}
sub bound_mpi8 {
my $one = Math::BigInt->new(1); # blsft modifies caller
return $one->blsft(bits_mpi8($_[0]));
}
# How many bits (a multiple of 32) needed to store the specified number
# when using 4-byte MPIs
sub bits_mpi4 {
return 32 * mpi4s($_[0]);
}
# How many bits (a multiple of 64) needed to store the specified number
# when using 8-byte MPIs
sub bits_mpi8 {
return 64 * mpi8s($_[0]);
}
# How many 4-byte MPIs needed to store the specified number
sub mpi4s {
my ($n) = @_;
my $h = $n->to_hex();
return int((length($h) + 7) / 8);
}
# How many 8-byte MPIs needed to store the specified number
sub mpi8s {
my ($n) = @_;
my $h = $n->to_hex();
return int((length($h) + 15) / 16);
}
sub output {
return join(":", @_);
}
sub str {
return '"' . $_[0] . '"';
}
```
Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>