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>
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>
A number of places lacked the necessary dependencies on one of
the used features: MD, key exchange with certificate,
entropy, or ETM.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
The same elements are now also used when MBEDTLS_USE_PSA_CRYPTO
is defined and respective SHA / MD5 defines are missing.
A new set of macros added in #6065 is used to reflect these dependencies.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
TEST_EQUAL(), has the benefit of outputting the values that don't match,
which can make debugging simpler.
Scope:
- Recently added new test functions
- Checks making sure the test case/data is consistent is out of scope
- Only checks where printing the values is likely to be helpful
Signed-off-by: Janos Follath <janos.follath@arm.com>
MBEDTLS_CMAC_C dependency is ivalid.
"PEM read (unknown encryption algorithm)" needs MBEDTLS_CIPHER_MODE_CBC dependency as
otherwise this test is failing in test_when_no_ciphersuites_have_mac configuration
because mbedtls_pem_read_buffer() returns a different error (MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE).
Signed-off-by: Przemek Stekiel <przemyslaw.stekiel@mobica.com>
- Improve test descriptions
- Add more test cases with return value of 1
- Remove the mbedtls prefix from the test function
Signed-off-by: Janos Follath <janos.follath@arm.com>
Add tests for a case in ECDSA signing where an invalid public
key is accepted in signature verification.
Test data taken from the OSS-fuzz issue, and additional
generated with python-ecdsa.
Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
MBEDTLS_SSL_IANA_TLS_GROUP_SECP192R1 and friends are not members of the mbedtls_ecp_group_id enum
Found by clang's -Wassign-enum
Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
This is done to be able to bild test_psa_crypto_config_accel_hash component where MD5 is only available accelerated (PSA_WANT_ALG_MD5 is enabled and MBEDTLS_MD5_C is disabled) but MBEDTLS_USE_PSA_CRYPTO is disabled.
So the build should not attempt to enable pem_pbkdf1.
Signed-off-by: Przemek Stekiel <przemyslaw.stekiel@mobica.com>
Test cases added to check curve parameters and information for each
curve supported. Expected parameters are taken from references: SEC 2
for NIST, RFC 5639 for Brainpool, and RFC 7748 for curve25519/curve448.
Signed-off-by: Werner Lewis <werner.lewis@arm.com>
- Instead of macros, use direct calculations for array sizes
- Move variable declarations closer to first use
Signed-off-by: Janos Follath <janos.follath@arm.com>
Previously these tests depended on the definition from
inside the MD module, which in turn could be 32 or 64
bytes depending on whether MBEDTLS_SHA512_C was
defined. This is unnecessary, so a constant is itnroduced
instead.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
Previously the whole .function file had a global dependency on
MBEDTLS_SHA1_C. This hasn't been correct for a long time:
- on principle, dependency declarations in .function files are for
compile-time dependencies;
- in practice, a number of test cases do not depend on SHA-1, as they only
use SHA-256 or SHA-512 - those cases should not be skipped in builds
without SHA-1;
- this was "taken advantage of" to skip dependency declarations for
test cases that only depended on SHA-1.
The previous commit removed the global dependency on SHA1_C; as a result
the test cases that actually depend on SHA-1 were not skipped in builds
without SHA-1. This commit fixes that by adding dependency declarations
where they belong: in the .data file.
All cases compute hashes using MD is available, or PSA otherwise; so
MD_OR_PSA is appropriate here.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
sed -i -f md_or_psa_hash.sed \
tests/suites/test_suite_pkcs1_v21.data
tests/suites/test_suite_pk.data
with md_or_psa_hash.sed containing:
s/MBEDTLS_MD5_C/MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA/g
s/MBEDTLS_RIPEMD160_C/MBEDTLS_HAS_ALG_RIPEMD160_VIA_MD_OR_PSA/g
s/MBEDTLS_SHA1_C/MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA/g
s/MBEDTLS_SHA224_C/MBEDTLS_HAS_ALG_SHA_224_VIA_MD_OR_PSA/g
s/MBEDTLS_SHA256_C/MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA/g
s/MBEDTLS_SHA384_C/MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA/g
s/MBEDTLS_SHA512_C/MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA/g
(The only lines in pk.data that still had old-style dependencies where
the ones about PKCS1_V21.)
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Tests function with various ECP point conditions, covering freshly
initialized, zeroed, non-zero, and freed points.
Signed-off-by: Werner Lewis <werner.lewis@arm.com>
When USE_PSA_INIT() failed because lack of seedfile, mbedtls_x509write_csr_free()
crashed when called on an unitialized mbedtls_x509write_csr struct.
This moves mbedtls_x509write_csr_init before calling USE_PSA_INIT(),
which could probably fail, and uses the same flow in x509_csr_check()
and x509_csr_check_opaque().
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Unfortunately reusing the new function from the signed constant time
comparison is not trivial.
One option would be to do temporary conditional swaps which would prevent
qualifying input to const. Another way would be to add an additional
flag for the sign and make it an integral part of the computation, which
would defeat the purpose of having an unsigned core comparison.
Going with two separate function for now and the signed version can be
retired/compiled out with the legacy API eventually.
The new function in theory could be placed into either
`library/constant_time.c` or `library/bignum_new.c`. Going with the
first as the other functions in the second are not constant time yet and
this distinction seems more valuable for new (as opposed to belonging to
the `_core` functions.
Signed-off-by: Janos Follath <janos.follath@arm.com>
- We don't check for NULL pointers this deep in the library
- Accessing a NULL pointer when the limb number is 0 as a mistake is the
very similar to any other out of bounds access
- We could potentially mandate at least 1 limb representation for 0 but
we either would need to enforce it or the implementation would be less
robust.
- Allowing zero limb representation - (NULL, 0) in particular - for zero
is present in the legacy interface, if we disallow it, the
compatibility code will need to deal with this (more code size and
opportunities for mistakes)
In summary, interpreting (NULL, 0) as the number zero in the core
interface is the least of the two evils.
Signed-off-by: Janos Follath <janos.follath@arm.com>
The test case where there were extra limbs in the MPI failed and this
commit contains the corresponding fix as well. (We used to use the
minimum required limbs instead of the actual limbs present.)
Signed-off-by: Janos Follath <janos.follath@arm.com>
Test data which is compared as a hex string now uses upper case to
match output of mbedtls_mpi_write_string() output. This removes usage
of strcasecmp().
Signed-off-by: Werner Lewis <werner.lewis@arm.com>
Cases where radix was explictly declared are removed in most cases,
replaced using script. bignum arguments are represented as hexadecimal
strings. This reduces clutter in test data and makes bit patterns
clearer.
Signed-off-by: Werner Lewis <werner.lewis@arm.com>
When USE_PSA is disabled and ECDSA_DETERMINISTIC is enabled, generating
ECDSA signatures via PK requires use of the hash via the MD layer (in
HMAC-DRBG, used by deterministic ECDSA).
When USE_PSA is enabled, ECDSA signatures via PK go through PSA which
always uses non-deterministic ECDSA, so does not rely on HMAC-DRBG/MD.
The condition used here is slightly too strong, but expressing exactly
the optimal condition seems more effort than it's worth for just 3 test
cases.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Using VIA_MD_OR_PSA_BASED_ON_USE_PSA was justified by the fact that
until a few commits ago, the test functions here computed hashes using
either MD or PSA, depending on whether USE_PSA was defined (which itself
was justified by the loose reasoning that "PK is USE_PSA territory").
A few commits ago, test code stopped computing hashes because the hash
values became part of the test data. PK itself does not compute hashes.
As a result, VIA_MD_OR_PSA_BASED_ON_USE_PSA is no longer justified.
There are now two kinds of tests:
- those that only rely on hash data (ECDSA, RSA PKCS#1 v1.5) should
depend on VIA_LOWLEVEL_OR_PSA as that is the minimal dependency, hence
the one used for data
- those that were the layer below PK will internally compute a hash (RSA
PKCS#1 v2.1): currently this hash is always computed using MD (on which
MBEDTLS_PKCS1_V21 depends), so legacy dependencies like MBEDTLS_SHA256_C
should be used for now. The previous dependency was morally wrong, it
didn't show in the driver-only tests only because PKCS#1 v2.1 is
disabled in this test for now.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Fix usage with sed:
s/MBEDTLS_OR_PSA_WANT_\([A-Z_0-9]*\)/MBEDTLS_HAS_\1_VIA_LOWLEVEL_OR_PSA/
s/MBEDTLS_USE_PSA_WANT_\([A-Z_0-9]*\)/MBEDTLS_HAS_\1_VIA_MD_OR_PSA_BASED_ON_USE_PSA/
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
We had a message in the data file, and were computing its hash in the
test function. It is more efficient (and simpler when it comes to
dependencies) to directly have the message hash in the data file.
It was probably this way because some test vectors provide the message
for the sake of all-in-one implementation that hash-and-sign at once.
But our API gets a hash as the input and signs it. In unit tests, this
should be reflected in the signature of the test function, which should
take a hash as input.
The changes to the .data file were done using the following python
script:
import hashlib
suite = 'pkcs1_v21'
functions = {
'pkcs1_rsassa_pss_sign': (6, 8),
'pkcs1_rsassa_pss_verify': (4, 6),
'pkcs1_rsassa_pss_verify_ext': (4, 8),
}
def hash_ctx(s):
if s == 'MBEDTLS_MD_MD5':
return hashlib.md5()
if s == 'MBEDTLS_MD_SHA1':
return hashlib.sha1()
if s == 'MBEDTLS_MD_SHA224':
return hashlib.sha224()
if s == 'MBEDTLS_MD_SHA256':
return hashlib.sha256()
if s == 'MBEDTLS_MD_SHA384':
return hashlib.sha384()
if s == 'MBEDTLS_MD_SHA512':
return hashlib.sha512()
def fix(l):
parts = l.rstrip().split(":")
fun = parts[0]
if fun not in functions:
return l
(digest_idx, msg_idx) = functions[fun]
alg_str = parts[digest_idx]
if alg_str == "MBEDTLS_MD_NONE":
return l
h = hash_ctx(alg_str)
msg_str = parts[msg_idx]
msg_hex = msg_str[1:-1]
msg = bytes.fromhex(msg_hex)
h.update(msg)
msg_hash = h.hexdigest()
msg_hash_str = '"' + msg_hash + '"'
parts[msg_idx] = msg_hash_str
return ":".join(parts) + '\n'
filename = 'tests/suites/test_suite_' + suite + '.data'
with open(filename) as f:
lines = f.readlines()
lines = [fix(l) for l in lines]
with open(filename, 'w') as f:
f.writelines(lines)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
We had a message in the data file, and were computing its hash in the
test function. It is more efficient (and simpler when it comes to
dependencies) to directly have the message hash in the data file.
It was probably this way because some test vectors provide the message
for the sake of all-in-one implementation that hash-and-sign at once.
But our API gets a hash as the input and signs it. In unit tests, this
should be reflected in the signature of the test function, which should
take a hash as input.
The changes to the .data file were done using the following python
script:
import hashlib
suite = 'ecdsa'
functions = {
'ecdsa_det_test_vectors': (3, 4),
'ecdsa_write_restart': (3, 4),
}
def hash_ctx(s):
if s == 'MBEDTLS_MD_MD5':
return hashlib.md5()
if s == 'MBEDTLS_MD_SHA1':
return hashlib.sha1()
if s == 'MBEDTLS_MD_SHA224':
return hashlib.sha224()
if s == 'MBEDTLS_MD_SHA256':
return hashlib.sha256()
if s == 'MBEDTLS_MD_SHA384':
return hashlib.sha384()
if s == 'MBEDTLS_MD_SHA512':
return hashlib.sha512()
def fix(l):
parts = l.rstrip().split(":")
fun = parts[0]
if fun not in functions:
return l
(alg_idx, msg_idx) = functions[fun]
alg_str = parts[alg_idx]
if alg_str == "MBEDTLS_MD_NONE":
return l
h = hash_ctx(alg_str)
msg_str = parts[msg_idx][1:-1]
h.update(msg_str.encode('ascii'))
msg_hash = h.hexdigest()
msg_hash_str = '"' + msg_hash.upper() + '"'
parts[msg_idx] = msg_hash_str
return ":".join(parts) + '\n'
filename = 'tests/suites/test_suite_' + suite + '.data'
with open(filename) as f:
lines = f.readlines()
lines = [fix(l) for l in lines]
with open(filename, 'w') as f:
f.writelines(lines)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
This is mostly:
sed -i 's/mbedtls_psa_translate_md/mbedtls_hash_info_psa_from_md/' \
library/*.c tests/suites/*.function
This should be good for code size as the old inline function was used
from 10 translation units inside the library, so we have 10 copies at
least.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Using static inline functions is bad for code size; the function from
md_internal.h was already used from 3 different C files, so already was
copied at least 3 times in the library, and this would only get worse
over time.
Use actual functions, and also share the actual data between them.
Provide a consistent set of operations. Conversion to/from
human-readable string was omitted for now but could be added later if
needed.
In the future, this can be used to replace other similar (inline)
functions that are currently scattered, including (but perhaps not
limited to):
- mbedtls_psa_translate_md() from psa_util.h
- mbedtls_md_info_from_psa() (indirectly) from psa_crypto_hash.h
- get_md_alg_from_psa() from psa_crypto_rsa.c
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Same rationale as previous "Rm useless use of MD" commits.
Here the first two test functions were already not depending on MD_C,
but the new version is much simpler, as it avoids having two versions of
the code depending on the value of USE_PSA.
Changes to the data file generated with the following Python script:
import hashlib
suite = 'pk'
functions = {
'pk_rsa_verify_test_vec': (2, 1, True),
'pk_rsa_verify_ext_test_vec': (2, 1, True),
'pk_sign_verify_restart': (6, 7, False),
}
def hash_ctx(s):
if s == 'MBEDTLS_MD_MD5':
return hashlib.md5()
if s == 'MBEDTLS_MD_SHA1':
return hashlib.sha1()
if s == 'MBEDTLS_MD_SHA224':
return hashlib.sha224()
if s == 'MBEDTLS_MD_SHA256':
return hashlib.sha256()
if s == 'MBEDTLS_MD_SHA384':
return hashlib.sha384()
if s == 'MBEDTLS_MD_SHA512':
return hashlib.sha512()
if s == 'MBEDTLS_MD_RIPEMD160':
return hashlib.new("ripemd160")
def fix(l):
parts = l.rstrip().split(":")
fun = parts[0]
if fun not in functions:
return l
(alg_idx, msg_idx, is_hex) = functions[fun]
alg_str = parts[alg_idx]
if alg_str == "MBEDTLS_MD_NONE" or alg_str == "255":
return l
h = hash_ctx(alg_str)
msg_str = parts[msg_idx][1:-1]
msg = bytes.fromhex(msg_str) if is_hex else bytes(msg_str, 'ascii')
h.update(msg)
msg_hash = h.hexdigest()
msg_hash_str = '"' + msg_hash + '"'
parts[msg_idx] = msg_hash_str
return ":".join(parts) + '\n'
filename = 'tests/suites/test_suite_' + suite + '.data'
with open(filename) as f:
lines = f.readlines()
lines = [fix(l) for l in lines]
with open(filename, 'w') as f:
f.writelines(lines)
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Tests are not here to demonstrate best practice, but to test a specific
part of the code. Using an RNG provided by the test framework also makes
the test code more focused on what we actually mean to test.
This brings the number of tests skipped in test_suite_rsa in
test_psa_crypto_config_accel_hash_use_psa down to 0 (from 50).
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Probably the result of copy-pasting: the test functions actually don't
use those modules at all.
This brings the number of tests skipped in test_suite_rsa in
test_psa_crypto_config_accel_hash_use_psa down to 50 (from 61).
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This brings the number of tests skipped in test_suite_rsa in
test_psa_crypto_config_accel_hash_use_psa down to 61 (from 117).
The changes to the test data file were generated with:
sed -i -f or_psa_hash.sed tests/suites/test_suite_rsa.data
with or_psa_hash.sed containing:
s/MBEDTLS_MD5_C/MBEDTLS_OR_PSA_WANT_ALG_MD5/g
s/MBEDTLS_RIPEMD160_C/MBEDTLS_OR_PSA_WANT_ALG_RIPEMD160/g
s/MBEDTLS_SHA1_C/MBEDTLS_OR_PSA_WANT_ALG_SHA_1/g
s/MBEDTLS_SHA224_C/MBEDTLS_OR_PSA_WANT_ALG_SHA_224/g
s/MBEDTLS_SHA256_C/MBEDTLS_OR_PSA_WANT_ALG_SHA_256/g
s/MBEDTLS_SHA384_C/MBEDTLS_OR_PSA_WANT_ALG_SHA_384/g
s/MBEDTLS_SHA512_C/MBEDTLS_OR_PSA_WANT_ALG_SHA_512/g
Here the MBEDTLS_OR_PSA_xxx macros are the right choice as we just need
data about the hashes to be available.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Same rationale as two commits ago.
Changes to the data file generated with the following script:
import hashlib
suite = 'rsa'
functions = {
'mbedtls_rsa_pkcs1_sign': (3, 1),
'mbedtls_rsa_pkcs1_verify': (3, 1),
}
def hash_ctx(s):
if s == 'MBEDTLS_MD_MD5':
return hashlib.md5()
if s == 'MBEDTLS_MD_SHA1':
return hashlib.sha1()
if s == 'MBEDTLS_MD_SHA224':
return hashlib.sha224()
if s == 'MBEDTLS_MD_SHA256':
return hashlib.sha256()
if s == 'MBEDTLS_MD_SHA384':
return hashlib.sha384()
if s == 'MBEDTLS_MD_SHA512':
return hashlib.sha512()
if s == 'MBEDTLS_MD_RIPEMD160':
return hashlib.new("ripemd160")
def fix(l):
parts = l.rstrip().split(":")
fun = parts[0]
if fun not in functions:
return l
(alg_idx, msg_idx) = functions[fun]
alg_str = parts[alg_idx]
if alg_str == "MBEDTLS_MD_NONE" or alg_str == "255":
return l
h = hash_ctx(alg_str)
msg_str = parts[msg_idx]
msg_hex = msg_str[1:-1]
msg = bytes.fromhex(msg_hex)
h.update(msg)
msg_hash = h.hexdigest()
msg_hash_str = '"' + msg_hash + '"'
parts[msg_idx] = msg_hash_str
return ":".join(parts) + '\n'
filename = 'tests/suites/test_suite_' + suite + '.data'
with open(filename) as f:
lines = f.readlines()
lines = [fix(l) for l in lines]
with open(filename, 'w') as f:
f.writelines(lines)
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This brings the number of tests skipped in test_suite_pkcs1_v15 in
test_psa_crypto_config_accel_hash_use_psa to 0.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
We had a message in the data file, and were computing its hash in the
test function. It is more efficient (and simpler when it comes to
dependencies) to directly have the message hash in the data file.
It was probably this way because some test vectors provide the message
for the sake of all-in-one implementation that hash-and-sign at once.
But our API gets a hash as the input and signs it. In unit tests, this
should be reflected in the signature of the test function, which should
take a hash as input.
The changes to the .data file were done using the following python
script:
import hashlib
suite = 'pkcs1_v15'
functions = {
'pkcs1_rsassa_v15_sign': (10, 12),
'pkcs1_rsassa_v15_verify': (6, 8),
}
def hash_ctx(s):
if s == 'MBEDTLS_MD_MD5':
return hashlib.md5()
if s == 'MBEDTLS_MD_SHA1':
return hashlib.sha1()
if s == 'MBEDTLS_MD_SHA224':
return hashlib.sha224()
if s == 'MBEDTLS_MD_SHA256':
return hashlib.sha256()
if s == 'MBEDTLS_MD_SHA384':
return hashlib.sha384()
if s == 'MBEDTLS_MD_SHA512':
return hashlib.sha512()
def fix(l):
parts = l.rstrip().split(":")
fun = parts[0]
if fun not in functions:
return l
(alg_idx, msg_idx) = functions[fun]
alg_str = parts[alg_idx]
if alg_str == "MBEDTLS_MD_NONE":
return l
h = hash_ctx(alg_str)
msg_str = parts[msg_idx]
msg_hex = msg_str[1:-1]
msg = bytes.fromhex(msg_hex)
h.update(msg)
msg_hash = h.hexdigest()
msg_hash_str = '"' + msg_hash + '"'
parts[msg_idx] = msg_hash_str
return ":".join(parts) + '\n'
filename = 'tests/suites/test_suite_' + suite + '.data'
with open(filename) as f:
lines = f.readlines()
lines = [fix(l) for l in lines]
with open(filename, 'w') as f:
f.writelines(lines)
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
The encrypt/decrypt cases don't depend on actually computing a hash,
just on information about it being available, and this information is
guarded by MBEDTLS_OR_PSA_WANT_xxx.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Having the whole .function file depend on SHA-1 was wrong: dependencies
in .function files are for compile-time dependencies all functions in
this file build just fine without SHA-1. It's just some tests cases that
do need SHA-1 at runtime, use dependencies on those specific tests in
the .data file then.
This reduces the number of cases skipped in this test suite in
test_psa_crypto_config_accel_hash_use_psa from 28 (all of them) down to
12 (those that actually use SHA-1 as opposed to no hash).
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Applied:
sed -i -f use_psa_hash.sed tests/suites/test_suite_pk.*
with use_psa_hash.sed as follows:
s/MBEDTLS_MD5_C/MBEDTLS_USE_PSA_WANT_ALG_MD5/g
s/MBEDTLS_RIPEMD160_C/MBEDTLS_USE_PSA_WANT_ALG_RIPEMD160/g
s/MBEDTLS_SHA1_C/MBEDTLS_USE_PSA_WANT_ALG_SHA_1/g
s/MBEDTLS_SHA224_C/MBEDTLS_USE_PSA_WANT_ALG_SHA_224/g
s/MBEDTLS_SHA256_C/MBEDTLS_USE_PSA_WANT_ALG_SHA_256/g
s/MBEDTLS_SHA384_C/MBEDTLS_USE_PSA_WANT_ALG_SHA_384/g
s/MBEDTLS_SHA512_C/MBEDTLS_USE_PSA_WANT_ALG_SHA_512/g
With this commit, test_suite_pk achieves parity between:
- crypto_full minus PKCS#1v2.1
- same minus MD (from all.sh's test_crypto_full_no_md)
and between:
- default config plus use_psa minus PKCS#1v2.1
- same with accelerators (test_psa_crypto_config_accel_hash_use_psa)
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
While at it, also fix buffer size for functions that already depend on
USE_PSA: it should be PSA_HASH_MAX_SIZE for functions that always use
PSA, and the new macro MBEDTLS_USE_PSA_MD_MAX_SIZE for functions that
use it or not depending on USE_PSA.
The only case where MBEDTLS_MD_MAX_SIZE is OK is when the function
always uses MD - currently this is the case with
pk_sign_verify_restart() as it is incompatible with USE_PSA anyway.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
When MD is only used to compute a size, use md_internal.h instead.
When it's actually used to compute a hash, mark the test function as
depending on it. This is probably suboptimal in the long run, and we
might want to either adapt the code so that it can use PSA Crypto
instead, or just pre-compute the hash in the test data.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
The parameters for init_handshake_options had changed on the development
branch after this test was created, so fixing up this test in order to
correct build failures after merge.
Signed-off-by: Paul Elliott <paul.elliott@arm.com>
Force a bad session_id_len before handshake wrapup. This should
result in a forced jump to a clean up of a serialized session.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>