xref: /optee_os/lib/libmbedtls/core/bignum.c (revision e2ec831cb07ed0099535c7c140cb6338aa62816a)
1000fae55SEdison Ai // SPDX-License-Identifier: BSD-2-Clause
2000fae55SEdison Ai /*
3000fae55SEdison Ai  * Copyright (C) 2018, ARM Limited
4000fae55SEdison Ai  * Copyright (C) 2019, Linaro Limited
5000fae55SEdison Ai  */
6000fae55SEdison Ai 
7000fae55SEdison Ai #include <assert.h>
8000fae55SEdison Ai #include <crypto/crypto.h>
9000fae55SEdison Ai #include <kernel/panic.h>
10000fae55SEdison Ai #include <mbedtls/bignum.h>
11000fae55SEdison Ai #include <stdlib.h>
12000fae55SEdison Ai #include <string.h>
13000fae55SEdison Ai #include <util.h>
14000fae55SEdison Ai 
15000fae55SEdison Ai #define ciL		(sizeof(mbedtls_mpi_uint))	/* chars in limb  */
16000fae55SEdison Ai #define biL		(ciL << 3)			/* bits  in limb  */
17000fae55SEdison Ai #define BITS_TO_LIMBS(i) ((i) / biL + ((i) % biL != 0))
18000fae55SEdison Ai 
crypto_bignum_num_bytes(struct bignum * a)19000fae55SEdison Ai size_t crypto_bignum_num_bytes(struct bignum *a)
20000fae55SEdison Ai {
21000fae55SEdison Ai 	assert(a != NULL);
22000fae55SEdison Ai 	return mbedtls_mpi_size((const mbedtls_mpi *)a);
23000fae55SEdison Ai }
24000fae55SEdison Ai 
crypto_bignum_num_bits(struct bignum * a)25000fae55SEdison Ai size_t crypto_bignum_num_bits(struct bignum *a)
26000fae55SEdison Ai {
27000fae55SEdison Ai 	assert(a != NULL);
28000fae55SEdison Ai 	return mbedtls_mpi_bitlen((const mbedtls_mpi *)a);
29000fae55SEdison Ai }
30000fae55SEdison Ai 
crypto_bignum_compare(struct bignum * a,struct bignum * b)31000fae55SEdison Ai int32_t crypto_bignum_compare(struct bignum *a, struct bignum *b)
32000fae55SEdison Ai {
33000fae55SEdison Ai 	int ret = 0;
34000fae55SEdison Ai 
35000fae55SEdison Ai 	assert(a != NULL);
36000fae55SEdison Ai 	assert(b != NULL);
37000fae55SEdison Ai 	ret = mbedtls_mpi_cmp_mpi((const mbedtls_mpi *)a,
38000fae55SEdison Ai 				  (const mbedtls_mpi *)b);
39000fae55SEdison Ai 	return CMP_TRILEAN(ret, 0);
40000fae55SEdison Ai }
41000fae55SEdison Ai 
crypto_bignum_bn2bin(const struct bignum * from,uint8_t * to)42000fae55SEdison Ai void crypto_bignum_bn2bin(const struct bignum *from, uint8_t *to)
43000fae55SEdison Ai {
44000fae55SEdison Ai 	size_t len = 0;
45000fae55SEdison Ai 
46000fae55SEdison Ai 	assert(from != NULL);
47000fae55SEdison Ai 	assert(to != NULL);
48000fae55SEdison Ai 	len = crypto_bignum_num_bytes((struct bignum *)from);
49000fae55SEdison Ai 	if (mbedtls_mpi_write_binary((mbedtls_mpi *)from, to, len))
50000fae55SEdison Ai 		panic();
51000fae55SEdison Ai }
52000fae55SEdison Ai 
crypto_bignum_bin2bn(const uint8_t * from,size_t fromsize,struct bignum * to)53000fae55SEdison Ai TEE_Result crypto_bignum_bin2bn(const uint8_t *from, size_t fromsize,
54000fae55SEdison Ai 			 struct bignum *to)
55000fae55SEdison Ai {
56000fae55SEdison Ai 	assert(from != NULL);
57000fae55SEdison Ai 	assert(to != NULL);
58000fae55SEdison Ai 	if (mbedtls_mpi_read_binary((mbedtls_mpi *)to, from, fromsize))
59000fae55SEdison Ai 		return TEE_ERROR_BAD_PARAMETERS;
60000fae55SEdison Ai 	return TEE_SUCCESS;
61000fae55SEdison Ai }
62000fae55SEdison Ai 
crypto_bignum_copy(struct bignum * to,const struct bignum * from)63000fae55SEdison Ai void crypto_bignum_copy(struct bignum *to, const struct bignum *from)
64000fae55SEdison Ai {
65000fae55SEdison Ai 	assert(from != NULL);
66000fae55SEdison Ai 	assert(to != NULL);
67000fae55SEdison Ai 	if (mbedtls_mpi_copy((mbedtls_mpi *)to, (const mbedtls_mpi *)from))
68000fae55SEdison Ai 		panic();
69000fae55SEdison Ai }
70000fae55SEdison Ai 
crypto_bignum_allocate(size_t size_bits)71000fae55SEdison Ai struct bignum *crypto_bignum_allocate(size_t size_bits)
72000fae55SEdison Ai {
73000fae55SEdison Ai 	mbedtls_mpi *bn = NULL;
74000fae55SEdison Ai 
75000fae55SEdison Ai 	if (size_bits > CFG_CORE_BIGNUM_MAX_BITS)
76000fae55SEdison Ai 		size_bits = CFG_CORE_BIGNUM_MAX_BITS;
77000fae55SEdison Ai 
78000fae55SEdison Ai 	bn = calloc(1, sizeof(mbedtls_mpi));
79000fae55SEdison Ai 	if (!bn)
80000fae55SEdison Ai 		return NULL;
81000fae55SEdison Ai 	mbedtls_mpi_init(bn);
82000fae55SEdison Ai 	if (mbedtls_mpi_grow(bn, BITS_TO_LIMBS(size_bits)) != 0) {
83000fae55SEdison Ai 		free(bn);
84000fae55SEdison Ai 		return NULL;
85000fae55SEdison Ai 	}
86000fae55SEdison Ai 
87000fae55SEdison Ai 	return (struct bignum *)bn;
88000fae55SEdison Ai }
89000fae55SEdison Ai 
crypto_bignum_free(struct bignum ** s)90*e2ec831cSJihwan Park void crypto_bignum_free(struct bignum **s)
91000fae55SEdison Ai {
92*e2ec831cSJihwan Park 	assert(s);
93*e2ec831cSJihwan Park 
94*e2ec831cSJihwan Park 	mbedtls_mpi_free((mbedtls_mpi *)*s);
95*e2ec831cSJihwan Park 	free(*s);
96*e2ec831cSJihwan Park 	*s = NULL;
97000fae55SEdison Ai }
98000fae55SEdison Ai 
crypto_bignum_clear(struct bignum * s)99000fae55SEdison Ai void crypto_bignum_clear(struct bignum *s)
100000fae55SEdison Ai {
101000fae55SEdison Ai 	mbedtls_mpi *bn = (mbedtls_mpi *)s;
102000fae55SEdison Ai 
103000fae55SEdison Ai 	memset(bn->p, 0, mbedtls_mpi_size((const mbedtls_mpi *)bn));
104000fae55SEdison Ai }
105