1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-10-23 01:52:40 +03:00

Merge remote-tracking branch 'restricted/mbedtls-3.6-restricted' into mbedtls-3.6.5rc0-pr

Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
This commit is contained in:
Minos Galanakis
2025-10-02 15:37:04 +01:00
34 changed files with 2900 additions and 413 deletions

5
ChangeLog.d/gcd-sign.txt Normal file
View File

@@ -0,0 +1,5 @@
Changes
* The function mbedtls_mpi_gcd() now always gives a non-negative output.
Previously the output was negative when B = 0 and A < 0, which was not
documented, and inconsistent as all other inputs resulted in a non-negative
output.

View File

@@ -0,0 +1,4 @@
Features
* The new function mbedtls_cipher_finish_padded() is similar to
mbedtls_cipher_finish(), but makes it easier to process invalid-padding
conditions in constant time.

View File

@@ -0,0 +1,5 @@
Security
* Fix a timing side channel in CBC-PKCS7 decryption that could
allow an attacker who can submit chosen ciphertexts to recover
some plaintexts through a timing-based padding oracle attack.
Credits to Beat Heeb from Oberon microsystems AG. CVE-2025-59438

View File

@@ -0,0 +1,12 @@
Security
* Fix a local timing side-channel in modular inversion and GCD that was
exploitable in RSA key generation and other RSA operations (see the full
advisory for details), allowing a local attacker to fully recover the
private key. This can be exploited on some Arm-v9 CPUs by an unprivileged
attacker running code on the same core (SSBleed), or when Trustzone-M is
used, by the non-secure side abusing timer interrupts (M-Step), and
probably in other similar settings as well. Found and reported
independently by: SSBleed: Chang Liu (Tsinghua University) and Trevor E.
Carlson (National University of Singapore); M-Step: Cristiano Rodrigues
(University of Minho), Marton Bognar (DistriNet, KU Leuven), Sandro Pinto
(University of Minho), Jo Van Bulck (DistriNet, KU Leuven). CVE-2025-54764

View File

@@ -974,6 +974,7 @@ int mbedtls_mpi_random(mbedtls_mpi *X,
* \brief Compute the greatest common divisor: G = gcd(A, B)
*
* \param G The destination MPI. This must point to an initialized MPI.
* This will always be positive or 0.
* \param A The first operand. This must point to an initialized MPI.
* \param B The second operand. This must point to an initialized MPI.
*
@@ -988,10 +989,12 @@ int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A,
* \brief Compute the modular inverse: X = A^-1 mod N
*
* \param X The destination MPI. This must point to an initialized MPI.
* The value returned on success will be between [1, N-1].
* \param A The MPI to calculate the modular inverse of. This must point
* to an initialized MPI.
* to an initialized MPI. This value can be negative, in which
* case a positive answer will still be returned in \p X.
* \param N The base of the modular inversion. This must point to an
* initialized MPI.
* initialized MPI and be greater than one.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.

View File

@@ -329,8 +329,15 @@ typedef struct mbedtls_cipher_context_t {
/** Padding functions to use, if relevant for
* the specific cipher mode.
*/
void(*MBEDTLS_PRIVATE(add_padding))(unsigned char *output, size_t olen, size_t data_len);
int(*MBEDTLS_PRIVATE(get_padding))(unsigned char *input, size_t ilen, size_t *data_len);
void(*MBEDTLS_PRIVATE(add_padding))(unsigned char *output, size_t olen,
size_t data_len);
/* Report invalid-padding condition through the output parameter
* invalid_padding. To minimize changes in Mbed TLS 3.6, where this
* declaration is in a public header, use the public type size_t
* rather than the internal type mbedtls_ct_condition_t. */
int(*MBEDTLS_PRIVATE(get_padding))(unsigned char *input, size_t ilen,
size_t *data_len,
size_t *invalid_padding);
#endif
/** Buffer for input that has not been processed yet. */
@@ -878,23 +885,24 @@ int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx,
*
* \note With non-AEAD ciphers, the order of calls for each message
* is as follows:
* 1. mbedtls_cipher_set_iv() if the mode uses an IV/nonce.
* 2. mbedtls_cipher_reset()
* 3. mbedtls_cipher_update() one or more times
* 4. mbedtls_cipher_finish()
* 1. mbedtls_cipher_set_iv() if the mode uses an IV/nonce;
* 2. mbedtls_cipher_reset();
* 3. mbedtls_cipher_update() zero, one or more times;
* 4. mbedtls_cipher_finish_padded() (recommended for decryption
* if the mode uses padding) or mbedtls_cipher_finish().
* .
* This sequence can be repeated to encrypt or decrypt multiple
* messages with the same key.
*
* \note With AEAD ciphers, the order of calls for each message
* is as follows:
* 1. mbedtls_cipher_set_iv() if the mode uses an IV/nonce.
* 2. mbedtls_cipher_reset()
* 3. mbedtls_cipher_update_ad()
* 4. mbedtls_cipher_update() one or more times
* 5. mbedtls_cipher_finish()
* 1. mbedtls_cipher_set_iv() if the mode uses an IV/nonce;
* 2. mbedtls_cipher_reset();
* 3. mbedtls_cipher_update_ad();
* 4. mbedtls_cipher_update() zero, one or more times;
* 5. mbedtls_cipher_finish() (or mbedtls_cipher_finish_padded());
* 6. mbedtls_cipher_check_tag() (for decryption) or
* mbedtls_cipher_write_tag() (for encryption).
* mbedtls_cipher_write_tag() (for encryption).
* .
* This sequence can be repeated to encrypt or decrypt multiple
* messages with the same key.
@@ -930,7 +938,8 @@ int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx,
* many block-sized blocks of data as possible to output.
* Any data that cannot be written immediately is either
* added to the next block, or flushed when
* mbedtls_cipher_finish() is called.
* mbedtls_cipher_finish() or mbedtls_cipher_finish_padded()
* is called.
* Exception: For MBEDTLS_MODE_ECB, expects a single block
* in size. For example, 16 Bytes for AES.
*
@@ -964,12 +973,30 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx,
* contained in it is padded to the size of
* the last block, and written to the \p output buffer.
*
* \warning This function reports invalid padding through an error
* code. Adversaries may be able to decrypt encrypted
* data if they can submit chosen ciphertexts and
* detect whether it has valid padding or not,
* either through direct observation or through a side
* channel such as timing. This is known as a
* padding oracle attack.
* Therefore applications that call this function for
* decryption with a cipher that involves padding
* should take care around error handling. Preferably,
* such applications should use
* mbedtls_cipher_finish_padded() instead of this function.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a key.
* \param output The buffer to write data to. This needs to be a writable
* buffer of at least block_size Bytes.
* \param olen The length of the data written to the \p output buffer.
* This may not be \c NULL.
* Note that when decrypting in a mode with padding,
* the actual output length is sensitive and may be
* used to mount a padding oracle attack (see warning
* above), although less efficiently than through
* the invalid-padding condition.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
@@ -977,17 +1004,66 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx,
* \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
* expecting a full block but not receiving one.
* \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting.
* while decrypting. Note that invalid-padding errors
* should be handled carefully; see the warning above.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen);
/**
* \brief The generic cipher finalization function. If data still
* needs to be flushed from an incomplete block, the data
* contained in it is padded to the size of
* the last block, and written to the \p output buffer.
*
* \note This function is similar to mbedtls_cipher_finish().
* The only difference is that it reports invalid padding
* decryption differently, through the \p invalid_padding
* parameter rather than an error code.
* For encryption, and in modes without padding (including
* all authenticated modes), this function is identical
* to mbedtls_cipher_finish().
*
* \param[in,out] ctx The generic cipher context. This must be initialized and
* bound to a key.
* \param[out] output The buffer to write data to. This needs to be a writable
* buffer of at least block_size Bytes.
* \param[out] olen The length of the data written to the \p output buffer.
* This may not be \c NULL.
* Note that when decrypting in a mode with padding,
* the actual output length is sensitive and may be
* used to mount a padding oracle attack (see warning
* on mbedtls_cipher_finish()).
* \param[out] invalid_padding
* If this function returns \c 0 on decryption,
* \p *invalid_padding is \c 0 if the ciphertext was
* valid, and all-bits-one if the ciphertext had invalid
* padding.
* On encryption, or in a mode without padding (including
* all authenticated modes), \p *invalid_padding is \c 0
* on success.
* The value in \p *invalid_padding is unspecified if
* this function returns a nonzero status.
*
* \return \c 0 on success.
* Also \c 0 for decryption with invalid padding.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
* expecting a full block but not receiving one.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_finish_padded(mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen,
size_t *invalid_padding);
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/**
* \brief This function writes a tag for AEAD ciphers.
* Currently supported with GCM and ChaCha20+Poly1305.
* This must be called after mbedtls_cipher_finish().
* This must be called after mbedtls_cipher_finish()
* or mbedtls_cipher_finish_padded().
*
* \param ctx The generic cipher context. This must be initialized,
* bound to a key, and have just completed a cipher
@@ -1006,7 +1082,8 @@ int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx,
/**
* \brief This function checks the tag for AEAD ciphers.
* Currently supported with GCM and ChaCha20+Poly1305.
* This must be called after mbedtls_cipher_finish().
* This must be called after mbedtls_cipher_finish()
* or mbedtls_cipher_finish_padded().
*
* \param ctx The generic cipher context. This must be initialized.
* \param tag The buffer holding the tag. This must be a readable

View File

@@ -430,13 +430,6 @@ cleanup:
return ret;
}
/*
* Return the number of less significant zero-bits
*/
size_t mbedtls_mpi_lsb(const mbedtls_mpi *X)
{
size_t i;
#if defined(__has_builtin)
#if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_ctz)
#define mbedtls_mpi_uint_ctz __builtin_ctz
@@ -447,22 +440,34 @@ size_t mbedtls_mpi_lsb(const mbedtls_mpi *X)
#endif
#endif
#if defined(mbedtls_mpi_uint_ctz)
#if !defined(mbedtls_mpi_uint_ctz)
static size_t mbedtls_mpi_uint_ctz(mbedtls_mpi_uint x)
{
size_t count = 0;
mbedtls_ct_condition_t done = MBEDTLS_CT_FALSE;
for (size_t i = 0; i < biL; i++) {
mbedtls_ct_condition_t non_zero = mbedtls_ct_bool((x >> i) & 1);
done = mbedtls_ct_bool_or(done, non_zero);
count = mbedtls_ct_size_if(done, count, i + 1);
}
return count;
}
#endif
/*
* Return the number of less significant zero-bits
*/
size_t mbedtls_mpi_lsb(const mbedtls_mpi *X)
{
size_t i;
for (i = 0; i < X->n; i++) {
if (X->p[i] != 0) {
return i * biL + mbedtls_mpi_uint_ctz(X->p[i]);
}
}
#else
size_t count = 0;
for (i = 0; i < X->n; i++) {
for (size_t j = 0; j < biL; j++, count++) {
if (((X->p[i] >> j) & 1) != 0) {
return count;
}
}
}
#endif
return 0;
}
@@ -1743,104 +1748,122 @@ int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR);
}
/* Constant-time GCD and/or modinv with odd modulus and A <= N */
int mbedtls_mpi_gcd_modinv_odd(mbedtls_mpi *G,
mbedtls_mpi *I,
const mbedtls_mpi *A,
const mbedtls_mpi *N)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi local_g;
mbedtls_mpi_uint *T = NULL;
const size_t T_factor = I != NULL ? 5 : 4;
const mbedtls_mpi_uint zero = 0;
/* Check requirements on A and N */
if (mbedtls_mpi_cmp_int(A, 0) < 0 ||
mbedtls_mpi_cmp_mpi(A, N) > 0 ||
mbedtls_mpi_get_bit(N, 0) != 1 ||
(I != NULL && mbedtls_mpi_cmp_int(N, 1) == 0)) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
/* Check aliasing requirements */
if (A == N || (I != NULL && (I == N || G == N))) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
mbedtls_mpi_init(&local_g);
if (G == NULL) {
G = &local_g;
}
/* We can't modify the values of G or I before use in the main function,
* as they could be aliased to A or N. */
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(G, N->n));
if (I != NULL) {
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(I, N->n));
}
T = mbedtls_calloc(sizeof(mbedtls_mpi_uint) * N->n, T_factor);
if (T == NULL) {
ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
goto cleanup;
}
mbedtls_mpi_uint *Ip = I != NULL ? I->p : NULL;
/* If A is 0 (null), then A->p would be null, and A->n would be 0,
* which would be an issue if A->p and A->n were passed to
* mbedtls_mpi_core_gcd_modinv_odd below. */
const mbedtls_mpi_uint *Ap = A->p != NULL ? A->p : &zero;
size_t An = A->n >= N->n ? N->n : A->p != NULL ? A->n : 1;
mbedtls_mpi_core_gcd_modinv_odd(G->p, Ip, Ap, An, N->p, N->n, T);
G->s = 1;
if (I != NULL) {
I->s = 1;
}
if (G->n > N->n) {
memset(G->p + N->n, 0, ciL * (G->n - N->n));
}
if (I != NULL && I->n > N->n) {
memset(I->p + N->n, 0, ciL * (I->n - N->n));
}
cleanup:
mbedtls_mpi_free(&local_g);
mbedtls_free(T);
return ret;
}
/*
* Greatest common divisor: G = gcd(A, B) (HAC 14.54)
* Greatest common divisor: G = gcd(A, B)
* Wrapper around mbedtls_mpi_gcd_modinv() that removes its restrictions.
*/
int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t lz, lzt;
mbedtls_mpi TA, TB;
mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TB);
/* Make copies and take absolute values */
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A));
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B));
TA.s = TB.s = 1;
lz = mbedtls_mpi_lsb(&TA);
lzt = mbedtls_mpi_lsb(&TB);
/* Make the two values the same (non-zero) number of limbs.
* This is needed to use mbedtls_mpi_core functions below. */
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&TA, TB.n != 0 ? TB.n : 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&TB, TA.n)); // non-zero from above
/* The loop below gives the correct result when A==0 but not when B==0.
* So have a special case for B==0. Leverage the fact that we just
* calculated the lsb and lsb(B)==0 iff B is odd or 0 to make the test
* slightly more efficient than cmp_int(). */
if (lzt == 0 && mbedtls_mpi_get_bit(&TB, 0) == 0) {
ret = mbedtls_mpi_copy(G, A);
/* Handle special cases (that don't happen in crypto usage) */
if (mbedtls_mpi_core_check_zero_ct(TA.p, TA.n) == MBEDTLS_CT_FALSE) {
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TB)); // GCD(0, B) = abs(B)
goto cleanup;
}
if (mbedtls_mpi_core_check_zero_ct(TB.p, TB.n) == MBEDTLS_CT_FALSE) {
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TA)); // GCD(A, 0) = abs(A)
goto cleanup;
}
if (lzt < lz) {
lz = lzt;
}
/* Make boths inputs odd by putting powers of 2 on the side */
const size_t za = mbedtls_mpi_lsb(&TA);
const size_t zb = mbedtls_mpi_lsb(&TB);
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, za));
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, zb));
TA.s = TB.s = 1;
/* Ensure A <= B: if B < A, swap them */
mbedtls_ct_condition_t swap = mbedtls_mpi_core_lt_ct(TB.p, TA.p, TA.n);
mbedtls_mpi_core_cond_swap(TA.p, TB.p, TA.n, swap);
/* We mostly follow the procedure described in HAC 14.54, but with some
* minor differences:
* - Sequences of multiplications or divisions by 2 are grouped into a
* single shift operation.
* - The procedure in HAC assumes that 0 < TB <= TA.
* - The condition TB <= TA is not actually necessary for correctness.
* TA and TB have symmetric roles except for the loop termination
* condition, and the shifts at the beginning of the loop body
* remove any significance from the ordering of TA vs TB before
* the shifts.
* - If TA = 0, the loop goes through 0 iterations and the result is
* correctly TB.
* - The case TB = 0 was short-circuited above.
*
* For the correctness proof below, decompose the original values of
* A and B as
* A = sa * 2^a * A' with A'=0 or A' odd, and sa = +-1
* B = sb * 2^b * B' with B'=0 or B' odd, and sb = +-1
* Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'),
* and gcd(A',B') is odd or 0.
*
* At the beginning, we have TA = |A| and TB = |B| so gcd(A,B) = gcd(TA,TB).
* The code maintains the following invariant:
* gcd(A,B) = 2^k * gcd(TA,TB) for some k (I)
*/
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(G, NULL, &TA, &TB));
/* Proof that the loop terminates:
* At each iteration, either the right-shift by 1 is made on a nonzero
* value and the nonnegative integer bitlen(TA) + bitlen(TB) decreases
* by at least 1, or the right-shift by 1 is made on zero and then
* TA becomes 0 which ends the loop (TB cannot be 0 if it is right-shifted
* since in that case TB is calculated from TB-TA with the condition TB>TA).
*/
while (mbedtls_mpi_cmp_int(&TA, 0) != 0) {
/* Divisions by 2 preserve the invariant (I). */
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, mbedtls_mpi_lsb(&TA)));
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, mbedtls_mpi_lsb(&TB)));
/* Set either TA or TB to |TA-TB|/2. Since TA and TB are both odd,
* TA-TB is even so the division by 2 has an integer result.
* Invariant (I) is preserved since any odd divisor of both TA and TB
* also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2
* also divides TB, and any odd divisor of both TB and |TA-TB|/2 also
* divides TA.
*/
if (mbedtls_mpi_cmp_mpi(&TA, &TB) >= 0) {
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&TA, &TA, &TB));
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, 1));
} else {
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&TB, &TB, &TA));
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, 1));
}
/* Note that one of TA or TB is still odd. */
}
/* By invariant (I), gcd(A,B) = 2^k * gcd(TA,TB) for some k.
* At the loop exit, TA = 0, so gcd(TA,TB) = TB.
* - If there was at least one loop iteration, then one of TA or TB is odd,
* and TA = 0, so TB is odd and gcd(TA,TB) = gcd(A',B'). In this case,
* lz = min(a,b) so gcd(A,B) = 2^lz * TB.
* - If there was no loop iteration, then A was 0, and gcd(A,B) = B.
* In this case, lz = 0 and B = TB so gcd(A,B) = B = 2^lz * TB as well.
*/
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&TB, lz));
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TB));
/* Re-inject the power of 2 we had previously put aside */
size_t zg = za > zb ? zb : za; // zg = min(za, zb)
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(G, zg));
cleanup:
@@ -1899,93 +1922,141 @@ int mbedtls_mpi_random(mbedtls_mpi *X,
}
/*
* Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
* Modular inverse: X = A^-1 mod N with N odd (and A any range)
*/
int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N)
int mbedtls_mpi_inv_mod_odd(mbedtls_mpi *X,
const mbedtls_mpi *A,
const mbedtls_mpi *N)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
mbedtls_mpi T, G;
if (mbedtls_mpi_cmp_int(N, 1) <= 0) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TU); mbedtls_mpi_init(&U1); mbedtls_mpi_init(&U2);
mbedtls_mpi_init(&G); mbedtls_mpi_init(&TB); mbedtls_mpi_init(&TV);
mbedtls_mpi_init(&V1); mbedtls_mpi_init(&V2);
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, A, N));
mbedtls_mpi_init(&T);
mbedtls_mpi_init(&G);
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, A, N));
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &T, &T, N));
if (mbedtls_mpi_cmp_int(&G, 1) != 0) {
ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
goto cleanup;
}
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&TA, A, N));
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TU, &TA));
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, N));
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TV, N));
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&U1, 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&U2, 0));
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&V1, 0));
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&V2, 1));
do {
while ((TU.p[0] & 1) == 0) {
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TU, 1));
if ((U1.p[0] & 1) != 0 || (U2.p[0] & 1) != 0) {
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&U1, &U1, &TB));
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U2, &U2, &TA));
}
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&U1, 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&U2, 1));
}
while ((TV.p[0] & 1) == 0) {
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TV, 1));
if ((V1.p[0] & 1) != 0 || (V2.p[0] & 1) != 0) {
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&V1, &V1, &TB));
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V2, &V2, &TA));
}
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&V1, 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&V2, 1));
}
if (mbedtls_mpi_cmp_mpi(&TU, &TV) >= 0) {
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&TU, &TU, &TV));
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U1, &U1, &V1));
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U2, &U2, &V2));
} else {
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&TV, &TV, &TU));
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V1, &V1, &U1));
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V2, &V2, &U2));
}
} while (mbedtls_mpi_cmp_int(&TU, 0) != 0);
while (mbedtls_mpi_cmp_int(&V1, 0) < 0) {
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&V1, &V1, N));
}
while (mbedtls_mpi_cmp_mpi(&V1, N) >= 0) {
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V1, &V1, N));
}
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &V1));
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &T));
cleanup:
mbedtls_mpi_free(&TA); mbedtls_mpi_free(&TU); mbedtls_mpi_free(&U1); mbedtls_mpi_free(&U2);
mbedtls_mpi_free(&G); mbedtls_mpi_free(&TB); mbedtls_mpi_free(&TV);
mbedtls_mpi_free(&V1); mbedtls_mpi_free(&V2);
mbedtls_mpi_free(&T);
mbedtls_mpi_free(&G);
return ret;
}
/*
* Compute X = A^-1 mod N with N even, A odd and 1 < A < N.
*
* This is not obvious because our constant-time modinv function only works with
* an odd modulus, and here the modulus is even. The idea is that computing a
* a^-1 mod b is really just computing the u coefficient in the Bézout relation
* a*u + b*v = 1 (assuming gcd(a,b) = 1, i.e. the inverse exists). But if we know
* one of u, v in this relation then the other is easy to find. So we can
* actually start by computing N^-1 mod A with gives us "the wrong half" of the
* Bézout relation, from which we'll deduce the interesting half A^-1 mod N.
*
* Return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the inverse doesn't exist.
*/
int mbedtls_mpi_inv_mod_even_in_range(mbedtls_mpi *X,
mbedtls_mpi const *A,
mbedtls_mpi const *N)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi I, G;
mbedtls_mpi_init(&I);
mbedtls_mpi_init(&G);
/* Set I = N^-1 mod A */
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&I, N, A));
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &I, &I, A));
if (mbedtls_mpi_cmp_int(&G, 1) != 0) {
ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
goto cleanup;
}
/* We know N * I = 1 + k * A for some k, which we can easily compute
* as k = (N*I - 1) / A (we know there will be no remainder). */
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&I, &I, N));
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&I, &I, 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&G, NULL, &I, A));
/* Now we have a Bézout relation N * (previous value of I) - G * A = 1,
* so A^-1 mod N is -G mod N, which is N - G.
* Note that 0 < k < N since 0 < I < A, so G (k) is already in range. */
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(X, N, &G));
cleanup:
mbedtls_mpi_free(&I);
mbedtls_mpi_free(&G);
return ret;
}
/*
* Compute X = A^-1 mod N with N even and A odd (but in any range).
*
* Return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the inverse doesn't exist.
*/
static int mbedtls_mpi_inv_mod_even(mbedtls_mpi *X,
mbedtls_mpi const *A,
mbedtls_mpi const *N)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi AA;
mbedtls_mpi_init(&AA);
/* Bring A in the range [0, N). */
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&AA, A, N));
/* We know A >= 0 but the next function wants A > 1 */
int cmp = mbedtls_mpi_cmp_int(&AA, 1);
if (cmp < 0) { // AA == 0
ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
goto cleanup;
}
if (cmp == 0) { // AA = 1
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 1));
goto cleanup;
}
/* Now we know 1 < A < N, N is even and AA is still odd */
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod_even_in_range(X, &AA, N));
cleanup:
mbedtls_mpi_free(&AA);
return ret;
}
/*
* Modular inverse: X = A^-1 mod N
*
* Wrapper around mbedtls_mpi_gcd_modinv_odd() that lifts its limitations.
*/
int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N)
{
if (mbedtls_mpi_cmp_int(N, 1) <= 0) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
if (mbedtls_mpi_get_bit(N, 0) == 1) {
return mbedtls_mpi_inv_mod_odd(X, A, N);
}
if (mbedtls_mpi_get_bit(A, 0) == 1) {
return mbedtls_mpi_inv_mod_even(X, A, N);
}
/* If A and N are both even, 2 divides their GCD, so no inverse. */
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
}
#if defined(MBEDTLS_GENPRIME)
/* Gaps between primes, starting at 3. https://oeis.org/A001223 */

