1
0
mirror of https://github.com/ARMmbed/mbedtls.git synced 2025-10-20 13:04:23 +08:00
Commit Graph

32222 Commits

Author SHA1 Message Date
Gilles Peskine
94e4e15748 Explain the near-duplication of test function for constant-flow tests
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-25 16:56:44 +02:00
Gilles Peskine
f845e9d111 Minor documentation improvements
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-25 16:48:42 +02:00
Gilles Peskine
b4b1920f7a We now run some tests with MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
Addresses https://github.com/Mbed-TLS/mbedtls/issues/9586 .

This is not a fully satisfactory resolution, because we don't run every
constant-flow test with Valgrind in PR jobs, only a small subset. We should
improve the coverage/resource balance.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 17:17:04 +02:00
Gilles Peskine
7db50d0700 Changelog entry for mbedtls_cipher_finish_padded()
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 15:15:07 +02:00
Gilles Peskine
beb53af31f Expand the ignore patterns for test_full_block_cipher_psa_dispatch
Some tests from `test_suite_cipher.constant_time.data` follow the same
pattern as `test_suite_cipher.aes.data` and so have the same coverage
discrepancy.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 15:15:07 +02:00
Gilles Peskine
4eba1cc364 Improve outcome reporting of additional valgrind_cf testing
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 15:15:07 +02:00
Gilles Peskine
46ebc3a758 Note that the decrypted length is sensitive when there was padding
The decrypted length reveals the amount of padding that was eliminated, and
thus reveals partial information about the last ciphertext block.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 15:15:07 +02:00
Gilles Peskine
6cb9f35d8c Switch legacy cipher to constant-time invalid padding reporting
In internal `get_padding` functions, report whether the padding was invalid
through a separate output parameter, rather than the return code. Take
advantage of this to have `mbedtls_cipher_finish_padded()` be the easy path
that just passes the `invalid_padding` through. Make
`mbedtls_cipher_finish()` a wrapper around `mbedtls_cipher_finish_padded()`
that converts the invalid-padding output into an error code.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 15:14:47 +02:00
Gilles Peskine
155de2ab77 New function mbedtls_cipher_finish_padded
New function `mbedtls_cipher_finish_padded()`, similar to
`mbedtls_cipher_finish()`, but reporting padding errors through a separate
output parameter. This makes it easier to avoid leaking the presence of a
padding error, especially through timing. Thus the new function is
recommended to defend against padding oracle attacks.

In this commit, implement this function naively, with timing that depends on
whether an error happened. A subsequent commit will make this function
constant-time.

Copy the test decrypt_test_vec and decrypt_test_vec_cf test cases into
variants that call `mbedtls_cipher_finish_padded()`.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 15:14:47 +02:00
Gilles Peskine
2da5328406 Constant-flow tests for mbedtls_cipher_crypt
Add some basic constant-flow tests for `mbedtls_cipher_crypt()`. We already
test auxiliary functions and functional behavior pretty thoroughly
elsewhere, so here just focus on the interesting cases for constant-flow
behavior with this specific function: encrypt, valid decrypt and
invalid-padding decrypt.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 15:14:47 +02:00
Gilles Peskine
df00d458a2 Constant-flow AES-CBC multipart decrypt tests
The main goal is to validate that unpadding is constant-time, including
error reporting.

Use a separate test function, not annotations in the existing function, so
that the functional tests can run on any platform, and we know from test
outcomes where we have run the constant-time tests.

