Beispiel #1
0
static void test_div_random(void)
{
	int i;
	char str[MAX_RAND_STRING_SIZE];

	TB_INFO("   Testing random divisions");

	DEF_BIGINT(n, 2048);
	DEF_BIGINT(d, 2048);
	DEF_BIGINT(q, 2048);
	DEF_BIGINT(r, 2048);
	DEF_BIGINT(v, 2048);

	for (i = 0; i < 10000; i++) {
		tb_set_random_value(n, str, 1);
		/* don't divide by zero */
		do {
			tb_set_random_value(d, str, 1);
		} while (TEE_BigIntCmpS32(d, 0) == 0);
		TEE_BigIntDiv(q, r, n, d);
		TEE_BigIntMul(v, q, d);
		TEE_BigIntAdd(v, v, r);
		TB_ASSERT_BIGINT_EQ(n, v);
		if (TEE_BigIntCmpS32(d, 0) > 0)
			TB_ASSERT_BIGINT_LESS(r, d);

	}

	DEL_BIGINT(n);
	DEL_BIGINT(d);
	DEL_BIGINT(q);
	DEL_BIGINT(r);
	DEL_BIGINT(v);
}
void TEE_BigIntInvMod(TEE_BigInt *dest, const TEE_BigInt *op,
		      const TEE_BigInt *n)
{
	if (TEE_BigIntCmpS32(n, 2) < 0 || TEE_BigIntCmpS32(op, 0) == 0)
		API_PANIC("too small modulus or trying to invert zero");

	mbedtls_mpi mpi_dest;
	mbedtls_mpi mpi_op;
	mbedtls_mpi mpi_n;
	mbedtls_mpi *pop = &mpi_op;

	get_mpi(&mpi_dest, dest);
	get_mpi(&mpi_n, n);

	if (op == dest)
		pop = &mpi_dest;
	else
		get_mpi(&mpi_op, op);

	MPI_CHECK(mbedtls_mpi_inv_mod(&mpi_dest, pop, &mpi_n));

	MPI_CHECK(copy_mpi_to_bigint(&mpi_dest, dest));
	mbedtls_mpi_free(&mpi_dest);
	mbedtls_mpi_free(&mpi_n);
	if (pop == &mpi_op)
		mbedtls_mpi_free(&mpi_op);
}
/*
 * TEE_BigIntInvMod
 */
void TEE_BigIntInvMod(TEE_BigInt *dest, const TEE_BigInt *op,
		      const TEE_BigInt *n)
{
	mpanum mpa_dest = (mpa_num_base *)dest;
	mpanum mpa_op = (mpa_num_base *)op;
	mpanum mpa_n = (mpa_num_base *)n;

	if (TEE_BigIntCmpS32(n, 2) < 0 || TEE_BigIntCmpS32(op, 0) == 0)
		TEE_BigInt_Panic("too small modulus or trying to invert zero");

	mpa_inv_mod(mpa_dest, mpa_op, mpa_n, mempool);
}
/*
 *  TEE_BigIntMulMod
 */
void TEE_BigIntMulMod(TEE_BigInt *dest, const TEE_BigInt *op1,
		      const TEE_BigInt *op2, const TEE_BigInt *n)
{
	mpanum mpa_dest = (mpa_num_base *)dest;
	mpanum mpa_op1 = (mpa_num_base *)op1;
	mpanum mpa_op2 = (mpa_num_base *)op2;
	mpanum mpa_n = (mpa_num_base *)n;
	mpanum tmp_dest;

	if (TEE_BigIntCmpS32(n, 2) < 0)
		TEE_BigInt_Panic("Modulus is too short");

	/*
	 * From the spec, mpa_dest must be of magnitude "mpa_n"
	 * But internal computations in mpa do not have such assumptions
	 * (as __mpa_div_q_r, where "r" must be of magnitude "op1",
	 * whereas GP provides a magnitude of "op2")
	 * This is a tempory variable is used, before storing the
	 * final result.
	 */
	mpa_alloc_static_temp_var(&tmp_dest, mempool);
	mpa_mul_mod(tmp_dest, mpa_op1, mpa_op2, mpa_n, mempool);
	if (mpa_cmp_short(tmp_dest, 0) < 0)
		mpa_add(tmp_dest, tmp_dest, mpa_n, mempool);
	mpa_copy(mpa_dest, tmp_dest);
	mpa_free_static_temp_var(&tmp_dest, mempool);
}
void TEE_BigIntMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n)
{
	if (TEE_BigIntCmpS32(n, 2) < 0)
		API_PANIC("Modulus is too short");

	bigint_binary(dest, op, n, mbedtls_mpi_mod_mpi);
}
/*
 * TEE_BigIntDiv
 */