View File

@@ -18,6 +18,7 @@
#include "mbedtls/platform.h"
#include "bignum_core.h"
#include "bignum_core_invasive.h"
#include "bn_mul.h"
#include "constant_time_internal.h"
@@ -1019,4 +1020,221 @@ void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X,
mbedtls_mpi_core_montmul(X, A, &Rinv, 1, N, AN_limbs, mm, T);
}
/*
* Compute X = A - B mod N.
* Both A and B must be in [0, N) and so will the output.
*/
static void mpi_core_sub_mod(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *B,
const mbedtls_mpi_uint *N,
size_t limbs)
{
mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, A, B, limbs);
(void) mbedtls_mpi_core_add_if(X, N, limbs, (unsigned) c);
}
/*
* Divide X by 2 mod N in place, assuming N is odd.
* The input must be in [0, N) and so will the output.
*/
MBEDTLS_STATIC_TESTABLE
void mbedtls_mpi_core_div2_mod_odd(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *N,
size_t limbs)
{
/* If X is odd, add N to make it even before shifting. */
unsigned odd = (unsigned) X[0] & 1;
mbedtls_mpi_uint c = mbedtls_mpi_core_add_if(X, N, limbs, odd);
mbedtls_mpi_core_shift_r(X, limbs, 1);
X[limbs - 1] |= c << (biL - 1);
}
/*
* Constant-time GCD and modular inversion - odd modulus.
*
* Pre-conditions: see public documentation.
*
* See https://www.jstage.jst.go.jp/article/transinf/E106.D/9/E106.D_2022ICP0009/_pdf
*
* The paper gives two computationally equivalent algorithms: Alg 7 (readable)
* and Alg 8 (constant-time). We use a third version that's hopefully both:
*
* u, v = A, N # N is called p in the paper but doesn't have to be prime
* q, r = 0, 1
* repeat bits(A_limbs + N_limbs) times:
* d = v - u # t1 in Alg 7
* t1 = (u and v both odd) ? u : d # t1 in Alg 8
* t2 = (u and v both odd) ? d : (u odd) ? v : u # t2 in Alg 8
* t2 >>= 1
* swap = t1 > t2 # similar to s, z in Alg 8
* u, v = (swap) ? t2, t1 : t1, t2
*
* d = r - q mod N # t2 in Alg 7
* t1 = (u and v both odd) ? q : d # t3 in Alg 8
* t2 = (u and v both odd) ? d : (u odd) ? r : q # t4 Alg 8
* t2 /= 2 mod N # see below (pre_com)
* q, r = (swap) ? t2, t1 : t1, t2
* return v, q # v: GCD, see Alg 6; q: no mult by pre_com, see below
*
* The ternary operators in the above pseudo-code need to be realised in a
* constant-time fashion. We use conditional assign for t1, t2 and conditional
* swap for the final update. (Note: the similarity between branches of Alg 7
* are highlighted in tables 2 and 3 and the surrounding text.)
*
* Also, we re-order operations, grouping things related to the inverse, which
* facilitates making its computation optional, and requires fewer temporaries.
*
* The only actual change from the paper is dropping the trick with pre_com,
* which I think complicates things for no benefit.
* See the comment on the big I != NULL block below for details.
*/
void mbedtls_mpi_core_gcd_modinv_odd(mbedtls_mpi_uint *G,
mbedtls_mpi_uint *I,
const mbedtls_mpi_uint *A,
size_t A_limbs,
const mbedtls_mpi_uint *N,
size_t N_limbs,
mbedtls_mpi_uint *T)
{
/* GCD and modinv, names common to Alg 7 and Alg 8 */
mbedtls_mpi_uint *u = T + 0 * N_limbs;
mbedtls_mpi_uint *v = G;
/* GCD and modinv, my name (t1, t2 from Alg 7) */
mbedtls_mpi_uint *d = T + 1 * N_limbs;
/* GCD and modinv, names from Alg 8 (note: t1, t2 from Alg 7 are d above) */
mbedtls_mpi_uint *t1 = T + 2 * N_limbs;
mbedtls_mpi_uint *t2 = T + 3 * N_limbs;
/* modinv only, names common to Alg 7 and Alg 8 */
mbedtls_mpi_uint *q = I;
mbedtls_mpi_uint *r = I != NULL ? T + 4 * N_limbs : NULL;
/*
* Initial values:
* u, v = A, N
* q, r = 0, 1
*
* We only write to G (aka v) after reading from inputs (A and N), which
* allows aliasing, except with N when I != NULL, as then we'll be operating
* mod N on q and r later - see the public documentation.
*/
if (A_limbs > N_limbs) {
/* Violating this precondition should not result in memory errors. */
A_limbs = N_limbs;
}
memcpy(u, A, A_limbs * ciL);
memset((char *) u + A_limbs * ciL, 0, (N_limbs - A_limbs) * ciL);
/* Avoid possible UB with memcpy when src == dst. */
if (v != N) {
memcpy(v, N, N_limbs * ciL);
}
if (I != NULL) {
memset(q, 0, N_limbs * ciL);
memset(r, 0, N_limbs * ciL);
r[0] = 1;
}
/*
* At each step, out of u, v, v - u we keep one, shift another, and discard
* the third, then update (u, v) with the ordered result.
* Then we mirror those actions with q, r, r - q mod N.
*
* Loop invariants:
* u <= v (on entry: A <= N)
* GCD(u, v) == GCD(A, N) (on entry: trivial)
* v = A * q mod N (on entry: N = A * 0 mod N)
* u = A * r mod N (on entry: A = A * 1 mod N)
* q, r in [0, N) (on entry: 0, 1)
*
* On exit:
* u = 0
* v = GCD(A, N) = A * q mod N
* if v == 1 then 1 = A * q mod N ie q is A's inverse mod N
* r = 0
*
* The exit state is a fixed point of the loop's body.
* Alg 7 and Alg 8 use 2 * bitlen(N) iterations but Theorem 2 (above in the
* paper) says bitlen(A) + bitlen(N) is actually enough.
*/
for (size_t i = 0; i < (A_limbs + N_limbs) * biL; i++) {
/* s, z in Alg 8 - use meaningful names instead */
mbedtls_ct_condition_t u_odd = mbedtls_ct_bool(u[0] & 1);
mbedtls_ct_condition_t v_odd = mbedtls_ct_bool(v[0] & 1);
/* Other conditions that will be useful below */
mbedtls_ct_condition_t u_odd_v_odd = mbedtls_ct_bool_and(u_odd, v_odd);
mbedtls_ct_condition_t v_even = mbedtls_ct_bool_not(v_odd);
mbedtls_ct_condition_t u_odd_v_even = mbedtls_ct_bool_and(u_odd, v_even);
/* This is called t1 in Alg 7 (no name in Alg 8).
* We know that u <= v so there is no carry */
(void) mbedtls_mpi_core_sub(d, v, u, N_limbs);
/* t1 (the thing that's kept) can be d (default) or u (if t2 is d) */
memcpy(t1, d, N_limbs * ciL);
mbedtls_mpi_core_cond_assign(t1, u, N_limbs, u_odd_v_odd);
/* t2 (the thing that's shifted) can be u (if even), or v (if even),
* or d (which is even if both u and v were odd) */
memcpy(t2, u, N_limbs * ciL);
mbedtls_mpi_core_cond_assign(t2, v, N_limbs, u_odd_v_even);
mbedtls_mpi_core_cond_assign(t2, d, N_limbs, u_odd_v_odd);
mbedtls_mpi_core_shift_r(t2, N_limbs, 1); // t2 is even
/* Update u, v and re-order them if needed */
memcpy(u, t1, N_limbs * ciL);
memcpy(v, t2, N_limbs * ciL);
mbedtls_ct_condition_t swap = mbedtls_mpi_core_lt_ct(v, u, N_limbs);
mbedtls_mpi_core_cond_swap(u, v, N_limbs, swap);
/* Now, if modinv was requested, do the same with q, r, but:
* - decisions still based on u and v (their initial values);
* - operations are now mod N;
* - we re-use t1, t2 for what the paper calls t3, t4 in Alg 8.
*
* Here we slightly diverge from the paper and instead do the obvious
* thing that preserves the invariants involving q and r: mirror
* operations on u and v, ie also divide by 2 here (mod N).
*
* The paper uses a trick where it replaces division by 2 with
* multiplication by 2 here, and compensates in the end by multiplying
* by pre_com, which is probably intended as an optimisation.
*
* However I believe it's not actually an optimisation, since
* constant-time modular multiplication by 2 (left-shift + conditional
* subtract) is just as costly as constant-time modular division by 2
* (conditional add + right-shift). So, skip it and keep things simple.
*/
if (I != NULL) {
/* This is called t2 in Alg 7 (no name in Alg 8). */
mpi_core_sub_mod(d, q, r, N, N_limbs);
/* t3 (the thing that's kept) */
memcpy(t1, d, N_limbs * ciL);
mbedtls_mpi_core_cond_assign(t1, r, N_limbs, u_odd_v_odd);
/* t4 (the thing that's shifted) */
memcpy(t2, r, N_limbs * ciL);
mbedtls_mpi_core_cond_assign(t2, q, N_limbs, u_odd_v_even);
mbedtls_mpi_core_cond_assign(t2, d, N_limbs, u_odd_v_odd);
mbedtls_mpi_core_div2_mod_odd(t2, N, N_limbs);
/* Update and possibly swap */
memcpy(r, t1, N_limbs * ciL);
memcpy(q, t2, N_limbs * ciL);
mbedtls_mpi_core_cond_swap(r, q, N_limbs, swap);
}
}
/* G and I already hold the correct values by virtue of being aliased */
}
#endif /* MBEDTLS_BIGNUM_C */

View File

@@ -822,4 +822,45 @@ void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X,
mbedtls_mpi_uint mm,
mbedtls_mpi_uint *T);
/** Compute GCD(A, N) and optionally the inverse of A mod N if it exists.
*
* Requires N to be odd, 0 <= A <= N and A_limbs <= N_limbs.
* When I != NULL, N (the modulus) must be greater than 1.
*
* A and N may not alias each other.
* When I == NULL (computing only the GCD), G may alias A or N.
* When I != NULL (computing the modular inverse), G or I may alias A
* but none of them may alias N (the modulus).
*
* If any of the above preconditions is not met, output values are unspecified.
*
* \param[out] G The GCD of \p A and \p N.
* Must have the same number of limbs as \p N.
* \param[out] I The inverse of \p A modulo \p N if it exists (that is,
* if \p G above is 1 on exit); indeterminate otherwise.
* This must either be NULL (to only compute the GCD),
* or have the same number of limbs as \p N.
* \param[in] A The 1st operand of GCD and number to invert.
* This value must be less than or equal to \p N.
* \param A_limbs The number of limbs of \p A.
* Must be less than or equal to \p N_limbs.
* \param[in] N The 2nd operand of GCD and modulus for inversion.
* This value must be odd.
* If I != NULL this value must be greater than 1.
* \param N_limbs The number of limbs of \p N.
* \param[in,out] T Temporary storage of size at least 5 * N_limbs limbs,
* or 4 * N_limbs if \p I is NULL (GCD only).
* Its initial content is unused and
* its final content is indeterminate.
* It must not alias or otherwise overlap any of the
* other parameters.
*/
void mbedtls_mpi_core_gcd_modinv_odd(mbedtls_mpi_uint *G,
mbedtls_mpi_uint *I,
const mbedtls_mpi_uint *A,
size_t A_limbs,
const mbedtls_mpi_uint *N,
size_t N_limbs,
mbedtls_mpi_uint *T);
#endif /* MBEDTLS_BIGNUM_CORE_H */

View File

@@ -13,11 +13,26 @@
#include "bignum_core.h"
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
#if defined(MBEDTLS_TEST_HOOKS)
#if !defined(MBEDTLS_THREADING_C)
extern void (*mbedtls_safe_codepath_hook)(void);
extern void (*mbedtls_unsafe_codepath_hook)(void);
#endif /* MBEDTLS_TEST_HOOKS && !MBEDTLS_THREADING_C */
#endif /* !MBEDTLS_THREADING_C */
/** Divide X by 2 mod N in place, assuming N is odd.
*
* \param[in,out] X The value to divide by 2 mod \p N.
* \param[in] N The modulus. Must be odd.
* \param[in] limbs The number of limbs in \p X and \p N.
*/
MBEDTLS_STATIC_TESTABLE
void mbedtls_mpi_core_div2_mod_odd(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *N,
size_t limbs);
#endif /* MBEDTLS_TEST_HOOKS */
#endif /* MBEDTLS_BIGNUM_CORE_INVASIVE_H */

View File

@@ -47,4 +47,76 @@ int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *E, const mbedtls_mpi *N,
mbedtls_mpi *prec_RR);
/**
* \brief A wrapper around a constant time function to compute
* GCD(A, N) and/or A^-1 mod N if it exists.
*
* \warning Requires N to be odd, and 0 <= A <= N. Additionally, if
* I != NULL, requires N > 1.
* The wrapper part of this function is not constant time.
*
* \note A and N must not alias each other.
* When I == NULL (computing only the GCD), G can alias A or N.
* When I != NULL (computing the modular inverse), G or I can
* alias A, but neither of them can alias N (the modulus).
*
* \param[out] G The GCD of \p A and \p N.
* This may be NULL, to only compute I.
* \param[out] I The inverse of \p A modulo \p N if it exists (that is,
* if \p G above is 1 on exit), in the range [1, \p N);
* indeterminate otherwise.
* This may be NULL, to only compute G.
* \param[in] A The 1st operand of GCD and number to invert.
* This value must be less than or equal to \p N.
* \param[in] N The 2nd operand of GCD and modulus for inversion.
* Must be odd or the results are indeterminate.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if preconditions were not
* met.
*/
int mbedtls_mpi_gcd_modinv_odd(mbedtls_mpi *G,
mbedtls_mpi *I,
const mbedtls_mpi *A,
const mbedtls_mpi *N);
/**
* \brief Modular inverse: X = A^-1 mod N with N odd
*
* \param[out] X The inverse of \p A modulo \p N in the range [1, \p N)
* on success; indeterminate otherwise.
* \param[in] A The number to invert.
* \param[in] N The modulus. Must be odd and greater than 1.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if preconditions were not
* met.
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A is not invertible mod N.
*/
int mbedtls_mpi_inv_mod_odd(mbedtls_mpi *X,
const mbedtls_mpi *A,
const mbedtls_mpi *N);
/**
* \brief Modular inverse: X = A^-1 mod N with N even,
* A odd and 1 < A < N.
*
* \param[out] X The inverse of \p A modulo \p N in the range [1, \p N)
* on success; indeterminate otherwise.
* \param[in] A The number to invert. Must be odd, greated than 1
* and less than \p N.
* \param[in] N The modulus. Must be even and greater than 1.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if preconditions were not
* met.
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A is not invertible mod N.
*/
int mbedtls_mpi_inv_mod_even_in_range(mbedtls_mpi *X,
mbedtls_mpi const *A,
mbedtls_mpi const *N);
#endif /* bignum_internal.h */