The tests can only be actually constant-time if AES is constant time, since
AES computations are part of what is checked. Thus this requires
hardware-accelerated AES. We can't run our AESNI (or AESCE?) code under
Msan (it doesn't detect when memory is written from assembly code), so these
tests can only be run with Valgrind.

Same test data as the newly introduced functional tests.

    #!/usr/bin/env python3
    from Crypto.Cipher import AES

    KEYS = {
        128: bytes.fromhex("ffffffffe00000000000000000000000"),
        192: bytes.fromhex("000000000000000000000000000000000000000000000000"),
        256: bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000"),
    }
    IV = bytes.fromhex("00000000000000000000000000000000")

    def decrypt_test_vec(cf, bits, mode, padded_hex, padding_length, note=''):
        depends = ['MBEDTLS_AES_C', 'MBEDTLS_CIPHER_MODE_CBC']
        plaintext = bytes.fromhex(padded_hex)
        plaintext_length = len(plaintext)
        if bits != 128:
            depends.append('!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH')
        key = KEYS[bits]
        iv = IV
        result = '0'
        if mode == 'NONE':
            padding_description = 'no padding'
            assert padding_length == 0
        else:
            depends.append('MBEDTLS_CIPHER_PADDING_' + mode)
            padding_description = mode
            if padding_length is None:
                result = 'MBEDTLS_ERR_CIPHER_INVALID_PADDING'
                plaintext_length = 0
            else:
                plaintext_length -= padding_length
        cipher = AES.new(key, AES.MODE_CBC, iv=iv)
        ciphertext = cipher.encrypt(plaintext)
        function = 'decrypt_test_vec'
        cf_maybe = ''
        if cf:
            function += '_cf'
            cf_maybe = 'CF '
            depends.append('HAVE_CONSTANT_TIME_AES')
        if note:
            note = f' ({note})'
        print(f'''\
    {cf_maybe}AES-{bits}-CBC Decrypt test vector, {padding_description}{note}
    depends_on:{':'.join(depends)}
    {function}:MBEDTLS_CIPHER_AES_{bits}_CBC:MBEDTLS_PADDING_{mode}:"{key.hex()}":"{iv.hex()}":"{ciphertext.hex()}":"{plaintext[:plaintext_length].hex()}":"":"":{result}:0
    ''')

    def emit_tests(cf):
        # Already existing tests
        decrypt_test_vec(cf, 128, 'NONE', "00000000000000000000000000000000", 0)
        decrypt_test_vec(cf, 192, 'NONE', "fffffffff80000000000000000000000", 0)
        decrypt_test_vec(cf, 256, 'NONE', "ff000000000000000000000000000000", 0)

        # New tests
        decrypt_test_vec(cf, 128, 'PKCS7', "00000000000000000000000000000001", 1, 'good pad 1')
        decrypt_test_vec(cf, 192, 'PKCS7', "fffffffff80000000000000000000001", 1, 'good pad 1')
        decrypt_test_vec(cf, 256, 'PKCS7', "ff000000000000000000000000000001", 1, 'good pad 1')
        decrypt_test_vec(cf, 128, 'PKCS7', "00000000000000000000000000000202", 2, 'good pad 2')
        decrypt_test_vec(cf, 192, 'PKCS7', "fffffffff80000000000000000000202", 2, 'good pad 2')
        decrypt_test_vec(cf, 256, 'PKCS7', "ff000000000000000000000000000202", 2, 'good pad 2')
        decrypt_test_vec(cf, 128, 'PKCS7', "2a0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", 15, 'good pad 15')
        decrypt_test_vec(cf, 192, 'PKCS7', "2a0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", 15, 'good pad 15')
        decrypt_test_vec(cf, 256, 'PKCS7', "2a0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", 15, 'good pad 15')
        decrypt_test_vec(cf, 128, 'PKCS7', "10101010101010101010101010101010", 16, 'good pad 16')
        decrypt_test_vec(cf, 192, 'PKCS7', "10101010101010101010101010101010", 16, 'good pad 16')
        decrypt_test_vec(cf, 256, 'PKCS7', "10101010101010101010101010101010", 16, 'good pad 16')
        decrypt_test_vec(cf, 128, 'PKCS7', "00000000000000000000000000000000", None, 'bad pad 0')
        decrypt_test_vec(cf, 192, 'PKCS7', "fffffffff80000000000000000000000", None, 'bad pad 0')
        decrypt_test_vec(cf, 256, 'PKCS7', "ff000000000000000000000000000000", None, 'bad pad 0')
        decrypt_test_vec(cf, 128, 'PKCS7', "00000000000000000000000000000102", None, 'bad pad 0102')
        decrypt_test_vec(cf, 192, 'PKCS7', "fffffffff80000000000000000000102", None, 'bad pad 0102')
        decrypt_test_vec(cf, 256, 'PKCS7', "ff000000000000000000000000000102", None, 'bad pad 0102')
        decrypt_test_vec(cf, 128, 'PKCS7', "1111111111111111111111111111111111111111111111111111111111111111", None, 'long, bad pad 17')
        decrypt_test_vec(cf, 192, 'PKCS7', "1111111111111111111111111111111111111111111111111111111111111111", None, 'long, bad pad 17')
        decrypt_test_vec(cf, 256, 'PKCS7', "1111111111111111111111111111111111111111111111111111111111111111", None, 'long, bad pad 17')
        decrypt_test_vec(cf, 128, 'PKCS7', "11111111111111111111111111111111", None, 'short, bad pad 17')
        decrypt_test_vec(cf, 192, 'PKCS7', "11111111111111111111111111111111", None, 'short, bad pad 17')
        decrypt_test_vec(cf, 256, 'PKCS7', "11111111111111111111111111111111", None, 'short, bad pad 17')

    emit_tests(True)

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 15:14:47 +02:00
Gilles Peskine
580d1f4954 Do dedicated constant-time testing in a few more configurations
Do constant-time testing in a couple of configurations that give some
interesting coverage;

* In a configuration that's close to the default: `test_aes_only_128_bit_keys`.
  Having only 128-bit AES keys doesn't reduce the interesting scope much
  (except that it doesn't test 192-bit and 256-bit AES, but since that
  configuration uses hardware AES, we don't care about that part).
* when PSA buffer copying is not done, i.e. when
  `MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS` is enabled. This will be very
  relevant for the upcoming PSA constant-time tests.

Use Valgrind, since some of the interesting tests require constant-time AES,
which for us means AESNI or AESCE, which MSan doesn't support.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 15:14:47 +02:00
Gilles Peskine
54131a3dc6 Move constant-time padding tests to a separate suite
Make it easier to run just the tests that matter under constant-flow testing
instrumentation.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 15:14:47 +02:00
Gilles Peskine
5ee94d52a6 More variety of CBC decrypt tests
Have tests without padding, with valid PKCS7 padding and with several kinds
of invalid PKCS7 padding.

    #!/usr/bin/env python3
    from Crypto.Cipher import AES

    KEYS = {
        128: bytes.fromhex("ffffffffe00000000000000000000000"),
        192: bytes.fromhex("000000000000000000000000000000000000000000000000"),
        256: bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000"),
    }
    IV = bytes.fromhex("00000000000000000000000000000000")

    def decrypt_test_vec(cf, bits, mode, padded_hex, padding_length, note=''):
        depends = ['MBEDTLS_AES_C', 'MBEDTLS_CIPHER_MODE_CBC']
        plaintext = bytes.fromhex(padded_hex)
        plaintext_length = len(plaintext)
        if bits != 128:
            depends.append('!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH')
        key = KEYS[bits]
        iv = IV
        result = '0'
        if mode == 'NONE':
            padding_description = 'no padding'
            assert padding_length == 0
        else:
            depends.append('MBEDTLS_CIPHER_PADDING_' + mode)
            padding_description = mode
            if padding_length is None:
                result = 'MBEDTLS_ERR_CIPHER_INVALID_PADDING'
                plaintext_length = 0
            else:
                plaintext_length -= padding_length
        cipher = AES.new(key, AES.MODE_CBC, iv=iv)
        ciphertext = cipher.encrypt(plaintext)
        function = 'decrypt_test_vec'
        cf_maybe = ''
        if cf:
            function += '_cf'
            cf_maybe = 'CF '
            depends.append('HAVE_CONSTANT_TIME_AES')
        if note:
            note = f' ({note})'
        print(f'''\
    {cf_maybe}AES-{bits}-CBC Decrypt test vector, {padding_description}{note}
    depends_on:{':'.join(depends)}
    {function}:MBEDTLS_CIPHER_AES_{bits}_CBC:MBEDTLS_PADDING_{mode}:"{key.hex()}":"{iv.hex()}":"{ciphertext.hex()}":"{plaintext[:plaintext_length].hex()}":"":"":{result}:0
    ''')

    def emit_tests(cf):
        # Already existing tests
        decrypt_test_vec(cf, 128, 'NONE', "00000000000000000000000000000000", 0)
        decrypt_test_vec(cf, 192, 'NONE', "fffffffff80000000000000000000000", 0)
        decrypt_test_vec(cf, 256, 'NONE', "ff000000000000000000000000000000", 0)

        # New tests
        decrypt_test_vec(cf, 128, 'PKCS7', "00000000000000000000000000000001", 1, 'good pad 1')
        decrypt_test_vec(cf, 192, 'PKCS7', "fffffffff80000000000000000000001", 1, 'good pad 1')
        decrypt_test_vec(cf, 256, 'PKCS7', "ff000000000000000000000000000001", 1, 'good pad 1')
        decrypt_test_vec(cf, 128, 'PKCS7', "00000000000000000000000000000202", 2, 'good pad 2')
        decrypt_test_vec(cf, 192, 'PKCS7', "fffffffff80000000000000000000202", 2, 'good pad 2')
        decrypt_test_vec(cf, 256, 'PKCS7', "ff000000000000000000000000000202", 2, 'good pad 2')
        decrypt_test_vec(cf, 128, 'PKCS7', "2a0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", 15, 'good pad 15')
        decrypt_test_vec(cf, 192, 'PKCS7', "2a0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", 15, 'good pad 15')
        decrypt_test_vec(cf, 256, 'PKCS7', "2a0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", 15, 'good pad 15')
        decrypt_test_vec(cf, 128, 'PKCS7', "10101010101010101010101010101010", 16, 'good pad 16')
        decrypt_test_vec(cf, 192, 'PKCS7', "10101010101010101010101010101010", 16, 'good pad 16')
        decrypt_test_vec(cf, 256, 'PKCS7', "10101010101010101010101010101010", 16, 'good pad 16')
        decrypt_test_vec(cf, 128, 'PKCS7', "00000000000000000000000000000000", None, 'bad pad 0')
        decrypt_test_vec(cf, 192, 'PKCS7', "fffffffff80000000000000000000000", None, 'bad pad 0')
        decrypt_test_vec(cf, 256, 'PKCS7', "ff000000000000000000000000000000", None, 'bad pad 0')
        decrypt_test_vec(cf, 128, 'PKCS7', "00000000000000000000000000000102", None, 'bad pad 0102')
        decrypt_test_vec(cf, 192, 'PKCS7', "fffffffff80000000000000000000102", None, 'bad pad 0102')
        decrypt_test_vec(cf, 256, 'PKCS7', "ff000000000000000000000000000102", None, 'bad pad 0102')
        decrypt_test_vec(cf, 128, 'PKCS7', "1111111111111111111111111111111111111111111111111111111111111111", None, 'long, bad pad 17')
        decrypt_test_vec(cf, 192, 'PKCS7', "1111111111111111111111111111111111111111111111111111111111111111", None, 'long, bad pad 17')
        decrypt_test_vec(cf, 256, 'PKCS7', "1111111111111111111111111111111111111111111111111111111111111111", None, 'long, bad pad 17')
        decrypt_test_vec(cf, 128, 'PKCS7', "11111111111111111111111111111111", None, 'short, bad pad 17')
        decrypt_test_vec(cf, 192, 'PKCS7', "11111111111111111111111111111111", None, 'short, bad pad 17')
        decrypt_test_vec(cf, 256, 'PKCS7', "11111111111111111111111111111111", None, 'short, bad pad 17')

    emit_tests(False)

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 15:14:47 +02:00
Gilles Peskine
71ee919dbe More meaningful test case names
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2025-08-08 15:14:47 +02:00
Manuel Pégourié-Gonnard
81a3e86a45 Merge pull request #1402 from felixc-arm/bignum-gcd-testing-followup
Bignum gcd testing followup
2025-08-04 10:20:29 +02:00
Felix Conway
014d9d16fd Update framework pointer
Signed-off-by: Felix Conway <felix.conway@arm.com>
2025-08-01 13:57:42 +01:00
Felix Conway
1e89301a2d Add GCD tests for (0, negative) inputs
Signed-off-by: Felix Conway <felix.conway@arm.com>
2025-08-01 13:57:26 +01:00
Manuel Pégourié-Gonnard
847697cee2 Merge pull request #1398 from felixc-arm/bignum-improve-gcd-invmod-testing
[3.6] Improve testing of mbedtls_mpi_gcd() and mbedtls_mpi_inv_mod()
2025-07-30 21:58:26 +02:00
Felix Conway
7758aa340a Add GCD tests that return negative when b=0
Signed-off-by: Felix Conway <felix.conway@arm.com>
2025-07-30 09:59:42 +01:00
Felix Conway
e28bb8cbe6 Revert "Remove manual GCD tests that are now generated"
This reverts commit bb50b5ab0e.

Signed-off-by: Felix Conway <felix.conway@arm.com>
2025-07-30 09:59:08 +01:00
Felix Conway
c51168039b Clarify mpi_gdc() documentation when B is 0
Signed-off-by: Felix Conway <felix.conway@arm.com>
2025-07-29 15:50:05 +01:00
Felix Conway
bb50b5ab0e Remove manual GCD tests that are now generated
Signed-off-by: Felix Conway <felix.conway@arm.com>
2025-07-29 15:36:19 +01:00
Felix Conway
fca43c79fb Rework misleading comment
Signed-off-by: Felix Conway <felix.conway@arm.com>
2025-07-29 15:34:28 +01:00
Felix Conway
4c7c5c3f17 Add more manual inv_mod tests
Signed-off-by: Felix Conway <felix.conway@arm.com>
2025-07-29 12:10:03 +01:00
Felix Conway
8951916ac7 Fix pointer aliasing in bignum tests
Signed-off-by: Felix Conway <felix.conway@arm.com>
2025-07-29 11:03:08 +01:00
Manuel Pégourié-Gonnard
9b54f93458 Merge pull request #1387 from mpg/ct-gcd-modinv
bignum_core: Add mbedtls_mpi_core_gcd_modinv_odd()
2025-07-28 23:25:35 +02:00
Felix Conway
f6d883c928 Improve invmod and gcd handwritten tests
Signed-off-by: Felix Conway <felix.conway@arm.com>
2025-07-28 16:32:14 +01:00
Felix Conway
1527b69c7f Clarify parameter documentation
Signed-off-by: Felix Conway <felix.conway@arm.com>
2025-07-28 16:31:44 +01:00
Manuel Pégourié-Gonnard
eb34680126 Use more meaningful names in test function
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-25 09:49:30 +02:00
Manuel Pégourié-Gonnard
be8983d394 Use precise sizes for temporaries in test
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-25 09:46:52 +02:00
Manuel Pégourié-Gonnard
0904a74235 Remove tests for 0 limbs
That rule is common to the whole module and not a likely mistake to
make. Also, the test was not really precise as G, I, T were oversized.
Better remove it than give a false sense of security.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-25 09:33:20 +02:00
Felix Conway
9646537e94 Improve testing of mbedtls_mpi_gcd() and mbedtls_mpi_inv_mod()
Signed-off-by: Felix Conway <felix.conway@arm.com>
2025-07-24 15:25:00 +01:00
Manuel Pégourié-Gonnard
ec35382a51 Try again to clarify connection with the paper
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-24 12:22:16 +02:00
Manuel Pégourié-Gonnard
efd242a0e5 Gracefully handle A_limbs > N_limbs and test it
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-24 11:10:59 +02:00
Manuel Pégourié-Gonnard
9361550c45 Tune comment about paper vs our code again
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-23 13:21:07 +02:00
Manuel Pégourié-Gonnard
dbda872369 Expand comment about adaptations from the paper
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-22 09:21:53 +02:00
Manuel Pégourié-Gonnard
ed711e1420 Clarify preconditions and impact if not met
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-22 09:00:52 +02:00
Manuel Pégourié-Gonnard
0d25cd965d Add test case exercising (almost) max iterations
With this data, the loop only settles to its final state u == 0 and v ==
GCD(A, N) at the last iteration. However it already has v == GCD(A, N)
at the previous iteration. Concretely, this means that if in
mbedtls_mpi_core_gcd_modinv_odd() we change the main loop as follows

-    for (size_t i = 0; i < (A_limbs + N_limbs) * biL; i++) {
+    for (size_t i = 0; i < (A_limbs + N_limbs) * biL - 2; i++) {

then this test case would fail. Ideally we'd like a test case that would
fail with -1 above but I've not been able to find one and I have no idea
whether that's possible.

Experimentally I've systematically tried small values (8 bit) and
noticed the case A = 2^n and N significantly larger then A is promising,
so I explored that further. Clearly we want A and N's bitlength to be a
multiple of biL because the bound in the paper is with bitlenths while
we use limbs * biL.

Anyway, I ended up with the following Python script.

import secrets
import math

bil = 64

def bitlimbs(x):
    return (x.bit_length() + bil - 1) // bil * bil

def sict_gcd(p, a):
    assert p >= a >= 0
    assert p & 1 != 0 or a & 1 != 0

    u, v = a, p
    for i in range(2 * p.bit_length()):
        s, z = u & 1, v & 1
        t1 = (s ^ z) * v + (2 * s * z - 1) * u
        t2 = (s * v + (2 - 2 * s - z) * u) >> 1

        if t2 >= t1:
            u, v = t1, t2
        else:
            u, v = t2, t1

        if u == 0:  # v == 1 ideally, but can't get it
            return bitlimbs(a) + bitlimbs(p) - (i + 1)

    return 0

a = 2 ** (bil - 1)
m = 1000
while m != 0:
    n = secrets.randbits(2 * bil) | 1
    d = sict_gcd(n, a)
    if d < m:
        m = d
        print(d)

g = math.gcd(a, n)
i = pow(a, -1, n)
print(f'mpi_core_gcd_modinv_odd:"{a:x}":"{n:x}":"{g:x}":"{i:x}"')

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-18 09:40:14 +02:00
Manuel Pégourié-Gonnard
5972096114 Forbid uninteresting edge cases
A == N (as pointers) will not happen in pratice: in our context, it
would mean we know at compile time that A == N (as values), and we
wouldn't be calling this function if we knew that already.

N == 1 when I != NULL is also not going to happen: we don't care about
operations mod 1.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-18 09:40:14 +02:00
Manuel Pégourié-Gonnard
7fba466826 Unit-test mpi_core_div2_mod_odd()
This function has specific code to handle carries and it's not clear how
to exercises that code through the modinv function, so well, that's what
unit tests are for.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-18 09:40:14 +02:00
Manuel Pégourié-Gonnard
fb2001faf5 Make sure the whole temporary array is non-zero
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-18 09:40:14 +02:00
Manuel Pégourié-Gonnard
04ac5d8d35 Reduce clutter & improve readbility in test func
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-18 09:40:14 +02:00
Manuel Pégourié-Gonnard
d0527406c0 Relax number-of-limbs requirement on test data
Also more precisely enforce requirement that A <= N.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-18 09:40:14 +02:00
Manuel Pégourié-Gonnard
de5eeb5ce9 Relax and test aliasing rules
This is consistent with the general rules documented at the top of the
file:
- when computing GCD(A, N), there is no modular arithmetic, so the
  output can alias any of the inputs;
- when computing a modular inverse, N is the modulus, so it can't be
  aliased by any of the outputs (we'll use it for modular operations
  over the entire course of the function's execution).

But since this function has two modes of operations with different
aliasing rules (G can alias N only if I == NULL), I think it should
really be stated explicitly.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-18 09:40:14 +02:00
Manuel Pégourié-Gonnard
07a057756c bignum_core: Add mbedtls_mpi_core_gcd_modinv_odd()
This is a direct translation of sict_mi2() from
https://github.com/mpg/cryptohack/blob/main/ct-pres.py
which was presented in the book club's special session.

This commit only includes two test cases which is very little. Most of
the test cases will be generated by Python modules that belong  to the
framework. However we can't have the framework generate those before we
have the corresponding test function in the consuming branches. So,
extended tests are coming as a 2nd step, after the test function has
been merged.

(The test cases in .misc should stay, as they can be convenient when
working on the test function.)

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2025-07-18 09:40:14 +02:00
Bence Szépkúti
8f4779c6fa Merge pull request #10303 from bensze01/freebsd-3.6
[Backport 3.6] Clean up ci.requirements.txt
2025-07-16 21:29:19 +00:00
Bence Szépkúti
222090abf6 Restrict CI-specific python requirements to Linux
The dependencies declared in ci.requirements.txt are only used in
scripts that we run on the Linux CI.

Signed-off-by: Bence Szépkúti <bence.szepkuti@arm.com>
2025-07-16 15:13:14 +02:00
Bence Szépkúti
9ecab503c2 Don't install cryptography on the FreeBSD CI
Recent versions of cryptography require a Rust toolchain to install on
FreeBSD, which we do not have set up yet.

Signed-off-by: Bence Szépkúti <bence.szepkuti@arm.com>
2025-07-16 15:13:13 +02:00
Bence Szépkúti
22dd79367c Freeze cryptography version on the CI at 35.0.0
The version was unspecified because of our use of Python 3.5 on the CI,
whichi has since been eliminated.

Signed-off-by: Bence Szépkúti <bence.szepkuti@arm.com>
2025-07-16 15:13:13 +02:00