/* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TEE_ARITH_API_H #define TEE_ARITH_API_H /** * @addtogroup TeeTrusted * @{ * * @brief TEE(Trusted Excution Environment) API. * Provides security capability APIs such as trusted storage, encryption and decryption, * and trusted time for trusted application development. * * @since 12 */ /** * @file tee_arith_api.h * * @brief Provides APIs for operating big integers. * * @library NA * @kit TEEKit * @syscap SystemCapability.Tee.TeeClient * @since 12 * @version 1.0 */ #include #ifdef __cplusplus extern "C" { #endif typedef uint32_t TEE_BigInt; typedef uint32_t TEE_BigIntFMM; typedef uint32_t TEE_BigIntFMMContext; /** * @brief Obtains the size of the array of uint32_t values required to represent a BigInt. * * @param n Indicates the TEE_BigInt type. * * @return Returns the BigInt size obtained. * * @since 12 * @version 1.0 */ #define TEE_BigIntSizeInU32(n) ((((n) + 31) / 32) + 2) /** * @brief Obtains the size of the array of uint32_t values. * * @param modulusSizeInBits Indicates the modulus size, in bits. * * @return Returns the number of bytes required to store a TEE_BigIntFMM, * given a modulus of length modSizeInBits. * * @since 12 * @version 1.0 */ size_t TEE_BigIntFMMSizeInU32(size_t modulusSizeInBits); /** * @brief Obtains the size of an array of uint32_t values required to represent a fast modular context. * * @param modulusSizeInBits Indicates the modulus size, in bits. * * @return Returns the number of bytes required to store a TEE_BigIntFMMContext, * given a modulus of length modSizeInBits. * * @since 12 * @version 1.0 */ size_t TEE_BigIntFMMContextSizeInU32(size_t modulusSizeInBits); /** * @brief Initializes a TEE_BigInt. * * @param bigInt Indicates the pointer to the TEE_BigInt to initialize. * @param len Indicates the size of the memory pointed to by TEE_BigInt, in uint32_t. * * @since 12 * @version 1.0 */ void TEE_BigIntInit(TEE_BigInt *bigInt, size_t len); /** * @brief Calculates the necessary prerequisites for fast modular multiplication and stores them in a context. * * @param context Indicates the pointer to the TEE_BigIntFMMContext to initialize. * @param len Indicates the size of the memory pointed to by context, in uint32_t. * @param modulus Indicates the pointer to the modulus. * * @since 12 * @version 1.0 */ void TEE_BigIntInitFMMContext(TEE_BigIntFMMContext *context, size_t len, const TEE_BigInt *modulus); /** * @brief Calculates the necessary prerequisites for fast modular multiplication and stores them in a context. * * @param context Indicates the pointer to the TEE_BigIntFMMContext to initialize. * @param len Indicates the size of the memory pointed to by context, in uint32_t. * @param modulus Indicates the pointer to the modulus. * * @return Returns TEE_SUCCESS if the operation is successful. * Returns other values if the operation fails. * * @since 12 * @version 1.0 */ TEE_Result TEE_BigIntInitFMMContext1(TEE_BigIntFMMContext *context, size_t len, const TEE_BigInt *modulus); /** * @brief Initializes a TEE_BigIntFMM and sets its represented value to zero. * * @param bigIntFMM Indicates the pointer to the TEE_BigIntFMM to initialize. * @param len Indicates the size of the memory pointed to by bigIntFMM, in uint32_t. * * @since 12 * @version 1.0 */ void TEE_BigIntInitFMM(TEE_BigIntFMM *bigIntFMM, size_t len); /** * @brief Converts an octet string buffer into the TEE_BigInt format. * * @param dest Indicates the pointer to the TEE_BigInt that holds the result. * @param buffer Indicates the pointer to the buffer that holds the octet string representation of the integer. * @param bufferLen Indicates the buffer length, in bytes. * @param sign Indicates the sign of dest, which is set to the sign of sign. * * @return Returns TEE_SUCCESS if the operation is successful. * Returns TEE_ERROR_OVERFLOW if the memory allocated for dest is too small. * * @since 12 * @version 1.0 */ TEE_Result TEE_BigIntConvertFromOctetString(TEE_BigInt *dest, const uint8_t *buffer, size_t bufferLen, int32_t sign); /** * @brief Converts the absolute value of an integer in TEE_BigInt format into an octet string. * * @param buffer Indicates the pointer to the output buffer that holds the converted octet string representation * of the integer. * @param bufferLen Indicates the pointer to the buffer length, in bytes. * @param bigInt Indicates the pointer to the integer to convert. * * @return Returns TEE_SUCCESS if the operation is successful. * Returns TEE_ERROR_SHORT_BUFFER if the output buffer is too small to hold the octet string. * * @since 12 * @version 1.0 */ TEE_Result TEE_BigIntConvertToOctetString(void *buffer, size_t *bufferLen, const TEE_BigInt *bigInt); /** * @brief Sets dest to the value shortVal. * * @param dest Indicates the pointer to the TEE_BigInt that holds the result. * @param shortVal Indicates the value to set. * * @since 12 * @version 1.0 */ void TEE_BigIntConvertFromS32(TEE_BigInt *dest, int32_t shortVal); /** * @brief Sets dest to the value of src, including the sign of src. * * @param dest Indicates the pointer to the int32_t that holds the result. * @param src Indicates the pointer to the value to set. * * @return Returns TEE_SUCCESS if the operation is successful. * Returns TEE_ERROR_OVERFLOW if src does not fit within an int32_t. * * @since 12 * @version 1.0 */ TEE_Result TEE_BigIntConvertToS32(int32_t *dest, const TEE_BigInt *src); /** * @brief Checks whether op1 > op2, op1 == op2, or op1 < op2. * * @param op1 Indicates the pointer to the first operand. * @param op2 Indicates the pointer to the second operand. * * @return Returns 0 if op1 == op2. * Returns a positive number if op1 > op2. * * @since 12 * @version 1.0 */ int32_t TEE_BigIntCmp(const TEE_BigInt *op1, const TEE_BigInt *op2); /** * @brief Checks whether op > shortVal, op == shortVal, or op < shortVal. * * @param op Indicates the pointer to the first operand. * @param shortVal Indicates the pointer to the second operand. * * @return Returns 0 if op1 == shortVal. * Returns a positive number if op1 > shortVal. * * @since 12 * @version 1.0 */ int32_t TEE_BigIntCmpS32(const TEE_BigInt *op, int32_t shortVal); /** * @brief Computes |dest| = |op| >> bits. * * @param dest Indicates the pointer to the TEE_BigInt that holds the shifted result. * @param op Indicates the pointer to the operand to be shifted. * @param bits Indicates the number of bits to shift. * * @since 12 * @version 1.0 */ void TEE_BigIntShiftRight(TEE_BigInt *dest, const TEE_BigInt *op, size_t bits); /** * @brief Obtains the bitIndex bit of the natural binary representation of |src|. * * @param src Indicates the pointer to the integer. * @param bitIndex Indicates the offset of the bit to read, starting from offset 0 of the least significant bit. * * @return Returns the Boolean value of bitIndexth in |src|. The value true represents a 1, * and false represents a 0. * * @since 12 * @version 1.0 */ bool TEE_BigIntGetBit(const TEE_BigInt *src, uint32_t bitIndex); /** * @brief Obtains the number of bits in the natural binary representation of |src|, * that is, the magnitude of src. * * @param src Indicates the pointer to the integer. * * @return Returns 0 if src is 0. * Returns the number of bits in the natural binary representation of src. * * @since 12 * @version 1.0 */ uint32_t TEE_BigIntGetBitCount(const TEE_BigInt *src); #if defined(API_LEVEL) && (API_LEVEL >= API_LEVEL1_2) /** * @brief Sets the first bit of bitIndex in the natural binary representation of op to * 1 or 0. * * @param op Indicates the pointer to the integer. * @param bitIndex Indicates the offset of the bit to set, starting from offset 0 of the least significant bit. * @param value Indicates the bit value to set. The value true represents a 1, and the value false * represents a 0. * * @return Returns TEE_SUCCESS if the operation is successful. * Returns TEE_ERROR_OVERFLOW bitIndexth if the bitIndexth bit is larger than the allocated bit * length of op. * * @since 12 * @version 1.0 */ TEE_Result TEE_BigIntSetBit(TEE_BigInt *op, uint32_t bitIndex, bool value); /** * @brief Assigns the value of src to dest. * * @param dest Indicates the pointer to the TEE_BigInt to be assigned. * @param src Indicates the pointer to the source operand. * * @return Returns TEE_SUCCESS if the operation is successful. * Returns TEE_ERROR_OVERFLOW if the dest operand cannot hold the value of src. * * @since 12 * @version 1.0 */ TEE_Result TEE_BigIntAssign(TEE_BigInt *dest, const TEE_BigInt *src); /** * @brief Assigns the value of src to dest. * * @param dest Indicates the pointer to the TEE_BigInt to be assigned. * @param src Indicates the pointer to the source operand. * * @return Returns TEE_SUCCESS if the operation is successful. * Returns TEE_ERROR_OVERFLOW if the dest operand cannot hold the value of src. * * @since 12 * @version 1.0 */ TEE_Result TEE_BigIntAbs(TEE_BigInt *dest, const TEE_BigInt *src); #endif /* API_LEVEL */ /** * @brief Computes dest = op1 + op2. * * @param dest Indicates the pointer to the TEE_BigInt that holds the sum of op1 and op2. * @param op1 Indicates the pointer to the first operand. * @param op2 Indicates the pointer to the second operand. * * @since 12 * @version 1.0 */ void TEE_BigIntAdd(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2); /** * @brief Computes dest = op1 – op2. * * @param dest Indicates the pointer to the TEE_BigInt that holds the difference between op1 * and op2. * @param op1 Indicates the pointer to the first operand. * @param op2 Indicates the pointer to the second operand. * * @since 12 * @version 1.0 */ void TEE_BigIntSub(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2); /** * @brief Negates an operand: dest = –op. * * @param dest Indicates the pointer to the TEE_BigInt that holds the result –op. * @param op Indicates the pointer to the operand to be negated. * * @since 12 * @version 1.0 */ void TEE_BigIntNeg(TEE_BigInt *dest, const TEE_BigInt *op); /** * @brief Computes dest = op1 * op2. * * @param dest Indicates the pointer to the TEE_BigInt that holds the product of op1 and op2. * @param op1 Indicates the pointer to the first operand. * @param op2 Indicates the pointer to the second operand. * * @since 12 * @version 1.0 */ void TEE_BigIntMul(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2); /** * @brief Computes dest = op * op. * * @param dest Indicates the pointer to the TEE_BigInt that holds the result op * op. * @param op Indicates the pointer to the operand to be squared. * * @since 12 * @version 1.0 */ void TEE_BigIntSquare(TEE_BigInt *dest, const TEE_BigInt *op); /** * @brief Computes dest_r and dest_q to make op1 = dest_q* op2 + dest_r. * * @param dest_q Indicates the pointer to the TEE_BigInt that holds the quotient. * @param dest_r Indicates the pointer to the TEE_BigInt that holds the remainder. * @param op1 Indicates the pointer to the first operand, which is the dividend. * @param op2 Indicates the pointer to the second operand, which is the divisor. * * @return Returns TEE_SUCCESS if the operation is successful. * Returns TEE_ERROR_BAD_PARAMETERS if at least one parameter is null. * * @since 12 * @version 1.0 */ void TEE_BigIntDiv(TEE_BigInt *dest_q, TEE_BigInt *dest_r, const TEE_BigInt *op1, const TEE_BigInt *op2); /** * @brief Computes dest = op (mod n) to make 0 <= dest < n. * * @param dest Indicates the pointer to the TEE_BigInt that holds the result op (mod n). * @param op Indicates the pointer to the operand to be reduced mod n. * @param n [IN] Indicates the pointer to the modulus, which must be greater than 1. * * @since 12 * @version 1.0 */ void TEE_BigIntMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n); /** * @brief Computes dest = (op1 + op2) (mod n). * * @param dest Indicates the pointer to the TEE_BigInt that holds the result op (op1 + op2)(mod n). * @param op1 Indicates the pointer to the first operand. * @param op2 Indicates the pointer to the second operand. * @param n Indicates the pointer to the modulus, which must be greater than 1. * * @since 12 * @version 1.0 */ void TEE_BigIntAddMod(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n); /** * @brief Computes dest = (op1 – op2) (mod n). * * @param dest Indicates the pointer to the TEE_BigInt that holds the result op (op1 – op2)(mod n). * @param op1 Indicates the pointer to the first operand. * @param op2 Indicates the pointer to the second operand. * @param n Indicates the pointer to the modulus, which must be greater than 1. * * @since 12 * @version 1.0 */ void TEE_BigIntSubMod(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n); /** * @brief Computes dest = (op1* op2)(mod n). * * @param dest Indicates the pointer to the TEE_BigInt that holds the result op (op1 * op2)(mod n). * @param op1 Indicates the pointer to the first operand. * @param op2 Indicates the pointer to the second operand. * @param n Indicates the pointer to the modulus, which must be greater than 1. * * @since 12 * @version 1.0 */ void TEE_BigIntMulMod(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n); /** * @brief Computes dest = (op * op) (mod n). * * @param dest Indicates the pointer to the TEE_BigInt that holds the result op (op * op)(mod n). * @param op Indicates the pointer to the operand. * @param n [IN] Indicates the pointer to the modulus, which must be greater than 1. * * @since 12 * @version 1.0 */ void TEE_BigIntSquareMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n); /** * @brief Computes dest to make dest* op = 1 (mod n). * * @param dest Indicates the pointer to the TEE_BigInt that holds the result (op^–1)(mod n). * @param op Indicates the pointer to the operand. * @param n [IN] Indicates the pointer to the modulus, which must be greater than 1. * * @since 12 * @version 1.0 */ void TEE_BigIntInvMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n); /** * @brief Checks whether gcd(op1, op2) == 1. * * @param op1 Indicates the pointer to the first operand. * @param op2 Indicates the pointer to the second operand. * * @return Returns true if gcd(op1, op2) == 1. * Returns false if gcd(op1, op2) != 1. * * @since 12 * @version 1.0 */ bool TEE_BigIntRelativePrime(const TEE_BigInt *op1, const TEE_BigInt *op2); /** * @brief Computes the greatest common divisor of op1 and op2. * * @param gcd Indicates the pointer to the TEE_BigInt that holds the greatest common divisor of op1 * and op2. * @param u Indicates the pointer to the TEE_BigInt that holds the first coefficient. * @param v Indicates the pointer to the TEE_BigInt that holds the second coefficient. * @param op1 Indicates the pointer to the first operand. * @param op2 Indicates the pointer to the second operand. * * @since 12 * @version 1.0 */ void TEE_BigIntComputeExtendedGcd(TEE_BigInt *gcd, TEE_BigInt *u, TEE_BigInt *v, const TEE_BigInt *op1, const TEE_BigInt *op2); /** * @brief Performs a probabilistic primality test on op. * * @param op Indicates the pointer to the candidate number that is tested for primality. * @param confidenceLevel Indicates the expected confidence level for a non-conclusive test. * * @return Returns 0 if op is a composite number. * Returns 1 if op is a prime number. * Returns –1 if the test is non-conclusive but the probability that op is composite is * less than 2^(-confidenceLevel). * * @since 12 * @version 1.0 */ int32_t TEE_BigIntIsProbablePrime(const TEE_BigInt *op, uint32_t confidenceLevel); /** * @brief Converts src into a representation suitable for doing fast modular multiplication. * * @param dest Indicates the pointer to an initialized TEE_BigIntFMM memory area. * @param src Indicates the pointer to the TEE_BigInt to convert. * @param n Indicates the pointer to the modulus. * @param context Indicates the pointer to the context that is previously initialized using * {@link TEE_BigIntInitFMMContext1}. * * @since 12 * @version 1.0 */ void TEE_BigIntConvertToFMM(TEE_BigIntFMM *dest, const TEE_BigInt *src, const TEE_BigInt *n, const TEE_BigIntFMMContext *context); /** * @brief Converts src in the fast modular multiplication representation back to a * TEE_BigInt representation. * * @param dest Indicates the pointer to an initialized TEE_BigIntFMM memory area to store the converted result. * @param src Indicates the pointer to a TEE_BigIntFMM holding the value in the fast modular multiplication * representation. * @param n Indicates the pointer to the modulus. * @param context Indicates the pointer to the context that is previously initialized using * {@link TEE_BigIntInitFMMContext1}. * * @since 12 * @version 1.0 */ void TEE_BigIntConvertFromFMM(TEE_BigInt *dest, const TEE_BigIntFMM *src, const TEE_BigInt *n, const TEE_BigIntFMMContext *context); /** * @brief Computes dest = op1* op2 in the fast modular multiplication representation. * * @param dest Indicates the pointer to the TEE_BigIntFMM that holds the result op1* op2. * @param op1 Indicates the pointer to the first operand. * @param op2 Indicates the pointer to the second operand. * @param n Indicates the pointer to the modulus. * @param context Indicates the pointer to the context that is previously initialized using * {@link TEE_BigIntInitFMMContext1}. * * @since 12 * @version 1.0 */ void TEE_BigIntComputeFMM(TEE_BigIntFMM *dest, const TEE_BigIntFMM *op1, const TEE_BigIntFMM *op2, const TEE_BigInt *n, const TEE_BigIntFMMContext *context); /** * @brief Computes dest = (op1 ^ op2)(mod n). * * @param des Indicates the pointer to the TEE_BigInt that holds the result (op1 ^ op2)(mod n). * @param op1 Indicates the pointer to the first operand. * @param op2 Indicates the pointer to the second operand. * @param n Indicates the pointer to the modulus. * @param context Indicates the pointer to the context that is previously initialized using * {@link TEE_BigIntInitFMMContext1} or initialized to null. * * @return Returns TEE_SUCCESS if the operation is successful. * Returns TEE_ERROR_NOT_SUPPORTED if the value of n is not supported. * * @since 12 * @version 1.0 */ TEE_Result TEE_BigIntExpMod(TEE_BigInt *des, TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n, TEE_BigIntFMMContext *context); #ifdef __cplusplus } #endif /** @} */ #endif