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