예제 #1
0
파일: mpi_desc.c 프로젝트: OP-TEE/optee_os
/* modi */
static int modi(void *a, unsigned long b, unsigned long *c)
{
	mbedtls_mpi bn_b;
	mbedtls_mpi bn_c;
	int res = 0;

	mbedtls_mpi_init_mempool(&bn_b);
	mbedtls_mpi_init_mempool(&bn_c);

	res = set_int(&bn_b, b);
	if (res)
		return res;

	res = mbedtls_mpi_mod_mpi(&bn_c, &bn_b, a);
	if (!res)
		*c = get_int(&bn_c);

	mbedtls_mpi_free(&bn_b);
	mbedtls_mpi_free(&bn_c);

	if (res)
		return CRYPT_MEM;

	return CRYPT_OK;
}
/*
 * Initializes a MPI.
 *
 * A temporary MPI is allocated and if a bigInt is supplied the MPI is
 * initialized with the value of the bigInt.
 */
static void get_mpi(mbedtls_mpi *mpi, const TEE_BigInt *bigInt)
{
	/*
	 * The way the GP spec is defining the bignums it's
	 * difficult/tricky to do it using 64-bit arithmetics given that
	 * we'd need 64-bit alignment of the data as well.
	 */
	COMPILE_TIME_ASSERT(sizeof(mbedtls_mpi_uint) == sizeof(uint32_t));

	/*
	 * The struct bigint_hdr is the overhead added to the bigint and
	 * is required to take exactly 2 uint32_t.
	 */
	COMPILE_TIME_ASSERT(sizeof(struct bigint_hdr) ==
			    sizeof(uint32_t) * BIGINT_HDR_SIZE_IN_U32);

	mbedtls_mpi_init_mempool(mpi);

	if (bigInt) {
		const struct bigint_hdr *hdr = (struct bigint_hdr *)bigInt;
		const mbedtls_mpi_uint *p = (const mbedtls_mpi_uint *)(hdr + 1);
		size_t n = hdr->nblimbs;

		/* Trim of eventual insignificant zeroes */
		while (n && !p[n - 1])
			n--;

		MPI_CHECK(mbedtls_mpi_grow(mpi, n));
		mpi->s = hdr->sign;
		memcpy(mpi->p, p, n * sizeof(mbedtls_mpi_uint));
	}
}
예제 #3
0
파일: mpi_desc.c 프로젝트: OP-TEE/optee_os
static int init(void **a)
{
	mbedtls_mpi *bn = mempool_alloc(mbedtls_mpi_mempool, sizeof(*bn));

	if (!bn)
		return CRYPT_MEM;

	mbedtls_mpi_init_mempool(bn);
	*a = bn;
	return CRYPT_OK;
}
예제 #4
0
파일: mpi_desc.c 프로젝트: OP-TEE/optee_os
/* reduce */
static int montgomery_reduce(void *a, void *b, void *c)
{
	mbedtls_mpi A;
	mbedtls_mpi *N = b;
	mbedtls_mpi_uint *mm = c;
	mbedtls_mpi T;
	int ret = CRYPT_MEM;

	mbedtls_mpi_init_mempool(&T);
	mbedtls_mpi_init_mempool(&A);

	if (mbedtls_mpi_grow(&T, (N->n + 1) * 2))
		goto out;

	if (mbedtls_mpi_cmp_mpi(a, N) > 0) {
		if (mbedtls_mpi_mod_mpi(&A, a, N))
			goto out;
	} else {
		if (mbedtls_mpi_copy(&A, a))
			goto out;
	}

	if (mbedtls_mpi_grow(&A, N->n + 1))
		goto out;

	if (mbedtls_mpi_montred(&A, N, *mm, &T))
		goto out;

	if (mbedtls_mpi_copy(a, &A))
		goto out;

	ret = CRYPT_OK;
out:
	mbedtls_mpi_free(&A);
	mbedtls_mpi_free(&T);

	return ret;
}
예제 #5
0
파일: mpi_desc.c 프로젝트: OP-TEE/optee_os
static int mulmod(void *a, void *b, void *c, void *d)
{
	int res;
	mbedtls_mpi ta;
	mbedtls_mpi tb;

	mbedtls_mpi_init_mempool(&ta);
	mbedtls_mpi_init_mempool(&tb);

	res = mod(a, c, &ta);
	if (res)
		goto out;
	res = mod(b, c, &tb);
	if (res)
		goto out;
	res = mul(&ta, &tb, d);
	if (res)
		goto out;
	res = mod(d, c, d);
out:
	mbedtls_mpi_free(&ta);
	mbedtls_mpi_free(&tb);
	return res;
}
예제 #6
0
파일: mpi_desc.c 프로젝트: OP-TEE/optee_os
/* lcm */
static int lcm(void *a, void *b, void *c)
{
	int res = CRYPT_MEM;
	mbedtls_mpi tmp;

	mbedtls_mpi_init_mempool(&tmp);
	if (mbedtls_mpi_mul_mpi(&tmp, a, b))
		goto out;

	if (mbedtls_mpi_gcd(c, a, b))
		goto out;

	/* We use the following equality: gcd(a, b) * lcm(a, b) = a * b */
	res = divide(&tmp, c, c, NULL);
out:
	mbedtls_mpi_free(&tmp);
	return res;
}
예제 #7
0
파일: mpi_desc.c 프로젝트: OP-TEE/optee_os
/*
 * This function calculates:
 *  d = a^b mod c
 *
 * @a: base
 * @b: exponent
 * @c: modulus
 * @d: destination
 */