View File

@@ -846,7 +846,8 @@ static void add_pkcs_padding(unsigned char *output, size_t output_len,
*/
MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input,
size_t input_len,
size_t *data_len)
size_t *data_len,
size_t *invalid_padding)
{
size_t i, pad_idx;
unsigned char padding_len;
@@ -872,7 +873,8 @@ MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input,
/* If the padding is invalid, set the output length to 0 */
*data_len = mbedtls_ct_if(bad, 0, input_len - padding_len);
return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
*invalid_padding = mbedtls_ct_size_if_else_0(bad, SIZE_MAX);
return 0;
}
#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
@@ -893,7 +895,7 @@ static void add_one_and_zeros_padding(unsigned char *output,
}
static int get_one_and_zeros_padding(unsigned char *input, size_t input_len,
size_t *data_len)
size_t *data_len, size_t *invalid_padding)
{
if (NULL == input || NULL == data_len) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
@@ -916,7 +918,8 @@ static int get_one_and_zeros_padding(unsigned char *input, size_t input_len,
in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_bool_not(is_nonzero));
}
return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
*invalid_padding = mbedtls_ct_size_if_else_0(bad, SIZE_MAX);
return 0;
}
#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
@@ -937,7 +940,7 @@ static void add_zeros_and_len_padding(unsigned char *output,
}
static int get_zeros_and_len_padding(unsigned char *input, size_t input_len,
size_t *data_len)
size_t *data_len, size_t *invalid_padding)
{
size_t i, pad_idx;
unsigned char padding_len;
@@ -963,7 +966,8 @@ static int get_zeros_and_len_padding(unsigned char *input, size_t input_len,
bad = mbedtls_ct_bool_or(bad, nonzero_pad_byte);
}
return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
*invalid_padding = mbedtls_ct_size_if_else_0(bad, SIZE_MAX);
return 0;
}
#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
@@ -978,7 +982,7 @@ static void add_zeros_padding(unsigned char *output,
}
static int get_zeros_padding(unsigned char *input, size_t input_len,
size_t *data_len)
size_t *data_len, size_t *invalid_padding)
{
size_t i;
mbedtls_ct_condition_t done = MBEDTLS_CT_FALSE, prev_done;
@@ -994,6 +998,7 @@ static int get_zeros_padding(unsigned char *input, size_t input_len,
*data_len = mbedtls_ct_size_if(mbedtls_ct_bool_ne(done, prev_done), i, *data_len);
}
*invalid_padding = 0;
return 0;
}
#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
@@ -1005,20 +1010,21 @@ static int get_zeros_padding(unsigned char *input, size_t input_len,
* but a trivial get_padding function
*/
static int get_no_padding(unsigned char *input, size_t input_len,
size_t *data_len)
size_t *data_len, size_t *invalid_padding)
{
if (NULL == input || NULL == data_len) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
}
*data_len = input_len;
*invalid_padding = 0;
return 0;
}
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen)
int mbedtls_cipher_finish_padded(mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen,
size_t *invalid_padding)
{
if (ctx->cipher_info == NULL) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
@@ -1034,6 +1040,7 @@ int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
*olen = 0;
*invalid_padding = 0;
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/* CBC mode requires padding so we make sure a call to
@@ -1110,7 +1117,7 @@ int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
/* Set output size for decryption */
if (MBEDTLS_DECRYPT == ctx->operation) {
return ctx->get_padding(output, mbedtls_cipher_get_block_size(ctx),
olen);
olen, invalid_padding);
}
/* Set output size for encryption */
@@ -1124,6 +1131,19 @@ int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
}
int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen)
{
size_t invalid_padding = 0;
int ret = mbedtls_cipher_finish_padded(ctx, output, olen,
&invalid_padding);
if (ret == 0) {
ret = mbedtls_ct_error_if_else_0(invalid_padding,
MBEDTLS_ERR_CIPHER_INVALID_PADDING);
}
return ret;
}
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx,
mbedtls_cipher_padding_t mode)
@@ -1393,14 +1413,17 @@ int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx,
return ret;
}
if ((ret = mbedtls_cipher_finish(ctx, output + *olen,
&finish_olen)) != 0) {
size_t invalid_padding = 0;
if ((ret = mbedtls_cipher_finish_padded(ctx, output + *olen,
&finish_olen,
&invalid_padding)) != 0) {
return ret;
}
*olen += finish_olen;
return 0;
ret = mbedtls_ct_error_if_else_0(invalid_padding,
MBEDTLS_ERR_CIPHER_INVALID_PADDING);
return ret;
}
#if defined(MBEDTLS_CIPHER_MODE_AEAD)

View File

@@ -20,7 +20,8 @@
MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input,
size_t input_len,
size_t *data_len);
size_t *data_len,
size_t *invalid_padding);
#endif

View File

@@ -18,6 +18,7 @@
#if defined(MBEDTLS_DHM_C)
#include "mbedtls/dhm.h"
#include "bignum_internal.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
@@ -344,9 +345,6 @@ static int dhm_update_blinding(mbedtls_dhm_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
{
int ret;
mbedtls_mpi R;
mbedtls_mpi_init(&R);
/*
* Don't use any blinding the first time a particular X is used,
@@ -381,21 +379,11 @@ static int dhm_update_blinding(mbedtls_dhm_context *ctx,
/* Vi = random( 2, P-2 ) */
MBEDTLS_MPI_CHK(dhm_random_below(&ctx->Vi, &ctx->P, f_rng, p_rng));
/* Vf = Vi^-X mod P
* First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
* then elevate to the Xth power. */
MBEDTLS_MPI_CHK(dhm_random_below(&R, &ctx->P, f_rng, p_rng));
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vi, &R));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&ctx->Vf, &ctx->Vf, &ctx->P));
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &R));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
/* Vf = Vi^-X = (Vi^-1)^X mod P */
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, &ctx->Vf, &ctx->Vi, &ctx->P));
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP));
cleanup:
mbedtls_mpi_free(&R);
return ret;
}

View File

@@ -17,6 +17,7 @@
#include "mbedtls/ecdsa.h"
#include "mbedtls/asn1write.h"
#include "bignum_internal.h"
#include <string.h>
@@ -251,7 +252,7 @@ int mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp,
int ret, key_tries, sign_tries;
int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries;
mbedtls_ecp_point R;
mbedtls_mpi k, e, t;
mbedtls_mpi k, e;
mbedtls_mpi *pk = &k, *pr = r;
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
@@ -265,7 +266,7 @@ int mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp,
}
mbedtls_ecp_point_init(&R);
mbedtls_mpi_init(&k); mbedtls_mpi_init(&e); mbedtls_mpi_init(&t);
mbedtls_mpi_init(&k); mbedtls_mpi_init(&e);
ECDSA_RS_ENTER(sig);
@@ -340,21 +341,11 @@ modn:
MBEDTLS_MPI_CHK(derive_mpi(grp, &e, buf, blen));
/*
* Generate a random value to blind inv_mod in next step,
* avoiding a potential timing leak.
*/
MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, &t, f_rng_blind,
p_rng_blind));
/*
* Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
* Step 6: compute s = (e + r * d) / k
*/
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(s, pr, d));
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&e, &e, s));
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&e, &e, &t));
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pk, pk, &t));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pk, pk, &grp->N));
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(s, pk, &grp->N));
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, s, pk, &grp->N));
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(s, s, &e));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(s, s, &grp->N));
} while (mbedtls_mpi_cmp_int(s, 0) == 0);
@@ -367,7 +358,7 @@ modn:
cleanup:
mbedtls_ecp_point_free(&R);
mbedtls_mpi_free(&k); mbedtls_mpi_free(&e); mbedtls_mpi_free(&t);
mbedtls_mpi_free(&k); mbedtls_mpi_free(&e);
ECDSA_RS_LEAVE(sig);
@@ -540,7 +531,7 @@ int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp,
*/
ECDSA_BUDGET(MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2);
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&s_inv, s, &grp->N));
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, &s_inv, s, &grp->N));
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pu1, &e, &s_inv));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pu1, pu1, &grp->N));

View File

@@ -68,6 +68,7 @@
#include "mbedtls/error.h"
#include "bn_mul.h"
#include "bignum_internal.h"
#include "ecp_invasive.h"
#include <string.h>
@@ -1173,7 +1174,7 @@ cleanup:
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int_mod(grp, X, A, c))
#define MPI_ECP_INV(dst, src) \
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod((dst), (src), &grp->P))
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, (dst), (src), &grp->P))
#define MPI_ECP_MOV(X, A) \
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A))
@@ -2201,21 +2202,6 @@ static int ecp_mul_comb_after_precomp(const mbedtls_ecp_group *grp,
final_norm:
MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV);
#endif
/*
* Knowledge of the jacobian coordinates may leak the last few bits of the
* scalar [1], and since our MPI implementation isn't constant-flow,
* inversion (used for coordinate normalization) may leak the full value
* of its input via side-channels [2].
*
* [1] https://eprint.iacr.org/2003/191
* [2] https://eprint.iacr.org/2020/055
*
* Avoid the leak by randomizing coordinates before we normalize them.
*/
if (f_rng != 0) {
MBEDTLS_MPI_CHK(ecp_randomize_jac(grp, RR, f_rng, p_rng));
}
MBEDTLS_MPI_CHK(ecp_normalize_jac(grp, RR));
#if defined(MBEDTLS_ECP_RESTARTABLE)
@@ -2594,18 +2580,6 @@ static int ecp_mul_mxz(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
MPI_ECP_COND_SWAP(&R->Z, &RP.Z, b);
}
/*
* Knowledge of the projective coordinates may leak the last few bits of the
* scalar [1], and since our MPI implementation isn't constant-flow,
* inversion (used for coordinate normalization) may leak the full value
* of its input via side-channels [2].
*
* [1] https://eprint.iacr.org/2003/191
* [2] https://eprint.iacr.org/2020/055
*
* Avoid the leak by randomizing coordinates before we normalize them.
*/
MBEDTLS_MPI_CHK(ecp_randomize_mxz(grp, R, f_rng, p_rng));
MBEDTLS_MPI_CHK(ecp_normalize_mxz(grp, R));
cleanup:

View File

@@ -73,6 +73,8 @@
#include "mbedtls/psa_util.h"
#include "mbedtls/threading.h"
#include "constant_time_internal.h"
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND)
@@ -4692,13 +4694,27 @@ psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
output_length);
exit:
if (status == PSA_SUCCESS) {
status = psa_cipher_abort(operation);
} else {
*output_length = 0;
(void) psa_cipher_abort(operation);
/* C99 doesn't allow a declaration to follow a label */;
psa_status_t abort_status = psa_cipher_abort(operation);
/* Normally abort shouldn't fail unless the operation is in a bad
* state, in which case we'd expect finish to fail with the same error.
* So it doesn't matter much which call's error code we pick when both
* fail. However, in unauthenticated decryption specifically, the
* distinction between PSA_SUCCESS and PSA_ERROR_INVALID_PADDING is
* security-sensitive (risk of a padding oracle attack), so here we
* must not have a code path that depends on the value of status. */
if (abort_status != PSA_SUCCESS) {
status = abort_status;
}
/* Set *output_length to 0 if status != PSA_SUCCESS, without
* leaking the value of status through a timing side channel
* (status == PSA_ERROR_INVALID_PADDING is sensitive when doing
* unpadded decryption, due to the risk of padding oracle attack). */
mbedtls_ct_condition_t success =
mbedtls_ct_bool_not(mbedtls_ct_bool(status));
*output_length = mbedtls_ct_size_if_else_0(success, *output_length);
LOCAL_OUTPUT_FREE(output_external, output);
return status;
@@ -4841,13 +4857,17 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key,
exit:
unlock_status = psa_unregister_read_under_mutex(slot);
if (status == PSA_SUCCESS) {
if (unlock_status != PSA_SUCCESS) {
status = unlock_status;
}
if (status != PSA_SUCCESS) {
*output_length = 0;
}
/* Set *output_length to 0 if status != PSA_SUCCESS, without
* leaking the value of status through a timing side channel
* (status == PSA_ERROR_INVALID_PADDING is sensitive when doing
* unpadded decryption, due to the risk of padding oracle attack). */
mbedtls_ct_condition_t success =
mbedtls_ct_bool_not(mbedtls_ct_bool(status));
*output_length = mbedtls_ct_size_if_else_0(success, *output_length);
LOCAL_INPUT_FREE(input_external, input);
LOCAL_OUTPUT_FREE(output_external, output);

View File

@@ -13,6 +13,7 @@
#include "psa_crypto_cipher.h"
#include "psa_crypto_core.h"
#include "psa_crypto_random_impl.h"
#include "constant_time_internal.h"
#include "mbedtls/cipher.h"
#include "mbedtls/error.h"
@@ -551,7 +552,19 @@ psa_status_t mbedtls_psa_cipher_finish(
uint8_t *output, size_t output_size, size_t *output_length)
{
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
size_t invalid_padding = 0;
/* We will copy output_size bytes from temp_output_buffer to the
* output buffer. We can't use *output_length to determine how
* much to copy because we must not leak that value through timing
* when doing decryption with unpadding. But the underlying function
* is not guaranteed to write beyond *output_length. To ensure we don't
* leak the former content of the stack to the caller, wipe that
* former content. */
uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH] = { 0 };
if (output_size > sizeof(temp_output_buffer)) {
output_size = sizeof(temp_output_buffer);
}
if (operation->ctx.cipher.unprocessed_len != 0) {
if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
@@ -562,25 +575,34 @@ psa_status_t mbedtls_psa_cipher_finish(
}
status = mbedtls_to_psa_error(
mbedtls_cipher_finish(&operation->ctx.cipher,
temp_output_buffer,
output_length));
mbedtls_cipher_finish_padded(&operation->ctx.cipher,
temp_output_buffer,
output_length,
&invalid_padding));
if (status != PSA_SUCCESS) {
goto exit;
}
if (*output_length == 0) {
if (output_size == 0) {
; /* Nothing to copy. Note that output may be NULL in this case. */
} else if (output_size >= *output_length) {
memcpy(output, temp_output_buffer, *output_length);
} else {
status = PSA_ERROR_BUFFER_TOO_SMALL;
/* Do not use the value of *output_length to determine how much
* to copy. When decrypting a padded cipher, the output length is
* sensitive, and leaking it could allow a padding oracle attack. */
memcpy(output, temp_output_buffer, output_size);
}
status = mbedtls_ct_error_if_else_0(invalid_padding,
PSA_ERROR_INVALID_PADDING);
mbedtls_ct_condition_t buffer_too_small =
mbedtls_ct_uint_lt(output_size, *output_length);
status = mbedtls_ct_error_if(buffer_too_small,
PSA_ERROR_BUFFER_TOO_SMALL,
status);
exit:
mbedtls_platform_zeroize(temp_output_buffer,
sizeof(temp_output_buffer));
return status;
}
@@ -701,17 +723,21 @@ psa_status_t mbedtls_psa_cipher_decrypt(
&operation,
mbedtls_buffer_offset(output, accumulated_length),
output_size - accumulated_length, &olength);
if (status != PSA_SUCCESS) {
goto exit;
}
*output_length = accumulated_length + olength;
exit:
if (status == PSA_SUCCESS) {
status = mbedtls_psa_cipher_abort(&operation);
} else {
mbedtls_psa_cipher_abort(&operation);
/* C99 doesn't allow a declaration to follow a label */;
psa_status_t abort_status = mbedtls_psa_cipher_abort(&operation);
/* Normally abort shouldn't fail unless the operation is in a bad
* state, in which case we'd expect finish to fail with the same error.
* So it doesn't matter much which call's error code we pick when both
* fail. However, in unauthenticated decryption specifically, the
* distinction between PSA_SUCCESS and PSA_ERROR_INVALID_PADDING is
* security-sensitive (risk of a padding oracle attack), so here we
* must not have a code path that depends on the value of status. */
if (abort_status != PSA_SUCCESS) {
status = abort_status;
}
return status;

View File

@@ -1047,7 +1047,7 @@ int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx,
unsigned int nbits, int exponent)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi H, G, L;
mbedtls_mpi H;
int prime_quality = 0;
/*
@@ -1060,8 +1060,6 @@ int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx,
}
mbedtls_mpi_init(&H);
mbedtls_mpi_init(&G);
mbedtls_mpi_init(&L);
if (exponent < 3 || nbits % 2 != 0) {
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
@@ -1099,35 +1097,28 @@ int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx,
mbedtls_mpi_swap(&ctx->P, &ctx->Q);
}
/* Temporarily replace P,Q by P-1, Q-1 */
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&ctx->P, &ctx->P, 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&ctx->Q, &ctx->Q, 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&H, &ctx->P, &ctx->Q));
/* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, &ctx->E, &H));
if (mbedtls_mpi_cmp_int(&G, 1) != 0) {
/* Compute D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b))
* if it exists (FIPS 186-4 §B.3.1 criterion 2(a)) */
ret = mbedtls_rsa_deduce_private_exponent(&ctx->P, &ctx->Q, &ctx->E, &ctx->D);
if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
mbedtls_mpi_lset(&ctx->D, 0); /* needed for the next call */
continue;
}
if (ret != 0) {
goto cleanup;
}
/* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, &ctx->P, &ctx->Q));
MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&L, NULL, &H, &G));
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&ctx->D, &ctx->E, &L));
if (mbedtls_mpi_bitlen(&ctx->D) <= ((nbits + 1) / 2)) { // (FIPS 186-4 §B.3.1 criterion 3(a))
/* (FIPS 186-4 §B.3.1 criterion 3(a)) */
if (mbedtls_mpi_bitlen(&ctx->D) <= ((nbits + 1) / 2)) {
continue;
}
break;
} while (1);
/* Restore P,Q */
MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&ctx->P, &ctx->P, 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&ctx->Q, &ctx->Q, 1));
/* N = P * Q */
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->N, &ctx->P, &ctx->Q));
ctx->len = mbedtls_mpi_size(&ctx->N);
#if !defined(MBEDTLS_RSA_NO_CRT)
@@ -1146,8 +1137,6 @@ int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx,
cleanup:
mbedtls_mpi_free(&H);
mbedtls_mpi_free(&G);
mbedtls_mpi_free(&L);
if (ret != 0) {
mbedtls_rsa_free(ctx);
@@ -1304,33 +1293,16 @@ static int rsa_prepare_blinding(mbedtls_rsa_context *ctx,
}
/* Unblinding value: Vf = random number, invertible mod N */
mbedtls_mpi_lset(&R, 0);
do {
if (count++ > 10) {
ret = MBEDTLS_ERR_RSA_RNG_FAILED;
goto cleanup;
}
MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->Vf, ctx->len - 1, f_rng, p_rng));
/* Compute Vf^-1 as R * (R Vf)^-1 to avoid leaks from inv_mod. */
MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, ctx->len - 1, f_rng, p_rng));
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vf, &R));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N));
/* At this point, Vi is invertible mod N if and only if both Vf and R
* are invertible mod N. If one of them isn't, we don't need to know
* which one, we just loop and choose new values for both of them.
* (Each iteration succeeds with overwhelming probability.) */
ret = mbedtls_mpi_inv_mod(&ctx->Vi, &ctx->Vi, &ctx->N);
if (ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
goto cleanup;
}
} while (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
/* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &R));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N));
MBEDTLS_MPI_CHK(mbedtls_mpi_random(&ctx->Vf, 1, &ctx->N, f_rng, p_rng));
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&R, &ctx->Vi, &ctx->Vf, &ctx->N));
} while (mbedtls_mpi_cmp_int(&R, 1) != 0);
/* Blinding value: Vi = Vf^(-e) mod N
* (Vi already contains Vf^-1 at this point) */

View File

@@ -12,6 +12,7 @@
#include "mbedtls/rsa.h"
#include "mbedtls/bignum.h"
#include "bignum_internal.h"
#include "rsa_alt_helpers.h"
/*
@@ -117,7 +118,7 @@ int mbedtls_rsa_deduce_primes(mbedtls_mpi const *N,
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&K, primes[attempt]));
/* Check if gcd(K,N) = 1 */
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(P, &K, N));
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(P, NULL, &K, N));
if (mbedtls_mpi_cmp_int(P, 1) != 0) {
continue;
}
@@ -136,7 +137,7 @@ int mbedtls_rsa_deduce_primes(mbedtls_mpi const *N,
}
MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&K, &K, 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(P, &K, N));
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(P, NULL, &K, N));
if (mbedtls_mpi_cmp_int(P, 1) == 1 &&
mbedtls_mpi_cmp_mpi(P, N) == -1) {
@@ -197,6 +198,10 @@ int mbedtls_rsa_deduce_private_exponent(mbedtls_mpi const *P,
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
if (mbedtls_mpi_get_bit(E, 0) != 1) {
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
}
mbedtls_mpi_init(&K);
mbedtls_mpi_init(&L);
@@ -211,8 +216,11 @@ int mbedtls_rsa_deduce_private_exponent(mbedtls_mpi const *P,
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, &K, &L));
MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&K, NULL, &K, D));
/* Compute modular inverse of E in LCM(P-1, Q-1) */
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(D, E, &K));
/* Compute modular inverse of E mod LCM(P-1, Q-1)
* This is FIPS 186-4 §B.3.1 criterion 3(b).
* This will return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if E is not coprime to
* (P-1)(Q-1), also validating FIPS 186-4 §B.3.1 criterion 2(a). */
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod_even_in_range(D, E, &K));
cleanup:
@@ -244,7 +252,7 @@ int mbedtls_rsa_deduce_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q,
/* QP = Q^{-1} mod P */
if (QP != NULL) {
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(QP, Q, P));
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod_odd(QP, Q, P));
}
cleanup:

