1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2018, ARM Limited 4 * Copyright (C) 2019, Linaro Limited 5 */ 6 7 #include <assert.h> 8 #include <crypto/crypto.h> 9 #include <kernel/panic.h> 10 #include <mbedtls/bignum.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <util.h> 14 15 #define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ 16 #define biL (ciL << 3) /* bits in limb */ 17 #define BITS_TO_LIMBS(i) ((i) / biL + ((i) % biL != 0)) 18 19 size_t crypto_bignum_num_bytes(struct bignum *a) 20 { 21 assert(a != NULL); 22 return mbedtls_mpi_size((const mbedtls_mpi *)a); 23 } 24 25 size_t crypto_bignum_num_bits(struct bignum *a) 26 { 27 assert(a != NULL); 28 return mbedtls_mpi_bitlen((const mbedtls_mpi *)a); 29 } 30 31 int32_t crypto_bignum_compare(struct bignum *a, struct bignum *b) 32 { 33 int ret = 0; 34 35 assert(a != NULL); 36 assert(b != NULL); 37 ret = mbedtls_mpi_cmp_mpi((const mbedtls_mpi *)a, 38 (const mbedtls_mpi *)b); 39 return CMP_TRILEAN(ret, 0); 40 } 41 42 void crypto_bignum_bn2bin(const struct bignum *from, uint8_t *to) 43 { 44 size_t len = 0; 45 46 assert(from != NULL); 47 assert(to != NULL); 48 len = crypto_bignum_num_bytes((struct bignum *)from); 49 if (mbedtls_mpi_write_binary((mbedtls_mpi *)from, to, len)) 50 panic(); 51 } 52 53 TEE_Result crypto_bignum_bin2bn(const uint8_t *from, size_t fromsize, 54 struct bignum *to) 55 { 56 assert(from != NULL); 57 assert(to != NULL); 58 if (mbedtls_mpi_read_binary((mbedtls_mpi *)to, from, fromsize)) 59 return TEE_ERROR_BAD_PARAMETERS; 60 return TEE_SUCCESS; 61 } 62 63 void crypto_bignum_copy(struct bignum *to, const struct bignum *from) 64 { 65 assert(from != NULL); 66 assert(to != NULL); 67 if (mbedtls_mpi_copy((mbedtls_mpi *)to, (const mbedtls_mpi *)from)) 68 panic(); 69 } 70 71 struct bignum *crypto_bignum_allocate(size_t size_bits) 72 { 73 mbedtls_mpi *bn = NULL; 74 75 if (size_bits > CFG_CORE_BIGNUM_MAX_BITS) 76 size_bits = CFG_CORE_BIGNUM_MAX_BITS; 77 78 bn = calloc(1, sizeof(mbedtls_mpi)); 79 if (!bn) 80 return NULL; 81 mbedtls_mpi_init(bn); 82 if (mbedtls_mpi_grow(bn, BITS_TO_LIMBS(size_bits)) != 0) { 83 free(bn); 84 return NULL; 85 } 86 87 return (struct bignum *)bn; 88 } 89 90 void crypto_bignum_free(struct bignum **s) 91 { 92 assert(s); 93 94 mbedtls_mpi_free((mbedtls_mpi *)*s); 95 free(*s); 96 *s = NULL; 97 } 98 99 void crypto_bignum_clear(struct bignum *s) 100 { 101 mbedtls_mpi *bn = (mbedtls_mpi *)s; 102 103 memset(bn->p, 0, mbedtls_mpi_size((const mbedtls_mpi *)bn)); 104 } 105