static int exptmod(void *a, void *b, void *c, void *d)
{
	int res;

	if (d == a || d == b || d == c) {
		mbedtls_mpi dest;

		mbedtls_mpi_init_mempool(&dest);
		res = mbedtls_mpi_exp_mod(&dest, a, b, c, NULL);
		if (!res)
			res = mbedtls_mpi_copy(d, &dest);
		mbedtls_mpi_free(&dest);
	} else {
		res = mbedtls_mpi_exp_mod(d, a, b, c, NULL);
	}

	if (res)
		return CRYPT_MEM;
	else
		return CRYPT_OK;
}
예제 #8
0
/*
 * Initializes a MPI.
 *
 * If a bigint is supplied it's initialized with the value of the bigint
 * and changes will be written back completely with a call to put_mpi().
 * The bigint dictates the size of the MPI which will be fixed to this
 * size.
 *
 * If no bigint is supplied a temporary MPI is allocated instead which will
 * be freed by put_mpi().
 */
static void get_mpi(mbedtls_mpi *mpi, TEE_BigInt *bigInt)
{
	/*
	 * The way the GP spec is defining the bignums it's
	 * difficult/tricky to do it using 64-bit arithmetics given that
	 * we'd need 64-bit alignment of the data as well.
	 */
	COMPILE_TIME_ASSERT(sizeof(mbedtls_mpi_uint) == sizeof(uint32_t));

	/*
	 * The struct bigint_hdr is the overhead added to the bigint and
	 * is required to take exactly 2 uint32_t.
	 */
	COMPILE_TIME_ASSERT(sizeof(struct bigint_hdr) ==
			    sizeof(uint32_t) * BIGINT_HDR_SIZE_IN_U32);

	if (bigInt)
		init_static_mpi(mpi, bigInt);
	else
		mbedtls_mpi_init_mempool(mpi);
}
예제 #9
0
파일: mpi_desc.c 프로젝트: OP-TEE/optee_os
static int compare_d(void *a, unsigned long b)
{
	unsigned long v = b;
	unsigned int shift = 31;
	uint32_t mask = BIT(shift) - 1;
	mbedtls_mpi bn;

	mbedtls_mpi_init_mempool(&bn);
	while (true) {
		mbedtls_mpi_add_int(&bn, &bn, v & mask);
		v >>= shift;
		if (!v)
			break;
		mbedtls_mpi_shift_l(&bn, shift);
	}

	int ret = compare(a, &bn);

	mbedtls_mpi_free(&bn);

	return ret;
}