View File

@@ -89,12 +89,15 @@ int mbedtls_rsa_deduce_primes(mbedtls_mpi const *N, mbedtls_mpi const *E,
* \param P First prime factor of RSA modulus
* \param Q Second prime factor of RSA modulus
* \param E RSA public exponent
* \param D Pointer to MPI holding the private exponent on success.
* \param D Pointer to MPI holding the private exponent on success,
* i.e. the modular inverse of E modulo LCM(P-1,Q-1).
*
* \return
* - 0 if successful. In this case, D is set to a simultaneous
* modular inverse of E modulo both P-1 and Q-1.
* - A non-zero error code otherwise.
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if E is not coprime to P-1
* and Q-1, that is, if GCD( E, (P-1)*(Q-1) ) != 1.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if inputs are otherwise
* invalid.
*
* \note This function does not check whether P and Q are primes.
*

View File

@@ -98,9 +98,6 @@ class CoverageTask(outcome_analysis.CoverageTask):
'Config: MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY',
'Config: MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY',
'Config: MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY',
# We don't run test_suite_config when we test this.
# https://github.com/Mbed-TLS/mbedtls/issues/9586
'Config: MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND',
],
'test_suite_config.psa_boolean': [
# We don't test with HMAC disabled.
@@ -667,6 +664,12 @@ class DriverVSReference_block_cipher_dispatch(outcome_analysis.DriverVSReference
'CMAC null arguments',
re.compile('CMAC.* (AES|ARIA|Camellia).*'),
],
'test_suite_cipher.constant_time': [
# Like with test_suite_cipher.aes and such, these tests call
# cipher_wrapper in a way that requires the block cipher to
# be built in.
re.compile('.*(AES|ARIA|CAMELLIA).*(encrypt|decrypt).*', re.I),
],
'test_suite_cipher.padding': [
# Following tests require AES_C/CAMELLIA_C to be enabled,
# but these are not available in the accelerated component.

View File

@@ -5,6 +5,33 @@
# This file contains test components that are executed by all.sh
## test_with_valgrind tests/suites/SUITE.data [...]
## Run the specified test suite(s) with Valgrind.
test_with_valgrind () {
for data_file in "$@"; do
suite="${data_file##*/}"; suite="${suite%.data}"
exe="tests/$suite"
log_file="tests/MemoryChecker.$suite.log"
make -C tests "$suite"
valgrind -q --tool=memcheck --track-origins=yes --log-file="$log_file" "$exe"
not grep . -- "$log_file"
done
}
## Run a small set of dedicated constant-time tests with Valgrind.
## Exclude very slow suites.
## Exclude suites that contain some constant-time tests, but whose focus
## isn't on constant-time tests.
test_with_valgrind_constant_time () {
# Use a different configuration name in the outcome file if we're doing
# additional valgrind testing on top of non-instrumented testing.
if [[ $MBEDTLS_TEST_CONFIGURATION != *valgrind_cf* ]]; then
declare MBEDTLS_TEST_CONFIGURATION="${MBEDTLS_TEST_CONFIGURATION}+valgrind_cf"
fi
declare GLOBIGNORE="tests/suites/test_suite_constant_time_hmac.data"
test_with_valgrind tests/suites/*constant_time*.data
}
################################################################
#### Configuration Testing - Crypto
################################################################
@@ -31,6 +58,17 @@ component_test_psa_assume_exclusive_buffers () {
make test
}
component_test_psa_assume_exclusive_buffers_valgrind_cf () {
msg "build: full config + MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS, constant flow with Valgrind"
scripts/config.py full
scripts/config.py set MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS
scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
make lib
msg "test: full config + MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS, constant flow with Valgrind, selected suites"
test_with_valgrind_constant_time tests/suites/*constant_time*.data
}
component_test_crypto_with_static_key_slots() {
msg "build: crypto full + MBEDTLS_PSA_STATIC_KEY_SLOTS"
scripts/config.py crypto_full
@@ -1293,7 +1331,8 @@ common_test_psa_crypto_config_accel_ecc_some_curves () {
ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
helper_libtestdriver1_make_drivers "$loc_accel_list" "$loc_extra_list"
helper_libtestdriver1_make_main "$loc_accel_list"
# For grep to work below we need less inlining in ecp.c
ASAN_CFLAGS="$ASAN_CFLAGS -O0" helper_libtestdriver1_make_main "$loc_accel_list"
# We expect ECDH to be re-enabled for the missing curves
grep mbedtls_ecdh_ library/ecdh.o
@@ -2969,11 +3008,15 @@ component_test_aes_only_128_bit_keys () {
msg "build: default config + AES_ONLY_128_BIT_KEY_LENGTH"
scripts/config.py set MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
scripts/config.py unset MBEDTLS_PADLOCK_C
scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
make CFLAGS='-O2 -Werror -Wall -Wextra'
msg "test: default config + AES_ONLY_128_BIT_KEY_LENGTH"
make test
msg "test: default config + AES_ONLY_128_BIT_KEY_LENGTH constant flow with Valgrind, selected suites"
test_with_valgrind_constant_time
}
component_test_no_ctr_drbg_aes_only_128_bit_keys () {

View File

@@ -390,12 +390,24 @@ void mpi_gcd(char *input_X, char *input_Y,
mbedtls_mpi A, X, Y, Z;
mbedtls_mpi_init(&A); mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
TEST_ASSERT(mbedtls_mpi_gcd(&Z, &X, &Y) == 0);
TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&Y, input_Y), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
TEST_EQUAL(mbedtls_mpi_gcd(&Z, &X, &Y), 0);
TEST_ASSERT(sign_is_valid(&Z));
TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &A), 0);
/* Test pointer aliasing where &Z == &X. */
TEST_EQUAL(mbedtls_test_read_mpi(&Z, input_X), 0);
TEST_EQUAL(mbedtls_mpi_gcd(&Z, /* X */ &Z, &Y), 0);
TEST_ASSERT(sign_is_valid(&Z));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &A), 0);
/* Test pointer aliasing where &Z == &Y. */
TEST_EQUAL(mbedtls_test_read_mpi(&Z, input_Y), 0);
TEST_EQUAL(mbedtls_mpi_gcd(&Z, &X, /* Y */ &Z), 0);
TEST_ASSERT(sign_is_valid(&Z));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &A), 0);
exit:
mbedtls_mpi_free(&A); mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
@@ -1134,14 +1146,32 @@ void mpi_inv_mod(char *input_X, char *input_Y,
int res;
mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&Y, input_Y), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
res = mbedtls_mpi_inv_mod(&Z, &X, &Y);
TEST_ASSERT(res == div_result);
TEST_EQUAL(res, div_result);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&Z));
TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &A), 0);
}
/* Test pointer aliasing where &Z == &X. */
TEST_EQUAL(mbedtls_test_read_mpi(&Z, input_X), 0);
res = mbedtls_mpi_inv_mod(&Z, /* X */ &Z, &Y);
TEST_EQUAL(res, div_result);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&Z));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &A), 0);
}
/* Test pointer aliasing where &Z == &Y. */
TEST_EQUAL(mbedtls_test_read_mpi(&Z, input_Y), 0);
res = mbedtls_mpi_inv_mod(&Z, &X, /* Y */ &Z);
TEST_EQUAL(res, div_result);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&Z));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &A), 0);
}
exit:
@@ -1149,6 +1179,219 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE */
void mpi_gcd_modinv_odd_both(char *input_A, char *input_N,
char *result_G, char *result_I,
int return_code)
{
int has_inverse = strcmp(result_I, "no_inverse") ? 1 : 0;
mbedtls_mpi G, I, A, N, exp_G, exp_I;
int res;
mbedtls_mpi_init(&G); mbedtls_mpi_init(&I); mbedtls_mpi_init(&A); mbedtls_mpi_init(&N);
mbedtls_mpi_init(&exp_G); mbedtls_mpi_init(&exp_I);
TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&exp_G, result_G), 0);
/* If there is no inverse then the value returned in I will be
* indeterminate, and so not useful or possible to test. */
if (has_inverse) {
TEST_EQUAL(mbedtls_test_read_mpi(&exp_I, result_I), 0);
}
res = mbedtls_mpi_gcd_modinv_odd(&G, &I, &A, &N);
TEST_EQUAL(res, return_code);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&G));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&G, &exp_G), 0);
if (has_inverse) {
TEST_ASSERT(sign_is_valid(&I));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&I, &exp_I), 0);
}
}
/* Test pointer aliasing where &G == &A. */
TEST_EQUAL(mbedtls_test_read_mpi(&G, input_A), 0);
res = mbedtls_mpi_gcd_modinv_odd(&G, &I, /* A */ &G, &N);
TEST_EQUAL(res, return_code);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&G));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&G, &exp_G), 0);
if (has_inverse) {
TEST_ASSERT(sign_is_valid(&I));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&I, &exp_I), 0);
}
}
/* Test pointer aliasing where &G == &N. This should fail. */
TEST_EQUAL(mbedtls_test_read_mpi(&G, input_N), 0);
res = mbedtls_mpi_gcd_modinv_odd(&G, &I, &A, /* N */ &G);
TEST_EQUAL(res, MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
/* Test pointer aliasing where &I == &A. */
TEST_EQUAL(mbedtls_test_read_mpi(&I, input_A), 0);
res = mbedtls_mpi_gcd_modinv_odd(&G, &I, /* A */ &I, &N);
TEST_EQUAL(res, return_code);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&G));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&G, &exp_G), 0);
if (has_inverse) {
TEST_ASSERT(sign_is_valid(&I));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&I, &exp_I), 0);
}
}
/* Test pointer aliasing where &I == &N. This should fail. */
TEST_EQUAL(mbedtls_test_read_mpi(&I, input_N), 0);
res = mbedtls_mpi_gcd_modinv_odd(&G, &I, &A, /* N */ &I);
TEST_EQUAL(res, MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
/* Test pointer aliasing where &A == &N. This should fail. */
res = mbedtls_mpi_gcd_modinv_odd(&G, &I, &A, /* N */ &A);
TEST_EQUAL(res, MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
/* Test G & I initialized to a number with more limbs than N. */
if (N.n > 0) {
TEST_EQUAL(mbedtls_mpi_grow(&G, N.n * 2), 0);
memset(G.p, 0x2d, G.n * sizeof(mbedtls_mpi_uint));
TEST_EQUAL(mbedtls_mpi_grow(&I, N.n * 2), 0);
memset(I.p, 0x2f, I.n * sizeof(mbedtls_mpi_uint));
res = mbedtls_mpi_gcd_modinv_odd(&G, &I, &A, &N);
TEST_EQUAL(res, return_code);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&G));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&G, &exp_G), 0);
if (has_inverse) {
TEST_ASSERT(sign_is_valid(&I));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&I, &exp_I), 0);
}
}
}
exit:
mbedtls_mpi_free(&G); mbedtls_mpi_free(&I); mbedtls_mpi_free(&A); mbedtls_mpi_free(&N);
mbedtls_mpi_free(&exp_G); mbedtls_mpi_free(&exp_I);
}
/* END_CASE */
/* BEGIN_CASE */
void mpi_gcd_modinv_odd_only_gcd(char *input_A, char *input_N,
char *result_G, int return_code)
{
mbedtls_mpi G, A, N, exp_G;
int res;
mbedtls_mpi_init(&G); mbedtls_mpi_init(&A); mbedtls_mpi_init(&N);
mbedtls_mpi_init(&exp_G);
TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&exp_G, result_G), 0);
res = mbedtls_mpi_gcd_modinv_odd(&G, NULL, &A, &N);
TEST_EQUAL(res, return_code);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&G));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&G, &exp_G), 0);
}
/* Test pointer aliasing where &G == &A. */
TEST_EQUAL(mbedtls_test_read_mpi(&G, input_A), 0);
res = mbedtls_mpi_gcd_modinv_odd(&G, NULL, /* A */ &G, &N);
TEST_EQUAL(res, return_code);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&G));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&G, &exp_G), 0);
}
/* Test pointer aliasing where &G == &N. */
TEST_EQUAL(mbedtls_test_read_mpi(&G, input_N), 0);
res = mbedtls_mpi_gcd_modinv_odd(&G, NULL, &A, /* N */ &G);
TEST_EQUAL(res, return_code);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&G));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&G, &exp_G), 0);
}
/* Test pointer aliasing where &A == &N. This should fail. */
res = mbedtls_mpi_gcd_modinv_odd(&G, NULL, &A, /* N */ &A);
TEST_EQUAL(res, MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
/* Test G initialized to a number with more limbs than N. */
if (N.n > 0) {
TEST_EQUAL(mbedtls_mpi_grow(&G, N.n * 2), 0);
memset(G.p, 0x2b, G.n * sizeof(mbedtls_mpi_uint));
res = mbedtls_mpi_gcd_modinv_odd(&G, NULL, &A, &N);
TEST_EQUAL(res, return_code);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&G));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&G, &exp_G), 0);
}
}
exit:
mbedtls_mpi_free(&G); mbedtls_mpi_free(&A); mbedtls_mpi_free(&N);
mbedtls_mpi_free(&exp_G);
}
/* END_CASE */
/* BEGIN_CASE */
void mpi_gcd_modinv_odd_only_modinv(char *input_A, char *input_N,
char *result_I, int return_code)
{
int has_inverse = strcmp(result_I, "no_inverse") ? 1 : 0;
mbedtls_mpi I, A, N, exp_I;
int res;
mbedtls_mpi_init(&I); mbedtls_mpi_init(&A); mbedtls_mpi_init(&N);
mbedtls_mpi_init(&exp_I);
TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
/* If there is no inverse then the value returned in I will be
* indeterminate, and so not useful or possible to test. */
if (has_inverse) {
TEST_EQUAL(mbedtls_test_read_mpi(&exp_I, result_I), 0);
}
res = mbedtls_mpi_gcd_modinv_odd(NULL, &I, &A, &N);
TEST_EQUAL(res, return_code);
if (res == 0 && has_inverse) {
TEST_ASSERT(sign_is_valid(&I));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&I, &exp_I), 0);
}
/* Test pointer aliasing where &I == &A. */
TEST_EQUAL(mbedtls_test_read_mpi(&I, input_A), 0);
res = mbedtls_mpi_gcd_modinv_odd(NULL, &I, /* A */ &I, &N);
TEST_EQUAL(res, return_code);
if (res == 0 && has_inverse) {
TEST_ASSERT(sign_is_valid(&I));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&I, &exp_I), 0);
}
/* Test pointer aliasing where &I == &N. This should fail. */
TEST_EQUAL(mbedtls_test_read_mpi(&I, input_N), 0);
res = mbedtls_mpi_gcd_modinv_odd(NULL, &I, &A, /* N */ &I);
TEST_EQUAL(res, MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
/* Test pointer aliasing where &A == &N. This should fail. */
res = mbedtls_mpi_gcd_modinv_odd(NULL, &I, &A, /* N */ &A);
TEST_EQUAL(res, MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
/* Test I initialized to a number with more limbs than N. */
if (N.n > 0) {
TEST_EQUAL(mbedtls_mpi_grow(&I, N.n * 2), 0);
memset(I.p, 0x29, I.n * sizeof(mbedtls_mpi_uint));
res = mbedtls_mpi_gcd_modinv_odd(NULL, &I, &A, &N);
TEST_EQUAL(res, return_code);
if (res == 0 && has_inverse) {
TEST_ASSERT(sign_is_valid(&I));
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&I, &exp_I), 0);
}
}
exit:
mbedtls_mpi_free(&I); mbedtls_mpi_free(&A); mbedtls_mpi_free(&N);
mbedtls_mpi_free(&exp_I);
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
void mpi_is_prime(char *input_X, int div_result)
{

View File

@@ -1435,6 +1435,9 @@ mpi_gcd:"":"":"0"
Test GCD: 0 (null), 0 (1 limb)
mpi_gcd:"":"00":"0"
Test GCD: 0 (1 limb), 0 (1 limb)
mpi_gcd:"00":"00":"0"
Test GCD: 0 (null), 3
mpi_gcd:"":"03":"3"
@@ -1462,66 +1465,195 @@ mpi_gcd:"06":"":"6"
Test GCD: 6, 0 (1 limb)
mpi_gcd:"06":"00":"6"
Test GCD: gcd=1, 0 < A < B
Test GCD: negative, 0 (null)
mpi_gcd:"-50000":"":"50000"
Test GCD: negative, 0 (1 limb)
mpi_gcd:"-a782374b2ee927df28802745833a":"00":"a782374b2ee927df28802745833a"
Test GCD: 0 (null), negative
mpi_gcd:"":"-50000":"50000"
Test GCD: 0 (1 limb), negative
mpi_gcd:"00":"-a782374b2ee927df28802745833a":"a782374b2ee927df28802745833a"
Test GCD: gcd=1, A is odd, B is odd, 0 < A < B
mpi_gcd:"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"33ae3764fd06a00cdc3cba5c45dc79a9edb4e67e4d057cc74139d531c25190d111775fc4a0f4439b8b1930bbd766e7b46f170601f316c8a18ff8d5cb5ca5581f168345d101edb462b7d93b7c520ccb8fb276b447a63d869203cc11f67a1122dc4da034218de85e39":"1"
Test GCD: gcd=1, 0 < B < A
Test GCD: gcd=1, A is odd, B is odd, 0 < B < A
mpi_gcd:"33ae3764fd06a00cdc3cba5c45dc79a9edb4e67e4d057cc74139d531c25190d111775fc4a0f4439b8b1930bbd766e7b46f170601f316c8a18ff8d5cb5ca5581f168345d101edb462b7d93b7c520ccb8fb276b447a63d869203cc11f67a1122dc4da034218de85e39":"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"1"
Test GCD: gcd=1, A > 0, B < 0
Test GCD: gcd=1, A is odd, B is odd, A > 0, B < 0
mpi_gcd:"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"-33ae3764fd06a00cdc3cba5c45dc79a9edb4e67e4d057cc74139d531c25190d111775fc4a0f4439b8b1930bbd766e7b46f170601f316c8a18ff8d5cb5ca5581f168345d101edb462b7d93b7c520ccb8fb276b447a63d869203cc11f67a1122dc4da034218de85e39":"1"
Test GCD: gcd=1, A < 0 < B, |A| < |B|
Test GCD: gcd=1, A is odd, B is odd, A < 0 < B, |A| < |B|
mpi_gcd:"-109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"33ae3764fd06a00cdc3cba5c45dc79a9edb4e67e4d057cc74139d531c25190d111775fc4a0f4439b8b1930bbd766e7b46f170601f316c8a18ff8d5cb5ca5581f168345d101edb462b7d93b7c520ccb8fb276b447a63d869203cc11f67a1122dc4da034218de85e39":"1"
Test GCD: gcd=1, B < A < 0
Test GCD: gcd=1, A is odd, B is odd, B < A < 0
mpi_gcd:"-109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"-33ae3764fd06a00cdc3cba5c45dc79a9edb4e67e4d057cc74139d531c25190d111775fc4a0f4439b8b1930bbd766e7b46f170601f316c8a18ff8d5cb5ca5581f168345d101edb462b7d93b7c520ccb8fb276b447a63d869203cc11f67a1122dc4da034218de85e39":"1"
Test GCD: gcd=2, 0 < A < B
Test GCD: gcd=2, A is even, B is even, 0 < A < B
mpi_gcd:"213fc8ae290cdcadfba95b36d6d0dbe4e4495f6f0d19e9e1976f28a4d2650a797e17dd4c2b282ccca9a279b3fc1b3b4b2952fdc40461e25f6a869bce7f69f0204e4b402c4566363d485c744ca032073583be630d37b2f261af25f6e59b552e3b15002b5e":"675c6ec9fa0d4019b87974b88bb8f353db69ccfc9a0af98e8273aa6384a321a222eebf8941e8873716326177aecdcf68de2e0c03e62d91431ff1ab96b94ab03e2d068ba203db68c56fb276f8a419971f64ed688f4c7b0d24079823ecf42245b89b4068431bd0bc72":"2"
Test GCD: gcd=2, 0 < B < A
Test GCD: gcd=2, A is even, B is even, 0 < B < A
mpi_gcd:"675c6ec9fa0d4019b87974b88bb8f353db69ccfc9a0af98e8273aa6384a321a222eebf8941e8873716326177aecdcf68de2e0c03e62d91431ff1ab96b94ab03e2d068ba203db68c56fb276f8a419971f64ed688f4c7b0d24079823ecf42245b89b4068431bd0bc72":"213fc8ae290cdcadfba95b36d6d0dbe4e4495f6f0d19e9e1976f28a4d2650a797e17dd4c2b282ccca9a279b3fc1b3b4b2952fdc40461e25f6a869bce7f69f0204e4b402c4566363d485c744ca032073583be630d37b2f261af25f6e59b552e3b15002b5e":"2"
Test GCD: gcd=3, 0 < A < B
Test GCD: gcd=3, A is odd, B is odd, 0 < A < B
mpi_gcd:"31dfad053d934b04f97e08d2423949d7566e0f2693a6ded26326bcf73b978fb63d23cbf240bc4332fe73b68dfa28d8f0bdfc7ca60692d38f1fc9e9b5bf1ee8307570e0426819515bec8aae72f04b0ad0459d9493d38c6b9286b8f25868ffc5589f80410d":"9b0aa62ef713e02694b62f14d1956cfdc91eb37ae7107655c3ad7f9546f4b27334661f4de2dccad2a14b92338634b71d4d451205d94459e4afea816215f0085d4389d17305c91d28278bb274f62662af17641cd6f2b893b60b6435e36e336894e8e09c64a9b91aab":"3"
Test GCD: gcd=3, 0 < B < A
Test GCD: gcd=3, A is odd, B is odd, 0 < B < A
mpi_gcd:"9b0aa62ef713e02694b62f14d1956cfdc91eb37ae7107655c3ad7f9546f4b27334661f4de2dccad2a14b92338634b71d4d451205d94459e4afea816215f0085d4389d17305c91d28278bb274f62662af17641cd6f2b893b60b6435e36e336894e8e09c64a9b91aab":"31dfad053d934b04f97e08d2423949d7566e0f2693a6ded26326bcf73b978fb63d23cbf240bc4332fe73b68dfa28d8f0bdfc7ca60692d38f1fc9e9b5bf1ee8307570e0426819515bec8aae72f04b0ad0459d9493d38c6b9286b8f25868ffc5589f80410d":"3"
Test GCD: gcd=4, 0 < A < B
Test GCD: gcd=4, A is even, B is even, 0 < A < B
mpi_gcd:"427f915c5219b95bf752b66dada1b7c9c892bede1a33d3c32ede5149a4ca14f2fc2fba98565059995344f367f836769652a5fb8808c3c4bed50d379cfed3e0409c9680588acc6c7a90b8e89940640e6b077cc61a6f65e4c35e4bedcb36aa5c762a0056bc":"ceb8dd93f41a803370f2e9711771e6a7b6d399f93415f31d04e754c70946434445dd7f1283d10e6e2c64c2ef5d9b9ed1bc5c1807cc5b22863fe3572d7295607c5a0d174407b6d18adf64edf148332e3ec9dad11e98f61a480f3047d9e8448b713680d08637a178e4":"4"
Test GCD: gcd=4, 0 < B < A
Test GCD: gcd=4, A is even, B is even, 0 < B < A
mpi_gcd:"ceb8dd93f41a803370f2e9711771e6a7b6d399f93415f31d04e754c70946434445dd7f1283d10e6e2c64c2ef5d9b9ed1bc5c1807cc5b22863fe3572d7295607c5a0d174407b6d18adf64edf148332e3ec9dad11e98f61a480f3047d9e8448b713680d08637a178e4":"427f915c5219b95bf752b66dada1b7c9c892bede1a33d3c32ede5149a4ca14f2fc2fba98565059995344f367f836769652a5fb8808c3c4bed50d379cfed3e0409c9680588acc6c7a90b8e89940640e6b077cc61a6f65e4c35e4bedcb36aa5c762a0056bc":"4"
Test GCD: gcd=6, 0 < A < B
Test GCD: gcd=6, A is even, B is even, 0 < A < B
mpi_gcd:"63bf5a0a7b269609f2fc11a4847293aeacdc1e4d274dbda4c64d79ee772f1f6c7a4797e481788665fce76d1bf451b1e17bf8f94c0d25a71e3f93d36b7e3dd060eae1c084d032a2b7d9155ce5e09615a08b3b2927a718d7250d71e4b0d1ff8ab13f00821a":"136154c5dee27c04d296c5e29a32ad9fb923d66f5ce20ecab875aff2a8de964e668cc3e9bc5b995a5429724670c696e3a9a8a240bb288b3c95fd502c42be010ba8713a2e60b923a504f1764e9ec4cc55e2ec839ade571276c16c86bc6dc66d129d1c138c953723556":"6"
Test GCD: gcd=6, 0 < B < A
Test GCD: gcd=6, A is even, B is even, 0 < B < A
mpi_gcd:"136154c5dee27c04d296c5e29a32ad9fb923d66f5ce20ecab875aff2a8de964e668cc3e9bc5b995a5429724670c696e3a9a8a240bb288b3c95fd502c42be010ba8713a2e60b923a504f1764e9ec4cc55e2ec839ade571276c16c86bc6dc66d129d1c138c953723556":"63bf5a0a7b269609f2fc11a4847293aeacdc1e4d274dbda4c64d79ee772f1f6c7a4797e481788665fce76d1bf451b1e17bf8f94c0d25a71e3f93d36b7e3dd060eae1c084d032a2b7d9155ce5e09615a08b3b2927a718d7250d71e4b0d1ff8ab13f00821a":"6"
Test GCD: 0 < A = B
Test GCD: A is odd, B is odd, 0 < A = B
mpi_gcd:"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af"
Test GCD: A is odd, B is odd, A = B < 0
mpi_gcd:"-9986dabb54d13cd9fe0d9da594a97e8372ab26ed98ff622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"-9986dabb54d13cd9fe0d9da594a97e8372ab26ed98ff622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"9986dabb54d13cd9fe0d9da594a97e8372ab26ed98ff622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af"
Base test mbedtls_mpi_inv_mod #1
mpi_inv_mod:"3":"b":"4":0
Base test mbedtls_mpi_inv_mod: 0 mod 3
mpi_inv_mod:"0":"3":"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Base test mbedtls_mpi_inv_mod: 1 mod 3
mpi_inv_mod:"1":"3":"1":0
Base test mbedtls_mpi_inv_mod: 2 mod 3
mpi_inv_mod:"2":"3":"2":0
Base test mbedtls_mpi_inv_mod: 3 mod 3
mpi_inv_mod:"0":"3":"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Base test mbedtls_mpi_inv_mod: 4 mod 3
mpi_inv_mod:"4":"3":"1":0
Base test mbedtls_mpi_inv_mod: 5 mod 3
mpi_inv_mod:"5":"3":"2":0
Base test mbedtls_mpi_inv_mod: -1 mod 3
mpi_inv_mod:"-1":"3":"2":0
Base test mbedtls_mpi_inv_mod: -2 mod 3
mpi_inv_mod:"-2":"3":"1":0
Base test mbedtls_mpi_inv_mod: -3 mod 3
mpi_inv_mod:"-3":"3":"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Base test mbedtls_mpi_inv_mod: -4 mod 3
mpi_inv_mod:"-4":"3":"2":0
Base test mbedtls_mpi_inv_mod: 0 mod 4
mpi_inv_mod:"0":"4":"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Base test mbedtls_mpi_inv_mod: 1 mod 4
mpi_inv_mod:"1":"4":"1":0
Base test mbedtls_mpi_inv_mod: 2 mod 4
mpi_inv_mod:"2":"4":"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Base test mbedtls_mpi_inv_mod: 3 mod 4
mpi_inv_mod:"3":"4":"3":0
Base test mbedtls_mpi_inv_mod: 4 mod 4
mpi_inv_mod:"4":"4":"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Base test mbedtls_mpi_inv_mod: 5 mod 4
mpi_inv_mod:"5":"4":"1":0
Base test mbedtls_mpi_inv_mod: 6 mod 4
mpi_inv_mod:"6":"4":"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Base test mbedtls_mpi_inv_mod: 7 mod 4
mpi_inv_mod:"7":"4":"3":0
Base test mbedtls_mpi_inv_mod: -1 mod 4
mpi_inv_mod:"-1":"4":"3":0
Base test mbedtls_mpi_inv_mod: -2 mod 4
mpi_inv_mod:"-2":"4":"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Base test mbedtls_mpi_inv_mod: -3 mod 4
mpi_inv_mod:"-3":"4":"1":0
Base test mbedtls_mpi_inv_mod: -4 mod 4
mpi_inv_mod:"-4":"4":"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Base test mbedtls_mpi_inv_mod: -5 mod 4
mpi_inv_mod:"-5":"4":"3":0
Test mbedtls_mpi_inv_mod: mod 0 (null)
mpi_inv_mod:"3":"":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: mod 0 (1 limb)
mpi_inv_mod:"3":"0":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: 0 (null) mod positive
mpi_inv_mod:"":"25":"0":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Test mbedtls_mpi_inv_mod: 0 (1 limb) mod positive
mpi_inv_mod:"00":"25":"0":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Test mbedtls_mpi_inv_mod: 0 (null) mod 0 (null)
mpi_inv_mod:"":"":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: 0 (1 limb) mod 0 (1 limb)
mpi_inv_mod:"00":"00":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: 0 (null) mod 0 (1 limb)
mpi_inv_mod:"":"00":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: 0 (1 limb) mod 0 (null)
mpi_inv_mod:"00":"":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: mod negative
mpi_inv_mod:"3":"-b":"4":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: negative mod negative
mpi_inv_mod:"-3543a":"-f":"5":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: 1 mod negative
mpi_inv_mod:"1":"-f":"1":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: 0 (null) mod negative
mpi_inv_mod:"":"-f":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: 0 (1 limb) mod negative
mpi_inv_mod:"00":"-f":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: 2^-1 mod 4
mpi_inv_mod:"2":"4":"0":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Test mbedtls_mpi_inv_mod: mod 1
mpi_inv_mod:"3":"1":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: negative mod 1
mpi_inv_mod:"-732487665ae082f75c44":"1":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: 1 mod 1
mpi_inv_mod:"1":"1":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: larger positive mod 1
mpi_inv_mod:"aaf97513ce987d99d9d934e":"1":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: 0 (null) mod 1
mpi_inv_mod:"":"1":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: 0 (1 limb) mod 1
mpi_inv_mod:"00":"1":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Test mbedtls_mpi_inv_mod: 0 (null) ^-1
mpi_inv_mod:"":"11":"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
@@ -1531,6 +1663,60 @@ mpi_inv_mod:"00":"11":"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
Test mbedtls_mpi_inv_mod #1
mpi_inv_mod:"aa4df5cb14b4c31237f98bd1faf527c283c2d0f3eec89718664ba33f9762907c":"fffbbd660b94412ae61ead9c2906a344116e316a256fd387874c6c675b1d587d":"8d6a5c1d7adeae3e94b9bcd2c47e0d46e778bc8804a2cc25c02d775dc3d05b0c":0
GCD-modinv wrapper: working, A < N
mpi_gcd_modinv_odd_both:"54a":"3999":"1":"30b5":0
GCD-modinv wrapper: no mod inverse, A = N
mpi_gcd_modinv_odd_both:"365":"365":"365":"no_inverse":0
GCD-modinv wrapper: no mod inverse, A < N
mpi_gcd_modinv_odd_both:"5a":"b9":"5":"no_inverse":0
GCD-modinv wrapper: bad inputs, A > N
mpi_gcd_modinv_odd_both:"3999":"54a":"":"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
GCD-modinv wrapper: bad inputs, A < 0
mpi_gcd_modinv_odd_both:"-5":"54a":"":"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
GCD-modinv wrapper: bad inputs, N even
mpi_gcd_modinv_odd_both:"89":"540":"":"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
GCD-modinv wrapper only gcd: working, A < N
mpi_gcd_modinv_odd_only_gcd:"1de3":"31d9":"7":0
GCD-modinv wrapper only gcd: working, A = N
mpi_gcd_modinv_odd_only_gcd:"365":"365":"365":0
GCD-modinv wrapper only gcd: working, no mod inverse, A < N
mpi_gcd_modinv_odd_only_gcd:"19e":"a47f":"9":0
GCD-modinv wrapper only gcd: bad inputs, A > N
mpi_gcd_modinv_odd_only_gcd:"319d":"1de3":"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
GCD-modinv wrapper only gcd: bad inputs, A < 0
mpi_gcd_modinv_odd_only_gcd:"-628ef":"991827f":"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
GCD-modinv wrapper only gcd: bad inputs, N even
mpi_gcd_modinv_odd_only_gcd:"319d":"24":"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
GCD-modinv wrapper only modinv: working, A < N
mpi_gcd_modinv_odd_only_modinv:"28c":"26f9":"84f":0
GCD-modinv wrapper only modinv: no mod inverse, A = N
mpi_gcd_modinv_odd_only_modinv:"365":"365":"no_inverse":0
GCD-modinv wrapper only modinv: no mod inverse, A < N
mpi_gcd_modinv_odd_only_modinv:"19e":"a47f":"no_inverse":0
GCD-modinv wrapper only modinv: bad inputs, A > N
mpi_gcd_modinv_odd_only_modinv:"26f9":"28c":"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
GCD-modinv wrapper only modinv: bad inputs, A < 0
mpi_gcd_modinv_odd_only_modinv:"-992f":"1000002":"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
GCD-modinv wrapper only modinv: bad inputs, N even
mpi_gcd_modinv_odd_only_modinv:"28c":"26f0":"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Base test mbedtls_mpi_is_prime #1
depends_on:MBEDTLS_GENPRIME
mpi_is_prime:"0":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE

View File

@@ -2,6 +2,7 @@
#include "mbedtls/bignum.h"
#include "mbedtls/entropy.h"
#include "bignum_core.h"
#include "bignum_core_invasive.h"
#include "constant_time_internal.h"
#include "test/constant_flow.h"
#include "test/bignum_codepath_check.h"
@@ -148,6 +149,29 @@ exit:
return ret;
}
/*
* Return -1 if A < B, +1 if A > B and 0 if A == B
*/
static int mpi_core_cmp(const mbedtls_mpi_uint *A, size_t A_limbs,
const mbedtls_mpi_uint *B, size_t B_limbs)
{
TEST_CF_PUBLIC(A, A_limbs * sizeof(mbedtls_mpi_uint));
TEST_CF_PUBLIC(B, B_limbs * sizeof(mbedtls_mpi_uint));
const mbedtls_mpi AA = {
.p = (mbedtls_mpi_uint *) A,
.s = 1,
.n = (unsigned short) A_limbs,
};
const mbedtls_mpi BB = {
.p = (mbedtls_mpi_uint *) B,
.s = 1,
.n = (unsigned short) B_limbs,
};
return mbedtls_mpi_cmp_mpi(&AA, &BB);
}
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -1356,3 +1380,285 @@ exit:
mbedtls_free(X);
}
/* END_CASE */
/* BEGIN_CASE */
void mpi_core_gcd_modinv_odd(char *input_A, char *input_N,
char *input_exp_G, char *input_exp_I)
{
mbedtls_mpi_uint *A = NULL;
size_t A_limbs = 0;
mbedtls_mpi_uint *N = NULL;
size_t N_limbs = 0;
mbedtls_mpi_uint *exp_G = NULL;
size_t exp_G_limbs = 0;
mbedtls_mpi_uint *exp_I = NULL;
size_t exp_I_limbs = 0;
mbedtls_mpi_uint *G = NULL, *I = NULL, *T = NULL;
/* Read test parameters into MPI structures */
TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &A_limbs, input_A));
TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &N_limbs, input_N));
TEST_EQUAL(0, mbedtls_test_read_mpi_core(&exp_G, &exp_G_limbs, input_exp_G));
const unsigned char got_I = strlen(input_exp_I) != 0;
if (got_I) {
TEST_EQUAL(0, mbedtls_test_read_mpi_core(&exp_I, &exp_I_limbs, input_exp_I));
}
/* The function under test wants this */
TEST_EQUAL(N[0] & 1, 1);
TEST_LE_U(A_limbs, N_limbs);
TEST_ASSERT(mpi_core_cmp(A, A_limbs, N, N_limbs) <= 0);
const size_t N_bytes = N_limbs * sizeof(mbedtls_mpi_uint);
TEST_CF_SECRET(A, A_limbs * sizeof(mbedtls_mpi_uint));
TEST_CF_SECRET(N, N_limbs * sizeof(mbedtls_mpi_uint));
#define FREE_G_I_T \
mbedtls_free(G); \
G = NULL; \
mbedtls_free(I); \
I = NULL; \
mbedtls_free(T); \
T = NULL
/*
* Test GCD only (I == NULL)
*/
TEST_CALLOC(G, N_limbs);
memset(G, 'G', N_bytes);
TEST_CALLOC(T, 4 * N_limbs);
memset(T, 'T', 4 * N_bytes);
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, A, A_limbs, N, N_limbs, T);
TEST_EQUAL(mpi_core_cmp(G, N_limbs, exp_G, exp_G_limbs), 0);
FREE_G_I_T;
/* GCD only, G aliased to N */
TEST_CALLOC(G, N_limbs);
memcpy(G, N, N_bytes);
TEST_CALLOC(T, 4 * N_limbs);
memset(T, 'T', 4 * N_bytes);
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, A, A_limbs, /* N */ G, N_limbs, T);
TEST_EQUAL(mpi_core_cmp(G, N_limbs, exp_G, exp_G_limbs), 0);
FREE_G_I_T;
/* GCD only, G aliased to A (hence A_limbs = N_limbs) */
TEST_CALLOC(G, N_limbs);
memcpy(G, A, A_limbs * sizeof(mbedtls_mpi_uint));
TEST_CALLOC(T, 4 * N_limbs);
memset(T, 'T', 4 * N_bytes);
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, /* A */ G, N_limbs, N, N_limbs, T);
TEST_EQUAL(mpi_core_cmp(G, N_limbs, exp_G, exp_G_limbs), 0);
FREE_G_I_T;
/*
* Test GCD + modinv
*/
TEST_CALLOC(G, N_limbs);
memset(G, 'G', N_bytes);
TEST_CALLOC(I, N_limbs);
memset(I, 'I', N_bytes);
TEST_CALLOC(T, 5 * N_limbs);
memset(T, 'T', 5 * N_bytes);
mbedtls_mpi_core_gcd_modinv_odd(G, I, A, A_limbs, N, N_limbs, T);
TEST_EQUAL(mpi_core_cmp(G, N_limbs, exp_G, exp_G_limbs), 0);
if (got_I) {
TEST_EQUAL(mpi_core_cmp(I, N_limbs, exp_I, exp_I_limbs), 0);
}
FREE_G_I_T;
/* GCD + modinv, G aliased to A */
TEST_CALLOC(G, N_limbs);
memcpy(G, A, A_limbs * sizeof(mbedtls_mpi_uint));
TEST_CALLOC(I, N_limbs);
memset(I, 'I', N_bytes);
TEST_CALLOC(T, 5 * N_limbs);
memset(T, 'T', 5 * N_bytes);
mbedtls_mpi_core_gcd_modinv_odd(G, I, /* A */ G, N_limbs, N, N_limbs, T);
TEST_EQUAL(mpi_core_cmp(G, N_limbs, exp_G, exp_G_limbs), 0);
if (got_I) {
TEST_EQUAL(mpi_core_cmp(I, N_limbs, exp_I, exp_I_limbs), 0);
}
FREE_G_I_T;
/* GCD + modinv, I aliased to A */
TEST_CALLOC(G, N_limbs);
memset(G, 'G', N_bytes);
TEST_CALLOC(I, N_limbs);
memcpy(I, A, A_limbs * sizeof(mbedtls_mpi_uint));
TEST_CALLOC(T, 5 * N_limbs);
memset(T, 'T', 5 * N_bytes);
mbedtls_mpi_core_gcd_modinv_odd(G, I, /* A */ I, N_limbs, N, N_limbs, T);
TEST_EQUAL(mpi_core_cmp(G, N_limbs, exp_G, exp_G_limbs), 0);
if (got_I) {
TEST_EQUAL(mpi_core_cmp(I, N_limbs, exp_I, exp_I_limbs), 0);
}
FREE_G_I_T;
#undef FREE_G_I_T
exit:
mbedtls_free(A);
mbedtls_free(N);
mbedtls_free(exp_G);
mbedtls_free(exp_I);
mbedtls_free(G);
mbedtls_free(I);
mbedtls_free(T);
}
/* END_CASE */
/* BEGIN_CASE */
void mpi_core_gcd_modinv_odd_preconditions()
{
/*
* The purpose of this test function is to ensure that the function doesn't
* crash (but just outputs garbage) when preconditions are not met.
*/
mbedtls_mpi_uint A[1];
mbedtls_mpi_uint N[2];
mbedtls_mpi_uint AAA[3];
mbedtls_mpi_uint *G = NULL, *I = NULL, *TG = NULL, *TI = NULL;
/* We'll always use a two-limbs N */
TEST_CALLOC(G, 2);
TEST_CALLOC(I, 2);
TEST_CALLOC(TG, 4 * 2); // For I == NULL
TEST_CALLOC(TI, 5 * 2); // For I != NULL
/*
* Input values
*/
/* N is not odd */
N[0] = 2; // N = 2^n + 2
N[1] = 1;
A[0] = 42; // A = 42
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, A, 1, N, 2, TG);
mbedtls_mpi_core_gcd_modinv_odd(G, I, A, 1, N, 2, TI);
/* A > N */
N[0] = 3; // N = 3
N[1] = 0;
A[0] = 42; // A = 42
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, A, 1, N, 2, TG);
mbedtls_mpi_core_gcd_modinv_odd(G, I, A, 1, N, 2, TI);
/* A_limbs > N_limbs (but A <= N) */
N[0] = 3; // N = 3
N[1] = 0;
AAA[0] = 1; // A = 1
AAA[1] = 0;
AAA[2] = 0;
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, AAA, 3, N, 2, TG);
mbedtls_mpi_core_gcd_modinv_odd(G, I, AAA, 3, N, 2, TI);
/* A_limbs > N_limbs (and A > N) */
N[0] = 3; // N = 3
N[1] = 0;
AAA[0] = 0; // A = 2^2n
AAA[1] = 0;
AAA[2] = 1;
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, AAA, 3, N, 2, TG);
mbedtls_mpi_core_gcd_modinv_odd(G, I, AAA, 3, N, 2, TI);
/* I != NULL but N is 1 */
N[0] = 1; // N = 1
N[1] = 0;
A[0] = 1; // A = 1
mbedtls_mpi_core_gcd_modinv_odd(G, I, N, 2, A, 1, TI);
/*
* Aliasing
*/
/* Now use valid values for remaining tests */
N[0] = 1; // N = 2^n + 1
N[1] = 1;
A[0] = 42; // A = 42
/* A aliased to N */
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, N, 2, N, 2, TG);
mbedtls_mpi_core_gcd_modinv_odd(G, I, N, 2, N, 2, TI);
/* G aliased to A and N */
memcpy(G, N, 2 * sizeof(mbedtls_mpi_uint));
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, G, 2, G, 2, TG);
mbedtls_mpi_core_gcd_modinv_odd(G, I, G, 2, G, 2, TI);
/* I != NULL, G aliased to N */
memcpy(G, N, 2 * sizeof(mbedtls_mpi_uint));
mbedtls_mpi_core_gcd_modinv_odd(G, I, A, 1, G, 2, TI);
/* I != NULL, I aliased to N */
memcpy(I, N, 2 * sizeof(mbedtls_mpi_uint));
mbedtls_mpi_core_gcd_modinv_odd(G, I, A, 1, I, 2, TI);
/* I aliased to A and N */
memcpy(I, N, 2 * sizeof(mbedtls_mpi_uint));
mbedtls_mpi_core_gcd_modinv_odd(G, I, I, 2, I, 2, TI);
exit:
mbedtls_free(G);
mbedtls_free(I);
mbedtls_free(TG);
mbedtls_free(TI);
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
void mpi_core_div2_mod_odd(char *input_X, char *input_N, char *input_exp_X)
{
mbedtls_mpi_uint *X = NULL;
size_t X_limbs = 0;
mbedtls_mpi_uint *N = NULL;
size_t N_limbs = 0;
mbedtls_mpi_uint *exp_X = NULL;
size_t exp_X_limbs = 0;
/* Read test parameters into MPI structures */
TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &X_limbs, input_X));
TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &N_limbs, input_N));
TEST_EQUAL(0, mbedtls_test_read_mpi_core(&exp_X, &exp_X_limbs, input_exp_X));
/* The function under test requires this */
TEST_EQUAL(X_limbs, N_limbs);
TEST_CF_SECRET(X, X_limbs * sizeof(mbedtls_mpi_uint));
TEST_CF_SECRET(N, N_limbs * sizeof(mbedtls_mpi_uint));
mbedtls_mpi_core_div2_mod_odd(X, N, N_limbs);
TEST_CF_PUBLIC(X, X_limbs * sizeof(mbedtls_mpi_uint));
TEST_EQUAL(0, mpi_core_cmp(X, X_limbs, exp_X, exp_X_limbs));
exit:
mbedtls_free(X);
mbedtls_free(N);
mbedtls_free(exp_X);
}
/* END_CASE */