void TEE_BigIntDiv(TEE_BigInt *dest_q, TEE_BigInt *dest_r,
		   const TEE_BigInt *op1, const TEE_BigInt *op2)
{
	mpanum mpa_dest_q = (mpa_num_base *)dest_q;
	mpanum mpa_dest_r = (mpa_num_base *)dest_r;
	mpanum mpa_op1 = (mpa_num_base *)op1;
	mpanum mpa_op2 = (mpa_num_base *)op2;

	if (TEE_BigIntCmpS32(op2, 0) == 0)
		TEE_BigInt_Panic("Divisor is zero");

	mpa_div(mpa_dest_q, mpa_dest_r, mpa_op1, mpa_op2, mempool);
}
/*
 * TEE_BigIntSubMod
 */
void TEE_BigIntSubMod(TEE_BigInt *dest, const TEE_BigInt *op1,
		      const TEE_BigInt *op2, const TEE_BigInt *n)
{
	mpanum mpa_dest = (mpa_num_base *)dest;
	mpanum mpa_op1 = (mpa_num_base *)op1;
	mpanum mpa_op2 = (mpa_num_base *)op2;
	mpanum mpa_n = (mpa_num_base *)n;

	if (TEE_BigIntCmpS32(n, 2) < 0)
		TEE_BigInt_Panic("Modulus is too short");

	mpa_sub_mod(mpa_dest, mpa_op1, mpa_op2, mpa_n, mempool);
	if (mpa_cmp_short(mpa_dest, 0) < 0)
		mpa_add(mpa_dest, mpa_dest, mpa_n, mempool);
}
static void bigint_binary_mod(TEE_BigInt *dest, const TEE_BigInt *op1,
			      const TEE_BigInt *op2, const TEE_BigInt *n,
			      int (*func)(mbedtls_mpi *X, const mbedtls_mpi *A,
					  const mbedtls_mpi *B))
{
	if (TEE_BigIntCmpS32(n, 2) < 0)
		API_PANIC("Modulus is too short");

	mbedtls_mpi mpi_dest;
	mbedtls_mpi mpi_op1;
	mbedtls_mpi mpi_op2;
	mbedtls_mpi mpi_n;
	mbedtls_mpi *pop1 = &mpi_op1;
	mbedtls_mpi *pop2 = &mpi_op2;
	mbedtls_mpi mpi_t;

	get_mpi(&mpi_dest, dest);
	get_mpi(&mpi_n, n);

	if (op1 == dest)
		pop1 = &mpi_dest;
	else
		get_mpi(&mpi_op1, op1);

	if (op2 == dest)
		pop2 = &mpi_dest;
	else if (op2 == op1)
		pop2 = pop1;
	else
		get_mpi(&mpi_op2, op2);

	get_mpi(&mpi_t, NULL);

	MPI_CHECK(func(&mpi_t, pop1, pop2));
	MPI_CHECK(mbedtls_mpi_mod_mpi(&mpi_dest, &mpi_t, &mpi_n));

	MPI_CHECK(copy_mpi_to_bigint(&mpi_dest, dest));
	mbedtls_mpi_free(&mpi_dest);
	if (pop1 == &mpi_op1)
		mbedtls_mpi_free(&mpi_op1);
	if (pop2 == &mpi_op2)
		mbedtls_mpi_free(&mpi_op2);
	mbedtls_mpi_free(&mpi_t);
}