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>
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>
"bignum_new.c(61,52): warning C4244: 'function': conversion from 'mbedtls_mpi_uint' to 'unsigned int', possible loss of data"
Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
Since a is not a pointer, it is passed by value and declaring it const
doesn’t make any sense and on the first read can make me miss the fact
that a is not a pointer.
Signed-off-by: Janos Follath <janos.follath@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>
Co-authored-by: Tom Cosgrove <81633263+tom-cosgrove-arm@users.noreply.github.com>
Co-authored-by: Werner Lewis <Werner.Lewis@arm.com>
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>