View File

@@ -523,3 +523,29 @@ mpi_core_clz:64:0
CLZ: 100000 0: skip overly long input
mpi_core_clz:100000:0
GCD-modinv random 80-bit, non-trivial GCD -> no inverse
mpi_core_gcd_modinv_odd:"e4518a1900fce698fa3":"1a84113636607520200d":"3":""
GCD-modinv random 80-bit, trivial GCD -> inverse
mpi_core_gcd_modinv_odd:"7f2405d6de7db80a7bc":"1a84113636607520200d":"1":"15f158844a59cd7a3ed2"
# This data results in the gcd-modinv loop converging to its final state
# only in the last iteration. See python script in commit message.
GCD-modinv (almost) max iterations
mpi_core_gcd_modinv_odd:"8000000000000000":"b26eb5721a2cb24c36acb4550b176671":"1":"77e1dd63583a6b3c8deefe7737862c89"
GCD-modinv preconditions not met
mpi_core_gcd_modinv_odd_preconditions:
Div2 mod odd: even value
mpi_core_div2_mod_odd:"4":"7":"2"
Div2 mod odd: odd value, no carry
mpi_core_div2_mod_odd:"5":"7":"6"
Div2 mod odd: odd value with carry
mpi_core_div2_mod_odd:"8000000000000001":"8000000000000003":"8000000000000002"
Div2 mod odd: even value with top bit set
mpi_core_div2_mod_odd:"8000000000000002":"8000000000000003":"4000000000000001"

View File

@@ -1482,43 +1482,243 @@ AES-256 CBC - Encrypt and decrypt 32 bytes in multiple parts with PKCS7 padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_CBC:256:16:16:MBEDTLS_PADDING_PKCS7:16:16:0:32
AES Decrypt test vector #0
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_PADDING_PKCS7:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"00000000000000000000000000000000":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES Decrypt test vector #1
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
AES-128-CBC Decrypt test vector, no padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
decrypt_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_NONE:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"00000000000000000000000000000000":"":"":0:0
AES Decrypt test vector #2
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
AES-192-CBC Decrypt test vector, no padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
decrypt_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_NONE:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"fffffffff80000000000000000000000":"":"":0:0
AES Decrypt test vector #3
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
AES-256-CBC Decrypt test vector, no padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_NONE:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"ff000000000000000000000000000000":"":"":0:0
AES Decrypt test vector #4
AES-128-CBC Decrypt test vector, PKCS7 (good pad 1)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"6dbd04d1579f6a7bee0842b9ae491588":"000000000000000000000000000000":"":"":0:0
AES-192-CBC Decrypt test vector, PKCS7 (good pad 1)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"593ebdf9a785f414cbed5d8a9eee1e4d":"fffffffff800000000000000000000":"":"":0:0
AES-256-CBC Decrypt test vector, PKCS7 (good pad 1)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"f1b27ac78b93f6b0ab9787d8827176e6":"ff0000000000000000000000000000":"":"":0:0
AES-128-CBC Decrypt test vector, PKCS7 (good pad 2)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"175334ced3166a22437861f4bcced178":"0000000000000000000000000000":"":"":0:0
AES-192-CBC Decrypt test vector, PKCS7 (good pad 2)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"5d9ee7bc7066e438582c86c165604f2e":"fffffffff8000000000000000000":"":"":0:0
AES-256-CBC Decrypt test vector, PKCS7 (good pad 2)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"cc71abea78b8e82c3791b52d3dba55e2":"ff00000000000000000000000000":"":"":0:0
AES-128-CBC Decrypt test vector, PKCS7 (good pad 15)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"7d340c60b9067883962c69766cf9ec35":"2a":"":"":0:0
AES-192-CBC Decrypt test vector, PKCS7 (good pad 15)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"48fef8aaa78c4a148f241aaf14866772":"2a":"":"":0:0
AES-256-CBC Decrypt test vector, PKCS7 (good pad 15)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"6ad50ca266a3e32024818f11839afb2f":"2a":"":"":0:0
AES-128-CBC Decrypt test vector, PKCS7 (good pad 16)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"e9844992c4b55bcaf8199d5df842adad":"":"":"":0:0
AES-192-CBC Decrypt test vector, PKCS7 (good pad 16)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"02bb292527e726fd51eb29894d6f0aad":"":"":"":0:0
AES-256-CBC Decrypt test vector, PKCS7 (good pad 16)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"1f788fe6d86c317549697fbf0c07fa43":"":"":"":0:0
AES-128-CBC Decrypt test vector, PKCS7 (bad pad 0)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-192-CBC Decrypt test vector, PKCS7 (bad pad 0)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-256-CBC Decrypt test vector, PKCS7 (bad pad 0)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-128-CBC Decrypt test vector, PKCS7 (bad pad 0102)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"e651289760d35177eade56eae724f8fd":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-192-CBC Decrypt test vector, PKCS7 (bad pad 0102)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"f5b599490354e71a3b3fb5f1419fb971":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-256-CBC Decrypt test vector, PKCS7 (bad pad 0102)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"6852d318a0884a289a725c558e761e25":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-128-CBC Decrypt test vector, PKCS7 (long, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"9c336551cc31074ffcefc161bac686b7afa572c3b53bd14a1b98d201229ddd03":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-192-CBC Decrypt test vector, PKCS7 (long, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"33a31ec7605c85893872a467777f3ddb5c4271870e51a0c618f20a0efccc2bfc":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-256-CBC Decrypt test vector, PKCS7 (long, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e64f439d87aa0deb338029253bea0ba54f":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-128-CBC Decrypt test vector, PKCS7 (short, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"9c336551cc31074ffcefc161bac686b7":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-192-CBC Decrypt test vector, PKCS7 (short, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"33a31ec7605c85893872a467777f3ddb":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-256-CBC Decrypt test vector, PKCS7 (short, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e6":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-128-CBC Decrypt with finish_padded, no padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_NONE:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"00000000000000000000000000000000":"":"":0:0
AES-192-CBC Decrypt with finish_padded, no padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_NONE:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"fffffffff80000000000000000000000":"":"":0:0
AES-256-CBC Decrypt with finish_padded, no padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_NONE:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"ff000000000000000000000000000000":"":"":0:0
AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 1)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"6dbd04d1579f6a7bee0842b9ae491588":"000000000000000000000000000000":"":"":0:0
AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 1)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"593ebdf9a785f414cbed5d8a9eee1e4d":"fffffffff800000000000000000000":"":"":0:0
AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 1)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"f1b27ac78b93f6b0ab9787d8827176e6":"ff0000000000000000000000000000":"":"":0:0
AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 2)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"175334ced3166a22437861f4bcced178":"0000000000000000000000000000":"":"":0:0
AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 2)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"5d9ee7bc7066e438582c86c165604f2e":"fffffffff8000000000000000000":"":"":0:0
AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 2)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"cc71abea78b8e82c3791b52d3dba55e2":"ff00000000000000000000000000":"":"":0:0
AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 15)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"7d340c60b9067883962c69766cf9ec35":"2a":"":"":0:0
AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 15)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"48fef8aaa78c4a148f241aaf14866772":"2a":"":"":0:0
AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 15)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"6ad50ca266a3e32024818f11839afb2f":"2a":"":"":0:0
AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 16)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"e9844992c4b55bcaf8199d5df842adad":"":"":"":0:0
AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 16)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"02bb292527e726fd51eb29894d6f0aad":"":"":"":0:0
AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 16)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"1f788fe6d86c317549697fbf0c07fa43":"":"":"":0:0
AES-128-CBC Decrypt with finish_padded, PKCS7 (bad pad 0)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-192-CBC Decrypt with finish_padded, PKCS7 (bad pad 0)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-256-CBC Decrypt with finish_padded, PKCS7 (bad pad 0)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-128-CBC Decrypt with finish_padded, PKCS7 (bad pad 0102)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"e651289760d35177eade56eae724f8fd":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-192-CBC Decrypt with finish_padded, PKCS7 (bad pad 0102)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"f5b599490354e71a3b3fb5f1419fb971":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-256-CBC Decrypt with finish_padded, PKCS7 (bad pad 0102)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"6852d318a0884a289a725c558e761e25":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-128-CBC Decrypt with finish_padded, PKCS7 (long, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"9c336551cc31074ffcefc161bac686b7afa572c3b53bd14a1b98d201229ddd03":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-192-CBC Decrypt with finish_padded, PKCS7 (long, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"33a31ec7605c85893872a467777f3ddb5c4271870e51a0c618f20a0efccc2bfc":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-256-CBC Decrypt with finish_padded, PKCS7 (long, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e64f439d87aa0deb338029253bea0ba54f":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-128-CBC Decrypt with finish_padded, PKCS7 (short, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"9c336551cc31074ffcefc161bac686b7":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-192-CBC Decrypt with finish_padded, PKCS7 (short, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"33a31ec7605c85893872a467777f3ddb":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-256-CBC Decrypt with finish_padded, PKCS7 (short, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e6":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
AES-128-CFB Decrypt test vector
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CFB
decrypt_test_vec:MBEDTLS_CIPHER_AES_128_CFB128:-1:"fffffffe000000000000000000000000":"00000000000000000000000000000000":"1114bc2028009b923f0b01915ce5e7c4":"00000000000000000000000000000000":"":"":0:0:
AES Decrypt test vector #5
AES-192-CFB Decrypt test vector
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CFB:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
decrypt_test_vec:MBEDTLS_CIPHER_AES_192_CFB128:-1:"ffffffffffffffffffffffffffffffffffffffffffe00000":"00000000000000000000000000000000":"60136703374f64e860b48ce31f930716":"00000000000000000000000000000000":"":"":0:0
AES Decrypt test vector #6
AES-256-CFB Decrypt test vector
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CFB:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CFB128:-1:"ffffffffff800000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"be66cfea2fecd6bf0ec7b4352c99bcaa":"00000000000000000000000000000000":"":"":0:0
AES Decrypt test vector #7
AES-128-OFB Decrypt test vector
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
decrypt_test_vec:MBEDTLS_CIPHER_AES_128_OFB:-1:"2B7E151628AED2A6ABF7158809CF4F3C":"000102030405060708090A0B0C0D0E0F":"3B3FD92EB72DAD20333449F8E83CFB4A7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"":"":0:0:
AES Decrypt test vector #8
AES-192-OFB Decrypt test vector
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
decrypt_test_vec:MBEDTLS_CIPHER_AES_192_OFB:-1:"8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B":"000102030405060708090A0B0C0D0E0F":"CDC80D6FDDF18CAB34C25909C99A4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"":"":0:0:
AES Decrypt test vector #9
AES-256-OFB Decrypt test vector
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
decrypt_test_vec:MBEDTLS_CIPHER_AES_256_OFB:-1:"603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4":"000102030405060708090A0B0C0D0E0F":"DC7E84BFDA79164B7ECD8486985D38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484":"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710":"":"":0:0:

View File

@@ -0,0 +1,255 @@
Constant-time PKCS7 padding, valid #1
get_pkcs_padding:"00112233445566778899AABBCCDDEE01":0:15
Constant-time PKCS7 padding, valid #2
get_pkcs_padding:"00112233445566778899AA0505050505":0:11
Constant-time PKCS7 padding, valid #3
get_pkcs_padding:"10101010101010101010101010101010":0:0
Constant-time PKCS7 padding, invalid zero
get_pkcs_padding:"00112233445566778899AABBCCDDEE00":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
Constant-time PKCS7 padding, invalid > 16
get_pkcs_padding:"00112233445566778899AABBCCDDEE11":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-128-CBC Decrypt with finish_padded, no padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_NONE:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"00000000000000000000000000000000":"":"":0:0
CF AES-192-CBC Decrypt with finish_padded, no padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_NONE:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"fffffffff80000000000000000000000":"":"":0:0
CF AES-256-CBC Decrypt with finish_padded, no padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_NONE:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"ff000000000000000000000000000000":"":"":0:0
CF AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 1)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"6dbd04d1579f6a7bee0842b9ae491588":"000000000000000000000000000000":"":"":0:0
CF AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 1)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"593ebdf9a785f414cbed5d8a9eee1e4d":"fffffffff800000000000000000000":"":"":0:0
CF AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 1)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"f1b27ac78b93f6b0ab9787d8827176e6":"ff0000000000000000000000000000":"":"":0:0
CF AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 2)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"175334ced3166a22437861f4bcced178":"0000000000000000000000000000":"":"":0:0
CF AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 2)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"5d9ee7bc7066e438582c86c165604f2e":"fffffffff8000000000000000000":"":"":0:0
CF AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 2)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"cc71abea78b8e82c3791b52d3dba55e2":"ff00000000000000000000000000":"":"":0:0
CF AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 15)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"7d340c60b9067883962c69766cf9ec35":"2a":"":"":0:0
CF AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 15)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"48fef8aaa78c4a148f241aaf14866772":"2a":"":"":0:0
CF AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 15)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"6ad50ca266a3e32024818f11839afb2f":"2a":"":"":0:0
CF AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 16)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"e9844992c4b55bcaf8199d5df842adad":"":"":"":0:0
CF AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 16)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"02bb292527e726fd51eb29894d6f0aad":"":"":"":0:0
CF AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 16)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"1f788fe6d86c317549697fbf0c07fa43":"":"":"":0:0
CF AES-128-CBC Decrypt with finish_padded, PKCS7 (bad pad 0)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-192-CBC Decrypt with finish_padded, PKCS7 (bad pad 0)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-256-CBC Decrypt with finish_padded, PKCS7 (bad pad 0)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-128-CBC Decrypt with finish_padded, PKCS7 (bad pad 0102)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"e651289760d35177eade56eae724f8fd":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-192-CBC Decrypt with finish_padded, PKCS7 (bad pad 0102)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"f5b599490354e71a3b3fb5f1419fb971":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-256-CBC Decrypt with finish_padded, PKCS7 (bad pad 0102)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"6852d318a0884a289a725c558e761e25":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-128-CBC Decrypt with finish_padded, PKCS7 (long, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"9c336551cc31074ffcefc161bac686b7afa572c3b53bd14a1b98d201229ddd03":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-192-CBC Decrypt with finish_padded, PKCS7 (long, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"33a31ec7605c85893872a467777f3ddb5c4271870e51a0c618f20a0efccc2bfc":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-256-CBC Decrypt with finish_padded, PKCS7 (long, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e64f439d87aa0deb338029253bea0ba54f":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-128-CBC Decrypt with finish_padded, PKCS7 (short, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"9c336551cc31074ffcefc161bac686b7":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-192-CBC Decrypt with finish_padded, PKCS7 (short, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"33a31ec7605c85893872a467777f3ddb":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-256-CBC Decrypt with finish_padded, PKCS7 (short, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e6":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-128-CBC Decrypt test vector, no padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_NONE:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"00000000000000000000000000000000":"":"":0:0
CF AES-192-CBC Decrypt test vector, no padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_NONE:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"fffffffff80000000000000000000000":"":"":0:0
CF AES-256-CBC Decrypt test vector, no padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_NONE:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"ff000000000000000000000000000000":"":"":0:0
CF AES-128-CBC Decrypt test vector, PKCS7 (good pad 1)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"6dbd04d1579f6a7bee0842b9ae491588":"000000000000000000000000000000":"":"":0:0
CF AES-192-CBC Decrypt test vector, PKCS7 (good pad 1)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"593ebdf9a785f414cbed5d8a9eee1e4d":"fffffffff800000000000000000000":"":"":0:0
CF AES-256-CBC Decrypt test vector, PKCS7 (good pad 1)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"f1b27ac78b93f6b0ab9787d8827176e6":"ff0000000000000000000000000000":"":"":0:0
CF AES-128-CBC Decrypt test vector, PKCS7 (good pad 2)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"175334ced3166a22437861f4bcced178":"0000000000000000000000000000":"":"":0:0
CF AES-192-CBC Decrypt test vector, PKCS7 (good pad 2)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"5d9ee7bc7066e438582c86c165604f2e":"fffffffff8000000000000000000":"":"":0:0
CF AES-256-CBC Decrypt test vector, PKCS7 (good pad 2)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"cc71abea78b8e82c3791b52d3dba55e2":"ff00000000000000000000000000":"":"":0:0
CF AES-128-CBC Decrypt test vector, PKCS7 (good pad 15)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"7d340c60b9067883962c69766cf9ec35":"2a":"":"":0:0
CF AES-192-CBC Decrypt test vector, PKCS7 (good pad 15)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"48fef8aaa78c4a148f241aaf14866772":"2a":"":"":0:0
CF AES-256-CBC Decrypt test vector, PKCS7 (good pad 15)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"6ad50ca266a3e32024818f11839afb2f":"2a":"":"":0:0
CF AES-128-CBC Decrypt test vector, PKCS7 (good pad 16)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"e9844992c4b55bcaf8199d5df842adad":"":"":"":0:0
CF AES-192-CBC Decrypt test vector, PKCS7 (good pad 16)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"02bb292527e726fd51eb29894d6f0aad":"":"":"":0:0
CF AES-256-CBC Decrypt test vector, PKCS7 (good pad 16)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"1f788fe6d86c317549697fbf0c07fa43":"":"":"":0:0
CF AES-128-CBC Decrypt test vector, PKCS7 (bad pad 0)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-192-CBC Decrypt test vector, PKCS7 (bad pad 0)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-256-CBC Decrypt test vector, PKCS7 (bad pad 0)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-128-CBC Decrypt test vector, PKCS7 (bad pad 0102)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"e651289760d35177eade56eae724f8fd":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-192-CBC Decrypt test vector, PKCS7 (bad pad 0102)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"f5b599490354e71a3b3fb5f1419fb971":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-256-CBC Decrypt test vector, PKCS7 (bad pad 0102)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"6852d318a0884a289a725c558e761e25":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-128-CBC Decrypt test vector, PKCS7 (long, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"9c336551cc31074ffcefc161bac686b7afa572c3b53bd14a1b98d201229ddd03":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-192-CBC Decrypt test vector, PKCS7 (long, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"33a31ec7605c85893872a467777f3ddb5c4271870e51a0c618f20a0efccc2bfc":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-256-CBC Decrypt test vector, PKCS7 (long, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e64f439d87aa0deb338029253bea0ba54f":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-128-CBC Decrypt test vector, PKCS7 (short, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"9c336551cc31074ffcefc161bac686b7":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-192-CBC Decrypt test vector, PKCS7 (short, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"33a31ec7605c85893872a467777f3ddb":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-256-CBC Decrypt test vector, PKCS7 (short, bad pad 17)
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e6":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-128-CBC crypt Encrypt NIST KAT #4
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:HAVE_CONSTANT_TIME_AES
test_vec_crypt_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_NONE:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"00000000000000000000000000000000":"f34481ec3cc627bacd5dc3fb08f273e6":"0336763e966d92595a567cc9ce537f5e":0:0
CF AES-128-CBC crypt Decrypt NIST KAT #4
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:HAVE_CONSTANT_TIME_AES
test_vec_crypt_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_NONE:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"00000000000000000000000000000000":"0336763e966d92595a567cc9ce537f5e":"f34481ec3cc627bacd5dc3fb08f273e6":0:0
CF AES-128-CBC crypt Decrypt PKCS7 invalid padding
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES
test_vec_crypt_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"00000000000000000000000000000000":"0336763e966d92595a567cc9ce537f5e":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
CF AES-128-CBC crypt Encrypt NIST KAT #4 PSA
depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_CBC_NO_PADDING:HAVE_CONSTANT_TIME_AES
test_vec_crypt_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_NONE:MBEDTLS_ENCRYPT:"00000000000000000000000000000000":"00000000000000000000000000000000":"f34481ec3cc627bacd5dc3fb08f273e6":"0336763e966d92595a567cc9ce537f5e":0:1
CF AES-128-CBC crypt Decrypt NIST KAT #4 PSA
depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_CBC_NO_PADDING:HAVE_CONSTANT_TIME_AES
test_vec_crypt_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_NONE:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"00000000000000000000000000000000":"0336763e966d92595a567cc9ce537f5e":"f34481ec3cc627bacd5dc3fb08f273e6":0:1
## PSA-backed cipher contexts do not support PKCS7 padding.
#CF AES-128-CBC crypt Decrypt PKCS7 invalid padding PSA
#depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_DEPRECATED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_CBC_PKCS7:HAVE_CONSTANT_TIME_AES
#test_vec_crypt_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:MBEDTLS_DECRYPT:"00000000000000000000000000000000":"00000000000000000000000000000000":"0336763e966d92595a567cc9ce537f5e":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:1

View File

@@ -14,6 +14,20 @@
#define MBEDTLS_CIPHER_AUTH_CRYPT
#endif
/* Our software AES implementation is not constant-time. For constant-time
* testing involving AES, require a hardware-assisted AES that is
* constant-time.
*
* We assume that if the hardware-assisted version is available in the build,
* it will be available at runtime. The AES tests will fail if run on a
* processor without AESNI/AESCE.
*/
#include "aesce.h"
#include "aesni.h"
#if defined(MBEDTLS_AESCE_HAVE_CODE) || defined(MBEDTLS_AESNI_HAVE_CODE)
#define HAVE_CONSTANT_TIME_AES
#endif
/* Check the internal consistency of a cipher info structure, and
* check it against mbedtls_cipher_info_from_xxx(). */
static int check_cipher_info(mbedtls_cipher_type_t type,
@@ -858,6 +872,269 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE */
/* Similar to decrypt_test_vec, but with constant-flow assertions.
* We use a separate test function so that we can run the functional tests
* in all configurations where the underlying cipher is enabled, and
* run the constant-flow tests only in configurations where the underlying
* cipher is constant-time. In particular, AES test cases need to depend
* on HAVE_CONSTANT_TIME_AES.
*/
void decrypt_test_vec_cf(int cipher_id, int pad_mode, data_t *key,
data_t *iv, data_t *cipher,
data_t *clear, data_t *ad, data_t *tag,
int expected_finish_result, int tag_result)
{
unsigned char output[265];
mbedtls_cipher_context_t ctx;
size_t outlen, total_len;
mbedtls_cipher_init(&ctx);
memset(output, 0x00, sizeof(output));
#if !defined(MBEDTLS_GCM_C) && !defined(MBEDTLS_CHACHAPOLY_C)
((void) ad);
((void) tag);
#endif
TEST_CF_SECRET(key->x, key->len);
TEST_CF_SECRET(cipher->x, cipher->len);
/* Prepare context */
TEST_ASSERT(0 == mbedtls_cipher_setup(&ctx,
mbedtls_cipher_info_from_type(cipher_id)));
TEST_ASSERT(0 == mbedtls_cipher_setkey(&ctx, key->x, 8 * key->len, MBEDTLS_DECRYPT));
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
if (pad_mode != -1) {
TEST_ASSERT(0 == mbedtls_cipher_set_padding_mode(&ctx, pad_mode));
}
#else
(void) pad_mode;
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
TEST_ASSERT(0 == mbedtls_cipher_set_iv(&ctx, iv->x, iv->len));
TEST_ASSERT(0 == mbedtls_cipher_reset(&ctx));
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
int expected = (ctx.cipher_info->mode == MBEDTLS_MODE_GCM ||
ctx.cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305) ?
0 : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
TEST_EQUAL(expected, mbedtls_cipher_update_ad(&ctx, ad->x, ad->len));
#endif
/* decode buffer and check tag->x */
total_len = 0;
TEST_ASSERT(0 == mbedtls_cipher_update(&ctx, cipher->x, cipher->len, output, &outlen));
total_len += outlen;
int actual_finish_result = mbedtls_cipher_finish(&ctx, output + outlen,
&outlen);
TEST_CF_PUBLIC(&outlen, sizeof(outlen));
TEST_EQUAL(actual_finish_result, expected_finish_result);
if (0 != expected_finish_result) {
/* Check output parameter is set to the least-harmful value on error */
TEST_ASSERT(0 == outlen);
}
total_len += outlen;
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
int tag_expected = (ctx.cipher_info->mode == MBEDTLS_MODE_GCM ||
ctx.cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305) ?
tag_result : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
TEST_EQUAL(tag_expected, mbedtls_cipher_check_tag(&ctx, tag->x, tag->len));
#endif
/* check plaintext only if everything went fine */
if (0 == expected_finish_result && 0 == tag_result) {
TEST_CF_PUBLIC(output, sizeof(output));
TEST_MEMORY_COMPARE(output, total_len, clear->x, clear->len);
}
exit:
mbedtls_cipher_free(&ctx);
}
/* END_CASE */
/* BEGIN_CASE */
void decrypt_padded_test_vec(int cipher_id, int pad_mode, data_t *key,
data_t *iv, data_t *cipher,
data_t *clear, data_t *ad, data_t *tag,
int expected_finish_result, int tag_result)
{
unsigned char output[265];
mbedtls_cipher_context_t ctx;
size_t outlen, total_len;
mbedtls_cipher_init(&ctx);
memset(output, 0x00, sizeof(output));
#if !defined(MBEDTLS_GCM_C) && !defined(MBEDTLS_CHACHAPOLY_C)
((void) ad);
((void) tag);
#endif
/* Prepare context */
TEST_ASSERT(0 == mbedtls_cipher_setup(&ctx,
mbedtls_cipher_info_from_type(cipher_id)));
TEST_ASSERT(0 == mbedtls_cipher_setkey(&ctx, key->x, 8 * key->len, MBEDTLS_DECRYPT));
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
if (pad_mode != -1) {
TEST_ASSERT(0 == mbedtls_cipher_set_padding_mode(&ctx, pad_mode));
}
#else
(void) pad_mode;
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
TEST_ASSERT(0 == mbedtls_cipher_set_iv(&ctx, iv->x, iv->len));
TEST_ASSERT(0 == mbedtls_cipher_reset(&ctx));
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
int expected = (ctx.cipher_info->mode == MBEDTLS_MODE_GCM ||
ctx.cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305) ?
0 : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
TEST_EQUAL(expected, mbedtls_cipher_update_ad(&ctx, ad->x, ad->len));
#endif
/* decode buffer and check tag->x */
total_len = 0;
TEST_ASSERT(0 == mbedtls_cipher_update(&ctx, cipher->x, cipher->len, output, &outlen));
total_len += outlen;
size_t invalid_padding = 42;
int actual_finish_result =
mbedtls_cipher_finish_padded(&ctx, output + outlen, &outlen,
&invalid_padding);
switch (expected_finish_result) {
case 0:
TEST_EQUAL(actual_finish_result, 0);
TEST_EQUAL(invalid_padding, 0);
break;
case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
TEST_EQUAL(actual_finish_result, 0);
TEST_EQUAL(invalid_padding, ~(size_t) 0);
break;
default:
TEST_EQUAL(actual_finish_result, expected_finish_result);
/* Check output parameter is set to the least-harmful value on error */
TEST_EQUAL(0, outlen);
break;
}
total_len += outlen;
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
int tag_expected = (ctx.cipher_info->mode == MBEDTLS_MODE_GCM ||
ctx.cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305) ?
tag_result : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
TEST_EQUAL(tag_expected, mbedtls_cipher_check_tag(&ctx, tag->x, tag->len));
#endif
/* check plaintext only if everything went fine */
if (0 == expected_finish_result && 0 == tag_result) {
TEST_ASSERT(total_len == clear->len);
TEST_ASSERT(0 == memcmp(output, clear->x, clear->len));
}
exit:
mbedtls_cipher_free(&ctx);
}
/* END_CASE */
/* BEGIN_CASE */
/* Similar to decrypt_padded_test_vec, but with constant-flow assertions.
* We use a separate test function so that we can run the functional tests
* in all configurations where the underlying cipher is enabled, and
* run the constant-flow tests only in configurations where the underlying
* cipher is constant-time. In particular, AES test cases need to depend
* on HAVE_CONSTANT_TIME_AES.
*/
void decrypt_padded_test_vec_cf(int cipher_id, int pad_mode, data_t *key,
data_t *iv, data_t *cipher,
data_t *clear, data_t *ad, data_t *tag,
int expected_finish_result, int tag_result)
{
unsigned char output[265];
mbedtls_cipher_context_t ctx;
size_t outlen, total_len;
mbedtls_cipher_init(&ctx);
memset(output, 0x00, sizeof(output));
#if !defined(MBEDTLS_GCM_C) && !defined(MBEDTLS_CHACHAPOLY_C)
((void) ad);
((void) tag);
#endif
TEST_CF_SECRET(key->x, key->len);
TEST_CF_SECRET(cipher->x, cipher->len);
/* Prepare context */
TEST_ASSERT(0 == mbedtls_cipher_setup(&ctx,
mbedtls_cipher_info_from_type(cipher_id)));
TEST_ASSERT(0 == mbedtls_cipher_setkey(&ctx, key->x, 8 * key->len, MBEDTLS_DECRYPT));
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
if (pad_mode != -1) {
TEST_ASSERT(0 == mbedtls_cipher_set_padding_mode(&ctx, pad_mode));
}
#else
(void) pad_mode;
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
TEST_ASSERT(0 == mbedtls_cipher_set_iv(&ctx, iv->x, iv->len));
TEST_ASSERT(0 == mbedtls_cipher_reset(&ctx));
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
int expected = (ctx.cipher_info->mode == MBEDTLS_MODE_GCM ||
ctx.cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305) ?
0 : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
TEST_EQUAL(expected, mbedtls_cipher_update_ad(&ctx, ad->x, ad->len));
#endif
/* decode buffer and check tag->x */
total_len = 0;
TEST_ASSERT(0 == mbedtls_cipher_update(&ctx, cipher->x, cipher->len, output, &outlen));
total_len += outlen;
size_t invalid_padding = 42;
int actual_finish_result =
mbedtls_cipher_finish_padded(&ctx, output + outlen, &outlen,
&invalid_padding);
TEST_CF_PUBLIC(&outlen, sizeof(outlen));
switch (expected_finish_result) {
case 0:
TEST_EQUAL(actual_finish_result, 0);
TEST_EQUAL(invalid_padding, 0);
break;
case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
TEST_EQUAL(actual_finish_result, 0);
TEST_EQUAL(invalid_padding, ~(size_t) 0);
break;
default:
TEST_EQUAL(actual_finish_result, expected_finish_result);
/* Check output parameter is set to the least-harmful value on error */
TEST_EQUAL(0, outlen);
break;
}
total_len += outlen;
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
int tag_expected = (ctx.cipher_info->mode == MBEDTLS_MODE_GCM ||
ctx.cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305) ?
tag_result : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
TEST_EQUAL(tag_expected, mbedtls_cipher_check_tag(&ctx, tag->x, tag->len));
#endif
/* check plaintext only if everything went fine */
if (0 == expected_finish_result && 0 == tag_result) {
TEST_CF_PUBLIC(output, sizeof(output));
TEST_MEMORY_COMPARE(output, total_len, clear->x, clear->len);
}
exit:
mbedtls_cipher_free(&ctx);
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_AEAD */
void auth_crypt_tv(int cipher_id, data_t *key, data_t *iv,
data_t *ad, data_t *cipher, data_t *tag,
@@ -1140,6 +1417,68 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_WITH_PADDING */
/* Similar to test_vec_crypt, but with constant-flow assertions.
* We use a separate test function so that we can run the functional tests
* in all configurations where the underlying cipher is enabled, and
* run the constant-flow tests only in configurations where the underlying
* cipher is constant-time. In particular, AES test cases need to depend
* on HAVE_CONSTANT_TIME_AES.
*/
void test_vec_crypt_cf(int cipher_id, int pad_mode, int operation, data_t *key,
data_t *iv, data_t *input, data_t *result,
int expected_finish_result, int use_psa)
{
mbedtls_cipher_context_t ctx;
unsigned char output[32];
size_t outlen;
mbedtls_cipher_init(&ctx);
memset(output, 0x00, sizeof(output));
TEST_CF_SECRET(key->x, key->len);
TEST_CF_SECRET(input->x, input->len);
/* Prepare context */
#if !defined(MBEDTLS_USE_PSA_CRYPTO) || !defined(MBEDTLS_TEST_DEPRECATED)
(void) use_psa;
#else
if (use_psa == 1) {
PSA_ASSERT(psa_crypto_init());
TEST_ASSERT(0 == mbedtls_cipher_setup_psa(&ctx,
mbedtls_cipher_info_from_type(cipher_id), 0));
} else
#endif /* !MBEDTLS_USE_PSA_CRYPTO || !MBEDTLS_TEST_DEPRECATED*/
TEST_ASSERT(0 == mbedtls_cipher_setup(&ctx,
mbedtls_cipher_info_from_type(cipher_id)));
TEST_ASSERT(0 == mbedtls_cipher_setkey(&ctx, key->x, 8 * key->len, operation));
if (MBEDTLS_MODE_CBC == ctx.cipher_info->mode) {
TEST_ASSERT(0 == mbedtls_cipher_set_padding_mode(&ctx, pad_mode));
}
int actual_finish_result =
mbedtls_cipher_crypt(&ctx, iv->len ? iv->x : NULL, iv->len,
input->x, input->len,
output, &outlen);
TEST_CF_PUBLIC(&outlen, sizeof(outlen));
TEST_EQUAL(expected_finish_result, actual_finish_result);
/* check plaintext only if everything went fine */
if (0 == expected_finish_result) {
TEST_CF_PUBLIC(output, sizeof(output));
TEST_MEMORY_COMPARE(output, outlen, result->x, result->len);
}
exit:
mbedtls_cipher_free(&ctx);
#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_TEST_DEPRECATED)
PSA_DONE();
#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_TEST_DEPRECATED */
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_WITH_PADDING */
void set_padding(int cipher_id, int pad_mode, int ret)
{
@@ -1160,8 +1499,8 @@ exit:
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
void check_padding(int pad_mode, data_t *input, int ret, int dlen_check
)
void check_padding(int pad_mode, data_t *input,
int expected_ret, int dlen_check)
{
mbedtls_cipher_info_t cipher_info;
mbedtls_cipher_context_t ctx;
@@ -1174,10 +1513,20 @@ void check_padding(int pad_mode, data_t *input, int ret, int dlen_check
TEST_ASSERT(0 == mbedtls_cipher_set_padding_mode(&ctx, pad_mode));
TEST_ASSERT(ret == ctx.get_padding(input->x, input->len, &dlen));
if (0 == ret) {
TEST_ASSERT(dlen == (size_t) dlen_check);
size_t invalid_padding = 42;
int ret = ctx.get_padding(input->x, input->len, &dlen, &invalid_padding);
switch (expected_ret) {
case 0:
TEST_EQUAL(ret, 0);
TEST_EQUAL(invalid_padding, 0);
TEST_EQUAL(dlen, dlen_check);
break;
case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
TEST_EQUAL(ret, 0);
TEST_EQUAL(invalid_padding, ~(size_t) 0);
break;
default:
TEST_EQUAL(ret, expected_ret);
}
}
/* END_CASE */
@@ -1270,14 +1619,27 @@ void get_pkcs_padding(data_t *decrypted_block, int exp_ret, int exp_len)
{
int ret;
size_t calculated_len;
size_t invalid_padding;
TEST_CF_SECRET(decrypted_block->x, decrypted_block->len);
ret = mbedtls_get_pkcs_padding(decrypted_block->x, decrypted_block->len,
&calculated_len);
&calculated_len, &invalid_padding);
TEST_EQUAL(ret, exp_ret);
if (exp_ret == 0) {
TEST_EQUAL(calculated_len, exp_len);
switch (exp_ret) {
case 0:
TEST_EQUAL(ret, 0);
TEST_EQUAL(invalid_padding, 0);
TEST_EQUAL(calculated_len, exp_len);
break;
case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
TEST_EQUAL(ret, 0);
TEST_EQUAL(invalid_padding, ~(size_t) 0);
break;
default:
TEST_EQUAL(ret, exp_ret);
break;
}
}
/* END_CASE */

View File

@@ -217,18 +217,3 @@ check_padding:MBEDTLS_PADDING_NONE:"DABBAD0001":0:5
Check no padding #3 (correct by definition)
check_padding:MBEDTLS_PADDING_NONE:"":0:0
Constant-time PKCS7 padding, valid #1
get_pkcs_padding:"00112233445566778899AABBCCDDEE01":0:15
Constant-time PKCS7 padding, valid #2
get_pkcs_padding:"00112233445566778899AA0505050505":0:11
Constant-time PKCS7 padding, valid #3
get_pkcs_padding:"10101010101010101010101010101010":0:0
Constant-time PKCS7 padding, invalid zero
get_pkcs_padding:"00112233445566778899AABBCCDDEE00":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
Constant-time PKCS7 padding, invalid > 16
get_pkcs_padding:"00112233445566778899AABBCCDDEE11":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0

View File

@@ -0,0 +1,39 @@
CT encrypt CHACHA20
depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
ct_cipher_encrypt:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"000000000000004a00000000":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"af051e40bba0354981329a806a140eafd258a22a6dcb4bb9f6569cb3efe2deaf837bd87ca20b5ba12081a306af0eb35c41a239d20dfc74c81771560d9c9c1e4b224f51f3401bd9e12fde276fb8631ded8c131f823d2c06e27e4fcaec9ef3cf788a3b0aa372600a92b57974cded2b9334794cba40c63e34cdea212c4cf07d41b769a6749f3f630f4122cafe28ec4dc47e26d4346d70b98c73f3e9c53ac40c5945398b6eda1a832c89c167eacd901d7e2bf363"
CT encrypt AES-CTR
depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES
ct_cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"dd3b5e5319b7591daab1e1a92687feb2":"396ee84fb75fdbb5c2b13c7fe5a654aa"
CT encrypt AES-CBC-nopad
depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES
ct_cipher_encrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"49e4e66c89a86b67758df89db9ad6955":"396ee84fb75fdbb5c2b13c7fe5a654aa"
CT encrypt AES-CBC-PKCS7
depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES
ct_cipher_encrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":"a076ec9dfbe47d52afc357336f20743bca7e8a15dc3c776436314293031cd4f3"
CT decrypt CHACHA20
depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
ct_cipher_decrypt:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"000000000000004a00000000":"af051e40bba0354981329a806a140eafd258a22a6dcb4bb9f6569cb3efe2deaf837bd87ca20b5ba12081a306af0eb35c41a239d20dfc74c81771560d9c9c1e4b224f51f3401bd9e12fde276fb8631ded8c131f823d2c06e27e4fcaec9ef3cf788a3b0aa372600a92b57974cded2b9334794cba40c63e34cdea212c4cf07d41b769a6749f3f630f4122cafe28ec4dc47e26d4346d70b98c73f3e9c53ac40c5945398b6eda1a832c89c167eacd901d7e2bf363":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":0
CT decrypt AES-CTR
depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES
ct_cipher_decrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":"dd3b5e5319b7591daab1e1a92687feb2":0
CT decrypt AES-CBC-nopad
depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES
ct_cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":"49e4e66c89a86b67758df89db9ad6955":0
CT decrypt AES-CBC-PKCS7 good
depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES
ct_cipher_decrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743bca7e8a15dc3c776436314293031cd4f3":"6bc1bee22e409f96e93d7e117393172a":0
CT decrypt AES-CBC-PKCS7 invalid padding @0
depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES
ct_cipher_decrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743bf42ddf64c420325affb343d5d5f5d5dc":"6bc1bee22e409f96e93d7e117393172a":1
CT decrypt AES-CBC-PKCS7 invalid padding @16
depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES
ct_cipher_decrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743ba3d6a86d0a9d172eeb1b754512d04416":"6bc1bee22e409f96e93d7e117393172a":1

View File

@@ -0,0 +1,310 @@
/* BEGIN_HEADER */
/* Positive test cases for PSA crypto APIs that assert constant-time
* (more accurately constant-flow) behavior. */
#include <psa/crypto.h>
#include <test/constant_flow.h>
/* Our software AES implementation is not constant-time. For constant-time
* testing involving AES, require a hardware-assisted AES that is
* constant-time.
*
* We assume that if the hardware-assisted version is available in the build,
* it will be available at runtime. The AES tests will fail if run on a
* processor without AESNI/AESCE.
*/
#include "aesce.h"
#include "aesni.h"
#if defined(MBEDTLS_AESCE_HAVE_CODE) || defined(MBEDTLS_AESNI_HAVE_CODE)
#define HAVE_CONSTANT_TIME_AES
#endif
static int ct_cipher_multipart(psa_cipher_operation_t *operation,
const data_t *iv,
const data_t *input,
size_t output_size,
const data_t *expected_output,
psa_status_t expected_finish_status)
{
unsigned char *output = NULL;
size_t update_length = SIZE_MAX;
size_t finish_length = SIZE_MAX;
psa_status_t status;
int ok = 0;
TEST_CALLOC(output, output_size);
PSA_ASSERT(psa_cipher_set_iv(operation, iv->x, iv->len));
status = psa_cipher_update(operation,
input->x, input->len,
output, output_size, &update_length);
if (expected_finish_status == PSA_ERROR_BUFFER_TOO_SMALL &&
status == PSA_ERROR_BUFFER_TOO_SMALL) {
/* The output buffer is already too small for update. That's ok. */
ok = 1;
goto exit;
} else {
PSA_ASSERT(status);
}
TEST_LE_U(update_length, output_size);
TEST_EQUAL(psa_cipher_finish(operation,
output + update_length,
output_size - update_length,
&finish_length),
expected_finish_status);
TEST_CF_PUBLIC(output, output_size);
if (expected_finish_status == PSA_SUCCESS) {
TEST_MEMORY_COMPARE(expected_output->x, expected_output->len,
output, update_length + finish_length);
}
ok = 1;
exit:
mbedtls_free(output);
psa_cipher_abort(operation);
return ok;
}
static int ct_cipher_decrypt_oneshot(mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const data_t *input,
size_t output_size,
const data_t *expected_output,
psa_status_t expected_status)
{
unsigned char *output = NULL;
size_t output_length = SIZE_MAX;
int ok = 0;
TEST_CALLOC(output, output_size);
TEST_EQUAL(psa_cipher_decrypt(key, alg,
input->x, input->len,
output, output_size, &output_length),
expected_status);
TEST_CF_PUBLIC(output, output_size);
if (expected_status == PSA_SUCCESS) {
TEST_MEMORY_COMPARE(expected_output->x, expected_output->len,
output, output_length);
}
ok = 1;
exit:
mbedtls_free(output);
return ok;
}
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_PSA_CRYPTO_C
* END_DEPENDENCIES
*/
/* BEGIN_CASE */
/* Known answer test for cipher multipart encryption.
* There is no known answer test for one-shot encryption because that
* uses a random IV. */
void ct_cipher_encrypt(int alg_arg,
int key_type_arg, const data_t *key_data,
const data_t *iv,
const data_t *plaintext,
const data_t *expected_ciphertext)
{
psa_key_type_t key_type = key_type_arg;
psa_algorithm_t alg = alg_arg;
size_t sufficient_output_size =
PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, plaintext->len);
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
PSA_INIT();
TEST_CF_SECRET(key_data->x, key_data->len);
TEST_CF_SECRET(plaintext->x, plaintext->len);
//TEST_ASSERT(key_data->x[0] != 42); // uncomment to trip constant-flow test
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
psa_set_key_algorithm(&attributes, alg);
psa_set_key_type(&attributes, key_type);
PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, &key));
/* Output buffer too small for the actual output */
mbedtls_test_set_step(1);
PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, plaintext,
expected_ciphertext->len - 1,
expected_ciphertext,
PSA_ERROR_BUFFER_TOO_SMALL)) {
goto exit;
}
if (expected_ciphertext->len < sufficient_output_size) {
/* For a buffer of intermediate size (between the actual output length
* and the guaranteed sufficient size), either PSA_SUCCESS or
* PSA_ERROR_BUFFER_TOO_SMALL is acceptable. Require what the our
* built-in implementation currently does. */
psa_status_t intermediate_size_status = PSA_SUCCESS;
/* Output buffer size just large enough for the actual output
* but less than the guaranteed sufficient size */
mbedtls_test_set_step(2);
PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, plaintext,
expected_ciphertext->len,
expected_ciphertext,
intermediate_size_status)) {
goto exit;
}
/* Output buffer size large enough for the actual output
* but one less than the guaranteed sufficient size */
mbedtls_test_set_step(3);
PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, plaintext,
sufficient_output_size - 1,
expected_ciphertext,
intermediate_size_status)) {
goto exit;
}
}
/* Guaranteed sufficient output buffer size */
mbedtls_test_set_step(4);
PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, plaintext,
sufficient_output_size,
expected_ciphertext,
PSA_SUCCESS)) {
goto exit;
}
exit:
psa_cipher_abort(&operation);
psa_destroy_key(key);
PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE */
/* Known answer for cipher decryption (one-shot and multipart).
* Supports good cases and invalid padding cases. */
void ct_cipher_decrypt(int alg_arg,
int key_type_arg, const data_t *key_data,
const data_t *iv,
const data_t *ciphertext,
const data_t *expected_plaintext,
int expect_invalid_padding)
{
psa_key_type_t key_type = key_type_arg;
psa_algorithm_t alg = alg_arg;
size_t sufficient_output_size =
PSA_CIPHER_DECRYPT_OUTPUT_SIZE(key_type, alg, ciphertext->len);
psa_status_t expected_status =
expect_invalid_padding ? PSA_ERROR_INVALID_PADDING : PSA_SUCCESS;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
data_t input = { NULL, iv->len + ciphertext->len };
PSA_INIT();
TEST_CF_SECRET(key_data->x, key_data->len);
TEST_CF_SECRET(ciphertext->x, ciphertext->len);
//TEST_ASSERT(key_data->x[0] != 42); // uncomment to trip constant-flow test
TEST_CALLOC(input.x, input.len);
memcpy(input.x, iv->x, iv->len);
memcpy(input.x + iv->len, ciphertext->x, ciphertext->len);
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(&attributes, alg);
psa_set_key_type(&attributes, key_type);
PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, &key));
/* Output buffer too small for the actual output */
mbedtls_test_set_step(1);
PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, ciphertext,
expected_plaintext->len - 1,
expected_plaintext,
PSA_ERROR_BUFFER_TOO_SMALL)) {
goto exit;
}
if (!ct_cipher_decrypt_oneshot(key, alg, &input,
expected_plaintext->len - 1,
expected_plaintext,
PSA_ERROR_BUFFER_TOO_SMALL)) {
goto exit;
}
if (expected_plaintext->len < sufficient_output_size) {
/* For a buffer of intermediate size (between the actual output length
* and the guaranteed sufficient size), either PSA_SUCCESS (or
* PSA_ERROR_INVALID_PADDING if the padding is invalid) or
* PSA_ERROR_BUFFER_TOO_SMALL is acceptable. Require what the our
* built-in implementation currently does. */
psa_status_t intermediate_size_status = expected_status;
if (alg == PSA_ALG_CBC_PKCS7) {
intermediate_size_status = PSA_ERROR_BUFFER_TOO_SMALL;
}
/* Output buffer size just large enough for the actual output
* but less than the guaranteed sufficient size */
mbedtls_test_set_step(2);
PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, ciphertext,
expected_plaintext->len,
expected_plaintext,
intermediate_size_status)) {
goto exit;
}
if (!ct_cipher_decrypt_oneshot(key, alg, &input,
expected_plaintext->len - 1,
expected_plaintext,
intermediate_size_status)) {
goto exit;
}
/* Output buffer size large enough for the actual output
* but one less than the guaranteed sufficient size */
mbedtls_test_set_step(3);
PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, ciphertext,
sufficient_output_size - 1,
expected_plaintext,
intermediate_size_status)) {
goto exit;
}
if (!ct_cipher_decrypt_oneshot(key, alg, &input,
sufficient_output_size - 1,
expected_plaintext,
intermediate_size_status)) {
goto exit;
}
}
/* Guaranteed sufficient output buffer size */
mbedtls_test_set_step(4);
PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, ciphertext,
sufficient_output_size,
expected_plaintext,
expected_status)) {
goto exit;
}
if (!ct_cipher_decrypt_oneshot(key, alg, &input,
sufficient_output_size,
expected_plaintext,
expected_status)) {
goto exit;
}
exit:
mbedtls_free(input.x);
psa_cipher_abort(&operation);
psa_destroy_key(key);
PSA_DONE();
}
/* END_CASE */