Imported more library files
Not compiling currently
This commit is contained in:
2294
Libs/util/third_party/mbedtls/library/aes.c
vendored
Normal file
2294
Libs/util/third_party/mbedtls/library/aes.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
684
Libs/util/third_party/mbedtls/library/alignment.h
vendored
Normal file
684
Libs/util/third_party/mbedtls/library/alignment.h
vendored
Normal file
@@ -0,0 +1,684 @@
|
||||
/**
|
||||
* \file alignment.h
|
||||
*
|
||||
* \brief Utility code for dealing with unaligned memory accesses
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_LIBRARY_ALIGNMENT_H
|
||||
#define MBEDTLS_LIBRARY_ALIGNMENT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory
|
||||
* accesses are known to be efficient.
|
||||
*
|
||||
* All functions defined here will behave correctly regardless, but might be less
|
||||
* efficient when this is not defined.
|
||||
*/
|
||||
#if defined(__ARM_FEATURE_UNALIGNED) \
|
||||
|| defined(MBEDTLS_ARCH_IS_X86) || defined(MBEDTLS_ARCH_IS_X64) \
|
||||
|| defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
|
||||
/*
|
||||
* __ARM_FEATURE_UNALIGNED is defined where appropriate by armcc, gcc 7, clang 9
|
||||
* (and later versions) for Arm v7 and later; all x86 platforms should have
|
||||
* efficient unaligned access.
|
||||
*
|
||||
* https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#alignment
|
||||
* specifies that on Windows-on-Arm64, unaligned access is safe (except for uncached
|
||||
* device memory).
|
||||
*/
|
||||
#define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS
|
||||
#endif
|
||||
|
||||
#if defined(__IAR_SYSTEMS_ICC__) && \
|
||||
(defined(MBEDTLS_ARCH_IS_ARM64) || defined(MBEDTLS_ARCH_IS_ARM32) \
|
||||
|| defined(__ICCRX__) || defined(__ICCRL78__) || defined(__ICCRISCV__))
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
#define MBEDTLS_POP_IAR_LANGUAGE_PRAGMA
|
||||
/* IAR recommend this technique for accessing unaligned data in
|
||||
* https://www.iar.com/knowledge/support/technical-notes/compiler/accessing-unaligned-data
|
||||
* This results in a single load / store instruction (if unaligned access is supported).
|
||||
* According to that document, this is only supported on certain architectures.
|
||||
*/
|
||||
#define UINT_UNALIGNED
|
||||
typedef uint16_t __packed mbedtls_uint16_unaligned_t;
|
||||
typedef uint32_t __packed mbedtls_uint32_unaligned_t;
|
||||
typedef uint64_t __packed mbedtls_uint64_unaligned_t;
|
||||
#elif defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 40504) && \
|
||||
((MBEDTLS_GCC_VERSION < 60300) || (!defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)))
|
||||
/*
|
||||
* gcc may generate a branch to memcpy for calls like `memcpy(dest, src, 4)` rather than
|
||||
* generating some LDR or LDRB instructions (similar for stores).
|
||||
*
|
||||
* This is architecture dependent: x86-64 seems fine even with old gcc; 32-bit Arm
|
||||
* is affected. To keep it simple, we enable for all architectures.
|
||||
*
|
||||
* For versions of gcc < 5.4.0 this issue always happens.
|
||||
* For gcc < 6.3.0, this issue happens at -O0
|
||||
* For all versions, this issue happens iff unaligned access is not supported.
|
||||
*
|
||||
* For gcc 4.x, this implementation will generate byte-by-byte loads even if unaligned access is
|
||||
* supported, which is correct but not optimal.
|
||||
*
|
||||
* For performance (and code size, in some cases), we want to avoid the branch and just generate
|
||||
* some inline load/store instructions since the access is small and constant-size.
|
||||
*
|
||||
* The manual states:
|
||||
* "The packed attribute specifies that a variable or structure field should have the smallest
|
||||
* possible alignment—one byte for a variable"
|
||||
* https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Variable-Attributes.html
|
||||
*
|
||||
* Previous implementations used __attribute__((__aligned__(1)), but had issues with a gcc bug:
|
||||
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94662
|
||||
*
|
||||
* Tested with several versions of GCC from 4.5.0 up to 13.2.0
|
||||
* We don't enable for older than 4.5.0 as this has not been tested.
|
||||
*/
|
||||
#define UINT_UNALIGNED_STRUCT
|
||||
typedef struct {
|
||||
uint16_t x;
|
||||
} __attribute__((packed)) mbedtls_uint16_unaligned_t;
|
||||
typedef struct {
|
||||
uint32_t x;
|
||||
} __attribute__((packed)) mbedtls_uint32_unaligned_t;
|
||||
typedef struct {
|
||||
uint64_t x;
|
||||
} __attribute__((packed)) mbedtls_uint64_unaligned_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We try to force mbedtls_(get|put)_unaligned_uintXX to be always inline, because this results
|
||||
* in code that is both smaller and faster. IAR and gcc both benefit from this when optimising
|
||||
* for size.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Read the unsigned 16 bits integer from the given address, which need not
|
||||
* be aligned.
|
||||
*
|
||||
* \param p pointer to 2 bytes of data
|
||||
* \return Data at the given address
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline uint16_t mbedtls_get_unaligned_uint16(const void *p)
|
||||
{
|
||||
uint16_t r;
|
||||
#if defined(UINT_UNALIGNED)
|
||||
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
|
||||
r = *p16;
|
||||
#elif defined(UINT_UNALIGNED_STRUCT)
|
||||
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
|
||||
r = p16->x;
|
||||
#else
|
||||
memcpy(&r, p, sizeof(r));
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the unsigned 16 bits integer to the given address, which need not
|
||||
* be aligned.
|
||||
*
|
||||
* \param p pointer to 2 bytes of data
|
||||
* \param x data to write
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x)
|
||||
{
|
||||
#if defined(UINT_UNALIGNED)
|
||||
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
|
||||
*p16 = x;
|
||||
#elif defined(UINT_UNALIGNED_STRUCT)
|
||||
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
|
||||
p16->x = x;
|
||||
#else
|
||||
memcpy(p, &x, sizeof(x));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the unsigned 32 bits integer from the given address, which need not
|
||||
* be aligned.
|
||||
*
|
||||
* \param p pointer to 4 bytes of data
|
||||
* \return Data at the given address
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
|
||||
{
|
||||
uint32_t r;
|
||||
#if defined(UINT_UNALIGNED)
|
||||
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
|
||||
r = *p32;
|
||||
#elif defined(UINT_UNALIGNED_STRUCT)
|
||||
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
|
||||
r = p32->x;
|
||||
#else
|
||||
memcpy(&r, p, sizeof(r));
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the unsigned 32 bits integer to the given address, which need not
|
||||
* be aligned.
|
||||
*
|
||||
* \param p pointer to 4 bytes of data
|
||||
* \param x data to write
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
|
||||
{
|
||||
#if defined(UINT_UNALIGNED)
|
||||
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
|
||||
*p32 = x;
|
||||
#elif defined(UINT_UNALIGNED_STRUCT)
|
||||
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
|
||||
p32->x = x;
|
||||
#else
|
||||
memcpy(p, &x, sizeof(x));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the unsigned 64 bits integer from the given address, which need not
|
||||
* be aligned.
|
||||
*
|
||||
* \param p pointer to 8 bytes of data
|
||||
* \return Data at the given address
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline uint64_t mbedtls_get_unaligned_uint64(const void *p)
|
||||
{
|
||||
uint64_t r;
|
||||
#if defined(UINT_UNALIGNED)
|
||||
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
|
||||
r = *p64;
|
||||
#elif defined(UINT_UNALIGNED_STRUCT)
|
||||
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
|
||||
r = p64->x;
|
||||
#else
|
||||
memcpy(&r, p, sizeof(r));
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the unsigned 64 bits integer to the given address, which need not
|
||||
* be aligned.
|
||||
*
|
||||
* \param p pointer to 8 bytes of data
|
||||
* \param x data to write
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
|
||||
{
|
||||
#if defined(UINT_UNALIGNED)
|
||||
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
|
||||
*p64 = x;
|
||||
#elif defined(UINT_UNALIGNED_STRUCT)
|
||||
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
|
||||
p64->x = x;
|
||||
#else
|
||||
memcpy(p, &x, sizeof(x));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_POP_IAR_LANGUAGE_PRAGMA)
|
||||
#pragma language=restore
|
||||
#endif
|
||||
|
||||
/** Byte Reading Macros
|
||||
*
|
||||
* Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
|
||||
* byte from x, where byte 0 is the least significant byte.
|
||||
*/
|
||||
#define MBEDTLS_BYTE_0(x) ((uint8_t) ((x) & 0xff))
|
||||
#define MBEDTLS_BYTE_1(x) ((uint8_t) (((x) >> 8) & 0xff))
|
||||
#define MBEDTLS_BYTE_2(x) ((uint8_t) (((x) >> 16) & 0xff))
|
||||
#define MBEDTLS_BYTE_3(x) ((uint8_t) (((x) >> 24) & 0xff))
|
||||
#define MBEDTLS_BYTE_4(x) ((uint8_t) (((x) >> 32) & 0xff))
|
||||
#define MBEDTLS_BYTE_5(x) ((uint8_t) (((x) >> 40) & 0xff))
|
||||
#define MBEDTLS_BYTE_6(x) ((uint8_t) (((x) >> 48) & 0xff))
|
||||
#define MBEDTLS_BYTE_7(x) ((uint8_t) (((x) >> 56) & 0xff))
|
||||
|
||||
/*
|
||||
* Detect GCC built-in byteswap routines
|
||||
*/
|
||||
#if defined(__GNUC__) && defined(__GNUC_PREREQ)
|
||||
#if __GNUC_PREREQ(4, 8)
|
||||
#define MBEDTLS_BSWAP16 __builtin_bswap16
|
||||
#endif /* __GNUC_PREREQ(4,8) */
|
||||
#if __GNUC_PREREQ(4, 3)
|
||||
#define MBEDTLS_BSWAP32 __builtin_bswap32
|
||||
#define MBEDTLS_BSWAP64 __builtin_bswap64
|
||||
#endif /* __GNUC_PREREQ(4,3) */
|
||||
#endif /* defined(__GNUC__) && defined(__GNUC_PREREQ) */
|
||||
|
||||
/*
|
||||
* Detect Clang built-in byteswap routines
|
||||
*/
|
||||
#if defined(__clang__) && defined(__has_builtin)
|
||||
#if __has_builtin(__builtin_bswap16) && !defined(MBEDTLS_BSWAP16)
|
||||
#define MBEDTLS_BSWAP16 __builtin_bswap16
|
||||
#endif /* __has_builtin(__builtin_bswap16) */
|
||||
#if __has_builtin(__builtin_bswap32) && !defined(MBEDTLS_BSWAP32)
|
||||
#define MBEDTLS_BSWAP32 __builtin_bswap32
|
||||
#endif /* __has_builtin(__builtin_bswap32) */
|
||||
#if __has_builtin(__builtin_bswap64) && !defined(MBEDTLS_BSWAP64)
|
||||
#define MBEDTLS_BSWAP64 __builtin_bswap64
|
||||
#endif /* __has_builtin(__builtin_bswap64) */
|
||||
#endif /* defined(__clang__) && defined(__has_builtin) */
|
||||
|
||||
/*
|
||||
* Detect MSVC built-in byteswap routines
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#if !defined(MBEDTLS_BSWAP16)
|
||||
#define MBEDTLS_BSWAP16 _byteswap_ushort
|
||||
#endif
|
||||
#if !defined(MBEDTLS_BSWAP32)
|
||||
#define MBEDTLS_BSWAP32 _byteswap_ulong
|
||||
#endif
|
||||
#if !defined(MBEDTLS_BSWAP64)
|
||||
#define MBEDTLS_BSWAP64 _byteswap_uint64
|
||||
#endif
|
||||
#endif /* defined(_MSC_VER) */
|
||||
|
||||
/* Detect armcc built-in byteswap routine */
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000) && !defined(MBEDTLS_BSWAP32)
|
||||
#if defined(__ARM_ACLE) /* ARM Compiler 6 - earlier versions don't need a header */
|
||||
#include <arm_acle.h>
|
||||
#endif
|
||||
#define MBEDTLS_BSWAP32 __rev
|
||||
#endif
|
||||
|
||||
/* Detect IAR built-in byteswap routine */
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#if defined(__ARM_ACLE)
|
||||
#include <arm_acle.h>
|
||||
#define MBEDTLS_BSWAP16(x) ((uint16_t) __rev16((uint32_t) (x)))
|
||||
#define MBEDTLS_BSWAP32 __rev
|
||||
#define MBEDTLS_BSWAP64 __revll
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Where compiler built-ins are not present, fall back to C code that the
|
||||
* compiler may be able to detect and transform into the relevant bswap or
|
||||
* similar instruction.
|
||||
*/
|
||||
#if !defined(MBEDTLS_BSWAP16)
|
||||
static inline uint16_t mbedtls_bswap16(uint16_t x)
|
||||
{
|
||||
return
|
||||
(x & 0x00ff) << 8 |
|
||||
(x & 0xff00) >> 8;
|
||||
}
|
||||
#define MBEDTLS_BSWAP16 mbedtls_bswap16
|
||||
#endif /* !defined(MBEDTLS_BSWAP16) */
|
||||
|
||||
#if !defined(MBEDTLS_BSWAP32)
|
||||
static inline uint32_t mbedtls_bswap32(uint32_t x)
|
||||
{
|
||||
return
|
||||
(x & 0x000000ff) << 24 |
|
||||
(x & 0x0000ff00) << 8 |
|
||||
(x & 0x00ff0000) >> 8 |
|
||||
(x & 0xff000000) >> 24;
|
||||
}
|
||||
#define MBEDTLS_BSWAP32 mbedtls_bswap32
|
||||
#endif /* !defined(MBEDTLS_BSWAP32) */
|
||||
|
||||
#if !defined(MBEDTLS_BSWAP64)
|
||||
static inline uint64_t mbedtls_bswap64(uint64_t x)
|
||||
{
|
||||
return
|
||||
(x & 0x00000000000000ffULL) << 56 |
|
||||
(x & 0x000000000000ff00ULL) << 40 |
|
||||
(x & 0x0000000000ff0000ULL) << 24 |
|
||||
(x & 0x00000000ff000000ULL) << 8 |
|
||||
(x & 0x000000ff00000000ULL) >> 8 |
|
||||
(x & 0x0000ff0000000000ULL) >> 24 |
|
||||
(x & 0x00ff000000000000ULL) >> 40 |
|
||||
(x & 0xff00000000000000ULL) >> 56;
|
||||
}
|
||||
#define MBEDTLS_BSWAP64 mbedtls_bswap64
|
||||
#endif /* !defined(MBEDTLS_BSWAP64) */
|
||||
|
||||
#if !defined(__BYTE_ORDER__)
|
||||
|
||||
#if defined(__LITTLE_ENDIAN__)
|
||||
/* IAR defines __xxx_ENDIAN__, but not __BYTE_ORDER__ */
|
||||
#define MBEDTLS_IS_BIG_ENDIAN 0
|
||||
#elif defined(__BIG_ENDIAN__)
|
||||
#define MBEDTLS_IS_BIG_ENDIAN 1
|
||||
#else
|
||||
static const uint16_t mbedtls_byte_order_detector = { 0x100 };
|
||||
#define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if (__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__)
|
||||
#define MBEDTLS_IS_BIG_ENDIAN 1
|
||||
#else
|
||||
#define MBEDTLS_IS_BIG_ENDIAN 0
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__BYTE_ORDER__) */
|
||||
|
||||
/**
|
||||
* Get the unsigned 32 bits integer corresponding to four bytes in
|
||||
* big-endian order (MSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the four bytes from.
|
||||
* \param offset Offset from \p data of the first and most significant
|
||||
* byte of the four bytes to build the 32 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT32_BE(data, offset) \
|
||||
((MBEDTLS_IS_BIG_ENDIAN) \
|
||||
? mbedtls_get_unaligned_uint32((data) + (offset)) \
|
||||
: MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 32 bits unsigned integer in big-endian order.
|
||||
*
|
||||
* \param n 32 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 32
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the most significant
|
||||
* byte of the 32 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \
|
||||
{ \
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t) (n)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 32 bits integer corresponding to four bytes in
|
||||
* little-endian order (LSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the four bytes from.
|
||||
* \param offset Offset from \p data of the first and least significant
|
||||
* byte of the four bytes to build the 32 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT32_LE(data, offset) \
|
||||
((MBEDTLS_IS_BIG_ENDIAN) \
|
||||
? MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
|
||||
: mbedtls_get_unaligned_uint32((data) + (offset)) \
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* Put in memory a 32 bits unsigned integer in little-endian order.
|
||||
*
|
||||
* \param n 32 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 32
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the least significant
|
||||
* byte of the 32 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT32_LE(n, data, offset) \
|
||||
{ \
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t) (n))); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 16 bits integer corresponding to two bytes in
|
||||
* little-endian order (LSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the two bytes from.
|
||||
* \param offset Offset from \p data of the first and least significant
|
||||
* byte of the two bytes to build the 16 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT16_LE(data, offset) \
|
||||
((MBEDTLS_IS_BIG_ENDIAN) \
|
||||
? MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
|
||||
: mbedtls_get_unaligned_uint16((data) + (offset)) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 16 bits unsigned integer in little-endian order.
|
||||
*
|
||||
* \param n 16 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 16
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the least significant
|
||||
* byte of the 16 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT16_LE(n, data, offset) \
|
||||
{ \
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 16 bits integer corresponding to two bytes in
|
||||
* big-endian order (MSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the two bytes from.
|
||||
* \param offset Offset from \p data of the first and most significant
|
||||
* byte of the two bytes to build the 16 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT16_BE(data, offset) \
|
||||
((MBEDTLS_IS_BIG_ENDIAN) \
|
||||
? mbedtls_get_unaligned_uint16((data) + (offset)) \
|
||||
: MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 16 bits unsigned integer in big-endian order.
|
||||
*
|
||||
* \param n 16 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 16
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the most significant
|
||||
* byte of the 16 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT16_BE(n, data, offset) \
|
||||
{ \
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 24 bits integer corresponding to three bytes in
|
||||
* big-endian order (MSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the three bytes from.
|
||||
* \param offset Offset from \p data of the first and most significant
|
||||
* byte of the three bytes to build the 24 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT24_BE(data, offset) \
|
||||
( \
|
||||
((uint32_t) (data)[(offset)] << 16) \
|
||||
| ((uint32_t) (data)[(offset) + 1] << 8) \
|
||||
| ((uint32_t) (data)[(offset) + 2]) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 24 bits unsigned integer in big-endian order.
|
||||
*
|
||||
* \param n 24 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 24
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the most significant
|
||||
* byte of the 24 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT24_BE(n, data, offset) \
|
||||
{ \
|
||||
(data)[(offset)] = MBEDTLS_BYTE_2(n); \
|
||||
(data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \
|
||||
(data)[(offset) + 2] = MBEDTLS_BYTE_0(n); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 24 bits integer corresponding to three bytes in
|
||||
* little-endian order (LSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the three bytes from.
|
||||
* \param offset Offset from \p data of the first and least significant
|
||||
* byte of the three bytes to build the 24 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT24_LE(data, offset) \
|
||||
( \
|
||||
((uint32_t) (data)[(offset)]) \
|
||||
| ((uint32_t) (data)[(offset) + 1] << 8) \
|
||||
| ((uint32_t) (data)[(offset) + 2] << 16) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 24 bits unsigned integer in little-endian order.
|
||||
*
|
||||
* \param n 24 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 24
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the least significant
|
||||
* byte of the 24 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT24_LE(n, data, offset) \
|
||||
{ \
|
||||
(data)[(offset)] = MBEDTLS_BYTE_0(n); \
|
||||
(data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \
|
||||
(data)[(offset) + 2] = MBEDTLS_BYTE_2(n); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 64 bits integer corresponding to eight bytes in
|
||||
* big-endian order (MSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the eight bytes from.
|
||||
* \param offset Offset from \p data of the first and most significant
|
||||
* byte of the eight bytes to build the 64 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT64_BE(data, offset) \
|
||||
((MBEDTLS_IS_BIG_ENDIAN) \
|
||||
? mbedtls_get_unaligned_uint64((data) + (offset)) \
|
||||
: MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 64 bits unsigned integer in big-endian order.
|
||||
*
|
||||
* \param n 64 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 64
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the most significant
|
||||
* byte of the 64 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT64_BE(n, data, offset) \
|
||||
{ \
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 64 bits integer corresponding to eight bytes in
|
||||
* little-endian order (LSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the eight bytes from.
|
||||
* \param offset Offset from \p data of the first and least significant
|
||||
* byte of the eight bytes to build the 64 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT64_LE(data, offset) \
|
||||
((MBEDTLS_IS_BIG_ENDIAN) \
|
||||
? MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
|
||||
: mbedtls_get_unaligned_uint64((data) + (offset)) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 64 bits unsigned integer in little-endian order.
|
||||
*
|
||||
* \param n 64 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 64
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the least significant
|
||||
* byte of the 64 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT64_LE(n, data, offset) \
|
||||
{ \
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_LIBRARY_ALIGNMENT_H */
|
||||
468
Libs/util/third_party/mbedtls/library/asn1parse.c
vendored
Normal file
468
Libs/util/third_party/mbedtls/library/asn1parse.c
vendored
Normal file
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* Generic ASN.1 parsing
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
|
||||
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
|
||||
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
#include "mbedtls/bignum.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
/*
|
||||
* ASN.1 DER decoding routines
|
||||
*/
|
||||
int mbedtls_asn1_get_len(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
size_t *len)
|
||||
{
|
||||
if ((end - *p) < 1) {
|
||||
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
|
||||
}
|
||||
|
||||
if ((**p & 0x80) == 0) {
|
||||
*len = *(*p)++;
|
||||
} else {
|
||||
int n = (**p) & 0x7F;
|
||||
if (n == 0 || n > 4) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
|
||||
}
|
||||
if ((end - *p) <= n) {
|
||||
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
|
||||
}
|
||||
*len = 0;
|
||||
(*p)++;
|
||||
while (n--) {
|
||||
*len = (*len << 8) | **p;
|
||||
(*p)++;
|
||||
}
|
||||
}
|
||||
|
||||
if (*len > (size_t) (end - *p)) {
|
||||
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_asn1_get_tag(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
size_t *len, int tag)
|
||||
{
|
||||
if ((end - *p) < 1) {
|
||||
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
|
||||
}
|
||||
|
||||
if (**p != tag) {
|
||||
return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
|
||||
}
|
||||
|
||||
(*p)++;
|
||||
|
||||
return mbedtls_asn1_get_len(p, end, len);
|
||||
}
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||
int mbedtls_asn1_get_bool(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (len != 1) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
*val = (**p != 0) ? 1 : 0;
|
||||
(*p)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int asn1_get_tagged_int(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int tag, int *val)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* len==0 is malformed (0 must be represented as 020100 for INTEGER,
|
||||
* or 0A0100 for ENUMERATED tags
|
||||
*/
|
||||
if (len == 0) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
|
||||
}
|
||||
/* This is a cryptography library. Reject negative integers. */
|
||||
if ((**p & 0x80) != 0) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
/* Skip leading zeros. */
|
||||
while (len > 0 && **p == 0) {
|
||||
++(*p);
|
||||
--len;
|
||||
}
|
||||
|
||||
/* Reject integers that don't fit in an int. This code assumes that
|
||||
* the int type has no padding bit. */
|
||||
if (len > sizeof(int)) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
|
||||
}
|
||||
if (len == sizeof(int) && (**p & 0x80) != 0) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
*val = 0;
|
||||
while (len-- > 0) {
|
||||
*val = (*val << 8) | **p;
|
||||
(*p)++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_asn1_get_int(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val)
|
||||
{
|
||||
return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_get_enum(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val)
|
||||
{
|
||||
return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
int mbedtls_asn1_get_mpi(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_mpi *X)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_read_binary(X, *p, len);
|
||||
|
||||
*p += len;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_BIGNUM_C */
|
||||
|
||||
int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
|
||||
mbedtls_asn1_bitstring *bs)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* Certificate type is a single byte bitstring */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check length, subtract one for actual bit string length */
|
||||
if (bs->len < 1) {
|
||||
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
|
||||
}
|
||||
bs->len -= 1;
|
||||
|
||||
/* Get number of unused bits, ensure unused bits <= 7 */
|
||||
bs->unused_bits = **p;
|
||||
if (bs->unused_bits > 7) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
|
||||
}
|
||||
(*p)++;
|
||||
|
||||
/* Get actual bitstring */
|
||||
bs->p = *p;
|
||||
*p += bs->len;
|
||||
|
||||
if (*p != end) {
|
||||
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Traverse an ASN.1 "SEQUENCE OF <tag>"
|
||||
* and call a callback for each entry found.
|
||||
*/
|
||||
int mbedtls_asn1_traverse_sequence_of(
|
||||
unsigned char **p,
|
||||
const unsigned char *end,
|
||||
unsigned char tag_must_mask, unsigned char tag_must_val,
|
||||
unsigned char tag_may_mask, unsigned char tag_may_val,
|
||||
int (*cb)(void *ctx, int tag,
|
||||
unsigned char *start, size_t len),
|
||||
void *ctx)
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
/* Get main sequence tag */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (*p + len != end) {
|
||||
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
while (*p < end) {
|
||||
unsigned char const tag = *(*p)++;
|
||||
|
||||
if ((tag & tag_must_mask) != tag_must_val) {
|
||||
return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((tag & tag_may_mask) == tag_may_val) {
|
||||
if (cb != NULL) {
|
||||
ret = cb(ctx, tag, *p, len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*p += len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a bit string without unused bits
|
||||
*/
|
||||
int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
|
||||
size_t *len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (*len == 0) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
--(*len);
|
||||
|
||||
if (**p != 0) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
++(*p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
|
||||
{
|
||||
while (seq != NULL) {
|
||||
mbedtls_asn1_sequence *next = seq->next;
|
||||
mbedtls_free(seq);
|
||||
seq = next;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int tag;
|
||||
mbedtls_asn1_sequence *cur;
|
||||
} asn1_get_sequence_of_cb_ctx_t;
|
||||
|
||||
static int asn1_get_sequence_of_cb(void *ctx,
|
||||
int tag,
|
||||
unsigned char *start,
|
||||
size_t len)
|
||||
{
|
||||
asn1_get_sequence_of_cb_ctx_t *cb_ctx =
|
||||
(asn1_get_sequence_of_cb_ctx_t *) ctx;
|
||||
mbedtls_asn1_sequence *cur =
|
||||
cb_ctx->cur;
|
||||
|
||||
if (cur->buf.p != NULL) {
|
||||
cur->next =
|
||||
mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
|
||||
|
||||
if (cur->next == NULL) {
|
||||
return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
cur->buf.p = start;
|
||||
cur->buf.len = len;
|
||||
cur->buf.tag = tag;
|
||||
|
||||
cb_ctx->cur = cur;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
|
||||
*/
|
||||
int mbedtls_asn1_get_sequence_of(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_asn1_sequence *cur,
|
||||
int tag)
|
||||
{
|
||||
asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
|
||||
memset(cur, 0, sizeof(mbedtls_asn1_sequence));
|
||||
return mbedtls_asn1_traverse_sequence_of(
|
||||
p, end, 0xFF, tag, 0, 0,
|
||||
asn1_get_sequence_of_cb, &cb_ctx);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_get_alg(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((end - *p) < 1) {
|
||||
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
|
||||
}
|
||||
|
||||
alg->tag = **p;
|
||||
end = *p + len;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
alg->p = *p;
|
||||
*p += alg->len;
|
||||
|
||||
if (*p == end) {
|
||||
mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
params->tag = **p;
|
||||
(*p)++;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_len(p, end, ¶ms->len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
params->p = *p;
|
||||
*p += params->len;
|
||||
|
||||
if (*p != end) {
|
||||
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_asn1_get_alg_null(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_asn1_buf *alg)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_asn1_buf params;
|
||||
|
||||
memset(¶ms, 0, sizeof(mbedtls_asn1_buf));
|
||||
|
||||
if ((ret = mbedtls_asn1_get_alg(p, end, alg, ¶ms)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
|
||||
{
|
||||
if (cur == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_free(cur->oid.p);
|
||||
mbedtls_free(cur->val.p);
|
||||
|
||||
mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
|
||||
}
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
|
||||
{
|
||||
mbedtls_asn1_named_data *cur;
|
||||
|
||||
while ((cur = *head) != NULL) {
|
||||
*head = cur->next;
|
||||
mbedtls_free(cur->oid.p);
|
||||
mbedtls_free(cur->val.p);
|
||||
mbedtls_free(cur);
|
||||
}
|
||||
}
|
||||
|
||||
void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name)
|
||||
{
|
||||
for (mbedtls_asn1_named_data *next; name != NULL; name = next) {
|
||||
next = name->next;
|
||||
mbedtls_free(name);
|
||||
}
|
||||
}
|
||||
|
||||
const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list,
|
||||
const char *oid, size_t len)
|
||||
{
|
||||
while (list != NULL) {
|
||||
if (list->oid.len == len &&
|
||||
memcmp(list->oid.p, oid, len) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C */
|
||||
437
Libs/util/third_party/mbedtls/library/asn1write.c
vendored
Normal file
437
Libs/util/third_party/mbedtls/library/asn1write.c
vendored
Normal file
@@ -0,0 +1,437 @@
|
||||
/*
|
||||
* ASN.1 buffer writing functionality
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \
|
||||
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
|
||||
|
||||
#include "mbedtls/asn1write.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||
#include "mbedtls/asn1.h"
|
||||
#endif
|
||||
|
||||
int mbedtls_asn1_write_len(unsigned char **p, const unsigned char *start, size_t len)
|
||||
{
|
||||
#if SIZE_MAX > 0xFFFFFFFF
|
||||
if (len > 0xFFFFFFFF) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
|
||||
}
|
||||
#endif
|
||||
|
||||
int required = 1;
|
||||
|
||||
if (len >= 0x80) {
|
||||
for (size_t l = len; l != 0; l >>= 8) {
|
||||
required++;
|
||||
}
|
||||
}
|
||||
|
||||
if (required > (*p - start)) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
do {
|
||||
*--(*p) = MBEDTLS_BYTE_0(len);
|
||||
len >>= 8;
|
||||
} while (len);
|
||||
|
||||
if (required > 1) {
|
||||
*--(*p) = (unsigned char) (0x80 + required - 1);
|
||||
}
|
||||
|
||||
return required;
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start, unsigned char tag)
|
||||
{
|
||||
if (*p - start < 1) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
*--(*p) = tag;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
|
||||
|
||||
#if defined(MBEDTLS_ASN1_WRITE_C)
|
||||
static int mbedtls_asn1_write_len_and_tag(unsigned char **p,
|
||||
const unsigned char *start,
|
||||
size_t len,
|
||||
unsigned char tag)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, tag));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_raw_buffer(unsigned char **p, const unsigned char *start,
|
||||
const unsigned char *buf, size_t size)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
if (*p < start || (size_t) (*p - start) < size) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
len = size;
|
||||
(*p) -= len;
|
||||
memcpy(*p, buf, len);
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
int mbedtls_asn1_write_mpi(unsigned char **p, const unsigned char *start, const mbedtls_mpi *X)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
// Write the MPI
|
||||
//
|
||||
len = mbedtls_mpi_size(X);
|
||||
|
||||
/* DER represents 0 with a sign bit (0=nonnegative) and 7 value bits, not
|
||||
* as 0 digits. We need to end up with 020100, not with 0200. */
|
||||
if (len == 0) {
|
||||
len = 1;
|
||||
}
|
||||
|
||||
if (*p < start || (size_t) (*p - start) < len) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
(*p) -= len;
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(X, *p, len));
|
||||
|
||||
// DER format assumes 2s complement for numbers, so the leftmost bit
|
||||
// should be 0 for positive numbers and 1 for negative numbers.
|
||||
//
|
||||
if (X->s == 1 && **p & 0x80) {
|
||||
if (*p - start < 1) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
*--(*p) = 0x00;
|
||||
len += 1;
|
||||
}
|
||||
|
||||
ret = mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_INTEGER);
|
||||
|
||||
cleanup:
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_BIGNUM_C */
|
||||
|
||||
int mbedtls_asn1_write_null(unsigned char **p, const unsigned char *start)
|
||||
{
|
||||
// Write NULL
|
||||
//
|
||||
return mbedtls_asn1_write_len_and_tag(p, start, 0, MBEDTLS_ASN1_NULL);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_oid(unsigned char **p, const unsigned char *start,
|
||||
const char *oid, size_t oid_len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start,
|
||||
(const unsigned char *) oid, oid_len));
|
||||
return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_OID);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_algorithm_identifier(unsigned char **p, const unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
size_t par_len)
|
||||
{
|
||||
return mbedtls_asn1_write_algorithm_identifier_ext(p, start, oid, oid_len, par_len, 1);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p, const unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
size_t par_len, int has_par)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
if (has_par) {
|
||||
if (par_len == 0) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_null(p, start));
|
||||
} else {
|
||||
len += par_len;
|
||||
}
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len));
|
||||
|
||||
return mbedtls_asn1_write_len_and_tag(p, start, len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_bool(unsigned char **p, const unsigned char *start, int boolean)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
if (*p - start < 1) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
*--(*p) = (boolean) ? 255 : 0;
|
||||
len++;
|
||||
|
||||
return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_BOOLEAN);
|
||||
}
|
||||
|
||||
static int asn1_write_tagged_int(unsigned char **p, const unsigned char *start, int val, int tag)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
do {
|
||||
if (*p - start < 1) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
len += 1;
|
||||
*--(*p) = val & 0xff;
|
||||
val >>= 8;
|
||||
} while (val > 0);
|
||||
|
||||
if (**p & 0x80) {
|
||||
if (*p - start < 1) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
*--(*p) = 0x00;
|
||||
len += 1;
|
||||
}
|
||||
|
||||
return mbedtls_asn1_write_len_and_tag(p, start, len, tag);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_int(unsigned char **p, const unsigned char *start, int val)
|
||||
{
|
||||
return asn1_write_tagged_int(p, start, val, MBEDTLS_ASN1_INTEGER);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_enum(unsigned char **p, const unsigned char *start, int val)
|
||||
{
|
||||
return asn1_write_tagged_int(p, start, val, MBEDTLS_ASN1_ENUMERATED);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_tagged_string(unsigned char **p, const unsigned char *start, int tag,
|
||||
const char *text, size_t text_len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start,
|
||||
(const unsigned char *) text,
|
||||
text_len));
|
||||
|
||||
return mbedtls_asn1_write_len_and_tag(p, start, len, tag);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_utf8_string(unsigned char **p, const unsigned char *start,
|
||||
const char *text, size_t text_len)
|
||||
{
|
||||
return mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_printable_string(unsigned char **p, const unsigned char *start,
|
||||
const char *text, size_t text_len)
|
||||
{
|
||||
return mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text,
|
||||
text_len);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_ia5_string(unsigned char **p, const unsigned char *start,
|
||||
const char *text, size_t text_len)
|
||||
{
|
||||
return mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_named_bitstring(unsigned char **p,
|
||||
const unsigned char *start,
|
||||
const unsigned char *buf,
|
||||
size_t bits)
|
||||
{
|
||||
size_t unused_bits, byte_len;
|
||||
const unsigned char *cur_byte;
|
||||
unsigned char cur_byte_shifted;
|
||||
unsigned char bit;
|
||||
|
||||
byte_len = (bits + 7) / 8;
|
||||
unused_bits = (byte_len * 8) - bits;
|
||||
|
||||
/*
|
||||
* Named bitstrings require that trailing 0s are excluded in the encoding
|
||||
* of the bitstring. Trailing 0s are considered part of the 'unused' bits
|
||||
* when encoding this value in the first content octet
|
||||
*/
|
||||
if (bits != 0) {
|
||||
cur_byte = buf + byte_len - 1;
|
||||
cur_byte_shifted = *cur_byte >> unused_bits;
|
||||
|
||||
for (;;) {
|
||||
bit = cur_byte_shifted & 0x1;
|
||||
cur_byte_shifted >>= 1;
|
||||
|
||||
if (bit != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
bits--;
|
||||
if (bits == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (bits % 8 == 0) {
|
||||
cur_byte_shifted = *--cur_byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mbedtls_asn1_write_bitstring(p, start, buf, bits);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_bitstring(unsigned char **p, const unsigned char *start,
|
||||
const unsigned char *buf, size_t bits)
|
||||
{
|
||||
size_t len = 0;
|
||||
size_t unused_bits, byte_len;
|
||||
|
||||
byte_len = (bits + 7) / 8;
|
||||
unused_bits = (byte_len * 8) - bits;
|
||||
|
||||
if (*p < start || (size_t) (*p - start) < byte_len + 1) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
len = byte_len + 1;
|
||||
|
||||
/* Write the bitstring. Ensure the unused bits are zeroed */
|
||||
if (byte_len > 0) {
|
||||
byte_len--;
|
||||
*--(*p) = buf[byte_len] & ~((0x1 << unused_bits) - 1);
|
||||
(*p) -= byte_len;
|
||||
memcpy(*p, buf, byte_len);
|
||||
}
|
||||
|
||||
/* Write unused bits */
|
||||
*--(*p) = (unsigned char) unused_bits;
|
||||
|
||||
return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_BIT_STRING);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_octet_string(unsigned char **p, const unsigned char *start,
|
||||
const unsigned char *buf, size_t size)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, buf, size));
|
||||
|
||||
return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_OCTET_STRING);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(MBEDTLS_ASN1_PARSE_C)
|
||||
/* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(),
|
||||
* which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */
|
||||
static mbedtls_asn1_named_data *asn1_find_named_data(
|
||||
mbedtls_asn1_named_data *list,
|
||||
const char *oid, size_t len)
|
||||
{
|
||||
while (list != NULL) {
|
||||
if (list->oid.len == len &&
|
||||
memcmp(list->oid.p, oid, len) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
#else
|
||||
#define asn1_find_named_data(list, oid, len) \
|
||||
((mbedtls_asn1_named_data *) mbedtls_asn1_find_named_data(list, oid, len))
|
||||
#endif
|
||||
|
||||
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
|
||||
mbedtls_asn1_named_data **head,
|
||||
const char *oid, size_t oid_len,
|
||||
const unsigned char *val,
|
||||
size_t val_len)
|
||||
{
|
||||
mbedtls_asn1_named_data *cur;
|
||||
|
||||
if ((cur = asn1_find_named_data(*head, oid, oid_len)) == NULL) {
|
||||
// Add new entry if not present yet based on OID
|
||||
//
|
||||
cur = (mbedtls_asn1_named_data *) mbedtls_calloc(1,
|
||||
sizeof(mbedtls_asn1_named_data));
|
||||
if (cur == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cur->oid.len = oid_len;
|
||||
cur->oid.p = mbedtls_calloc(1, oid_len);
|
||||
if (cur->oid.p == NULL) {
|
||||
mbedtls_free(cur);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(cur->oid.p, oid, oid_len);
|
||||
|
||||
cur->val.len = val_len;
|
||||
if (val_len != 0) {
|
||||
cur->val.p = mbedtls_calloc(1, val_len);
|
||||
if (cur->val.p == NULL) {
|
||||
mbedtls_free(cur->oid.p);
|
||||
mbedtls_free(cur);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
cur->next = *head;
|
||||
*head = cur;
|
||||
} else if (val_len == 0) {
|
||||
mbedtls_free(cur->val.p);
|
||||
cur->val.p = NULL;
|
||||
} else if (cur->val.len != val_len) {
|
||||
/*
|
||||
* Enlarge existing value buffer if needed
|
||||
* Preserve old data until the allocation succeeded, to leave list in
|
||||
* a consistent state in case allocation fails.
|
||||
*/
|
||||
void *p = mbedtls_calloc(1, val_len);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbedtls_free(cur->val.p);
|
||||
cur->val.p = p;
|
||||
cur->val.len = val_len;
|
||||
}
|
||||
|
||||
if (val != NULL && val_len != 0) {
|
||||
memcpy(cur->val.p, val, val_len);
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
#endif /* MBEDTLS_ASN1_WRITE_C */
|
||||
299
Libs/util/third_party/mbedtls/library/base64.c
vendored
Normal file
299
Libs/util/third_party/mbedtls/library/base64.c
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* RFC 1521 base64 encoding/decoding
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BASE64_C)
|
||||
|
||||
#include "mbedtls/base64.h"
|
||||
#include "base64_internal.h"
|
||||
#include "constant_time_internal.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
unsigned char mbedtls_ct_base64_enc_char(unsigned char value)
|
||||
{
|
||||
unsigned char digit = 0;
|
||||
/* For each range of values, if value is in that range, mask digit with
|
||||
* the corresponding value. Since value can only be in a single range,
|
||||
* only at most one masking will change digit. */
|
||||
digit |= mbedtls_ct_uchar_in_range_if(0, 25, value, 'A' + value);
|
||||
digit |= mbedtls_ct_uchar_in_range_if(26, 51, value, 'a' + value - 26);
|
||||
digit |= mbedtls_ct_uchar_in_range_if(52, 61, value, '0' + value - 52);
|
||||
digit |= mbedtls_ct_uchar_in_range_if(62, 62, value, '+');
|
||||
digit |= mbedtls_ct_uchar_in_range_if(63, 63, value, '/');
|
||||
return digit;
|
||||
}
|
||||
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
signed char mbedtls_ct_base64_dec_value(unsigned char c)
|
||||
{
|
||||
unsigned char val = 0;
|
||||
/* For each range of digits, if c is in that range, mask val with
|
||||
* the corresponding value. Since c can only be in a single range,
|
||||
* only at most one masking will change val. Set val to one plus
|
||||
* the desired value so that it stays 0 if c is in none of the ranges. */
|
||||
val |= mbedtls_ct_uchar_in_range_if('A', 'Z', c, c - 'A' + 0 + 1);
|
||||
val |= mbedtls_ct_uchar_in_range_if('a', 'z', c, c - 'a' + 26 + 1);
|
||||
val |= mbedtls_ct_uchar_in_range_if('0', '9', c, c - '0' + 52 + 1);
|
||||
val |= mbedtls_ct_uchar_in_range_if('+', '+', c, c - '+' + 62 + 1);
|
||||
val |= mbedtls_ct_uchar_in_range_if('/', '/', c, c - '/' + 63 + 1);
|
||||
/* At this point, val is 0 if c is an invalid digit and v+1 if c is
|
||||
* a digit with the value v. */
|
||||
return val - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode a buffer into base64 format
|
||||
*/
|
||||
int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
const unsigned char *src, size_t slen)
|
||||
{
|
||||
size_t i, n;
|
||||
int C1, C2, C3;
|
||||
unsigned char *p;
|
||||
|
||||
if (slen == 0) {
|
||||
*olen = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = slen / 3 + (slen % 3 != 0);
|
||||
|
||||
if (n > (SIZE_MAX - 1) / 4) {
|
||||
*olen = SIZE_MAX;
|
||||
return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
n *= 4;
|
||||
|
||||
if ((dlen < n + 1) || (NULL == dst)) {
|
||||
*olen = n + 1;
|
||||
return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
n = (slen / 3) * 3;
|
||||
|
||||
for (i = 0, p = dst; i < n; i += 3) {
|
||||
C1 = *src++;
|
||||
C2 = *src++;
|
||||
C3 = *src++;
|
||||
|
||||
*p++ = mbedtls_ct_base64_enc_char((C1 >> 2) & 0x3F);
|
||||
*p++ = mbedtls_ct_base64_enc_char((((C1 & 3) << 4) + (C2 >> 4))
|
||||
& 0x3F);
|
||||
*p++ = mbedtls_ct_base64_enc_char((((C2 & 15) << 2) + (C3 >> 6))
|
||||
& 0x3F);
|
||||
*p++ = mbedtls_ct_base64_enc_char(C3 & 0x3F);
|
||||
}
|
||||
|
||||
if (i < slen) {
|
||||
C1 = *src++;
|
||||
C2 = ((i + 1) < slen) ? *src++ : 0;
|
||||
|
||||
*p++ = mbedtls_ct_base64_enc_char((C1 >> 2) & 0x3F);
|
||||
*p++ = mbedtls_ct_base64_enc_char((((C1 & 3) << 4) + (C2 >> 4))
|
||||
& 0x3F);
|
||||
|
||||
if ((i + 1) < slen) {
|
||||
*p++ = mbedtls_ct_base64_enc_char(((C2 & 15) << 2) & 0x3F);
|
||||
} else {
|
||||
*p++ = '=';
|
||||
}
|
||||
|
||||
*p++ = '=';
|
||||
}
|
||||
|
||||
*olen = (size_t) (p - dst);
|
||||
*p = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a base64-formatted buffer
|
||||
*/
|
||||
int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
const unsigned char *src, size_t slen)
|
||||
{
|
||||
size_t i; /* index in source */
|
||||
size_t n; /* number of digits or trailing = in source */
|
||||
uint32_t x; /* value accumulator */
|
||||
unsigned accumulated_digits = 0;
|
||||
unsigned equals = 0;
|
||||
int spaces_present = 0;
|
||||
unsigned char *p;
|
||||
|
||||
/* First pass: check for validity and get output length */
|
||||
for (i = n = 0; i < slen; i++) {
|
||||
/* Skip spaces before checking for EOL */
|
||||
spaces_present = 0;
|
||||
while (i < slen && src[i] == ' ') {
|
||||
++i;
|
||||
spaces_present = 1;
|
||||
}
|
||||
|
||||
/* Spaces at end of buffer are OK */
|
||||
if (i == slen) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((slen - i) >= 2 &&
|
||||
src[i] == '\r' && src[i + 1] == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (src[i] == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Space inside a line is an error */
|
||||
if (spaces_present) {
|
||||
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
|
||||
}
|
||||
|
||||
if (src[i] > 127) {
|
||||
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
|
||||
}
|
||||
|
||||
if (src[i] == '=') {
|
||||
if (++equals > 2) {
|
||||
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
|
||||
}
|
||||
} else {
|
||||
if (equals != 0) {
|
||||
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
|
||||
}
|
||||
if (mbedtls_ct_base64_dec_value(src[i]) < 0) {
|
||||
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
|
||||
}
|
||||
}
|
||||
n++;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
*olen = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The following expression is to calculate the following formula without
|
||||
* risk of integer overflow in n:
|
||||
* n = ( ( n * 6 ) + 7 ) >> 3;
|
||||
*/
|
||||
n = (6 * (n >> 3)) + ((6 * (n & 0x7) + 7) >> 3);
|
||||
n -= equals;
|
||||
|
||||
if (dst == NULL || dlen < n) {
|
||||
*olen = n;
|
||||
return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
equals = 0;
|
||||
for (x = 0, p = dst; i > 0; i--, src++) {
|
||||
if (*src == '\r' || *src == '\n' || *src == ' ') {
|
||||
continue;
|
||||
}
|
||||
|
||||
x = x << 6;
|
||||
if (*src == '=') {
|
||||
++equals;
|
||||
} else {
|
||||
x |= mbedtls_ct_base64_dec_value(*src);
|
||||
}
|
||||
|
||||
if (++accumulated_digits == 4) {
|
||||
accumulated_digits = 0;
|
||||
*p++ = MBEDTLS_BYTE_2(x);
|
||||
if (equals <= 1) {
|
||||
*p++ = MBEDTLS_BYTE_1(x);
|
||||
}
|
||||
if (equals <= 0) {
|
||||
*p++ = MBEDTLS_BYTE_0(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*olen = (size_t) (p - dst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
static const unsigned char base64_test_dec[64] =
|
||||
{
|
||||
0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
|
||||
0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
|
||||
0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
|
||||
0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
|
||||
0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
|
||||
0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
|
||||
0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
|
||||
0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
|
||||
};
|
||||
|
||||
static const unsigned char base64_test_enc[] =
|
||||
"JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
|
||||
"swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int mbedtls_base64_self_test(int verbose)
|
||||
{
|
||||
size_t len;
|
||||
const unsigned char *src;
|
||||
unsigned char buffer[128];
|
||||
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf(" Base64 encoding test: ");
|
||||
}
|
||||
|
||||
src = base64_test_dec;
|
||||
|
||||
if (mbedtls_base64_encode(buffer, sizeof(buffer), &len, src, 64) != 0 ||
|
||||
memcmp(base64_test_enc, buffer, 88) != 0) {
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("failed\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("passed\n Base64 decoding test: ");
|
||||
}
|
||||
|
||||
src = base64_test_enc;
|
||||
|
||||
if (mbedtls_base64_decode(buffer, sizeof(buffer), &len, src, 88) != 0 ||
|
||||
memcmp(base64_test_dec, buffer, 64) != 0) {
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("failed\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("passed\n\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#endif /* MBEDTLS_BASE64_C */
|
||||
45
Libs/util/third_party/mbedtls/library/base64_internal.h
vendored
Normal file
45
Libs/util/third_party/mbedtls/library/base64_internal.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* \file base64_internal.h
|
||||
*
|
||||
* \brief RFC 1521 base64 encoding/decoding: interfaces for invasive testing
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_BASE64_INTERNAL
|
||||
#define MBEDTLS_BASE64_INTERNAL
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
|
||||
/** Given a value in the range 0..63, return the corresponding Base64 digit.
|
||||
*
|
||||
* The implementation assumes that letters are consecutive (e.g. ASCII
|
||||
* but not EBCDIC).
|
||||
*
|
||||
* \param value A value in the range 0..63.
|
||||
*
|
||||
* \return A base64 digit converted from \p value.
|
||||
*/
|
||||
unsigned char mbedtls_ct_base64_enc_char(unsigned char value);
|
||||
|
||||
/** Given a Base64 digit, return its value.
|
||||
*
|
||||
* If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'),
|
||||
* return -1.
|
||||
*
|
||||
* The implementation assumes that letters are consecutive (e.g. ASCII
|
||||
* but not EBCDIC).
|
||||
*
|
||||
* \param c A base64 digit.
|
||||
*
|
||||
* \return The value of the base64 digit \p c.
|
||||
*/
|
||||
signed char mbedtls_ct_base64_dec_value(unsigned char c);
|
||||
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
|
||||
#endif /* MBEDTLS_BASE64_INTERNAL */
|
||||
2487
Libs/util/third_party/mbedtls/library/bignum.c
vendored
Normal file
2487
Libs/util/third_party/mbedtls/library/bignum.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1020
Libs/util/third_party/mbedtls/library/bignum_core.c
vendored
Normal file
1020
Libs/util/third_party/mbedtls/library/bignum_core.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
833
Libs/util/third_party/mbedtls/library/bignum_core.h
vendored
Normal file
833
Libs/util/third_party/mbedtls/library/bignum_core.h
vendored
Normal file
@@ -0,0 +1,833 @@
|
||||
/**
|
||||
* Core bignum functions
|
||||
*
|
||||
* This interface should only be used by the legacy bignum module (bignum.h)
|
||||
* and the modular bignum modules (bignum_mod.c, bignum_mod_raw.c). All other
|
||||
* modules should use the high-level modular bignum interface (bignum_mod.h)
|
||||
* or the legacy bignum interface (bignum.h).
|
||||
*
|
||||
* This module is about processing non-negative integers with a fixed upper
|
||||
* bound that's of the form 2^n-1 where n is a multiple of #biL.
|
||||
* These can be thought of integers written in base 2^#biL with a fixed
|
||||
* number of digits. Digits in this base are called *limbs*.
|
||||
* Many operations treat these numbers as the principal representation of
|
||||
* a number modulo 2^n or a smaller bound.
|
||||
*
|
||||
* The functions in this module obey the following conventions unless
|
||||
* explicitly indicated otherwise:
|
||||
*
|
||||
* - **Overflow**: some functions indicate overflow from the range
|
||||
* [0, 2^n-1] by returning carry parameters, while others operate
|
||||
* modulo and so cannot overflow. This should be clear from the function
|
||||
* documentation.
|
||||
* - **Bignum parameters**: Bignums are passed as pointers to an array of
|
||||
* limbs. A limb has the type #mbedtls_mpi_uint. Unless otherwise specified:
|
||||
* - Bignum parameters called \p A, \p B, ... are inputs, and are
|
||||
* not modified by the function.
|
||||
* - For operations modulo some number, the modulus is called \p N
|
||||
* and is input-only.
|
||||
* - Bignum parameters called \p X, \p Y are outputs or input-output.
|
||||
* The initial content of output-only parameters is ignored.
|
||||
* - Some functions use different names that reflect traditional
|
||||
* naming of operands of certain operations (e.g.
|
||||
* divisor/dividend/quotient/remainder).
|
||||
* - \p T is a temporary storage area. The initial content of such
|
||||
* parameter is ignored and the final content is unspecified.
|
||||
* - **Bignum sizes**: bignum sizes are always expressed in limbs.
|
||||
* Most functions work on bignums of a given size and take a single
|
||||
* \p limbs parameter that applies to all parameters that are limb arrays.
|
||||
* All bignum sizes must be at least 1 and must be significantly less than
|
||||
* #SIZE_MAX. The behavior if a size is 0 is undefined. The behavior if the
|
||||
* total size of all parameters overflows #SIZE_MAX is undefined.
|
||||
* - **Parameter ordering**: for bignum parameters, outputs come before inputs.
|
||||
* Temporaries come last.
|
||||
* - **Aliasing**: in general, output bignums may be aliased to one or more
|
||||
* inputs. As an exception, parameters that are documented as a modulus value
|
||||
* may not be aliased to an output. Outputs may not be aliased to one another.
|
||||
* Temporaries may not be aliased to any other parameter.
|
||||
* - **Overlap**: apart from aliasing of limb array pointers (where two
|
||||
* arguments are equal pointers), overlap is not supported and may result
|
||||
* in undefined behavior.
|
||||
* - **Error handling**: This is a low-level module. Functions generally do not
|
||||
* try to protect against invalid arguments such as nonsensical sizes or
|
||||
* null pointers. Note that some functions that operate on bignums of
|
||||
* different sizes have constraints about their size, and violating those
|
||||
* constraints may lead to buffer overflows.
|
||||
* - **Modular representatives**: functions that operate modulo \p N expect
|
||||
* all modular inputs to be in the range [0, \p N - 1] and guarantee outputs
|
||||
* in the range [0, \p N - 1]. If an input is out of range, outputs are
|
||||
* fully unspecified, though bignum values out of range should not cause
|
||||
* buffer overflows (beware that this is not extensively tested).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_BIGNUM_CORE_H
|
||||
#define MBEDTLS_BIGNUM_CORE_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
#include "mbedtls/bignum.h"
|
||||
#endif
|
||||
|
||||
#include "constant_time_internal.h"
|
||||
|
||||
#define ciL (sizeof(mbedtls_mpi_uint)) /** chars in limb */
|
||||
#define biL (ciL << 3) /** bits in limb */
|
||||
#define biH (ciL << 2) /** half limb size */
|
||||
|
||||
/*
|
||||
* Convert between bits/chars and number of limbs
|
||||
* Divide first in order to avoid potential overflows
|
||||
*/
|
||||
#define BITS_TO_LIMBS(i) ((i) / biL + ((i) % biL != 0))
|
||||
#define CHARS_TO_LIMBS(i) ((i) / ciL + ((i) % ciL != 0))
|
||||
/* Get a specific byte, without range checks. */
|
||||
#define GET_BYTE(X, i) \
|
||||
(((X)[(i) / ciL] >> (((i) % ciL) * 8)) & 0xff)
|
||||
|
||||
/* Constants to identify whether a value is public or secret. If a parameter is marked as secret by
|
||||
* this constant, the function must be constant time with respect to the parameter.
|
||||
*
|
||||
* This is only needed for functions with the _optionally_safe postfix. All other functions have
|
||||
* fixed behavior that can't be changed at runtime and are constant time with respect to their
|
||||
* parameters as prescribed by their documentation or by conventions in their module's documentation.
|
||||
*
|
||||
* Parameters should be named X_public where X is the name of the
|
||||
* corresponding input parameter.
|
||||
*
|
||||
* Implementation should always check using
|
||||
* if (X_public == MBEDTLS_MPI_IS_PUBLIC) {
|
||||
* // unsafe path
|
||||
* } else {
|
||||
* // safe path
|
||||
* }
|
||||
* not the other way round, in order to prevent misuse. (This is, if a value
|
||||
* other than the two below is passed, default to the safe path.) */
|
||||
#define MBEDTLS_MPI_IS_PUBLIC 0x2a2a2a2a
|
||||
#define MBEDTLS_MPI_IS_SECRET 0
|
||||
|
||||
/** Count leading zero bits in a given integer.
|
||||
*
|
||||
* \warning The result is undefined if \p a == 0
|
||||
*
|
||||
* \param a Integer to count leading zero bits.
|
||||
*
|
||||
* \return The number of leading zero bits in \p a, if \p a != 0.
|
||||
* If \p a == 0, the result is undefined.
|
||||
*/
|
||||
size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a);
|
||||
|
||||
/** Return the minimum number of bits required to represent the value held
|
||||
* in the MPI.
|
||||
*
|
||||
* \note This function returns 0 if all the limbs of \p A are 0.
|
||||
*
|
||||
* \param[in] A The address of the MPI.
|
||||
* \param A_limbs The number of limbs of \p A.
|
||||
*
|
||||
* \return The number of bits in \p A.
|
||||
*/
|
||||
size_t mbedtls_mpi_core_bitlen(const mbedtls_mpi_uint *A, size_t A_limbs);
|
||||
|
||||
/** Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
|
||||
* into the storage form used by mbedtls_mpi.
|
||||
*
|
||||
* \param[in,out] A The address of the MPI.
|
||||
* \param A_limbs The number of limbs of \p A.
|
||||
*/
|
||||
void mbedtls_mpi_core_bigendian_to_host(mbedtls_mpi_uint *A,
|
||||
size_t A_limbs);
|
||||
|
||||
/** \brief Compare a machine integer with an MPI.
|
||||
*
|
||||
* This function operates in constant time with respect
|
||||
* to the values of \p min and \p A.
|
||||
*
|
||||
* \param min A machine integer.
|
||||
* \param[in] A An MPI.
|
||||
* \param A_limbs The number of limbs of \p A.
|
||||
* This must be at least 1.
|
||||
*
|
||||
* \return MBEDTLS_CT_TRUE if \p min is less than or equal to \p A, otherwise MBEDTLS_CT_FALSE.
|
||||
*/
|
||||
mbedtls_ct_condition_t mbedtls_mpi_core_uint_le_mpi(mbedtls_mpi_uint min,
|
||||
const mbedtls_mpi_uint *A,
|
||||
size_t A_limbs);
|
||||
|
||||
/**
|
||||
* \brief Check if one unsigned MPI is less than another in constant
|
||||
* time.
|
||||
*
|
||||
* \param A The left-hand MPI. This must point to an array of limbs
|
||||
* with the same allocated length as \p B.
|
||||
* \param B The right-hand MPI. This must point to an array of limbs
|
||||
* with the same allocated length as \p A.
|
||||
* \param limbs The number of limbs in \p A and \p B.
|
||||
* This must not be 0.
|
||||
*
|
||||
* \return MBEDTLS_CT_TRUE if \p A is less than \p B.
|
||||
* MBEDTLS_CT_FALSE if \p A is greater than or equal to \p B.
|
||||
*/
|
||||
mbedtls_ct_condition_t mbedtls_mpi_core_lt_ct(const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
size_t limbs);
|
||||
|
||||
/**
|
||||
* \brief Perform a safe conditional copy of an MPI which doesn't reveal
|
||||
* whether assignment was done or not.
|
||||
*
|
||||
* \param[out] X The address of the destination MPI.
|
||||
* This must be initialized. Must have enough limbs to
|
||||
* store the full value of \p A.
|
||||
* \param[in] A The address of the source MPI. This must be initialized.
|
||||
* \param limbs The number of limbs of \p A.
|
||||
* \param assign The condition deciding whether to perform the
|
||||
* assignment or not. Callers will need to use
|
||||
* the constant time interface (e.g. `mbedtls_ct_bool()`)
|
||||
* to construct this argument.
|
||||
*
|
||||
* \note This function avoids leaking any information about whether
|
||||
* the assignment was done or not.
|
||||
*/
|
||||
void mbedtls_mpi_core_cond_assign(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
size_t limbs,
|
||||
mbedtls_ct_condition_t assign);
|
||||
|
||||
/**
|
||||
* \brief Perform a safe conditional swap of two MPIs which doesn't reveal
|
||||
* whether the swap was done or not.
|
||||
*
|
||||
* \param[in,out] X The address of the first MPI.
|
||||
* This must be initialized.
|
||||
* \param[in,out] Y The address of the second MPI.
|
||||
* This must be initialized.
|
||||
* \param limbs The number of limbs of \p X and \p Y.
|
||||
* \param swap The condition deciding whether to perform
|
||||
* the swap or not.
|
||||
*
|
||||
* \note This function avoids leaking any information about whether
|
||||
* the swap was done or not.
|
||||
*/
|
||||
void mbedtls_mpi_core_cond_swap(mbedtls_mpi_uint *X,
|
||||
mbedtls_mpi_uint *Y,
|
||||
size_t limbs,
|
||||
mbedtls_ct_condition_t swap);
|
||||
|
||||
/** Import X from unsigned binary data, little-endian.
|
||||
*
|
||||
* The MPI needs to have enough limbs to store the full value (including any
|
||||
* most significant zero bytes in the input).
|
||||
*
|
||||
* \param[out] X The address of the MPI.
|
||||
* \param X_limbs The number of limbs of \p X.
|
||||
* \param[in] input The input buffer to import from.
|
||||
* \param input_length The length bytes of \p input.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't
|
||||
* large enough to hold the value in \p input.
|
||||
*/
|
||||
int mbedtls_mpi_core_read_le(mbedtls_mpi_uint *X,
|
||||
size_t X_limbs,
|
||||
const unsigned char *input,
|
||||
size_t input_length);
|
||||
|
||||
/** Import X from unsigned binary data, big-endian.
|
||||
*
|
||||
* The MPI needs to have enough limbs to store the full value (including any
|
||||
* most significant zero bytes in the input).
|
||||
*
|
||||
* \param[out] X The address of the MPI.
|
||||
* May only be #NULL if \p X_limbs is 0 and \p input_length
|
||||
* is 0.
|
||||
* \param X_limbs The number of limbs of \p X.
|
||||
* \param[in] input The input buffer to import from.
|
||||
* May only be #NULL if \p input_length is 0.
|
||||
* \param input_length The length in bytes of \p input.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't
|
||||
* large enough to hold the value in \p input.
|
||||
*/
|
||||
int mbedtls_mpi_core_read_be(mbedtls_mpi_uint *X,
|
||||
size_t X_limbs,
|
||||
const unsigned char *input,
|
||||
size_t input_length);
|
||||
|
||||
/** Export A into unsigned binary data, little-endian.
|
||||
*
|
||||
* \note If \p output is shorter than \p A the export is still successful if the
|
||||
* value held in \p A fits in the buffer (that is, if enough of the most
|
||||
* significant bytes of \p A are 0).
|
||||
*
|
||||
* \param[in] A The address of the MPI.
|
||||
* \param A_limbs The number of limbs of \p A.
|
||||
* \param[out] output The output buffer to export to.
|
||||
* \param output_length The length in bytes of \p output.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't
|
||||
* large enough to hold the value of \p A.
|
||||
*/
|
||||
int mbedtls_mpi_core_write_le(const mbedtls_mpi_uint *A,
|
||||
size_t A_limbs,
|
||||
unsigned char *output,
|
||||
size_t output_length);
|
||||
|
||||
/** Export A into unsigned binary data, big-endian.
|
||||
*
|
||||
* \note If \p output is shorter than \p A the export is still successful if the
|
||||
* value held in \p A fits in the buffer (that is, if enough of the most
|
||||
* significant bytes of \p A are 0).
|
||||
*
|
||||
* \param[in] A The address of the MPI.
|
||||
* \param A_limbs The number of limbs of \p A.
|
||||
* \param[out] output The output buffer to export to.
|
||||
* \param output_length The length in bytes of \p output.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't
|
||||
* large enough to hold the value of \p A.
|
||||
*/
|
||||
int mbedtls_mpi_core_write_be(const mbedtls_mpi_uint *A,
|
||||
size_t A_limbs,
|
||||
unsigned char *output,
|
||||
size_t output_length);
|
||||
|
||||
/** \brief Shift an MPI in-place right by a number of bits.
|
||||
*
|
||||
* Shifting by more bits than there are bit positions
|
||||
* in \p X is valid and results in setting \p X to 0.
|
||||
*
|
||||
* This function's execution time depends on the value
|
||||
* of \p count (and of course \p limbs).
|
||||
*
|
||||
* \param[in,out] X The number to shift.
|
||||
* \param limbs The number of limbs of \p X. This must be at least 1.
|
||||
* \param count The number of bits to shift by.
|
||||
*/
|
||||
void mbedtls_mpi_core_shift_r(mbedtls_mpi_uint *X, size_t limbs,
|
||||
size_t count);
|
||||
|
||||
/**
|
||||
* \brief Shift an MPI in-place left by a number of bits.
|
||||
*
|
||||
* Shifting by more bits than there are bit positions
|
||||
* in \p X will produce an unspecified result.
|
||||
*
|
||||
* This function's execution time depends on the value
|
||||
* of \p count (and of course \p limbs).
|
||||
* \param[in,out] X The number to shift.
|
||||
* \param limbs The number of limbs of \p X. This must be at least 1.
|
||||
* \param count The number of bits to shift by.
|
||||
*/
|
||||
void mbedtls_mpi_core_shift_l(mbedtls_mpi_uint *X, size_t limbs,
|
||||
size_t count);
|
||||
|
||||
/**
|
||||
* \brief Add two fixed-size large unsigned integers, returning the carry.
|
||||
*
|
||||
* Calculates `A + B` where `A` and `B` have the same size.
|
||||
*
|
||||
* This function operates modulo `2^(biL*limbs)` and returns the carry
|
||||
* (1 if there was a wraparound, and 0 otherwise).
|
||||
*
|
||||
* \p X may be aliased to \p A or \p B.
|
||||
*
|
||||
* \param[out] X The result of the addition.
|
||||
* \param[in] A Little-endian presentation of the left operand.
|
||||
* \param[in] B Little-endian presentation of the right operand.
|
||||
* \param limbs Number of limbs of \p X, \p A and \p B.
|
||||
*
|
||||
* \return 1 if `A + B >= 2^(biL*limbs)`, 0 otherwise.
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_add(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
size_t limbs);
|
||||
|
||||
/**
|
||||
* \brief Conditional addition of two fixed-size large unsigned integers,
|
||||
* returning the carry.
|
||||
*
|
||||
* Functionally equivalent to
|
||||
*
|
||||
* ```
|
||||
* if( cond )
|
||||
* X += A;
|
||||
* return carry;
|
||||
* ```
|
||||
*
|
||||
* This function operates modulo `2^(biL*limbs)`.
|
||||
*
|
||||
* \param[in,out] X The pointer to the (little-endian) array
|
||||
* representing the bignum to accumulate onto.
|
||||
* \param[in] A The pointer to the (little-endian) array
|
||||
* representing the bignum to conditionally add
|
||||
* to \p X. This may be aliased to \p X but may not
|
||||
* overlap otherwise.
|
||||
* \param limbs Number of limbs of \p X and \p A.
|
||||
* \param cond Condition bit dictating whether addition should
|
||||
* happen or not. This must be \c 0 or \c 1.
|
||||
*
|
||||
* \warning If \p cond is neither 0 nor 1, the result of this function
|
||||
* is unspecified, and the resulting value in \p X might be
|
||||
* neither its original value nor \p X + \p A.
|
||||
*
|
||||
* \return 1 if `X + cond * A >= 2^(biL*limbs)`, 0 otherwise.
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_add_if(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
size_t limbs,
|
||||
unsigned cond);
|
||||
|
||||
/**
|
||||
* \brief Subtract two fixed-size large unsigned integers, returning the borrow.
|
||||
*
|
||||
* Calculate `A - B` where \p A and \p B have the same size.
|
||||
* This function operates modulo `2^(biL*limbs)` and returns the carry
|
||||
* (1 if there was a wraparound, i.e. if `A < B`, and 0 otherwise).
|
||||
*
|
||||
* \p X may be aliased to \p A or \p B, or even both, but may not overlap
|
||||
* either otherwise.
|
||||
*
|
||||
* \param[out] X The result of the subtraction.
|
||||
* \param[in] A Little-endian presentation of left operand.
|
||||
* \param[in] B Little-endian presentation of right operand.
|
||||
* \param limbs Number of limbs of \p X, \p A and \p B.
|
||||
*
|
||||
* \return 1 if `A < B`.
|
||||
* 0 if `A >= B`.
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_sub(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
size_t limbs);
|
||||
|
||||
/**
|
||||
* \brief Perform a fixed-size multiply accumulate operation: X += b * A
|
||||
*
|
||||
* \p X may be aliased to \p A (when \p X_limbs == \p A_limbs), but may not
|
||||
* otherwise overlap.
|
||||
*
|
||||
* This function operates modulo `2^(biL*X_limbs)`.
|
||||
*
|
||||
* \param[in,out] X The pointer to the (little-endian) array
|
||||
* representing the bignum to accumulate onto.
|
||||
* \param X_limbs The number of limbs of \p X. This must be
|
||||
* at least \p A_limbs.
|
||||
* \param[in] A The pointer to the (little-endian) array
|
||||
* representing the bignum to multiply with.
|
||||
* This may be aliased to \p X but may not overlap
|
||||
* otherwise.
|
||||
* \param A_limbs The number of limbs of \p A.
|
||||
* \param b X scalar to multiply with.
|
||||
*
|
||||
* \return The carry at the end of the operation.
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_mla(mbedtls_mpi_uint *X, size_t X_limbs,
|
||||
const mbedtls_mpi_uint *A, size_t A_limbs,
|
||||
mbedtls_mpi_uint b);
|
||||
|
||||
/**
|
||||
* \brief Perform a known-size multiplication
|
||||
*
|
||||
* \p X may not be aliased to any of the inputs for this function.
|
||||
* \p A may be aliased to \p B.
|
||||
*
|
||||
* \param[out] X The pointer to the (little-endian) array to receive
|
||||
* the product of \p A_limbs and \p B_limbs.
|
||||
* This must be of length \p A_limbs + \p B_limbs.
|
||||
* \param[in] A The pointer to the (little-endian) array
|
||||
* representing the first factor.
|
||||
* \param A_limbs The number of limbs in \p A.
|
||||
* \param[in] B The pointer to the (little-endian) array
|
||||
* representing the second factor.
|
||||
* \param B_limbs The number of limbs in \p B.
|
||||
*/
|
||||
void mbedtls_mpi_core_mul(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A, size_t A_limbs,
|
||||
const mbedtls_mpi_uint *B, size_t B_limbs);
|
||||
|
||||
/**
|
||||
* \brief Calculate initialisation value for fast Montgomery modular
|
||||
* multiplication
|
||||
*
|
||||
* \param[in] N Little-endian presentation of the modulus. This must have
|
||||
* at least one limb.
|
||||
*
|
||||
* \return The initialisation value for fast Montgomery modular multiplication
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_montmul_init(const mbedtls_mpi_uint *N);
|
||||
|
||||
/**
|
||||
* \brief Montgomery multiplication: X = A * B * R^-1 mod N (HAC 14.36)
|
||||
*
|
||||
* \p A and \p B must be in canonical form. That is, < \p N.
|
||||
*
|
||||
* \p X may be aliased to \p A or \p N, or even \p B (if \p AN_limbs ==
|
||||
* \p B_limbs) but may not overlap any parameters otherwise.
|
||||
*
|
||||
* \p A and \p B may alias each other, if \p AN_limbs == \p B_limbs. They may
|
||||
* not alias \p N (since they must be in canonical form, they cannot == \p N).
|
||||
*
|
||||
* \param[out] X The destination MPI, as a little-endian array of
|
||||
* length \p AN_limbs.
|
||||
* On successful completion, X contains the result of
|
||||
* the multiplication `A * B * R^-1` mod N where
|
||||
* `R = 2^(biL*AN_limbs)`.
|
||||
* \param[in] A Little-endian presentation of first operand.
|
||||
* Must have the same number of limbs as \p N.
|
||||
* \param[in] B Little-endian presentation of second operand.
|
||||
* \param[in] B_limbs The number of limbs in \p B.
|
||||
* Must be <= \p AN_limbs.
|
||||
* \param[in] N Little-endian presentation of the modulus.
|
||||
* This must be odd, and have exactly the same number
|
||||
* of limbs as \p A.
|
||||
* It may alias \p X, but must not alias or otherwise
|
||||
* overlap any of the other parameters.
|
||||
* \param[in] AN_limbs The number of limbs in \p X, \p A and \p N.
|
||||
* \param mm The Montgomery constant for \p N: -N^-1 mod 2^biL.
|
||||
* This can be calculated by `mbedtls_mpi_core_montmul_init()`.
|
||||
* \param[in,out] T Temporary storage of size at least 2*AN_limbs+1 limbs.
|
||||
* Its initial content is unused and
|
||||
* its final content is indeterminate.
|
||||
* It must not alias or otherwise overlap any of the
|
||||
* other parameters.
|
||||
*/
|
||||
void mbedtls_mpi_core_montmul(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B, size_t B_limbs,
|
||||
const mbedtls_mpi_uint *N, size_t AN_limbs,
|
||||
mbedtls_mpi_uint mm, mbedtls_mpi_uint *T);
|
||||
|
||||
/**
|
||||
* \brief Calculate the square of the Montgomery constant. (Needed
|
||||
* for conversion and operations in Montgomery form.)
|
||||
*
|
||||
* \param[out] X A pointer to the result of the calculation of
|
||||
* the square of the Montgomery constant:
|
||||
* 2^{2*n*biL} mod N.
|
||||
* \param[in] N Little-endian presentation of the modulus, which must be odd.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if there is not enough space
|
||||
* to store the value of Montgomery constant squared.
|
||||
* \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p N modulus is zero.
|
||||
* \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p N modulus is negative.
|
||||
*/
|
||||
int mbedtls_mpi_core_get_mont_r2_unsafe(mbedtls_mpi *X,
|
||||
const mbedtls_mpi *N);
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
/**
|
||||
* Copy an MPI from a table without leaking the index.
|
||||
*
|
||||
* \param dest The destination buffer. This must point to a writable
|
||||
* buffer of at least \p limbs limbs.
|
||||
* \param table The address of the table. This must point to a readable
|
||||
* array of \p count elements of \p limbs limbs each.
|
||||
* \param limbs The number of limbs in each table entry.
|
||||
* \param count The number of entries in \p table.
|
||||
* \param index The (secret) table index to look up. This must be in the
|
||||
* range `0 .. count-1`.
|
||||
*/
|
||||
void mbedtls_mpi_core_ct_uint_table_lookup(mbedtls_mpi_uint *dest,
|
||||
const mbedtls_mpi_uint *table,
|
||||
size_t limbs,
|
||||
size_t count,
|
||||
size_t index);
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
|
||||
/**
|
||||
* \brief Fill an integer with a number of random bytes.
|
||||
*
|
||||
* \param X The destination MPI.
|
||||
* \param X_limbs The number of limbs of \p X.
|
||||
* \param bytes The number of random bytes to generate.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG parameter to be passed to \p f_rng. This may be
|
||||
* \c NULL if \p f_rng doesn't need a context argument.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p X does not have
|
||||
* enough room for \p bytes bytes.
|
||||
* \return A negative error code on RNG failure.
|
||||
*
|
||||
* \note The bytes obtained from the RNG are interpreted
|
||||
* as a big-endian representation of an MPI; this can
|
||||
* be relevant in applications like deterministic ECDSA.
|
||||
*/
|
||||
int mbedtls_mpi_core_fill_random(mbedtls_mpi_uint *X, size_t X_limbs,
|
||||
size_t bytes,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/** Generate a random number uniformly in a range.
|
||||
*
|
||||
* This function generates a random number between \p min inclusive and
|
||||
* \p N exclusive.
|
||||
*
|
||||
* The procedure complies with RFC 6979 §3.3 (deterministic ECDSA)
|
||||
* when the RNG is a suitably parametrized instance of HMAC_DRBG
|
||||
* and \p min is \c 1.
|
||||
*
|
||||
* \note There are `N - min` possible outputs. The lower bound
|
||||
* \p min can be reached, but the upper bound \p N cannot.
|
||||
*
|
||||
* \param X The destination MPI, with \p limbs limbs.
|
||||
* It must not be aliased with \p N or otherwise overlap it.
|
||||
* \param min The minimum value to return.
|
||||
* \param N The upper bound of the range, exclusive, with \p limbs limbs.
|
||||
* In other words, this is one plus the maximum value to return.
|
||||
* \p N must be strictly larger than \p min.
|
||||
* \param limbs The number of limbs of \p N and \p X.
|
||||
* This must not be 0.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG parameter to be passed to \p f_rng.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was
|
||||
* unable to find a suitable value within a limited number
|
||||
* of attempts. This has a negligible probability if \p N
|
||||
* is significantly larger than \p min, which is the case
|
||||
* for all usual cryptographic applications.
|
||||
*/
|
||||
int mbedtls_mpi_core_random(mbedtls_mpi_uint *X,
|
||||
mbedtls_mpi_uint min,
|
||||
const mbedtls_mpi_uint *N,
|
||||
size_t limbs,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief Returns the number of limbs of working memory required for
|
||||
* a call to `mbedtls_mpi_core_exp_mod()`.
|
||||
*
|
||||
* \note This will always be at least
|
||||
* `mbedtls_mpi_core_montmul_working_limbs(AN_limbs)`,
|
||||
* i.e. sufficient for a call to `mbedtls_mpi_core_montmul()`.
|
||||
*
|
||||
* \param AN_limbs The number of limbs in the input `A` and the modulus `N`
|
||||
* (they must be the same size) that will be given to
|
||||
* `mbedtls_mpi_core_exp_mod()`.
|
||||
* \param E_limbs The number of limbs in the exponent `E` that will be given
|
||||
* to `mbedtls_mpi_core_exp_mod()`.
|
||||
*
|
||||
* \return The number of limbs of working memory required by
|
||||
* `mbedtls_mpi_core_exp_mod()`.
|
||||
*/
|
||||
size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs);
|
||||
|
||||
/**
|
||||
* \brief Perform a modular exponentiation with public or secret exponent:
|
||||
* X = A^E mod N, where \p A is already in Montgomery form.
|
||||
*
|
||||
* \warning This function is not constant time with respect to \p E (the exponent).
|
||||
*
|
||||
* \p X may be aliased to \p A, but not to \p RR or \p E, even if \p E_limbs ==
|
||||
* \p AN_limbs.
|
||||
*
|
||||
* \param[out] X The destination MPI, as a little endian array of length
|
||||
* \p AN_limbs.
|
||||
* \param[in] A The base MPI, as a little endian array of length \p AN_limbs.
|
||||
* Must be in Montgomery form.
|
||||
* \param[in] N The modulus, as a little endian array of length \p AN_limbs.
|
||||
* \param AN_limbs The number of limbs in \p X, \p A, \p N, \p RR.
|
||||
* \param[in] E The exponent, as a little endian array of length \p E_limbs.
|
||||
* \param E_limbs The number of limbs in \p E.
|
||||
* \param[in] RR The precomputed residue of 2^{2*biL} modulo N, as a little
|
||||
* endian array of length \p AN_limbs.
|
||||
* \param[in,out] T Temporary storage of at least the number of limbs returned
|
||||
* by `mbedtls_mpi_core_exp_mod_working_limbs()`.
|
||||
* Its initial content is unused and its final content is
|
||||
* indeterminate.
|
||||
* It must not alias or otherwise overlap any of the other
|
||||
* parameters.
|
||||
* It is up to the caller to zeroize \p T when it is no
|
||||
* longer needed, and before freeing it if it was dynamically
|
||||
* allocated.
|
||||
*/
|
||||
void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *N, size_t AN_limbs,
|
||||
const mbedtls_mpi_uint *E, size_t E_limbs,
|
||||
const mbedtls_mpi_uint *RR,
|
||||
mbedtls_mpi_uint *T);
|
||||
|
||||
/**
|
||||
* \brief Perform a modular exponentiation with secret exponent:
|
||||
* X = A^E mod N, where \p A is already in Montgomery form.
|
||||
*
|
||||
* \p X may be aliased to \p A, but not to \p RR or \p E, even if \p E_limbs ==
|
||||
* \p AN_limbs.
|
||||
*
|
||||
* \param[out] X The destination MPI, as a little endian array of length
|
||||
* \p AN_limbs.
|
||||
* \param[in] A The base MPI, as a little endian array of length \p AN_limbs.
|
||||
* Must be in Montgomery form.
|
||||
* \param[in] N The modulus, as a little endian array of length \p AN_limbs.
|
||||
* \param AN_limbs The number of limbs in \p X, \p A, \p N, \p RR.
|
||||
* \param[in] E The exponent, as a little endian array of length \p E_limbs.
|
||||
* \param E_limbs The number of limbs in \p E.
|
||||
* \param[in] RR The precomputed residue of 2^{2*biL} modulo N, as a little
|
||||
* endian array of length \p AN_limbs.
|
||||
* \param[in,out] T Temporary storage of at least the number of limbs returned
|
||||
* by `mbedtls_mpi_core_exp_mod_working_limbs()`.
|
||||
* Its initial content is unused and its final content is
|
||||
* indeterminate.
|
||||
* It must not alias or otherwise overlap any of the other
|
||||
* parameters.
|
||||
* It is up to the caller to zeroize \p T when it is no
|
||||
* longer needed, and before freeing it if it was dynamically
|
||||
* allocated.
|
||||
*/
|
||||
void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *N, size_t AN_limbs,
|
||||
const mbedtls_mpi_uint *E, size_t E_limbs,
|
||||
const mbedtls_mpi_uint *RR,
|
||||
mbedtls_mpi_uint *T);
|
||||
|
||||
/**
|
||||
* \brief Subtract unsigned integer from known-size large unsigned integers.
|
||||
* Return the borrow.
|
||||
*
|
||||
* \param[out] X The result of the subtraction.
|
||||
* \param[in] A The left operand.
|
||||
* \param b The unsigned scalar to subtract.
|
||||
* \param limbs Number of limbs of \p X and \p A.
|
||||
*
|
||||
* \return 1 if `A < b`.
|
||||
* 0 if `A >= b`.
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
mbedtls_mpi_uint b,
|
||||
size_t limbs);
|
||||
|
||||
/**
|
||||
* \brief Determine if a given MPI has the value \c 0 in constant time with
|
||||
* respect to the value (but not with respect to the number of limbs).
|
||||
*
|
||||
* \param[in] A The MPI to test.
|
||||
* \param limbs Number of limbs in \p A.
|
||||
*
|
||||
* \return MBEDTLS_CT_FALSE if `A == 0`
|
||||
* MBEDTLS_CT_TRUE if `A != 0`.
|
||||
*/
|
||||
mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
|
||||
size_t limbs);
|
||||
|
||||
/**
|
||||
* \brief Returns the number of limbs of working memory required for
|
||||
* a call to `mbedtls_mpi_core_montmul()`.
|
||||
*
|
||||
* \param AN_limbs The number of limbs in the input `A` and the modulus `N`
|
||||
* (they must be the same size) that will be given to
|
||||
* `mbedtls_mpi_core_montmul()` or one of the other functions
|
||||
* that specifies this as the amount of working memory needed.
|
||||
*
|
||||
* \return The number of limbs of working memory required by
|
||||
* `mbedtls_mpi_core_montmul()` (or other similar function).
|
||||
*/
|
||||
static inline size_t mbedtls_mpi_core_montmul_working_limbs(size_t AN_limbs)
|
||||
{
|
||||
return 2 * AN_limbs + 1;
|
||||
}
|
||||
|
||||
/** Convert an MPI into Montgomery form.
|
||||
*
|
||||
* \p X may be aliased to \p A, but may not otherwise overlap it.
|
||||
*
|
||||
* \p X may not alias \p N (it is in canonical form, so must be strictly less
|
||||
* than \p N). Nor may it alias or overlap \p rr (this is unlikely to be
|
||||
* required in practice.)
|
||||
*
|
||||
* This function is a thin wrapper around `mbedtls_mpi_core_montmul()` that is
|
||||
* an alternative to calling `mbedtls_mpi_mod_raw_to_mont_rep()` when we
|
||||
* don't want to allocate memory.
|
||||
*
|
||||
* \param[out] X The result of the conversion.
|
||||
* Must have the same number of limbs as \p A.
|
||||
* \param[in] A The MPI to convert into Montgomery form.
|
||||
* Must have the same number of limbs as the modulus.
|
||||
* \param[in] N The address of the modulus, which gives the size of
|
||||
* the base `R` = 2^(biL*N->limbs).
|
||||
* \param[in] AN_limbs The number of limbs in \p X, \p A, \p N and \p rr.
|
||||
* \param mm The Montgomery constant for \p N: -N^-1 mod 2^biL.
|
||||
* This can be determined by calling
|
||||
* `mbedtls_mpi_core_montmul_init()`.
|
||||
* \param[in] rr The residue for `2^{2*n*biL} mod N`.
|
||||
* \param[in,out] T Temporary storage of size at least
|
||||
* `mbedtls_mpi_core_montmul_working_limbs(AN_limbs)`
|
||||
* limbs.
|
||||
* Its initial content is unused and
|
||||
* its final content is indeterminate.
|
||||
* It must not alias or otherwise overlap any of the
|
||||
* other parameters.
|
||||
*/
|
||||
void mbedtls_mpi_core_to_mont_rep(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *N,
|
||||
size_t AN_limbs,
|
||||
mbedtls_mpi_uint mm,
|
||||
const mbedtls_mpi_uint *rr,
|
||||
mbedtls_mpi_uint *T);
|
||||
|
||||
/** Convert an MPI from Montgomery form.
|
||||
*
|
||||
* \p X may be aliased to \p A, but may not otherwise overlap it.
|
||||
*
|
||||
* \p X may not alias \p N (it is in canonical form, so must be strictly less
|
||||
* than \p N).
|
||||
*
|
||||
* This function is a thin wrapper around `mbedtls_mpi_core_montmul()` that is
|
||||
* an alternative to calling `mbedtls_mpi_mod_raw_from_mont_rep()` when we
|
||||
* don't want to allocate memory.
|
||||
*
|
||||
* \param[out] X The result of the conversion.
|
||||
* Must have the same number of limbs as \p A.
|
||||
* \param[in] A The MPI to convert from Montgomery form.
|
||||
* Must have the same number of limbs as the modulus.
|
||||
* \param[in] N The address of the modulus, which gives the size of
|
||||
* the base `R` = 2^(biL*N->limbs).
|
||||
* \param[in] AN_limbs The number of limbs in \p X, \p A and \p N.
|
||||
* \param mm The Montgomery constant for \p N: -N^-1 mod 2^biL.
|
||||
* This can be determined by calling
|
||||
* `mbedtls_mpi_core_montmul_init()`.
|
||||
* \param[in,out] T Temporary storage of size at least
|
||||
* `mbedtls_mpi_core_montmul_working_limbs(AN_limbs)`
|
||||
* limbs.
|
||||
* Its initial content is unused and
|
||||
* its final content is indeterminate.
|
||||
* It must not alias or otherwise overlap any of the
|
||||
* other parameters.
|
||||
*/
|
||||
void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *N,
|
||||
size_t AN_limbs,
|
||||
mbedtls_mpi_uint mm,
|
||||
mbedtls_mpi_uint *T);
|
||||
|
||||
/*
|
||||
* Can't define thread local variables with our abstraction layer: do nothing if threading is on.
|
||||
*/
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
|
||||
extern int mbedtls_mpi_optionally_safe_codepath;
|
||||
|
||||
static inline void mbedtls_mpi_optionally_safe_codepath_reset(void)
|
||||
{
|
||||
// Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
|
||||
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_CORE_H */
|
||||
50
Libs/util/third_party/mbedtls/library/bignum_internal.h
vendored
Normal file
50
Libs/util/third_party/mbedtls/library/bignum_internal.h
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* \file bignum_internal.h
|
||||
*
|
||||
* \brief Internal-only bignum public-key cryptosystem API.
|
||||
*
|
||||
* This file declares bignum-related functions that are to be used
|
||||
* only from within the Mbed TLS library itself.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_BIGNUM_INTERNAL_H
|
||||
#define MBEDTLS_BIGNUM_INTERNAL_H
|
||||
|
||||
/**
|
||||
* \brief Perform a modular exponentiation: X = A^E mod N
|
||||
*
|
||||
* \warning This function is not constant time with respect to \p E (the exponent).
|
||||
*
|
||||
* \param X The destination MPI. This must point to an initialized MPI.
|
||||
* This must not alias E or N.
|
||||
* \param A The base of the exponentiation.
|
||||
* This must point to an initialized MPI.
|
||||
* \param E The exponent MPI. This must point to an initialized MPI.
|
||||
* \param N The base for the modular reduction. This must point to an
|
||||
* initialized MPI.
|
||||
* \param prec_RR A helper MPI depending solely on \p N which can be used to
|
||||
* speed-up multiple modular exponentiations for the same value
|
||||
* of \p N. This may be \c NULL. If it is not \c NULL, it must
|
||||
* point to an initialized MPI. If it hasn't been used after
|
||||
* the call to mbedtls_mpi_init(), this function will compute
|
||||
* the helper value and store it in \p prec_RR for reuse on
|
||||
* subsequent calls to this function. Otherwise, the function
|
||||
* will assume that \p prec_RR holds the helper value set by a
|
||||
* previous call to mbedtls_mpi_exp_mod(), and reuse it.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or
|
||||
* even, or if \c E is negative.
|
||||
* \return Another negative error code on different kinds of failures.
|
||||
*
|
||||
*/
|
||||
int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
|
||||
const mbedtls_mpi *E, const mbedtls_mpi *N,
|
||||
mbedtls_mpi *prec_RR);
|
||||
|
||||
#endif /* bignum_internal.h */
|
||||
394
Libs/util/third_party/mbedtls/library/bignum_mod.c
vendored
Normal file
394
Libs/util/third_party/mbedtls/library/bignum_mod.c
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
/**
|
||||
* Modular bignum functions
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ECP_WITH_MPI_UINT)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/bignum.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "bignum_core.h"
|
||||
#include "bignum_mod.h"
|
||||
#include "bignum_mod_raw.h"
|
||||
#include "constant_time_internal.h"
|
||||
|
||||
int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
mbedtls_mpi_uint *p,
|
||||
size_t p_limbs)
|
||||
{
|
||||
if (p_limbs != N->limbs || !mbedtls_mpi_core_lt_ct(p, N->p, N->limbs)) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
r->limbs = N->limbs;
|
||||
r->p = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mbedtls_mpi_mod_residue_release(mbedtls_mpi_mod_residue *r)
|
||||
{
|
||||
if (r == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
r->limbs = 0;
|
||||
r->p = NULL;
|
||||
}
|
||||
|
||||
void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
if (N == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
N->p = NULL;
|
||||
N->limbs = 0;
|
||||
N->bits = 0;
|
||||
N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
|
||||
}
|
||||
|
||||
void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
if (N == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (N->int_rep) {
|
||||
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
|
||||
if (N->rep.mont.rr != NULL) {
|
||||
mbedtls_zeroize_and_free((mbedtls_mpi_uint *) N->rep.mont.rr,
|
||||
N->limbs * sizeof(mbedtls_mpi_uint));
|
||||
N->rep.mont.rr = NULL;
|
||||
}
|
||||
N->rep.mont.mm = 0;
|
||||
break;
|
||||
case MBEDTLS_MPI_MOD_REP_OPT_RED:
|
||||
N->rep.ored.modp = NULL;
|
||||
break;
|
||||
case MBEDTLS_MPI_MOD_REP_INVALID:
|
||||
break;
|
||||
}
|
||||
|
||||
N->p = NULL;
|
||||
N->limbs = 0;
|
||||
N->bits = 0;
|
||||
N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
|
||||
}
|
||||
|
||||
static int set_mont_const_square(const mbedtls_mpi_uint **X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
size_t limbs)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi N;
|
||||
mbedtls_mpi RR;
|
||||
*X = NULL;
|
||||
|
||||
mbedtls_mpi_init(&N);
|
||||
mbedtls_mpi_init(&RR);
|
||||
|
||||
if (A == NULL || limbs == 0 || limbs >= (MBEDTLS_MPI_MAX_LIMBS / 2) - 2) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (mbedtls_mpi_grow(&N, limbs)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memcpy(N.p, A, sizeof(mbedtls_mpi_uint) * limbs);
|
||||
|
||||
ret = mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N);
|
||||
|
||||
if (ret == 0) {
|
||||
*X = RR.p;
|
||||
RR.p = NULL;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&N);
|
||||
mbedtls_mpi_free(&RR);
|
||||
ret = (ret != 0) ? MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED : 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void standard_modulus_setup(mbedtls_mpi_mod_modulus *N,
|
||||
const mbedtls_mpi_uint *p,
|
||||
size_t p_limbs,
|
||||
mbedtls_mpi_mod_rep_selector int_rep)
|
||||
{
|
||||
N->p = p;
|
||||
N->limbs = p_limbs;
|
||||
N->bits = mbedtls_mpi_core_bitlen(p, p_limbs);
|
||||
N->int_rep = int_rep;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N,
|
||||
const mbedtls_mpi_uint *p,
|
||||
size_t p_limbs)
|
||||
{
|
||||
int ret = 0;
|
||||
standard_modulus_setup(N, p, p_limbs, MBEDTLS_MPI_MOD_REP_MONTGOMERY);
|
||||
N->rep.mont.mm = mbedtls_mpi_core_montmul_init(N->p);
|
||||
ret = set_mont_const_square(&N->rep.mont.rr, N->p, N->limbs);
|
||||
|
||||
if (ret != 0) {
|
||||
mbedtls_mpi_mod_modulus_free(N);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_optred_modulus_setup(mbedtls_mpi_mod_modulus *N,
|
||||
const mbedtls_mpi_uint *p,
|
||||
size_t p_limbs,
|
||||
mbedtls_mpi_modp_fn modp)
|
||||
{
|
||||
standard_modulus_setup(N, p, p_limbs, MBEDTLS_MPI_MOD_REP_OPT_RED);
|
||||
N->rep.ored.modp = modp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_mul(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_residue *B,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
if (N->limbs == 0) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
mbedtls_mpi_uint *T = mbedtls_calloc(N->limbs * 2 + 1, ciL);
|
||||
if (T == NULL) {
|
||||
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
mbedtls_mpi_mod_raw_mul(X->p, A->p, B->p, N, T);
|
||||
|
||||
mbedtls_free(T);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_sub(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_residue *B,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
mbedtls_mpi_mod_raw_sub(X->p, A->p, B->p, N);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mbedtls_mpi_mod_inv_mont(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
mbedtls_mpi_uint *working_memory)
|
||||
{
|
||||
/* Input already in Montgomery form, so there's little to do */
|
||||
mbedtls_mpi_mod_raw_inv_prime(X->p, A->p,
|
||||
N->p, N->limbs,
|
||||
N->rep.mont.rr,
|
||||
working_memory);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mbedtls_mpi_mod_inv_non_mont(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
mbedtls_mpi_uint *working_memory)
|
||||
{
|
||||
/* Need to convert input into Montgomery form */
|
||||
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
mbedtls_mpi_mod_modulus Nmont;
|
||||
mbedtls_mpi_mod_modulus_init(&Nmont);
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_modulus_setup(&Nmont, N->p, N->limbs));
|
||||
|
||||
/* We'll use X->p to hold the Montgomery form of the input A->p */
|
||||
mbedtls_mpi_core_to_mont_rep(X->p, A->p, Nmont.p, Nmont.limbs,
|
||||
Nmont.rep.mont.mm, Nmont.rep.mont.rr,
|
||||
working_memory);
|
||||
|
||||
mbedtls_mpi_mod_raw_inv_prime(X->p, X->p,
|
||||
Nmont.p, Nmont.limbs,
|
||||
Nmont.rep.mont.rr,
|
||||
working_memory);
|
||||
|
||||
/* And convert back from Montgomery form */
|
||||
|
||||
mbedtls_mpi_core_from_mont_rep(X->p, X->p, Nmont.p, Nmont.limbs,
|
||||
Nmont.rep.mont.mm, working_memory);
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_mod_modulus_free(&Nmont);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
if (X->limbs != N->limbs || A->limbs != N->limbs) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
/* Zero has the same value regardless of Montgomery form or not */
|
||||
if (mbedtls_mpi_core_check_zero_ct(A->p, A->limbs) == 0) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
size_t working_limbs =
|
||||
mbedtls_mpi_mod_raw_inv_prime_working_limbs(N->limbs);
|
||||
|
||||
mbedtls_mpi_uint *working_memory = mbedtls_calloc(working_limbs,
|
||||
sizeof(mbedtls_mpi_uint));
|
||||
if (working_memory == NULL) {
|
||||
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
switch (N->int_rep) {
|
||||
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
|
||||
ret = mbedtls_mpi_mod_inv_mont(X, A, N, working_memory);
|
||||
break;
|
||||
case MBEDTLS_MPI_MOD_REP_OPT_RED:
|
||||
ret = mbedtls_mpi_mod_inv_non_mont(X, A, N, working_memory);
|
||||
break;
|
||||
default:
|
||||
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
mbedtls_zeroize_and_free(working_memory,
|
||||
working_limbs * sizeof(mbedtls_mpi_uint));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_add(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_residue *B,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
mbedtls_mpi_mod_raw_add(X->p, A->p, B->p, N);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_random(mbedtls_mpi_mod_residue *X,
|
||||
mbedtls_mpi_uint min,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng)
|
||||
{
|
||||
if (X->limbs != N->limbs) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
return mbedtls_mpi_mod_raw_random(X->p, min, N, f_rng, p_rng);
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
const unsigned char *buf,
|
||||
size_t buflen,
|
||||
mbedtls_mpi_mod_ext_rep ext_rep)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
|
||||
/* Do our best to check if r and m have been set up */
|
||||
if (r->limbs == 0 || N->limbs == 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (r->limbs != N->limbs) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_mod_raw_read(r->p, N, buf, buflen, ext_rep);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
r->limbs = N->limbs;
|
||||
|
||||
ret = mbedtls_mpi_mod_raw_canonical_to_modulus_rep(r->p, N);
|
||||
|
||||
cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char *buf,
|
||||
size_t buflen,
|
||||
mbedtls_mpi_mod_ext_rep ext_rep)
|
||||
{
|
||||
/* Do our best to check if r and m have been set up */
|
||||
if (r->limbs == 0 || N->limbs == 0) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
if (r->limbs != N->limbs) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi_uint *working_memory = r->p;
|
||||
size_t working_memory_len = sizeof(mbedtls_mpi_uint) * r->limbs;
|
||||
|
||||
if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
|
||||
|
||||
working_memory = mbedtls_calloc(r->limbs, sizeof(mbedtls_mpi_uint));
|
||||
|
||||
if (working_memory == NULL) {
|
||||
ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memcpy(working_memory, r->p, working_memory_len);
|
||||
|
||||
ret = mbedtls_mpi_mod_raw_from_mont_rep(working_memory, N);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_mod_raw_write(working_memory, N, buf, buflen, ext_rep);
|
||||
|
||||
cleanup:
|
||||
|
||||
if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY &&
|
||||
working_memory != NULL) {
|
||||
|
||||
mbedtls_zeroize_and_free(working_memory, working_memory_len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ECP_WITH_MPI_UINT */
|
||||
452
Libs/util/third_party/mbedtls/library/bignum_mod.h
vendored
Normal file
452
Libs/util/third_party/mbedtls/library/bignum_mod.h
vendored
Normal file
@@ -0,0 +1,452 @@
|
||||
/**
|
||||
* Modular bignum functions
|
||||
*
|
||||
* This module implements operations on integers modulo some fixed modulus.
|
||||
*
|
||||
* The functions in this module obey the following conventions unless
|
||||
* explicitly indicated otherwise:
|
||||
*
|
||||
* - **Modulus parameters**: the modulus is passed as a pointer to a structure
|
||||
* of type #mbedtls_mpi_mod_modulus. The structure must be set up with an
|
||||
* array of limbs storing the bignum value of the modulus. The modulus must
|
||||
* be odd and is assumed to have no leading zeroes. The modulus is usually
|
||||
* named \c N and is usually input-only. Functions which take a parameter
|
||||
* of type \c const #mbedtls_mpi_mod_modulus* must not modify its value.
|
||||
* - **Bignum parameters**: Bignums are passed as pointers to an array of
|
||||
* limbs or to a #mbedtls_mpi_mod_residue structure. A limb has the type
|
||||
* #mbedtls_mpi_uint. Residues must be initialized before use, and must be
|
||||
* associated with the modulus \c N. Unless otherwise specified:
|
||||
* - Bignum parameters called \c A, \c B, ... are inputs and are not
|
||||
* modified by the function. Functions which take a parameter of
|
||||
* type \c const #mbedtls_mpi_mod_residue* must not modify its value.
|
||||
* - Bignum parameters called \c X, \c Y, ... are outputs or input-output.
|
||||
* The initial bignum value of output-only parameters is ignored, but
|
||||
* they must be set up and associated with the modulus \c N. Some
|
||||
* functions (typically constant-flow) require that the limbs in an
|
||||
* output residue are initialized.
|
||||
* - Bignum parameters called \c p are inputs used to set up a modulus or
|
||||
* residue. These must be pointers to an array of limbs.
|
||||
* - \c T is a temporary storage area. The initial content of such a
|
||||
* parameter is ignored and the final content is unspecified.
|
||||
* - Some functions use different names, such as \c r for the residue.
|
||||
* - **Bignum sizes**: bignum sizes are always expressed in limbs. Both
|
||||
* #mbedtls_mpi_mod_modulus and #mbedtls_mpi_mod_residue have a \c limbs
|
||||
* member storing its size. All bignum parameters must have the same
|
||||
* number of limbs as the modulus. All bignum sizes must be at least 1 and
|
||||
* must be significantly less than #SIZE_MAX. The behavior if a size is 0 is
|
||||
* undefined.
|
||||
* - **Bignum representation**: the representation of inputs and outputs is
|
||||
* specified by the \c int_rep field of the modulus.
|
||||
* - **Parameter ordering**: for bignum parameters, outputs come before inputs.
|
||||
* The modulus is passed after residues. Temporaries come last.
|
||||
* - **Aliasing**: in general, output bignums may be aliased to one or more
|
||||
* inputs. Modulus values may not be aliased to any other parameter. Outputs
|
||||
* may not be aliased to one another. Temporaries may not be aliased to any
|
||||
* other parameter.
|
||||
* - **Overlap**: apart from aliasing of residue pointers (where two residue
|
||||
* arguments are equal pointers), overlap is not supported and may result
|
||||
* in undefined behavior.
|
||||
* - **Error handling**: functions generally check compatibility of input
|
||||
* sizes. Most functions will not check that input values are in canonical
|
||||
* form (i.e. that \c A < \c N), this is only checked during setup of a
|
||||
* residue structure.
|
||||
* - **Modular representatives**: all functions expect inputs to be in the
|
||||
* range [0, \c N - 1] and guarantee outputs in the range [0, \c N - 1].
|
||||
* Residues are set up with an associated modulus, and operations are only
|
||||
* guaranteed to work if the modulus is associated with all residue
|
||||
* parameters. If a residue is passed with a modulus other than the one it
|
||||
* is associated with, then it may be out of range. If an input is out of
|
||||
* range, outputs are fully unspecified, though bignum values out of range
|
||||
* should not cause buffer overflows (beware that this is not extensively
|
||||
* tested).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_BIGNUM_MOD_H
|
||||
#define MBEDTLS_BIGNUM_MOD_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
#include "mbedtls/bignum.h"
|
||||
#endif
|
||||
|
||||
/** How residues associated with a modulus are represented.
|
||||
*
|
||||
* This also determines which fields of the modulus structure are valid and
|
||||
* what their contents are (see #mbedtls_mpi_mod_modulus).
|
||||
*/
|
||||
typedef enum {
|
||||
/** Representation not chosen (makes the modulus structure invalid). */
|
||||
MBEDTLS_MPI_MOD_REP_INVALID = 0,
|
||||
/* Skip 1 as it is slightly easier to accidentally pass to functions. */
|
||||
/** Montgomery representation. */
|
||||
MBEDTLS_MPI_MOD_REP_MONTGOMERY = 2,
|
||||
/* Optimised reduction available. This indicates a coordinate modulus (P)
|
||||
* and one or more of the following have been configured:
|
||||
* - A nist curve (MBEDTLS_ECP_DP_SECPXXXR1_ENABLED) & MBEDTLS_ECP_NIST_OPTIM.
|
||||
* - A Kobliz Curve.
|
||||
* - A Fast Reduction Curve CURVE25519 or CURVE448. */
|
||||
MBEDTLS_MPI_MOD_REP_OPT_RED,
|
||||
} mbedtls_mpi_mod_rep_selector;
|
||||
|
||||
/* Make mbedtls_mpi_mod_rep_selector and mbedtls_mpi_mod_ext_rep disjoint to
|
||||
* make it easier to catch when they are accidentally swapped. */
|
||||
typedef enum {
|
||||
MBEDTLS_MPI_MOD_EXT_REP_INVALID = 0,
|
||||
MBEDTLS_MPI_MOD_EXT_REP_LE = 8,
|
||||
MBEDTLS_MPI_MOD_EXT_REP_BE
|
||||
} mbedtls_mpi_mod_ext_rep;
|
||||
|
||||
typedef struct {
|
||||
mbedtls_mpi_uint *p;
|
||||
size_t limbs;
|
||||
} mbedtls_mpi_mod_residue;
|
||||
|
||||
typedef struct {
|
||||
mbedtls_mpi_uint const *rr; /* The residue for 2^{2*n*biL} mod N */
|
||||
mbedtls_mpi_uint mm; /* Montgomery const for -N^{-1} mod 2^{ciL} */
|
||||
} mbedtls_mpi_mont_struct;
|
||||
|
||||
typedef int (*mbedtls_mpi_modp_fn)(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
typedef struct {
|
||||
mbedtls_mpi_modp_fn modp; /* The optimised reduction function pointer */
|
||||
} mbedtls_mpi_opt_red_struct;
|
||||
|
||||
typedef struct {
|
||||
const mbedtls_mpi_uint *p;
|
||||
size_t limbs; // number of limbs
|
||||
size_t bits; // bitlen of p
|
||||
mbedtls_mpi_mod_rep_selector int_rep; // selector to signal the active member of the union
|
||||
union rep {
|
||||
/* if int_rep == #MBEDTLS_MPI_MOD_REP_MONTGOMERY */
|
||||
mbedtls_mpi_mont_struct mont;
|
||||
/* if int_rep == #MBEDTLS_MPI_MOD_REP_OPT_RED */
|
||||
mbedtls_mpi_opt_red_struct ored;
|
||||
} rep;
|
||||
} mbedtls_mpi_mod_modulus;
|
||||
|
||||
/** Setup a residue structure.
|
||||
*
|
||||
* The residue will be set up with the buffer \p p and modulus \p N.
|
||||
*
|
||||
* The memory pointed to by \p p will be used by the resulting residue structure.
|
||||
* The value at the pointed-to memory will be the initial value of \p r and must
|
||||
* hold a value that is less than the modulus. This value will be used as-is
|
||||
* and interpreted according to the value of the `N->int_rep` field.
|
||||
*
|
||||
* The modulus \p N will be the modulus associated with \p r. The residue \p r
|
||||
* should only be used in operations where the modulus is \p N.
|
||||
*
|
||||
* \param[out] r The address of the residue to setup.
|
||||
* \param[in] N The address of the modulus related to \p r.
|
||||
* \param[in] p The address of the limb array containing the value of \p r.
|
||||
* The memory pointed to by \p p will be used by \p r and must
|
||||
* not be modified in any way until after
|
||||
* mbedtls_mpi_mod_residue_release() is called. The data
|
||||
* pointed to by \p p must be less than the modulus (the value
|
||||
* pointed to by `N->p`) and already in the representation
|
||||
* indicated by `N->int_rep`.
|
||||
* \param p_limbs The number of limbs of \p p. Must be the same as the number
|
||||
* of limbs in the modulus \p N.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p p_limbs is less than the
|
||||
* limbs in \p N or if \p p is not less than \p N.
|
||||
*/
|
||||
int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
mbedtls_mpi_uint *p,
|
||||
size_t p_limbs);
|
||||
|
||||
/** Unbind elements of a residue structure.
|
||||
*
|
||||
* This function removes the reference to the limb array that was passed to
|
||||
* mbedtls_mpi_mod_residue_setup() to make it safe to free or use again.
|
||||
*
|
||||
* This function invalidates \p r and it must not be used until after
|
||||
* mbedtls_mpi_mod_residue_setup() is called on it again.
|
||||
*
|
||||
* \param[out] r The address of residue to release.
|
||||
*/
|
||||
void mbedtls_mpi_mod_residue_release(mbedtls_mpi_mod_residue *r);
|
||||
|
||||
/** Initialize a modulus structure.
|
||||
*
|
||||
* \param[out] N The address of the modulus structure to initialize.
|
||||
*/
|
||||
void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
/** Setup a modulus structure.
|
||||
*
|
||||
* \param[out] N The address of the modulus structure to populate.
|
||||
* \param[in] p The address of the limb array storing the value of \p N.
|
||||
* The memory pointed to by \p p will be used by \p N and must
|
||||
* not be modified in any way until after
|
||||
* mbedtls_mpi_mod_modulus_free() is called.
|
||||
* \param p_limbs The number of limbs of \p p.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
*/
|
||||
int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N,
|
||||
const mbedtls_mpi_uint *p,
|
||||
size_t p_limbs);
|
||||
|
||||
/** Setup an optimised-reduction compatible modulus structure.
|
||||
*
|
||||
* \param[out] N The address of the modulus structure to populate.
|
||||
* \param[in] p The address of the limb array storing the value of \p N.
|
||||
* The memory pointed to by \p p will be used by \p N and must
|
||||
* not be modified in any way until after
|
||||
* mbedtls_mpi_mod_modulus_free() is called.
|
||||
* \param p_limbs The number of limbs of \p p.
|
||||
* \param modp A pointer to the optimised reduction function to use. \p p.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
*/
|
||||
int mbedtls_mpi_mod_optred_modulus_setup(mbedtls_mpi_mod_modulus *N,
|
||||
const mbedtls_mpi_uint *p,
|
||||
size_t p_limbs,
|
||||
mbedtls_mpi_modp_fn modp);
|
||||
|
||||
/** Free elements of a modulus structure.
|
||||
*
|
||||
* This function frees any memory allocated by mbedtls_mpi_mod_modulus_setup().
|
||||
*
|
||||
* \warning This function does not free the limb array passed to
|
||||
* mbedtls_mpi_mod_modulus_setup() only removes the reference to it,
|
||||
* making it safe to free or to use it again.
|
||||
*
|
||||
* \param[in,out] N The address of the modulus structure to free.
|
||||
*/
|
||||
void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
/** \brief Multiply two residues, returning the residue modulo the specified
|
||||
* modulus.
|
||||
*
|
||||
* \note Currently handles the case when `N->int_rep` is
|
||||
* MBEDTLS_MPI_MOD_REP_MONTGOMERY.
|
||||
*
|
||||
* The size of the operation is determined by \p N. \p A, \p B and \p X must
|
||||
* all be associated with the modulus \p N and must all have the same number
|
||||
* of limbs as \p N.
|
||||
*
|
||||
* \p X may be aliased to \p A or \p B, or even both, but may not overlap
|
||||
* either otherwise. They may not alias \p N (since they must be in canonical
|
||||
* form, they cannot == \p N).
|
||||
*
|
||||
* \param[out] X The address of the result MPI. Must have the same
|
||||
* number of limbs as \p N.
|
||||
* On successful completion, \p X contains the result of
|
||||
* the multiplication `A * B * R^-1` mod N where
|
||||
* `R = 2^(biL * N->limbs)`.
|
||||
* \param[in] A The address of the first MPI.
|
||||
* \param[in] B The address of the second MPI.
|
||||
* \param[in] N The address of the modulus. Used to perform a modulo
|
||||
* operation on the result of the multiplication.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if all the parameters do not
|
||||
* have the same number of limbs or \p N is invalid.
|
||||
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
|
||||
*/
|
||||
int mbedtls_mpi_mod_mul(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_residue *B,
|
||||
const mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
/**
|
||||
* \brief Perform a fixed-size modular subtraction.
|
||||
*
|
||||
* Calculate `A - B modulo N`.
|
||||
*
|
||||
* \p A, \p B and \p X must all have the same number of limbs as \p N.
|
||||
*
|
||||
* \p X may be aliased to \p A or \p B, or even both, but may not overlap
|
||||
* either otherwise.
|
||||
*
|
||||
* \note This function does not check that \p A or \p B are in canonical
|
||||
* form (that is, are < \p N) - that will have been done by
|
||||
* mbedtls_mpi_mod_residue_setup().
|
||||
*
|
||||
* \param[out] X The address of the result MPI. Must be initialized.
|
||||
* Must have the same number of limbs as the modulus \p N.
|
||||
* \param[in] A The address of the first MPI.
|
||||
* \param[in] B The address of the second MPI.
|
||||
* \param[in] N The address of the modulus. Used to perform a modulo
|
||||
* operation on the result of the subtraction.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the given MPIs do not
|
||||
* have the correct number of limbs.
|
||||
*/
|
||||
int mbedtls_mpi_mod_sub(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_residue *B,
|
||||
const mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
/**
|
||||
* \brief Perform modular inversion of an MPI with respect to a modulus \p N.
|
||||
*
|
||||
* \p A and \p X must be associated with the modulus \p N and will therefore
|
||||
* have the same number of limbs as \p N.
|
||||
*
|
||||
* \p X may be aliased to \p A.
|
||||
*
|
||||
* \warning Currently only supports prime moduli, but does not check for them.
|
||||
*
|
||||
* \param[out] X The modular inverse of \p A with respect to \p N.
|
||||
* \param[in] A The number to calculate the modular inverse of.
|
||||
* Must not be 0.
|
||||
* \param[in] N The modulus to use.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p A and \p N do not
|
||||
* have the same number of limbs.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p A is zero.
|
||||
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if couldn't allocate enough
|
||||
* memory (needed for conversion to and from Mongtomery form
|
||||
* when not in Montgomery form already, and for temporary use
|
||||
* by the inversion calculation itself).
|
||||
*/
|
||||
|
||||
int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_modulus *N);
|
||||
/**
|
||||
* \brief Perform a fixed-size modular addition.
|
||||
*
|
||||
* Calculate `A + B modulo N`.
|
||||
*
|
||||
* \p A, \p B and \p X must all be associated with the modulus \p N and must
|
||||
* all have the same number of limbs as \p N.
|
||||
*
|
||||
* \p X may be aliased to \p A or \p B, or even both, but may not overlap
|
||||
* either otherwise.
|
||||
*
|
||||
* \note This function does not check that \p A or \p B are in canonical
|
||||
* form (that is, are < \p N) - that will have been done by
|
||||
* mbedtls_mpi_mod_residue_setup().
|
||||
*
|
||||
* \param[out] X The address of the result residue. Must be initialized.
|
||||
* Must have the same number of limbs as the modulus \p N.
|
||||
* \param[in] A The address of the first input residue.
|
||||
* \param[in] B The address of the second input residue.
|
||||
* \param[in] N The address of the modulus. Used to perform a modulo
|
||||
* operation on the result of the addition.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the given MPIs do not
|
||||
* have the correct number of limbs.
|
||||
*/
|
||||
int mbedtls_mpi_mod_add(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_residue *B,
|
||||
const mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
/** Generate a random number uniformly in a range.
|
||||
*
|
||||
* This function generates a random number between \p min inclusive and
|
||||
* \p N exclusive.
|
||||
*
|
||||
* The procedure complies with RFC 6979 §3.3 (deterministic ECDSA)
|
||||
* when the RNG is a suitably parametrized instance of HMAC_DRBG
|
||||
* and \p min is \c 1.
|
||||
*
|
||||
* \note There are `N - min` possible outputs. The lower bound
|
||||
* \p min can be reached, but the upper bound \p N cannot.
|
||||
*
|
||||
* \param X The destination residue.
|
||||
* \param min The minimum value to return. It must be strictly smaller
|
||||
* than \b N.
|
||||
* \param N The modulus.
|
||||
* This is the upper bound of the output range, exclusive.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG parameter to be passed to \p f_rng.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was
|
||||
* unable to find a suitable value within a limited number
|
||||
* of attempts. This has a negligible probability if \p N
|
||||
* is significantly larger than \p min, which is the case
|
||||
* for all usual cryptographic applications.
|
||||
*/
|
||||
int mbedtls_mpi_mod_random(mbedtls_mpi_mod_residue *X,
|
||||
mbedtls_mpi_uint min,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/** Read a residue from a byte buffer.
|
||||
*
|
||||
* The residue will be automatically converted to the internal representation
|
||||
* based on the value of the `N->int_rep` field.
|
||||
*
|
||||
* The modulus \p N will be the modulus associated with \p r. The residue \p r
|
||||
* should only be used in operations where the modulus is \p N or a modulus
|
||||
* equivalent to \p N (in the sense that all their fields or memory pointed by
|
||||
* their fields hold the same value).
|
||||
*
|
||||
* \param[out] r The address of the residue. It must have exactly the same
|
||||
* number of limbs as the modulus \p N.
|
||||
* \param[in] N The address of the modulus.
|
||||
* \param[in] buf The input buffer to import from.
|
||||
* \param buflen The length in bytes of \p buf.
|
||||
* \param ext_rep The endianness of the number in the input buffer.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p r isn't
|
||||
* large enough to hold the value in \p buf.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p ext_rep
|
||||
* is invalid or the value in the buffer is not less than \p N.
|
||||
*/
|
||||
int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
const unsigned char *buf,
|
||||
size_t buflen,
|
||||
mbedtls_mpi_mod_ext_rep ext_rep);
|
||||
|
||||
/** Write a residue into a byte buffer.
|
||||
*
|
||||
* The modulus \p N must be the modulus associated with \p r (see
|
||||
* mbedtls_mpi_mod_residue_setup() and mbedtls_mpi_mod_read()).
|
||||
*
|
||||
* The residue will be automatically converted from the internal representation
|
||||
* based on the value of `N->int_rep` field.
|
||||
*
|
||||
* \warning If the buffer is smaller than `N->bits`, the number of
|
||||
* leading zeroes is leaked through timing. If \p r is
|
||||
* secret, the caller must ensure that \p buflen is at least
|
||||
* (`N->bits`+7)/8.
|
||||
*
|
||||
* \param[in] r The address of the residue. It must have the same number of
|
||||
* limbs as the modulus \p N. (\p r is an input parameter, but
|
||||
* its value will be modified during execution and restored
|
||||
* before the function returns.)
|
||||
* \param[in] N The address of the modulus associated with \p r.
|
||||
* \param[out] buf The output buffer to export to.
|
||||
* \param buflen The length in bytes of \p buf.
|
||||
* \param ext_rep The endianness in which the number should be written into
|
||||
* the output buffer.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't
|
||||
* large enough to hold the value of \p r (without leading
|
||||
* zeroes).
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p ext_rep is invalid.
|
||||
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if couldn't allocate enough
|
||||
* memory for conversion. Can occur only for moduli with
|
||||
* MBEDTLS_MPI_MOD_REP_MONTGOMERY.
|
||||
*/
|
||||
int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char *buf,
|
||||
size_t buflen,
|
||||
mbedtls_mpi_mod_ext_rep ext_rep);
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_MOD_H */
|
||||
276
Libs/util/third_party/mbedtls/library/bignum_mod_raw.c
vendored
Normal file
276
Libs/util/third_party/mbedtls/library/bignum_mod_raw.c
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* Low-level modular bignum functions
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ECP_WITH_MPI_UINT)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "bignum_core.h"
|
||||
#include "bignum_mod_raw.h"
|
||||
#include "bignum_mod.h"
|
||||
#include "constant_time_internal.h"
|
||||
|
||||
#include "bignum_mod_raw_invasive.h"
|
||||
|
||||
void mbedtls_mpi_mod_raw_cond_assign(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char assign)
|
||||
{
|
||||
mbedtls_mpi_core_cond_assign(X, A, N->limbs, mbedtls_ct_bool(assign));
|
||||
}
|
||||
|
||||
void mbedtls_mpi_mod_raw_cond_swap(mbedtls_mpi_uint *X,
|
||||
mbedtls_mpi_uint *Y,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char swap)
|
||||
{
|
||||
mbedtls_mpi_core_cond_swap(X, Y, N->limbs, mbedtls_ct_bool(swap));
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_raw_read(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
const unsigned char *input,
|
||||
size_t input_length,
|
||||
mbedtls_mpi_mod_ext_rep ext_rep)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
switch (ext_rep) {
|
||||
case MBEDTLS_MPI_MOD_EXT_REP_LE:
|
||||
ret = mbedtls_mpi_core_read_le(X, N->limbs,
|
||||
input, input_length);
|
||||
break;
|
||||
case MBEDTLS_MPI_MOD_EXT_REP_BE:
|
||||
ret = mbedtls_mpi_core_read_be(X, N->limbs,
|
||||
input, input_length);
|
||||
break;
|
||||
default:
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!mbedtls_mpi_core_lt_ct(X, N->p, N->limbs)) {
|
||||
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_raw_write(const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char *output,
|
||||
size_t output_length,
|
||||
mbedtls_mpi_mod_ext_rep ext_rep)
|
||||
{
|
||||
switch (ext_rep) {
|
||||
case MBEDTLS_MPI_MOD_EXT_REP_LE:
|
||||
return mbedtls_mpi_core_write_le(A, N->limbs,
|
||||
output, output_length);
|
||||
case MBEDTLS_MPI_MOD_EXT_REP_BE:
|
||||
return mbedtls_mpi_core_write_be(A, N->limbs,
|
||||
output, output_length);
|
||||
default:
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
void mbedtls_mpi_mod_raw_sub(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, A, B, N->limbs);
|
||||
|
||||
(void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) c);
|
||||
}
|
||||
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
void mbedtls_mpi_mod_raw_fix_quasi_reduction(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, X, N->p, N->limbs);
|
||||
|
||||
(void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) c);
|
||||
}
|
||||
|
||||
|
||||
void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
mbedtls_mpi_uint *T)
|
||||
{
|
||||
/* Standard (A * B) multiplication stored into pre-allocated T
|
||||
* buffer of fixed limb size of (2N + 1).
|
||||
*
|
||||
* The space may not not fully filled by when
|
||||
* MBEDTLS_MPI_MOD_REP_OPT_RED is used. */
|
||||
const size_t T_limbs = BITS_TO_LIMBS(N->bits) * 2;
|
||||
switch (N->int_rep) {
|
||||
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
|
||||
mbedtls_mpi_core_montmul(X, A, B, N->limbs, N->p, N->limbs,
|
||||
N->rep.mont.mm, T);
|
||||
break;
|
||||
case MBEDTLS_MPI_MOD_REP_OPT_RED:
|
||||
mbedtls_mpi_core_mul(T, A, N->limbs, B, N->limbs);
|
||||
|
||||
/* Optimised Reduction */
|
||||
(*N->rep.ored.modp)(T, T_limbs);
|
||||
|
||||
/* Convert back to canonical representation */
|
||||
mbedtls_mpi_mod_raw_fix_quasi_reduction(T, N);
|
||||
memcpy(X, T, N->limbs * sizeof(mbedtls_mpi_uint));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
size_t mbedtls_mpi_mod_raw_inv_prime_working_limbs(size_t AN_limbs)
|
||||
{
|
||||
/* mbedtls_mpi_mod_raw_inv_prime() needs a temporary for the exponent,
|
||||
* which will be the same size as the modulus and input (AN_limbs),
|
||||
* and additional space to pass to mbedtls_mpi_core_exp_mod(). */
|
||||
return AN_limbs +
|
||||
mbedtls_mpi_core_exp_mod_working_limbs(AN_limbs, AN_limbs);
|
||||
}
|
||||
|
||||
void mbedtls_mpi_mod_raw_inv_prime(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *N,
|
||||
size_t AN_limbs,
|
||||
const mbedtls_mpi_uint *RR,
|
||||
mbedtls_mpi_uint *T)
|
||||
{
|
||||
/* Inversion by power: g^|G| = 1 => g^(-1) = g^(|G|-1), and
|
||||
* |G| = N - 1, so we want
|
||||
* g^(|G|-1) = g^(N - 2)
|
||||
*/
|
||||
|
||||
/* Use the first AN_limbs of T to hold N - 2 */
|
||||
mbedtls_mpi_uint *Nminus2 = T;
|
||||
(void) mbedtls_mpi_core_sub_int(Nminus2, N, 2, AN_limbs);
|
||||
|
||||
/* Rest of T is given to exp_mod for its working space */
|
||||
mbedtls_mpi_core_exp_mod(X,
|
||||
A, N, AN_limbs, Nminus2, AN_limbs,
|
||||
RR, T + AN_limbs);
|
||||
}
|
||||
|
||||
void mbedtls_mpi_mod_raw_add(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
mbedtls_mpi_uint carry, borrow;
|
||||
carry = mbedtls_mpi_core_add(X, A, B, N->limbs);
|
||||
borrow = mbedtls_mpi_core_sub(X, X, N->p, N->limbs);
|
||||
(void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) (carry ^ borrow));
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_raw_canonical_to_modulus_rep(
|
||||
mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
switch (N->int_rep) {
|
||||
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
|
||||
return mbedtls_mpi_mod_raw_to_mont_rep(X, N);
|
||||
case MBEDTLS_MPI_MOD_REP_OPT_RED:
|
||||
return 0;
|
||||
default:
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_raw_modulus_to_canonical_rep(
|
||||
mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
switch (N->int_rep) {
|
||||
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
|
||||
return mbedtls_mpi_mod_raw_from_mont_rep(X, N);
|
||||
case MBEDTLS_MPI_MOD_REP_OPT_RED:
|
||||
return 0;
|
||||
default:
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_raw_random(mbedtls_mpi_uint *X,
|
||||
mbedtls_mpi_uint min,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng)
|
||||
{
|
||||
int ret = mbedtls_mpi_core_random(X, min, N->p, N->limbs, f_rng, p_rng);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
return mbedtls_mpi_mod_raw_canonical_to_modulus_rep(X, N);
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_raw_to_mont_rep(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
mbedtls_mpi_uint *T;
|
||||
const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(N->limbs);
|
||||
|
||||
if ((T = (mbedtls_mpi_uint *) mbedtls_calloc(t_limbs, ciL)) == NULL) {
|
||||
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
mbedtls_mpi_core_to_mont_rep(X, X, N->p, N->limbs,
|
||||
N->rep.mont.mm, N->rep.mont.rr, T);
|
||||
|
||||
mbedtls_zeroize_and_free(T, t_limbs * ciL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_raw_from_mont_rep(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(N->limbs);
|
||||
mbedtls_mpi_uint *T;
|
||||
|
||||
if ((T = (mbedtls_mpi_uint *) mbedtls_calloc(t_limbs, ciL)) == NULL) {
|
||||
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
mbedtls_mpi_core_from_mont_rep(X, X, N->p, N->limbs, N->rep.mont.mm, T);
|
||||
|
||||
mbedtls_zeroize_and_free(T, t_limbs * ciL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mbedtls_mpi_mod_raw_neg(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
mbedtls_mpi_core_sub(X, N->p, A, N->limbs);
|
||||
|
||||
/* If A=0 initially, then X=N now. Detect this by
|
||||
* subtracting N and catching the carry. */
|
||||
mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub(X, X, N->p, N->limbs);
|
||||
(void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) borrow);
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ECP_WITH_MPI_UINT */
|
||||
416
Libs/util/third_party/mbedtls/library/bignum_mod_raw.h
vendored
Normal file
416
Libs/util/third_party/mbedtls/library/bignum_mod_raw.h
vendored
Normal file
@@ -0,0 +1,416 @@
|
||||
/**
|
||||
* Low-level modular bignum functions
|
||||
*
|
||||
* This interface should only be used by the higher-level modular bignum
|
||||
* module (bignum_mod.c) and the ECP module (ecp.c, ecp_curves.c). All other
|
||||
* modules should use the high-level modular bignum interface (bignum_mod.h)
|
||||
* or the legacy bignum interface (bignum.h).
|
||||
*
|
||||
* This is a low-level interface to operations on integers modulo which
|
||||
* has no protection against passing invalid arguments such as arrays of
|
||||
* the wrong size. The functions in bignum_mod.h provide a higher-level
|
||||
* interface that includes protections against accidental misuse, at the
|
||||
* expense of code size and sometimes more cumbersome memory management.
|
||||
*
|
||||
* The functions in this module obey the following conventions unless
|
||||
* explicitly indicated otherwise:
|
||||
* - **Modulus parameters**: the modulus is passed as a pointer to a structure
|
||||
* of type #mbedtls_mpi_mod_modulus. The structure must be set up with an
|
||||
* array of limbs storing the bignum value of the modulus. The modulus must
|
||||
* be odd and is assumed to have no leading zeroes. The modulus is usually
|
||||
* named \c N and is usually input-only.
|
||||
* - **Bignum parameters**: Bignums are passed as pointers to an array of
|
||||
* limbs. A limb has the type #mbedtls_mpi_uint. Unless otherwise specified:
|
||||
* - Bignum parameters called \c A, \c B, ... are inputs, and are not
|
||||
* modified by the function.
|
||||
* - Bignum parameters called \c X, \c Y are outputs or input-output.
|
||||
* The initial content of output-only parameters is ignored.
|
||||
* - \c T is a temporary storage area. The initial content of such a
|
||||
* parameter is ignored and the final content is unspecified.
|
||||
* - **Bignum sizes**: bignum sizes are usually expressed by the \c limbs
|
||||
* member of the modulus argument. All bignum parameters must have the same
|
||||
* number of limbs as the modulus. All bignum sizes must be at least 1 and
|
||||
* must be significantly less than #SIZE_MAX. The behavior if a size is 0 is
|
||||
* undefined.
|
||||
* - **Bignum representation**: the representation of inputs and outputs is
|
||||
* specified by the \c int_rep field of the modulus for arithmetic
|
||||
* functions. Utility functions may allow for different representation.
|
||||
* - **Parameter ordering**: for bignum parameters, outputs come before inputs.
|
||||
* The modulus is passed after other bignum input parameters. Temporaries
|
||||
* come last.
|
||||
* - **Aliasing**: in general, output bignums may be aliased to one or more
|
||||
* inputs. Modulus values may not be aliased to any other parameter. Outputs
|
||||
* may not be aliased to one another. Temporaries may not be aliased to any
|
||||
* other parameter.
|
||||
* - **Overlap**: apart from aliasing of limb array pointers (where two
|
||||
* arguments are equal pointers), overlap is not supported and may result
|
||||
* in undefined behavior.
|
||||
* - **Error handling**: This is a low-level module. Functions generally do not
|
||||
* try to protect against invalid arguments such as nonsensical sizes or
|
||||
* null pointers. Note that passing bignums with a different size than the
|
||||
* modulus may lead to buffer overflows. Some functions which allocate
|
||||
* memory or handle reading/writing of bignums will return an error if
|
||||
* memory allocation fails or if buffer sizes are invalid.
|
||||
* - **Modular representatives**: all functions expect inputs to be in the
|
||||
* range [0, \c N - 1] and guarantee outputs in the range [0, \c N - 1]. If
|
||||
* an input is out of range, outputs are fully unspecified, though bignum
|
||||
* values out of range should not cause buffer overflows (beware that this is
|
||||
* not extensively tested).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_BIGNUM_MOD_RAW_H
|
||||
#define MBEDTLS_BIGNUM_MOD_RAW_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
#include "mbedtls/bignum.h"
|
||||
#endif
|
||||
|
||||
#include "bignum_mod.h"
|
||||
|
||||
/**
|
||||
* \brief Perform a safe conditional copy of an MPI which doesn't reveal
|
||||
* whether the assignment was done or not.
|
||||
*
|
||||
* The size to copy is determined by \p N.
|
||||
*
|
||||
* \param[out] X The address of the destination MPI.
|
||||
* This must be initialized. Must have enough limbs to
|
||||
* store the full value of \p A.
|
||||
* \param[in] A The address of the source MPI. This must be initialized.
|
||||
* \param[in] N The address of the modulus related to \p X and \p A.
|
||||
* \param assign The condition deciding whether to perform the
|
||||
* assignment or not. Must be either 0 or 1:
|
||||
* * \c 1: Perform the assignment `X = A`.
|
||||
* * \c 0: Keep the original value of \p X.
|
||||
*
|
||||
* \note This function avoids leaking any information about whether
|
||||
* the assignment was done or not.
|
||||
*
|
||||
* \warning If \p assign is neither 0 nor 1, the result of this function
|
||||
* is indeterminate, and the resulting value in \p X might be
|
||||
* neither its original value nor the value in \p A.
|
||||
*/
|
||||
void mbedtls_mpi_mod_raw_cond_assign(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char assign);
|
||||
|
||||
/**
|
||||
* \brief Perform a safe conditional swap of two MPIs which doesn't reveal
|
||||
* whether the swap was done or not.
|
||||
*
|
||||
* The size to swap is determined by \p N.
|
||||
*
|
||||
* \param[in,out] X The address of the first MPI. This must be initialized.
|
||||
* \param[in,out] Y The address of the second MPI. This must be initialized.
|
||||
* \param[in] N The address of the modulus related to \p X and \p Y.
|
||||
* \param swap The condition deciding whether to perform
|
||||
* the swap or not. Must be either 0 or 1:
|
||||
* * \c 1: Swap the values of \p X and \p Y.
|
||||
* * \c 0: Keep the original values of \p X and \p Y.
|
||||
*
|
||||
* \note This function avoids leaking any information about whether
|
||||
* the swap was done or not.
|
||||
*
|
||||
* \warning If \p swap is neither 0 nor 1, the result of this function
|
||||
* is indeterminate, and both \p X and \p Y might end up with
|
||||
* values different to either of the original ones.
|
||||
*/
|
||||
void mbedtls_mpi_mod_raw_cond_swap(mbedtls_mpi_uint *X,
|
||||
mbedtls_mpi_uint *Y,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char swap);
|
||||
|
||||
/** Import X from unsigned binary data.
|
||||
*
|
||||
* The MPI needs to have enough limbs to store the full value (including any
|
||||
* most significant zero bytes in the input).
|
||||
*
|
||||
* \param[out] X The address of the MPI. The size is determined by \p N.
|
||||
* (In particular, it must have at least as many limbs as
|
||||
* the modulus \p N.)
|
||||
* \param[in] N The address of the modulus related to \p X.
|
||||
* \param[in] input The input buffer to import from.
|
||||
* \param input_length The length in bytes of \p input.
|
||||
* \param ext_rep The endianness of the number in the input buffer.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't
|
||||
* large enough to hold the value in \p input.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the external representation
|
||||
* of \p N is invalid or \p X is not less than \p N.
|
||||
*/
|
||||
int mbedtls_mpi_mod_raw_read(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
const unsigned char *input,
|
||||
size_t input_length,
|
||||
mbedtls_mpi_mod_ext_rep ext_rep);
|
||||
|
||||
/** Export A into unsigned binary data.
|
||||
*
|
||||
* \param[in] A The address of the MPI. The size is determined by \p N.
|
||||
* (In particular, it must have at least as many limbs as
|
||||
* the modulus \p N.)
|
||||
* \param[in] N The address of the modulus related to \p A.
|
||||
* \param[out] output The output buffer to export to.
|
||||
* \param output_length The length in bytes of \p output.
|
||||
* \param ext_rep The endianness in which the number should be written into the output buffer.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't
|
||||
* large enough to hold the value of \p A.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the external representation
|
||||
* of \p N is invalid.
|
||||
*/
|
||||
int mbedtls_mpi_mod_raw_write(const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char *output,
|
||||
size_t output_length,
|
||||
mbedtls_mpi_mod_ext_rep ext_rep);
|
||||
|
||||
/** \brief Subtract two MPIs, returning the residue modulo the specified
|
||||
* modulus.
|
||||
*
|
||||
* The size of the operation is determined by \p N. \p A and \p B must have
|
||||
* the same number of limbs as \p N.
|
||||
*
|
||||
* \p X may be aliased to \p A or \p B, or even both, but may not overlap
|
||||
* either otherwise.
|
||||
*
|
||||
* \param[out] X The address of the result MPI.
|
||||
* This must be initialized. Must have enough limbs to
|
||||
* store the full value of the result.
|
||||
* \param[in] A The address of the first MPI. This must be initialized.
|
||||
* \param[in] B The address of the second MPI. This must be initialized.
|
||||
* \param[in] N The address of the modulus. Used to perform a modulo
|
||||
* operation on the result of the subtraction.
|
||||
*/
|
||||
void mbedtls_mpi_mod_raw_sub(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
const mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
/** \brief Multiply two MPIs, returning the residue modulo the specified
|
||||
* modulus.
|
||||
*
|
||||
* \note Currently handles the case when `N->int_rep` is
|
||||
* MBEDTLS_MPI_MOD_REP_MONTGOMERY.
|
||||
*
|
||||
* The size of the operation is determined by \p N. \p A, \p B and \p X must
|
||||
* all be associated with the modulus \p N and must all have the same number
|
||||
* of limbs as \p N.
|
||||
*
|
||||
* \p X may be aliased to \p A or \p B, or even both, but may not overlap
|
||||
* either otherwise. They may not alias \p N (since they must be in canonical
|
||||
* form, they cannot == \p N).
|
||||
*
|
||||
* \param[out] X The address of the result MPI. Must have the same
|
||||
* number of limbs as \p N.
|
||||
* On successful completion, \p X contains the result of
|
||||
* the multiplication `A * B * R^-1` mod N where
|
||||
* `R = 2^(biL * N->limbs)`.
|
||||
* \param[in] A The address of the first MPI.
|
||||
* \param[in] B The address of the second MPI.
|
||||
* \param[in] N The address of the modulus. Used to perform a modulo
|
||||
* operation on the result of the multiplication.
|
||||
* \param[in,out] T Temporary storage of size at least 2 * N->limbs + 1
|
||||
* limbs. Its initial content is unused and
|
||||
* its final content is indeterminate.
|
||||
* It must not alias or otherwise overlap any of the
|
||||
* other parameters.
|
||||
*/
|
||||
void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
mbedtls_mpi_uint *T);
|
||||
|
||||
/**
|
||||
* \brief Returns the number of limbs of working memory required for
|
||||
* a call to `mbedtls_mpi_mod_raw_inv_prime()`.
|
||||
*
|
||||
* \note This will always be at least
|
||||
* `mbedtls_mpi_core_montmul_working_limbs(AN_limbs)`,
|
||||
* i.e. sufficient for a call to `mbedtls_mpi_core_montmul()`.
|
||||
*
|
||||
* \param AN_limbs The number of limbs in the input `A` and the modulus `N`
|
||||
* (they must be the same size) that will be given to
|
||||
* `mbedtls_mpi_mod_raw_inv_prime()`.
|
||||
*
|
||||
* \return The number of limbs of working memory required by
|
||||
* `mbedtls_mpi_mod_raw_inv_prime()`.
|
||||
*/
|
||||
size_t mbedtls_mpi_mod_raw_inv_prime_working_limbs(size_t AN_limbs);
|
||||
|
||||
/**
|
||||
* \brief Perform fixed-width modular inversion of a Montgomery-form MPI with
|
||||
* respect to a modulus \p N that must be prime.
|
||||
*
|
||||
* \p X may be aliased to \p A, but not to \p N or \p RR.
|
||||
*
|
||||
* \param[out] X The modular inverse of \p A with respect to \p N.
|
||||
* Will be in Montgomery form.
|
||||
* \param[in] A The number to calculate the modular inverse of.
|
||||
* Must be in Montgomery form. Must not be 0.
|
||||
* \param[in] N The modulus, as a little-endian array of length \p AN_limbs.
|
||||
* Must be prime.
|
||||
* \param AN_limbs The number of limbs in \p A, \p N and \p RR.
|
||||
* \param[in] RR The precomputed residue of 2^{2*biL} modulo N, as a little-
|
||||
* endian array of length \p AN_limbs.
|
||||
* \param[in,out] T Temporary storage of at least the number of limbs returned
|
||||
* by `mbedtls_mpi_mod_raw_inv_prime_working_limbs()`.
|
||||
* Its initial content is unused and its final content is
|
||||
* indeterminate.
|
||||
* It must not alias or otherwise overlap any of the other
|
||||
* parameters.
|
||||
* It is up to the caller to zeroize \p T when it is no
|
||||
* longer needed, and before freeing it if it was dynamically
|
||||
* allocated.
|
||||
*/
|
||||
void mbedtls_mpi_mod_raw_inv_prime(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *N,
|
||||
size_t AN_limbs,
|
||||
const mbedtls_mpi_uint *RR,
|
||||
mbedtls_mpi_uint *T);
|
||||
|
||||
/**
|
||||
* \brief Perform a known-size modular addition.
|
||||
*
|
||||
* Calculate `A + B modulo N`.
|
||||
*
|
||||
* The number of limbs in each operand, and the result, is given by the
|
||||
* modulus \p N.
|
||||
*
|
||||
* \p X may be aliased to \p A or \p B, or even both, but may not overlap
|
||||
* either otherwise.
|
||||
*
|
||||
* \param[out] X The result of the modular addition.
|
||||
* \param[in] A Little-endian presentation of the left operand. This
|
||||
* must be smaller than \p N.
|
||||
* \param[in] B Little-endian presentation of the right operand. This
|
||||
* must be smaller than \p N.
|
||||
* \param[in] N The address of the modulus.
|
||||
*/
|
||||
void mbedtls_mpi_mod_raw_add(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
const mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
/** Convert an MPI from canonical representation (little-endian limb array)
|
||||
* to the representation associated with the modulus.
|
||||
*
|
||||
* \param[in,out] X The limb array to convert.
|
||||
* It must have as many limbs as \p N.
|
||||
* It is converted in place.
|
||||
* If this function returns an error, the content of \p X
|
||||
* is unspecified.
|
||||
* \param[in] N The modulus structure.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* Otherwise an \c MBEDTLS_ERR_MPI_xxx error code.
|
||||
*/
|
||||
int mbedtls_mpi_mod_raw_canonical_to_modulus_rep(
|
||||
mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
/** Convert an MPI from the representation associated with the modulus
|
||||
* to canonical representation (little-endian limb array).
|
||||
*
|
||||
* \param[in,out] X The limb array to convert.
|
||||
* It must have as many limbs as \p N.
|
||||
* It is converted in place.
|
||||
* If this function returns an error, the content of \p X
|
||||
* is unspecified.
|
||||
* \param[in] N The modulus structure.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* Otherwise an \c MBEDTLS_ERR_MPI_xxx error code.
|
||||
*/
|
||||
int mbedtls_mpi_mod_raw_modulus_to_canonical_rep(
|
||||
mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
/** Generate a random number uniformly in a range.
|
||||
*
|
||||
* This function generates a random number between \p min inclusive and
|
||||
* \p N exclusive.
|
||||
*
|
||||
* The procedure complies with RFC 6979 §3.3 (deterministic ECDSA)
|
||||
* when the RNG is a suitably parametrized instance of HMAC_DRBG
|
||||
* and \p min is \c 1.
|
||||
*
|
||||
* \note There are `N - min` possible outputs. The lower bound
|
||||
* \p min can be reached, but the upper bound \p N cannot.
|
||||
*
|
||||
* \param X The destination MPI, in canonical representation modulo \p N.
|
||||
* It must not be aliased with \p N or otherwise overlap it.
|
||||
* \param min The minimum value to return. It must be strictly smaller
|
||||
* than \b N.
|
||||
* \param N The modulus.
|
||||
* This is the upper bound of the output range, exclusive.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG parameter to be passed to \p f_rng.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was
|
||||
* unable to find a suitable value within a limited number
|
||||
* of attempts. This has a negligible probability if \p N
|
||||
* is significantly larger than \p min, which is the case
|
||||
* for all usual cryptographic applications.
|
||||
*/
|
||||
int mbedtls_mpi_mod_raw_random(mbedtls_mpi_uint *X,
|
||||
mbedtls_mpi_uint min,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/** Convert an MPI into Montgomery form.
|
||||
*
|
||||
* \param X The address of the MPI.
|
||||
* Must have the same number of limbs as \p N.
|
||||
* \param N The address of the modulus, which gives the size of
|
||||
* the base `R` = 2^(biL*N->limbs).
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
*/
|
||||
int mbedtls_mpi_mod_raw_to_mont_rep(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
/** Convert an MPI back from Montgomery representation.
|
||||
*
|
||||
* \param X The address of the MPI.
|
||||
* Must have the same number of limbs as \p N.
|
||||
* \param N The address of the modulus, which gives the size of
|
||||
* the base `R`= 2^(biL*N->limbs).
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
*/
|
||||
int mbedtls_mpi_mod_raw_from_mont_rep(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
/** \brief Perform fixed width modular negation.
|
||||
*
|
||||
* The size of the operation is determined by \p N. \p A must have
|
||||
* the same number of limbs as \p N.
|
||||
*
|
||||
* \p X may be aliased to \p A.
|
||||
*
|
||||
* \param[out] X The result of the modular negation.
|
||||
* This must be initialized.
|
||||
* \param[in] A Little-endian presentation of the input operand. This
|
||||
* must be less than or equal to \p N.
|
||||
* \param[in] N The modulus to use.
|
||||
*/
|
||||
void mbedtls_mpi_mod_raw_neg(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_MOD_RAW_H */
|
||||
34
Libs/util/third_party/mbedtls/library/bignum_mod_raw_invasive.h
vendored
Normal file
34
Libs/util/third_party/mbedtls/library/bignum_mod_raw_invasive.h
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* \file bignum_mod_raw_invasive.h
|
||||
*
|
||||
* \brief Function declarations for invasive functions of Low-level
|
||||
* modular bignum.
|
||||
*/
|
||||
/**
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_BIGNUM_MOD_RAW_INVASIVE_H
|
||||
#define MBEDTLS_BIGNUM_MOD_RAW_INVASIVE_H
|
||||
|
||||
#include "common.h"
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "bignum_mod.h"
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
|
||||
/** Convert the result of a quasi-reduction to its canonical representative.
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted. Must have the
|
||||
* same number of limbs as \p N. The input value must
|
||||
* be in range 0 <= X < 2N.
|
||||
* \param[in] N The address of the modulus.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
void mbedtls_mpi_mod_raw_fix_quasi_reduction(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *N);
|
||||
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_MOD_RAW_INVASIVE_H */
|
||||
207
Libs/util/third_party/mbedtls/library/block_cipher.c
vendored
Normal file
207
Libs/util/third_party/mbedtls/library/block_cipher.c
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* \file block_cipher.c
|
||||
*
|
||||
* \brief Lightweight abstraction layer for block ciphers with 128 bit blocks,
|
||||
* for use by the GCM and CCM modules.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_util_internal.h"
|
||||
#endif
|
||||
|
||||
#include "block_cipher_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
static psa_key_type_t psa_key_type_from_block_cipher_id(mbedtls_block_cipher_id_t cipher_id)
|
||||
{
|
||||
switch (cipher_id) {
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
return PSA_KEY_TYPE_AES;
|
||||
#endif
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
return PSA_KEY_TYPE_ARIA;
|
||||
#endif
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
return PSA_KEY_TYPE_CAMELLIA;
|
||||
#endif
|
||||
default:
|
||||
return PSA_KEY_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static int mbedtls_cipher_error_from_psa(psa_status_t status)
|
||||
{
|
||||
return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_cipher_errors,
|
||||
psa_generic_status_to_mbedtls);
|
||||
}
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */
|
||||
|
||||
void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
|
||||
psa_destroy_key(ctx->psa_key_id);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
switch (ctx->id) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
mbedtls_aes_free(&ctx->ctx.aes);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
mbedtls_aria_free(&ctx->ctx.aria);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
mbedtls_camellia_free(&ctx->ctx.camellia);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE;
|
||||
}
|
||||
|
||||
int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx,
|
||||
mbedtls_cipher_id_t cipher_id)
|
||||
{
|
||||
ctx->id = (cipher_id == MBEDTLS_CIPHER_ID_AES) ? MBEDTLS_BLOCK_CIPHER_ID_AES :
|
||||
(cipher_id == MBEDTLS_CIPHER_ID_ARIA) ? MBEDTLS_BLOCK_CIPHER_ID_ARIA :
|
||||
(cipher_id == MBEDTLS_CIPHER_ID_CAMELLIA) ? MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA :
|
||||
MBEDTLS_BLOCK_CIPHER_ID_NONE;
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
psa_key_type_t psa_key_type = psa_key_type_from_block_cipher_id(ctx->id);
|
||||
if (psa_key_type != PSA_KEY_TYPE_NONE &&
|
||||
psa_can_do_cipher(psa_key_type, PSA_ALG_ECB_NO_PADDING)) {
|
||||
ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_PSA;
|
||||
return 0;
|
||||
}
|
||||
ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY;
|
||||
#endif
|
||||
|
||||
switch (ctx->id) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
mbedtls_aes_init(&ctx->ctx.aes);
|
||||
return 0;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
mbedtls_aria_init(&ctx->ctx.aria);
|
||||
return 0;
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
mbedtls_camellia_init(&ctx->ctx.camellia);
|
||||
return 0;
|
||||
#endif
|
||||
default:
|
||||
ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE;
|
||||
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned key_bitlen)
|
||||
{
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status;
|
||||
|
||||
psa_set_key_type(&key_attr, psa_key_type_from_block_cipher_id(ctx->id));
|
||||
psa_set_key_bits(&key_attr, key_bitlen);
|
||||
psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);
|
||||
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT);
|
||||
|
||||
status = psa_import_key(&key_attr, key, PSA_BITS_TO_BYTES(key_bitlen), &ctx->psa_key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return mbedtls_cipher_error_from_psa(status);
|
||||
}
|
||||
psa_reset_key_attributes(&key_attr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */
|
||||
|
||||
switch (ctx->id) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
return mbedtls_aes_setkey_enc(&ctx->ctx.aes, key, key_bitlen);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
return mbedtls_aria_setkey_enc(&ctx->ctx.aria, key, key_bitlen);
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
return mbedtls_camellia_setkey_enc(&ctx->ctx.camellia, key, key_bitlen);
|
||||
#endif
|
||||
default:
|
||||
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16])
|
||||
{
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
|
||||
psa_status_t status;
|
||||
size_t olen;
|
||||
|
||||
status = psa_cipher_encrypt(ctx->psa_key_id, PSA_ALG_ECB_NO_PADDING,
|
||||
input, 16, output, 16, &olen);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return mbedtls_cipher_error_from_psa(status);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */
|
||||
|
||||
switch (ctx->id) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
return mbedtls_aes_crypt_ecb(&ctx->ctx.aes, MBEDTLS_AES_ENCRYPT,
|
||||
input, output);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
return mbedtls_aria_crypt_ecb(&ctx->ctx.aria, input, output);
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
return mbedtls_camellia_crypt_ecb(&ctx->ctx.camellia,
|
||||
MBEDTLS_CAMELLIA_ENCRYPT,
|
||||
input, output);
|
||||
#endif
|
||||
default:
|
||||
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_C */
|
||||
99
Libs/util/third_party/mbedtls/library/block_cipher_internal.h
vendored
Normal file
99
Libs/util/third_party/mbedtls/library/block_cipher_internal.h
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* \file block_cipher_internal.h
|
||||
*
|
||||
* \brief Lightweight abstraction layer for block ciphers with 128 bit blocks,
|
||||
* for use by the GCM and CCM modules.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_BLOCK_CIPHER_INTERNAL_H
|
||||
#define MBEDTLS_BLOCK_CIPHER_INTERNAL_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "mbedtls/cipher.h"
|
||||
|
||||
#include "mbedtls/block_cipher.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initialize the context.
|
||||
* This must be the first API call before using the context.
|
||||
*
|
||||
* \param ctx The context to initialize.
|
||||
*/
|
||||
static inline void mbedtls_block_cipher_init(mbedtls_block_cipher_context_t *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the block cipher to use with this context.
|
||||
* This must be called after mbedtls_block_cipher_init().
|
||||
*
|
||||
* \param ctx The context to set up.
|
||||
* \param cipher_id The identifier of the cipher to use.
|
||||
* This must be either AES, ARIA or Camellia.
|
||||
* Warning: this is a ::mbedtls_cipher_id_t,
|
||||
* not a ::mbedtls_block_cipher_id_t!
|
||||
*
|
||||
* \retval \c 0 on success.
|
||||
* \retval #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if \p cipher_id was
|
||||
* invalid.
|
||||
*/
|
||||
int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx,
|
||||
mbedtls_cipher_id_t cipher_id);
|
||||
|
||||
/**
|
||||
* \brief Set the key into the context.
|
||||
*
|
||||
* \param ctx The context to configure.
|
||||
* \param key The buffer holding the key material.
|
||||
* \param key_bitlen The size of the key in bits.
|
||||
*
|
||||
* \retval \c 0 on success.
|
||||
* \retval #MBEDTLS_ERR_CIPHER_INVALID_CONTEXT if the context was not
|
||||
* properly set up before calling this function.
|
||||
* \retval One of #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH,
|
||||
* #MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
|
||||
* #MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA if \p key_bitlen is
|
||||
* invalid.
|
||||
*/
|
||||
int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned key_bitlen);
|
||||
|
||||
/**
|
||||
* \brief Encrypt one block (16 bytes) with the configured key.
|
||||
*
|
||||
* \param ctx The context holding the key.
|
||||
* \param input The buffer holding the input block. Must be 16 bytes.
|
||||
* \param output The buffer to which the output block will be written.
|
||||
* Must be writable and 16 bytes long.
|
||||
* This must either not overlap with \p input, or be equal.
|
||||
*
|
||||
* \retval \c 0 on success.
|
||||
* \retval #MBEDTLS_ERR_CIPHER_INVALID_CONTEXT if the context was not
|
||||
* properly set up before calling this function.
|
||||
* \retval Another negative value if encryption failed.
|
||||
*/
|
||||
int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16]);
|
||||
/**
|
||||
* \brief Clear the context.
|
||||
*
|
||||
* \param ctx The context to clear.
|
||||
*/
|
||||
void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_INTERNAL_H */
|
||||
1094
Libs/util/third_party/mbedtls/library/bn_mul.h
vendored
Normal file
1094
Libs/util/third_party/mbedtls/library/bn_mul.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
141
Libs/util/third_party/mbedtls/library/check_crypto_config.h
vendored
Normal file
141
Libs/util/third_party/mbedtls/library/check_crypto_config.h
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* \file check_crypto_config.h
|
||||
*
|
||||
* \brief Consistency checks for PSA configuration options
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* It is recommended to include this file from your crypto_config.h
|
||||
* in order to catch dependency issues early.
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CHECK_CRYPTO_CONFIG_H
|
||||
#define MBEDTLS_CHECK_CRYPTO_CONFIG_H
|
||||
|
||||
#if defined(PSA_WANT_ALG_CCM) && \
|
||||
!(defined(PSA_WANT_KEY_TYPE_AES) || \
|
||||
defined(PSA_WANT_KEY_TYPE_CAMELLIA))
|
||||
#error "PSA_WANT_ALG_CCM defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_CMAC) && \
|
||||
!(defined(PSA_WANT_KEY_TYPE_AES) || \
|
||||
defined(PSA_WANT_KEY_TYPE_CAMELLIA) || \
|
||||
defined(PSA_WANT_KEY_TYPE_DES))
|
||||
#error "PSA_WANT_ALG_CMAC defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \
|
||||
!(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY))
|
||||
#error "PSA_WANT_ALG_DETERMINISTIC_ECDSA defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_ECDSA) && \
|
||||
!(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY))
|
||||
#error "PSA_WANT_ALG_ECDSA defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_GCM) && \
|
||||
!(defined(PSA_WANT_KEY_TYPE_AES) || \
|
||||
defined(PSA_WANT_KEY_TYPE_CAMELLIA))
|
||||
#error "PSA_WANT_ALG_GCM defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) && \
|
||||
!(defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \
|
||||
defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY))
|
||||
#error "PSA_WANT_ALG_RSA_PKCS1V15_CRYPT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) && \
|
||||
!(defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \
|
||||
defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY))
|
||||
#error "PSA_WANT_ALG_RSA_PKCS1V15_SIGN defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_RSA_OAEP) && \
|
||||
!(defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \
|
||||
defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY))
|
||||
#error "PSA_WANT_ALG_RSA_OAEP defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_RSA_PSS) && \
|
||||
!(defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \
|
||||
defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY))
|
||||
#error "PSA_WANT_ALG_RSA_PSS defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) || \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE)) && \
|
||||
!defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
#error "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_xxx defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if (defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \
|
||||
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \
|
||||
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
|
||||
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)) && \
|
||||
!defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
#error "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_xxx defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if (defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) || \
|
||||
defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \
|
||||
defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
|
||||
defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)) && \
|
||||
!defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY)
|
||||
#error "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_xxx defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
|
||||
#if defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
#error "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR is deprecated and will be removed in a \
|
||||
future version of Mbed TLS. Please switch to new PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_xxx \
|
||||
symbols, where xxx can be: USE, IMPORT, EXPORT, GENERATE, DERIVE"
|
||||
#elif defined(MBEDTLS_DEPRECATED_WARNING)
|
||||
#warning "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR is deprecated and will be removed in a \
|
||||
future version of Mbed TLS. Please switch to new PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_xxx \
|
||||
symbols, where xxx can be: USE, IMPORT, EXPORT, GENERATE, DERIVE"
|
||||
#endif /* MBEDTLS_DEPRECATED_WARNING */
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
|
||||
#if defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
#error "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR is deprecated and will be removed in a \
|
||||
future version of Mbed TLS. Please switch to new PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_xxx \
|
||||
symbols, where xxx can be: USE, IMPORT, EXPORT, GENERATE, DERIVE"
|
||||
#elif defined(MBEDTLS_DEPRECATED_WARNING)
|
||||
#warning "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR is deprecated and will be removed in a \
|
||||
future version of Mbed TLS. Please switch to new PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_xxx \
|
||||
symbols, where xxx can be: USE, IMPORT, EXPORT, GENERATE, DERIVE"
|
||||
#endif /* MBEDTLS_DEPRECATED_WARNING */
|
||||
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE)
|
||||
#error "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE defined, but feature is not supported"
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_DERIVE)
|
||||
#error "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_DERIVE defined, but feature is not supported"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
!(defined(PSA_WANT_ALG_SHA_1) || defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_512))
|
||||
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS) && \
|
||||
!defined(PSA_WANT_ALG_SHA_256)
|
||||
#error "PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CHECK_CRYPTO_CONFIG_H */
|
||||
1689
Libs/util/third_party/mbedtls/library/cipher.c
vendored
Normal file
1689
Libs/util/third_party/mbedtls/library/cipher.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2483
Libs/util/third_party/mbedtls/library/cipher_wrap.c
vendored
Normal file
2483
Libs/util/third_party/mbedtls/library/cipher_wrap.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
178
Libs/util/third_party/mbedtls/library/cipher_wrap.h
vendored
Normal file
178
Libs/util/third_party/mbedtls/library/cipher_wrap.h
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* \file cipher_wrap.h
|
||||
*
|
||||
* \brief Cipher wrappers.
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_CIPHER_WRAP_H
|
||||
#define MBEDTLS_CIPHER_WRAP_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "mbedtls/cipher.h"
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Support for GCM either through Mbed TLS SW implementation or PSA */
|
||||
#if defined(MBEDTLS_GCM_C) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_GCM))
|
||||
#define MBEDTLS_CIPHER_HAVE_GCM_VIA_LEGACY_OR_USE_PSA
|
||||
#endif
|
||||
|
||||
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_AES_C)) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_GCM) && defined(PSA_WANT_KEY_TYPE_AES))
|
||||
#define MBEDTLS_CIPHER_HAVE_GCM_AES_VIA_LEGACY_OR_USE_PSA
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CCM_C) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CCM))
|
||||
#define MBEDTLS_CIPHER_HAVE_CCM_VIA_LEGACY_OR_USE_PSA
|
||||
#endif
|
||||
|
||||
#if (defined(MBEDTLS_CCM_C) && defined(MBEDTLS_AES_C)) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CCM) && defined(PSA_WANT_KEY_TYPE_AES))
|
||||
#define MBEDTLS_CIPHER_HAVE_CCM_AES_VIA_LEGACY_OR_USE_PSA
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CCM_C) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CCM_STAR_NO_TAG))
|
||||
#define MBEDTLS_CIPHER_HAVE_CCM_STAR_NO_TAG_VIA_LEGACY_OR_USE_PSA
|
||||
#endif
|
||||
|
||||
#if (defined(MBEDTLS_CCM_C) && defined(MBEDTLS_AES_C)) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) && \
|
||||
defined(PSA_WANT_KEY_TYPE_AES))
|
||||
#define MBEDTLS_CIPHER_HAVE_CCM_STAR_NO_TAG_AES_VIA_LEGACY_OR_USE_PSA
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CHACHAPOLY_C) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CHACHA20_POLY1305))
|
||||
#define MBEDTLS_CIPHER_HAVE_CHACHAPOLY_VIA_LEGACY_OR_USE_PSA
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_HAVE_GCM_VIA_LEGACY_OR_USE_PSA) || \
|
||||
defined(MBEDTLS_CIPHER_HAVE_CCM_VIA_LEGACY_OR_USE_PSA) || \
|
||||
defined(MBEDTLS_CIPHER_HAVE_CCM_STAR_NO_TAG_VIA_LEGACY_OR_USE_PSA) || \
|
||||
defined(MBEDTLS_CIPHER_HAVE_CHACHAPOLY_VIA_LEGACY_OR_USE_PSA)
|
||||
#define MBEDTLS_CIPHER_HAVE_SOME_AEAD_VIA_LEGACY_OR_USE_PSA
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Base cipher information. The non-mode specific functions and values.
|
||||
*/
|
||||
struct mbedtls_cipher_base_t {
|
||||
/** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */
|
||||
mbedtls_cipher_id_t cipher;
|
||||
|
||||
/** Encrypt using ECB */
|
||||
int (*ecb_func)(void *ctx, mbedtls_operation_t mode,
|
||||
const unsigned char *input, unsigned char *output);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/** Encrypt using CBC */
|
||||
int (*cbc_func)(void *ctx, mbedtls_operation_t mode, size_t length,
|
||||
unsigned char *iv, const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
/** Encrypt using CFB (Full length) */
|
||||
int (*cfb_func)(void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off,
|
||||
unsigned char *iv, const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_OFB)
|
||||
/** Encrypt using OFB (Full length) */
|
||||
int (*ofb_func)(void *ctx, size_t length, size_t *iv_off,
|
||||
unsigned char *iv,
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||
/** Encrypt using CTR */
|
||||
int (*ctr_func)(void *ctx, size_t length, size_t *nc_off,
|
||||
unsigned char *nonce_counter, unsigned char *stream_block,
|
||||
const unsigned char *input, unsigned char *output);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
/** Encrypt or decrypt using XTS. */
|
||||
int (*xts_func)(void *ctx, mbedtls_operation_t mode, size_t length,
|
||||
const unsigned char data_unit[16],
|
||||
const unsigned char *input, unsigned char *output);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
|
||||
/** Encrypt using STREAM */
|
||||
int (*stream_func)(void *ctx, size_t length,
|
||||
const unsigned char *input, unsigned char *output);
|
||||
#endif
|
||||
|
||||
/** Set key for encryption purposes */
|
||||
int (*setkey_enc_func)(void *ctx, const unsigned char *key,
|
||||
unsigned int key_bitlen);
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
/** Set key for decryption purposes */
|
||||
int (*setkey_dec_func)(void *ctx, const unsigned char *key,
|
||||
unsigned int key_bitlen);
|
||||
#endif
|
||||
|
||||
/** Allocate a new context */
|
||||
void * (*ctx_alloc_func)(void);
|
||||
|
||||
/** Free the given context */
|
||||
void (*ctx_free_func)(void *ctx);
|
||||
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
mbedtls_cipher_type_t type;
|
||||
const mbedtls_cipher_info_t *info;
|
||||
} mbedtls_cipher_definition_t;
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
typedef enum {
|
||||
MBEDTLS_CIPHER_PSA_KEY_UNSET = 0,
|
||||
MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */
|
||||
/* use raw key material internally imported */
|
||||
/* as a volatile key, and which hence need */
|
||||
/* to destroy that key when the context is */
|
||||
/* freed. */
|
||||
MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */
|
||||
/* which use a key provided by the */
|
||||
/* user, and which hence will not be */
|
||||
/* destroyed when the context is freed. */
|
||||
} mbedtls_cipher_psa_key_ownership;
|
||||
|
||||
typedef struct {
|
||||
psa_algorithm_t alg;
|
||||
mbedtls_svc_key_id_t slot;
|
||||
mbedtls_cipher_psa_key_ownership slot_state;
|
||||
} mbedtls_cipher_context_psa;
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
|
||||
|
||||
extern int mbedtls_cipher_supported[];
|
||||
|
||||
extern const mbedtls_cipher_base_t *mbedtls_cipher_base_lookup_table[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CIPHER_WRAP_H */
|
||||
1067
Libs/util/third_party/mbedtls/library/cmac.c
vendored
Normal file
1067
Libs/util/third_party/mbedtls/library/cmac.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
437
Libs/util/third_party/mbedtls/library/common.h
vendored
Normal file
437
Libs/util/third_party/mbedtls/library/common.h
vendored
Normal file
@@ -0,0 +1,437 @@
|
||||
/**
|
||||
* \file common.h
|
||||
*
|
||||
* \brief Utility macros for internal use in the library
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_LIBRARY_COMMON_H
|
||||
#define MBEDTLS_LIBRARY_COMMON_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
#include "alignment.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(__ARM_NEON)
|
||||
#include <arm_neon.h>
|
||||
#define MBEDTLS_HAVE_NEON_INTRINSICS
|
||||
#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
|
||||
#include <arm64_neon.h>
|
||||
#define MBEDTLS_HAVE_NEON_INTRINSICS
|
||||
#endif
|
||||
|
||||
/** Helper to define a function as static except when building invasive tests.
|
||||
*
|
||||
* If a function is only used inside its own source file and should be
|
||||
* declared `static` to allow the compiler to optimize for code size,
|
||||
* but that function has unit tests, define it with
|
||||
* ```
|
||||
* MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... }
|
||||
* ```
|
||||
* and declare it in a header in the `library/` directory with
|
||||
* ```
|
||||
* #if defined(MBEDTLS_TEST_HOOKS)
|
||||
* int mbedtls_foo(...);
|
||||
* #endif
|
||||
* ```
|
||||
*/
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
#define MBEDTLS_STATIC_TESTABLE
|
||||
#else
|
||||
#define MBEDTLS_STATIC_TESTABLE static
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
extern void (*mbedtls_test_hook_test_fail)(const char *test, int line, const char *file);
|
||||
#define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST) \
|
||||
do { \
|
||||
if ((!(TEST)) && ((*mbedtls_test_hook_test_fail) != NULL)) \
|
||||
{ \
|
||||
(*mbedtls_test_hook_test_fail)( #TEST, __LINE__, __FILE__); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST)
|
||||
#endif /* defined(MBEDTLS_TEST_HOOKS) */
|
||||
|
||||
/** \def ARRAY_LENGTH
|
||||
* Return the number of elements of a static or stack array.
|
||||
*
|
||||
* \param array A value of array (not pointer) type.
|
||||
*
|
||||
* \return The number of elements of the array.
|
||||
*/
|
||||
/* A correct implementation of ARRAY_LENGTH, but which silently gives
|
||||
* a nonsensical result if called with a pointer rather than an array. */
|
||||
#define ARRAY_LENGTH_UNSAFE(array) \
|
||||
(sizeof(array) / sizeof(*(array)))
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/* Test if arg and &(arg)[0] have the same type. This is true if arg is
|
||||
* an array but not if it's a pointer. */
|
||||
#define IS_ARRAY_NOT_POINTER(arg) \
|
||||
(!__builtin_types_compatible_p(__typeof__(arg), \
|
||||
__typeof__(&(arg)[0])))
|
||||
/* A compile-time constant with the value 0. If `const_expr` is not a
|
||||
* compile-time constant with a nonzero value, cause a compile-time error. */
|
||||
#define STATIC_ASSERT_EXPR(const_expr) \
|
||||
(0 && sizeof(struct { unsigned int STATIC_ASSERT : 1 - 2 * !(const_expr); }))
|
||||
|
||||
/* Return the scalar value `value` (possibly promoted). This is a compile-time
|
||||
* constant if `value` is. `condition` must be a compile-time constant.
|
||||
* If `condition` is false, arrange to cause a compile-time error. */
|
||||
#define STATIC_ASSERT_THEN_RETURN(condition, value) \
|
||||
(STATIC_ASSERT_EXPR(condition) ? 0 : (value))
|
||||
|
||||
#define ARRAY_LENGTH(array) \
|
||||
(STATIC_ASSERT_THEN_RETURN(IS_ARRAY_NOT_POINTER(array), \
|
||||
ARRAY_LENGTH_UNSAFE(array)))
|
||||
|
||||
#else
|
||||
/* If we aren't sure the compiler supports our non-standard tricks,
|
||||
* fall back to the unsafe implementation. */
|
||||
#define ARRAY_LENGTH(array) ARRAY_LENGTH_UNSAFE(array)
|
||||
#endif
|
||||
/** Allow library to access its structs' private members.
|
||||
*
|
||||
* Although structs defined in header files are publicly available,
|
||||
* their members are private and should not be accessed by the user.
|
||||
*/
|
||||
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
|
||||
|
||||
/**
|
||||
* \brief Securely zeroize a buffer then free it.
|
||||
*
|
||||
* Similar to making consecutive calls to
|
||||
* \c mbedtls_platform_zeroize() and \c mbedtls_free(), but has
|
||||
* code size savings, and potential for optimisation in the future.
|
||||
*
|
||||
* Guaranteed to be a no-op if \p buf is \c NULL and \p len is 0.
|
||||
*
|
||||
* \param buf Buffer to be zeroized then freed.
|
||||
* \param len Length of the buffer in bytes
|
||||
*/
|
||||
void mbedtls_zeroize_and_free(void *buf, size_t len);
|
||||
|
||||
/** Return an offset into a buffer.
|
||||
*
|
||||
* This is just the addition of an offset to a pointer, except that this
|
||||
* function also accepts an offset of 0 into a buffer whose pointer is null.
|
||||
* (`p + n` has undefined behavior when `p` is null, even when `n == 0`.
|
||||
* A null pointer is a valid buffer pointer when the size is 0, for example
|
||||
* as the result of `malloc(0)` on some platforms.)
|
||||
*
|
||||
* \param p Pointer to a buffer of at least n bytes.
|
||||
* This may be \p NULL if \p n is zero.
|
||||
* \param n An offset in bytes.
|
||||
* \return Pointer to offset \p n in the buffer \p p.
|
||||
* Note that this is only a valid pointer if the size of the
|
||||
* buffer is at least \p n + 1.
|
||||
*/
|
||||
static inline unsigned char *mbedtls_buffer_offset(
|
||||
unsigned char *p, size_t n)
|
||||
{
|
||||
return p == NULL ? NULL : p + n;
|
||||
}
|
||||
|
||||
/** Return an offset into a read-only buffer.
|
||||
*
|
||||
* Similar to mbedtls_buffer_offset(), but for const pointers.
|
||||
*
|
||||
* \param p Pointer to a buffer of at least n bytes.
|
||||
* This may be \p NULL if \p n is zero.
|
||||
* \param n An offset in bytes.
|
||||
* \return Pointer to offset \p n in the buffer \p p.
|
||||
* Note that this is only a valid pointer if the size of the
|
||||
* buffer is at least \p n + 1.
|
||||
*/
|
||||
static inline const unsigned char *mbedtls_buffer_offset_const(
|
||||
const unsigned char *p, size_t n)
|
||||
{
|
||||
return p == NULL ? NULL : p + n;
|
||||
}
|
||||
|
||||
/* Always inline mbedtls_xor() for similar reasons as mbedtls_xor_no_simd(). */
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
/**
|
||||
* Perform a fast block XOR operation, such that
|
||||
* r[i] = a[i] ^ b[i] where 0 <= i < n
|
||||
*
|
||||
* \param r Pointer to result (buffer of at least \p n bytes). \p r
|
||||
* may be equal to either \p a or \p b, but behaviour when
|
||||
* it overlaps in other ways is undefined.
|
||||
* \param a Pointer to input (buffer of at least \p n bytes)
|
||||
* \param b Pointer to input (buffer of at least \p n bytes)
|
||||
* \param n Number of bytes to process.
|
||||
*
|
||||
* \note Depending on the situation, it may be faster to use either mbedtls_xor() or
|
||||
* mbedtls_xor_no_simd() (these are functionally equivalent).
|
||||
* If the result is used immediately after the xor operation in non-SIMD code (e.g, in
|
||||
* AES-CBC), there may be additional latency to transfer the data from SIMD to scalar
|
||||
* registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where
|
||||
* the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster.
|
||||
* For targets without SIMD support, they will behave the same.
|
||||
*/
|
||||
static inline void mbedtls_xor(unsigned char *r,
|
||||
const unsigned char *a,
|
||||
const unsigned char *b,
|
||||
size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
|
||||
#if defined(MBEDTLS_HAVE_NEON_INTRINSICS) && \
|
||||
(!(defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_GCC_VERSION < 70300))
|
||||
/* Old GCC versions generate a warning here, so disable the NEON path for these compilers */
|
||||
for (; (i + 16) <= n; i += 16) {
|
||||
uint8x16_t v1 = vld1q_u8(a + i);
|
||||
uint8x16_t v2 = vld1q_u8(b + i);
|
||||
uint8x16_t x = veorq_u8(v1, v2);
|
||||
vst1q_u8(r + i, x);
|
||||
}
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
/* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case
|
||||
* where n is a constant multiple of 16.
|
||||
* For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time
|
||||
* constant, and is a very small perf regression if n is not a compile-time constant. */
|
||||
if (n % 16 == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#elif defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
|
||||
/* This codepath probably only makes sense on architectures with 64-bit registers */
|
||||
for (; (i + 8) <= n; i += 8) {
|
||||
uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
|
||||
mbedtls_put_unaligned_uint64(r + i, x);
|
||||
}
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
if (n % 8 == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
for (; (i + 4) <= n; i += 4) {
|
||||
uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
|
||||
mbedtls_put_unaligned_uint32(r + i, x);
|
||||
}
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
if (n % 4 == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
for (; i < n; i++) {
|
||||
r[i] = a[i] ^ b[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Always inline mbedtls_xor_no_simd() as we see significant perf regressions when it does not get
|
||||
* inlined (e.g., observed about 3x perf difference in gcm_mult_largetable with gcc 7 - 12) */
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
/**
|
||||
* Perform a fast block XOR operation, such that
|
||||
* r[i] = a[i] ^ b[i] where 0 <= i < n
|
||||
*
|
||||
* In some situations, this can perform better than mbedtls_xor() (e.g., it's about 5%
|
||||
* better in AES-CBC).
|
||||
*
|
||||
* \param r Pointer to result (buffer of at least \p n bytes). \p r
|
||||
* may be equal to either \p a or \p b, but behaviour when
|
||||
* it overlaps in other ways is undefined.
|
||||
* \param a Pointer to input (buffer of at least \p n bytes)
|
||||
* \param b Pointer to input (buffer of at least \p n bytes)
|
||||
* \param n Number of bytes to process.
|
||||
*
|
||||
* \note Depending on the situation, it may be faster to use either mbedtls_xor() or
|
||||
* mbedtls_xor_no_simd() (these are functionally equivalent).
|
||||
* If the result is used immediately after the xor operation in non-SIMD code (e.g, in
|
||||
* AES-CBC), there may be additional latency to transfer the data from SIMD to scalar
|
||||
* registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where
|
||||
* the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster.
|
||||
* For targets without SIMD support, they will behave the same.
|
||||
*/
|
||||
static inline void mbedtls_xor_no_simd(unsigned char *r,
|
||||
const unsigned char *a,
|
||||
const unsigned char *b,
|
||||
size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
|
||||
#if defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
|
||||
/* This codepath probably only makes sense on architectures with 64-bit registers */
|
||||
for (; (i + 8) <= n; i += 8) {
|
||||
uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
|
||||
mbedtls_put_unaligned_uint64(r + i, x);
|
||||
}
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
/* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case
|
||||
* where n is a constant multiple of 8.
|
||||
* For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time
|
||||
* constant, and is a very small perf regression if n is not a compile-time constant. */
|
||||
if (n % 8 == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
for (; (i + 4) <= n; i += 4) {
|
||||
uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
|
||||
mbedtls_put_unaligned_uint32(r + i, x);
|
||||
}
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
if (n % 4 == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
for (; i < n; i++) {
|
||||
r[i] = a[i] ^ b[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Fix MSVC C99 compatible issue
|
||||
* MSVC support __func__ from visual studio 2015( 1900 )
|
||||
* Use MSVC predefine macro to avoid name check fail.
|
||||
*/
|
||||
#if (defined(_MSC_VER) && (_MSC_VER <= 1900))
|
||||
#define /*no-check-names*/ __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
/* Define `asm` for compilers which don't define it. */
|
||||
/* *INDENT-OFF* */
|
||||
#ifndef asm
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#define asm __asm
|
||||
#else
|
||||
#define asm __asm__
|
||||
#endif
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*
|
||||
* Define the constraint used for read-only pointer operands to aarch64 asm.
|
||||
*
|
||||
* This is normally the usual "r", but for aarch64_32 (aka ILP32,
|
||||
* as found in watchos), "p" is required to avoid warnings from clang.
|
||||
*
|
||||
* Note that clang does not recognise '+p' or '=p', and armclang
|
||||
* does not recognise 'p' at all. Therefore, to update a pointer from
|
||||
* aarch64 assembly, it is necessary to use something like:
|
||||
*
|
||||
* uintptr_t uptr = (uintptr_t) ptr;
|
||||
* asm( "ldr x4, [%x0], #8" ... : "+r" (uptr) : : )
|
||||
* ptr = (void*) uptr;
|
||||
*
|
||||
* Note that the "x" in "%x0" is neccessary; writing "%0" will cause warnings.
|
||||
*/
|
||||
#if defined(__aarch64__) && defined(MBEDTLS_HAVE_ASM)
|
||||
#if UINTPTR_MAX == 0xfffffffful
|
||||
/* ILP32: Specify the pointer operand slightly differently, as per #7787. */
|
||||
#define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "p"
|
||||
#elif UINTPTR_MAX == 0xfffffffffffffffful
|
||||
/* Normal case (64-bit pointers): use "r" as the constraint for pointer operands to asm */
|
||||
#define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "r"
|
||||
#else
|
||||
#error "Unrecognised pointer size for aarch64"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Always provide a static assert macro, so it can be used unconditionally.
|
||||
* It does nothing on systems where we don't know how to define a static assert.
|
||||
*/
|
||||
/* Can't use the C11-style `defined(static_assert)` on FreeBSD, since it
|
||||
* defines static_assert even with -std=c99, but then complains about it.
|
||||
*/
|
||||
#if defined(static_assert) && !defined(__FreeBSD__)
|
||||
#define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
|
||||
#else
|
||||
/* Make sure `MBEDTLS_STATIC_ASSERT(expr, msg);` is valid both inside and
|
||||
* outside a function. We choose a struct declaration, which can be repeated
|
||||
* any number of times and does not need a matching definition. */
|
||||
#define MBEDTLS_STATIC_ASSERT(expr, msg) \
|
||||
struct ISO_C_does_not_allow_extra_semicolon_outside_of_a_function
|
||||
#endif
|
||||
|
||||
#if defined(__has_builtin)
|
||||
#define MBEDTLS_HAS_BUILTIN(x) __has_builtin(x)
|
||||
#else
|
||||
#define MBEDTLS_HAS_BUILTIN(x) 0
|
||||
#endif
|
||||
|
||||
/* Define compiler branch hints */
|
||||
#if MBEDTLS_HAS_BUILTIN(__builtin_expect)
|
||||
#define MBEDTLS_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define MBEDTLS_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
#define MBEDTLS_LIKELY(x) x
|
||||
#define MBEDTLS_UNLIKELY(x) x
|
||||
#endif
|
||||
|
||||
/* MBEDTLS_ASSUME may be used to provide additional information to the compiler
|
||||
* which can result in smaller code-size. */
|
||||
#if MBEDTLS_HAS_BUILTIN(__builtin_assume)
|
||||
/* clang provides __builtin_assume */
|
||||
#define MBEDTLS_ASSUME(x) __builtin_assume(x)
|
||||
#elif MBEDTLS_HAS_BUILTIN(__builtin_unreachable)
|
||||
/* gcc and IAR can use __builtin_unreachable */
|
||||
#define MBEDTLS_ASSUME(x) do { if (!(x)) __builtin_unreachable(); } while (0)
|
||||
#elif defined(_MSC_VER)
|
||||
/* Supported by MSVC since VS 2005 */
|
||||
#define MBEDTLS_ASSUME(x) __assume(x)
|
||||
#else
|
||||
#define MBEDTLS_ASSUME(x) do { } while (0)
|
||||
#endif
|
||||
|
||||
/* For gcc -Os, override with -O2 for a given function.
|
||||
*
|
||||
* This will not affect behaviour for other optimisation settings, e.g. -O0.
|
||||
*/
|
||||
#if defined(MBEDTLS_COMPILER_IS_GCC) && defined(__OPTIMIZE_SIZE__)
|
||||
#define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE __attribute__((optimize("-O2")))
|
||||
#else
|
||||
#define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
|
||||
#endif
|
||||
|
||||
/* Suppress compiler warnings for unused functions and variables. */
|
||||
#if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__has_attribute)
|
||||
# if __has_attribute(unused)
|
||||
# define MBEDTLS_MAYBE_UNUSED __attribute__((unused))
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__GNUC__)
|
||||
# define MBEDTLS_MAYBE_UNUSED __attribute__((unused))
|
||||
#endif
|
||||
#if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__IAR_SYSTEMS_ICC__) && defined(__VER__)
|
||||
/* IAR does support __attribute__((unused)), but only if the -e flag (extended language support)
|
||||
* is given; the pragma always works.
|
||||
* Unfortunately the pragma affects the rest of the file where it is used, but this is harmless.
|
||||
* Check for version 5.2 or later - this pragma may be supported by earlier versions, but I wasn't
|
||||
* able to find documentation).
|
||||
*/
|
||||
# if (__VER__ >= 5020000)
|
||||
# define MBEDTLS_MAYBE_UNUSED _Pragma("diag_suppress=Pe177")
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(MBEDTLS_MAYBE_UNUSED) && defined(_MSC_VER)
|
||||
# define MBEDTLS_MAYBE_UNUSED __pragma(warning(suppress:4189))
|
||||
#endif
|
||||
#if !defined(MBEDTLS_MAYBE_UNUSED)
|
||||
# define MBEDTLS_MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_LIBRARY_COMMON_H */
|
||||
248
Libs/util/third_party/mbedtls/library/constant_time.c
vendored
Normal file
248
Libs/util/third_party/mbedtls/library/constant_time.c
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* Constant-time functions
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following functions are implemented without using comparison operators, as those
|
||||
* might be translated to branches by some compilers on some platforms.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "constant_time_internal.h"
|
||||
#include "mbedtls/constant_time.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(MBEDTLS_CT_ASM)
|
||||
/*
|
||||
* Define an object with the value zero, such that the compiler cannot prove that it
|
||||
* has the value zero (because it is volatile, it "may be modified in ways unknown to
|
||||
* the implementation").
|
||||
*/
|
||||
volatile mbedtls_ct_uint_t mbedtls_ct_zero = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS where assembly is present to
|
||||
* perform fast unaligned access to volatile data.
|
||||
*
|
||||
* This is needed because mbedtls_get_unaligned_uintXX etc don't support volatile
|
||||
* memory accesses.
|
||||
*
|
||||
* Some of these definitions could be moved into alignment.h but for now they are
|
||||
* only used here.
|
||||
*/
|
||||
#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) && \
|
||||
((defined(MBEDTLS_CT_ARM_ASM) && (UINTPTR_MAX == 0xfffffffful)) || \
|
||||
defined(MBEDTLS_CT_AARCH64_ASM))
|
||||
/* We check pointer sizes to avoid issues with them not matching register size requirements */
|
||||
#define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS
|
||||
|
||||
static inline uint32_t mbedtls_get_unaligned_volatile_uint32(volatile const unsigned char *p)
|
||||
{
|
||||
/* This is UB, even where it's safe:
|
||||
* return *((volatile uint32_t*)p);
|
||||
* so instead the same thing is expressed in assembly below.
|
||||
*/
|
||||
uint32_t r;
|
||||
#if defined(MBEDTLS_CT_ARM_ASM)
|
||||
asm volatile ("ldr %0, [%1]" : "=r" (r) : "r" (p) :);
|
||||
#elif defined(MBEDTLS_CT_AARCH64_ASM)
|
||||
asm volatile ("ldr %w0, [%1]" : "=r" (r) : MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT(p) :);
|
||||
#else
|
||||
#error "No assembly defined for mbedtls_get_unaligned_volatile_uint32"
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) &&
|
||||
(defined(MBEDTLS_CT_ARM_ASM) || defined(MBEDTLS_CT_AARCH64_ASM)) */
|
||||
|
||||
int mbedtls_ct_memcmp(const void *a,
|
||||
const void *b,
|
||||
size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
/*
|
||||
* `A` and `B` are cast to volatile to ensure that the compiler
|
||||
* generates code that always fully reads both buffers.
|
||||
* Otherwise it could generate a test to exit early if `diff` has all
|
||||
* bits set early in the loop.
|
||||
*/
|
||||
volatile const unsigned char *A = (volatile const unsigned char *) a;
|
||||
volatile const unsigned char *B = (volatile const unsigned char *) b;
|
||||
uint32_t diff = 0;
|
||||
|
||||
#if defined(MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS)
|
||||
for (; (i + 4) <= n; i += 4) {
|
||||
uint32_t x = mbedtls_get_unaligned_volatile_uint32(A + i);
|
||||
uint32_t y = mbedtls_get_unaligned_volatile_uint32(B + i);
|
||||
diff |= x ^ y;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; i < n; i++) {
|
||||
/* Read volatile data in order before computing diff.
|
||||
* This avoids IAR compiler warning:
|
||||
* 'the order of volatile accesses is undefined ..' */
|
||||
unsigned char x = A[i], y = B[i];
|
||||
diff |= x ^ y;
|
||||
}
|
||||
|
||||
|
||||
#if (INT_MAX < INT32_MAX)
|
||||
/* We don't support int smaller than 32-bits, but if someone tried to build
|
||||
* with this configuration, there is a risk that, for differing data, the
|
||||
* only bits set in diff are in the top 16-bits, and would be lost by a
|
||||
* simple cast from uint32 to int.
|
||||
* This would have significant security implications, so protect against it. */
|
||||
#error "mbedtls_ct_memcmp() requires minimum 32-bit ints"
|
||||
#else
|
||||
/* The bit-twiddling ensures that when we cast uint32_t to int, we are casting
|
||||
* a value that is in the range 0..INT_MAX - a value larger than this would
|
||||
* result in implementation defined behaviour.
|
||||
*
|
||||
* This ensures that the value returned by the function is non-zero iff
|
||||
* diff is non-zero.
|
||||
*/
|
||||
return (int) ((diff & 0xffff) | (diff >> 16));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_NIST_KW_C)
|
||||
|
||||
int mbedtls_ct_memcmp_partial(const void *a,
|
||||
const void *b,
|
||||
size_t n,
|
||||
size_t skip_head,
|
||||
size_t skip_tail)
|
||||
{
|
||||
unsigned int diff = 0;
|
||||
|
||||
volatile const unsigned char *A = (volatile const unsigned char *) a;
|
||||
volatile const unsigned char *B = (volatile const unsigned char *) b;
|
||||
|
||||
size_t valid_end = n - skip_tail;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
unsigned char x = A[i], y = B[i];
|
||||
unsigned int d = x ^ y;
|
||||
mbedtls_ct_condition_t valid = mbedtls_ct_bool_and(mbedtls_ct_uint_ge(i, skip_head),
|
||||
mbedtls_ct_uint_lt(i, valid_end));
|
||||
diff |= mbedtls_ct_uint_if_else_0(valid, d);
|
||||
}
|
||||
|
||||
/* Since we go byte-by-byte, the only bits set will be in the bottom 8 bits, so the
|
||||
* cast from uint to int is safe. */
|
||||
return (int) diff;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
|
||||
|
||||
void mbedtls_ct_memmove_left(void *start, size_t total, size_t offset)
|
||||
{
|
||||
volatile unsigned char *buf = start;
|
||||
for (size_t i = 0; i < total; i++) {
|
||||
mbedtls_ct_condition_t no_op = mbedtls_ct_uint_gt(total - offset, i);
|
||||
/* The first `total - offset` passes are a no-op. The last
|
||||
* `offset` passes shift the data one byte to the left and
|
||||
* zero out the last byte. */
|
||||
for (size_t n = 0; n < total - 1; n++) {
|
||||
unsigned char current = buf[n];
|
||||
unsigned char next = buf[n+1];
|
||||
buf[n] = mbedtls_ct_uint_if(no_op, current, next);
|
||||
}
|
||||
buf[total-1] = mbedtls_ct_uint_if_else_0(no_op, buf[total-1]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
|
||||
|
||||
void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition,
|
||||
unsigned char *dest,
|
||||
const unsigned char *src1,
|
||||
const unsigned char *src2,
|
||||
size_t len)
|
||||
{
|
||||
#if defined(MBEDTLS_CT_SIZE_64)
|
||||
const uint64_t mask = (uint64_t) condition;
|
||||
const uint64_t not_mask = (uint64_t) ~mbedtls_ct_compiler_opaque(condition);
|
||||
#else
|
||||
const uint32_t mask = (uint32_t) condition;
|
||||
const uint32_t not_mask = (uint32_t) ~mbedtls_ct_compiler_opaque(condition);
|
||||
#endif
|
||||
|
||||
/* If src2 is NULL, setup src2 so that we read from the destination address.
|
||||
*
|
||||
* This means that if src2 == NULL && condition is false, the result will be a
|
||||
* no-op because we read from dest and write the same data back into dest.
|
||||
*/
|
||||
if (src2 == NULL) {
|
||||
src2 = dest;
|
||||
}
|
||||
|
||||
/* dest[i] = c1 == c2 ? src[i] : dest[i] */
|
||||
size_t i = 0;
|
||||
#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
|
||||
#if defined(MBEDTLS_CT_SIZE_64)
|
||||
for (; (i + 8) <= len; i += 8) {
|
||||
uint64_t a = mbedtls_get_unaligned_uint64(src1 + i) & mask;
|
||||
uint64_t b = mbedtls_get_unaligned_uint64(src2 + i) & not_mask;
|
||||
mbedtls_put_unaligned_uint64(dest + i, a | b);
|
||||
}
|
||||
#else
|
||||
for (; (i + 4) <= len; i += 4) {
|
||||
uint32_t a = mbedtls_get_unaligned_uint32(src1 + i) & mask;
|
||||
uint32_t b = mbedtls_get_unaligned_uint32(src2 + i) & not_mask;
|
||||
mbedtls_put_unaligned_uint32(dest + i, a | b);
|
||||
}
|
||||
#endif /* defined(MBEDTLS_CT_SIZE_64) */
|
||||
#endif /* MBEDTLS_EFFICIENT_UNALIGNED_ACCESS */
|
||||
for (; i < len; i++) {
|
||||
dest[i] = (src1[i] & mask) | (src2[i] & not_mask);
|
||||
}
|
||||
}
|
||||
|
||||
void mbedtls_ct_memcpy_offset(unsigned char *dest,
|
||||
const unsigned char *src,
|
||||
size_t offset,
|
||||
size_t offset_min,
|
||||
size_t offset_max,
|
||||
size_t len)
|
||||
{
|
||||
size_t offsetval;
|
||||
|
||||
for (offsetval = offset_min; offsetval <= offset_max; offsetval++) {
|
||||
mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offsetval, offset), dest, src + offsetval, NULL,
|
||||
len);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
|
||||
|
||||
void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len)
|
||||
{
|
||||
uint32_t mask = (uint32_t) ~condition;
|
||||
uint8_t *p = (uint8_t *) buf;
|
||||
size_t i = 0;
|
||||
#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
|
||||
for (; (i + 4) <= len; i += 4) {
|
||||
mbedtls_put_unaligned_uint32((void *) (p + i),
|
||||
mbedtls_get_unaligned_uint32((void *) (p + i)) & mask);
|
||||
}
|
||||
#endif
|
||||
for (; i < len; i++) {
|
||||
p[i] = p[i] & mask;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */
|
||||
556
Libs/util/third_party/mbedtls/library/constant_time_impl.h
vendored
Normal file
556
Libs/util/third_party/mbedtls/library/constant_time_impl.h
vendored
Normal file
@@ -0,0 +1,556 @@
|
||||
/**
|
||||
* Constant-time functions
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CONSTANT_TIME_IMPL_H
|
||||
#define MBEDTLS_CONSTANT_TIME_IMPL_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
#include "mbedtls/bignum.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* To improve readability of constant_time_internal.h, the static inline
|
||||
* definitions are here, and constant_time_internal.h has only the declarations.
|
||||
*
|
||||
* This results in duplicate declarations of the form:
|
||||
* static inline void f(); // from constant_time_internal.h
|
||||
* static inline void f() { ... } // from constant_time_impl.h
|
||||
* when constant_time_internal.h is included.
|
||||
*
|
||||
* This appears to behave as if the declaration-without-definition was not present
|
||||
* (except for warnings if gcc -Wredundant-decls or similar is used).
|
||||
*
|
||||
* Disable -Wredundant-decls so that gcc does not warn about this. This is re-enabled
|
||||
* at the bottom of this file.
|
||||
*/
|
||||
#if defined(MBEDTLS_COMPILER_IS_GCC) && (__GNUC__ > 4)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
||||
#endif
|
||||
|
||||
/* Disable asm under Memsan because it confuses Memsan and generates false errors.
|
||||
*
|
||||
* We also disable under Valgrind by default, because it's more useful
|
||||
* for Valgrind to test the plain C implementation. MBEDTLS_TEST_CONSTANT_FLOW_ASM //no-check-names
|
||||
* may be set to permit building asm under Valgrind.
|
||||
*/
|
||||
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) || \
|
||||
(defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND) && !defined(MBEDTLS_TEST_CONSTANT_FLOW_ASM)) //no-check-names
|
||||
#define MBEDTLS_CT_NO_ASM
|
||||
#elif defined(__has_feature)
|
||||
#if __has_feature(memory_sanitizer)
|
||||
#define MBEDTLS_CT_NO_ASM
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
|
||||
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && (!defined(__ARMCC_VERSION) || \
|
||||
__ARMCC_VERSION >= 6000000) && !defined(MBEDTLS_CT_NO_ASM)
|
||||
#define MBEDTLS_CT_ASM
|
||||
#if (defined(__arm__) || defined(__thumb__) || defined(__thumb2__))
|
||||
#define MBEDTLS_CT_ARM_ASM
|
||||
#elif defined(__aarch64__)
|
||||
#define MBEDTLS_CT_AARCH64_ASM
|
||||
#elif defined(__amd64__) || defined(__x86_64__)
|
||||
#define MBEDTLS_CT_X86_64_ASM
|
||||
#elif defined(__i386__)
|
||||
#define MBEDTLS_CT_X86_ASM
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_CT_SIZE (sizeof(mbedtls_ct_uint_t) * 8)
|
||||
|
||||
|
||||
/* ============================================================================
|
||||
* Core const-time primitives
|
||||
*/
|
||||
|
||||
/* Ensure that the compiler cannot know the value of x (i.e., cannot optimise
|
||||
* based on its value) after this function is called.
|
||||
*
|
||||
* If we are not using assembly, this will be fairly inefficient, so its use
|
||||
* should be minimised.
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CT_ASM)
|
||||
extern volatile mbedtls_ct_uint_t mbedtls_ct_zero;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Ensure that a value cannot be known at compile time.
|
||||
*
|
||||
* \param x The value to hide from the compiler.
|
||||
* \return The same value that was passed in, such that the compiler
|
||||
* cannot prove its value (even for calls of the form
|
||||
* x = mbedtls_ct_compiler_opaque(1), x will be unknown).
|
||||
*
|
||||
* \note This is mainly used in constructing mbedtls_ct_condition_t
|
||||
* values and performing operations over them, to ensure that
|
||||
* there is no way for the compiler to ever know anything about
|
||||
* the value of an mbedtls_ct_condition_t.
|
||||
*/
|
||||
static inline mbedtls_ct_uint_t mbedtls_ct_compiler_opaque(mbedtls_ct_uint_t x)
|
||||
{
|
||||
#if defined(MBEDTLS_CT_ASM)
|
||||
asm volatile ("" : [x] "+r" (x) :);
|
||||
return x;
|
||||
#else
|
||||
return x ^ mbedtls_ct_zero;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Selecting unified syntax is needed for gcc, and harmless on clang.
|
||||
*
|
||||
* This is needed because on Thumb 1, condition flags are always set, so
|
||||
* e.g. "negs" is supported but "neg" is not (on Thumb 2, both exist).
|
||||
*
|
||||
* Under Thumb 1 unified syntax, only the "negs" form is accepted, and
|
||||
* under divided syntax, only the "neg" form is accepted. clang only
|
||||
* supports unified syntax.
|
||||
*
|
||||
* On Thumb 2 and Arm, both compilers are happy with the "s" suffix,
|
||||
* although we don't actually care about setting the flags.
|
||||
*
|
||||
* For old versions of gcc (see #8516 for details), restore divided
|
||||
* syntax afterwards - otherwise old versions of gcc seem to apply
|
||||
* unified syntax globally, which breaks other asm code.
|
||||
*/
|
||||
#if defined(MBEDTLS_COMPILER_IS_GCC) && defined(__thumb__) && !defined(__thumb2__) && \
|
||||
(__GNUC__ < 11) && !defined(__ARM_ARCH_2__)
|
||||
#define RESTORE_ASM_SYNTAX ".syntax divided \n\t"
|
||||
#else
|
||||
#define RESTORE_ASM_SYNTAX
|
||||
#endif
|
||||
|
||||
/* Convert a number into a condition in constant time. */
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x)
|
||||
{
|
||||
/*
|
||||
* Define mask-generation code that, as far as possible, will not use branches or conditional instructions.
|
||||
*
|
||||
* For some platforms / type sizes, we define assembly to assure this.
|
||||
*
|
||||
* Otherwise, we define a plain C fallback which (in May 2023) does not get optimised into
|
||||
* conditional instructions or branches by trunk clang, gcc, or MSVC v19.
|
||||
*/
|
||||
#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64))
|
||||
mbedtls_ct_uint_t s;
|
||||
asm volatile ("neg %x[s], %x[x] \n\t"
|
||||
"orr %x[x], %x[s], %x[x] \n\t"
|
||||
"asr %x[x], %x[x], 63 \n\t"
|
||||
:
|
||||
[s] "=&r" (s),
|
||||
[x] "+&r" (x)
|
||||
:
|
||||
:
|
||||
);
|
||||
return (mbedtls_ct_condition_t) x;
|
||||
#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32)
|
||||
uint32_t s;
|
||||
asm volatile (".syntax unified \n\t"
|
||||
"negs %[s], %[x] \n\t"
|
||||
"orrs %[x], %[x], %[s] \n\t"
|
||||
"asrs %[x], %[x], #31 \n\t"
|
||||
RESTORE_ASM_SYNTAX
|
||||
:
|
||||
[s] "=&l" (s),
|
||||
[x] "+&l" (x)
|
||||
:
|
||||
:
|
||||
"cc" /* clobbers flag bits */
|
||||
);
|
||||
return (mbedtls_ct_condition_t) x;
|
||||
#elif defined(MBEDTLS_CT_X86_64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64))
|
||||
uint64_t s;
|
||||
asm volatile ("mov %[x], %[s] \n\t"
|
||||
"neg %[s] \n\t"
|
||||
"or %[x], %[s] \n\t"
|
||||
"sar $63, %[s] \n\t"
|
||||
:
|
||||
[s] "=&a" (s)
|
||||
:
|
||||
[x] "D" (x)
|
||||
:
|
||||
);
|
||||
return (mbedtls_ct_condition_t) s;
|
||||
#elif defined(MBEDTLS_CT_X86_ASM) && defined(MBEDTLS_CT_SIZE_32)
|
||||
uint32_t s;
|
||||
asm volatile ("mov %[x], %[s] \n\t"
|
||||
"neg %[s] \n\t"
|
||||
"or %[s], %[x] \n\t"
|
||||
"sar $31, %[x] \n\t"
|
||||
:
|
||||
[s] "=&c" (s),
|
||||
[x] "+&a" (x)
|
||||
:
|
||||
:
|
||||
);
|
||||
return (mbedtls_ct_condition_t) x;
|
||||
#else
|
||||
const mbedtls_ct_uint_t xo = mbedtls_ct_compiler_opaque(x);
|
||||
#if defined(_MSC_VER)
|
||||
/* MSVC has a warning about unary minus on unsigned, but this is
|
||||
* well-defined and precisely what we want to do here */
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4146 )
|
||||
#endif
|
||||
// y is negative (i.e., top bit set) iff x is non-zero
|
||||
mbedtls_ct_int_t y = (-xo) | -(xo >> 1);
|
||||
|
||||
// extract only the sign bit of y so that y == 1 (if x is non-zero) or 0 (if x is zero)
|
||||
y = (((mbedtls_ct_uint_t) y) >> (MBEDTLS_CT_SIZE - 1));
|
||||
|
||||
// -y has all bits set (if x is non-zero), or all bits clear (if x is zero)
|
||||
return (mbedtls_ct_condition_t) (-y);
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_uint_t mbedtls_ct_if(mbedtls_ct_condition_t condition,
|
||||
mbedtls_ct_uint_t if1,
|
||||
mbedtls_ct_uint_t if0)
|
||||
{
|
||||
#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64))
|
||||
asm volatile ("and %x[if1], %x[if1], %x[condition] \n\t"
|
||||
"mvn %x[condition], %x[condition] \n\t"
|
||||
"and %x[condition], %x[condition], %x[if0] \n\t"
|
||||
"orr %x[condition], %x[if1], %x[condition]"
|
||||
:
|
||||
[condition] "+&r" (condition),
|
||||
[if1] "+&r" (if1)
|
||||
:
|
||||
[if0] "r" (if0)
|
||||
:
|
||||
);
|
||||
return (mbedtls_ct_uint_t) condition;
|
||||
#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32)
|
||||
asm volatile (".syntax unified \n\t"
|
||||
"ands %[if1], %[if1], %[condition] \n\t"
|
||||
"mvns %[condition], %[condition] \n\t"
|
||||
"ands %[condition], %[condition], %[if0] \n\t"
|
||||
"orrs %[condition], %[if1], %[condition] \n\t"
|
||||
RESTORE_ASM_SYNTAX
|
||||
:
|
||||
[condition] "+&l" (condition),
|
||||
[if1] "+&l" (if1)
|
||||
:
|
||||
[if0] "l" (if0)
|
||||
:
|
||||
"cc"
|
||||
);
|
||||
return (mbedtls_ct_uint_t) condition;
|
||||
#elif defined(MBEDTLS_CT_X86_64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64))
|
||||
asm volatile ("and %[condition], %[if1] \n\t"
|
||||
"not %[condition] \n\t"
|
||||
"and %[condition], %[if0] \n\t"
|
||||
"or %[if1], %[if0] \n\t"
|
||||
:
|
||||
[condition] "+&D" (condition),
|
||||
[if1] "+&S" (if1),
|
||||
[if0] "+&a" (if0)
|
||||
:
|
||||
:
|
||||
);
|
||||
return if0;
|
||||
#elif defined(MBEDTLS_CT_X86_ASM) && defined(MBEDTLS_CT_SIZE_32)
|
||||
asm volatile ("and %[condition], %[if1] \n\t"
|
||||
"not %[condition] \n\t"
|
||||
"and %[if0], %[condition] \n\t"
|
||||
"or %[condition], %[if1] \n\t"
|
||||
:
|
||||
[condition] "+&c" (condition),
|
||||
[if1] "+&a" (if1)
|
||||
:
|
||||
[if0] "b" (if0)
|
||||
:
|
||||
);
|
||||
return if1;
|
||||
#else
|
||||
mbedtls_ct_condition_t not_cond =
|
||||
(mbedtls_ct_condition_t) (~mbedtls_ct_compiler_opaque(condition));
|
||||
return (mbedtls_ct_uint_t) ((condition & if1) | (not_cond & if0));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y)
|
||||
{
|
||||
#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64))
|
||||
uint64_t s1;
|
||||
asm volatile ("eor %x[s1], %x[y], %x[x] \n\t"
|
||||
"sub %x[x], %x[x], %x[y] \n\t"
|
||||
"bic %x[x], %x[x], %x[s1] \n\t"
|
||||
"and %x[s1], %x[s1], %x[y] \n\t"
|
||||
"orr %x[s1], %x[x], %x[s1] \n\t"
|
||||
"asr %x[x], %x[s1], 63"
|
||||
:
|
||||
[s1] "=&r" (s1),
|
||||
[x] "+&r" (x)
|
||||
:
|
||||
[y] "r" (y)
|
||||
:
|
||||
);
|
||||
return (mbedtls_ct_condition_t) x;
|
||||
#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32)
|
||||
uint32_t s1;
|
||||
asm volatile (
|
||||
".syntax unified \n\t"
|
||||
#if defined(__thumb__) && !defined(__thumb2__)
|
||||
"movs %[s1], %[x] \n\t"
|
||||
"eors %[s1], %[s1], %[y] \n\t"
|
||||
#else
|
||||
"eors %[s1], %[x], %[y] \n\t"
|
||||
#endif
|
||||
"subs %[x], %[x], %[y] \n\t"
|
||||
"bics %[x], %[x], %[s1] \n\t"
|
||||
"ands %[y], %[s1], %[y] \n\t"
|
||||
"orrs %[x], %[x], %[y] \n\t"
|
||||
"asrs %[x], %[x], #31 \n\t"
|
||||
RESTORE_ASM_SYNTAX
|
||||
:
|
||||
[s1] "=&l" (s1),
|
||||
[x] "+&l" (x),
|
||||
[y] "+&l" (y)
|
||||
:
|
||||
:
|
||||
"cc"
|
||||
);
|
||||
return (mbedtls_ct_condition_t) x;
|
||||
#elif defined(MBEDTLS_CT_X86_64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64))
|
||||
uint64_t s;
|
||||
asm volatile ("mov %[x], %[s] \n\t"
|
||||
"xor %[y], %[s] \n\t"
|
||||
"sub %[y], %[x] \n\t"
|
||||
"and %[s], %[y] \n\t"
|
||||
"not %[s] \n\t"
|
||||
"and %[s], %[x] \n\t"
|
||||
"or %[y], %[x] \n\t"
|
||||
"sar $63, %[x] \n\t"
|
||||
:
|
||||
[s] "=&a" (s),
|
||||
[x] "+&D" (x),
|
||||
[y] "+&S" (y)
|
||||
:
|
||||
:
|
||||
);
|
||||
return (mbedtls_ct_condition_t) x;
|
||||
#elif defined(MBEDTLS_CT_X86_ASM) && defined(MBEDTLS_CT_SIZE_32)
|
||||
uint32_t s;
|
||||
asm volatile ("mov %[x], %[s] \n\t"
|
||||
"xor %[y], %[s] \n\t"
|
||||
"sub %[y], %[x] \n\t"
|
||||
"and %[s], %[y] \n\t"
|
||||
"not %[s] \n\t"
|
||||
"and %[s], %[x] \n\t"
|
||||
"or %[y], %[x] \n\t"
|
||||
"sar $31, %[x] \n\t"
|
||||
:
|
||||
[s] "=&b" (s),
|
||||
[x] "+&a" (x),
|
||||
[y] "+&c" (y)
|
||||
:
|
||||
:
|
||||
);
|
||||
return (mbedtls_ct_condition_t) x;
|
||||
#else
|
||||
/* Ensure that the compiler cannot optimise the following operations over x and y,
|
||||
* even if it knows the value of x and y.
|
||||
*/
|
||||
const mbedtls_ct_uint_t xo = mbedtls_ct_compiler_opaque(x);
|
||||
const mbedtls_ct_uint_t yo = mbedtls_ct_compiler_opaque(y);
|
||||
/*
|
||||
* Check if the most significant bits (MSB) of the operands are different.
|
||||
* cond is true iff the MSBs differ.
|
||||
*/
|
||||
mbedtls_ct_condition_t cond = mbedtls_ct_bool((xo ^ yo) >> (MBEDTLS_CT_SIZE - 1));
|
||||
|
||||
/*
|
||||
* If the MSB are the same then the difference x-y will be negative (and
|
||||
* have its MSB set to 1 during conversion to unsigned) if and only if x<y.
|
||||
*
|
||||
* If the MSB are different, then the operand with the MSB of 1 is the
|
||||
* bigger. (That is if y has MSB of 1, then x<y is true and it is false if
|
||||
* the MSB of y is 0.)
|
||||
*/
|
||||
|
||||
// Select either y, or x - y
|
||||
mbedtls_ct_uint_t ret = mbedtls_ct_if(cond, yo, (mbedtls_ct_uint_t) (xo - yo));
|
||||
|
||||
// Extract only the MSB of ret
|
||||
ret = ret >> (MBEDTLS_CT_SIZE - 1);
|
||||
|
||||
// Convert to a condition (i.e., all bits set iff non-zero)
|
||||
return mbedtls_ct_bool(ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y)
|
||||
{
|
||||
/* diff = 0 if x == y, non-zero otherwise */
|
||||
const mbedtls_ct_uint_t diff = mbedtls_ct_compiler_opaque(x) ^ mbedtls_ct_compiler_opaque(y);
|
||||
|
||||
/* all ones if x != y, 0 otherwise */
|
||||
return mbedtls_ct_bool(diff);
|
||||
}
|
||||
|
||||
static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low,
|
||||
unsigned char high,
|
||||
unsigned char c,
|
||||
unsigned char t)
|
||||
{
|
||||
const unsigned char co = (unsigned char) mbedtls_ct_compiler_opaque(c);
|
||||
const unsigned char to = (unsigned char) mbedtls_ct_compiler_opaque(t);
|
||||
|
||||
/* low_mask is: 0 if low <= c, 0x...ff if low > c */
|
||||
unsigned low_mask = ((unsigned) co - low) >> 8;
|
||||
/* high_mask is: 0 if c <= high, 0x...ff if c > high */
|
||||
unsigned high_mask = ((unsigned) high - co) >> 8;
|
||||
|
||||
return (unsigned char) (~(low_mask | high_mask)) & to;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Everything below here is trivial wrapper functions
|
||||
*/
|
||||
|
||||
static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition,
|
||||
size_t if1,
|
||||
size_t if0)
|
||||
{
|
||||
return (size_t) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1, (mbedtls_ct_uint_t) if0);
|
||||
}
|
||||
|
||||
static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition,
|
||||
unsigned if1,
|
||||
unsigned if0)
|
||||
{
|
||||
return (unsigned) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1, (mbedtls_ct_uint_t) if0);
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition,
|
||||
mbedtls_ct_condition_t if1,
|
||||
mbedtls_ct_condition_t if0)
|
||||
{
|
||||
return (mbedtls_ct_condition_t) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1,
|
||||
(mbedtls_ct_uint_t) if0);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
|
||||
static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition,
|
||||
mbedtls_mpi_uint if1,
|
||||
mbedtls_mpi_uint if0)
|
||||
{
|
||||
return (mbedtls_mpi_uint) mbedtls_ct_if(condition,
|
||||
(mbedtls_ct_uint_t) if1,
|
||||
(mbedtls_ct_uint_t) if0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1)
|
||||
{
|
||||
return (size_t) (condition & if1);
|
||||
}
|
||||
|
||||
static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1)
|
||||
{
|
||||
return (unsigned) (condition & if1);
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition,
|
||||
mbedtls_ct_condition_t if1)
|
||||
{
|
||||
return (mbedtls_ct_condition_t) (condition & if1);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
|
||||
static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition,
|
||||
mbedtls_mpi_uint if1)
|
||||
{
|
||||
return (mbedtls_mpi_uint) (condition & if1);
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_C */
|
||||
|
||||
static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0)
|
||||
{
|
||||
/* Coverting int -> uint -> int here is safe, because we require if1 and if0 to be
|
||||
* in the range -32767..0, and we require 32-bit int and uint types.
|
||||
*
|
||||
* This means that (0 <= -if0 < INT_MAX), so negating if0 is safe, and similarly for
|
||||
* converting back to int.
|
||||
*/
|
||||
return -((int) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) (-if1),
|
||||
(mbedtls_ct_uint_t) (-if0)));
|
||||
}
|
||||
|
||||
static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1)
|
||||
{
|
||||
return -((int) (condition & (-if1)));
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x,
|
||||
mbedtls_ct_uint_t y)
|
||||
{
|
||||
return ~mbedtls_ct_uint_ne(x, y);
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x,
|
||||
mbedtls_ct_uint_t y)
|
||||
{
|
||||
return mbedtls_ct_uint_lt(y, x);
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x,
|
||||
mbedtls_ct_uint_t y)
|
||||
{
|
||||
return ~mbedtls_ct_uint_lt(x, y);
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x,
|
||||
mbedtls_ct_uint_t y)
|
||||
{
|
||||
return ~mbedtls_ct_uint_gt(x, y);
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x,
|
||||
mbedtls_ct_condition_t y)
|
||||
{
|
||||
return (mbedtls_ct_condition_t) (x ^ y);
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x,
|
||||
mbedtls_ct_condition_t y)
|
||||
{
|
||||
return (mbedtls_ct_condition_t) (x & y);
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x,
|
||||
mbedtls_ct_condition_t y)
|
||||
{
|
||||
return (mbedtls_ct_condition_t) (x | y);
|
||||
}
|
||||
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x)
|
||||
{
|
||||
return (mbedtls_ct_condition_t) (~x);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_COMPILER_IS_GCC) && (__GNUC__ > 4)
|
||||
/* Restore warnings for -Wredundant-decls on gcc */
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CONSTANT_TIME_IMPL_H */
|
||||
579
Libs/util/third_party/mbedtls/library/constant_time_internal.h
vendored
Normal file
579
Libs/util/third_party/mbedtls/library/constant_time_internal.h
vendored
Normal file
@@ -0,0 +1,579 @@
|
||||
/**
|
||||
* Constant-time functions
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H
|
||||
#define MBEDTLS_CONSTANT_TIME_INTERNAL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
#include "mbedtls/bignum.h"
|
||||
#endif
|
||||
|
||||
/* The constant-time interface provides various operations that are likely
|
||||
* to result in constant-time code that does not branch or use conditional
|
||||
* instructions for secret data (for secret pointers, this also applies to
|
||||
* the data pointed to).
|
||||
*
|
||||
* It has three main parts:
|
||||
*
|
||||
* - boolean operations
|
||||
* These are all named mbedtls_ct_<type>_<operation>.
|
||||
* They operate over <type> and return mbedtls_ct_condition_t.
|
||||
* All arguments are considered secret.
|
||||
* example: bool x = y | z => x = mbedtls_ct_bool_or(y, z)
|
||||
* example: bool x = y == z => x = mbedtls_ct_uint_eq(y, z)
|
||||
*
|
||||
* - conditional data selection
|
||||
* These are all named mbedtls_ct_<type>_if and mbedtls_ct_<type>_if_else_0
|
||||
* All arguments are considered secret.
|
||||
* example: size_t a = x ? b : c => a = mbedtls_ct_size_if(x, b, c)
|
||||
* example: unsigned a = x ? b : 0 => a = mbedtls_ct_uint_if_else_0(x, b)
|
||||
*
|
||||
* - block memory operations
|
||||
* Only some arguments are considered secret, as documented for each
|
||||
* function.
|
||||
* example: if (x) memcpy(...) => mbedtls_ct_memcpy_if(x, ...)
|
||||
*
|
||||
* mbedtls_ct_condition_t must be treated as opaque and only created and
|
||||
* manipulated via the functions in this header. The compiler should never
|
||||
* be able to prove anything about its value at compile-time.
|
||||
*
|
||||
* mbedtls_ct_uint_t is an unsigned integer type over which constant time
|
||||
* operations may be performed via the functions in this header. It is as big
|
||||
* as the larger of size_t and mbedtls_mpi_uint, i.e. it is safe to cast
|
||||
* to/from "unsigned int", "size_t", and "mbedtls_mpi_uint" (and any other
|
||||
* not-larger integer types).
|
||||
*
|
||||
* For Arm (32-bit, 64-bit and Thumb), x86 and x86-64, assembly implementations
|
||||
* are used to ensure that the generated code is constant time. For other
|
||||
* architectures, it uses a plain C fallback designed to yield constant-time code
|
||||
* (this has been observed to be constant-time on latest gcc, clang and MSVC
|
||||
* as of May 2023).
|
||||
*
|
||||
* For readability, the static inline definitions are separated out into
|
||||
* constant_time_impl.h.
|
||||
*/
|
||||
|
||||
#if (SIZE_MAX > 0xffffffffffffffffULL)
|
||||
/* Pointer size > 64-bit */
|
||||
typedef size_t mbedtls_ct_condition_t;
|
||||
typedef size_t mbedtls_ct_uint_t;
|
||||
typedef ptrdiff_t mbedtls_ct_int_t;
|
||||
#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(SIZE_MAX))
|
||||
#elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64)
|
||||
/* 32-bit < pointer size <= 64-bit, or 64-bit MPI */
|
||||
typedef uint64_t mbedtls_ct_condition_t;
|
||||
typedef uint64_t mbedtls_ct_uint_t;
|
||||
typedef int64_t mbedtls_ct_int_t;
|
||||
#define MBEDTLS_CT_SIZE_64
|
||||
#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX))
|
||||
#else
|
||||
/* Pointer size <= 32-bit, and no 64-bit MPIs */
|
||||
typedef uint32_t mbedtls_ct_condition_t;
|
||||
typedef uint32_t mbedtls_ct_uint_t;
|
||||
typedef int32_t mbedtls_ct_int_t;
|
||||
#define MBEDTLS_CT_SIZE_32
|
||||
#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX))
|
||||
#endif
|
||||
#define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0))
|
||||
|
||||
/* ============================================================================
|
||||
* Boolean operations
|
||||
*/
|
||||
|
||||
/** Convert a number into a mbedtls_ct_condition_t.
|
||||
*
|
||||
* \param x Number to convert.
|
||||
*
|
||||
* \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 0
|
||||
*
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x);
|
||||
|
||||
/** Boolean "not equal" operation.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* \p x != \p y
|
||||
*
|
||||
* \param x The first value to analyze.
|
||||
* \param y The second value to analyze.
|
||||
*
|
||||
* \return MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE.
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
|
||||
|
||||
/** Boolean "equals" operation.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* \p x == \p y
|
||||
*
|
||||
* \param x The first value to analyze.
|
||||
* \param y The second value to analyze.
|
||||
*
|
||||
* \return MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE.
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x,
|
||||
mbedtls_ct_uint_t y);
|
||||
|
||||
/** Boolean "less than" operation.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* \p x < \p y
|
||||
*
|
||||
* \param x The first value to analyze.
|
||||
* \param y The second value to analyze.
|
||||
*
|
||||
* \return MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE.
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
|
||||
|
||||
/** Boolean "greater than" operation.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* \p x > \p y
|
||||
*
|
||||
* \param x The first value to analyze.
|
||||
* \param y The second value to analyze.
|
||||
*
|
||||
* \return MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE.
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x,
|
||||
mbedtls_ct_uint_t y);
|
||||
|
||||
/** Boolean "greater or equal" operation.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* \p x >= \p y
|
||||
*
|
||||
* \param x The first value to analyze.
|
||||
* \param y The second value to analyze.
|
||||
*
|
||||
* \return MBEDTLS_CT_TRUE if \p x >= \p y,
|
||||
* otherwise MBEDTLS_CT_FALSE.
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x,
|
||||
mbedtls_ct_uint_t y);
|
||||
|
||||
/** Boolean "less than or equal" operation.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* \p x <= \p y
|
||||
*
|
||||
* \param x The first value to analyze.
|
||||
* \param y The second value to analyze.
|
||||
*
|
||||
* \return MBEDTLS_CT_TRUE if \p x <= \p y,
|
||||
* otherwise MBEDTLS_CT_FALSE.
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x,
|
||||
mbedtls_ct_uint_t y);
|
||||
|
||||
/** Boolean not-equals operation.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* \p x != \p y
|
||||
*
|
||||
* \param x The first value to analyze.
|
||||
* \param y The second value to analyze.
|
||||
*
|
||||
* \note This is more efficient than mbedtls_ct_uint_ne if both arguments are
|
||||
* mbedtls_ct_condition_t.
|
||||
*
|
||||
* \return MBEDTLS_CT_TRUE if \p x != \p y,
|
||||
* otherwise MBEDTLS_CT_FALSE.
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x,
|
||||
mbedtls_ct_condition_t y);
|
||||
|
||||
/** Boolean "and" operation.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* \p x && \p y
|
||||
*
|
||||
* \param x The first value to analyze.
|
||||
* \param y The second value to analyze.
|
||||
*
|
||||
* \return MBEDTLS_CT_TRUE if \p x && \p y,
|
||||
* otherwise MBEDTLS_CT_FALSE.
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x,
|
||||
mbedtls_ct_condition_t y);
|
||||
|
||||
/** Boolean "or" operation.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* \p x || \p y
|
||||
*
|
||||
* \param x The first value to analyze.
|
||||
* \param y The second value to analyze.
|
||||
*
|
||||
* \return MBEDTLS_CT_TRUE if \p x || \p y,
|
||||
* otherwise MBEDTLS_CT_FALSE.
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x,
|
||||
mbedtls_ct_condition_t y);
|
||||
|
||||
/** Boolean "not" operation.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* ! \p x
|
||||
*
|
||||
* \param x The value to invert
|
||||
*
|
||||
* \return MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE.
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x);
|
||||
|
||||
|
||||
/* ============================================================================
|
||||
* Data selection operations
|
||||
*/
|
||||
|
||||
/** Choose between two size_t values.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* condition ? if1 : if0.
|
||||
*
|
||||
* \param condition Condition to test.
|
||||
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
|
||||
* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
|
||||
*
|
||||
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
|
||||
*/
|
||||
static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition,
|
||||
size_t if1,
|
||||
size_t if0);
|
||||
|
||||
/** Choose between two unsigned values.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* condition ? if1 : if0.
|
||||
*
|
||||
* \param condition Condition to test.
|
||||
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
|
||||
* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
|
||||
*
|
||||
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
|
||||
*/
|
||||
static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition,
|
||||
unsigned if1,
|
||||
unsigned if0);
|
||||
|
||||
/** Choose between two mbedtls_ct_condition_t values.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* condition ? if1 : if0.
|
||||
*
|
||||
* \param condition Condition to test.
|
||||
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
|
||||
* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
|
||||
*
|
||||
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition,
|
||||
mbedtls_ct_condition_t if1,
|
||||
mbedtls_ct_condition_t if0);
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
|
||||
/** Choose between two mbedtls_mpi_uint values.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* condition ? if1 : if0.
|
||||
*
|
||||
* \param condition Condition to test.
|
||||
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
|
||||
* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
|
||||
*
|
||||
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
|
||||
*/
|
||||
static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \
|
||||
mbedtls_mpi_uint if1, \
|
||||
mbedtls_mpi_uint if0);
|
||||
|
||||
#endif
|
||||
|
||||
/** Choose between an unsigned value and 0.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* condition ? if1 : 0.
|
||||
*
|
||||
* Functionally equivalent to mbedtls_ct_uint_if(condition, if1, 0) but
|
||||
* results in smaller code size.
|
||||
*
|
||||
* \param condition Condition to test.
|
||||
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
|
||||
*
|
||||
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
|
||||
*/
|
||||
static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1);
|
||||
|
||||
/** Choose between an mbedtls_ct_condition_t and 0.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* condition ? if1 : 0.
|
||||
*
|
||||
* Functionally equivalent to mbedtls_ct_bool_if(condition, if1, 0) but
|
||||
* results in smaller code size.
|
||||
*
|
||||
* \param condition Condition to test.
|
||||
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
|
||||
*
|
||||
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
|
||||
*/
|
||||
static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition,
|
||||
mbedtls_ct_condition_t if1);
|
||||
|
||||
/** Choose between a size_t value and 0.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* condition ? if1 : 0.
|
||||
*
|
||||
* Functionally equivalent to mbedtls_ct_size_if(condition, if1, 0) but
|
||||
* results in smaller code size.
|
||||
*
|
||||
* \param condition Condition to test.
|
||||
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
|
||||
*
|
||||
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
|
||||
*/
|
||||
static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1);
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
|
||||
/** Choose between an mbedtls_mpi_uint value and 0.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* condition ? if1 : 0.
|
||||
*
|
||||
* Functionally equivalent to mbedtls_ct_mpi_uint_if(condition, if1, 0) but
|
||||
* results in smaller code size.
|
||||
*
|
||||
* \param condition Condition to test.
|
||||
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
|
||||
*
|
||||
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
|
||||
*/
|
||||
static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition,
|
||||
mbedtls_mpi_uint if1);
|
||||
|
||||
#endif
|
||||
|
||||
/** Constant-flow char selection
|
||||
*
|
||||
* \param low Secret. Bottom of range
|
||||
* \param high Secret. Top of range
|
||||
* \param c Secret. Value to compare to range
|
||||
* \param t Secret. Value to return, if in range
|
||||
*
|
||||
* \return \p t if \p low <= \p c <= \p high, 0 otherwise.
|
||||
*/
|
||||
static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low,
|
||||
unsigned char high,
|
||||
unsigned char c,
|
||||
unsigned char t);
|
||||
|
||||
/** Choose between two error values. The values must be in the range [-32767..0].
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* condition ? if1 : if0.
|
||||
*
|
||||
* \param condition Condition to test.
|
||||
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
|
||||
* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
|
||||
*
|
||||
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
|
||||
*/
|
||||
static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0);
|
||||
|
||||
/** Choose between an error value and 0. The error value must be in the range [-32767..0].
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* condition ? if1 : 0.
|
||||
*
|
||||
* Functionally equivalent to mbedtls_ct_error_if(condition, if1, 0) but
|
||||
* results in smaller code size.
|
||||
*
|
||||
* \param condition Condition to test.
|
||||
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
|
||||
*
|
||||
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
|
||||
*/
|
||||
static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1);
|
||||
|
||||
/* ============================================================================
|
||||
* Block memory operations
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
|
||||
|
||||
/** Conditionally set a block of memory to zero.
|
||||
*
|
||||
* Regardless of the condition, every byte will be read once and written to
|
||||
* once.
|
||||
*
|
||||
* \param condition Secret. Condition to test.
|
||||
* \param buf Secret. Pointer to the start of the buffer.
|
||||
* \param len Number of bytes to set to zero.
|
||||
*
|
||||
* \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees
|
||||
* about not being optimised away if the memory is never read again.
|
||||
*/
|
||||
void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len);
|
||||
|
||||
/** Shift some data towards the left inside a buffer.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* memmove(start, start + offset, total - offset);
|
||||
* memset(start + (total - offset), 0, offset);
|
||||
*
|
||||
* Timing independence comes at the expense of performance.
|
||||
*
|
||||
* \param start Secret. Pointer to the start of the buffer.
|
||||
* \param total Total size of the buffer.
|
||||
* \param offset Secret. Offset from which to copy \p total - \p offset bytes.
|
||||
*/
|
||||
void mbedtls_ct_memmove_left(void *start,
|
||||
size_t total,
|
||||
size_t offset);
|
||||
|
||||
#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */
|
||||
|
||||
/** Conditional memcpy.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* if (condition) {
|
||||
* memcpy(dest, src1, len);
|
||||
* } else {
|
||||
* if (src2 != NULL)
|
||||
* memcpy(dest, src2, len);
|
||||
* }
|
||||
*
|
||||
* It will always read len bytes from src1.
|
||||
* If src2 != NULL, it will always read len bytes from src2.
|
||||
* If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest).
|
||||
*
|
||||
* \param condition The condition
|
||||
* \param dest Secret. Destination pointer.
|
||||
* \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE).
|
||||
* This may be equal to \p dest, but may not overlap in other ways.
|
||||
* \param src2 Secret (contents only - may branch to determine if this parameter is NULL).
|
||||
* Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL.
|
||||
* This may be equal to \p dest, but may not overlap it in other ways. It may overlap with \p src1.
|
||||
* \param len Number of bytes to copy.
|
||||
*/
|
||||
void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition,
|
||||
unsigned char *dest,
|
||||
const unsigned char *src1,
|
||||
const unsigned char *src2,
|
||||
size_t len
|
||||
);
|
||||
|
||||
/** Copy data from a secret position.
|
||||
*
|
||||
* Functionally equivalent to:
|
||||
*
|
||||
* memcpy(dst, src + offset, len)
|
||||
*
|
||||
* This function copies \p len bytes from \p src + \p offset to
|
||||
* \p dst, with a code flow and memory access pattern that does not depend on
|
||||
* \p offset, but only on \p offset_min, \p offset_max and \p len.
|
||||
*
|
||||
* \note This function reads from \p dest, but the value that
|
||||
* is read does not influence the result and this
|
||||
* function's behavior is well-defined regardless of the
|
||||
* contents of the buffers. This may result in false
|
||||
* positives from static or dynamic analyzers, especially
|
||||
* if \p dest is not initialized.
|
||||
*
|
||||
* \param dest Secret. The destination buffer. This must point to a writable
|
||||
* buffer of at least \p len bytes.
|
||||
* \param src Secret. The base of the source buffer. This must point to a
|
||||
* readable buffer of at least \p offset_max + \p len
|
||||
* bytes. Shouldn't overlap with \p dest
|
||||
* \param offset Secret. The offset in the source buffer from which to copy.
|
||||
* This must be no less than \p offset_min and no greater
|
||||
* than \p offset_max.
|
||||
* \param offset_min The minimal value of \p offset.
|
||||
* \param offset_max The maximal value of \p offset.
|
||||
* \param len The number of bytes to copy.
|
||||
*/
|
||||
void mbedtls_ct_memcpy_offset(unsigned char *dest,
|
||||
const unsigned char *src,
|
||||
size_t offset,
|
||||
size_t offset_min,
|
||||
size_t offset_max,
|
||||
size_t len);
|
||||
|
||||
/* Documented in include/mbedtls/constant_time.h. a and b are secret.
|
||||
|
||||
int mbedtls_ct_memcmp(const void *a,
|
||||
const void *b,
|
||||
size_t n);
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_NIST_KW_C)
|
||||
|
||||
/** Constant-time buffer comparison without branches.
|
||||
*
|
||||
* Similar to mbedtls_ct_memcmp, except that the result only depends on part of
|
||||
* the input data - differences in the head or tail are ignored. Functionally equivalent to:
|
||||
*
|
||||
* memcmp(a + skip_head, b + skip_head, size - skip_head - skip_tail)
|
||||
*
|
||||
* Time taken depends on \p n, but not on \p skip_head or \p skip_tail .
|
||||
*
|
||||
* Behaviour is undefined if ( \p skip_head + \p skip_tail) > \p n.
|
||||
*
|
||||
* \param a Secret. Pointer to the first buffer, containing at least \p n bytes. May not be NULL.
|
||||
* \param b Secret. Pointer to the second buffer, containing at least \p n bytes. May not be NULL.
|
||||
* \param n The number of bytes to examine (total size of the buffers).
|
||||
* \param skip_head Secret. The number of bytes to treat as non-significant at the start of the buffer.
|
||||
* These bytes will still be read.
|
||||
* \param skip_tail Secret. The number of bytes to treat as non-significant at the end of the buffer.
|
||||
* These bytes will still be read.
|
||||
*
|
||||
* \return Zero if the contents of the two buffers are the same, otherwise non-zero.
|
||||
*/
|
||||
int mbedtls_ct_memcmp_partial(const void *a,
|
||||
const void *b,
|
||||
size_t n,
|
||||
size_t skip_head,
|
||||
size_t skip_tail);
|
||||
|
||||
#endif
|
||||
|
||||
/* Include the implementation of static inline functions above. */
|
||||
#include "constant_time_impl.h"
|
||||
|
||||
#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */
|
||||
35
Libs/util/third_party/mbedtls/library/ctr.h
vendored
Normal file
35
Libs/util/third_party/mbedtls/library/ctr.h
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* \file ctr.h
|
||||
*
|
||||
* \brief This file contains common functionality for counter algorithms.
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CTR_H
|
||||
#define MBEDTLS_CTR_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* \brief Increment a big-endian 16-byte value.
|
||||
* This is quite performance-sensitive for AES-CTR and CTR-DRBG.
|
||||
*
|
||||
* \param n A 16-byte value to be incremented.
|
||||
*/
|
||||
static inline void mbedtls_ctr_increment_counter(uint8_t n[16])
|
||||
{
|
||||
// The 32-bit version seems to perform about the same as a 64-bit version
|
||||
// on 64-bit architectures, so no need to define a 64-bit version.
|
||||
for (int i = 3;; i--) {
|
||||
uint32_t x = MBEDTLS_GET_UINT32_BE(n, i << 2);
|
||||
x += 1;
|
||||
MBEDTLS_PUT_UINT32_BE(x, n, i << 2);
|
||||
if (x != 0 || i == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_CTR_H */
|
||||
1016
Libs/util/third_party/mbedtls/library/ctr_drbg.c
vendored
Normal file
1016
Libs/util/third_party/mbedtls/library/ctr_drbg.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
172
Libs/util/third_party/mbedtls/library/debug_internal.h
vendored
Normal file
172
Libs/util/third_party/mbedtls/library/debug_internal.h
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* \file debug_internal.h
|
||||
*
|
||||
* \brief Internal part of the public "debug.h".
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_DEBUG_INTERNAL_H
|
||||
#define MBEDTLS_DEBUG_INTERNAL_H
|
||||
|
||||
#include "mbedtls/debug.h"
|
||||
|
||||
/**
|
||||
* \brief Print a message to the debug output. This function is always used
|
||||
* through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl
|
||||
* context, file and line number parameters.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param level error level of the debug message
|
||||
* \param file file the message has occurred in
|
||||
* \param line line number the message has occurred at
|
||||
* \param format format specifier, in printf format
|
||||
* \param ... variables used by the format specifier
|
||||
*
|
||||
* \attention This function is intended for INTERNAL usage within the
|
||||
* library only.
|
||||
*/
|
||||
void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(5, 6);
|
||||
|
||||
/**
|
||||
* \brief Print the return value of a function to the debug output. This
|
||||
* function is always used through the MBEDTLS_SSL_DEBUG_RET() macro,
|
||||
* which supplies the ssl context, file and line number parameters.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param level error level of the debug message
|
||||
* \param file file the error has occurred in
|
||||
* \param line line number the error has occurred in
|
||||
* \param text the name of the function that returned the error
|
||||
* \param ret the return code value
|
||||
*
|
||||
* \attention This function is intended for INTERNAL usage within the
|
||||
* library only.
|
||||
*/
|
||||
void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, int ret);
|
||||
|
||||
/**
|
||||
* \brief Output a buffer of size len bytes to the debug output. This function
|
||||
* is always used through the MBEDTLS_SSL_DEBUG_BUF() macro,
|
||||
* which supplies the ssl context, file and line number parameters.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param level error level of the debug message
|
||||
* \param file file the error has occurred in
|
||||
* \param line line number the error has occurred in
|
||||
* \param text a name or label for the buffer being dumped. Normally the
|
||||
* variable or buffer name
|
||||
* \param buf the buffer to be outputted
|
||||
* \param len length of the buffer
|
||||
*
|
||||
* \attention This function is intended for INTERNAL usage within the
|
||||
* library only.
|
||||
*/
|
||||
void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line, const char *text,
|
||||
const unsigned char *buf, size_t len);
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
/**
|
||||
* \brief Print a MPI variable to the debug output. This function is always
|
||||
* used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the
|
||||
* ssl context, file and line number parameters.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param level error level of the debug message
|
||||
* \param file file the error has occurred in
|
||||
* \param line line number the error has occurred in
|
||||
* \param text a name or label for the MPI being output. Normally the
|
||||
* variable name
|
||||
* \param X the MPI variable
|
||||
*
|
||||
* \attention This function is intended for INTERNAL usage within the
|
||||
* library only.
|
||||
*/
|
||||
void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const mbedtls_mpi *X);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/**
|
||||
* \brief Print an ECP point to the debug output. This function is always
|
||||
* used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the
|
||||
* ssl context, file and line number parameters.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param level error level of the debug message
|
||||
* \param file file the error has occurred in
|
||||
* \param line line number the error has occurred in
|
||||
* \param text a name or label for the ECP point being output. Normally the
|
||||
* variable name
|
||||
* \param X the ECP point
|
||||
*
|
||||
* \attention This function is intended for INTERNAL usage within the
|
||||
* library only.
|
||||
*/
|
||||
void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const mbedtls_ecp_point *X);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
/**
|
||||
* \brief Print a X.509 certificate structure to the debug output. This
|
||||
* function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro,
|
||||
* which supplies the ssl context, file and line number parameters.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param level error level of the debug message
|
||||
* \param file file the error has occurred in
|
||||
* \param line line number the error has occurred in
|
||||
* \param text a name or label for the certificate being output
|
||||
* \param crt X.509 certificate structure
|
||||
*
|
||||
* \attention This function is intended for INTERNAL usage within the
|
||||
* library only.
|
||||
*/
|
||||
void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const mbedtls_x509_crt *crt);
|
||||
#endif
|
||||
|
||||
/* Note: the MBEDTLS_ECDH_C guard here is mandatory because this debug function
|
||||
only works for the built-in implementation. */
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) && \
|
||||
defined(MBEDTLS_ECDH_C)
|
||||
typedef enum {
|
||||
MBEDTLS_DEBUG_ECDH_Q,
|
||||
MBEDTLS_DEBUG_ECDH_QP,
|
||||
MBEDTLS_DEBUG_ECDH_Z,
|
||||
} mbedtls_debug_ecdh_attr;
|
||||
|
||||
/**
|
||||
* \brief Print a field of the ECDH structure in the SSL context to the debug
|
||||
* output. This function is always used through the
|
||||
* MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file
|
||||
* and line number parameters.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param level error level of the debug message
|
||||
* \param file file the error has occurred in
|
||||
* \param line line number the error has occurred in
|
||||
* \param ecdh the ECDH context
|
||||
* \param attr the identifier of the attribute being output
|
||||
*
|
||||
* \attention This function is intended for INTERNAL usage within the
|
||||
* library only.
|
||||
*/
|
||||
void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const mbedtls_ecdh_context *ecdh,
|
||||
mbedtls_debug_ecdh_attr attr);
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED &&
|
||||
MBEDTLS_ECDH_C */
|
||||
|
||||
#endif /* MBEDTLS_DEBUG_INTERNAL_H */
|
||||
867
Libs/util/third_party/mbedtls/library/ecdsa.c
vendored
Normal file
867
Libs/util/third_party/mbedtls/library/ecdsa.c
vendored
Normal file
@@ -0,0 +1,867 @@
|
||||
/*
|
||||
* Elliptic curve DSA
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* References:
|
||||
*
|
||||
* SEC1 https://www.secg.org/sec1-v2.pdf
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_C)
|
||||
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "mbedtls/asn1write.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
#include "mbedtls/hmac_drbg.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
|
||||
/*
|
||||
* Sub-context for ecdsa_verify()
|
||||
*/
|
||||
struct mbedtls_ecdsa_restart_ver {
|
||||
mbedtls_mpi u1, u2; /* intermediate values */
|
||||
enum { /* what to do next? */
|
||||
ecdsa_ver_init = 0, /* getting started */
|
||||
ecdsa_ver_muladd, /* muladd step */
|
||||
} state;
|
||||
};
|
||||
|
||||
/*
|
||||
* Init verify restart sub-context
|
||||
*/
|
||||
static void ecdsa_restart_ver_init(mbedtls_ecdsa_restart_ver_ctx *ctx)
|
||||
{
|
||||
mbedtls_mpi_init(&ctx->u1);
|
||||
mbedtls_mpi_init(&ctx->u2);
|
||||
ctx->state = ecdsa_ver_init;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the components of a verify restart sub-context
|
||||
*/
|
||||
static void ecdsa_restart_ver_free(mbedtls_ecdsa_restart_ver_ctx *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_mpi_free(&ctx->u1);
|
||||
mbedtls_mpi_free(&ctx->u2);
|
||||
|
||||
ecdsa_restart_ver_init(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sub-context for ecdsa_sign()
|
||||
*/
|
||||
struct mbedtls_ecdsa_restart_sig {
|
||||
int sign_tries;
|
||||
int key_tries;
|
||||
mbedtls_mpi k; /* per-signature random */
|
||||
mbedtls_mpi r; /* r value */
|
||||
enum { /* what to do next? */
|
||||
ecdsa_sig_init = 0, /* getting started */
|
||||
ecdsa_sig_mul, /* doing ecp_mul() */
|
||||
ecdsa_sig_modn, /* mod N computations */
|
||||
} state;
|
||||
};
|
||||
|
||||
/*
|
||||
* Init verify sign sub-context
|
||||
*/
|
||||
static void ecdsa_restart_sig_init(mbedtls_ecdsa_restart_sig_ctx *ctx)
|
||||
{
|
||||
ctx->sign_tries = 0;
|
||||
ctx->key_tries = 0;
|
||||
mbedtls_mpi_init(&ctx->k);
|
||||
mbedtls_mpi_init(&ctx->r);
|
||||
ctx->state = ecdsa_sig_init;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the components of a sign restart sub-context
|
||||
*/
|
||||
static void ecdsa_restart_sig_free(mbedtls_ecdsa_restart_sig_ctx *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_mpi_free(&ctx->k);
|
||||
mbedtls_mpi_free(&ctx->r);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
/*
|
||||
* Sub-context for ecdsa_sign_det()
|
||||
*/
|
||||
struct mbedtls_ecdsa_restart_det {
|
||||
mbedtls_hmac_drbg_context rng_ctx; /* DRBG state */
|
||||
enum { /* what to do next? */
|
||||
ecdsa_det_init = 0, /* getting started */
|
||||
ecdsa_det_sign, /* make signature */
|
||||
} state;
|
||||
};
|
||||
|
||||
/*
|
||||
* Init verify sign_det sub-context
|
||||
*/
|
||||
static void ecdsa_restart_det_init(mbedtls_ecdsa_restart_det_ctx *ctx)
|
||||
{
|
||||
mbedtls_hmac_drbg_init(&ctx->rng_ctx);
|
||||
ctx->state = ecdsa_det_init;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the components of a sign_det restart sub-context
|
||||
*/
|
||||
static void ecdsa_restart_det_free(mbedtls_ecdsa_restart_det_ctx *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_hmac_drbg_free(&ctx->rng_ctx);
|
||||
|
||||
ecdsa_restart_det_init(ctx);
|
||||
}
|
||||
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
||||
|
||||
#define ECDSA_RS_ECP (rs_ctx == NULL ? NULL : &rs_ctx->ecp)
|
||||
|
||||
/* Utility macro for checking and updating ops budget */
|
||||
#define ECDSA_BUDGET(ops) \
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecp_check_budget(grp, ECDSA_RS_ECP, ops));
|
||||
|
||||
/* Call this when entering a function that needs its own sub-context */
|
||||
#define ECDSA_RS_ENTER(SUB) do { \
|
||||
/* reset ops count for this call if top-level */ \
|
||||
if (rs_ctx != NULL && rs_ctx->ecp.depth++ == 0) \
|
||||
rs_ctx->ecp.ops_done = 0; \
|
||||
\
|
||||
/* set up our own sub-context if needed */ \
|
||||
if (mbedtls_ecp_restart_is_enabled() && \
|
||||
rs_ctx != NULL && rs_ctx->SUB == NULL) \
|
||||
{ \
|
||||
rs_ctx->SUB = mbedtls_calloc(1, sizeof(*rs_ctx->SUB)); \
|
||||
if (rs_ctx->SUB == NULL) \
|
||||
return MBEDTLS_ERR_ECP_ALLOC_FAILED; \
|
||||
\
|
||||
ecdsa_restart_## SUB ##_init(rs_ctx->SUB); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Call this when leaving a function that needs its own sub-context */
|
||||
#define ECDSA_RS_LEAVE(SUB) do { \
|
||||
/* clear our sub-context when not in progress (done or error) */ \
|
||||
if (rs_ctx != NULL && rs_ctx->SUB != NULL && \
|
||||
ret != MBEDTLS_ERR_ECP_IN_PROGRESS) \
|
||||
{ \
|
||||
ecdsa_restart_## SUB ##_free(rs_ctx->SUB); \
|
||||
mbedtls_free(rs_ctx->SUB); \
|
||||
rs_ctx->SUB = NULL; \
|
||||
} \
|
||||
\
|
||||
if (rs_ctx != NULL) \
|
||||
rs_ctx->ecp.depth--; \
|
||||
} while (0)
|
||||
|
||||
#else /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
#define ECDSA_RS_ECP NULL
|
||||
|
||||
#define ECDSA_BUDGET(ops) /* no-op; for compatibility */
|
||||
|
||||
#define ECDSA_RS_ENTER(SUB) (void) rs_ctx
|
||||
#define ECDSA_RS_LEAVE(SUB) (void) rs_ctx
|
||||
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) || \
|
||||
!defined(MBEDTLS_ECDSA_SIGN_ALT) || \
|
||||
!defined(MBEDTLS_ECDSA_VERIFY_ALT)
|
||||
/*
|
||||
* Derive a suitable integer for group grp from a buffer of length len
|
||||
* SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
|
||||
*/
|
||||
static int derive_mpi(const mbedtls_ecp_group *grp, mbedtls_mpi *x,
|
||||
const unsigned char *buf, size_t blen)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t n_size = (grp->nbits + 7) / 8;
|
||||
size_t use_size = blen > n_size ? n_size : blen;
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(x, buf, use_size));
|
||||
if (use_size * 8 > grp->nbits) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(x, use_size * 8 - grp->nbits));
|
||||
}
|
||||
|
||||
/* While at it, reduce modulo N */
|
||||
if (mbedtls_mpi_cmp_mpi(x, &grp->N) >= 0) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(x, x, &grp->N));
|
||||
}
|
||||
|
||||
cleanup:
|
||||
return ret;
|
||||
}
|
||||
#endif /* ECDSA_DETERMINISTIC || !ECDSA_SIGN_ALT || !ECDSA_VERIFY_ALT */
|
||||
|
||||
int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid)
|
||||
{
|
||||
switch (gid) {
|
||||
#ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
case MBEDTLS_ECP_DP_CURVE25519: return 0;
|
||||
#endif
|
||||
#ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
case MBEDTLS_ECP_DP_CURVE448: return 0;
|
||||
#endif
|
||||
default: return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_ECDSA_SIGN_ALT)
|
||||
/*
|
||||
* Compute ECDSA signature of a hashed message (SEC1 4.1.3)
|
||||
* Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
|
||||
*/
|
||||
int mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp,
|
||||
mbedtls_mpi *r, mbedtls_mpi *s,
|
||||
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
int (*f_rng_blind)(void *, unsigned char *, size_t),
|
||||
void *p_rng_blind,
|
||||
mbedtls_ecdsa_restart_ctx *rs_ctx)
|
||||
{
|
||||
int ret, key_tries, sign_tries;
|
||||
int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries;
|
||||
mbedtls_ecp_point R;
|
||||
mbedtls_mpi k, e, t;
|
||||
mbedtls_mpi *pk = &k, *pr = r;
|
||||
|
||||
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
|
||||
if (!mbedtls_ecdsa_can_do(grp->id) || grp->N.p == NULL) {
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
/* Make sure d is in range 1..n-1 */
|
||||
if (mbedtls_mpi_cmp_int(d, 1) < 0 || mbedtls_mpi_cmp_mpi(d, &grp->N) >= 0) {
|
||||
return MBEDTLS_ERR_ECP_INVALID_KEY;
|
||||
}
|
||||
|
||||
mbedtls_ecp_point_init(&R);
|
||||
mbedtls_mpi_init(&k); mbedtls_mpi_init(&e); mbedtls_mpi_init(&t);
|
||||
|
||||
ECDSA_RS_ENTER(sig);
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if (rs_ctx != NULL && rs_ctx->sig != NULL) {
|
||||
/* redirect to our context */
|
||||
p_sign_tries = &rs_ctx->sig->sign_tries;
|
||||
p_key_tries = &rs_ctx->sig->key_tries;
|
||||
pk = &rs_ctx->sig->k;
|
||||
pr = &rs_ctx->sig->r;
|
||||
|
||||
/* jump to current step */
|
||||
if (rs_ctx->sig->state == ecdsa_sig_mul) {
|
||||
goto mul;
|
||||
}
|
||||
if (rs_ctx->sig->state == ecdsa_sig_modn) {
|
||||
goto modn;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
*p_sign_tries = 0;
|
||||
do {
|
||||
if ((*p_sign_tries)++ > 10) {
|
||||
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Steps 1-3: generate a suitable ephemeral keypair
|
||||
* and set r = xR mod n
|
||||
*/
|
||||
*p_key_tries = 0;
|
||||
do {
|
||||
if ((*p_key_tries)++ > 10) {
|
||||
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, pk, f_rng, p_rng));
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if (rs_ctx != NULL && rs_ctx->sig != NULL) {
|
||||
rs_ctx->sig->state = ecdsa_sig_mul;
|
||||
}
|
||||
|
||||
mul:
|
||||
#endif
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, &R, pk, &grp->G,
|
||||
f_rng_blind,
|
||||
p_rng_blind,
|
||||
ECDSA_RS_ECP));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pr, &R.X, &grp->N));
|
||||
} while (mbedtls_mpi_cmp_int(pr, 0) == 0);
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if (rs_ctx != NULL && rs_ctx->sig != NULL) {
|
||||
rs_ctx->sig->state = ecdsa_sig_modn;
|
||||
}
|
||||
|
||||
modn:
|
||||
#endif
|
||||
/*
|
||||
* Accounting for everything up to the end of the loop
|
||||
* (step 6, but checking now avoids saving e and t)
|
||||
*/
|
||||
ECDSA_BUDGET(MBEDTLS_ECP_OPS_INV + 4);
|
||||
|
||||
/*
|
||||
* Step 5: derive MPI from hashed message
|
||||
*/
|
||||
MBEDTLS_MPI_CHK(derive_mpi(grp, &e, buf, blen));
|
||||
|
||||
/*
|
||||
* Generate a random value to blind inv_mod in next step,
|
||||
* avoiding a potential timing leak.
|
||||
*/
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, &t, f_rng_blind,
|
||||
p_rng_blind));
|
||||
|
||||
/*
|
||||
* Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
|
||||
*/
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(s, pr, d));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&e, &e, s));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&e, &e, &t));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pk, pk, &t));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pk, pk, &grp->N));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(s, pk, &grp->N));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(s, s, &e));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(s, s, &grp->N));
|
||||
} while (mbedtls_mpi_cmp_int(s, 0) == 0);
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if (rs_ctx != NULL && rs_ctx->sig != NULL) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(r, pr));
|
||||
}
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
mbedtls_ecp_point_free(&R);
|
||||
mbedtls_mpi_free(&k); mbedtls_mpi_free(&e); mbedtls_mpi_free(&t);
|
||||
|
||||
ECDSA_RS_LEAVE(sig);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute ECDSA signature of a hashed message
|
||||
*/
|
||||
int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
|
||||
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
/* Use the same RNG for both blinding and ephemeral key generation */
|
||||
return mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen,
|
||||
f_rng, p_rng, f_rng, p_rng, NULL);
|
||||
}
|
||||
#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
/*
|
||||
* Deterministic signature wrapper
|
||||
*
|
||||
* note: The f_rng_blind parameter must not be NULL.
|
||||
*
|
||||
*/
|
||||
int mbedtls_ecdsa_sign_det_restartable(mbedtls_ecp_group *grp,
|
||||
mbedtls_mpi *r, mbedtls_mpi *s,
|
||||
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
|
||||
mbedtls_md_type_t md_alg,
|
||||
int (*f_rng_blind)(void *, unsigned char *, size_t),
|
||||
void *p_rng_blind,
|
||||
mbedtls_ecdsa_restart_ctx *rs_ctx)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_hmac_drbg_context rng_ctx;
|
||||
mbedtls_hmac_drbg_context *p_rng = &rng_ctx;
|
||||
unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
|
||||
size_t grp_len = (grp->nbits + 7) / 8;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
mbedtls_mpi h;
|
||||
|
||||
if ((md_info = mbedtls_md_info_from_type(md_alg)) == NULL) {
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
mbedtls_mpi_init(&h);
|
||||
mbedtls_hmac_drbg_init(&rng_ctx);
|
||||
|
||||
ECDSA_RS_ENTER(det);
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if (rs_ctx != NULL && rs_ctx->det != NULL) {
|
||||
/* redirect to our context */
|
||||
p_rng = &rs_ctx->det->rng_ctx;
|
||||
|
||||
/* jump to current step */
|
||||
if (rs_ctx->det->state == ecdsa_det_sign) {
|
||||
goto sign;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
/* Use private key and message hash (reduced) to initialize HMAC_DRBG */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(d, data, grp_len));
|
||||
MBEDTLS_MPI_CHK(derive_mpi(grp, &h, buf, blen));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&h, data + grp_len, grp_len));
|
||||
MBEDTLS_MPI_CHK(mbedtls_hmac_drbg_seed_buf(p_rng, md_info, data, 2 * grp_len));
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if (rs_ctx != NULL && rs_ctx->det != NULL) {
|
||||
rs_ctx->det->state = ecdsa_det_sign;
|
||||
}
|
||||
|
||||
sign:
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECDSA_SIGN_ALT)
|
||||
(void) f_rng_blind;
|
||||
(void) p_rng_blind;
|
||||
ret = mbedtls_ecdsa_sign(grp, r, s, d, buf, blen,
|
||||
mbedtls_hmac_drbg_random, p_rng);
|
||||
#else
|
||||
ret = mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen,
|
||||
mbedtls_hmac_drbg_random, p_rng,
|
||||
f_rng_blind, p_rng_blind, rs_ctx);
|
||||
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
|
||||
|
||||
cleanup:
|
||||
mbedtls_hmac_drbg_free(&rng_ctx);
|
||||
mbedtls_mpi_free(&h);
|
||||
|
||||
ECDSA_RS_LEAVE(det);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deterministic signature wrapper
|
||||
*/
|
||||
int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r,
|
||||
mbedtls_mpi *s, const mbedtls_mpi *d,
|
||||
const unsigned char *buf, size_t blen,
|
||||
mbedtls_md_type_t md_alg,
|
||||
int (*f_rng_blind)(void *, unsigned char *,
|
||||
size_t),
|
||||
void *p_rng_blind)
|
||||
{
|
||||
return mbedtls_ecdsa_sign_det_restartable(grp, r, s, d, buf, blen, md_alg,
|
||||
f_rng_blind, p_rng_blind, NULL);
|
||||
}
|
||||
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
||||
|
||||
#if !defined(MBEDTLS_ECDSA_VERIFY_ALT)
|
||||
/*
|
||||
* Verify ECDSA signature of hashed message (SEC1 4.1.4)
|
||||
* Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
|
||||
*/
|
||||
int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp,
|
||||
const unsigned char *buf, size_t blen,
|
||||
const mbedtls_ecp_point *Q,
|
||||
const mbedtls_mpi *r,
|
||||
const mbedtls_mpi *s,
|
||||
mbedtls_ecdsa_restart_ctx *rs_ctx)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi e, s_inv, u1, u2;
|
||||
mbedtls_ecp_point R;
|
||||
mbedtls_mpi *pu1 = &u1, *pu2 = &u2;
|
||||
|
||||
mbedtls_ecp_point_init(&R);
|
||||
mbedtls_mpi_init(&e); mbedtls_mpi_init(&s_inv);
|
||||
mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2);
|
||||
|
||||
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
|
||||
if (!mbedtls_ecdsa_can_do(grp->id) || grp->N.p == NULL) {
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
ECDSA_RS_ENTER(ver);
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if (rs_ctx != NULL && rs_ctx->ver != NULL) {
|
||||
/* redirect to our context */
|
||||
pu1 = &rs_ctx->ver->u1;
|
||||
pu2 = &rs_ctx->ver->u2;
|
||||
|
||||
/* jump to current step */
|
||||
if (rs_ctx->ver->state == ecdsa_ver_muladd) {
|
||||
goto muladd;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
/*
|
||||
* Step 1: make sure r and s are in range 1..n-1
|
||||
*/
|
||||
if (mbedtls_mpi_cmp_int(r, 1) < 0 || mbedtls_mpi_cmp_mpi(r, &grp->N) >= 0 ||
|
||||
mbedtls_mpi_cmp_int(s, 1) < 0 || mbedtls_mpi_cmp_mpi(s, &grp->N) >= 0) {
|
||||
ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 3: derive MPI from hashed message
|
||||
*/
|
||||
MBEDTLS_MPI_CHK(derive_mpi(grp, &e, buf, blen));
|
||||
|
||||
/*
|
||||
* Step 4: u1 = e / s mod n, u2 = r / s mod n
|
||||
*/
|
||||
ECDSA_BUDGET(MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2);
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&s_inv, s, &grp->N));
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pu1, &e, &s_inv));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pu1, pu1, &grp->N));
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pu2, r, &s_inv));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pu2, pu2, &grp->N));
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if (rs_ctx != NULL && rs_ctx->ver != NULL) {
|
||||
rs_ctx->ver->state = ecdsa_ver_muladd;
|
||||
}
|
||||
|
||||
muladd:
|
||||
#endif
|
||||
/*
|
||||
* Step 5: R = u1 G + u2 Q
|
||||
*/
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecp_muladd_restartable(grp,
|
||||
&R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP));
|
||||
|
||||
if (mbedtls_ecp_is_zero(&R)) {
|
||||
ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 6: convert xR to an integer (no-op)
|
||||
* Step 7: reduce xR mod n (gives v)
|
||||
*/
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&R.X, &R.X, &grp->N));
|
||||
|
||||
/*
|
||||
* Step 8: check if v (that is, R.X) is equal to r
|
||||
*/
|
||||
if (mbedtls_mpi_cmp_mpi(&R.X, r) != 0) {
|
||||
ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
mbedtls_ecp_point_free(&R);
|
||||
mbedtls_mpi_free(&e); mbedtls_mpi_free(&s_inv);
|
||||
mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2);
|
||||
|
||||
ECDSA_RS_LEAVE(ver);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify ECDSA signature of hashed message
|
||||
*/
|
||||
int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
|
||||
const unsigned char *buf, size_t blen,
|
||||
const mbedtls_ecp_point *Q,
|
||||
const mbedtls_mpi *r,
|
||||
const mbedtls_mpi *s)
|
||||
{
|
||||
return mbedtls_ecdsa_verify_restartable(grp, buf, blen, Q, r, s, NULL);
|
||||
}
|
||||
#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */
|
||||
|
||||
/*
|
||||
* Convert a signature (given by context) to ASN.1
|
||||
*/
|
||||
static int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s,
|
||||
unsigned char *sig, size_t sig_size,
|
||||
size_t *slen)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = { 0 };
|
||||
unsigned char *p = buf + sizeof(buf);
|
||||
size_t len = 0;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, s));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, r));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
if (len > sig_size) {
|
||||
return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
memcpy(sig, p, len);
|
||||
*slen = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute and write signature
|
||||
*/
|
||||
int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
|
||||
mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hlen,
|
||||
unsigned char *sig, size_t sig_size, size_t *slen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
mbedtls_ecdsa_restart_ctx *rs_ctx)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi r, s;
|
||||
if (f_rng == NULL) {
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_restartable(&ctx->grp, &r, &s, &ctx->d,
|
||||
hash, hlen, md_alg, f_rng,
|
||||
p_rng, rs_ctx));
|
||||
#else
|
||||
(void) md_alg;
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_SIGN_ALT)
|
||||
(void) rs_ctx;
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign(&ctx->grp, &r, &s, &ctx->d,
|
||||
hash, hlen, f_rng, p_rng));
|
||||
#else
|
||||
/* Use the same RNG for both blinding and ephemeral key generation */
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_restartable(&ctx->grp, &r, &s, &ctx->d,
|
||||
hash, hlen, f_rng, p_rng, f_rng,
|
||||
p_rng, rs_ctx));
|
||||
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
|
||||
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
||||
|
||||
MBEDTLS_MPI_CHK(ecdsa_signature_to_asn1(&r, &s, sig, sig_size, slen));
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute and write signature
|
||||
*/
|
||||
int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
|
||||
mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hlen,
|
||||
unsigned char *sig, size_t sig_size, size_t *slen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng)
|
||||
{
|
||||
return mbedtls_ecdsa_write_signature_restartable(
|
||||
ctx, md_alg, hash, hlen, sig, sig_size, slen,
|
||||
f_rng, p_rng, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read and check signature
|
||||
*/
|
||||
int mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx,
|
||||
const unsigned char *hash, size_t hlen,
|
||||
const unsigned char *sig, size_t slen)
|
||||
{
|
||||
return mbedtls_ecdsa_read_signature_restartable(
|
||||
ctx, hash, hlen, sig, slen, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Restartable read and check signature
|
||||
*/
|
||||
int mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx,
|
||||
const unsigned char *hash, size_t hlen,
|
||||
const unsigned char *sig, size_t slen,
|
||||
mbedtls_ecdsa_restart_ctx *rs_ctx)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *p = (unsigned char *) sig;
|
||||
const unsigned char *end = sig + slen;
|
||||
size_t len;
|
||||
mbedtls_mpi r, s;
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (p + len != end) {
|
||||
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_mpi(&p, end, &r)) != 0 ||
|
||||
(ret = mbedtls_asn1_get_mpi(&p, end, &s)) != 0) {
|
||||
ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
goto cleanup;
|
||||
}
|
||||
#if defined(MBEDTLS_ECDSA_VERIFY_ALT)
|
||||
(void) rs_ctx;
|
||||
|
||||
if ((ret = mbedtls_ecdsa_verify(&ctx->grp, hash, hlen,
|
||||
&ctx->Q, &r, &s)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
#else
|
||||
if ((ret = mbedtls_ecdsa_verify_restartable(&ctx->grp, hash, hlen,
|
||||
&ctx->Q, &r, &s, rs_ctx)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
|
||||
|
||||
/* At this point we know that the buffer starts with a valid signature.
|
||||
* Return 0 if the buffer just contains the signature, and a specific
|
||||
* error code if the valid signature is followed by more data. */
|
||||
if (p != end) {
|
||||
ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_ECDSA_GENKEY_ALT)
|
||||
/*
|
||||
* Generate key pair
|
||||
*/
|
||||
int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = mbedtls_ecp_group_load(&ctx->grp, gid);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return mbedtls_ecp_gen_keypair(&ctx->grp, &ctx->d,
|
||||
&ctx->Q, f_rng, p_rng);
|
||||
}
|
||||
#endif /* !MBEDTLS_ECDSA_GENKEY_ALT */
|
||||
|
||||
/*
|
||||
* Set context from an mbedtls_ecp_keypair
|
||||
*/
|
||||
int mbedtls_ecdsa_from_keypair(mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
if ((ret = mbedtls_ecp_group_copy(&ctx->grp, &key->grp)) != 0 ||
|
||||
(ret = mbedtls_mpi_copy(&ctx->d, &key->d)) != 0 ||
|
||||
(ret = mbedtls_ecp_copy(&ctx->Q, &key->Q)) != 0) {
|
||||
mbedtls_ecdsa_free(ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize context
|
||||
*/
|
||||
void mbedtls_ecdsa_init(mbedtls_ecdsa_context *ctx)
|
||||
{
|
||||
mbedtls_ecp_keypair_init(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free context
|
||||
*/
|
||||
void mbedtls_ecdsa_free(mbedtls_ecdsa_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_ecp_keypair_free(ctx);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/*
|
||||
* Initialize a restart context
|
||||
*/
|
||||
void mbedtls_ecdsa_restart_init(mbedtls_ecdsa_restart_ctx *ctx)
|
||||
{
|
||||
mbedtls_ecp_restart_init(&ctx->ecp);
|
||||
|
||||
ctx->ver = NULL;
|
||||
ctx->sig = NULL;
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
ctx->det = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the components of a restart context
|
||||
*/
|
||||
void mbedtls_ecdsa_restart_free(mbedtls_ecdsa_restart_ctx *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_ecp_restart_free(&ctx->ecp);
|
||||
|
||||
ecdsa_restart_ver_free(ctx->ver);
|
||||
mbedtls_free(ctx->ver);
|
||||
ctx->ver = NULL;
|
||||
|
||||
ecdsa_restart_sig_free(ctx->sig);
|
||||
mbedtls_free(ctx->sig);
|
||||
ctx->sig = NULL;
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
ecdsa_restart_det_free(ctx->det);
|
||||
mbedtls_free(ctx->det);
|
||||
ctx->det = NULL;
|
||||
#endif
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
#endif /* MBEDTLS_ECDSA_C */
|
||||
3718
Libs/util/third_party/mbedtls/library/ecp.c
vendored
Normal file
3718
Libs/util/third_party/mbedtls/library/ecp.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5460
Libs/util/third_party/mbedtls/library/ecp_curves.c
vendored
Normal file
5460
Libs/util/third_party/mbedtls/library/ecp_curves.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6036
Libs/util/third_party/mbedtls/library/ecp_curves_new.c
vendored
Normal file
6036
Libs/util/third_party/mbedtls/library/ecp_curves_new.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
287
Libs/util/third_party/mbedtls/library/ecp_internal_alt.h
vendored
Normal file
287
Libs/util/third_party/mbedtls/library/ecp_internal_alt.h
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
/**
|
||||
* \file ecp_internal_alt.h
|
||||
*
|
||||
* \brief Function declarations for alternative implementation of elliptic curve
|
||||
* point arithmetic.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* References:
|
||||
*
|
||||
* [1] BERNSTEIN, Daniel J. Curve25519: new Diffie-Hellman speed records.
|
||||
* <http://cr.yp.to/ecdh/curve25519-20060209.pdf>
|
||||
*
|
||||
* [2] CORON, Jean-S'ebastien. Resistance against differential power analysis
|
||||
* for elliptic curve cryptosystems. In : Cryptographic Hardware and
|
||||
* Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
|
||||
* <http://link.springer.com/chapter/10.1007/3-540-48059-5_25>
|
||||
*
|
||||
* [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to
|
||||
* render ECC resistant against Side Channel Attacks. IACR Cryptology
|
||||
* ePrint Archive, 2004, vol. 2004, p. 342.
|
||||
* <http://eprint.iacr.org/2004/342.pdf>
|
||||
*
|
||||
* [4] Certicom Research. SEC 2: Recommended Elliptic Curve Domain Parameters.
|
||||
* <http://www.secg.org/sec2-v2.pdf>
|
||||
*
|
||||
* [5] HANKERSON, Darrel, MENEZES, Alfred J., VANSTONE, Scott. Guide to Elliptic
|
||||
* Curve Cryptography.
|
||||
*
|
||||
* [6] Digital Signature Standard (DSS), FIPS 186-4.
|
||||
* <http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf>
|
||||
*
|
||||
* [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer
|
||||
* Security (TLS), RFC 4492.
|
||||
* <https://tools.ietf.org/search/rfc4492>
|
||||
*
|
||||
* [8] <http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html>
|
||||
*
|
||||
* [9] COHEN, Henri. A Course in Computational Algebraic Number Theory.
|
||||
* Springer Science & Business Media, 1 Aug 2000
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_ECP_INTERNAL_H
|
||||
#define MBEDTLS_ECP_INTERNAL_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
|
||||
|
||||
/**
|
||||
* \brief Indicate if the Elliptic Curve Point module extension can
|
||||
* handle the group.
|
||||
*
|
||||
* \param grp The pointer to the elliptic curve group that will be the
|
||||
* basis of the cryptographic computations.
|
||||
*
|
||||
* \return Non-zero if successful.
|
||||
*/
|
||||
unsigned char mbedtls_internal_ecp_grp_capable(const mbedtls_ecp_group *grp);
|
||||
|
||||
/**
|
||||
* \brief Initialise the Elliptic Curve Point module extension.
|
||||
*
|
||||
* If mbedtls_internal_ecp_grp_capable returns true for a
|
||||
* group, this function has to be able to initialise the
|
||||
* module for it.
|
||||
*
|
||||
* This module can be a driver to a crypto hardware
|
||||
* accelerator, for which this could be an initialise function.
|
||||
*
|
||||
* \param grp The pointer to the group the module needs to be
|
||||
* initialised for.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
*/
|
||||
int mbedtls_internal_ecp_init(const mbedtls_ecp_group *grp);
|
||||
|
||||
/**
|
||||
* \brief Frees and deallocates the Elliptic Curve Point module
|
||||
* extension.
|
||||
*
|
||||
* \param grp The pointer to the group the module was initialised for.
|
||||
*/
|
||||
void mbedtls_internal_ecp_free(const mbedtls_ecp_group *grp);
|
||||
|
||||
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
|
||||
|
||||
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
|
||||
/**
|
||||
* \brief Randomize jacobian coordinates:
|
||||
* (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l.
|
||||
*
|
||||
* \param grp Pointer to the group representing the curve.
|
||||
*
|
||||
* \param pt The point on the curve to be randomised, given with Jacobian
|
||||
* coordinates.
|
||||
*
|
||||
* \param f_rng A function pointer to the random number generator.
|
||||
*
|
||||
* \param p_rng A pointer to the random number generator state.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
*/
|
||||
int mbedtls_internal_ecp_randomize_jac(const mbedtls_ecp_group *grp,
|
||||
mbedtls_ecp_point *pt, int (*f_rng)(void *,
|
||||
unsigned char *,
|
||||
size_t),
|
||||
void *p_rng);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_ADD_MIXED_ALT)
|
||||
/**
|
||||
* \brief Addition: R = P + Q, mixed affine-Jacobian coordinates.
|
||||
*
|
||||
* The coordinates of Q must be normalized (= affine),
|
||||
* but those of P don't need to. R is not normalized.
|
||||
*
|
||||
* This function is used only as a subrutine of
|
||||
* ecp_mul_comb().
|
||||
*
|
||||
* Special cases: (1) P or Q is zero, (2) R is zero,
|
||||
* (3) P == Q.
|
||||
* None of these cases can happen as intermediate step in
|
||||
* ecp_mul_comb():
|
||||
* - at each step, P, Q and R are multiples of the base
|
||||
* point, the factor being less than its order, so none of
|
||||
* them is zero;
|
||||
* - Q is an odd multiple of the base point, P an even
|
||||
* multiple, due to the choice of precomputed points in the
|
||||
* modified comb method.
|
||||
* So branches for these cases do not leak secret information.
|
||||
*
|
||||
* We accept Q->Z being unset (saving memory in tables) as
|
||||
* meaning 1.
|
||||
*
|
||||
* Cost in field operations if done by [5] 3.22:
|
||||
* 1A := 8M + 3S
|
||||
*
|
||||
* \param grp Pointer to the group representing the curve.
|
||||
*
|
||||
* \param R Pointer to a point structure to hold the result.
|
||||
*
|
||||
* \param P Pointer to the first summand, given with Jacobian
|
||||
* coordinates
|
||||
*
|
||||
* \param Q Pointer to the second summand, given with affine
|
||||
* coordinates.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
*/
|
||||
int mbedtls_internal_ecp_add_mixed(const mbedtls_ecp_group *grp,
|
||||
mbedtls_ecp_point *R, const mbedtls_ecp_point *P,
|
||||
const mbedtls_ecp_point *Q);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Point doubling R = 2 P, Jacobian coordinates.
|
||||
*
|
||||
* Cost: 1D := 3M + 4S (A == 0)
|
||||
* 4M + 4S (A == -3)
|
||||
* 3M + 6S + 1a otherwise
|
||||
* when the implementation is based on the "dbl-1998-cmo-2"
|
||||
* doubling formulas in [8] and standard optimizations are
|
||||
* applied when curve parameter A is one of { 0, -3 }.
|
||||
*
|
||||
* \param grp Pointer to the group representing the curve.
|
||||
*
|
||||
* \param R Pointer to a point structure to hold the result.
|
||||
*
|
||||
* \param P Pointer to the point that has to be doubled, given with
|
||||
* Jacobian coordinates.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
*/
|
||||
#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
|
||||
int mbedtls_internal_ecp_double_jac(const mbedtls_ecp_group *grp,
|
||||
mbedtls_ecp_point *R, const mbedtls_ecp_point *P);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Normalize jacobian coordinates of an array of (pointers to)
|
||||
* points.
|
||||
*
|
||||
* Using Montgomery's trick to perform only one inversion mod P
|
||||
* the cost is:
|
||||
* 1N(t) := 1I + (6t - 3)M + 1S
|
||||
* (See for example Algorithm 10.3.4. in [9])
|
||||
*
|
||||
* This function is used only as a subrutine of
|
||||
* ecp_mul_comb().
|
||||
*
|
||||
* Warning: fails (returning an error) if one of the points is
|
||||
* zero!
|
||||
* This should never happen, see choice of w in ecp_mul_comb().
|
||||
*
|
||||
* \param grp Pointer to the group representing the curve.
|
||||
*
|
||||
* \param T Array of pointers to the points to normalise.
|
||||
*
|
||||
* \param t_len Number of elements in the array.
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* an error if one of the points is zero.
|
||||
*/
|
||||
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
|
||||
int mbedtls_internal_ecp_normalize_jac_many(const mbedtls_ecp_group *grp,
|
||||
mbedtls_ecp_point *T[], size_t t_len);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Normalize jacobian coordinates so that Z == 0 || Z == 1.
|
||||
*
|
||||
* Cost in field operations if done by [5] 3.2.1:
|
||||
* 1N := 1I + 3M + 1S
|
||||
*
|
||||
* \param grp Pointer to the group representing the curve.
|
||||
*
|
||||
* \param pt pointer to the point to be normalised. This is an
|
||||
* input/output parameter.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
*/
|
||||
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
|
||||
int mbedtls_internal_ecp_normalize_jac(const mbedtls_ecp_group *grp,
|
||||
mbedtls_ecp_point *pt);
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
|
||||
|
||||
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
|
||||
int mbedtls_internal_ecp_double_add_mxz(const mbedtls_ecp_group *grp,
|
||||
mbedtls_ecp_point *R,
|
||||
mbedtls_ecp_point *S,
|
||||
const mbedtls_ecp_point *P,
|
||||
const mbedtls_ecp_point *Q,
|
||||
const mbedtls_mpi *d);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Randomize projective x/z coordinates:
|
||||
* (X, Z) -> (l X, l Z) for random l
|
||||
*
|
||||
* \param grp pointer to the group representing the curve
|
||||
*
|
||||
* \param P the point on the curve to be randomised given with
|
||||
* projective coordinates. This is an input/output parameter.
|
||||
*
|
||||
* \param f_rng a function pointer to the random number generator
|
||||
*
|
||||
* \param p_rng a pointer to the random number generator state
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
|
||||
int mbedtls_internal_ecp_randomize_mxz(const mbedtls_ecp_group *grp,
|
||||
mbedtls_ecp_point *P, int (*f_rng)(void *,
|
||||
unsigned char *,
|
||||
size_t),
|
||||
void *p_rng);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Normalize Montgomery x/z coordinates: X = X/Z, Z = 1.
|
||||
*
|
||||
* \param grp pointer to the group representing the curve
|
||||
*
|
||||
* \param P pointer to the point to be normalised. This is an
|
||||
* input/output parameter.
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
|
||||
int mbedtls_internal_ecp_normalize_mxz(const mbedtls_ecp_group *grp,
|
||||
mbedtls_ecp_point *P);
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
|
||||
|
||||
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
|
||||
|
||||
#endif /* ecp_internal_alt.h */
|
||||
325
Libs/util/third_party/mbedtls/library/ecp_invasive.h
vendored
Normal file
325
Libs/util/third_party/mbedtls/library/ecp_invasive.h
vendored
Normal file
@@ -0,0 +1,325 @@
|
||||
/**
|
||||
* \file ecp_invasive.h
|
||||
*
|
||||
* \brief ECP module: interfaces for invasive testing only.
|
||||
*
|
||||
* The interfaces in this file are intended for testing purposes only.
|
||||
* They SHOULD NOT be made available in library integrations except when
|
||||
* building the library for testing.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_ECP_INVASIVE_H
|
||||
#define MBEDTLS_ECP_INVASIVE_H
|
||||
|
||||
#include "common.h"
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "bignum_mod.h"
|
||||
#include "mbedtls/ecp.h"
|
||||
|
||||
/*
|
||||
* Curve modulus types
|
||||
*/
|
||||
typedef enum {
|
||||
MBEDTLS_ECP_MOD_NONE = 0,
|
||||
MBEDTLS_ECP_MOD_COORDINATE,
|
||||
MBEDTLS_ECP_MOD_SCALAR
|
||||
} mbedtls_ecp_modulus_type;
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_ECP_VARIANT_NONE = 0,
|
||||
MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT,
|
||||
MBEDTLS_ECP_VARIANT_WITH_MPI_UINT
|
||||
} mbedtls_ecp_variant;
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_LIGHT)
|
||||
|
||||
/** Queries the ecp variant.
|
||||
*
|
||||
* \return The id of the ecp variant.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
mbedtls_ecp_variant mbedtls_ecp_get_variant(void);
|
||||
|
||||
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
|
||||
/** Generate a private key on a Montgomery curve (Curve25519 or Curve448).
|
||||
*
|
||||
* This function implements key generation for the set of secret keys
|
||||
* specified in [Curve25519] p. 5 and in [Curve448]. The resulting value
|
||||
* has the lower bits masked but is not necessarily canonical.
|
||||
*
|
||||
* \note - [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
|
||||
* - [RFC7748] https://tools.ietf.org/html/rfc7748
|
||||
*
|
||||
* \p high_bit The position of the high-order bit of the key to generate.
|
||||
* This is the bit-size of the key minus 1:
|
||||
* 254 for Curve25519 or 447 for Curve448.
|
||||
* \param d The randomly generated key. This is a number of size
|
||||
* exactly \p high_bit + 1 bits, with the least significant bits
|
||||
* masked as specified in [Curve25519] and in [RFC7748] §5.
|
||||
* \param f_rng The RNG function.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c MBEDTLS_ERR_ECP_xxx or MBEDTLS_ERR_MPI_xxx on failure.
|
||||
*/
|
||||
int mbedtls_ecp_gen_privkey_mx(size_t high_bit,
|
||||
mbedtls_mpi *d,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
|
||||
*
|
||||
* This operation expects a 384 bit MPI and the result of the reduction
|
||||
* is a 192 bit MPI.
|
||||
*
|
||||
* \param[in,out] Np The address of the MPI to be converted.
|
||||
* Must have twice as many limbs as the modulus.
|
||||
* Upon return this holds the reduced value. The bitlength
|
||||
* of the reduced value is the same as that of the modulus
|
||||
* (192 bits).
|
||||
* \param[in] Nn The length of \p Np in limbs.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 448-bit MPI
|
||||
* (double the bitlength of the modulus).
|
||||
* Upon return holds the reduced value which is
|
||||
* in range `0 <= X < 2 * N` (where N is the modulus).
|
||||
* The bitlength of the reduced value is the same as
|
||||
* that of the modulus (224 bits).
|
||||
* \param[in] X_limbs The length of \p X in limbs.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs is not the
|
||||
* limb size that sores a 448-bit MPI.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 512-bit MPI
|
||||
* (double the bitlength of the modulus).
|
||||
* Upon return holds the reduced value which is
|
||||
* in range `0 <= X < 2 * N` (where N is the modulus).
|
||||
* The bitlength of the reduced value is the same as
|
||||
* that of the modulus (256 bits).
|
||||
* \param[in] X_limbs The length of \p X in limbs.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs is not the
|
||||
* limb size that sores a 512-bit MPI.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5)
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have twice as many limbs as the modulus
|
||||
* (the modulus is 521 bits long). Upon return this
|
||||
* holds the reduced value. The reduced value is
|
||||
* in range `0 <= X < 2 * N` (where N is the modulus).
|
||||
* and its the bitlength is one plus the bitlength
|
||||
* of the modulus.
|
||||
* \param[in] X_limbs The length of \p X in limbs.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs does not have
|
||||
* twice as many limbs as the modulus.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 768-bit MPI
|
||||
* (double the bitlength of the modulus).
|
||||
* Upon return holds the reduced value which is
|
||||
* in range `0 <= X < 2 * N` (where N is the modulus).
|
||||
* The bitlength of the reduced value is the same as
|
||||
* that of the modulus (384 bits).
|
||||
* \param[in] X_limbs The length of \p N in limbs.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p N_n does not have
|
||||
* twice as many limbs as the modulus.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p192k1 = 2^192 - R,
|
||||
* with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 384-bit MPI
|
||||
* (double the bitlength of the modulus).
|
||||
* Upon return holds the reduced value which is
|
||||
* in range `0 <= X < 2 * N` (where N is the modulus).
|
||||
* The bitlength of the reduced value is the same as
|
||||
* that of the modulus (192 bits).
|
||||
* \param[in] X_limbs The length of \p X in limbs.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
|
||||
* twice as many limbs as the modulus.
|
||||
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p224k1 = 2^224 - R,
|
||||
* with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 448-bit MPI
|
||||
* (double the bitlength of the modulus).
|
||||
* Upon return holds the reduced value which is
|
||||
* in range `0 <= X < 2 * N` (where N is the modulus).
|
||||
* The bitlength of the reduced value is the same as
|
||||
* that of the modulus (224 bits).
|
||||
* \param[in] X_limbs The length of \p X in limbs.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
|
||||
* twice as many limbs as the modulus.
|
||||
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p256k1 = 2^256 - R,
|
||||
* with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 512-bit MPI
|
||||
* (double the bitlength of the modulus).
|
||||
* Upon return holds the reduced value which is
|
||||
* in range `0 <= X < 2 * N` (where N is the modulus).
|
||||
* The bitlength of the reduced value is the same as
|
||||
* that of the modulus (256 bits).
|
||||
* \param[in] X_limbs The length of \p X in limbs.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
|
||||
* twice as many limbs as the modulus.
|
||||
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p255 = 2^255 - 19
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 510-bit MPI
|
||||
* (double the bitlength of the modulus).
|
||||
* Upon return holds the reduced value which is
|
||||
* in range `0 <= X < 2 * N` (where N is the modulus).
|
||||
* \param[in] X_limbs The length of \p X in limbs.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
|
||||
* twice as many limbs as the modulus.
|
||||
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
|
||||
* Write X as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return A0 + A1 + B1 +
|
||||
* (B0 + B1) * 2^224.
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 896-bit MPI
|
||||
* (double the bitlength of the modulus). Upon return
|
||||
* holds the reduced value which is in range `0 <= X <
|
||||
* N` (where N is the modulus). The bitlength of the
|
||||
* reduced value is the same as that of the modulus
|
||||
* (448 bits).
|
||||
* \param[in] X_limbs The length of \p X in limbs.
|
||||
*
|
||||
* \return \c 0 on Success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
|
||||
* twice as many limbs as the modulus.
|
||||
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation
|
||||
* failed.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
|
||||
|
||||
/** Initialise a modulus with hard-coded const curve data.
|
||||
*
|
||||
* \note The caller is responsible for the \p N modulus' memory.
|
||||
* mbedtls_mpi_mod_modulus_free(&N) should be invoked at the
|
||||
* end of its lifecycle.
|
||||
*
|
||||
* \param[in,out] N The address of the modulus structure to populate.
|
||||
* Must be initialized.
|
||||
* \param[in] id The mbedtls_ecp_group_id for which to initialise the modulus.
|
||||
* \param[in] ctype The mbedtls_ecp_modulus_type identifier for a coordinate modulus (P)
|
||||
* or a scalar modulus (N).
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the given MPIs do not
|
||||
* have the correct number of limbs.
|
||||
*
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N,
|
||||
const mbedtls_ecp_group_id id,
|
||||
const mbedtls_ecp_modulus_type ctype);
|
||||
|
||||
#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_ECP_C */
|
||||
|
||||
#endif /* MBEDTLS_ECP_INVASIVE_H */
|
||||
680
Libs/util/third_party/mbedtls/library/entropy.c
vendored
Normal file
680
Libs/util/third_party/mbedtls/library/entropy.c
vendored
Normal file
@@ -0,0 +1,680 @@
|
||||
/*
|
||||
* Entropy accumulator implementation
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_C)
|
||||
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "entropy_poll.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
|
||||
|
||||
void mbedtls_entropy_init(mbedtls_entropy_context *ctx)
|
||||
{
|
||||
ctx->source_count = 0;
|
||||
memset(ctx->source, 0, sizeof(ctx->source));
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init(&ctx->mutex);
|
||||
#endif
|
||||
|
||||
ctx->accumulator_started = 0;
|
||||
mbedtls_md_init(&ctx->accumulator);
|
||||
|
||||
/* Reminder: Update ENTROPY_HAVE_STRONG in the test files
|
||||
* when adding more strong entropy sources here. */
|
||||
|
||||
#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
|
||||
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
|
||||
mbedtls_entropy_add_source(ctx, mbedtls_platform_entropy_poll, NULL,
|
||||
MBEDTLS_ENTROPY_MIN_PLATFORM,
|
||||
MBEDTLS_ENTROPY_SOURCE_STRONG);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||
mbedtls_entropy_add_source(ctx, mbedtls_hardware_poll, NULL,
|
||||
MBEDTLS_ENTROPY_MIN_HARDWARE,
|
||||
MBEDTLS_ENTROPY_SOURCE_STRONG);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
mbedtls_entropy_add_source(ctx, mbedtls_nv_seed_poll, NULL,
|
||||
MBEDTLS_ENTROPY_BLOCK_SIZE,
|
||||
MBEDTLS_ENTROPY_SOURCE_STRONG);
|
||||
ctx->initial_entropy_run = 0;
|
||||
#endif
|
||||
#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
|
||||
}
|
||||
|
||||
void mbedtls_entropy_free(mbedtls_entropy_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the context was already free, don't call free() again.
|
||||
* This is important for mutexes which don't allow double-free. */
|
||||
if (ctx->accumulator_started == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_free(&ctx->mutex);
|
||||
#endif
|
||||
mbedtls_md_free(&ctx->accumulator);
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
ctx->initial_entropy_run = 0;
|
||||
#endif
|
||||
ctx->source_count = 0;
|
||||
mbedtls_platform_zeroize(ctx->source, sizeof(ctx->source));
|
||||
ctx->accumulator_started = -1;
|
||||
}
|
||||
|
||||
int mbedtls_entropy_add_source(mbedtls_entropy_context *ctx,
|
||||
mbedtls_entropy_f_source_ptr f_source, void *p_source,
|
||||
size_t threshold, int strong)
|
||||
{
|
||||
int idx, ret = 0;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
idx = ctx->source_count;
|
||||
if (idx >= MBEDTLS_ENTROPY_MAX_SOURCES) {
|
||||
ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ctx->source[idx].f_source = f_source;
|
||||
ctx->source[idx].p_source = p_source;
|
||||
ctx->source[idx].threshold = threshold;
|
||||
ctx->source[idx].strong = strong;
|
||||
|
||||
ctx->source_count++;
|
||||
|
||||
exit:
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
|
||||
return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Entropy accumulator update
|
||||
*/
|
||||
static int entropy_update(mbedtls_entropy_context *ctx, unsigned char source_id,
|
||||
const unsigned char *data, size_t len)
|
||||
{
|
||||
unsigned char header[2];
|
||||
unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
size_t use_len = len;
|
||||
const unsigned char *p = data;
|
||||
int ret = 0;
|
||||
|
||||
if (use_len > MBEDTLS_ENTROPY_BLOCK_SIZE) {
|
||||
if ((ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_ENTROPY_MD),
|
||||
data, len, tmp)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
p = tmp;
|
||||
use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
header[0] = source_id;
|
||||
header[1] = use_len & 0xFF;
|
||||
|
||||
/*
|
||||
* Start the accumulator if this has not already happened. Note that
|
||||
* it is sufficient to start the accumulator here only because all calls to
|
||||
* gather entropy eventually execute this code.
|
||||
*/
|
||||
if (ctx->accumulator_started == 0) {
|
||||
ret = mbedtls_md_setup(&ctx->accumulator,
|
||||
mbedtls_md_info_from_type(MBEDTLS_ENTROPY_MD), 0);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
ret = mbedtls_md_starts(&ctx->accumulator);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
ctx->accumulator_started = 1;
|
||||
}
|
||||
if ((ret = mbedtls_md_update(&ctx->accumulator, header, 2)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
ret = mbedtls_md_update(&ctx->accumulator, p, use_len);
|
||||
|
||||
cleanup:
|
||||
mbedtls_platform_zeroize(tmp, sizeof(tmp));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_entropy_update_manual(mbedtls_entropy_context *ctx,
|
||||
const unsigned char *data, size_t len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = entropy_update(ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len);
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
|
||||
return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run through the different sources to add entropy to our accumulator
|
||||
*/
|
||||
static int entropy_gather_internal(mbedtls_entropy_context *ctx)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
int i;
|
||||
int have_one_strong = 0;
|
||||
unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER];
|
||||
size_t olen;
|
||||
|
||||
if (ctx->source_count == 0) {
|
||||
return MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run through our entropy sources
|
||||
*/
|
||||
for (i = 0; i < ctx->source_count; i++) {
|
||||
if (ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG) {
|
||||
have_one_strong = 1;
|
||||
}
|
||||
|
||||
olen = 0;
|
||||
if ((ret = ctx->source[i].f_source(ctx->source[i].p_source,
|
||||
buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add if we actually gathered something
|
||||
*/
|
||||
if (olen > 0) {
|
||||
if ((ret = entropy_update(ctx, (unsigned char) i,
|
||||
buf, olen)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
ctx->source[i].size += olen;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_one_strong == 0) {
|
||||
ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Thread-safe wrapper for entropy_gather_internal()
|
||||
*/
|
||||
int mbedtls_entropy_gather(mbedtls_entropy_context *ctx)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = entropy_gather_internal(ctx);
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
|
||||
return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_entropy_func(void *data, unsigned char *output, size_t len)
|
||||
{
|
||||
int ret, count = 0, i, thresholds_reached;
|
||||
size_t strong_size;
|
||||
mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
|
||||
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
|
||||
if (len > MBEDTLS_ENTROPY_BLOCK_SIZE) {
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
/* Update the NV entropy seed before generating any entropy for outside
|
||||
* use.
|
||||
*/
|
||||
if (ctx->initial_entropy_run == 0) {
|
||||
ctx->initial_entropy_run = 1;
|
||||
if ((ret = mbedtls_entropy_update_nv_seed(ctx)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Always gather extra entropy before a call
|
||||
*/
|
||||
do {
|
||||
if (count++ > ENTROPY_MAX_LOOP) {
|
||||
ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((ret = entropy_gather_internal(ctx)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
thresholds_reached = 1;
|
||||
strong_size = 0;
|
||||
for (i = 0; i < ctx->source_count; i++) {
|
||||
if (ctx->source[i].size < ctx->source[i].threshold) {
|
||||
thresholds_reached = 0;
|
||||
}
|
||||
if (ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG) {
|
||||
strong_size += ctx->source[i].size;
|
||||
}
|
||||
}
|
||||
} while (!thresholds_reached || strong_size < MBEDTLS_ENTROPY_BLOCK_SIZE);
|
||||
|
||||
memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
|
||||
|
||||
/*
|
||||
* Note that at this stage it is assumed that the accumulator was started
|
||||
* in a previous call to entropy_update(). If this is not guaranteed, the
|
||||
* code below will fail.
|
||||
*/
|
||||
if ((ret = mbedtls_md_finish(&ctx->accumulator, buf)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset accumulator and counters and recycle existing entropy
|
||||
*/
|
||||
mbedtls_md_free(&ctx->accumulator);
|
||||
mbedtls_md_init(&ctx->accumulator);
|
||||
ret = mbedtls_md_setup(&ctx->accumulator,
|
||||
mbedtls_md_info_from_type(MBEDTLS_ENTROPY_MD), 0);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
ret = mbedtls_md_starts(&ctx->accumulator);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_update(&ctx->accumulator, buf,
|
||||
MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform second hashing on entropy
|
||||
*/
|
||||
if ((ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_ENTROPY_MD),
|
||||
buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 0; i < ctx->source_count; i++) {
|
||||
ctx->source[i].size = 0;
|
||||
}
|
||||
|
||||
memcpy(output, buf, len);
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
|
||||
return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
int mbedtls_entropy_update_nv_seed(mbedtls_entropy_context *ctx)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
||||
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
|
||||
/* Read new seed and write it to NV */
|
||||
if ((ret = mbedtls_entropy_func(ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mbedtls_nv_seed_write(buf, MBEDTLS_ENTROPY_BLOCK_SIZE) < 0) {
|
||||
return MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
||||
}
|
||||
|
||||
/* Manually update the remaining stream with a separator value to diverge */
|
||||
memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
|
||||
ret = mbedtls_entropy_update_manual(ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_ENTROPY_NV_SEED */
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
int mbedtls_entropy_write_seed_file(mbedtls_entropy_context *ctx, const char *path)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
FILE *f = NULL;
|
||||
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
|
||||
if ((ret = mbedtls_entropy_func(ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0) {
|
||||
ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((f = fopen(path, "wb")) == NULL) {
|
||||
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
|
||||
mbedtls_setbuf(f, NULL);
|
||||
|
||||
if (fwrite(buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f) != MBEDTLS_ENTROPY_BLOCK_SIZE) {
|
||||
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
||||
|
||||
if (f != NULL) {
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_entropy_update_seed_file(mbedtls_entropy_context *ctx, const char *path)
|
||||
{
|
||||
int ret = 0;
|
||||
FILE *f;
|
||||
size_t n;
|
||||
unsigned char buf[MBEDTLS_ENTROPY_MAX_SEED_SIZE];
|
||||
|
||||
if ((f = fopen(path, "rb")) == NULL) {
|
||||
return MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
||||
}
|
||||
|
||||
/* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
|
||||
mbedtls_setbuf(f, NULL);
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
n = (size_t) ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
if (n > MBEDTLS_ENTROPY_MAX_SEED_SIZE) {
|
||||
n = MBEDTLS_ENTROPY_MAX_SEED_SIZE;
|
||||
}
|
||||
|
||||
if (fread(buf, 1, n, f) != n) {
|
||||
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
||||
} else {
|
||||
ret = mbedtls_entropy_update_manual(ctx, buf, n);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return mbedtls_entropy_write_seed_file(ctx, path);
|
||||
}
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/*
|
||||
* Dummy source function
|
||||
*/
|
||||
static int entropy_dummy_source(void *data, unsigned char *output,
|
||||
size_t len, size_t *olen)
|
||||
{
|
||||
((void) data);
|
||||
|
||||
memset(output, 0x2a, len);
|
||||
*olen = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||
|
||||
static int mbedtls_entropy_source_self_test_gather(unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t entropy_len = 0;
|
||||
size_t olen = 0;
|
||||
size_t attempts = buf_len;
|
||||
|
||||
while (attempts > 0 && entropy_len < buf_len) {
|
||||
if ((ret = mbedtls_hardware_poll(NULL, buf + entropy_len,
|
||||
buf_len - entropy_len, &olen)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
entropy_len += olen;
|
||||
attempts--;
|
||||
}
|
||||
|
||||
if (entropy_len < buf_len) {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int mbedtls_entropy_source_self_test_check_bits(const unsigned char *buf,
|
||||
size_t buf_len)
|
||||
{
|
||||
unsigned char set = 0xFF;
|
||||
unsigned char unset = 0x00;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < buf_len; i++) {
|
||||
set &= buf[i];
|
||||
unset |= buf[i];
|
||||
}
|
||||
|
||||
return set == 0xFF || unset == 0x00;
|
||||
}
|
||||
|
||||
/*
|
||||
* A test to ensure that the entropy sources are functioning correctly
|
||||
* and there is no obvious failure. The test performs the following checks:
|
||||
* - The entropy source is not providing only 0s (all bits unset) or 1s (all
|
||||
* bits set).
|
||||
* - The entropy source is not providing values in a pattern. Because the
|
||||
* hardware could be providing data in an arbitrary length, this check polls
|
||||
* the hardware entropy source twice and compares the result to ensure they
|
||||
* are not equal.
|
||||
* - The error code returned by the entropy source is not an error.
|
||||
*/
|
||||
int mbedtls_entropy_source_self_test(int verbose)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char buf0[2 * sizeof(unsigned long long int)];
|
||||
unsigned char buf1[2 * sizeof(unsigned long long int)];
|
||||
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf(" ENTROPY_BIAS test: ");
|
||||
}
|
||||
|
||||
memset(buf0, 0x00, sizeof(buf0));
|
||||
memset(buf1, 0x00, sizeof(buf1));
|
||||
|
||||
if ((ret = mbedtls_entropy_source_self_test_gather(buf0, sizeof(buf0))) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
if ((ret = mbedtls_entropy_source_self_test_gather(buf1, sizeof(buf1))) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Make sure that the returned values are not all 0 or 1 */
|
||||
if ((ret = mbedtls_entropy_source_self_test_check_bits(buf0, sizeof(buf0))) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
if ((ret = mbedtls_entropy_source_self_test_check_bits(buf1, sizeof(buf1))) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Make sure that the entropy source is not returning values in a
|
||||
* pattern */
|
||||
ret = memcmp(buf0, buf1, sizeof(buf0)) == 0;
|
||||
|
||||
cleanup:
|
||||
if (verbose != 0) {
|
||||
if (ret != 0) {
|
||||
mbedtls_printf("failed\n");
|
||||
} else {
|
||||
mbedtls_printf("passed\n");
|
||||
}
|
||||
|
||||
mbedtls_printf("\n");
|
||||
}
|
||||
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
|
||||
|
||||
/*
|
||||
* The actual entropy quality is hard to test, but we can at least
|
||||
* test that the functions don't cause errors and write the correct
|
||||
* amount of data to buffers.
|
||||
*/
|
||||
int mbedtls_entropy_self_test(int verbose)
|
||||
{
|
||||
int ret = 1;
|
||||
mbedtls_entropy_context ctx;
|
||||
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
|
||||
unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
|
||||
size_t i, j;
|
||||
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf(" ENTROPY test: ");
|
||||
}
|
||||
|
||||
mbedtls_entropy_init(&ctx);
|
||||
|
||||
/* First do a gather to make sure we have default sources */
|
||||
if ((ret = mbedtls_entropy_gather(&ctx)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = mbedtls_entropy_add_source(&ctx, entropy_dummy_source, NULL, 16,
|
||||
MBEDTLS_ENTROPY_SOURCE_WEAK);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_entropy_update_manual(&ctx, buf, sizeof(buf))) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* To test that mbedtls_entropy_func writes correct number of bytes:
|
||||
* - use the whole buffer and rely on ASan to detect overruns
|
||||
* - collect entropy 8 times and OR the result in an accumulator:
|
||||
* any byte should then be 0 with probably 2^(-64), so requiring
|
||||
* each of the 32 or 64 bytes to be non-zero has a false failure rate
|
||||
* of at most 2^(-58) which is acceptable.
|
||||
*/
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((ret = mbedtls_entropy_func(&ctx, buf, sizeof(buf))) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (j = 0; j < sizeof(buf); j++) {
|
||||
acc[j] |= buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < sizeof(buf); j++) {
|
||||
if (acc[j] == 0) {
|
||||
ret = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||
if ((ret = mbedtls_entropy_source_self_test(0)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
mbedtls_entropy_free(&ctx);
|
||||
|
||||
if (verbose != 0) {
|
||||
if (ret != 0) {
|
||||
mbedtls_printf("failed\n");
|
||||
} else {
|
||||
mbedtls_printf("passed\n");
|
||||
}
|
||||
|
||||
mbedtls_printf("\n");
|
||||
}
|
||||
|
||||
return ret != 0;
|
||||
}
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#endif /* MBEDTLS_ENTROPY_C */
|
||||
231
Libs/util/third_party/mbedtls/library/entropy_poll.c
vendored
Normal file
231
Libs/util/third_party/mbedtls/library/entropy_poll.c
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Platform-specific and custom entropy polling functions
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#if defined(__linux__) || defined(__midipix__)
|
||||
/* Ensure that syscall() is available even when compiling with -std=c99 */
|
||||
#if !defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_C)
|
||||
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "entropy_poll.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#if defined(MBEDTLS_TIMING_C)
|
||||
#include "mbedtls/timing.h"
|
||||
#endif
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
|
||||
|
||||
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
|
||||
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
|
||||
!defined(__HAIKU__) && !defined(__midipix__) && !defined(__MVS__)
|
||||
#error \
|
||||
"Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in mbedtls_config.h"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
|
||||
|
||||
#include <windows.h>
|
||||
#include <bcrypt.h>
|
||||
#include <intsafe.h>
|
||||
|
||||
int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len,
|
||||
size_t *olen)
|
||||
{
|
||||
((void) data);
|
||||
*olen = 0;
|
||||
|
||||
/*
|
||||
* BCryptGenRandom takes ULONG for size, which is smaller than size_t on
|
||||
* 64-bit Windows platforms. Extract entropy in chunks of len (dependent
|
||||
* on ULONG_MAX) size.
|
||||
*/
|
||||
while (len != 0) {
|
||||
unsigned long ulong_bytes =
|
||||
(len > ULONG_MAX) ? ULONG_MAX : (unsigned long) len;
|
||||
|
||||
if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, ulong_bytes,
|
||||
BCRYPT_USE_SYSTEM_PREFERRED_RNG))) {
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
|
||||
*olen += ulong_bytes;
|
||||
len -= ulong_bytes;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else /* _WIN32 && !EFIX64 && !EFI32 */
|
||||
|
||||
/*
|
||||
* Test for Linux getrandom() support.
|
||||
* Since there is no wrapper in the libc yet, use the generic syscall wrapper
|
||||
* available in GNU libc and compatible libc's (eg uClibc).
|
||||
*/
|
||||
#if ((defined(__linux__) && defined(__GLIBC__)) || defined(__midipix__))
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#if defined(SYS_getrandom)
|
||||
#define HAVE_GETRANDOM
|
||||
#include <errno.h>
|
||||
|
||||
static int getrandom_wrapper(void *buf, size_t buflen, unsigned int flags)
|
||||
{
|
||||
/* MemSan cannot understand that the syscall writes to the buffer */
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(memory_sanitizer)
|
||||
memset(buf, 0, buflen);
|
||||
#endif
|
||||
#endif
|
||||
return (int) syscall(SYS_getrandom, buf, buflen, flags);
|
||||
}
|
||||
#endif /* SYS_getrandom */
|
||||
#endif /* __linux__ || __midipix__ */
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
#include <sys/param.h>
|
||||
#if (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || \
|
||||
(defined(__DragonFly__) && __DragonFly_version >= 500700)
|
||||
#include <errno.h>
|
||||
#include <sys/random.h>
|
||||
#define HAVE_GETRANDOM
|
||||
static int getrandom_wrapper(void *buf, size_t buflen, unsigned int flags)
|
||||
{
|
||||
return (int) getrandom(buf, buflen, flags);
|
||||
}
|
||||
#endif /* (__FreeBSD__ && __FreeBSD_version >= 1200000) ||
|
||||
(__DragonFly__ && __DragonFly_version >= 500700) */
|
||||
#endif /* __FreeBSD__ || __DragonFly__ */
|
||||
|
||||
/*
|
||||
* Some BSD systems provide KERN_ARND.
|
||||
* This is equivalent to reading from /dev/urandom, only it doesn't require an
|
||||
* open file descriptor, and provides up to 256 bytes per call (basically the
|
||||
* same as getentropy(), but with a longer history).
|
||||
*
|
||||
* Documentation: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7
|
||||
*/
|
||||
#if (defined(__FreeBSD__) || defined(__NetBSD__)) && !defined(HAVE_GETRANDOM)
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#if defined(KERN_ARND)
|
||||
#define HAVE_SYSCTL_ARND
|
||||
|
||||
static int sysctl_arnd_wrapper(unsigned char *buf, size_t buflen)
|
||||
{
|
||||
int name[2];
|
||||
size_t len;
|
||||
|
||||
name[0] = CTL_KERN;
|
||||
name[1] = KERN_ARND;
|
||||
|
||||
while (buflen > 0) {
|
||||
len = buflen > 256 ? 256 : buflen;
|
||||
if (sysctl(name, 2, buf, &len, NULL, 0) == -1) {
|
||||
return -1;
|
||||
}
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* KERN_ARND */
|
||||
#endif /* __FreeBSD__ || __NetBSD__ */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int mbedtls_platform_entropy_poll(void *data,
|
||||
unsigned char *output, size_t len, size_t *olen)
|
||||
{
|
||||
FILE *file;
|
||||
size_t read_len;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
((void) data);
|
||||
|
||||
#if defined(HAVE_GETRANDOM)
|
||||
ret = getrandom_wrapper(output, len, 0);
|
||||
if (ret >= 0) {
|
||||
*olen = (size_t) ret;
|
||||
return 0;
|
||||
} else if (errno != ENOSYS) {
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
/* Fall through if the system call isn't known. */
|
||||
#else
|
||||
((void) ret);
|
||||
#endif /* HAVE_GETRANDOM */
|
||||
|
||||
#if defined(HAVE_SYSCTL_ARND)
|
||||
((void) file);
|
||||
((void) read_len);
|
||||
if (sysctl_arnd_wrapper(output, len) == -1) {
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
*olen = len;
|
||||
return 0;
|
||||
#else
|
||||
|
||||
*olen = 0;
|
||||
|
||||
file = fopen("/dev/urandom", "rb");
|
||||
if (file == NULL) {
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
|
||||
/* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
|
||||
mbedtls_setbuf(file, NULL);
|
||||
|
||||
read_len = fread(output, 1, len, file);
|
||||
if (read_len != len) {
|
||||
fclose(file);
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
*olen = len;
|
||||
|
||||
return 0;
|
||||
#endif /* HAVE_SYSCTL_ARND */
|
||||
}
|
||||
#endif /* _WIN32 && !EFIX64 && !EFI32 */
|
||||
#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
int mbedtls_nv_seed_poll(void *data,
|
||||
unsigned char *output, size_t len, size_t *olen)
|
||||
{
|
||||
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
|
||||
size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
|
||||
((void) data);
|
||||
|
||||
memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
|
||||
|
||||
if (mbedtls_nv_seed_read(buf, MBEDTLS_ENTROPY_BLOCK_SIZE) < 0) {
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
|
||||
if (len < use_len) {
|
||||
use_len = len;
|
||||
}
|
||||
|
||||
memcpy(output, buf, use_len);
|
||||
*olen = use_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_ENTROPY_NV_SEED */
|
||||
|
||||
#endif /* MBEDTLS_ENTROPY_C */
|
||||
64
Libs/util/third_party/mbedtls/library/entropy_poll.h
vendored
Normal file
64
Libs/util/third_party/mbedtls/library/entropy_poll.h
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* \file entropy_poll.h
|
||||
*
|
||||
* \brief Platform-specific and custom entropy polling functions
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_ENTROPY_POLL_H
|
||||
#define MBEDTLS_ENTROPY_POLL_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default thresholds for built-in sources, in bytes
|
||||
*/
|
||||
#define MBEDTLS_ENTROPY_MIN_PLATFORM 32 /**< Minimum for platform source */
|
||||
#if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE)
|
||||
#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Minimum for the hardware source */
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
|
||||
/**
|
||||
* \brief Platform-specific entropy poll callback
|
||||
*/
|
||||
int mbedtls_platform_entropy_poll(void *data,
|
||||
unsigned char *output, size_t len, size_t *olen);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||
/**
|
||||
* \brief Entropy poll callback for a hardware source
|
||||
*
|
||||
* \warning This is not provided by Mbed TLS!
|
||||
* See \c MBEDTLS_ENTROPY_HARDWARE_ALT in mbedtls_config.h.
|
||||
*
|
||||
* \note This must accept NULL as its first argument.
|
||||
*/
|
||||
int mbedtls_hardware_poll(void *data,
|
||||
unsigned char *output, size_t len, size_t *olen);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
/**
|
||||
* \brief Entropy poll callback for a non-volatile seed file
|
||||
*
|
||||
* \note This must accept NULL as its first argument.
|
||||
*/
|
||||
int mbedtls_nv_seed_poll(void *data,
|
||||
unsigned char *output, size_t len, size_t *olen);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* entropy_poll.h */
|
||||
633
Libs/util/third_party/mbedtls/library/hmac_drbg.c
vendored
Normal file
633
Libs/util/third_party/mbedtls/library/hmac_drbg.c
vendored
Normal file
@@ -0,0 +1,633 @@
|
||||
/*
|
||||
* HMAC_DRBG implementation (NIST SP 800-90)
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* The NIST SP 800-90A DRBGs are described in the following publication.
|
||||
* http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
|
||||
* References below are based on rev. 1 (January 2012).
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_HMAC_DRBG_C)
|
||||
|
||||
#include "mbedtls/hmac_drbg.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
/*
|
||||
* HMAC_DRBG context initialization
|
||||
*/
|
||||
void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(mbedtls_hmac_drbg_context));
|
||||
|
||||
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* HMAC_DRBG update, using optional additional data (10.1.2.2)
|
||||
*/
|
||||
int mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional,
|
||||
size_t add_len)
|
||||
{
|
||||
size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info);
|
||||
unsigned char rounds = (additional != NULL && add_len != 0) ? 2 : 1;
|
||||
unsigned char sep[1];
|
||||
unsigned char K[MBEDTLS_MD_MAX_SIZE];
|
||||
int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
|
||||
|
||||
for (sep[0] = 0; sep[0] < rounds; sep[0]++) {
|
||||
/* Step 1 or 4 */
|
||||
if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
|
||||
ctx->V, md_len)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
|
||||
sep, 1)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if (rounds == 2) {
|
||||
if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
|
||||
additional, add_len)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, K)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Step 2 or 5 */
|
||||
if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, K, md_len)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
|
||||
ctx->V, md_len)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(K, sizeof(K));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
|
||||
*/
|
||||
int mbedtls_hmac_drbg_seed_buf(mbedtls_hmac_drbg_context *ctx,
|
||||
const mbedtls_md_info_t *md_info,
|
||||
const unsigned char *data, size_t data_len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init(&ctx->mutex);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set initial working state.
|
||||
* Use the V memory location, which is currently all 0, to initialize the
|
||||
* MD context with an all-zero key. Then set V to its initial value.
|
||||
*/
|
||||
if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V,
|
||||
mbedtls_md_get_size(md_info))) != 0) {
|
||||
return ret;
|
||||
}
|
||||
memset(ctx->V, 0x01, mbedtls_md_get_size(md_info));
|
||||
|
||||
if ((ret = mbedtls_hmac_drbg_update(ctx, data, data_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal function used both for seeding and reseeding the DRBG.
|
||||
* Comments starting with arabic numbers refer to section 10.1.2.4
|
||||
* of SP800-90A, while roman numbers refer to section 9.2.
|
||||
*/
|
||||
static int hmac_drbg_reseed_core(mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t len,
|
||||
int use_nonce)
|
||||
{
|
||||
unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
|
||||
size_t seedlen = 0;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
{
|
||||
size_t total_entropy_len;
|
||||
|
||||
if (use_nonce == 0) {
|
||||
total_entropy_len = ctx->entropy_len;
|
||||
} else {
|
||||
total_entropy_len = ctx->entropy_len * 3 / 2;
|
||||
}
|
||||
|
||||
/* III. Check input length */
|
||||
if (len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
|
||||
total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) {
|
||||
return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
|
||||
}
|
||||
}
|
||||
|
||||
memset(seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT);
|
||||
|
||||
/* IV. Gather entropy_len bytes of entropy for the seed */
|
||||
if ((ret = ctx->f_entropy(ctx->p_entropy,
|
||||
seed, ctx->entropy_len)) != 0) {
|
||||
return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
seedlen += ctx->entropy_len;
|
||||
|
||||
/* For initial seeding, allow adding of nonce generated
|
||||
* from the entropy source. See Sect 8.6.7 in SP800-90A. */
|
||||
if (use_nonce) {
|
||||
/* Note: We don't merge the two calls to f_entropy() in order
|
||||
* to avoid requesting too much entropy from f_entropy()
|
||||
* at once. Specifically, if the underlying digest is not
|
||||
* SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
|
||||
* is larger than the maximum of 32 Bytes that our own
|
||||
* entropy source implementation can emit in a single
|
||||
* call in configurations disabling SHA-512. */
|
||||
if ((ret = ctx->f_entropy(ctx->p_entropy,
|
||||
seed + seedlen,
|
||||
ctx->entropy_len / 2)) != 0) {
|
||||
return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
|
||||
seedlen += ctx->entropy_len / 2;
|
||||
}
|
||||
|
||||
|
||||
/* 1. Concatenate entropy and additional data if any */
|
||||
if (additional != NULL && len != 0) {
|
||||
memcpy(seed + seedlen, additional, len);
|
||||
seedlen += len;
|
||||
}
|
||||
|
||||
/* 2. Update state */
|
||||
if ((ret = mbedtls_hmac_drbg_update(ctx, seed, seedlen)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* 3. Reset reseed_counter */
|
||||
ctx->reseed_counter = 1;
|
||||
|
||||
exit:
|
||||
/* 4. Done */
|
||||
mbedtls_platform_zeroize(seed, seedlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* HMAC_DRBG reseeding: 10.1.2.4 + 9.2
|
||||
*/
|
||||
int mbedtls_hmac_drbg_reseed(mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t len)
|
||||
{
|
||||
return hmac_drbg_reseed_core(ctx, additional, len, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* HMAC_DRBG initialisation (10.1.2.3 + 9.1)
|
||||
*
|
||||
* The nonce is not passed as a separate parameter but extracted
|
||||
* from the entropy source as suggested in 8.6.7.
|
||||
*/
|
||||
int mbedtls_hmac_drbg_seed(mbedtls_hmac_drbg_context *ctx,
|
||||
const mbedtls_md_info_t *md_info,
|
||||
int (*f_entropy)(void *, unsigned char *, size_t),
|
||||
void *p_entropy,
|
||||
const unsigned char *custom,
|
||||
size_t len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t md_size;
|
||||
|
||||
if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The mutex is initialized iff the md context is set up. */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init(&ctx->mutex);
|
||||
#endif
|
||||
|
||||
md_size = mbedtls_md_get_size(md_info);
|
||||
|
||||
/*
|
||||
* Set initial working state.
|
||||
* Use the V memory location, which is currently all 0, to initialize the
|
||||
* MD context with an all-zero key. Then set V to its initial value.
|
||||
*/
|
||||
if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V, md_size)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
memset(ctx->V, 0x01, md_size);
|
||||
|
||||
ctx->f_entropy = f_entropy;
|
||||
ctx->p_entropy = p_entropy;
|
||||
|
||||
if (ctx->entropy_len == 0) {
|
||||
/*
|
||||
* See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
|
||||
* each hash function, then according to SP800-90A rev1 10.1 table 2,
|
||||
* min_entropy_len (in bits) is security_strength.
|
||||
*
|
||||
* (This also matches the sizes used in the NIST test vectors.)
|
||||
*/
|
||||
ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
|
||||
md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
|
||||
32; /* better (256+) -> 256 bits */
|
||||
}
|
||||
|
||||
if ((ret = hmac_drbg_reseed_core(ctx, custom, len,
|
||||
1 /* add nonce */)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set prediction resistance
|
||||
*/
|
||||
void mbedtls_hmac_drbg_set_prediction_resistance(mbedtls_hmac_drbg_context *ctx,
|
||||
int resistance)
|
||||
{
|
||||
ctx->prediction_resistance = resistance;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set entropy length grabbed for seeding
|
||||
*/
|
||||
void mbedtls_hmac_drbg_set_entropy_len(mbedtls_hmac_drbg_context *ctx, size_t len)
|
||||
{
|
||||
ctx->entropy_len = len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set reseed interval
|
||||
*/
|
||||
void mbedtls_hmac_drbg_set_reseed_interval(mbedtls_hmac_drbg_context *ctx, int interval)
|
||||
{
|
||||
ctx->reseed_interval = interval;
|
||||
}
|
||||
|
||||
/*
|
||||
* HMAC_DRBG random function with optional additional data:
|
||||
* 10.1.2.5 (arabic) + 9.3 (Roman)
|
||||
*/
|
||||
int mbedtls_hmac_drbg_random_with_add(void *p_rng,
|
||||
unsigned char *output, size_t out_len,
|
||||
const unsigned char *additional, size_t add_len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
|
||||
size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info);
|
||||
size_t left = out_len;
|
||||
unsigned char *out = output;
|
||||
|
||||
/* II. Check request length */
|
||||
if (out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST) {
|
||||
return MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG;
|
||||
}
|
||||
|
||||
/* III. Check input length */
|
||||
if (add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT) {
|
||||
return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
|
||||
}
|
||||
|
||||
/* 1. (aka VII and IX) Check reseed counter and PR */
|
||||
if (ctx->f_entropy != NULL && /* For no-reseeding instances */
|
||||
(ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
|
||||
ctx->reseed_counter > ctx->reseed_interval)) {
|
||||
if ((ret = mbedtls_hmac_drbg_reseed(ctx, additional, add_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
add_len = 0; /* VII.4 */
|
||||
}
|
||||
|
||||
/* 2. Use additional data if any */
|
||||
if (additional != NULL && add_len != 0) {
|
||||
if ((ret = mbedtls_hmac_drbg_update(ctx,
|
||||
additional, add_len)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* 3, 4, 5. Generate bytes */
|
||||
while (left != 0) {
|
||||
size_t use_len = left > md_len ? md_len : left;
|
||||
|
||||
if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
|
||||
ctx->V, md_len)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(out, ctx->V, use_len);
|
||||
out += use_len;
|
||||
left -= use_len;
|
||||
}
|
||||
|
||||
/* 6. Update */
|
||||
if ((ret = mbedtls_hmac_drbg_update(ctx,
|
||||
additional, add_len)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* 7. Update reseed counter */
|
||||
ctx->reseed_counter++;
|
||||
|
||||
exit:
|
||||
/* 8. Done */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* HMAC_DRBG random function
|
||||
*/
|
||||
int mbedtls_hmac_drbg_random(void *p_rng, unsigned char *output, size_t out_len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = mbedtls_hmac_drbg_random_with_add(ctx, output, out_len, NULL, 0);
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
|
||||
return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function resets HMAC_DRBG context to the state immediately
|
||||
* after initial call of mbedtls_hmac_drbg_init().
|
||||
*/
|
||||
void mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* The mutex is initialized iff the md context is set up. */
|
||||
if (ctx->md_ctx.md_info != NULL) {
|
||||
mbedtls_mutex_free(&ctx->mutex);
|
||||
}
|
||||
#endif
|
||||
mbedtls_md_free(&ctx->md_ctx);
|
||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_hmac_drbg_context));
|
||||
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
int mbedtls_hmac_drbg_write_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
FILE *f;
|
||||
unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
|
||||
|
||||
if ((f = fopen(path, "wb")) == NULL) {
|
||||
return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
|
||||
}
|
||||
|
||||
/* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
|
||||
mbedtls_setbuf(f, NULL);
|
||||
|
||||
if ((ret = mbedtls_hmac_drbg_random(ctx, buf, sizeof(buf))) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (fwrite(buf, 1, sizeof(buf), f) != sizeof(buf)) {
|
||||
ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
fclose(f);
|
||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_hmac_drbg_update_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path)
|
||||
{
|
||||
int ret = 0;
|
||||
FILE *f = NULL;
|
||||
size_t n;
|
||||
unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
|
||||
unsigned char c;
|
||||
|
||||
if ((f = fopen(path, "rb")) == NULL) {
|
||||
return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
|
||||
}
|
||||
|
||||
/* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
|
||||
mbedtls_setbuf(f, NULL);
|
||||
|
||||
n = fread(buf, 1, sizeof(buf), f);
|
||||
if (fread(&c, 1, 1, f) != 0) {
|
||||
ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
|
||||
goto exit;
|
||||
}
|
||||
if (n == 0 || ferror(f)) {
|
||||
ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
|
||||
ret = mbedtls_hmac_drbg_update(ctx, buf, n);
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
||||
if (f != NULL) {
|
||||
fclose(f);
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
return mbedtls_hmac_drbg_write_seed_file(ctx, path);
|
||||
}
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
#if !defined(MBEDTLS_MD_CAN_SHA1)
|
||||
/* Dummy checkup routine */
|
||||
int mbedtls_hmac_drbg_self_test(int verbose)
|
||||
{
|
||||
(void) verbose;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
#define OUTPUT_LEN 80
|
||||
|
||||
/* From a NIST PR=true test vector */
|
||||
static const unsigned char entropy_pr[] = {
|
||||
0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
|
||||
0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
|
||||
0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
|
||||
0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
|
||||
0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4
|
||||
};
|
||||
static const unsigned char result_pr[OUTPUT_LEN] = {
|
||||
0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
|
||||
0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
|
||||
0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
|
||||
0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
|
||||
0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
|
||||
0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
|
||||
0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44
|
||||
};
|
||||
|
||||
/* From a NIST PR=false test vector */
|
||||
static const unsigned char entropy_nopr[] = {
|
||||
0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
|
||||
0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
|
||||
0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
|
||||
0xe9, 0x9d, 0xfe, 0xdf
|
||||
};
|
||||
static const unsigned char result_nopr[OUTPUT_LEN] = {
|
||||
0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
|
||||
0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
|
||||
0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
|
||||
0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
|
||||
0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
|
||||
0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
|
||||
0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7
|
||||
};
|
||||
|
||||
/* "Entropy" from buffer */
|
||||
static size_t test_offset;
|
||||
static int hmac_drbg_self_test_entropy(void *data,
|
||||
unsigned char *buf, size_t len)
|
||||
{
|
||||
const unsigned char *p = data;
|
||||
memcpy(buf, p + test_offset, len);
|
||||
test_offset += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CHK(c) if ((c) != 0) \
|
||||
{ \
|
||||
if (verbose != 0) \
|
||||
mbedtls_printf("failed\n"); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Checkup routine for HMAC_DRBG with SHA-1
|
||||
*/
|
||||
int mbedtls_hmac_drbg_self_test(int verbose)
|
||||
{
|
||||
mbedtls_hmac_drbg_context ctx;
|
||||
unsigned char buf[OUTPUT_LEN];
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
|
||||
|
||||
mbedtls_hmac_drbg_init(&ctx);
|
||||
|
||||
/*
|
||||
* PR = True
|
||||
*/
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf(" HMAC_DRBG (PR = True) : ");
|
||||
}
|
||||
|
||||
test_offset = 0;
|
||||
CHK(mbedtls_hmac_drbg_seed(&ctx, md_info,
|
||||
hmac_drbg_self_test_entropy, (void *) entropy_pr,
|
||||
NULL, 0));
|
||||
mbedtls_hmac_drbg_set_prediction_resistance(&ctx, MBEDTLS_HMAC_DRBG_PR_ON);
|
||||
CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
|
||||
CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
|
||||
CHK(memcmp(buf, result_pr, OUTPUT_LEN));
|
||||
mbedtls_hmac_drbg_free(&ctx);
|
||||
|
||||
mbedtls_hmac_drbg_free(&ctx);
|
||||
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("passed\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* PR = False
|
||||
*/
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf(" HMAC_DRBG (PR = False) : ");
|
||||
}
|
||||
|
||||
mbedtls_hmac_drbg_init(&ctx);
|
||||
|
||||
test_offset = 0;
|
||||
CHK(mbedtls_hmac_drbg_seed(&ctx, md_info,
|
||||
hmac_drbg_self_test_entropy, (void *) entropy_nopr,
|
||||
NULL, 0));
|
||||
CHK(mbedtls_hmac_drbg_reseed(&ctx, NULL, 0));
|
||||
CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
|
||||
CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
|
||||
CHK(memcmp(buf, result_nopr, OUTPUT_LEN));
|
||||
mbedtls_hmac_drbg_free(&ctx);
|
||||
|
||||
mbedtls_hmac_drbg_free(&ctx);
|
||||
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("passed\n");
|
||||
}
|
||||
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_MD_CAN_SHA1 */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#endif /* MBEDTLS_HMAC_DRBG_C */
|
||||
288
Libs/util/third_party/mbedtls/library/lmots.h
vendored
Normal file
288
Libs/util/third_party/mbedtls/library/lmots.h
vendored
Normal file
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
* \file lmots.h
|
||||
*
|
||||
* \brief This file provides an API for the LM-OTS post-quantum-safe one-time
|
||||
* public-key signature scheme as defined in RFC8554 and NIST.SP.200-208.
|
||||
* This implementation currently only supports a single parameter set
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8 in order to reduce complexity.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_LMOTS_H
|
||||
#define MBEDTLS_LMOTS_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "mbedtls/lms.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#define MBEDTLS_LMOTS_PUBLIC_KEY_LEN(type) (MBEDTLS_LMOTS_TYPE_LEN + \
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN + \
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN + \
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(type))
|
||||
|
||||
#define MBEDTLS_LMOTS_SIG_TYPE_OFFSET (0)
|
||||
#define MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET (MBEDTLS_LMOTS_SIG_TYPE_OFFSET + \
|
||||
MBEDTLS_LMOTS_TYPE_LEN)
|
||||
#define MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(type) (MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET + \
|
||||
MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(type))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
extern int (*mbedtls_lmots_sign_private_key_invalidated_hook)(unsigned char *);
|
||||
#endif /* defined(MBEDTLS_TEST_HOOKS) */
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/**
|
||||
* \brief This function converts a \ref psa_status_t to a
|
||||
* low-level LMS error code.
|
||||
*
|
||||
* \param status The psa_status_t to convert
|
||||
*
|
||||
* \return The corresponding LMS error code.
|
||||
*/
|
||||
int MBEDTLS_DEPRECATED mbedtls_lms_error_from_psa(psa_status_t status);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief This function initializes a public LMOTS context
|
||||
*
|
||||
* \param ctx The uninitialized LMOTS context that will then be
|
||||
* initialized.
|
||||
*/
|
||||
void mbedtls_lmots_public_init(mbedtls_lmots_public_t *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function uninitializes a public LMOTS context
|
||||
*
|
||||
* \param ctx The initialized LMOTS context that will then be
|
||||
* uninitialized.
|
||||
*/
|
||||
void mbedtls_lmots_public_free(mbedtls_lmots_public_t *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function imports an LMOTS public key into a
|
||||
* LMOTS context.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized.
|
||||
*
|
||||
* \note See IETF RFC8554 for details of the encoding of
|
||||
* this public key.
|
||||
*
|
||||
* \param ctx The initialized LMOTS context store the key in.
|
||||
* \param key The buffer from which the key will be read.
|
||||
* #MBEDTLS_LMOTS_PUBLIC_KEY_LEN bytes will be read
|
||||
* from this.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_import_public_key(mbedtls_lmots_public_t *ctx,
|
||||
const unsigned char *key, size_t key_size);
|
||||
|
||||
/**
|
||||
* \brief This function exports an LMOTS public key from a
|
||||
* LMOTS context that already contains a public key.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized and the context must contain
|
||||
* a public key.
|
||||
*
|
||||
* \note See IETF RFC8554 for details of the encoding of
|
||||
* this public key.
|
||||
*
|
||||
* \param ctx The initialized LMOTS context that contains the
|
||||
* public key.
|
||||
* \param key The buffer into which the key will be output. Must
|
||||
* be at least #MBEDTLS_LMOTS_PUBLIC_KEY_LEN in size.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_export_public_key(const mbedtls_lmots_public_t *ctx,
|
||||
unsigned char *key, size_t key_size,
|
||||
size_t *key_len);
|
||||
|
||||
/**
|
||||
* \brief This function creates a candidate public key from
|
||||
* an LMOTS signature. This can then be compared to
|
||||
* the real public key to determine the validity of
|
||||
* the signature.
|
||||
*
|
||||
* \note This function is exposed publicly to be used in LMS
|
||||
* signature verification, it is expected that
|
||||
* mbedtls_lmots_verify will be used for LMOTS
|
||||
* signature verification.
|
||||
*
|
||||
* \param params The LMOTS parameter set, q and I values as an
|
||||
* mbedtls_lmots_parameters_t struct.
|
||||
* \param msg The buffer from which the message will be read.
|
||||
* \param msg_size The size of the message that will be read.
|
||||
* \param sig The buffer from which the signature will be read.
|
||||
* #MBEDTLS_LMOTS_SIG_LEN bytes will be read from
|
||||
* this.
|
||||
* \param out The buffer where the candidate public key will be
|
||||
* stored. Must be at least #MBEDTLS_LMOTS_N_HASH_LEN
|
||||
* bytes in size.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_calculate_public_key_candidate(const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *msg,
|
||||
size_t msg_size,
|
||||
const unsigned char *sig,
|
||||
size_t sig_size,
|
||||
unsigned char *out,
|
||||
size_t out_size,
|
||||
size_t *out_len);
|
||||
|
||||
/**
|
||||
* \brief This function verifies a LMOTS signature, using a
|
||||
* LMOTS context that contains a public key.
|
||||
*
|
||||
* \warning This function is **not intended for use in
|
||||
* production**, due to as-yet unsolved problems with
|
||||
* handling stateful keys. The API for this function
|
||||
* may change considerably in future versions.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized and must contain a public key
|
||||
* (either by import or calculation from a private
|
||||
* key).
|
||||
*
|
||||
* \param ctx The initialized LMOTS context from which the public
|
||||
* key will be read.
|
||||
* \param msg The buffer from which the message will be read.
|
||||
* \param msg_size The size of the message that will be read.
|
||||
* \param sig The buf from which the signature will be read.
|
||||
* #MBEDTLS_LMOTS_SIG_LEN bytes will be read from
|
||||
* this.
|
||||
*
|
||||
* \return \c 0 on successful verification.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_verify(const mbedtls_lmots_public_t *ctx,
|
||||
const unsigned char *msg,
|
||||
size_t msg_size, const unsigned char *sig,
|
||||
size_t sig_size);
|
||||
|
||||
#if defined(MBEDTLS_LMS_PRIVATE)
|
||||
|
||||
/**
|
||||
* \brief This function initializes a private LMOTS context
|
||||
*
|
||||
* \param ctx The uninitialized LMOTS context that will then be
|
||||
* initialized.
|
||||
*/
|
||||
void mbedtls_lmots_private_init(mbedtls_lmots_private_t *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function uninitializes a private LMOTS context
|
||||
*
|
||||
* \param ctx The initialized LMOTS context that will then be
|
||||
* uninitialized.
|
||||
*/
|
||||
void mbedtls_lmots_private_free(mbedtls_lmots_private_t *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function calculates an LMOTS private key, and
|
||||
* stores in into an LMOTS context.
|
||||
*
|
||||
* \warning This function is **not intended for use in
|
||||
* production**, due to as-yet unsolved problems with
|
||||
* handling stateful keys. The API for this function
|
||||
* may change considerably in future versions.
|
||||
*
|
||||
* \note The seed must have at least 256 bits of entropy.
|
||||
*
|
||||
* \param ctx The initialized LMOTS context to generate the key
|
||||
* into.
|
||||
* \param I_key_identifier The key identifier of the key, as a 16-byte string.
|
||||
* \param q_leaf_identifier The leaf identifier of key. If this LMOTS key is
|
||||
* not being used as part of an LMS key, this should
|
||||
* be set to 0.
|
||||
* \param seed The seed used to deterministically generate the
|
||||
* key.
|
||||
* \param seed_size The length of the seed.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_generate_private_key(mbedtls_lmots_private_t *ctx,
|
||||
mbedtls_lmots_algorithm_type_t type,
|
||||
const unsigned char I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN],
|
||||
uint32_t q_leaf_identifier,
|
||||
const unsigned char *seed,
|
||||
size_t seed_size);
|
||||
|
||||
/**
|
||||
* \brief This function generates an LMOTS public key from a
|
||||
* LMOTS context that already contains a private key.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized and the context must contain
|
||||
* a private key.
|
||||
*
|
||||
* \param ctx The initialized LMOTS context to generate the key
|
||||
* from and store it into.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_calculate_public_key(mbedtls_lmots_public_t *ctx,
|
||||
const mbedtls_lmots_private_t *priv_ctx);
|
||||
|
||||
/**
|
||||
* \brief This function creates a LMOTS signature, using a
|
||||
* LMOTS context that contains a private key.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized and must contain a private
|
||||
* key.
|
||||
*
|
||||
* \note LMOTS private keys can only be used once, otherwise
|
||||
* attackers may be able to create forged signatures.
|
||||
* If the signing operation is successful, the private
|
||||
* key in the context will be erased, and no further
|
||||
* signing will be possible until another private key
|
||||
* is loaded
|
||||
*
|
||||
* \param ctx The initialized LMOTS context from which the
|
||||
* private key will be read.
|
||||
* \param f_rng The RNG function to be used for signature
|
||||
* generation.
|
||||
* \param p_rng The RNG context to be passed to f_rng
|
||||
* \param msg The buffer from which the message will be read.
|
||||
* \param msg_size The size of the message that will be read.
|
||||
* \param sig The buf into which the signature will be stored.
|
||||
* Must be at least #MBEDTLS_LMOTS_SIG_LEN in size.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_sign(mbedtls_lmots_private_t *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng, const unsigned char *msg, size_t msg_size,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len);
|
||||
|
||||
#endif /* defined(MBEDTLS_LMS_PRIVATE) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_LMOTS_H */
|
||||
1106
Libs/util/third_party/mbedtls/library/md.c
vendored
Normal file
1106
Libs/util/third_party/mbedtls/library/md.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
26
Libs/util/third_party/mbedtls/library/md_psa.h
vendored
Normal file
26
Libs/util/third_party/mbedtls/library/md_psa.h
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Translation between MD and PSA identifiers (algorithms, errors).
|
||||
*
|
||||
* Note: this internal module will go away when everything becomes based on
|
||||
* PSA Crypto; it is a helper for the transition period.
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_MD_PSA_H
|
||||
#define MBEDTLS_MD_PSA_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "mbedtls/md.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
/** Convert PSA status to MD error code.
|
||||
*
|
||||
* \param status PSA status.
|
||||
*
|
||||
* \return The corresponding MD error code,
|
||||
*/
|
||||
int mbedtls_md_error_from_psa(psa_status_t status);
|
||||
|
||||
#endif /* MBEDTLS_MD_PSA_H */
|
||||
46
Libs/util/third_party/mbedtls/library/md_wrap.h
vendored
Normal file
46
Libs/util/third_party/mbedtls/library/md_wrap.h
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* \file md_wrap.h
|
||||
*
|
||||
* \brief Message digest wrappers.
|
||||
*
|
||||
* \warning This in an internal header. Do not include directly.
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_MD_WRAP_H
|
||||
#define MBEDTLS_MD_WRAP_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Message digest information.
|
||||
* Allows message digest functions to be called in a generic way.
|
||||
*/
|
||||
struct mbedtls_md_info_t {
|
||||
/** Digest identifier */
|
||||
mbedtls_md_type_t type;
|
||||
|
||||
/** Output length of the digest function in bytes */
|
||||
unsigned char size;
|
||||
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
/** Block length of the digest function in bytes */
|
||||
unsigned char block_size;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_MD_WRAP_H */
|
||||
181
Libs/util/third_party/mbedtls/library/mps_common.h
vendored
Normal file
181
Libs/util/third_party/mbedtls/library/mps_common.h
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file mps_common.h
|
||||
*
|
||||
* \brief Common functions and macros used by MPS
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_MPS_COMMON_H
|
||||
#define MBEDTLS_MPS_COMMON_H
|
||||
|
||||
#include "mps_error.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* \name SECTION: MPS Configuration
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
/*! This flag controls whether the MPS-internal components
|
||||
* (reader, writer, Layer 1-3) perform validation of the
|
||||
* expected abstract state at the entry of API calls.
|
||||
*
|
||||
* Context: All MPS API functions impose assumptions/preconditions on the
|
||||
* context on which they operate. For example, every structure has a notion of
|
||||
* state integrity which is established by `xxx_init()` and preserved by any
|
||||
* calls to the MPS API which satisfy their preconditions and either succeed,
|
||||
* or fail with an error code which is explicitly documented to not corrupt
|
||||
* structure integrity (such as WANT_READ and WANT_WRITE);
|
||||
* apart from `xxx_init()` any function assumes state integrity as a
|
||||
* precondition (but usually more). If any of the preconditions is violated,
|
||||
* the function's behavior is entirely undefined.
|
||||
* In addition to state integrity, all MPS structures have a more refined
|
||||
* notion of abstract state that the API operates on. For example, all layers
|
||||
* have a notion of 'abstract read state' which indicates if incoming data has
|
||||
* been passed to the user, e.g. through mps_l2_read_start() for Layer 2
|
||||
* or mps_l3_read() in Layer 3. After such a call, it doesn't make sense to
|
||||
* call these reading functions again until the incoming data has been
|
||||
* explicitly 'consumed', e.g. through mps_l2_read_consume() for Layer 2 or
|
||||
* mps_l3_read_consume() on Layer 3. However, even if it doesn't make sense,
|
||||
* it's a design choice whether the API should fail gracefully on such
|
||||
* non-sensical calls or not, and that's what this option is about:
|
||||
*
|
||||
* This option determines whether the expected abstract state
|
||||
* is part of the API preconditions or not: If the option is set,
|
||||
* then the abstract state is not part of the precondition and is
|
||||
* thus required to be validated by the implementation. If an unexpected
|
||||
* abstract state is encountered, the implementation must fail gracefully
|
||||
* with error #MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED.
|
||||
* Conversely, if this option is not set, then the expected abstract state
|
||||
* is included in the preconditions of the respective API calls, and
|
||||
* an implementation's behaviour is undefined if the abstract state is
|
||||
* not as expected.
|
||||
*
|
||||
* For example: Enabling this makes mps_l2_read_done() fail if
|
||||
* no incoming record is currently open; disabling this would
|
||||
* lead to undefined behavior in this case.
|
||||
*
|
||||
* Comment this to remove state validation.
|
||||
*/
|
||||
#define MBEDTLS_MPS_STATE_VALIDATION
|
||||
|
||||
/*! This flag enables/disables assertions on the internal state of MPS.
|
||||
*
|
||||
* Assertions are sanity checks that should never trigger when MPS
|
||||
* is used within the bounds of its API and preconditions.
|
||||
*
|
||||
* Enabling this increases security by limiting the scope of
|
||||
* potential bugs, but comes at the cost of increased code size.
|
||||
*
|
||||
* Note: So far, there is no guiding principle as to what
|
||||
* expected conditions merit an assertion, and which don't.
|
||||
*
|
||||
* Comment this to disable assertions.
|
||||
*/
|
||||
#define MBEDTLS_MPS_ENABLE_ASSERTIONS
|
||||
|
||||
/*! This flag controls whether tracing for MPS should be enabled. */
|
||||
//#define MBEDTLS_MPS_ENABLE_TRACE
|
||||
|
||||
#if defined(MBEDTLS_MPS_STATE_VALIDATION)
|
||||
|
||||
#define MBEDTLS_MPS_STATE_VALIDATE_RAW(cond, string) \
|
||||
do \
|
||||
{ \
|
||||
if (!(cond)) \
|
||||
{ \
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_ERROR, string); \
|
||||
MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else /* MBEDTLS_MPS_STATE_VALIDATION */
|
||||
|
||||
#define MBEDTLS_MPS_STATE_VALIDATE_RAW(cond, string) \
|
||||
do \
|
||||
{ \
|
||||
(cond); \
|
||||
} while (0)
|
||||
|
||||
#endif /* MBEDTLS_MPS_STATE_VALIDATION */
|
||||
|
||||
#if defined(MBEDTLS_MPS_ENABLE_ASSERTIONS)
|
||||
|
||||
#define MBEDTLS_MPS_ASSERT_RAW(cond, string) \
|
||||
do \
|
||||
{ \
|
||||
if (!(cond)) \
|
||||
{ \
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_ERROR, string); \
|
||||
MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_INTERNAL_ERROR); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else /* MBEDTLS_MPS_ENABLE_ASSERTIONS */
|
||||
|
||||
#define MBEDTLS_MPS_ASSERT_RAW(cond, string) do {} while (0)
|
||||
|
||||
#endif /* MBEDTLS_MPS_ENABLE_ASSERTIONS */
|
||||
|
||||
|
||||
/* \} name SECTION: MPS Configuration */
|
||||
|
||||
/**
|
||||
* \name SECTION: Common types
|
||||
*
|
||||
* Various common types used throughout MPS.
|
||||
* \{
|
||||
*/
|
||||
|
||||
/** \brief The type of buffer sizes and offsets used in MPS structures.
|
||||
*
|
||||
* This is an unsigned integer type that should be large enough to
|
||||
* hold the length of any buffer or message processed by MPS.
|
||||
*
|
||||
* The reason to pick a value as small as possible here is
|
||||
* to reduce the size of MPS structures.
|
||||
*
|
||||
* \warning Care has to be taken when using a narrower type
|
||||
* than ::mbedtls_mps_size_t here because of
|
||||
* potential truncation during conversion.
|
||||
*
|
||||
* \warning Handshake messages in TLS may be up to 2^24 ~ 16Mb in size.
|
||||
* If mbedtls_mps_[opt_]stored_size_t is smaller than that, the
|
||||
* maximum handshake message is restricted accordingly.
|
||||
*
|
||||
* For now, we use the default type of size_t throughout, and the use of
|
||||
* smaller types or different types for ::mbedtls_mps_size_t and
|
||||
* ::mbedtls_mps_stored_size_t is not yet supported.
|
||||
*
|
||||
*/
|
||||
typedef size_t mbedtls_mps_stored_size_t;
|
||||
#define MBEDTLS_MPS_STORED_SIZE_MAX (SIZE_MAX)
|
||||
|
||||
/** \brief The type of buffer sizes and offsets used in the MPS API
|
||||
* and implementation.
|
||||
*
|
||||
* This must be at least as wide as ::mbedtls_stored_size_t but
|
||||
* may be chosen to be strictly larger if more suitable for the
|
||||
* target architecture.
|
||||
*
|
||||
* For example, in a test build for ARM Thumb, using uint_fast16_t
|
||||
* instead of uint16_t reduced the code size from 1060 Byte to 962 Byte,
|
||||
* so almost 10%.
|
||||
*/
|
||||
typedef size_t mbedtls_mps_size_t;
|
||||
#define MBEDTLS_MPS_SIZE_MAX (SIZE_MAX)
|
||||
|
||||
#if MBEDTLS_MPS_STORED_SIZE_MAX > MBEDTLS_MPS_SIZE_MAX
|
||||
#error "Misconfiguration of mbedtls_mps_size_t and mbedtls_mps_stored_size_t."
|
||||
#endif
|
||||
|
||||
/* \} SECTION: Common types */
|
||||
|
||||
|
||||
#endif /* MBEDTLS_MPS_COMMON_H */
|
||||
89
Libs/util/third_party/mbedtls/library/mps_error.h
vendored
Normal file
89
Libs/util/third_party/mbedtls/library/mps_error.h
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file mps_error.h
|
||||
*
|
||||
* \brief Error codes used by MPS
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_MPS_ERROR_H
|
||||
#define MBEDTLS_MPS_ERROR_H
|
||||
|
||||
|
||||
/* TODO: The error code allocation needs to be revisited:
|
||||
*
|
||||
* - Should we make (some of) the MPS Reader error codes public?
|
||||
* If so, we need to adjust MBEDTLS_MPS_READER_MAKE_ERROR() to hit
|
||||
* a gap in the Mbed TLS public error space.
|
||||
* If not, we have to make sure we don't forward those errors
|
||||
* at the level of the public API -- no risk at the moment as
|
||||
* long as MPS is an experimental component not accessible from
|
||||
* public API.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \name SECTION: MPS general error codes
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_MPS_ERR_BASE
|
||||
#define MBEDTLS_MPS_ERR_BASE (0)
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_MPS_MAKE_ERROR(code) \
|
||||
(-(MBEDTLS_MPS_ERR_BASE | (code)))
|
||||
|
||||
#define MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED MBEDTLS_MPS_MAKE_ERROR(0x1)
|
||||
#define MBEDTLS_ERR_MPS_INTERNAL_ERROR MBEDTLS_MPS_MAKE_ERROR(0x2)
|
||||
|
||||
/* \} name SECTION: MPS general error codes */
|
||||
|
||||
/**
|
||||
* \name SECTION: MPS Reader error codes
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_MPS_READER_ERR_BASE
|
||||
#define MBEDTLS_MPS_READER_ERR_BASE (1 << 8)
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_MPS_READER_MAKE_ERROR(code) \
|
||||
(-(MBEDTLS_MPS_READER_ERR_BASE | (code)))
|
||||
|
||||
/*! An attempt to reclaim the data buffer from a reader failed because
|
||||
* the user hasn't yet read and committed all of it. */
|
||||
#define MBEDTLS_ERR_MPS_READER_DATA_LEFT MBEDTLS_MPS_READER_MAKE_ERROR(0x1)
|
||||
|
||||
/*! An invalid argument was passed to the reader. */
|
||||
#define MBEDTLS_ERR_MPS_READER_INVALID_ARG MBEDTLS_MPS_READER_MAKE_ERROR(0x2)
|
||||
|
||||
/*! An attempt to move a reader to consuming mode through mbedtls_mps_reader_feed()
|
||||
* after pausing failed because the provided data is not sufficient to serve the
|
||||
* read requests that led to the pausing. */
|
||||
#define MBEDTLS_ERR_MPS_READER_NEED_MORE MBEDTLS_MPS_READER_MAKE_ERROR(0x3)
|
||||
|
||||
/*! A get request failed because not enough data is available in the reader. */
|
||||
#define MBEDTLS_ERR_MPS_READER_OUT_OF_DATA MBEDTLS_MPS_READER_MAKE_ERROR(0x4)
|
||||
|
||||
/*!< A get request after pausing and reactivating the reader failed because
|
||||
* the request is not in line with the request made prior to pausing. The user
|
||||
* must not change it's 'strategy' after pausing and reactivating a reader. */
|
||||
#define MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS MBEDTLS_MPS_READER_MAKE_ERROR(0x5)
|
||||
|
||||
/*! An attempt to reclaim the data buffer from a reader failed because the reader
|
||||
* has no accumulator it can use to backup the data that hasn't been processed. */
|
||||
#define MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR MBEDTLS_MPS_READER_MAKE_ERROR(0x6)
|
||||
|
||||
/*! An attempt to reclaim the data buffer from a reader failed because the
|
||||
* accumulator passed to the reader is not large enough to hold both the
|
||||
* data that hasn't been processed and the excess of the last read-request. */
|
||||
#define MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL MBEDTLS_MPS_READER_MAKE_ERROR(0x7)
|
||||
|
||||
/* \} name SECTION: MPS Reader error codes */
|
||||
|
||||
#endif /* MBEDTLS_MPS_ERROR_H */
|
||||
366
Libs/util/third_party/mbedtls/library/mps_reader.h
vendored
Normal file
366
Libs/util/third_party/mbedtls/library/mps_reader.h
vendored
Normal file
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file mps_reader.h
|
||||
*
|
||||
* \brief This file defines reader objects, which together with their
|
||||
* sibling writer objects form the basis for the communication
|
||||
* between the various layers of the Mbed TLS messaging stack,
|
||||
* as well as the communication between the messaging stack and
|
||||
* the (D)TLS handshake protocol implementation.
|
||||
*
|
||||
* Readers provide a means of transferring incoming data from
|
||||
* a 'producer' providing it in chunks of arbitrary size, to
|
||||
* a 'consumer' which fetches and processes it in chunks of
|
||||
* again arbitrary, and potentially different, size.
|
||||
*
|
||||
* Readers can thus be seen as datagram-to-stream converters,
|
||||
* and they abstract away the following two tasks from the user:
|
||||
* 1. The pointer arithmetic of stepping through a producer-
|
||||
* provided chunk in smaller chunks.
|
||||
* 2. The merging of incoming data chunks in case the
|
||||
* consumer requests data in larger chunks than what the
|
||||
* producer provides.
|
||||
*
|
||||
* The basic abstract flow of operation is the following:
|
||||
* - Initially, the reader is in 'producing mode'.
|
||||
* - The producer hands an incoming data buffer to the reader,
|
||||
* moving it from 'producing' to 'consuming' mode.
|
||||
* - The consumer subsequently fetches and processes the buffer
|
||||
* content. Once that's done -- or partially done and a consumer's
|
||||
* request can't be fulfilled -- the producer revokes the reader's
|
||||
* access to the incoming data buffer, putting the reader back to
|
||||
* producing mode.
|
||||
* - The producer subsequently gathers more incoming data and hands
|
||||
* it to the reader until it switches back to consuming mode
|
||||
* if enough data is available for the last consumer request to
|
||||
* be satisfiable.
|
||||
* - Repeat the above.
|
||||
*
|
||||
* The abstract states of the reader from the producer's and
|
||||
* consumer's perspective are as follows:
|
||||
*
|
||||
* - From the perspective of the consumer, the state of the
|
||||
* reader consists of the following:
|
||||
* - A byte stream representing (concatenation of) the data
|
||||
* received through calls to mbedtls_mps_reader_get(),
|
||||
* - A marker within that byte stream indicating which data
|
||||
* can be considered processed, and hence need not be retained,
|
||||
* when the reader is passed back to the producer via
|
||||
* mbedtls_mps_reader_reclaim().
|
||||
* The marker is set via mbedtls_mps_reader_commit()
|
||||
* which places it at the end of the current byte stream.
|
||||
* The consumer need not be aware of the distinction between consumer
|
||||
* and producer mode, because it only interfaces with the reader
|
||||
* when the latter is in consuming mode.
|
||||
*
|
||||
* - From the perspective of the producer, the reader's state is one of:
|
||||
* - Attached: The reader is in consuming mode.
|
||||
* - Unset: No incoming data buffer is currently managed by the reader,
|
||||
* and all previously handed incoming data buffers have been
|
||||
* fully processed. More data needs to be fed into the reader
|
||||
* via mbedtls_mps_reader_feed().
|
||||
*
|
||||
* - Accumulating: No incoming data buffer is currently managed by the
|
||||
* reader, but some data from the previous incoming data
|
||||
* buffer hasn't been processed yet and is internally
|
||||
* held back.
|
||||
* The Attached state belongs to consuming mode, while the Unset and
|
||||
* Accumulating states belong to producing mode.
|
||||
*
|
||||
* Transitioning from the Unset or Accumulating state to Attached is
|
||||
* done via successful calls to mbedtls_mps_reader_feed(), while
|
||||
* transitioning from Attached to either Unset or Accumulating (depending
|
||||
* on what has been processed) is done via mbedtls_mps_reader_reclaim().
|
||||
*
|
||||
* The following diagram depicts the producer-state progression:
|
||||
*
|
||||
* +------------------+ reclaim
|
||||
* | Unset +<-------------------------------------+ get
|
||||
* +--------|---------+ | +------+
|
||||
* | | | |
|
||||
* | | | |
|
||||
* | feed +---------+---+--+ |
|
||||
* +--------------------------------------> <---+
|
||||
* | Attached |
|
||||
* +--------------------------------------> <---+
|
||||
* | feed, enough data available +---------+---+--+ |
|
||||
* | to serve previous consumer request | | |
|
||||
* | | | |
|
||||
* +--------+---------+ | +------+
|
||||
* +----> Accumulating |<-------------------------------------+ commit
|
||||
* | +---+--------------+ reclaim, previous read request
|
||||
* | | couldn't be fulfilled
|
||||
* | |
|
||||
* +--------+
|
||||
* feed, need more data to serve
|
||||
* previous consumer request
|
||||
* |
|
||||
* |
|
||||
* producing mode | consuming mode
|
||||
* |
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_READER_H
|
||||
#define MBEDTLS_READER_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mps_common.h"
|
||||
#include "mps_error.h"
|
||||
|
||||
struct mbedtls_mps_reader;
|
||||
typedef struct mbedtls_mps_reader mbedtls_mps_reader;
|
||||
|
||||
/*
|
||||
* Structure definitions
|
||||
*/
|
||||
|
||||
struct mbedtls_mps_reader {
|
||||
unsigned char *frag; /*!< The fragment of incoming data managed by
|
||||
* the reader; it is provided to the reader
|
||||
* through mbedtls_mps_reader_feed(). The reader
|
||||
* does not own the fragment and does not
|
||||
* perform any allocation operations on it,
|
||||
* but does have read and write access to it.
|
||||
*
|
||||
* The reader is in consuming mode if
|
||||
* and only if \c frag is not \c NULL. */
|
||||
mbedtls_mps_stored_size_t frag_len;
|
||||
/*!< The length of the current fragment.
|
||||
* Must be 0 if \c frag == \c NULL. */
|
||||
mbedtls_mps_stored_size_t commit;
|
||||
/*!< The offset of the last commit, relative
|
||||
* to the first byte in the fragment, if
|
||||
* no accumulator is present. If an accumulator
|
||||
* is present, it is viewed as a prefix to the
|
||||
* current fragment, and this variable contains
|
||||
* an offset from the beginning of the accumulator.
|
||||
*
|
||||
* This is only used when the reader is in
|
||||
* consuming mode, i.e. \c frag != \c NULL;
|
||||
* otherwise, its value is \c 0. */
|
||||
mbedtls_mps_stored_size_t end;
|
||||
/*!< The offset of the end of the last chunk
|
||||
* passed to the user through a call to
|
||||
* mbedtls_mps_reader_get(), relative to the first
|
||||
* byte in the fragment, if no accumulator is
|
||||
* present. If an accumulator is present, it is
|
||||
* viewed as a prefix to the current fragment, and
|
||||
* this variable contains an offset from the
|
||||
* beginning of the accumulator.
|
||||
*
|
||||
* This is only used when the reader is in
|
||||
* consuming mode, i.e. \c frag != \c NULL;
|
||||
* otherwise, its value is \c 0. */
|
||||
mbedtls_mps_stored_size_t pending;
|
||||
/*!< The amount of incoming data missing on the
|
||||
* last call to mbedtls_mps_reader_get().
|
||||
* In particular, it is \c 0 if the last call
|
||||
* was successful.
|
||||
* If a reader is reclaimed after an
|
||||
* unsuccessful call to mbedtls_mps_reader_get(),
|
||||
* this variable is used to have the reader
|
||||
* remember how much data should be accumulated
|
||||
* so that the call to mbedtls_mps_reader_get()
|
||||
* succeeds next time.
|
||||
* This is only used when the reader is in
|
||||
* consuming mode, i.e. \c frag != \c NULL;
|
||||
* otherwise, its value is \c 0. */
|
||||
|
||||
/* The accumulator is only needed if we need to be able to pause
|
||||
* the reader. A few bytes could be saved by moving this to a
|
||||
* separate struct and using a pointer here. */
|
||||
|
||||
unsigned char *acc; /*!< The accumulator is used to gather incoming
|
||||
* data if a read-request via mbedtls_mps_reader_get()
|
||||
* cannot be served from the current fragment. */
|
||||
mbedtls_mps_stored_size_t acc_len;
|
||||
/*!< The total size of the accumulator. */
|
||||
mbedtls_mps_stored_size_t acc_available;
|
||||
/*!< The number of bytes currently gathered in
|
||||
* the accumulator. This is both used in
|
||||
* producing and in consuming mode:
|
||||
* While producing, it is increased until
|
||||
* it reaches the value of \c acc_remaining below.
|
||||
* While consuming, it is used to judge if a
|
||||
* get request can be served from the
|
||||
* accumulator or not.
|
||||
* Must not be larger than \c acc_len. */
|
||||
union {
|
||||
mbedtls_mps_stored_size_t acc_remaining;
|
||||
/*!< This indicates the amount of data still
|
||||
* to be gathered in the accumulator. It is
|
||||
* only used in producing mode.
|
||||
* Must be at most acc_len - acc_available. */
|
||||
mbedtls_mps_stored_size_t frag_offset;
|
||||
/*!< If an accumulator is present and in use, this
|
||||
* field indicates the offset of the current
|
||||
* fragment from the beginning of the
|
||||
* accumulator. If no accumulator is present
|
||||
* or the accumulator is not in use, this is \c 0.
|
||||
* It is only used in consuming mode.
|
||||
* Must not be larger than \c acc_available. */
|
||||
} acc_share;
|
||||
};
|
||||
|
||||
/*
|
||||
* API organization:
|
||||
* A reader object is usually prepared and maintained
|
||||
* by some lower layer and passed for usage to an upper
|
||||
* layer, and the API naturally splits according to which
|
||||
* layer is supposed to use the respective functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Maintenance API (Lower layer)
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Initialize a reader object
|
||||
*
|
||||
* \param reader The reader to be initialized.
|
||||
* \param acc The buffer to be used as a temporary accumulator
|
||||
* in case get requests through mbedtls_mps_reader_get()
|
||||
* exceed the buffer provided by mbedtls_mps_reader_feed().
|
||||
* This buffer is owned by the caller and exclusive use
|
||||
* for reading and writing is given to the reader for the
|
||||
* duration of the reader's lifetime. It is thus the caller's
|
||||
* responsibility to maintain (and not touch) the buffer for
|
||||
* the lifetime of the reader, and to properly zeroize and
|
||||
* free the memory after the reader has been destroyed.
|
||||
* \param acc_len The size in Bytes of \p acc.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_mps_reader_init(mbedtls_mps_reader *reader,
|
||||
unsigned char *acc,
|
||||
mbedtls_mps_size_t acc_len);
|
||||
|
||||
/**
|
||||
* \brief Free a reader object
|
||||
*
|
||||
* \param reader The reader to be freed.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_mps_reader_free(mbedtls_mps_reader *reader);
|
||||
|
||||
/**
|
||||
* \brief Pass chunk of data for the reader to manage.
|
||||
*
|
||||
* \param reader The reader context to use. The reader must be
|
||||
* in producing mode.
|
||||
* \param buf The buffer to be managed by the reader.
|
||||
* \param buflen The size in Bytes of \p buffer.
|
||||
*
|
||||
* \return \c 0 on success. In this case, the reader will be
|
||||
* moved to consuming mode and obtains read access
|
||||
* of \p buf until mbedtls_mps_reader_reclaim()
|
||||
* is called. It is the responsibility of the caller
|
||||
* to ensure that the \p buf persists and is not changed
|
||||
* between successful calls to mbedtls_mps_reader_feed()
|
||||
* and mbedtls_mps_reader_reclaim().
|
||||
* \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is
|
||||
* required to fulfill a previous request to mbedtls_mps_reader_get().
|
||||
* In this case, the reader remains in producing mode and
|
||||
* takes no ownership of the provided buffer (an internal copy
|
||||
* is made instead).
|
||||
* \return Another negative \c MBEDTLS_ERR_READER_XXX error code on
|
||||
* different kinds of failures.
|
||||
*/
|
||||
int mbedtls_mps_reader_feed(mbedtls_mps_reader *reader,
|
||||
unsigned char *buf,
|
||||
mbedtls_mps_size_t buflen);
|
||||
|
||||
/**
|
||||
* \brief Reclaim reader's access to the current input buffer.
|
||||
*
|
||||
* \param reader The reader context to use. The reader must be
|
||||
* in consuming mode.
|
||||
* \param paused If not \c NULL, the integer at address \p paused will be
|
||||
* modified to indicate whether the reader has been paused
|
||||
* (value \c 1) or not (value \c 0). Pausing happens if there
|
||||
* is uncommitted data and a previous request to
|
||||
* mbedtls_mps_reader_get() has exceeded the bounds of the
|
||||
* input buffer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_mps_reader_reclaim(mbedtls_mps_reader *reader,
|
||||
int *paused);
|
||||
|
||||
/*
|
||||
* Usage API (Upper layer)
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Request data from the reader.
|
||||
*
|
||||
* \param reader The reader context to use. The reader must
|
||||
* be in consuming mode.
|
||||
* \param desired The desired amount of data to be read, in Bytes.
|
||||
* \param buffer The address to store the buffer pointer in.
|
||||
* This must not be \c NULL.
|
||||
* \param buflen The address to store the actual buffer
|
||||
* length in, or \c NULL.
|
||||
*
|
||||
* \return \c 0 on success. In this case, \c *buf holds the
|
||||
* address of a buffer of size \c *buflen
|
||||
* (if \c buflen != \c NULL) or \c desired
|
||||
* (if \c buflen == \c NULL). The user has read access
|
||||
* to the buffer and guarantee of stability of the data
|
||||
* until the next call to mbedtls_mps_reader_reclaim().
|
||||
* \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough
|
||||
* data available to serve the get request. In this case, the
|
||||
* reader remains intact and in consuming mode, and the consumer
|
||||
* should retry the call after a successful cycle of
|
||||
* mbedtls_mps_reader_reclaim() and mbedtls_mps_reader_feed().
|
||||
* If, after such a cycle, the consumer requests a different
|
||||
* amount of data, the result is implementation-defined;
|
||||
* progress is guaranteed only if the same amount of data
|
||||
* is requested after a mbedtls_mps_reader_reclaim() and
|
||||
* mbedtls_mps_reader_feed() cycle.
|
||||
* \return Another negative \c MBEDTLS_ERR_READER_XXX error
|
||||
* code for different kinds of failure.
|
||||
*
|
||||
* \note Passing \c NULL as \p buflen is a convenient way to
|
||||
* indicate that fragmentation is not tolerated.
|
||||
* It's functionally equivalent to passing a valid
|
||||
* address as buflen and checking \c *buflen == \c desired
|
||||
* afterwards.
|
||||
*/
|
||||
int mbedtls_mps_reader_get(mbedtls_mps_reader *reader,
|
||||
mbedtls_mps_size_t desired,
|
||||
unsigned char **buffer,
|
||||
mbedtls_mps_size_t *buflen);
|
||||
|
||||
/**
|
||||
* \brief Mark data obtained from mbedtls_mps_reader_get() as processed.
|
||||
*
|
||||
* This call indicates that all data received from prior calls to
|
||||
* mbedtls_mps_reader_get() has been or will have been
|
||||
* processed when mbedtls_mps_reader_reclaim() is called,
|
||||
* and thus need not be backed up.
|
||||
*
|
||||
* This function has no user observable effect until
|
||||
* mbedtls_mps_reader_reclaim() is called. In particular,
|
||||
* buffers received from mbedtls_mps_reader_get() remain
|
||||
* valid until mbedtls_mps_reader_reclaim() is called.
|
||||
*
|
||||
* \param reader The reader context to use.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
|
||||
*
|
||||
*/
|
||||
int mbedtls_mps_reader_commit(mbedtls_mps_reader *reader);
|
||||
|
||||
#endif /* MBEDTLS_READER_H */
|
||||
154
Libs/util/third_party/mbedtls/library/mps_trace.h
vendored
Normal file
154
Libs/util/third_party/mbedtls/library/mps_trace.h
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file mps_trace.h
|
||||
*
|
||||
* \brief Tracing module for MPS
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H
|
||||
#define MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H
|
||||
|
||||
#include "common.h"
|
||||
#include "mps_common.h"
|
||||
#include "mps_trace.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if defined(MBEDTLS_MPS_ENABLE_TRACE)
|
||||
|
||||
/*
|
||||
* Adapt this to enable/disable tracing output
|
||||
* from the various layers of the MPS.
|
||||
*/
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_1
|
||||
#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_2
|
||||
#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_3
|
||||
#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_4
|
||||
#define MBEDTLS_MPS_TRACE_ENABLE_READER
|
||||
#define MBEDTLS_MPS_TRACE_ENABLE_WRITER
|
||||
|
||||
/*
|
||||
* To use the existing trace module, only change
|
||||
* MBEDTLS_MPS_TRACE_ENABLE_XXX above, but don't modify the
|
||||
* rest of this file.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
MBEDTLS_MPS_TRACE_TYPE_CALL,
|
||||
MBEDTLS_MPS_TRACE_TYPE_ERROR,
|
||||
MBEDTLS_MPS_TRACE_TYPE_RETURN
|
||||
} mbedtls_mps_trace_type;
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_BIT_LAYER_1 1
|
||||
#define MBEDTLS_MPS_TRACE_BIT_LAYER_2 2
|
||||
#define MBEDTLS_MPS_TRACE_BIT_LAYER_3 3
|
||||
#define MBEDTLS_MPS_TRACE_BIT_LAYER_4 4
|
||||
#define MBEDTLS_MPS_TRACE_BIT_WRITER 5
|
||||
#define MBEDTLS_MPS_TRACE_BIT_READER 6
|
||||
|
||||
#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_1)
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_1 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_1)
|
||||
#else
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_1 0
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_2)
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_2 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_2)
|
||||
#else
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_2 0
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_3)
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_3 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_3)
|
||||
#else
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_3 0
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_4)
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_4 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_4)
|
||||
#else
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_4 0
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MPS_TRACE_ENABLE_READER)
|
||||
#define MBEDTLS_MPS_TRACE_MASK_READER (1u << MBEDTLS_MPS_TRACE_BIT_READER)
|
||||
#else
|
||||
#define MBEDTLS_MPS_TRACE_MASK_READER 0
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MPS_TRACE_ENABLE_WRITER)
|
||||
#define MBEDTLS_MPS_TRACE_MASK_WRITER (1u << MBEDTLS_MPS_TRACE_BIT_WRITER)
|
||||
#else
|
||||
#define MBEDTLS_MPS_TRACE_MASK_WRITER 0
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_MASK (MBEDTLS_MPS_TRACE_MASK_LAYER_1 | \
|
||||
MBEDTLS_MPS_TRACE_MASK_LAYER_2 | \
|
||||
MBEDTLS_MPS_TRACE_MASK_LAYER_3 | \
|
||||
MBEDTLS_MPS_TRACE_MASK_LAYER_4 | \
|
||||
MBEDTLS_MPS_TRACE_MASK_READER | \
|
||||
MBEDTLS_MPS_TRACE_MASK_WRITER)
|
||||
|
||||
/* We have to avoid globals because E-ACSL chokes on them...
|
||||
* Wrap everything in stub functions. */
|
||||
int mbedtls_mps_trace_get_depth(void);
|
||||
void mbedtls_mps_trace_inc_depth(void);
|
||||
void mbedtls_mps_trace_dec_depth(void);
|
||||
|
||||
void mbedtls_mps_trace_color(int id);
|
||||
void mbedtls_mps_trace_indent(int level, mbedtls_mps_trace_type ty);
|
||||
|
||||
void mbedtls_mps_trace_print_msg(int id, int line, const char *format, ...);
|
||||
|
||||
#define MBEDTLS_MPS_TRACE(type, ...) \
|
||||
do { \
|
||||
if (!(MBEDTLS_MPS_TRACE_MASK & (1u << mbedtls_mps_trace_id))) \
|
||||
break; \
|
||||
mbedtls_mps_trace_indent(mbedtls_mps_trace_get_depth(), type); \
|
||||
mbedtls_mps_trace_color(mbedtls_mps_trace_id); \
|
||||
mbedtls_mps_trace_print_msg(mbedtls_mps_trace_id, __LINE__, __VA_ARGS__); \
|
||||
mbedtls_mps_trace_color(0); \
|
||||
} while (0)
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_INIT(...) \
|
||||
do { \
|
||||
if (!(MBEDTLS_MPS_TRACE_MASK & (1u << mbedtls_mps_trace_id))) \
|
||||
break; \
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_CALL, __VA_ARGS__); \
|
||||
mbedtls_mps_trace_inc_depth(); \
|
||||
} while (0)
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_END(val) \
|
||||
do { \
|
||||
if (!(MBEDTLS_MPS_TRACE_MASK & (1u << mbedtls_mps_trace_id))) \
|
||||
break; \
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_RETURN, "%d (-%#04x)", \
|
||||
(int) (val), -((unsigned) (val))); \
|
||||
mbedtls_mps_trace_dec_depth(); \
|
||||
} while (0)
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_RETURN(val) \
|
||||
do { \
|
||||
/* Breaks tail recursion. */ \
|
||||
int ret__ = val; \
|
||||
MBEDTLS_MPS_TRACE_END(ret__); \
|
||||
return ret__; \
|
||||
} while (0)
|
||||
|
||||
#else /* MBEDTLS_MPS_TRACE */
|
||||
|
||||
#define MBEDTLS_MPS_TRACE(type, ...) do { } while (0)
|
||||
#define MBEDTLS_MPS_TRACE_INIT(...) do { } while (0)
|
||||
#define MBEDTLS_MPS_TRACE_END do { } while (0)
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_RETURN(val) return val;
|
||||
|
||||
#endif /* MBEDTLS_MPS_TRACE */
|
||||
|
||||
#endif /* MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H */
|
||||
1166
Libs/util/third_party/mbedtls/library/oid.c
vendored
Normal file
1166
Libs/util/third_party/mbedtls/library/oid.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
111
Libs/util/third_party/mbedtls/library/padlock.h
vendored
Normal file
111
Libs/util/third_party/mbedtls/library/padlock.h
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* \file padlock.h
|
||||
*
|
||||
* \brief VIA PadLock ACE for HW encryption/decryption supported by some
|
||||
* processors
|
||||
*
|
||||
* \warning These functions are only for internal use by other library
|
||||
* functions; you must not call them directly.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_PADLOCK_H
|
||||
#define MBEDTLS_PADLOCK_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
#define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */
|
||||
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(address_sanitizer)
|
||||
#define MBEDTLS_HAVE_ASAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* - `padlock` is implements with GNUC assembly for x86 target.
|
||||
* - Some versions of ASan result in errors about not enough registers.
|
||||
*/
|
||||
#if defined(MBEDTLS_PADLOCK_C) && \
|
||||
defined(__GNUC__) && defined(MBEDTLS_ARCH_IS_X86) && \
|
||||
defined(MBEDTLS_HAVE_ASM) && \
|
||||
!defined(MBEDTLS_HAVE_ASAN)
|
||||
|
||||
#define MBEDTLS_VIA_PADLOCK_HAVE_CODE
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MBEDTLS_PADLOCK_RNG 0x000C
|
||||
#define MBEDTLS_PADLOCK_ACE 0x00C0
|
||||
#define MBEDTLS_PADLOCK_PHE 0x0C00
|
||||
#define MBEDTLS_PADLOCK_PMM 0x3000
|
||||
|
||||
#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) (x) & ~15))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Internal PadLock detection routine
|
||||
*
|
||||
* \note This function is only for internal use by other library
|
||||
* functions; you must not call it directly.
|
||||
*
|
||||
* \param feature The feature to detect
|
||||
*
|
||||
* \return non-zero if CPU has support for the feature, 0 otherwise
|
||||
*/
|
||||
int mbedtls_padlock_has_support(int feature);
|
||||
|
||||
/**
|
||||
* \brief Internal PadLock AES-ECB block en(de)cryption
|
||||
*
|
||||
* \note This function is only for internal use by other library
|
||||
* functions; you must not call it directly.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
||||
* \param input 16-byte input block
|
||||
* \param output 16-byte output block
|
||||
*
|
||||
* \return 0 if success, 1 if operation failed
|
||||
*/
|
||||
int mbedtls_padlock_xcryptecb(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16]);
|
||||
|
||||
/**
|
||||
* \brief Internal PadLock AES-CBC buffer en(de)cryption
|
||||
*
|
||||
* \note This function is only for internal use by other library
|
||||
* functions; you must not call it directly.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if success, 1 if operation failed
|
||||
*/
|
||||
int mbedtls_padlock_xcryptcbc(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_X86 */
|
||||
|
||||
#endif /* padlock.h */
|
||||
551
Libs/util/third_party/mbedtls/library/pem.c
vendored
Normal file
551
Libs/util/third_party/mbedtls/library/pem.c
vendored
Normal file
@@ -0,0 +1,551 @@
|
||||
/*
|
||||
* Privacy Enhanced Mail (PEM) decoding
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
|
||||
|
||||
#include "mbedtls/pem.h"
|
||||
#include "mbedtls/base64.h"
|
||||
#include "mbedtls/des.h"
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/cipher.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MD_CAN_MD5) && \
|
||||
defined(MBEDTLS_CIPHER_MODE_CBC) && \
|
||||
(defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C))
|
||||
#define PEM_RFC1421
|
||||
#endif /* MBEDTLS_MD_CAN_MD5 &&
|
||||
MBEDTLS_CIPHER_MODE_CBC &&
|
||||
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
void mbedtls_pem_init(mbedtls_pem_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(mbedtls_pem_context));
|
||||
}
|
||||
|
||||
#if defined(PEM_RFC1421)
|
||||
/*
|
||||
* Read a 16-byte hex string and convert it to binary
|
||||
*/
|
||||
static int pem_get_iv(const unsigned char *s, unsigned char *iv,
|
||||
size_t iv_len)
|
||||
{
|
||||
size_t i, j, k;
|
||||
|
||||
memset(iv, 0, iv_len);
|
||||
|
||||
for (i = 0; i < iv_len * 2; i++, s++) {
|
||||
if (*s >= '0' && *s <= '9') {
|
||||
j = *s - '0';
|
||||
} else
|
||||
if (*s >= 'A' && *s <= 'F') {
|
||||
j = *s - '7';
|
||||
} else
|
||||
if (*s >= 'a' && *s <= 'f') {
|
||||
j = *s - 'W';
|
||||
} else {
|
||||
return MBEDTLS_ERR_PEM_INVALID_ENC_IV;
|
||||
}
|
||||
|
||||
k = ((i & 1) != 0) ? j : j << 4;
|
||||
|
||||
iv[i >> 1] = (unsigned char) (iv[i >> 1] | k);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pem_pbkdf1(unsigned char *key, size_t keylen,
|
||||
unsigned char *iv,
|
||||
const unsigned char *pwd, size_t pwdlen)
|
||||
{
|
||||
mbedtls_md_context_t md5_ctx;
|
||||
const mbedtls_md_info_t *md5_info;
|
||||
unsigned char md5sum[16];
|
||||
size_t use_len;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
mbedtls_md_init(&md5_ctx);
|
||||
|
||||
/* Prepare the context. (setup() errors gracefully on NULL info.) */
|
||||
md5_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
|
||||
if ((ret = mbedtls_md_setup(&md5_ctx, md5_info, 0)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* key[ 0..15] = MD5(pwd || IV)
|
||||
*/
|
||||
if ((ret = mbedtls_md_starts(&md5_ctx)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_update(&md5_ctx, pwd, pwdlen)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_update(&md5_ctx, iv, 8)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_finish(&md5_ctx, md5sum)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (keylen <= 16) {
|
||||
memcpy(key, md5sum, keylen);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(key, md5sum, 16);
|
||||
|
||||
/*
|
||||
* key[16..23] = MD5(key[ 0..15] || pwd || IV])
|
||||
*/
|
||||
if ((ret = mbedtls_md_starts(&md5_ctx)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_update(&md5_ctx, md5sum, 16)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_update(&md5_ctx, pwd, pwdlen)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_update(&md5_ctx, iv, 8)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if ((ret = mbedtls_md_finish(&md5_ctx, md5sum)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
use_len = 16;
|
||||
if (keylen < 32) {
|
||||
use_len = keylen - 16;
|
||||
}
|
||||
|
||||
memcpy(key + 16, md5sum, use_len);
|
||||
|
||||
exit:
|
||||
mbedtls_md_free(&md5_ctx);
|
||||
mbedtls_platform_zeroize(md5sum, 16);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_DES_C)
|
||||
/*
|
||||
* Decrypt with DES-CBC, using PBKDF1 for key derivation
|
||||
*/
|
||||
static int pem_des_decrypt(unsigned char des_iv[8],
|
||||
unsigned char *buf, size_t buflen,
|
||||
const unsigned char *pwd, size_t pwdlen)
|
||||
{
|
||||
mbedtls_des_context des_ctx;
|
||||
unsigned char des_key[8];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
mbedtls_des_init(&des_ctx);
|
||||
|
||||
if ((ret = pem_pbkdf1(des_key, 8, des_iv, pwd, pwdlen)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_des_setkey_dec(&des_ctx, des_key)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
ret = mbedtls_des_crypt_cbc(&des_ctx, MBEDTLS_DES_DECRYPT, buflen,
|
||||
des_iv, buf, buf);
|
||||
|
||||
exit:
|
||||
mbedtls_des_free(&des_ctx);
|
||||
mbedtls_platform_zeroize(des_key, 8);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrypt with 3DES-CBC, using PBKDF1 for key derivation
|
||||
*/
|
||||
static int pem_des3_decrypt(unsigned char des3_iv[8],
|
||||
unsigned char *buf, size_t buflen,
|
||||
const unsigned char *pwd, size_t pwdlen)
|
||||
{
|
||||
mbedtls_des3_context des3_ctx;
|
||||
unsigned char des3_key[24];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
mbedtls_des3_init(&des3_ctx);
|
||||
|
||||
if ((ret = pem_pbkdf1(des3_key, 24, des3_iv, pwd, pwdlen)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_des3_set3key_dec(&des3_ctx, des3_key)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
ret = mbedtls_des3_crypt_cbc(&des3_ctx, MBEDTLS_DES_DECRYPT, buflen,
|
||||
des3_iv, buf, buf);
|
||||
|
||||
exit:
|
||||
mbedtls_des3_free(&des3_ctx);
|
||||
mbedtls_platform_zeroize(des3_key, 24);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_DES_C */
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
/*
|
||||
* Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation
|
||||
*/
|
||||
static int pem_aes_decrypt(unsigned char aes_iv[16], unsigned int keylen,
|
||||
unsigned char *buf, size_t buflen,
|
||||
const unsigned char *pwd, size_t pwdlen)
|
||||
{
|
||||
mbedtls_aes_context aes_ctx;
|
||||
unsigned char aes_key[32];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
|
||||
if ((ret = pem_pbkdf1(aes_key, keylen, aes_iv, pwd, pwdlen)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_aes_setkey_dec(&aes_ctx, aes_key, keylen * 8)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
ret = mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, buflen,
|
||||
aes_iv, buf, buf);
|
||||
|
||||
exit:
|
||||
mbedtls_aes_free(&aes_ctx);
|
||||
mbedtls_platform_zeroize(aes_key, keylen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_AES_C */
|
||||
|
||||
#if defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C)
|
||||
static int pem_check_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len)
|
||||
{
|
||||
/* input_len > 0 is guaranteed by mbedtls_pem_read_buffer(). */
|
||||
size_t pad_len = input[input_len - 1];
|
||||
size_t i;
|
||||
|
||||
if (pad_len > input_len) {
|
||||
return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH;
|
||||
}
|
||||
|
||||
*data_len = input_len - pad_len;
|
||||
|
||||
for (i = *data_len; i < input_len; i++) {
|
||||
if (input[i] != pad_len) {
|
||||
return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_DES_C || MBEDTLS_AES_C */
|
||||
|
||||
#endif /* PEM_RFC1421 */
|
||||
|
||||
int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const char *footer,
|
||||
const unsigned char *data, const unsigned char *pwd,
|
||||
size_t pwdlen, size_t *use_len)
|
||||
{
|
||||
int ret, enc;
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
const unsigned char *s1, *s2, *end;
|
||||
#if defined(PEM_RFC1421)
|
||||
unsigned char pem_iv[16];
|
||||
mbedtls_cipher_type_t enc_alg = MBEDTLS_CIPHER_NONE;
|
||||
#else
|
||||
((void) pwd);
|
||||
((void) pwdlen);
|
||||
#endif /* PEM_RFC1421 */
|
||||
|
||||
if (ctx == NULL) {
|
||||
return MBEDTLS_ERR_PEM_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
s1 = (unsigned char *) strstr((const char *) data, header);
|
||||
|
||||
if (s1 == NULL) {
|
||||
return MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
|
||||
}
|
||||
|
||||
s2 = (unsigned char *) strstr((const char *) data, footer);
|
||||
|
||||
if (s2 == NULL || s2 <= s1) {
|
||||
return MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
|
||||
}
|
||||
|
||||
s1 += strlen(header);
|
||||
if (*s1 == ' ') {
|
||||
s1++;
|
||||
}
|
||||
if (*s1 == '\r') {
|
||||
s1++;
|
||||
}
|
||||
if (*s1 == '\n') {
|
||||
s1++;
|
||||
} else {
|
||||
return MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
|
||||
}
|
||||
|
||||
end = s2;
|
||||
end += strlen(footer);
|
||||
if (*end == ' ') {
|
||||
end++;
|
||||
}
|
||||
if (*end == '\r') {
|
||||
end++;
|
||||
}
|
||||
if (*end == '\n') {
|
||||
end++;
|
||||
}
|
||||
*use_len = (size_t) (end - data);
|
||||
|
||||
enc = 0;
|
||||
|
||||
if (s2 - s1 >= 22 && memcmp(s1, "Proc-Type: 4,ENCRYPTED", 22) == 0) {
|
||||
#if defined(PEM_RFC1421)
|
||||
enc++;
|
||||
|
||||
s1 += 22;
|
||||
if (*s1 == '\r') {
|
||||
s1++;
|
||||
}
|
||||
if (*s1 == '\n') {
|
||||
s1++;
|
||||
} else {
|
||||
return MBEDTLS_ERR_PEM_INVALID_DATA;
|
||||
}
|
||||
|
||||
|
||||
#if defined(MBEDTLS_DES_C)
|
||||
if (s2 - s1 >= 23 && memcmp(s1, "DEK-Info: DES-EDE3-CBC,", 23) == 0) {
|
||||
enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC;
|
||||
|
||||
s1 += 23;
|
||||
if (s2 - s1 < 16 || pem_get_iv(s1, pem_iv, 8) != 0) {
|
||||
return MBEDTLS_ERR_PEM_INVALID_ENC_IV;
|
||||
}
|
||||
|
||||
s1 += 16;
|
||||
} else if (s2 - s1 >= 18 && memcmp(s1, "DEK-Info: DES-CBC,", 18) == 0) {
|
||||
enc_alg = MBEDTLS_CIPHER_DES_CBC;
|
||||
|
||||
s1 += 18;
|
||||
if (s2 - s1 < 16 || pem_get_iv(s1, pem_iv, 8) != 0) {
|
||||
return MBEDTLS_ERR_PEM_INVALID_ENC_IV;
|
||||
}
|
||||
|
||||
s1 += 16;
|
||||
}
|
||||
#endif /* MBEDTLS_DES_C */
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if (s2 - s1 >= 14 && memcmp(s1, "DEK-Info: AES-", 14) == 0) {
|
||||
if (s2 - s1 < 22) {
|
||||
return MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG;
|
||||
} else if (memcmp(s1, "DEK-Info: AES-128-CBC,", 22) == 0) {
|
||||
enc_alg = MBEDTLS_CIPHER_AES_128_CBC;
|
||||
} else if (memcmp(s1, "DEK-Info: AES-192-CBC,", 22) == 0) {
|
||||
enc_alg = MBEDTLS_CIPHER_AES_192_CBC;
|
||||
} else if (memcmp(s1, "DEK-Info: AES-256-CBC,", 22) == 0) {
|
||||
enc_alg = MBEDTLS_CIPHER_AES_256_CBC;
|
||||
} else {
|
||||
return MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG;
|
||||
}
|
||||
|
||||
s1 += 22;
|
||||
if (s2 - s1 < 32 || pem_get_iv(s1, pem_iv, 16) != 0) {
|
||||
return MBEDTLS_ERR_PEM_INVALID_ENC_IV;
|
||||
}
|
||||
|
||||
s1 += 32;
|
||||
}
|
||||
#endif /* MBEDTLS_AES_C */
|
||||
|
||||
if (enc_alg == MBEDTLS_CIPHER_NONE) {
|
||||
return MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG;
|
||||
}
|
||||
|
||||
if (*s1 == '\r') {
|
||||
s1++;
|
||||
}
|
||||
if (*s1 == '\n') {
|
||||
s1++;
|
||||
} else {
|
||||
return MBEDTLS_ERR_PEM_INVALID_DATA;
|
||||
}
|
||||
#else
|
||||
return MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE;
|
||||
#endif /* PEM_RFC1421 */
|
||||
}
|
||||
|
||||
if (s1 >= s2) {
|
||||
return MBEDTLS_ERR_PEM_INVALID_DATA;
|
||||
}
|
||||
|
||||
ret = mbedtls_base64_decode(NULL, 0, &len, s1, (size_t) (s2 - s1));
|
||||
|
||||
if (ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret);
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
return MBEDTLS_ERR_PEM_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if ((buf = mbedtls_calloc(1, len)) == NULL) {
|
||||
return MBEDTLS_ERR_PEM_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_base64_decode(buf, len, &len, s1, (size_t) (s2 - s1))) != 0) {
|
||||
mbedtls_zeroize_and_free(buf, len);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret);
|
||||
}
|
||||
|
||||
if (enc != 0) {
|
||||
#if defined(PEM_RFC1421)
|
||||
if (pwd == NULL) {
|
||||
mbedtls_zeroize_and_free(buf, len);
|
||||
return MBEDTLS_ERR_PEM_PASSWORD_REQUIRED;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
#if defined(MBEDTLS_DES_C)
|
||||
if (enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC) {
|
||||
ret = pem_des3_decrypt(pem_iv, buf, len, pwd, pwdlen);
|
||||
} else if (enc_alg == MBEDTLS_CIPHER_DES_CBC) {
|
||||
ret = pem_des_decrypt(pem_iv, buf, len, pwd, pwdlen);
|
||||
}
|
||||
#endif /* MBEDTLS_DES_C */
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if (enc_alg == MBEDTLS_CIPHER_AES_128_CBC) {
|
||||
ret = pem_aes_decrypt(pem_iv, 16, buf, len, pwd, pwdlen);
|
||||
} else if (enc_alg == MBEDTLS_CIPHER_AES_192_CBC) {
|
||||
ret = pem_aes_decrypt(pem_iv, 24, buf, len, pwd, pwdlen);
|
||||
} else if (enc_alg == MBEDTLS_CIPHER_AES_256_CBC) {
|
||||
ret = pem_aes_decrypt(pem_iv, 32, buf, len, pwd, pwdlen);
|
||||
}
|
||||
#endif /* MBEDTLS_AES_C */
|
||||
|
||||
if (ret != 0) {
|
||||
mbedtls_zeroize_and_free(buf, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check PKCS padding and update data length based on padding info.
|
||||
* This can be used to detect invalid padding data and password
|
||||
* mismatches. */
|
||||
size_t unpadded_len;
|
||||
ret = pem_check_pkcs_padding(buf, len, &unpadded_len);
|
||||
if (ret != 0) {
|
||||
mbedtls_zeroize_and_free(buf, len);
|
||||
return ret;
|
||||
}
|
||||
len = unpadded_len;
|
||||
#else
|
||||
mbedtls_zeroize_and_free(buf, len);
|
||||
return MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE;
|
||||
#endif /* PEM_RFC1421 */
|
||||
}
|
||||
|
||||
ctx->buf = buf;
|
||||
ctx->buflen = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mbedtls_pem_free(mbedtls_pem_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->buf != NULL) {
|
||||
mbedtls_zeroize_and_free(ctx->buf, ctx->buflen);
|
||||
}
|
||||
mbedtls_free(ctx->info);
|
||||
|
||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pem_context));
|
||||
}
|
||||
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||
|
||||
#if defined(MBEDTLS_PEM_WRITE_C)
|
||||
int mbedtls_pem_write_buffer(const char *header, const char *footer,
|
||||
const unsigned char *der_data, size_t der_len,
|
||||
unsigned char *buf, size_t buf_len, size_t *olen)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *encode_buf = NULL, *c, *p = buf;
|
||||
size_t len = 0, use_len, add_len = 0;
|
||||
|
||||
mbedtls_base64_encode(NULL, 0, &use_len, der_data, der_len);
|
||||
add_len = strlen(header) + strlen(footer) + (((use_len > 2) ? (use_len - 2) : 0) / 64) + 1;
|
||||
|
||||
if (use_len + add_len > buf_len) {
|
||||
*olen = use_len + add_len;
|
||||
return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (use_len != 0 &&
|
||||
((encode_buf = mbedtls_calloc(1, use_len)) == NULL)) {
|
||||
return MBEDTLS_ERR_PEM_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_base64_encode(encode_buf, use_len, &use_len, der_data,
|
||||
der_len)) != 0) {
|
||||
mbedtls_free(encode_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(p, header, strlen(header));
|
||||
p += strlen(header);
|
||||
c = encode_buf;
|
||||
|
||||
while (use_len) {
|
||||
len = (use_len > 64) ? 64 : use_len;
|
||||
memcpy(p, c, len);
|
||||
use_len -= len;
|
||||
p += len;
|
||||
c += len;
|
||||
*p++ = '\n';
|
||||
}
|
||||
|
||||
memcpy(p, footer, strlen(footer));
|
||||
p += strlen(footer);
|
||||
|
||||
*p++ = '\0';
|
||||
*olen = (size_t) (p - buf);
|
||||
|
||||
/* Clean any remaining data previously written to the buffer */
|
||||
memset(buf + *olen, 0, buf_len - *olen);
|
||||
|
||||
mbedtls_free(encode_buf);
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PEM_WRITE_C */
|
||||
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
|
||||
1507
Libs/util/third_party/mbedtls/library/pk.c
vendored
Normal file
1507
Libs/util/third_party/mbedtls/library/pk.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
255
Libs/util/third_party/mbedtls/library/pk_ecc.c
vendored
Normal file
255
Libs/util/third_party/mbedtls/library/pk_ecc.c
vendored
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* ECC setters for PK.
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "mbedtls/pk.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "pk_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
|
||||
int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id)
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
size_t ec_bits;
|
||||
psa_ecc_family_t ec_family = mbedtls_ecc_group_to_psa(grp_id, &ec_bits);
|
||||
|
||||
/* group may already be initialized; if so, make sure IDs match */
|
||||
if ((pk->ec_family != 0 && pk->ec_family != ec_family) ||
|
||||
(pk->ec_bits != 0 && pk->ec_bits != ec_bits)) {
|
||||
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
/* set group */
|
||||
pk->ec_family = ec_family;
|
||||
pk->ec_bits = ec_bits;
|
||||
|
||||
return 0;
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk);
|
||||
|
||||
/* grp may already be initialized; if so, make sure IDs match */
|
||||
if (mbedtls_pk_ec_ro(*pk)->grp.id != MBEDTLS_ECP_DP_NONE &&
|
||||
mbedtls_pk_ec_ro(*pk)->grp.id != grp_id) {
|
||||
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
/* set group */
|
||||
return mbedtls_ecp_group_load(&(ecp->grp), grp_id);
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
}
|
||||
|
||||
int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len)
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_usage_t flags;
|
||||
psa_status_t status;
|
||||
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family));
|
||||
if (pk->ec_family == PSA_ECC_FAMILY_MONTGOMERY) {
|
||||
/* Do not set algorithm here because Montgomery keys cannot do ECDSA and
|
||||
* the PK module cannot do ECDH. When the key will be used in TLS for
|
||||
* ECDH, it will be exported and then re-imported with proper flags
|
||||
* and algorithm. */
|
||||
flags = PSA_KEY_USAGE_EXPORT;
|
||||
} else {
|
||||
psa_set_key_algorithm(&attributes,
|
||||
MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET(PSA_ALG_ANY_HASH));
|
||||
flags = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE |
|
||||
PSA_KEY_USAGE_EXPORT;
|
||||
}
|
||||
psa_set_key_usage_flags(&attributes, flags);
|
||||
|
||||
status = psa_import_key(&attributes, key, key_len, &pk->priv_id);
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
|
||||
int ret = mbedtls_ecp_read_key(eck->grp.id, eck, key, key_len);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
|
||||
}
|
||||
return 0;
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
}
|
||||
|
||||
int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk,
|
||||
const unsigned char *prv, size_t prv_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
(void) prv;
|
||||
(void) prv_len;
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_export_public_key(pk->priv_id, pk->pub_raw, sizeof(pk->pub_raw),
|
||||
&pk->pub_raw_len);
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
|
||||
#elif defined(MBEDTLS_USE_PSA_CRYPTO) /* && !MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
psa_status_t status;
|
||||
|
||||
mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
|
||||
size_t curve_bits;
|
||||
psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits);
|
||||
|
||||
/* Import private key into PSA, from serialized input */
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
|
||||
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
|
||||
status = psa_import_key(&key_attr, prv, prv_len, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
}
|
||||
|
||||
/* Export public key from PSA */
|
||||
unsigned char pub[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
|
||||
size_t pub_len;
|
||||
status = psa_export_public_key(key_id, pub, sizeof(pub), &pub_len);
|
||||
psa_status_t destruction_status = psa_destroy_key(key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
} else if (destruction_status != PSA_SUCCESS) {
|
||||
return psa_pk_status_to_mbedtls(destruction_status);
|
||||
}
|
||||
|
||||
/* Load serialized public key into ecp_keypair structure */
|
||||
return mbedtls_ecp_point_read_binary(&eck->grp, &eck->Q, pub, pub_len);
|
||||
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
(void) prv;
|
||||
(void) prv_len;
|
||||
|
||||
mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
|
||||
return mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G, f_rng, p_rng);
|
||||
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
/*
|
||||
* Set the public key: fallback using ECP_LIGHT in the USE_PSA_EC_DATA case.
|
||||
*
|
||||
* Normally, when MBEDTLS_PK_USE_PSA_EC_DATA is enabled, we only use PSA
|
||||
* functions to handle keys. However, currently psa_import_key() does not
|
||||
* support compressed points. In case that support was explicitly requested,
|
||||
* this fallback uses ECP functions to get the job done. This is the reason
|
||||
* why MBEDTLS_PK_PARSE_EC_COMPRESSED auto-enables MBEDTLS_ECP_LIGHT.
|
||||
*
|
||||
* [in/out] pk: in: must have the group set, see mbedtls_pk_ecc_set_group().
|
||||
* out: will have the public key set.
|
||||
* [in] pub, pub_len: the public key as an ECPoint,
|
||||
* in any format supported by ECP.
|
||||
*
|
||||
* Return:
|
||||
* - 0 on success;
|
||||
* - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid
|
||||
* but not supported;
|
||||
* - another error code otherwise.
|
||||
*/
|
||||
static int pk_ecc_set_pubkey_psa_ecp_fallback(mbedtls_pk_context *pk,
|
||||
const unsigned char *pub,
|
||||
size_t pub_len)
|
||||
{
|
||||
#if !defined(MBEDTLS_PK_PARSE_EC_COMPRESSED)
|
||||
(void) pk;
|
||||
(void) pub;
|
||||
(void) pub_len;
|
||||
return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
|
||||
#else /* MBEDTLS_PK_PARSE_EC_COMPRESSED */
|
||||
mbedtls_ecp_keypair ecp_key;
|
||||
mbedtls_ecp_group_id ecp_group_id;
|
||||
int ret;
|
||||
|
||||
ecp_group_id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits);
|
||||
|
||||
mbedtls_ecp_keypair_init(&ecp_key);
|
||||
ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
ret = mbedtls_ecp_point_read_binary(&(ecp_key.grp), &ecp_key.Q,
|
||||
pub, pub_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
ret = mbedtls_ecp_point_write_binary(&(ecp_key.grp), &ecp_key.Q,
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED,
|
||||
&pk->pub_raw_len, pk->pub_raw,
|
||||
sizeof(pk->pub_raw));
|
||||
|
||||
exit:
|
||||
mbedtls_ecp_keypair_free(&ecp_key);
|
||||
return ret;
|
||||
#endif /* MBEDTLS_PK_PARSE_EC_COMPRESSED */
|
||||
}
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len)
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
|
||||
/* Load the key */
|
||||
if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(pk->ec_family) || *pub == 0x04) {
|
||||
/* Format directly supported by PSA:
|
||||
* - non-Weierstrass curves that only have one format;
|
||||
* - uncompressed format for Weierstrass curves. */
|
||||
if (pub_len > sizeof(pk->pub_raw)) {
|
||||
return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
|
||||
}
|
||||
memcpy(pk->pub_raw, pub, pub_len);
|
||||
pk->pub_raw_len = pub_len;
|
||||
} else {
|
||||
/* Other format, try the fallback */
|
||||
int ret = pk_ecc_set_pubkey_psa_ecp_fallback(pk, pub, pub_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate the key by trying to import it */
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
psa_set_key_usage_flags(&key_attrs, 0);
|
||||
psa_set_key_type(&key_attrs, PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family));
|
||||
psa_set_key_bits(&key_attrs, pk->ec_bits);
|
||||
|
||||
if ((psa_import_key(&key_attrs, pk->pub_raw, pk->pub_raw_len,
|
||||
&key_id) != PSA_SUCCESS) ||
|
||||
(psa_destroy_key(key_id) != PSA_SUCCESS)) {
|
||||
return MBEDTLS_ERR_PK_INVALID_PUBKEY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
int ret;
|
||||
mbedtls_ecp_keypair *ec_key = (mbedtls_ecp_keypair *) pk->pk_ctx;
|
||||
ret = mbedtls_ecp_point_read_binary(&ec_key->grp, &ec_key->Q, pub, pub_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
return mbedtls_ecp_check_pubkey(&ec_key->grp, &ec_key->Q);
|
||||
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PK_C && MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
207
Libs/util/third_party/mbedtls/library/pk_internal.h
vendored
Normal file
207
Libs/util/third_party/mbedtls/library/pk_internal.h
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* \file pk_internal.h
|
||||
*
|
||||
* \brief Public Key abstraction layer: internal (i.e. library only) functions
|
||||
* and definitions.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_PK_INTERNAL_H
|
||||
#define MBEDTLS_PK_INTERNAL_H
|
||||
|
||||
#include "mbedtls/pk.h"
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
#include "mbedtls/ecp.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "psa_util_internal.h"
|
||||
#define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status)
|
||||
#define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
|
||||
psa_to_pk_rsa_errors, \
|
||||
psa_pk_status_to_mbedtls)
|
||||
#define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
|
||||
psa_to_pk_ecdsa_errors, \
|
||||
psa_pk_status_to_mbedtls)
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
|
||||
/* Headers/footers for PEM files */
|
||||
#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----"
|
||||
#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----"
|
||||
#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----"
|
||||
#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----"
|
||||
#define PEM_BEGIN_PUBLIC_KEY_RSA "-----BEGIN RSA PUBLIC KEY-----"
|
||||
#define PEM_END_PUBLIC_KEY_RSA "-----END RSA PUBLIC KEY-----"
|
||||
#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----"
|
||||
#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----"
|
||||
#define PEM_BEGIN_PRIVATE_KEY_PKCS8 "-----BEGIN PRIVATE KEY-----"
|
||||
#define PEM_END_PRIVATE_KEY_PKCS8 "-----END PRIVATE KEY-----"
|
||||
#define PEM_BEGIN_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----BEGIN ENCRYPTED PRIVATE KEY-----"
|
||||
#define PEM_END_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----END ENCRYPTED PRIVATE KEY-----"
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
/**
|
||||
* Public function mbedtls_pk_ec() can be used to get direct access to the
|
||||
* wrapped ecp_keypair structure pointed to the pk_ctx. However this is not
|
||||
* ideal because it bypasses the PK module on the control of its internal
|
||||
* structure (pk_context) fields.
|
||||
* For backward compatibility we keep mbedtls_pk_ec() when ECP_C is defined, but
|
||||
* we provide 2 very similar functions when only ECP_LIGHT is enabled and not
|
||||
* ECP_C.
|
||||
* These variants embed the "ro" or "rw" keywords in their name to make the
|
||||
* usage of the returned pointer explicit. Of course the returned value is
|
||||
* const or non-const accordingly.
|
||||
*/
|
||||
static inline const mbedtls_ecp_keypair *mbedtls_pk_ec_ro(const mbedtls_pk_context pk)
|
||||
{
|
||||
switch (mbedtls_pk_get_type(&pk)) {
|
||||
case MBEDTLS_PK_ECKEY:
|
||||
case MBEDTLS_PK_ECKEY_DH:
|
||||
case MBEDTLS_PK_ECDSA:
|
||||
return (const mbedtls_ecp_keypair *) (pk).MBEDTLS_PRIVATE(pk_ctx);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline mbedtls_ecp_keypair *mbedtls_pk_ec_rw(const mbedtls_pk_context pk)
|
||||
{
|
||||
switch (mbedtls_pk_get_type(&pk)) {
|
||||
case MBEDTLS_PK_ECKEY:
|
||||
case MBEDTLS_PK_ECKEY_DH:
|
||||
case MBEDTLS_PK_ECDSA:
|
||||
return (mbedtls_ecp_keypair *) (pk).MBEDTLS_PRIVATE(pk_ctx);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
static inline mbedtls_ecp_group_id mbedtls_pk_get_ec_group_id(const mbedtls_pk_context *pk)
|
||||
{
|
||||
mbedtls_ecp_group_id id;
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
|
||||
psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_type_t opaque_key_type;
|
||||
psa_ecc_family_t curve;
|
||||
|
||||
if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) {
|
||||
return MBEDTLS_ECP_DP_NONE;
|
||||
}
|
||||
opaque_key_type = psa_get_key_type(&opaque_attrs);
|
||||
curve = PSA_KEY_TYPE_ECC_GET_FAMILY(opaque_key_type);
|
||||
id = mbedtls_ecc_group_from_psa(curve, psa_get_key_bits(&opaque_attrs));
|
||||
psa_reset_key_attributes(&opaque_attrs);
|
||||
} else
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits);
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
id = mbedtls_pk_ec_ro(*pk)->grp.id;
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/* Helper for Montgomery curves */
|
||||
#if defined(MBEDTLS_ECP_HAVE_CURVE25519) || defined(MBEDTLS_ECP_HAVE_CURVE448)
|
||||
#define MBEDTLS_PK_HAVE_RFC8410_CURVES
|
||||
#endif /* MBEDTLS_ECP_HAVE_CURVE25519 || MBEDTLS_ECP_DP_CURVE448 */
|
||||
|
||||
#define MBEDTLS_PK_IS_RFC8410_GROUP_ID(id) \
|
||||
((id == MBEDTLS_ECP_DP_CURVE25519) || (id == MBEDTLS_ECP_DP_CURVE448))
|
||||
|
||||
static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk)
|
||||
{
|
||||
mbedtls_ecp_group_id id = mbedtls_pk_get_ec_group_id(pk);
|
||||
|
||||
return MBEDTLS_PK_IS_RFC8410_GROUP_ID(id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the group used by this key.
|
||||
*
|
||||
* [in/out] pk: in: must have been pk_setup() to an ECC type
|
||||
* out: will have group (curve) information set
|
||||
* [in] grp_in: a supported group ID (not NONE)
|
||||
*/
|
||||
int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id);
|
||||
|
||||
/*
|
||||
* Set the private key material
|
||||
*
|
||||
* [in/out] pk: in: must have the group set already, see mbedtls_pk_ecc_set_group().
|
||||
* out: will have the private key set.
|
||||
* [in] key, key_len: the raw private key (no ASN.1 wrapping).
|
||||
*/
|
||||
int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len);
|
||||
|
||||
/*
|
||||
* Set the public key.
|
||||
*
|
||||
* [in/out] pk: in: must have its group set, see mbedtls_pk_ecc_set_group().
|
||||
* out: will have the public key set.
|
||||
* [in] pub, pub_len: the raw public key (an ECPoint).
|
||||
*
|
||||
* Return:
|
||||
* - 0 on success;
|
||||
* - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid
|
||||
* but not supported;
|
||||
* - another error code otherwise.
|
||||
*/
|
||||
int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len);
|
||||
|
||||
/*
|
||||
* Derive a public key from its private counterpart.
|
||||
* Computationally intensive, only use when public key is not available.
|
||||
*
|
||||
* [in/out] pk: in: must have the private key set, see mbedtls_pk_ecc_set_key().
|
||||
* out: will have the public key set.
|
||||
* [in] prv, prv_len: the raw private key (see note below).
|
||||
* [in] f_rng, p_rng: RNG function and context.
|
||||
*
|
||||
* Note: the private key information is always available from pk,
|
||||
* however for convenience the serialized version is also passed,
|
||||
* as it's available at each calling site, and useful in some configs
|
||||
* (as otherwise we would have to re-serialize it from the pk context).
|
||||
*
|
||||
* There are three implementations of this function:
|
||||
* 1. MBEDTLS_PK_USE_PSA_EC_DATA,
|
||||
* 2. MBEDTLS_USE_PSA_CRYPTO but not MBEDTLS_PK_USE_PSA_EC_DATA,
|
||||
* 3. not MBEDTLS_USE_PSA_CRYPTO.
|
||||
*/
|
||||
int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk,
|
||||
const unsigned char *prv, size_t prv_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
|
||||
/* Helper for (deterministic) ECDSA */
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
#define MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET PSA_ALG_DETERMINISTIC_ECDSA
|
||||
#else
|
||||
#define MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET PSA_ALG_ECDSA
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
MBEDTLS_STATIC_TESTABLE int mbedtls_pk_parse_key_pkcs8_encrypted_der(
|
||||
mbedtls_pk_context *pk,
|
||||
unsigned char *key, size_t keylen,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n);
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_PK_INTERNAL_H */
|
||||
1586
Libs/util/third_party/mbedtls/library/pk_wrap.c
vendored
Normal file
1586
Libs/util/third_party/mbedtls/library/pk_wrap.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
138
Libs/util/third_party/mbedtls/library/pk_wrap.h
vendored
Normal file
138
Libs/util/third_party/mbedtls/library/pk_wrap.h
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* \file pk_wrap.h
|
||||
*
|
||||
* \brief Public Key abstraction layer: wrapper functions
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_PK_WRAP_H
|
||||
#define MBEDTLS_PK_WRAP_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "mbedtls/pk.h"
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#endif
|
||||
|
||||
struct mbedtls_pk_info_t {
|
||||
/** Public key type */
|
||||
mbedtls_pk_type_t type;
|
||||
|
||||
/** Type name */
|
||||
const char *name;
|
||||
|
||||
/** Get key size in bits */
|
||||
size_t (*get_bitlen)(mbedtls_pk_context *pk);
|
||||
|
||||
/** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */
|
||||
int (*can_do)(mbedtls_pk_type_t type);
|
||||
|
||||
/** Verify signature */
|
||||
int (*verify_func)(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len);
|
||||
|
||||
/** Make signature */
|
||||
int (*sign_func)(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/** Verify signature (restartable) */
|
||||
int (*verify_rs_func)(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len,
|
||||
void *rs_ctx);
|
||||
|
||||
/** Make signature (restartable) */
|
||||
int (*sign_rs_func)(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng, void *rs_ctx);
|
||||
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
/** Decrypt message */
|
||||
int (*decrypt_func)(mbedtls_pk_context *pk, const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/** Encrypt message */
|
||||
int (*encrypt_func)(mbedtls_pk_context *pk, const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/** Check public-private key pair */
|
||||
int (*check_pair_func)(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/** Allocate a new context */
|
||||
void * (*ctx_alloc_func)(void);
|
||||
|
||||
/** Free the given context */
|
||||
void (*ctx_free_func)(void *ctx);
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/** Allocate the restart context */
|
||||
void *(*rs_alloc_func)(void);
|
||||
|
||||
/** Free the restart context */
|
||||
void (*rs_free_func)(void *rs_ctx);
|
||||
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
/** Interface with the debug module */
|
||||
void (*debug_func)(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items);
|
||||
|
||||
};
|
||||
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
|
||||
/* Container for RSA-alt */
|
||||
typedef struct {
|
||||
void *key;
|
||||
mbedtls_pk_rsa_alt_decrypt_func decrypt_func;
|
||||
mbedtls_pk_rsa_alt_sign_func sign_func;
|
||||
mbedtls_pk_rsa_alt_key_len_func key_len_func;
|
||||
} mbedtls_rsa_alt_context;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
extern const mbedtls_pk_info_t mbedtls_rsa_info;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
extern const mbedtls_pk_info_t mbedtls_eckey_info;
|
||||
extern const mbedtls_pk_info_t mbedtls_eckeydh_info;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
|
||||
extern const mbedtls_pk_info_t mbedtls_ecdsa_info;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
|
||||
extern const mbedtls_pk_info_t mbedtls_rsa_alt_info;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
extern const mbedtls_pk_info_t mbedtls_ecdsa_opaque_info;
|
||||
extern const mbedtls_pk_info_t mbedtls_rsa_opaque_info;
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t psa_alg_md,
|
||||
mbedtls_rsa_context *rsa_ctx,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size,
|
||||
size_t *sig_len);
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#endif /* MBEDTLS_PK_WRAP_H */
|
||||
1392
Libs/util/third_party/mbedtls/library/pkparse.c
vendored
Normal file
1392
Libs/util/third_party/mbedtls/library/pkparse.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
629
Libs/util/third_party/mbedtls/library/pkwrite.c
vendored
Normal file
629
Libs/util/third_party/mbedtls/library/pkwrite.c
vendored
Normal file
@@ -0,0 +1,629 @@
|
||||
/*
|
||||
* Public Key layer for writing key files and structures
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PK_WRITE_C)
|
||||
|
||||
#include "mbedtls/pk.h"
|
||||
#include "mbedtls/asn1write.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "pk_internal.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
#include "pk_internal.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
#include "pkwrite.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_PEM_WRITE_C)
|
||||
#include "mbedtls/pem.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
#include "rsa_internal.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_util_internal.h"
|
||||
#endif
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
/* Helpers for properly sizing buffers aimed at holding public keys or
|
||||
* key-pairs based on build symbols. */
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
#define PK_MAX_EC_PUBLIC_KEY_SIZE PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
|
||||
#define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH
|
||||
#elif defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#define PK_MAX_EC_PUBLIC_KEY_SIZE PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
|
||||
#define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH
|
||||
#else
|
||||
#define PK_MAX_EC_PUBLIC_KEY_SIZE MBEDTLS_ECP_MAX_PT_LEN
|
||||
#define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_ECP_MAX_BYTES
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Internal functions for RSA keys.
|
||||
******************************************************************************/
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
static int pk_write_rsa_der(unsigned char **p, unsigned char *buf,
|
||||
const mbedtls_pk_context *pk)
|
||||
{
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
|
||||
uint8_t tmp[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
|
||||
size_t tmp_len = 0;
|
||||
|
||||
if (psa_export_key(pk->priv_id, tmp, sizeof(tmp), &tmp_len) != PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
/* Ensure there's enough space in the provided buffer before copying data into it. */
|
||||
if (tmp_len > (size_t) (*p - buf)) {
|
||||
mbedtls_platform_zeroize(tmp, sizeof(tmp));
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
*p -= tmp_len;
|
||||
memcpy(*p, tmp, tmp_len);
|
||||
mbedtls_platform_zeroize(tmp, sizeof(tmp));
|
||||
|
||||
return (int) tmp_len;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
return mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), buf, p);
|
||||
}
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
/******************************************************************************
|
||||
* Internal functions for EC keys.
|
||||
******************************************************************************/
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
|
||||
const mbedtls_pk_context *pk)
|
||||
{
|
||||
size_t len = 0;
|
||||
uint8_t buf[PK_MAX_EC_PUBLIC_KEY_SIZE];
|
||||
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
|
||||
if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
} else {
|
||||
len = pk->pub_raw_len;
|
||||
memcpy(buf, pk->pub_raw, len);
|
||||
}
|
||||
|
||||
if (*p < start || (size_t) (*p - start) < len) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
*p -= len;
|
||||
memcpy(*p, buf, len);
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
|
||||
const mbedtls_pk_context *pk)
|
||||
{
|
||||
size_t len = 0;
|
||||
unsigned char buf[PK_MAX_EC_PUBLIC_KEY_SIZE];
|
||||
mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*pk);
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
|
||||
if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
/* Ensure there's enough space in the provided buffer before copying data into it. */
|
||||
if (len > (size_t) (*p - start)) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
*p -= len;
|
||||
memcpy(*p, buf, len);
|
||||
return (int) len;
|
||||
} else
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
{
|
||||
if ((ret = mbedtls_ecp_point_write_binary(&ec->grp, &ec->Q,
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED,
|
||||
&len, buf, sizeof(buf))) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (*p < start || (size_t) (*p - start) < len) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
*p -= len;
|
||||
memcpy(*p, buf, len);
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
/*
|
||||
* privateKey OCTET STRING -- always of length ceil(log2(n)/8)
|
||||
*/
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
static int pk_write_ec_private(unsigned char **p, unsigned char *start,
|
||||
const mbedtls_pk_context *pk)
|
||||
{
|
||||
size_t byte_length;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char tmp[PK_MAX_EC_KEY_PAIR_SIZE];
|
||||
psa_status_t status;
|
||||
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
|
||||
status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length);
|
||||
exit:
|
||||
mbedtls_platform_zeroize(tmp, sizeof(tmp));
|
||||
return ret;
|
||||
}
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
static int pk_write_ec_private(unsigned char **p, unsigned char *start,
|
||||
const mbedtls_pk_context *pk)
|
||||
{
|
||||
size_t byte_length;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char tmp[PK_MAX_EC_KEY_PAIR_SIZE];
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status;
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
|
||||
status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
|
||||
return ret;
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
{
|
||||
mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
|
||||
byte_length = (ec->grp.pbits + 7) / 8;
|
||||
|
||||
ret = mbedtls_ecp_write_key_ext(ec, &byte_length, tmp, sizeof(tmp));
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length);
|
||||
exit:
|
||||
mbedtls_platform_zeroize(tmp, sizeof(tmp));
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
/*
|
||||
* ECParameters ::= CHOICE {
|
||||
* namedCurve OBJECT IDENTIFIER
|
||||
* }
|
||||
*/
|
||||
static int pk_write_ec_param(unsigned char **p, unsigned char *start,
|
||||
mbedtls_ecp_group_id grp_id)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
const char *oid;
|
||||
size_t oid_len;
|
||||
|
||||
if ((ret = mbedtls_oid_get_oid_by_ec_grp(grp_id, &oid, &oid_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
|
||||
/*
|
||||
* RFC8410 section 7
|
||||
*
|
||||
* OneAsymmetricKey ::= SEQUENCE {
|
||||
* version Version,
|
||||
* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
|
||||
* privateKey PrivateKey,
|
||||
* attributes [0] IMPLICIT Attributes OPTIONAL,
|
||||
* ...,
|
||||
* [[2: publicKey [1] IMPLICIT PublicKey OPTIONAL ]],
|
||||
* ...
|
||||
* }
|
||||
* ...
|
||||
* CurvePrivateKey ::= OCTET STRING
|
||||
*/
|
||||
static int pk_write_ec_rfc8410_der(unsigned char **p, unsigned char *buf,
|
||||
const mbedtls_pk_context *pk)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
size_t oid_len = 0;
|
||||
const char *oid;
|
||||
mbedtls_ecp_group_id grp_id;
|
||||
|
||||
/* privateKey */
|
||||
MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_OCTET_STRING));
|
||||
|
||||
grp_id = mbedtls_pk_get_ec_group_id(pk);
|
||||
/* privateKeyAlgorithm */
|
||||
if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(grp_id, &oid, &oid_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_algorithm_identifier_ext(p, buf, oid, oid_len, 0, 0));
|
||||
|
||||
/* version */
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 0));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
|
||||
|
||||
/*
|
||||
* RFC 5915, or SEC1 Appendix C.4
|
||||
*
|
||||
* ECPrivateKey ::= SEQUENCE {
|
||||
* version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
|
||||
* privateKey OCTET STRING,
|
||||
* parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
|
||||
* publicKey [1] BIT STRING OPTIONAL
|
||||
* }
|
||||
*/
|
||||
static int pk_write_ec_der(unsigned char **p, unsigned char *buf,
|
||||
const mbedtls_pk_context *pk)
|
||||
{
|
||||
size_t len = 0;
|
||||
int ret;
|
||||
size_t pub_len = 0, par_len = 0;
|
||||
mbedtls_ecp_group_id grp_id;
|
||||
|
||||
/* publicKey */
|
||||
MBEDTLS_ASN1_CHK_ADD(pub_len, pk_write_ec_pubkey(p, buf, pk));
|
||||
|
||||
if (*p - buf < 1) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
(*p)--;
|
||||
**p = 0;
|
||||
pub_len += 1;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len));
|
||||
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_BIT_STRING));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len));
|
||||
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
|
||||
MBEDTLS_ASN1_CONSTRUCTED | 1));
|
||||
len += pub_len;
|
||||
|
||||
/* parameters */
|
||||
grp_id = mbedtls_pk_get_ec_group_id(pk);
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(p, buf, grp_id));
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_len(p, buf, par_len));
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_tag(p, buf,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
|
||||
MBEDTLS_ASN1_CONSTRUCTED | 0));
|
||||
len += par_len;
|
||||
|
||||
/* privateKey */
|
||||
MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk));
|
||||
|
||||
/* version */
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 1));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
|
||||
/******************************************************************************
|
||||
* Internal functions for Opaque keys.
|
||||
******************************************************************************/
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
static int pk_write_opaque_pubkey(unsigned char **p, unsigned char *start,
|
||||
const mbedtls_pk_context *pk)
|
||||
{
|
||||
size_t buffer_size;
|
||||
size_t len = 0;
|
||||
|
||||
if (*p < start) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
buffer_size = (size_t) (*p - start);
|
||||
if (psa_export_public_key(pk->priv_id, start, buffer_size,
|
||||
&len) != PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
*p -= len;
|
||||
memmove(*p, start, len);
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
/******************************************************************************
|
||||
* Generic helpers
|
||||
******************************************************************************/
|
||||
|
||||
/* Extend the public mbedtls_pk_get_type() by getting key type also in case of
|
||||
* opaque keys. */
|
||||
static mbedtls_pk_type_t pk_get_type_ext(const mbedtls_pk_context *pk)
|
||||
{
|
||||
mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if (pk_type == MBEDTLS_PK_OPAQUE) {
|
||||
psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_type_t opaque_key_type;
|
||||
|
||||
if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) {
|
||||
return MBEDTLS_PK_NONE;
|
||||
}
|
||||
opaque_key_type = psa_get_key_type(&opaque_attrs);
|
||||
psa_reset_key_attributes(&opaque_attrs);
|
||||
|
||||
if (PSA_KEY_TYPE_IS_ECC(opaque_key_type)) {
|
||||
return MBEDTLS_PK_ECKEY;
|
||||
} else if (PSA_KEY_TYPE_IS_RSA(opaque_key_type)) {
|
||||
return MBEDTLS_PK_RSA;
|
||||
} else {
|
||||
return MBEDTLS_PK_NONE;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
return pk_type;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Public functions for writing private/public DER keys.
|
||||
******************************************************************************/
|
||||
int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
|
||||
const mbedtls_pk_context *key)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*key), start, p));
|
||||
} else
|
||||
#endif
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_pubkey(p, start, key));
|
||||
} else
|
||||
#endif
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, pk_write_opaque_pubkey(p, start, key));
|
||||
} else
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *c;
|
||||
int has_par = 1;
|
||||
size_t len = 0, par_len = 0, oid_len = 0;
|
||||
mbedtls_pk_type_t pk_type;
|
||||
const char *oid = NULL;
|
||||
|
||||
if (size == 0) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
c = buf + size;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_pk_write_pubkey(&c, buf, key));
|
||||
|
||||
if (c - buf < 1) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
/*
|
||||
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
* algorithm AlgorithmIdentifier,
|
||||
* subjectPublicKey BIT STRING }
|
||||
*/
|
||||
*--c = 0;
|
||||
len += 1;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_BIT_STRING));
|
||||
|
||||
pk_type = pk_get_type_ext(key);
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) {
|
||||
mbedtls_ecp_group_id ec_grp_id = mbedtls_pk_get_ec_group_id(key);
|
||||
if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) {
|
||||
ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec_grp_id, &oid, &oid_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
has_par = 0;
|
||||
} else {
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec_grp_id));
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
|
||||
/* At this point oid_len is not null only for EC Montgomery keys. */
|
||||
if (oid_len == 0) {
|
||||
ret = mbedtls_oid_get_oid_by_pk_alg(pk_type, &oid, &oid_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_algorithm_identifier_ext(&c, buf, oid, oid_len,
|
||||
par_len, has_par));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
|
||||
{
|
||||
unsigned char *c;
|
||||
|
||||
if (size == 0) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
c = buf + size;
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
if (pk_get_type_ext(key) == MBEDTLS_PK_RSA) {
|
||||
return pk_write_rsa_der(&c, buf, key);
|
||||
} else
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) {
|
||||
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
|
||||
if (mbedtls_pk_is_rfc8410(key)) {
|
||||
return pk_write_ec_rfc8410_der(&c, buf, key);
|
||||
}
|
||||
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
|
||||
return pk_write_ec_der(&c, buf, key);
|
||||
} else
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Public functions for wrinting private/public PEM keys.
|
||||
******************************************************************************/
|
||||
#if defined(MBEDTLS_PEM_WRITE_C)
|
||||
|
||||
#define PUB_DER_MAX_BYTES \
|
||||
(MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES > MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES ? \
|
||||
MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES : MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES)
|
||||
#define PRV_DER_MAX_BYTES \
|
||||
(MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES > MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES ? \
|
||||
MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES : MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES)
|
||||
|
||||
int mbedtls_pk_write_pubkey_pem(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *output_buf = NULL;
|
||||
output_buf = mbedtls_calloc(1, PUB_DER_MAX_BYTES);
|
||||
if (output_buf == NULL) {
|
||||
return MBEDTLS_ERR_PK_ALLOC_FAILED;
|
||||
}
|
||||
size_t olen = 0;
|
||||
|
||||
if ((ret = mbedtls_pk_write_pubkey_der(key, output_buf,
|
||||
PUB_DER_MAX_BYTES)) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_PUBLIC_KEY "\n", PEM_END_PUBLIC_KEY "\n",
|
||||
output_buf + PUB_DER_MAX_BYTES - ret,
|
||||
ret, buf, size, &olen)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
mbedtls_free(output_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_pk_write_key_pem(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *output_buf = NULL;
|
||||
output_buf = mbedtls_calloc(1, PRV_DER_MAX_BYTES);
|
||||
if (output_buf == NULL) {
|
||||
return MBEDTLS_ERR_PK_ALLOC_FAILED;
|
||||
}
|
||||
const char *begin, *end;
|
||||
size_t olen = 0;
|
||||
|
||||
if ((ret = mbedtls_pk_write_key_der(key, output_buf, PRV_DER_MAX_BYTES)) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
if (pk_get_type_ext(key) == MBEDTLS_PK_RSA) {
|
||||
begin = PEM_BEGIN_PRIVATE_KEY_RSA "\n";
|
||||
end = PEM_END_PRIVATE_KEY_RSA "\n";
|
||||
} else
|
||||
#endif
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) {
|
||||
if (mbedtls_pk_is_rfc8410(key)) {
|
||||
begin = PEM_BEGIN_PRIVATE_KEY_PKCS8 "\n";
|
||||
end = PEM_END_PRIVATE_KEY_PKCS8 "\n";
|
||||
} else {
|
||||
begin = PEM_BEGIN_PRIVATE_KEY_EC "\n";
|
||||
end = PEM_END_PRIVATE_KEY_EC "\n";
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
{
|
||||
ret = MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_pem_write_buffer(begin, end,
|
||||
output_buf + PRV_DER_MAX_BYTES - ret,
|
||||
ret, buf, size, &olen)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
mbedtls_zeroize_and_free(output_buf, PRV_DER_MAX_BYTES);
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_PEM_WRITE_C */
|
||||
|
||||
#endif /* MBEDTLS_PK_WRITE_C */
|
||||
121
Libs/util/third_party/mbedtls/library/pkwrite.h
vendored
Normal file
121
Libs/util/third_party/mbedtls/library/pkwrite.h
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* \file pkwrite.h
|
||||
*
|
||||
* \brief Internal defines shared by the PK write module
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_PK_WRITE_H
|
||||
#define MBEDTLS_PK_WRITE_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "mbedtls/pk.h"
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
/*
|
||||
* Max sizes of key per types. Shown as tag + len (+ content).
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
/*
|
||||
* RSA public keys:
|
||||
* SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3
|
||||
* algorithm AlgorithmIdentifier, 1 + 1 (sequence)
|
||||
* + 1 + 1 + 9 (rsa oid)
|
||||
* + 1 + 1 (params null)
|
||||
* subjectPublicKey BIT STRING } 1 + 3 + (1 + below)
|
||||
* RSAPublicKey ::= SEQUENCE { 1 + 3
|
||||
* modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1
|
||||
* publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1
|
||||
* }
|
||||
*/
|
||||
#define MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES (38 + 2 * MBEDTLS_MPI_MAX_SIZE)
|
||||
|
||||
/*
|
||||
* RSA private keys:
|
||||
* RSAPrivateKey ::= SEQUENCE { 1 + 3
|
||||
* version Version, 1 + 1 + 1
|
||||
* modulus INTEGER, 1 + 3 + MPI_MAX + 1
|
||||
* publicExponent INTEGER, 1 + 3 + MPI_MAX + 1
|
||||
* privateExponent INTEGER, 1 + 3 + MPI_MAX + 1
|
||||
* prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
|
||||
* prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
|
||||
* exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
|
||||
* exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
|
||||
* coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1
|
||||
* otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported)
|
||||
* }
|
||||
*/
|
||||
#define MBEDTLS_MPI_MAX_SIZE_2 (MBEDTLS_MPI_MAX_SIZE / 2 + \
|
||||
MBEDTLS_MPI_MAX_SIZE % 2)
|
||||
#define MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES (47 + 3 * MBEDTLS_MPI_MAX_SIZE \
|
||||
+ 5 * MBEDTLS_MPI_MAX_SIZE_2)
|
||||
|
||||
#else /* MBEDTLS_RSA_C */
|
||||
|
||||
#define MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES 0
|
||||
#define MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES 0
|
||||
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
|
||||
/* Find the maximum number of bytes necessary to store an EC point. When USE_PSA
|
||||
* is defined this means looking for the maximum between PSA and built-in
|
||||
* supported curves. */
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#define MBEDTLS_PK_MAX_ECC_BYTES (PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \
|
||||
MBEDTLS_ECP_MAX_BYTES ? \
|
||||
PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) : \
|
||||
MBEDTLS_ECP_MAX_BYTES)
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
#define MBEDTLS_PK_MAX_ECC_BYTES MBEDTLS_ECP_MAX_BYTES
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
/*
|
||||
* EC public keys:
|
||||
* SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2
|
||||
* algorithm AlgorithmIdentifier, 1 + 1 (sequence)
|
||||
* + 1 + 1 + 7 (ec oid)
|
||||
* + 1 + 1 + 9 (namedCurve oid)
|
||||
* subjectPublicKey BIT STRING 1 + 2 + 1 [1]
|
||||
* + 1 (point format) [1]
|
||||
* + 2 * ECP_MAX (coords) [1]
|
||||
* }
|
||||
*/
|
||||
#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_PK_MAX_ECC_BYTES)
|
||||
|
||||
/*
|
||||
* EC private keys:
|
||||
* ECPrivateKey ::= SEQUENCE { 1 + 2
|
||||
* version INTEGER , 1 + 1 + 1
|
||||
* privateKey OCTET STRING, 1 + 1 + ECP_MAX
|
||||
* parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9)
|
||||
* publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above
|
||||
* }
|
||||
*/
|
||||
#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES (29 + 3 * MBEDTLS_PK_MAX_ECC_BYTES)
|
||||
|
||||
#else /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
|
||||
#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES 0
|
||||
#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES 0
|
||||
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
|
||||
/* Define the maximum available public key DER length based on the supported
|
||||
* key types (EC and/or RSA). */
|
||||
#if (MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES > MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES)
|
||||
#define MBEDTLS_PK_WRITE_PUBKEY_MAX_SIZE MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES
|
||||
#else
|
||||
#define MBEDTLS_PK_WRITE_PUBKEY_MAX_SIZE MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_PK_WRITE_H */
|
||||
402
Libs/util/third_party/mbedtls/library/platform.c
vendored
Normal file
402
Libs/util/third_party/mbedtls/library/platform.c
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
* Platform abstraction layer
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
/* The compile time configuration of memory allocation via the macros
|
||||
* MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime
|
||||
* configuration via mbedtls_platform_set_calloc_free(). So, omit everything
|
||||
* related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */
|
||||
#if defined(MBEDTLS_PLATFORM_MEMORY) && \
|
||||
!(defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \
|
||||
defined(MBEDTLS_PLATFORM_FREE_MACRO))
|
||||
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
|
||||
static void *platform_calloc_uninit(size_t n, size_t size)
|
||||
{
|
||||
((void) n);
|
||||
((void) size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit
|
||||
#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */
|
||||
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_FREE)
|
||||
static void platform_free_uninit(void *ptr)
|
||||
{
|
||||
((void) ptr);
|
||||
}
|
||||
|
||||
#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit
|
||||
#endif /* !MBEDTLS_PLATFORM_STD_FREE */
|
||||
|
||||
static void * (*mbedtls_calloc_func)(size_t, size_t) = MBEDTLS_PLATFORM_STD_CALLOC;
|
||||
static void (*mbedtls_free_func)(void *) = MBEDTLS_PLATFORM_STD_FREE;
|
||||
|
||||
void *mbedtls_calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
return (*mbedtls_calloc_func)(nmemb, size);
|
||||
}
|
||||
|
||||
void mbedtls_free(void *ptr)
|
||||
{
|
||||
(*mbedtls_free_func)(ptr);
|
||||
}
|
||||
|
||||
int mbedtls_platform_set_calloc_free(void *(*calloc_func)(size_t, size_t),
|
||||
void (*free_func)(void *))
|
||||
{
|
||||
mbedtls_calloc_func = calloc_func;
|
||||
mbedtls_free_func = free_func;
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_MEMORY &&
|
||||
!( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&
|
||||
defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
|
||||
#include <stdarg.h>
|
||||
int mbedtls_platform_win32_snprintf(char *s, size_t n, const char *fmt, ...)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
va_list argp;
|
||||
|
||||
va_start(argp, fmt);
|
||||
ret = mbedtls_vsnprintf(s, n, fmt, argp);
|
||||
va_end(argp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
|
||||
/*
|
||||
* Make dummy function to prevent NULL pointer dereferences
|
||||
*/
|
||||
static int platform_snprintf_uninit(char *s, size_t n,
|
||||
const char *format, ...)
|
||||
{
|
||||
((void) s);
|
||||
((void) n);
|
||||
((void) format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit
|
||||
#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */
|
||||
|
||||
int (*mbedtls_snprintf)(char *s, size_t n,
|
||||
const char *format,
|
||||
...) = MBEDTLS_PLATFORM_STD_SNPRINTF;
|
||||
|
||||
int mbedtls_platform_set_snprintf(int (*snprintf_func)(char *s, size_t n,
|
||||
const char *format,
|
||||
...))
|
||||
{
|
||||
mbedtls_snprintf = snprintf_func;
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
|
||||
#include <stdarg.h>
|
||||
int mbedtls_platform_win32_vsnprintf(char *s, size_t n, const char *fmt, va_list arg)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* Avoid calling the invalid parameter handler by checking ourselves */
|
||||
if (s == NULL || n == 0 || fmt == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(_TRUNCATE)
|
||||
ret = vsnprintf_s(s, n, _TRUNCATE, fmt, arg);
|
||||
#else
|
||||
ret = vsnprintf(s, n, fmt, arg);
|
||||
if (ret < 0 || (size_t) ret == n) {
|
||||
s[n-1] = '\0';
|
||||
ret = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
|
||||
/*
|
||||
* Make dummy function to prevent NULL pointer dereferences
|
||||
*/
|
||||
static int platform_vsnprintf_uninit(char *s, size_t n,
|
||||
const char *format, va_list arg)
|
||||
{
|
||||
((void) s);
|
||||
((void) n);
|
||||
((void) format);
|
||||
((void) arg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define MBEDTLS_PLATFORM_STD_VSNPRINTF platform_vsnprintf_uninit
|
||||
#endif /* !MBEDTLS_PLATFORM_STD_VSNPRINTF */
|
||||
|
||||
int (*mbedtls_vsnprintf)(char *s, size_t n,
|
||||
const char *format,
|
||||
va_list arg) = MBEDTLS_PLATFORM_STD_VSNPRINTF;
|
||||
|
||||
int mbedtls_platform_set_vsnprintf(int (*vsnprintf_func)(char *s, size_t n,
|
||||
const char *format,
|
||||
va_list arg))
|
||||
{
|
||||
mbedtls_vsnprintf = vsnprintf_func;
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
|
||||
/*
|
||||
* Make dummy function to prevent NULL pointer dereferences
|
||||
*/
|
||||
static int platform_printf_uninit(const char *format, ...)
|
||||
{
|
||||
((void) format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit
|
||||
#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */
|
||||
|
||||
int (*mbedtls_printf)(const char *, ...) = MBEDTLS_PLATFORM_STD_PRINTF;
|
||||
|
||||
int mbedtls_platform_set_printf(int (*printf_func)(const char *, ...))
|
||||
{
|
||||
mbedtls_printf = printf_func;
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
|
||||
/*
|
||||
* Make dummy function to prevent NULL pointer dereferences
|
||||
*/
|
||||
static int platform_fprintf_uninit(FILE *stream, const char *format, ...)
|
||||
{
|
||||
((void) stream);
|
||||
((void) format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit
|
||||
#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */
|
||||
|
||||
int (*mbedtls_fprintf)(FILE *, const char *, ...) =
|
||||
MBEDTLS_PLATFORM_STD_FPRINTF;
|
||||
|
||||
int mbedtls_platform_set_fprintf(int (*fprintf_func)(FILE *, const char *, ...))
|
||||
{
|
||||
mbedtls_fprintf = fprintf_func;
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_SETBUF_ALT)
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_SETBUF)
|
||||
/*
|
||||
* Make dummy function to prevent NULL pointer dereferences
|
||||
*/
|
||||
static void platform_setbuf_uninit(FILE *stream, char *buf)
|
||||
{
|
||||
((void) stream);
|
||||
((void) buf);
|
||||
}
|
||||
|
||||
#define MBEDTLS_PLATFORM_STD_SETBUF platform_setbuf_uninit
|
||||
#endif /* !MBEDTLS_PLATFORM_STD_SETBUF */
|
||||
void (*mbedtls_setbuf)(FILE *stream, char *buf) = MBEDTLS_PLATFORM_STD_SETBUF;
|
||||
|
||||
int mbedtls_platform_set_setbuf(void (*setbuf_func)(FILE *stream, char *buf))
|
||||
{
|
||||
mbedtls_setbuf = setbuf_func;
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_SETBUF_ALT */
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_EXIT)
|
||||
/*
|
||||
* Make dummy function to prevent NULL pointer dereferences
|
||||
*/
|
||||
static void platform_exit_uninit(int status)
|
||||
{
|
||||
((void) status);
|
||||
}
|
||||
|
||||
#define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit
|
||||
#endif /* !MBEDTLS_PLATFORM_STD_EXIT */
|
||||
|
||||
void (*mbedtls_exit)(int status) = MBEDTLS_PLATFORM_STD_EXIT;
|
||||
|
||||
int mbedtls_platform_set_exit(void (*exit_func)(int status))
|
||||
{
|
||||
mbedtls_exit = exit_func;
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_EXIT_ALT */
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_TIME_ALT)
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_TIME)
|
||||
/*
|
||||
* Make dummy function to prevent NULL pointer dereferences
|
||||
*/
|
||||
static mbedtls_time_t platform_time_uninit(mbedtls_time_t *timer)
|
||||
{
|
||||
((void) timer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit
|
||||
#endif /* !MBEDTLS_PLATFORM_STD_TIME */
|
||||
|
||||
mbedtls_time_t (*mbedtls_time)(mbedtls_time_t *timer) = MBEDTLS_PLATFORM_STD_TIME;
|
||||
|
||||
int mbedtls_platform_set_time(mbedtls_time_t (*time_func)(mbedtls_time_t *timer))
|
||||
{
|
||||
mbedtls_time = time_func;
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_TIME_ALT */
|
||||
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
|
||||
/* Default implementations for the platform independent seed functions use
|
||||
* standard libc file functions to read from and write to a pre-defined filename
|
||||
*/
|
||||
int mbedtls_platform_std_nv_seed_read(unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
FILE *file;
|
||||
size_t n;
|
||||
|
||||
if ((file = fopen(MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb")) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
|
||||
mbedtls_setbuf(file, NULL);
|
||||
|
||||
if ((n = fread(buf, 1, buf_len, file)) != buf_len) {
|
||||
fclose(file);
|
||||
mbedtls_platform_zeroize(buf, buf_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return (int) n;
|
||||
}
|
||||
|
||||
int mbedtls_platform_std_nv_seed_write(unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
FILE *file;
|
||||
size_t n;
|
||||
|
||||
if ((file = fopen(MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w")) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
|
||||
mbedtls_setbuf(file, NULL);
|
||||
|
||||
if ((n = fwrite(buf, 1, buf_len, file)) != buf_len) {
|
||||
fclose(file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return (int) n;
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
|
||||
/*
|
||||
* Make dummy function to prevent NULL pointer dereferences
|
||||
*/
|
||||
static int platform_nv_seed_read_uninit(unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
((void) buf);
|
||||
((void) buf_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit
|
||||
#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */
|
||||
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
|
||||
/*
|
||||
* Make dummy function to prevent NULL pointer dereferences
|
||||
*/
|
||||
static int platform_nv_seed_write_uninit(unsigned char *buf, size_t buf_len)
|
||||
{
|
||||
((void) buf);
|
||||
((void) buf_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit
|
||||
#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */
|
||||
|
||||
int (*mbedtls_nv_seed_read)(unsigned char *buf, size_t buf_len) =
|
||||
MBEDTLS_PLATFORM_STD_NV_SEED_READ;
|
||||
int (*mbedtls_nv_seed_write)(unsigned char *buf, size_t buf_len) =
|
||||
MBEDTLS_PLATFORM_STD_NV_SEED_WRITE;
|
||||
|
||||
int mbedtls_platform_set_nv_seed(
|
||||
int (*nv_seed_read_func)(unsigned char *buf, size_t buf_len),
|
||||
int (*nv_seed_write_func)(unsigned char *buf, size_t buf_len))
|
||||
{
|
||||
mbedtls_nv_seed_read = nv_seed_read_func;
|
||||
mbedtls_nv_seed_write = nv_seed_write_func;
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
|
||||
#endif /* MBEDTLS_ENTROPY_NV_SEED */
|
||||
|
||||
#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT)
|
||||
/*
|
||||
* Placeholder platform setup that does nothing by default
|
||||
*/
|
||||
int mbedtls_platform_setup(mbedtls_platform_context *ctx)
|
||||
{
|
||||
(void) ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Placeholder platform teardown that does nothing by default
|
||||
*/
|
||||
void mbedtls_platform_teardown(mbedtls_platform_context *ctx)
|
||||
{
|
||||
(void) ctx;
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
|
||||
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
263
Libs/util/third_party/mbedtls/library/platform_util.c
vendored
Normal file
263
Libs/util/third_party/mbedtls/library/platform_util.c
vendored
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Common and shared functions used by multiple modules in the Mbed TLS
|
||||
* library.
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ensure gmtime_r is available even with -std=c99; must be defined before
|
||||
* mbedtls_config.h, which pulls in glibc's features.h. Harmless on other platforms
|
||||
* except OpenBSD, where it stops us accessing explicit_bzero.
|
||||
*/
|
||||
#if !defined(_POSIX_C_SOURCE) && !defined(__OpenBSD__)
|
||||
#define _POSIX_C_SOURCE 200112L
|
||||
#endif
|
||||
|
||||
#if !defined(_GNU_SOURCE)
|
||||
/* Clang requires this to get support for explicit_bzero */
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/threading.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef __STDC_WANT_LIB_EXT1__
|
||||
#define __STDC_WANT_LIB_EXT1__ 1 /* Ask for the C11 gmtime_s() and memset_s() if available */
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
// Detect platforms known to support explicit_bzero()
|
||||
#if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)
|
||||
#define MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO 1
|
||||
#elif (defined(__FreeBSD__) && (__FreeBSD_version >= 1100037)) || defined(__OpenBSD__)
|
||||
#define MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO 1
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)
|
||||
|
||||
#undef HAVE_MEMORY_SANITIZER
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(memory_sanitizer)
|
||||
#include <sanitizer/msan_interface.h>
|
||||
#define HAVE_MEMORY_SANITIZER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Where possible, we try to detect the presence of a platform-provided
|
||||
* secure memset, such as explicit_bzero(), that is safe against being optimized
|
||||
* out, and use that.
|
||||
*
|
||||
* For other platforms, we provide an implementation that aims not to be
|
||||
* optimized out by the compiler.
|
||||
*
|
||||
* This implementation for mbedtls_platform_zeroize() was inspired from Colin
|
||||
* Percival's blog article at:
|
||||
*
|
||||
* http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
|
||||
*
|
||||
* It uses a volatile function pointer to the standard memset(). Because the
|
||||
* pointer is volatile the compiler expects it to change at
|
||||
* any time and will not optimize out the call that could potentially perform
|
||||
* other operations on the input buffer instead of just setting it to 0.
|
||||
* Nevertheless, as pointed out by davidtgoldblatt on Hacker News
|
||||
* (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for
|
||||
* details), optimizations of the following form are still possible:
|
||||
*
|
||||
* if (memset_func != memset)
|
||||
* memset_func(buf, 0, len);
|
||||
*
|
||||
* Note that it is extremely difficult to guarantee that
|
||||
* the memset() call will not be optimized out by aggressive compilers
|
||||
* in a portable way. For this reason, Mbed TLS also provides the configuration
|
||||
* option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
|
||||
* mbedtls_platform_zeroize() to use a suitable implementation for their
|
||||
* platform and needs.
|
||||
*/
|
||||
#if !defined(MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO) && !(defined(__STDC_LIB_EXT1__) && \
|
||||
!defined(__IAR_SYSTEMS_ICC__)) \
|
||||
&& !defined(_WIN32)
|
||||
static void *(*const volatile memset_func)(void *, int, size_t) = memset;
|
||||
#endif
|
||||
|
||||
void mbedtls_platform_zeroize(void *buf, size_t len)
|
||||
{
|
||||
if (len > 0) {
|
||||
#if defined(MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO)
|
||||
explicit_bzero(buf, len);
|
||||
#if defined(HAVE_MEMORY_SANITIZER)
|
||||
/* You'd think that Msan would recognize explicit_bzero() as
|
||||
* equivalent to bzero(), but it actually doesn't on several
|
||||
* platforms, including Linux (Ubuntu 20.04).
|
||||
* https://github.com/google/sanitizers/issues/1507
|
||||
* https://github.com/openssh/openssh-portable/commit/74433a19bb6f4cef607680fa4d1d7d81ca3826aa
|
||||
*/
|
||||
__msan_unpoison(buf, len);
|
||||
#endif
|
||||
#elif defined(__STDC_LIB_EXT1__) && !defined(__IAR_SYSTEMS_ICC__)
|
||||
memset_s(buf, len, 0, len);
|
||||
#elif defined(_WIN32)
|
||||
SecureZeroMemory(buf, len);
|
||||
#else
|
||||
memset_func(buf, 0, len);
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/* For clang and recent gcc, pretend that we have some assembly that reads the
|
||||
* zero'd memory as an additional protection against being optimised away. */
|
||||
#if defined(__clang__) || (__GNUC__ >= 10)
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wvla"
|
||||
#elif defined(MBEDTLS_COMPILER_IS_GCC)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wvla"
|
||||
#endif
|
||||
asm volatile ("" : : "m" (*(char (*)[len]) buf) :);
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(MBEDTLS_COMPILER_IS_GCC)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
|
||||
|
||||
void mbedtls_zeroize_and_free(void *buf, size_t len)
|
||||
{
|
||||
if (buf != NULL) {
|
||||
mbedtls_platform_zeroize(buf, len);
|
||||
}
|
||||
|
||||
mbedtls_free(buf);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
|
||||
#include <time.h>
|
||||
#if !defined(_WIN32) && (defined(unix) || \
|
||||
defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
|
||||
defined(__MACH__)) || defined(__midipix__))
|
||||
#include <unistd.h>
|
||||
#endif /* !_WIN32 && (unix || __unix || __unix__ ||
|
||||
* (__APPLE__ && __MACH__) || __midipix__) */
|
||||
|
||||
#if !((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L) || \
|
||||
(defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \
|
||||
_POSIX_THREAD_SAFE_FUNCTIONS >= 200112L))
|
||||
/*
|
||||
* This is a convenience shorthand macro to avoid checking the long
|
||||
* preprocessor conditions above. Ideally, we could expose this macro in
|
||||
* platform_util.h and simply use it in platform_util.c, threading.c and
|
||||
* threading.h. However, this macro is not part of the Mbed TLS public API, so
|
||||
* we keep it private by only defining it in this file
|
||||
*/
|
||||
#if !(defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)) || \
|
||||
(defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
|
||||
#define PLATFORM_UTIL_USE_GMTIME
|
||||
#endif
|
||||
|
||||
#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
|
||||
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
|
||||
_POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */
|
||||
|
||||
struct tm *mbedtls_platform_gmtime_r(const mbedtls_time_t *tt,
|
||||
struct tm *tm_buf)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(PLATFORM_UTIL_USE_GMTIME)
|
||||
#if defined(__STDC_LIB_EXT1__)
|
||||
return (gmtime_s(tt, tm_buf) == 0) ? NULL : tm_buf;
|
||||
#else
|
||||
/* MSVC and mingw64 argument order and return value are inconsistent with the C11 standard */
|
||||
return (gmtime_s(tm_buf, tt) == 0) ? tm_buf : NULL;
|
||||
#endif
|
||||
#elif !defined(PLATFORM_UTIL_USE_GMTIME)
|
||||
return gmtime_r(tt, tm_buf);
|
||||
#else
|
||||
struct tm *lt;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if (mbedtls_mutex_lock(&mbedtls_threading_gmtime_mutex) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
lt = gmtime(tt);
|
||||
|
||||
if (lt != NULL) {
|
||||
memcpy(tm_buf, lt, sizeof(struct tm));
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if (mbedtls_mutex_unlock(&mbedtls_threading_gmtime_mutex) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return (lt == NULL) ? NULL : tm_buf;
|
||||
#endif /* _WIN32 && !EFIX64 && !EFI32 */
|
||||
}
|
||||
#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
void (*mbedtls_test_hook_test_fail)(const char *, int, const char *);
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME) && !defined(MBEDTLS_PLATFORM_MS_TIME_ALT)
|
||||
|
||||
#include <time.h>
|
||||
#if !defined(_WIN32) && \
|
||||
(defined(unix) || defined(__unix) || defined(__unix__) || \
|
||||
(defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__) || defined(__midipix__))
|
||||
#include <unistd.h>
|
||||
#endif \
|
||||
/* !_WIN32 && (unix || __unix || __unix__ || (__APPLE__ && __MACH__) || __HAIKU__ || __midipix__) */
|
||||
#if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 199309L) || defined(__HAIKU__)
|
||||
mbedtls_ms_time_t mbedtls_ms_time(void)
|
||||
{
|
||||
int ret;
|
||||
struct timespec tv;
|
||||
mbedtls_ms_time_t current_ms;
|
||||
|
||||
#if defined(__linux__) && defined(CLOCK_BOOTTIME) || defined(__midipix__)
|
||||
ret = clock_gettime(CLOCK_BOOTTIME, &tv);
|
||||
#else
|
||||
ret = clock_gettime(CLOCK_MONOTONIC, &tv);
|
||||
#endif
|
||||
if (ret) {
|
||||
return time(NULL) * 1000;
|
||||
}
|
||||
|
||||
current_ms = tv.tv_sec;
|
||||
|
||||
return current_ms*1000 + tv.tv_nsec / 1000000;
|
||||
}
|
||||
#elif defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \
|
||||
defined(__MINGW32__) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
mbedtls_ms_time_t mbedtls_ms_time(void)
|
||||
{
|
||||
FILETIME ct;
|
||||
mbedtls_ms_time_t current_ms;
|
||||
|
||||
GetSystemTimeAsFileTime(&ct);
|
||||
current_ms = ((mbedtls_ms_time_t) ct.dwLowDateTime +
|
||||
((mbedtls_ms_time_t) (ct.dwHighDateTime) << 32LL))/10000;
|
||||
return current_ms;
|
||||
}
|
||||
#else
|
||||
#error "No mbedtls_ms_time available"
|
||||
#endif
|
||||
#endif /* MBEDTLS_HAVE_TIME && !MBEDTLS_PLATFORM_MS_TIME_ALT */
|
||||
9503
Libs/util/third_party/mbedtls/library/psa_crypto.c
vendored
Normal file
9503
Libs/util/third_party/mbedtls/library/psa_crypto.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
651
Libs/util/third_party/mbedtls/library/psa_crypto_aead.c
vendored
Normal file
651
Libs/util/third_party/mbedtls/library/psa_crypto_aead.c
vendored
Normal file
@@ -0,0 +1,651 @@
|
||||
/*
|
||||
* PSA AEAD entry points
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include "psa_crypto_aead.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_cipher.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "mbedtls/ccm.h"
|
||||
#include "mbedtls/chachapoly.h"
|
||||
#include "mbedtls/cipher.h"
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
static psa_status_t psa_aead_setup(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_cipher_id_t cipher_id;
|
||||
mbedtls_cipher_mode_t mode;
|
||||
size_t key_bits = attributes->bits;
|
||||
(void) key_buffer_size;
|
||||
|
||||
status = mbedtls_cipher_values_from_psa(alg, attributes->type,
|
||||
&key_bits, &mode, &cipher_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
|
||||
operation->alg = PSA_ALG_CCM;
|
||||
/* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
|
||||
* The call to mbedtls_ccm_encrypt_and_tag or
|
||||
* mbedtls_ccm_auth_decrypt will validate the tag length. */
|
||||
if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
mbedtls_ccm_init(&operation->ctx.ccm);
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_setkey(&operation->ctx.ccm, cipher_id,
|
||||
key_buffer, (unsigned int) key_bits));
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
|
||||
operation->alg = PSA_ALG_GCM;
|
||||
/* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
|
||||
* The call to mbedtls_gcm_crypt_and_tag or
|
||||
* mbedtls_gcm_auth_decrypt will validate the tag length. */
|
||||
if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
mbedtls_gcm_init(&operation->ctx.gcm);
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_setkey(&operation->ctx.gcm, cipher_id,
|
||||
key_buffer, (unsigned int) key_bits));
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
|
||||
operation->alg = PSA_ALG_CHACHA20_POLY1305;
|
||||
/* We only support the default tag length. */
|
||||
if (alg != PSA_ALG_CHACHA20_POLY1305) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
mbedtls_chachapoly_init(&operation->ctx.chachapoly);
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_setkey(&operation->ctx.chachapoly,
|
||||
key_buffer));
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
|
||||
default:
|
||||
(void) status;
|
||||
(void) key_buffer;
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
operation->key_type = psa_get_key_type(attributes);
|
||||
|
||||
operation->tag_length = PSA_ALG_AEAD_GET_TAG_LENGTH(alg);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_aead_encrypt(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *nonce, size_t nonce_length,
|
||||
const uint8_t *additional_data, size_t additional_data_length,
|
||||
const uint8_t *plaintext, size_t plaintext_length,
|
||||
uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT;
|
||||
uint8_t *tag;
|
||||
|
||||
status = psa_aead_setup(&operation, attributes, key_buffer,
|
||||
key_buffer_size, alg);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* For all currently supported modes, the tag is at the end of the
|
||||
* ciphertext. */
|
||||
if (ciphertext_size < (plaintext_length + operation.tag_length)) {
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
goto exit;
|
||||
}
|
||||
tag = ciphertext + plaintext_length;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation.alg == PSA_ALG_CCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_encrypt_and_tag(&operation.ctx.ccm,
|
||||
plaintext_length,
|
||||
nonce, nonce_length,
|
||||
additional_data,
|
||||
additional_data_length,
|
||||
plaintext, ciphertext,
|
||||
tag, operation.tag_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
if (operation.alg == PSA_ALG_GCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_crypt_and_tag(&operation.ctx.gcm,
|
||||
MBEDTLS_GCM_ENCRYPT,
|
||||
plaintext_length,
|
||||
nonce, nonce_length,
|
||||
additional_data, additional_data_length,
|
||||
plaintext, ciphertext,
|
||||
operation.tag_length, tag));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
if (operation.alg == PSA_ALG_CHACHA20_POLY1305) {
|
||||
if (operation.tag_length != 16) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_encrypt_and_tag(&operation.ctx.chachapoly,
|
||||
plaintext_length,
|
||||
nonce,
|
||||
additional_data,
|
||||
additional_data_length,
|
||||
plaintext,
|
||||
ciphertext,
|
||||
tag));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
{
|
||||
(void) tag;
|
||||
(void) nonce;
|
||||
(void) nonce_length;
|
||||
(void) additional_data;
|
||||
(void) additional_data_length;
|
||||
(void) plaintext;
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
*ciphertext_length = plaintext_length + operation.tag_length;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_psa_aead_abort(&operation);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Locate the tag in a ciphertext buffer containing the encrypted data
|
||||
* followed by the tag. Return the length of the part preceding the tag in
|
||||
* *plaintext_length. This is the size of the plaintext in modes where
|
||||
* the encrypted data has the same size as the plaintext, such as
|
||||
* CCM and GCM. */
|
||||
static psa_status_t psa_aead_unpadded_locate_tag(size_t tag_length,
|
||||
const uint8_t *ciphertext,
|
||||
size_t ciphertext_length,
|
||||
size_t plaintext_size,
|
||||
const uint8_t **p_tag)
|
||||
{
|
||||
size_t payload_length;
|
||||
if (tag_length > ciphertext_length) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
payload_length = ciphertext_length - tag_length;
|
||||
if (payload_length > plaintext_size) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
*p_tag = ciphertext + payload_length;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_aead_decrypt(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *nonce, size_t nonce_length,
|
||||
const uint8_t *additional_data, size_t additional_data_length,
|
||||
const uint8_t *ciphertext, size_t ciphertext_length,
|
||||
uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT;
|
||||
const uint8_t *tag = NULL;
|
||||
|
||||
status = psa_aead_setup(&operation, attributes, key_buffer,
|
||||
key_buffer_size, alg);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_aead_unpadded_locate_tag(operation.tag_length,
|
||||
ciphertext, ciphertext_length,
|
||||
plaintext_size, &tag);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation.alg == PSA_ALG_CCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_auth_decrypt(&operation.ctx.ccm,
|
||||
ciphertext_length - operation.tag_length,
|
||||
nonce, nonce_length,
|
||||
additional_data,
|
||||
additional_data_length,
|
||||
ciphertext, plaintext,
|
||||
tag, operation.tag_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
if (operation.alg == PSA_ALG_GCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_auth_decrypt(&operation.ctx.gcm,
|
||||
ciphertext_length - operation.tag_length,
|
||||
nonce, nonce_length,
|
||||
additional_data,
|
||||
additional_data_length,
|
||||
tag, operation.tag_length,
|
||||
ciphertext, plaintext));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
if (operation.alg == PSA_ALG_CHACHA20_POLY1305) {
|
||||
if (operation.tag_length != 16) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_auth_decrypt(&operation.ctx.chachapoly,
|
||||
ciphertext_length - operation.tag_length,
|
||||
nonce,
|
||||
additional_data,
|
||||
additional_data_length,
|
||||
tag,
|
||||
ciphertext,
|
||||
plaintext));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
{
|
||||
(void) nonce;
|
||||
(void) nonce_length;
|
||||
(void) additional_data;
|
||||
(void) additional_data_length;
|
||||
(void) plaintext;
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
*plaintext_length = ciphertext_length - operation.tag_length;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_psa_aead_abort(&operation);
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
*plaintext_length = ciphertext_length - operation.tag_length;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Set the key and algorithm for a multipart authenticated encryption
|
||||
* operation. */
|
||||
psa_status_t mbedtls_psa_aead_encrypt_setup(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
status = psa_aead_setup(operation, attributes, key_buffer,
|
||||
key_buffer_size, alg);
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
operation->is_encrypt = 1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Set the key and algorithm for a multipart authenticated decryption
|
||||
* operation. */
|
||||
psa_status_t mbedtls_psa_aead_decrypt_setup(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
status = psa_aead_setup(operation, attributes, key_buffer,
|
||||
key_buffer_size, alg);
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
operation->is_encrypt = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Set a nonce for the multipart AEAD operation*/
|
||||
psa_status_t mbedtls_psa_aead_set_nonce(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const uint8_t *nonce,
|
||||
size_t nonce_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
if (operation->alg == PSA_ALG_GCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_starts(&operation->ctx.gcm,
|
||||
operation->is_encrypt ?
|
||||
MBEDTLS_GCM_ENCRYPT : MBEDTLS_GCM_DECRYPT,
|
||||
nonce,
|
||||
nonce_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation->alg == PSA_ALG_CCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_starts(&operation->ctx.ccm,
|
||||
operation->is_encrypt ?
|
||||
MBEDTLS_CCM_ENCRYPT : MBEDTLS_CCM_DECRYPT,
|
||||
nonce,
|
||||
nonce_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
|
||||
/* Note - ChaChaPoly allows an 8 byte nonce, but we would have to
|
||||
* allocate a buffer in the operation, copy the nonce to it and pad
|
||||
* it, so for now check the nonce is 12 bytes, as
|
||||
* mbedtls_chachapoly_starts() assumes it can read 12 bytes from the
|
||||
* passed in buffer. */
|
||||
if (nonce_length != 12) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_starts(&operation->ctx.chachapoly,
|
||||
nonce,
|
||||
operation->is_encrypt ?
|
||||
MBEDTLS_CHACHAPOLY_ENCRYPT :
|
||||
MBEDTLS_CHACHAPOLY_DECRYPT));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
{
|
||||
(void) operation;
|
||||
(void) nonce;
|
||||
(void) nonce_length;
|
||||
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Declare the lengths of the message and additional data for AEAD. */
|
||||
psa_status_t mbedtls_psa_aead_set_lengths(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
size_t ad_length,
|
||||
size_t plaintext_length)
|
||||
{
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation->alg == PSA_ALG_CCM) {
|
||||
return mbedtls_to_psa_error(
|
||||
mbedtls_ccm_set_lengths(&operation->ctx.ccm,
|
||||
ad_length,
|
||||
plaintext_length,
|
||||
operation->tag_length));
|
||||
|
||||
}
|
||||
#else /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
(void) operation;
|
||||
(void) ad_length;
|
||||
(void) plaintext_length;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/* Pass additional data to an active multipart AEAD operation. */
|
||||
psa_status_t mbedtls_psa_aead_update_ad(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
if (operation->alg == PSA_ALG_GCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_update_ad(&operation->ctx.gcm, input, input_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation->alg == PSA_ALG_CCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_update_ad(&operation->ctx.ccm, input, input_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_update_aad(&operation->ctx.chachapoly,
|
||||
input,
|
||||
input_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
{
|
||||
(void) operation;
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Encrypt or decrypt a message fragment in an active multipart AEAD
|
||||
* operation.*/
|
||||
psa_status_t mbedtls_psa_aead_update(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
size_t update_output_length;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
update_output_length = input_length;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
if (operation->alg == PSA_ALG_GCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_update(&operation->ctx.gcm,
|
||||
input, input_length,
|
||||
output, output_size,
|
||||
&update_output_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation->alg == PSA_ALG_CCM) {
|
||||
if (output_size < input_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_update(&operation->ctx.ccm,
|
||||
input, input_length,
|
||||
output, output_size,
|
||||
&update_output_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
|
||||
if (output_size < input_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_update(&operation->ctx.chachapoly,
|
||||
input_length,
|
||||
input,
|
||||
output));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
{
|
||||
(void) operation;
|
||||
(void) input;
|
||||
(void) output;
|
||||
(void) output_size;
|
||||
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
*output_length = update_output_length;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Finish encrypting a message in a multipart AEAD operation. */
|
||||
psa_status_t mbedtls_psa_aead_finish(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
uint8_t *ciphertext,
|
||||
size_t ciphertext_size,
|
||||
size_t *ciphertext_length,
|
||||
uint8_t *tag,
|
||||
size_t tag_size,
|
||||
size_t *tag_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t finish_output_size = 0;
|
||||
|
||||
if (tag_size < operation->tag_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
if (operation->alg == PSA_ALG_GCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_finish(&operation->ctx.gcm,
|
||||
ciphertext, ciphertext_size, ciphertext_length,
|
||||
tag, operation->tag_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation->alg == PSA_ALG_CCM) {
|
||||
/* tag must be big enough to store a tag of size passed into set
|
||||
* lengths. */
|
||||
if (tag_size < operation->tag_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_finish(&operation->ctx.ccm,
|
||||
tag, operation->tag_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
|
||||
/* Belt and braces. Although the above tag_size check should have
|
||||
* already done this, if we later start supporting smaller tag sizes
|
||||
* for chachapoly, then passing a tag buffer smaller than 16 into here
|
||||
* could cause a buffer overflow, so better safe than sorry. */
|
||||
if (tag_size < 16) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_finish(&operation->ctx.chachapoly,
|
||||
tag));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
{
|
||||
(void) ciphertext;
|
||||
(void) ciphertext_size;
|
||||
(void) ciphertext_length;
|
||||
(void) tag;
|
||||
(void) tag_size;
|
||||
(void) tag_length;
|
||||
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
/* This will be zero for all supported algorithms currently, but left
|
||||
* here for future support. */
|
||||
*ciphertext_length = finish_output_size;
|
||||
*tag_length = operation->tag_length;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Abort an AEAD operation */
|
||||
psa_status_t mbedtls_psa_aead_abort(
|
||||
mbedtls_psa_aead_operation_t *operation)
|
||||
{
|
||||
switch (operation->alg) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
case PSA_ALG_CCM:
|
||||
mbedtls_ccm_free(&operation->ctx.ccm);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
case PSA_ALG_GCM:
|
||||
mbedtls_gcm_free(&operation->ctx.gcm);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
case PSA_ALG_CHACHA20_POLY1305:
|
||||
mbedtls_chachapoly_free(&operation->ctx.chachapoly);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
}
|
||||
|
||||
operation->is_encrypt = 0;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
499
Libs/util/third_party/mbedtls/library/psa_crypto_aead.h
vendored
Normal file
499
Libs/util/third_party/mbedtls/library/psa_crypto_aead.h
vendored
Normal file
@@ -0,0 +1,499 @@
|
||||
/*
|
||||
* PSA AEAD driver entry points
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_AEAD_H
|
||||
#define PSA_CRYPTO_AEAD_H
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
/**
|
||||
* \brief Process an authenticated encryption operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* aead_encrypt entry point. This function behaves as an aead_encrypt
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the key context.
|
||||
* \param key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param alg The AEAD algorithm to compute.
|
||||
* \param[in] nonce Nonce or IV to use.
|
||||
* \param nonce_length Size of the nonce buffer in bytes. This must
|
||||
* be appropriate for the selected algorithm.
|
||||
* The default nonce size is
|
||||
* PSA_AEAD_NONCE_LENGTH(key_type, alg) where
|
||||
* key_type is the type of key.
|
||||
* \param[in] additional_data Additional data that will be authenticated
|
||||
* but not encrypted.
|
||||
* \param additional_data_length Size of additional_data in bytes.
|
||||
* \param[in] plaintext Data that will be authenticated and encrypted.
|
||||
* \param plaintext_length Size of plaintext in bytes.
|
||||
* \param[out] ciphertext Output buffer for the authenticated and
|
||||
* encrypted data. The additional data is not
|
||||
* part of this output. For algorithms where the
|
||||
* encrypted data and the authentication tag are
|
||||
* defined as separate outputs, the
|
||||
* authentication tag is appended to the
|
||||
* encrypted data.
|
||||
* \param ciphertext_size Size of the ciphertext buffer in bytes. This
|
||||
* must be appropriate for the selected algorithm
|
||||
* and key:
|
||||
* - A sufficient output size is
|
||||
* PSA_AEAD_ENCRYPT_OUTPUT_SIZE(key_type, alg,
|
||||
* plaintext_length) where key_type is the type
|
||||
* of key.
|
||||
* - PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(
|
||||
* plaintext_length) evaluates to the maximum
|
||||
* ciphertext size of any supported AEAD
|
||||
* encryption.
|
||||
* \param[out] ciphertext_length On success, the size of the output in the
|
||||
* ciphertext buffer.
|
||||
*
|
||||
* \retval #PSA_SUCCESS Success.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \p alg is not supported.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* ciphertext_size is too small.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_aead_encrypt(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *nonce, size_t nonce_length,
|
||||
const uint8_t *additional_data, size_t additional_data_length,
|
||||
const uint8_t *plaintext, size_t plaintext_length,
|
||||
uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length);
|
||||
|
||||
/**
|
||||
* \brief Process an authenticated decryption operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* aead_decrypt entry point. This function behaves as an aead_decrypt
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the key context.
|
||||
* \param key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param alg The AEAD algorithm to compute.
|
||||
* \param[in] nonce Nonce or IV to use.
|
||||
* \param nonce_length Size of the nonce buffer in bytes. This must
|
||||
* be appropriate for the selected algorithm.
|
||||
* The default nonce size is
|
||||
* PSA_AEAD_NONCE_LENGTH(key_type, alg) where
|
||||
* key_type is the type of key.
|
||||
* \param[in] additional_data Additional data that has been authenticated
|
||||
* but not encrypted.
|
||||
* \param additional_data_length Size of additional_data in bytes.
|
||||
* \param[in] ciphertext Data that has been authenticated and
|
||||
* encrypted. For algorithms where the encrypted
|
||||
* data and the authentication tag are defined
|
||||
* as separate inputs, the buffer contains
|
||||
* encrypted data followed by the authentication
|
||||
* tag.
|
||||
* \param ciphertext_length Size of ciphertext in bytes.
|
||||
* \param[out] plaintext Output buffer for the decrypted data.
|
||||
* \param plaintext_size Size of the plaintext buffer in bytes. This
|
||||
* must be appropriate for the selected algorithm
|
||||
* and key:
|
||||
* - A sufficient output size is
|
||||
* PSA_AEAD_DECRYPT_OUTPUT_SIZE(key_type, alg,
|
||||
* ciphertext_length) where key_type is the
|
||||
* type of key.
|
||||
* - PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(
|
||||
* ciphertext_length) evaluates to the maximum
|
||||
* plaintext size of any supported AEAD
|
||||
* decryption.
|
||||
* \param[out] plaintext_length On success, the size of the output in the
|
||||
* plaintext buffer.
|
||||
*
|
||||
* \retval #PSA_SUCCESS Success.
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
* The cipher is not authentic.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \p alg is not supported.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* plaintext_size is too small.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_aead_decrypt(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *nonce, size_t nonce_length,
|
||||
const uint8_t *additional_data, size_t additional_data_length,
|
||||
const uint8_t *ciphertext, size_t ciphertext_length,
|
||||
uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length);
|
||||
|
||||
/** Set the key for a multipart authenticated encryption operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* aead_encrypt_setup entry point. This function behaves as an
|
||||
* aead_encrypt_setup entry point as defined in the PSA driver interface
|
||||
* specification for transparent drivers.
|
||||
*
|
||||
* If an error occurs at any step after a call to
|
||||
* mbedtls_psa_aead_encrypt_setup(), the operation is reset by the PSA core by a
|
||||
* call to mbedtls_psa_aead_abort(). The PSA core may call
|
||||
* mbedtls_psa_aead_abort() at any time after the operation has been
|
||||
* initialized, and is required to when the operation is no longer needed.
|
||||
*
|
||||
* \param[in,out] operation The operation object to set up. It must have
|
||||
* been initialized as per the documentation for
|
||||
* #mbedtls_psa_aead_operation_t and not yet in
|
||||
* use.
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the key context.
|
||||
* \param key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
It must be consistent with the size in bits
|
||||
recorded in \p attributes.
|
||||
* \param alg The AEAD algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_AEAD(\p alg) is true).
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* An invalid block length was supplied.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \p alg is not supported.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* Failed to allocate memory for key material
|
||||
*/
|
||||
psa_status_t mbedtls_psa_aead_encrypt_setup(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
/** Set the key for a multipart authenticated decryption operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* aead_decrypt_setup entry point. This function behaves as an
|
||||
* aead_decrypt_setup entry point as defined in the PSA driver interface
|
||||
* specification for transparent drivers.
|
||||
*
|
||||
* If an error occurs at any step after a call to
|
||||
* mbedtls_psa_aead_decrypt_setup(), the PSA core resets the operation by a
|
||||
* call to mbedtls_psa_aead_abort(). The PSA core may call
|
||||
* mbedtls_psa_aead_abort() at any time after the operation has been
|
||||
* initialized, and is required to when the operation is no longer needed.
|
||||
*
|
||||
* \param[in,out] operation The operation object to set up. It must have
|
||||
* been initialized as per the documentation for
|
||||
* #mbedtls_psa_aead_operation_t and not yet in
|
||||
* use.
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the key context.
|
||||
* \param key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
It must be consistent with the size in bits
|
||||
recorded in \p attributes.
|
||||
* \param alg The AEAD algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_AEAD(\p alg) is true).
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* An invalid block length was supplied.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \p alg is not supported.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* Failed to allocate memory for key material
|
||||
*/
|
||||
psa_status_t mbedtls_psa_aead_decrypt_setup(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
/** Set the nonce for an authenticated encryption or decryption operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver aead_set_nonce
|
||||
* entry point. This function behaves as an aead_set_nonce entry point as
|
||||
* defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* This function sets the nonce for the authenticated
|
||||
* encryption or decryption operation.
|
||||
*
|
||||
* The PSA core calls mbedtls_psa_aead_encrypt_setup() or
|
||||
* mbedtls_psa_aead_decrypt_setup() before calling this function.
|
||||
*
|
||||
* If this function returns an error status, the PSA core will call
|
||||
* mbedtls_psa_aead_abort().
|
||||
*
|
||||
* \param[in,out] operation Active AEAD operation.
|
||||
* \param[in] nonce Buffer containing the nonce to use.
|
||||
* \param nonce_length Size of the nonce in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The size of \p nonce is not acceptable for the chosen algorithm.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* Algorithm previously set is not supported in this configuration of
|
||||
* the library.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_aead_set_nonce(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const uint8_t *nonce,
|
||||
size_t nonce_length);
|
||||
|
||||
/** Declare the lengths of the message and additional data for AEAD.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver aead_set_lengths
|
||||
* entry point. This function behaves as an aead_set_lengths entry point
|
||||
* as defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* The PSA core calls this function before calling mbedtls_psa_aead_update_ad()
|
||||
* or mbedtls_psa_aead_update() if the algorithm for the operation requires it.
|
||||
* If the algorithm does not require it, calling this function is optional, but
|
||||
* if this function is called then the implementation must enforce the lengths.
|
||||
*
|
||||
* The PSA core may call this function before or after setting the nonce with
|
||||
* mbedtls_psa_aead_set_nonce().
|
||||
*
|
||||
* - For #PSA_ALG_CCM, calling this function is required.
|
||||
* - For the other AEAD algorithms defined in this specification, calling
|
||||
* this function is not required.
|
||||
*
|
||||
* If this function returns an error status, the PSA core calls
|
||||
* mbedtls_psa_aead_abort().
|
||||
*
|
||||
* \param[in,out] operation Active AEAD operation.
|
||||
* \param ad_length Size of the non-encrypted additional
|
||||
* authenticated data in bytes.
|
||||
* \param plaintext_length Size of the plaintext to encrypt in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* At least one of the lengths is not acceptable for the chosen
|
||||
* algorithm.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* Algorithm previously set is not supported in this configuration of
|
||||
* the library.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_aead_set_lengths(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
size_t ad_length,
|
||||
size_t plaintext_length);
|
||||
|
||||
/** Pass additional data to an active AEAD operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* aead_update_ad entry point. This function behaves as an aead_update_ad
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* Additional data is authenticated, but not encrypted.
|
||||
*
|
||||
* The PSA core can call this function multiple times to pass successive
|
||||
* fragments of the additional data. It will not call this function after
|
||||
* passing data to encrypt or decrypt with mbedtls_psa_aead_update().
|
||||
*
|
||||
* Before calling this function, the PSA core will:
|
||||
* 1. Call either mbedtls_psa_aead_encrypt_setup() or
|
||||
* mbedtls_psa_aead_decrypt_setup().
|
||||
* 2. Set the nonce with mbedtls_psa_aead_set_nonce().
|
||||
*
|
||||
* If this function returns an error status, the PSA core will call
|
||||
* mbedtls_psa_aead_abort().
|
||||
*
|
||||
* \param[in,out] operation Active AEAD operation.
|
||||
* \param[in] input Buffer containing the fragment of
|
||||
* additional data.
|
||||
* \param input_length Size of the \p input buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* Algorithm previously set is not supported in this configuration of
|
||||
* the library.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_aead_update_ad(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length);
|
||||
|
||||
/** Encrypt or decrypt a message fragment in an active AEAD operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* aead_update entry point. This function behaves as an aead_update entry
|
||||
* point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* Before calling this function, the PSA core will:
|
||||
* 1. Call either mbedtls_psa_aead_encrypt_setup() or
|
||||
* mbedtls_psa_aead_decrypt_setup(). The choice of setup function
|
||||
* determines whether this function encrypts or decrypts its input.
|
||||
* 2. Set the nonce with mbedtls_psa_aead_set_nonce().
|
||||
* 3. Call mbedtls_psa_aead_update_ad() to pass all the additional data.
|
||||
*
|
||||
* If this function returns an error status, the PSA core will call
|
||||
* mbedtls_psa_aead_abort().
|
||||
*
|
||||
* This function does not require the input to be aligned to any
|
||||
* particular block boundary. If the implementation can only process
|
||||
* a whole block at a time, it must consume all the input provided, but
|
||||
* it may delay the end of the corresponding output until a subsequent
|
||||
* call to mbedtls_psa_aead_update(), mbedtls_psa_aead_finish() provides
|
||||
* sufficient input. The amount of data that can be delayed in this way is
|
||||
* bounded by #PSA_AEAD_UPDATE_OUTPUT_SIZE.
|
||||
*
|
||||
* \param[in,out] operation Active AEAD operation.
|
||||
* \param[in] input Buffer containing the message fragment to
|
||||
* encrypt or decrypt.
|
||||
* \param input_length Size of the \p input buffer in bytes.
|
||||
* \param[out] output Buffer where the output is to be written.
|
||||
* \param output_size Size of the \p output buffer in bytes.
|
||||
* This must be appropriate for the selected
|
||||
* algorithm and key:
|
||||
* - A sufficient output size is
|
||||
* #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type,
|
||||
* \c alg, \p input_length) where
|
||||
* \c key_type is the type of key and \c alg is
|
||||
* the algorithm that were used to set up the
|
||||
* operation.
|
||||
* - #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p
|
||||
* input_length) evaluates to the maximum
|
||||
* output size of any supported AEAD
|
||||
* algorithm.
|
||||
* \param[out] output_length On success, the number of bytes
|
||||
* that make up the returned output.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
*
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p output buffer is too small.
|
||||
* #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, \c alg, \p input_length) or
|
||||
* #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length) can be used to
|
||||
* determine the required buffer size.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_aead_update(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
/** Finish encrypting a message in an AEAD operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* aead_finish entry point. This function behaves as an aead_finish entry
|
||||
* point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* The operation must have been set up by the PSA core with
|
||||
* mbedtls_psa_aead_encrypt_setup().
|
||||
*
|
||||
* This function finishes the authentication of the additional data
|
||||
* formed by concatenating the inputs passed to preceding calls to
|
||||
* mbedtls_psa_aead_update_ad() with the plaintext formed by concatenating the
|
||||
* inputs passed to preceding calls to mbedtls_psa_aead_update().
|
||||
*
|
||||
* This function has two output buffers:
|
||||
* - \p ciphertext contains trailing ciphertext that was buffered from
|
||||
* preceding calls to mbedtls_psa_aead_update().
|
||||
* - \p tag contains the authentication tag.
|
||||
*
|
||||
* Whether or not this function returns successfully, the PSA core subsequently
|
||||
* calls mbedtls_psa_aead_abort() to deactivate the operation.
|
||||
*
|
||||
* \param[in,out] operation Active AEAD operation.
|
||||
* \param[out] ciphertext Buffer where the last part of the ciphertext
|
||||
* is to be written.
|
||||
* \param ciphertext_size Size of the \p ciphertext buffer in bytes.
|
||||
* This must be appropriate for the selected
|
||||
* algorithm and key:
|
||||
* - A sufficient output size is
|
||||
* #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type,
|
||||
* \c alg) where \c key_type is the type of key
|
||||
* and \c alg is the algorithm that were used to
|
||||
* set up the operation.
|
||||
* - #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE evaluates to
|
||||
* the maximum output size of any supported AEAD
|
||||
* algorithm.
|
||||
* \param[out] ciphertext_length On success, the number of bytes of
|
||||
* returned ciphertext.
|
||||
* \param[out] tag Buffer where the authentication tag is
|
||||
* to be written.
|
||||
* \param tag_size Size of the \p tag buffer in bytes.
|
||||
* This must be appropriate for the selected
|
||||
* algorithm and key:
|
||||
* - The exact tag size is #PSA_AEAD_TAG_LENGTH(\c
|
||||
* key_type, \c key_bits, \c alg) where
|
||||
* \c key_type and \c key_bits are the type and
|
||||
* bit-size of the key, and \c alg are the
|
||||
* algorithm that were used in the call to
|
||||
* mbedtls_psa_aead_encrypt_setup().
|
||||
* - #PSA_AEAD_TAG_MAX_SIZE evaluates to the
|
||||
* maximum tag size of any supported AEAD
|
||||
* algorithm.
|
||||
* \param[out] tag_length On success, the number of bytes
|
||||
* that make up the returned tag.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p tag buffer is too small.
|
||||
* #PSA_AEAD_TAG_LENGTH(\c key_type, key_bits, \c alg) or
|
||||
* #PSA_AEAD_TAG_MAX_SIZE can be used to determine the required \p tag
|
||||
* buffer size.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_aead_finish(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
uint8_t *ciphertext,
|
||||
size_t ciphertext_size,
|
||||
size_t *ciphertext_length,
|
||||
uint8_t *tag,
|
||||
size_t tag_size,
|
||||
size_t *tag_length);
|
||||
|
||||
/** Abort an AEAD operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* aead_abort entry point. This function behaves as an aead_abort entry
|
||||
* point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* Aborting an operation frees all associated resources except for the
|
||||
* \p operation structure itself. Once aborted, the operation object
|
||||
* can be reused for another operation by the PSA core by it calling
|
||||
* mbedtls_psa_aead_encrypt_setup() or mbedtls_psa_aead_decrypt_setup() again.
|
||||
*
|
||||
* The PSA core may call this function any time after the operation object has
|
||||
* been initialized as described in #mbedtls_psa_aead_operation_t.
|
||||
*
|
||||
* In particular, calling mbedtls_psa_aead_abort() after the operation has been
|
||||
* terminated by a call to mbedtls_psa_aead_abort() or
|
||||
* mbedtls_psa_aead_finish() is safe and has no effect.
|
||||
*
|
||||
* \param[in,out] operation Initialized AEAD operation.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_aead_abort(
|
||||
mbedtls_psa_aead_operation_t *operation);
|
||||
|
||||
#endif /* PSA_CRYPTO_AEAD_H */
|
||||
748
Libs/util/third_party/mbedtls/library/psa_crypto_cipher.c
vendored
Normal file
748
Libs/util/third_party/mbedtls/library/psa_crypto_cipher.c
vendored
Normal file
@@ -0,0 +1,748 @@
|
||||
/*
|
||||
* PSA cipher driver entry points
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include "psa_crypto_cipher.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_random_impl.h"
|
||||
|
||||
#include "mbedtls/cipher.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* mbedtls_cipher_values_from_psa() below only checks if the proper build symbols
|
||||
* are enabled, but it does not provide any compatibility check between them
|
||||
* (i.e. if the specified key works with the specified algorithm). This helper
|
||||
* function is meant to provide this support.
|
||||
* mbedtls_cipher_info_from_psa() might be used for the same purpose, but it
|
||||
* requires CIPHER_C to be enabled.
|
||||
*/
|
||||
static psa_status_t mbedtls_cipher_validate_values(
|
||||
psa_algorithm_t alg,
|
||||
psa_key_type_t key_type)
|
||||
{
|
||||
/* Reduce code size - hinting to the compiler about what it can assume allows the compiler to
|
||||
eliminate bits of the logic below. */
|
||||
#if !defined(PSA_WANT_KEY_TYPE_AES)
|
||||
MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_AES);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_KEY_TYPE_ARIA)
|
||||
MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_ARIA);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_KEY_TYPE_CAMELLIA)
|
||||
MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CAMELLIA);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_KEY_TYPE_CHACHA20)
|
||||
MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CHACHA20);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_KEY_TYPE_DES)
|
||||
MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_DES);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CCM)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0));
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_GCM)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0));
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_STREAM_CIPHER)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_STREAM_CIPHER);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CHACHA20_POLY1305)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0));
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_CCM_STAR_NO_TAG);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CTR)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_CTR);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CFB)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_CFB);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_OFB)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_OFB);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_XTS)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_XTS);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_ECB_NO_PADDING)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_ECB_NO_PADDING);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_CBC_NO_PADDING);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CBC_PKCS7)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_CBC_PKCS7);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CMAC)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_CMAC);
|
||||
#endif
|
||||
|
||||
if (alg == PSA_ALG_STREAM_CIPHER ||
|
||||
alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) {
|
||||
if (key_type == PSA_KEY_TYPE_CHACHA20) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) ||
|
||||
alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) ||
|
||||
alg == PSA_ALG_CCM_STAR_NO_TAG) {
|
||||
if (key_type == PSA_KEY_TYPE_AES ||
|
||||
key_type == PSA_KEY_TYPE_ARIA ||
|
||||
key_type == PSA_KEY_TYPE_CAMELLIA) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (alg == PSA_ALG_CTR ||
|
||||
alg == PSA_ALG_CFB ||
|
||||
alg == PSA_ALG_OFB ||
|
||||
alg == PSA_ALG_XTS ||
|
||||
alg == PSA_ALG_ECB_NO_PADDING ||
|
||||
alg == PSA_ALG_CBC_NO_PADDING ||
|
||||
alg == PSA_ALG_CBC_PKCS7 ||
|
||||
alg == PSA_ALG_CMAC) {
|
||||
if (key_type == PSA_KEY_TYPE_AES ||
|
||||
key_type == PSA_KEY_TYPE_ARIA ||
|
||||
key_type == PSA_KEY_TYPE_DES ||
|
||||
key_type == PSA_KEY_TYPE_CAMELLIA) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_cipher_values_from_psa(
|
||||
psa_algorithm_t alg,
|
||||
psa_key_type_t key_type,
|
||||
size_t *key_bits,
|
||||
mbedtls_cipher_mode_t *mode,
|
||||
mbedtls_cipher_id_t *cipher_id)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
mbedtls_cipher_id_t cipher_id_tmp;
|
||||
/* Only DES modifies key_bits */
|
||||
#if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
|
||||
(void) key_bits;
|
||||
#endif
|
||||
|
||||
if (PSA_ALG_IS_AEAD(alg)) {
|
||||
alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
|
||||
}
|
||||
|
||||
if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
|
||||
switch (alg) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
|
||||
case PSA_ALG_STREAM_CIPHER:
|
||||
*mode = MBEDTLS_MODE_STREAM;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
|
||||
case PSA_ALG_CTR:
|
||||
*mode = MBEDTLS_MODE_CTR;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
|
||||
case PSA_ALG_CFB:
|
||||
*mode = MBEDTLS_MODE_CFB;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
|
||||
case PSA_ALG_OFB:
|
||||
*mode = MBEDTLS_MODE_OFB;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
|
||||
case PSA_ALG_ECB_NO_PADDING:
|
||||
*mode = MBEDTLS_MODE_ECB;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
|
||||
case PSA_ALG_CBC_NO_PADDING:
|
||||
*mode = MBEDTLS_MODE_CBC;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
|
||||
case PSA_ALG_CBC_PKCS7:
|
||||
*mode = MBEDTLS_MODE_CBC;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
|
||||
case PSA_ALG_CCM_STAR_NO_TAG:
|
||||
*mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
|
||||
*mode = MBEDTLS_MODE_CCM;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
|
||||
*mode = MBEDTLS_MODE_GCM;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
|
||||
*mode = MBEDTLS_MODE_CHACHAPOLY;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
} else if (alg == PSA_ALG_CMAC) {
|
||||
*mode = MBEDTLS_MODE_ECB;
|
||||
} else {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (key_type) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
|
||||
case PSA_KEY_TYPE_AES:
|
||||
cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
|
||||
case PSA_KEY_TYPE_ARIA:
|
||||
cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
|
||||
case PSA_KEY_TYPE_DES:
|
||||
/* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
|
||||
* and 192 for three-key Triple-DES. */
|
||||
if (*key_bits == 64) {
|
||||
cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
|
||||
} else {
|
||||
cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
|
||||
}
|
||||
/* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
|
||||
* but two-key Triple-DES is functionally three-key Triple-DES
|
||||
* with K1=K3, so that's how we present it to mbedtls. */
|
||||
if (*key_bits == 128) {
|
||||
*key_bits = 192;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
|
||||
case PSA_KEY_TYPE_CAMELLIA:
|
||||
cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
|
||||
case PSA_KEY_TYPE_CHACHA20:
|
||||
cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (cipher_id != NULL) {
|
||||
*cipher_id = cipher_id_tmp;
|
||||
}
|
||||
|
||||
return mbedtls_cipher_validate_values(alg, key_type);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_C)
|
||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
|
||||
psa_algorithm_t alg,
|
||||
psa_key_type_t key_type,
|
||||
size_t key_bits,
|
||||
mbedtls_cipher_id_t *cipher_id)
|
||||
{
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
|
||||
|
||||
mbedtls_cipher_mode_t mode;
|
||||
psa_status_t status;
|
||||
mbedtls_cipher_id_t cipher_id_tmp = MBEDTLS_CIPHER_ID_NONE;
|
||||
|
||||
status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
if (cipher_id != NULL) {
|
||||
*cipher_id = cipher_id_tmp;
|
||||
}
|
||||
|
||||
return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode);
|
||||
#else
|
||||
(void) alg;
|
||||
(void) key_type;
|
||||
(void) key_bits;
|
||||
(void) cipher_id;
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_C */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
|
||||
|
||||
static psa_status_t psa_cipher_setup(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
mbedtls_operation_t cipher_operation)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t key_bits;
|
||||
const mbedtls_cipher_info_t *cipher_info = NULL;
|
||||
psa_key_type_t key_type = attributes->type;
|
||||
|
||||
(void) key_buffer_size;
|
||||
|
||||
mbedtls_cipher_init(&operation->ctx.cipher);
|
||||
|
||||
operation->alg = alg;
|
||||
key_bits = attributes->bits;
|
||||
cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
|
||||
key_bits, NULL);
|
||||
if (cipher_info == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
|
||||
if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
|
||||
/* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
|
||||
uint8_t keys[24];
|
||||
memcpy(keys, key_buffer, 16);
|
||||
memcpy(keys + 16, key_buffer, 8);
|
||||
ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
|
||||
keys,
|
||||
192, cipher_operation);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
|
||||
(int) key_bits, cipher_operation);
|
||||
}
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
|
||||
switch (alg) {
|
||||
case PSA_ALG_CBC_NO_PADDING:
|
||||
ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
|
||||
MBEDTLS_PADDING_NONE);
|
||||
break;
|
||||
case PSA_ALG_CBC_PKCS7:
|
||||
ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
|
||||
MBEDTLS_PADDING_PKCS7);
|
||||
break;
|
||||
default:
|
||||
/* The algorithm doesn't involve padding. */
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
|
||||
MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
|
||||
|
||||
operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
|
||||
PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
|
||||
operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
|
||||
|
||||
exit:
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_encrypt_setup(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
return psa_cipher_setup(operation, attributes,
|
||||
key_buffer, key_buffer_size,
|
||||
alg, MBEDTLS_ENCRYPT);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_decrypt_setup(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
return psa_cipher_setup(operation, attributes,
|
||||
key_buffer, key_buffer_size,
|
||||
alg, MBEDTLS_DECRYPT);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_set_iv(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const uint8_t *iv, size_t iv_length)
|
||||
{
|
||||
if (iv_length != operation->iv_length) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return mbedtls_to_psa_error(
|
||||
mbedtls_cipher_set_iv(&operation->ctx.cipher,
|
||||
iv, iv_length));
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
|
||||
/** Process input for which the algorithm is set to ECB mode.
|
||||
*
|
||||
* This requires manual processing, since the PSA API is defined as being
|
||||
* able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
|
||||
* but the underlying mbedtls_cipher_update only takes full blocks.
|
||||
*
|
||||
* \param ctx The mbedtls cipher context to use. It must have been
|
||||
* set up for ECB.
|
||||
* \param[in] input The input plaintext or ciphertext to process.
|
||||
* \param input_length The number of bytes to process from \p input.
|
||||
* This does not need to be aligned to a block boundary.
|
||||
* If there is a partial block at the end of the input,
|
||||
* it is stored in \p ctx for future processing.
|
||||
* \param output The buffer where the output is written. It must be
|
||||
* at least `BS * floor((p + input_length) / BS)` bytes
|
||||
* long, where `p` is the number of bytes in the
|
||||
* unprocessed partial block in \p ctx (with
|
||||
* `0 <= p <= BS - 1`) and `BS` is the block size.
|
||||
* \param output_length On success, the number of bytes written to \p output.
|
||||
* \c 0 on error.
|
||||
*
|
||||
* \return #PSA_SUCCESS or an error from a hardware accelerator
|
||||
*/
|
||||
static psa_status_t psa_cipher_update_ecb(
|
||||
mbedtls_cipher_context_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
|
||||
size_t internal_output_length = 0;
|
||||
*output_length = 0;
|
||||
|
||||
if (input_length == 0) {
|
||||
status = PSA_SUCCESS;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ctx->unprocessed_len > 0) {
|
||||
/* Fill up to block size, and run the block if there's a full one. */
|
||||
size_t bytes_to_copy = block_size - ctx->unprocessed_len;
|
||||
|
||||
if (input_length < bytes_to_copy) {
|
||||
bytes_to_copy = input_length;
|
||||
}
|
||||
|
||||
memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
|
||||
input, bytes_to_copy);
|
||||
input_length -= bytes_to_copy;
|
||||
input += bytes_to_copy;
|
||||
ctx->unprocessed_len += bytes_to_copy;
|
||||
|
||||
if (ctx->unprocessed_len == block_size) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_cipher_update(ctx,
|
||||
ctx->unprocessed_data,
|
||||
block_size,
|
||||
output, &internal_output_length));
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
output += internal_output_length;
|
||||
*output_length += internal_output_length;
|
||||
ctx->unprocessed_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (input_length >= block_size) {
|
||||
/* Run all full blocks we have, one by one */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_cipher_update(ctx, input,
|
||||
block_size,
|
||||
output, &internal_output_length));
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
input_length -= block_size;
|
||||
input += block_size;
|
||||
|
||||
output += internal_output_length;
|
||||
*output_length += internal_output_length;
|
||||
}
|
||||
|
||||
if (input_length > 0) {
|
||||
/* Save unprocessed bytes for later processing */
|
||||
memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
|
||||
input, input_length);
|
||||
ctx->unprocessed_len += input_length;
|
||||
}
|
||||
|
||||
status = PSA_SUCCESS;
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_update(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const uint8_t *input, size_t input_length,
|
||||
uint8_t *output, size_t output_size, size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t expected_output_size;
|
||||
|
||||
if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
|
||||
/* Take the unprocessed partial block left over from previous
|
||||
* update calls, if any, plus the input to this call. Remove
|
||||
* the last partial block, if any. You get the data that will be
|
||||
* output in this call. */
|
||||
expected_output_size =
|
||||
(operation->ctx.cipher.unprocessed_len + input_length)
|
||||
/ operation->block_length * operation->block_length;
|
||||
} else {
|
||||
expected_output_size = input_length;
|
||||
}
|
||||
|
||||
if (output_size < expected_output_size) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
|
||||
if (operation->alg == PSA_ALG_ECB_NO_PADDING) {
|
||||
/* mbedtls_cipher_update has an API inconsistency: it will only
|
||||
* process a single block at a time in ECB mode. Abstract away that
|
||||
* inconsistency here to match the PSA API behaviour. */
|
||||
status = psa_cipher_update_ecb(&operation->ctx.cipher,
|
||||
input,
|
||||
input_length,
|
||||
output,
|
||||
output_length);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
|
||||
if (input_length == 0) {
|
||||
/* There is no input, nothing to be done */
|
||||
*output_length = 0;
|
||||
status = PSA_SUCCESS;
|
||||
} else {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_cipher_update(&operation->ctx.cipher, input,
|
||||
input_length, output, output_length));
|
||||
|
||||
if (*output_length > output_size) {
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_finish(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
uint8_t *output, size_t output_size, size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
|
||||
uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
|
||||
|
||||
if (operation->ctx.cipher.unprocessed_len != 0) {
|
||||
if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
|
||||
operation->alg == PSA_ALG_CBC_NO_PADDING) {
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_cipher_finish(&operation->ctx.cipher,
|
||||
temp_output_buffer,
|
||||
output_length));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (*output_length == 0) {
|
||||
; /* Nothing to copy. Note that output may be NULL in this case. */
|
||||
} else if (output_size >= *output_length) {
|
||||
memcpy(output, temp_output_buffer, *output_length);
|
||||
} else {
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(temp_output_buffer,
|
||||
sizeof(temp_output_buffer));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_abort(
|
||||
mbedtls_psa_cipher_operation_t *operation)
|
||||
{
|
||||
/* Sanity check (shouldn't happen: operation->alg should
|
||||
* always have been initialized to a valid value). */
|
||||
if (!PSA_ALG_IS_CIPHER(operation->alg)) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
mbedtls_cipher_free(&operation->ctx.cipher);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_encrypt(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *iv,
|
||||
size_t iv_length,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
|
||||
size_t update_output_length, finish_output_length;
|
||||
|
||||
status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
|
||||
key_buffer, key_buffer_size,
|
||||
alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (iv_length > 0) {
|
||||
status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
status = mbedtls_psa_cipher_update(&operation, input, input_length,
|
||||
output, output_size,
|
||||
&update_output_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = mbedtls_psa_cipher_finish(
|
||||
&operation,
|
||||
mbedtls_buffer_offset(output, update_output_length),
|
||||
output_size - update_output_length, &finish_output_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*output_length = update_output_length + finish_output_length;
|
||||
|
||||
exit:
|
||||
if (status == PSA_SUCCESS) {
|
||||
status = mbedtls_psa_cipher_abort(&operation);
|
||||
} else {
|
||||
mbedtls_psa_cipher_abort(&operation);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_decrypt(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
|
||||
size_t olength, accumulated_length;
|
||||
|
||||
status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
|
||||
key_buffer, key_buffer_size,
|
||||
alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (operation.iv_length > 0) {
|
||||
status = mbedtls_psa_cipher_set_iv(&operation,
|
||||
input, operation.iv_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
status = mbedtls_psa_cipher_update(
|
||||
&operation,
|
||||
mbedtls_buffer_offset_const(input, operation.iv_length),
|
||||
input_length - operation.iv_length,
|
||||
output, output_size, &olength);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
accumulated_length = olength;
|
||||
|
||||
status = mbedtls_psa_cipher_finish(
|
||||
&operation,
|
||||
mbedtls_buffer_offset(output, accumulated_length),
|
||||
output_size - accumulated_length, &olength);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*output_length = accumulated_length + olength;
|
||||
|
||||
exit:
|
||||
if (status == PSA_SUCCESS) {
|
||||
status = mbedtls_psa_cipher_abort(&operation);
|
||||
} else {
|
||||
mbedtls_psa_cipher_abort(&operation);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
316
Libs/util/third_party/mbedtls/library/psa_crypto_cipher.h
vendored
Normal file
316
Libs/util/third_party/mbedtls/library/psa_crypto_cipher.h
vendored
Normal file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* PSA cipher driver entry points and associated auxiliary functions
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_CIPHER_H
|
||||
#define PSA_CRYPTO_CIPHER_H
|
||||
|
||||
#include <mbedtls/cipher.h>
|
||||
#include <psa/crypto.h>
|
||||
|
||||
/** Get Mbed TLS cipher information given the cipher algorithm PSA identifier
|
||||
* as well as the PSA type and size of the key to be used with the cipher
|
||||
* algorithm.
|
||||
*
|
||||
* \param[in] alg PSA cipher algorithm identifier
|
||||
* \param[in] key_type PSA key type
|
||||
* \param[in,out] key_bits Size of the key in bits. The value provided in input
|
||||
* might be updated if necessary.
|
||||
* \param[out] mode Mbed TLS cipher mode
|
||||
* \param[out] cipher_id Mbed TLS cipher algorithm identifier
|
||||
*
|
||||
* \return On success \c PSA_SUCCESS is returned and key_bits, mode and cipher_id
|
||||
* are properly updated.
|
||||
* \c PSA_ERROR_NOT_SUPPORTED is returned if the cipher algorithm is not
|
||||
* supported.
|
||||
*/
|
||||
|
||||
psa_status_t mbedtls_cipher_values_from_psa(psa_algorithm_t alg, psa_key_type_t key_type,
|
||||
size_t *key_bits, mbedtls_cipher_mode_t *mode,
|
||||
mbedtls_cipher_id_t *cipher_id);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_C)
|
||||
/** Get Mbed TLS cipher information given the cipher algorithm PSA identifier
|
||||
* as well as the PSA type and size of the key to be used with the cipher
|
||||
* algorithm.
|
||||
*
|
||||
* \param alg PSA cipher algorithm identifier
|
||||
* \param key_type PSA key type
|
||||
* \param key_bits Size of the key in bits
|
||||
* \param[out] cipher_id Mbed TLS cipher algorithm identifier
|
||||
*
|
||||
* \return The Mbed TLS cipher information of the cipher algorithm.
|
||||
* \c NULL if the PSA cipher algorithm is not supported.
|
||||
*/
|
||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
|
||||
psa_algorithm_t alg, psa_key_type_t key_type, size_t key_bits,
|
||||
mbedtls_cipher_id_t *cipher_id);
|
||||
#endif /* MBEDTLS_CIPHER_C */
|
||||
|
||||
/**
|
||||
* \brief Set the key for a multipart symmetric encryption operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* cipher_encrypt_setup entry point. This function behaves as a
|
||||
* cipher_encrypt_setup entry point as defined in the PSA driver
|
||||
* interface specification for transparent drivers.
|
||||
*
|
||||
* \param[in,out] operation The operation object to set up. It has been
|
||||
* initialized as per the documentation for
|
||||
* #psa_cipher_operation_t and not yet in use.
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the key context.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg The cipher algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_CIPHER(\p alg) is true).
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_cipher_encrypt_setup(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
/**
|
||||
* \brief Set the key for a multipart symmetric decryption operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* cipher_decrypt_setup entry point. This function behaves as a
|
||||
* cipher_decrypt_setup entry point as defined in the PSA driver
|
||||
* interface specification for transparent drivers.
|
||||
*
|
||||
* \param[in,out] operation The operation object to set up. It has been
|
||||
* initialized as per the documentation for
|
||||
* #psa_cipher_operation_t and not yet in use.
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the key context.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg The cipher algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_CIPHER(\p alg) is true).
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_cipher_decrypt_setup(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
/** Set the IV for a symmetric encryption or decryption operation.
|
||||
*
|
||||
* This function sets the IV (initialization vector), nonce
|
||||
* or initial counter value for the encryption or decryption operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* cipher_set_iv entry point. This function behaves as a
|
||||
* cipher_set_iv entry point as defined in the PSA driver
|
||||
* interface specification for transparent drivers.
|
||||
*
|
||||
* \param[in,out] operation Active cipher operation.
|
||||
* \param[in] iv Buffer containing the IV to use.
|
||||
* \param[in] iv_length Size of the IV in bytes. It is guaranteed by
|
||||
* the core to be less or equal to
|
||||
* PSA_CIPHER_IV_MAX_SIZE.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The size of \p iv is not acceptable for the chosen algorithm,
|
||||
* or the chosen algorithm does not use an IV.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_cipher_set_iv(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const uint8_t *iv, size_t iv_length);
|
||||
|
||||
/** Encrypt or decrypt a message fragment in an active cipher operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* cipher_update entry point. This function behaves as a
|
||||
* cipher_update entry point as defined in the PSA driver
|
||||
* interface specification for transparent drivers.
|
||||
*
|
||||
* \param[in,out] operation Active cipher operation.
|
||||
* \param[in] input Buffer containing the message fragment to
|
||||
* encrypt or decrypt.
|
||||
* \param[in] input_length Size of the \p input buffer in bytes.
|
||||
* \param[out] output Buffer where the output is to be written.
|
||||
* \param[in] output_size Size of the \p output buffer in bytes.
|
||||
* \param[out] output_length On success, the number of bytes
|
||||
* that make up the returned output.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p output buffer is too small.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_cipher_update(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const uint8_t *input, size_t input_length,
|
||||
uint8_t *output, size_t output_size, size_t *output_length);
|
||||
|
||||
/** Finish encrypting or decrypting a message in a cipher operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* cipher_finish entry point. This function behaves as a
|
||||
* cipher_finish entry point as defined in the PSA driver
|
||||
* interface specification for transparent drivers.
|
||||
*
|
||||
* \param[in,out] operation Active cipher operation.
|
||||
* \param[out] output Buffer where the output is to be written.
|
||||
* \param[in] output_size Size of the \p output buffer in bytes.
|
||||
* \param[out] output_length On success, the number of bytes
|
||||
* that make up the returned output.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The total input size passed to this operation is not valid for
|
||||
* this particular algorithm. For example, the algorithm is a based
|
||||
* on block cipher and requires a whole number of blocks, but the
|
||||
* total input size is not a multiple of the block size.
|
||||
* \retval #PSA_ERROR_INVALID_PADDING
|
||||
* This is a decryption operation for an algorithm that includes
|
||||
* padding, and the ciphertext does not contain valid padding.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p output buffer is too small.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_cipher_finish(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
uint8_t *output, size_t output_size, size_t *output_length);
|
||||
|
||||
/** Abort a cipher operation.
|
||||
*
|
||||
* Aborting an operation frees all associated resources except for the
|
||||
* \p operation structure itself. Once aborted, the operation object
|
||||
* can be reused for another operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* cipher_abort entry point. This function behaves as a
|
||||
* cipher_abort entry point as defined in the PSA driver
|
||||
* interface specification for transparent drivers.
|
||||
*
|
||||
* \param[in,out] operation Initialized cipher operation.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_cipher_abort(mbedtls_psa_cipher_operation_t *operation);
|
||||
|
||||
/** Encrypt a message using a symmetric cipher.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* cipher_encrypt entry point. This function behaves as a
|
||||
* cipher_encrypt entry point as defined in the PSA driver
|
||||
* interface specification for transparent drivers.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the key context.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg The cipher algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_CIPHER(\p alg) is true).
|
||||
* \param[in] iv Buffer containing the IV for encryption. The
|
||||
* IV has been generated by the core.
|
||||
* \param[in] iv_length Size of the \p iv in bytes.
|
||||
* \param[in] input Buffer containing the message to encrypt.
|
||||
* \param[in] input_length Size of the \p input buffer in bytes.
|
||||
* \param[in,out] output Buffer where the output is to be written.
|
||||
* \param[in] output_size Size of the \p output buffer in bytes.
|
||||
* \param[out] output_length On success, the number of bytes that make up
|
||||
* the returned output. Initialized to zero
|
||||
* by the core.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p output buffer is too small.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The size \p iv_length is not acceptable for the chosen algorithm,
|
||||
* or the chosen algorithm does not use an IV.
|
||||
* The total input size passed to this operation is not valid for
|
||||
* this particular algorithm. For example, the algorithm is a based
|
||||
* on block cipher and requires a whole number of blocks, but the
|
||||
* total input size is not a multiple of the block size.
|
||||
* \retval #PSA_ERROR_INVALID_PADDING
|
||||
* This is a decryption operation for an algorithm that includes
|
||||
* padding, and the ciphertext does not contain valid padding.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_cipher_encrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *iv,
|
||||
size_t iv_length,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
/** Decrypt a message using a symmetric cipher.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* cipher_decrypt entry point. This function behaves as a
|
||||
* cipher_decrypt entry point as defined in the PSA driver
|
||||
* interface specification for transparent drivers.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the key context.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg The cipher algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_CIPHER(\p alg) is true).
|
||||
* \param[in] input Buffer containing the iv and the ciphertext.
|
||||
* \param[in] input_length Size of the \p input buffer in bytes.
|
||||
* \param[out] output Buffer where the output is to be written.
|
||||
* \param[in] output_size Size of the \p output buffer in bytes.
|
||||
* \param[out] output_length On success, the number of bytes that make up
|
||||
* the returned output. Initialized to zero
|
||||
* by the core.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p output buffer is too small.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The size of \p iv is not acceptable for the chosen algorithm,
|
||||
* or the chosen algorithm does not use an IV.
|
||||
* The total input size passed to this operation is not valid for
|
||||
* this particular algorithm. For example, the algorithm is a based
|
||||
* on block cipher and requires a whole number of blocks, but the
|
||||
* total input size is not a multiple of the block size.
|
||||
* \retval #PSA_ERROR_INVALID_PADDING
|
||||
* This is a decryption operation for an algorithm that includes
|
||||
* padding, and the ciphertext does not contain valid padding.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_cipher_decrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
#endif /* PSA_CRYPTO_CIPHER_H */
|
||||
22
Libs/util/third_party/mbedtls/library/psa_crypto_client.c
vendored
Normal file
22
Libs/util/third_party/mbedtls/library/psa_crypto_client.c
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* PSA crypto client code
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
void psa_reset_key_attributes(psa_key_attributes_t *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(*attributes));
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
1003
Libs/util/third_party/mbedtls/library/psa_crypto_core.h
vendored
Normal file
1003
Libs/util/third_party/mbedtls/library/psa_crypto_core.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
52
Libs/util/third_party/mbedtls/library/psa_crypto_core_common.h
vendored
Normal file
52
Libs/util/third_party/mbedtls/library/psa_crypto_core_common.h
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* \file psa_crypto_core_common.h
|
||||
*
|
||||
* \brief Utility macros for internal use in the PSA cryptography core.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_CORE_COMMON_H
|
||||
#define PSA_CRYPTO_CORE_COMMON_H
|
||||
|
||||
/** Return an offset into a buffer.
|
||||
*
|
||||
* This is just the addition of an offset to a pointer, except that this
|
||||
* function also accepts an offset of 0 into a buffer whose pointer is null.
|
||||
* (`p + n` has undefined behavior when `p` is null, even when `n == 0`.
|
||||
* A null pointer is a valid buffer pointer when the size is 0, for example
|
||||
* as the result of `malloc(0)` on some platforms.)
|
||||
*
|
||||
* \param p Pointer to a buffer of at least n bytes.
|
||||
* This may be \p NULL if \p n is zero.
|
||||
* \param n An offset in bytes.
|
||||
* \return Pointer to offset \p n in the buffer \p p.
|
||||
* Note that this is only a valid pointer if the size of the
|
||||
* buffer is at least \p n + 1.
|
||||
*/
|
||||
static inline unsigned char *psa_crypto_buffer_offset(
|
||||
unsigned char *p, size_t n)
|
||||
{
|
||||
return p == NULL ? NULL : p + n;
|
||||
}
|
||||
|
||||
/** Return an offset into a read-only buffer.
|
||||
*
|
||||
* Similar to mbedtls_buffer_offset(), but for const pointers.
|
||||
*
|
||||
* \param p Pointer to a buffer of at least n bytes.
|
||||
* This may be \p NULL if \p n is zero.
|
||||
* \param n An offset in bytes.
|
||||
* \return Pointer to offset \p n in the buffer \p p.
|
||||
* Note that this is only a valid pointer if the size of the
|
||||
* buffer is at least \p n + 1.
|
||||
*/
|
||||
static inline const unsigned char *psa_crypto_buffer_offset_const(
|
||||
const unsigned char *p, size_t n)
|
||||
{
|
||||
return p == NULL ? NULL : p + n;
|
||||
}
|
||||
|
||||
#endif /* PSA_CRYPTO_CORE_COMMON_H */
|
||||
5062
Libs/util/third_party/mbedtls/library/psa_crypto_driver_wrappers.h
vendored
Normal file
5062
Libs/util/third_party/mbedtls/library/psa_crypto_driver_wrappers.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
422
Libs/util/third_party/mbedtls/library/psa_crypto_driver_wrappers_no_static.c
vendored
Normal file
422
Libs/util/third_party/mbedtls/library/psa_crypto_driver_wrappers_no_static.c
vendored
Normal file
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Functions to delegate cryptographic operations to an available
|
||||
* and appropriate accelerator.
|
||||
* Warning: This file is now auto-generated.
|
||||
*/
|
||||
/* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
|
||||
/* BEGIN-common headers */
|
||||
#include "common.h"
|
||||
#include "psa_crypto_aead.h"
|
||||
#include "psa_crypto_cipher.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_driver_wrappers_no_static.h"
|
||||
#include "psa_crypto_hash.h"
|
||||
#include "psa_crypto_mac.h"
|
||||
#include "psa_crypto_pake.h"
|
||||
#include "psa_crypto_rsa.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
/* END-common headers */
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
/* BEGIN-driver headers */
|
||||
/* Headers for mbedtls_test opaque driver */
|
||||
#if defined(PSA_CRYPTO_DRIVER_TEST)
|
||||
#include "test/drivers/test_driver.h"
|
||||
|
||||
#endif
|
||||
/* Headers for mbedtls_test transparent driver */
|
||||
#if defined(PSA_CRYPTO_DRIVER_TEST)
|
||||
#include "test/drivers/test_driver.h"
|
||||
|
||||
#endif
|
||||
/* Headers for p256 transparent driver */
|
||||
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
|
||||
#include "../3rdparty/p256-m/p256-m_driver_entrypoints.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* SiLabs Driver Headers */
|
||||
#include "sli_psa_driver_features.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(SLI_MBEDTLS_DEVICE_HSE)
|
||||
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#endif
|
||||
#include "sli_se_transparent_types.h"
|
||||
#include "sli_se_transparent_functions.h"
|
||||
#endif
|
||||
|
||||
#if defined(SLI_MBEDTLS_DEVICE_HSE) && defined(SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS)
|
||||
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#endif
|
||||
#include "sli_se_opaque_types.h"
|
||||
#include "sli_se_opaque_functions.h"
|
||||
#endif /* SLI_MBEDTLS_DEVICE_HSE && SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS */
|
||||
|
||||
#if defined(SLI_MBEDTLS_DEVICE_VSE)
|
||||
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#endif
|
||||
#include "sli_cryptoacc_transparent_types.h"
|
||||
#include "sli_cryptoacc_transparent_functions.h"
|
||||
#if defined(SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS)
|
||||
#include "sli_cryptoacc_opaque_types.h"
|
||||
#include "sli_cryptoacc_opaque_functions.h"
|
||||
#endif /* SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS */
|
||||
#endif
|
||||
|
||||
#if defined(SLI_MBEDTLS_DEVICE_S1)
|
||||
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#endif
|
||||
#include "sli_crypto_transparent_types.h"
|
||||
#include "sli_crypto_transparent_functions.h"
|
||||
#endif
|
||||
|
||||
#if defined(SLI_MBEDTLS_DEVICE_SI91X)
|
||||
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#endif
|
||||
#include "sli_si91x_crypto_driver_functions.h"
|
||||
#endif
|
||||
|
||||
#ifdef SLI_SECURE_KEY_STORAGE_DEVICE_SI91X
|
||||
#include "sl_si91x_psa_wrap.h"
|
||||
#endif /* Secure key storage driver **/
|
||||
|
||||
/* END-driver headers */
|
||||
|
||||
/* Auto-generated values depending on which drivers are registered.
|
||||
* ID 0 is reserved for unallocated operations.
|
||||
* ID 1 is reserved for the Mbed TLS software driver. */
|
||||
/* BEGIN-driver id definition */
|
||||
#define PSA_CRYPTO_MBED_TLS_DRIVER_ID (1)
|
||||
#define MBEDTLS_TEST_OPAQUE_DRIVER_ID (2)
|
||||
#define MBEDTLS_TEST_TRANSPARENT_DRIVER_ID (3)
|
||||
#define P256_TRANSPARENT_DRIVER_ID (4)
|
||||
|
||||
|
||||
/* SiLabs Driver IDs */
|
||||
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
#define SLI_SE_TRANSPARENT_DRIVER_ID (4)
|
||||
#define SLI_SE_OPAQUE_DRIVER_ID (5)
|
||||
#define SLI_CRYPTOACC_TRANSPARENT_DRIVER_ID (6)
|
||||
#define SLI_CRYPTO_TRANSPARENT_DRIVER_ID (7)
|
||||
#endif
|
||||
|
||||
/* END-driver id */
|
||||
|
||||
/* BEGIN-Common Macro definitions */
|
||||
|
||||
/* END-Common Macro definitions */
|
||||
|
||||
/* Support the 'old' SE interface when asked to */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/* PSA_CRYPTO_DRIVER_PRESENT is defined when either a new-style or old-style
|
||||
* SE driver is present, to avoid unused argument errors at compile time. */
|
||||
#ifndef PSA_CRYPTO_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_DRIVER_PRESENT
|
||||
#endif
|
||||
#include "psa_crypto_se.h"
|
||||
#endif
|
||||
|
||||
/** Get the key buffer size required to store the key material of a key
|
||||
* associated with an opaque driver.
|
||||
*
|
||||
* \param[in] attributes The key attributes.
|
||||
* \param[out] key_buffer_size Minimum buffer size to contain the key material
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The minimum size for a buffer to contain the key material has been
|
||||
* returned successfully.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The type and/or the size in bits of the key or the combination of
|
||||
* the two is not supported.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The key is declared with a lifetime not known to us.
|
||||
*/
|
||||
psa_status_t psa_driver_wrapper_get_key_buffer_size(
|
||||
const psa_key_attributes_t *attributes,
|
||||
size_t *key_buffer_size )
|
||||
{
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
|
||||
psa_key_type_t key_type = psa_get_key_type(attributes);
|
||||
size_t key_bits = psa_get_key_bits(attributes);
|
||||
size_t buffer_size = 0;
|
||||
|
||||
switch( location )
|
||||
{
|
||||
#if defined(SLI_MBEDTLS_DEVICE_VSE) && defined(SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS)
|
||||
case PSA_KEY_LOCATION_SL_CRYPTOACC_OPAQUE:
|
||||
buffer_size = sizeof(sli_cryptoacc_opaque_key_context_t);
|
||||
*key_buffer_size = buffer_size;
|
||||
return ( PSA_SUCCESS );
|
||||
#endif
|
||||
#if defined(PSA_CRYPTO_DRIVER_TEST)
|
||||
case PSA_CRYPTO_TEST_DRIVER_LOCATION:
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
|
||||
/* Emulate property 'builtin_key_size' */
|
||||
if( psa_key_id_is_builtin(
|
||||
MBEDTLS_SVC_KEY_ID_GET_KEY_ID(
|
||||
psa_get_key_id( attributes ) ) ) )
|
||||
{
|
||||
*key_buffer_size = sizeof( psa_drv_slot_number_t );
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
|
||||
*key_buffer_size = mbedtls_test_opaque_size_function( key_type,
|
||||
key_bits );
|
||||
return( ( *key_buffer_size != 0 ) ?
|
||||
PSA_SUCCESS : PSA_ERROR_NOT_SUPPORTED );
|
||||
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||
case PSA_KEY_LOCATION_LOCAL_STORAGE:
|
||||
buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits );
|
||||
if( buffer_size == 0 ||
|
||||
( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) && buffer_size == 1 ) )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
*key_buffer_size = buffer_size;
|
||||
return( PSA_SUCCESS );
|
||||
#if defined(SLI_MBEDTLS_DEVICE_HSE) && defined(SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS)
|
||||
case PSA_KEY_LOCATION_SLI_SE_OPAQUE:
|
||||
buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits );
|
||||
if( buffer_size == 0 ||
|
||||
( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) && buffer_size == 1 ) )
|
||||
buffer_size = *key_buffer_size;
|
||||
// Remove public key format byte
|
||||
if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( key_type ) ) {
|
||||
buffer_size--;
|
||||
}
|
||||
// Compensate for word alignment demands
|
||||
buffer_size = sli_se_word_align( buffer_size );
|
||||
if( PSA_BITS_TO_BYTES( key_bits ) & 0x3 || PSA_BITS_TO_BYTES( key_bits ) == 0 ) {
|
||||
if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ) {
|
||||
// Allocate extra word for public keys, since alignment constrains
|
||||
// May require that
|
||||
buffer_size += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
// Add wrapped context overhead
|
||||
buffer_size += sizeof(sli_se_opaque_wrapped_key_context_t);
|
||||
*key_buffer_size = buffer_size;
|
||||
return ( PSA_SUCCESS );
|
||||
#endif
|
||||
#if defined(SLI_SECURE_KEY_STORAGE_DEVICE_SI91X)
|
||||
case PSA_KEY_VOLATILE_PERSISTENT_WRAPPED:
|
||||
buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits );
|
||||
if( buffer_size == 0 ||
|
||||
( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) && buffer_size == 1 ) )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
*key_buffer_size = buffer_size;
|
||||
return( PSA_SUCCESS );
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
(void)key_type;
|
||||
(void)key_bits;
|
||||
*key_buffer_size = 0;
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_driver_wrapper_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length )
|
||||
|
||||
{
|
||||
|
||||
psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(
|
||||
psa_get_key_lifetime( attributes ) );
|
||||
|
||||
/* Try dynamically-registered SE interface first */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
|
||||
if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
|
||||
{
|
||||
if( ( drv->key_management == NULL ) ||
|
||||
( drv->key_management->p_export_public == NULL ) )
|
||||
{
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
return( drv->key_management->p_export_public(
|
||||
drv_context,
|
||||
*( (psa_key_slot_number_t *)key_buffer ),
|
||||
data, data_size, data_length ) );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
|
||||
switch( location )
|
||||
{
|
||||
case PSA_KEY_LOCATION_LOCAL_STORAGE:
|
||||
/* Key is stored in the slot in export representation, so
|
||||
* cycle through all known transparent accelerators */
|
||||
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
|
||||
#if (defined(PSA_CRYPTO_DRIVER_TEST) )
|
||||
status = mbedtls_test_transparent_export_public_key
|
||||
(attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length
|
||||
);
|
||||
|
||||
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||
return( status );
|
||||
#endif
|
||||
|
||||
#if (defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) )
|
||||
status = p256_transparent_export_public_key
|
||||
(attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length
|
||||
);
|
||||
|
||||
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||
return( status );
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(SLI_MBEDTLS_DEVICE_HSE)
|
||||
status = sli_se_transparent_export_public_key( attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length );
|
||||
/* Declared with fallback == true */
|
||||
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||
return( status );
|
||||
#endif // SLI_MBEDTLS_DEVICE_HSE
|
||||
#if defined(SLI_MBEDTLS_DEVICE_VSE)
|
||||
status = sli_cryptoacc_transparent_export_public_key( attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length );
|
||||
/* Declared with fallback == true */
|
||||
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||
return( status );
|
||||
#endif // SLI_MBEDTLS_DEVICE_VSE
|
||||
#if defined(SLI_ECDH_DEVICE_SI91X)
|
||||
status = sli_si91x_psa_export_public_key_ecdh( attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length );
|
||||
/* Declared with fallback == true */
|
||||
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||
return( status );
|
||||
#endif // SLI_ECDH_DEVICE_SI91X
|
||||
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
|
||||
/* Fell through, meaning no accelerator supports this operation */
|
||||
return( psa_export_public_key_internal( attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length ) );
|
||||
|
||||
/* Add cases for opaque driver here */
|
||||
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
|
||||
#if (defined(PSA_CRYPTO_DRIVER_TEST) )
|
||||
case 0x7fffff:
|
||||
return( mbedtls_test_opaque_export_public_key
|
||||
(attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length
|
||||
));
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(SLI_MBEDTLS_DEVICE_HSE) && defined(SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS)
|
||||
case PSA_KEY_LOCATION_SLI_SE_OPAQUE:
|
||||
return( sli_se_opaque_export_public_key( attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length ) );
|
||||
#endif
|
||||
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
|
||||
default:
|
||||
/* Key is declared with a lifetime not known to us */
|
||||
return( status );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
psa_status_t psa_driver_wrapper_get_builtin_key(
|
||||
psa_drv_slot_number_t slot_number,
|
||||
psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
|
||||
{
|
||||
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
|
||||
switch( location )
|
||||
{
|
||||
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
|
||||
#if (defined(PSA_CRYPTO_DRIVER_TEST) )
|
||||
case 0x7fffff:
|
||||
return( mbedtls_test_opaque_get_builtin_key
|
||||
(slot_number,
|
||||
attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
key_buffer_length
|
||||
));
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(SLI_MBEDTLS_DEVICE_HSE) && defined(SLI_PSA_DRIVER_FEATURE_BUILTIN_KEYS)
|
||||
case PSA_KEY_LOCATION_SLI_SE_OPAQUE:
|
||||
return( sli_se_opaque_get_builtin_key(
|
||||
slot_number,
|
||||
attributes,
|
||||
key_buffer, key_buffer_size, key_buffer_length ) );
|
||||
#endif
|
||||
#if defined(SLI_MBEDTLS_DEVICE_VSE) && defined(SLI_PSA_DRIVER_FEATURE_BUILTIN_KEYS)
|
||||
case PSA_KEY_LOCATION_SL_CRYPTOACC_OPAQUE:
|
||||
return( sli_cryptoacc_opaque_get_builtin_key(
|
||||
slot_number,
|
||||
attributes,
|
||||
key_buffer, key_buffer_size, key_buffer_length ) );
|
||||
#endif
|
||||
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
|
||||
default:
|
||||
(void) slot_number;
|
||||
(void) key_buffer;
|
||||
(void) key_buffer_size;
|
||||
(void) key_buffer_length;
|
||||
return( PSA_ERROR_DOES_NOT_EXIST );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
31
Libs/util/third_party/mbedtls/library/psa_crypto_driver_wrappers_no_static.h
vendored
Normal file
31
Libs/util/third_party/mbedtls/library/psa_crypto_driver_wrappers_no_static.h
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Function signatures for functionality that can be provided by
|
||||
* cryptographic accelerators.
|
||||
*/
|
||||
/* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_DRIVER_WRAPPERS_NO_STATIC_H
|
||||
#define PSA_CRYPTO_DRIVER_WRAPPERS_NO_STATIC_H
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_driver_common.h"
|
||||
|
||||
psa_status_t psa_driver_wrapper_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length);
|
||||
|
||||
psa_status_t psa_driver_wrapper_get_key_buffer_size(
|
||||
const psa_key_attributes_t *attributes,
|
||||
size_t *key_buffer_size);
|
||||
|
||||
psa_status_t psa_driver_wrapper_get_builtin_key(
|
||||
psa_drv_slot_number_t slot_number,
|
||||
psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
|
||||
|
||||
#endif /* PSA_CRYPTO_DRIVER_WRAPPERS_NO_STATIC_H */
|
||||
|
||||
/* End of automatically generated file. */
|
||||
596
Libs/util/third_party/mbedtls/library/psa_crypto_ecp.c
vendored
Normal file
596
Libs/util/third_party/mbedtls/library/psa_crypto_ecp.c
vendored
Normal file
@@ -0,0 +1,596 @@
|
||||
/*
|
||||
* PSA ECP layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_ecp.h"
|
||||
#include "psa_crypto_random_impl.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include <mbedtls/ecdsa.h>
|
||||
#include <mbedtls/ecdh.h>
|
||||
#include <mbedtls/ecp.h>
|
||||
#include <mbedtls/error.h>
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
|
||||
/* Helper function to verify if the provided EC's family and key bit size are valid.
|
||||
*
|
||||
* Note: "bits" parameter is used both as input and output and it might be updated
|
||||
* in case provided input value is not multiple of 8 ("sloppy" bits).
|
||||
*/
|
||||
static int check_ecc_parameters(psa_ecc_family_t family, size_t *bits)
|
||||
{
|
||||
switch (family) {
|
||||
case PSA_ECC_FAMILY_SECP_R1:
|
||||
switch (*bits) {
|
||||
case 192:
|
||||
case 224:
|
||||
case 256:
|
||||
case 384:
|
||||
case 521:
|
||||
return PSA_SUCCESS;
|
||||
case 528:
|
||||
*bits = 521;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
|
||||
switch (*bits) {
|
||||
case 256:
|
||||
case 384:
|
||||
case 512:
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case PSA_ECC_FAMILY_MONTGOMERY:
|
||||
switch (*bits) {
|
||||
case 448:
|
||||
case 255:
|
||||
return PSA_SUCCESS;
|
||||
case 256:
|
||||
*bits = 255;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case PSA_ECC_FAMILY_SECP_K1:
|
||||
switch (*bits) {
|
||||
case 192:
|
||||
/* secp224k1 is not and will not be supported in PSA (#3541). */
|
||||
case 256:
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_ecp_load_representation(
|
||||
psa_key_type_t type, size_t curve_bits,
|
||||
const uint8_t *data, size_t data_length,
|
||||
mbedtls_ecp_keypair **p_ecp)
|
||||
{
|
||||
mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
|
||||
psa_status_t status;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
size_t curve_bytes = data_length;
|
||||
int explicit_bits = (curve_bits != 0);
|
||||
|
||||
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) &&
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(type) != PSA_ECC_FAMILY_MONTGOMERY) {
|
||||
/* A Weierstrass public key is represented as:
|
||||
* - The byte 0x04;
|
||||
* - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
|
||||
* - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
|
||||
* So its data length is 2m+1 where m is the curve size in bits.
|
||||
*/
|
||||
if ((data_length & 1) == 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
curve_bytes = data_length / 2;
|
||||
|
||||
/* Montgomery public keys are represented in compressed format, meaning
|
||||
* their curve_bytes is equal to the amount of input. */
|
||||
|
||||
/* Private keys are represented in uncompressed private random integer
|
||||
* format, meaning their curve_bytes is equal to the amount of input. */
|
||||
}
|
||||
|
||||
if (explicit_bits) {
|
||||
/* With an explicit bit-size, the data must have the matching length. */
|
||||
if (curve_bytes != PSA_BITS_TO_BYTES(curve_bits)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
} else {
|
||||
/* We need to infer the bit-size from the data. Since the only
|
||||
* information we have is the length in bytes, the value of curve_bits
|
||||
* at this stage is rounded up to the nearest multiple of 8. */
|
||||
curve_bits = PSA_BYTES_TO_BITS(curve_bytes);
|
||||
}
|
||||
|
||||
/* Allocate and initialize a key representation. */
|
||||
ecp = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
|
||||
if (ecp == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
mbedtls_ecp_keypair_init(ecp);
|
||||
|
||||
status = check_ecc_parameters(PSA_KEY_TYPE_ECC_GET_FAMILY(type), &curve_bits);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Load the group. */
|
||||
grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type),
|
||||
curve_bits);
|
||||
if (grp_id == MBEDTLS_ECP_DP_NONE) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_group_load(&ecp->grp, grp_id));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Load the key material. */
|
||||
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
|
||||
/* Load the public value. */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_point_read_binary(&ecp->grp, &ecp->Q,
|
||||
data,
|
||||
data_length));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Check that the point is on the curve. */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_check_pubkey(&ecp->grp, &ecp->Q));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
/* Load and validate the secret value. */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_read_key(ecp->grp.id,
|
||||
ecp,
|
||||
data,
|
||||
data_length));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
*p_ecp = ecp;
|
||||
exit:
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
mbedtls_free(ecp);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
|
||||
psa_status_t mbedtls_psa_ecp_import_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data, size_t data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size,
|
||||
size_t *key_buffer_length, size_t *bits)
|
||||
{
|
||||
psa_status_t status;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
|
||||
/* Parse input */
|
||||
status = mbedtls_psa_ecp_load_representation(attributes->type,
|
||||
attributes->bits,
|
||||
data,
|
||||
data_length,
|
||||
&ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type) ==
|
||||
PSA_ECC_FAMILY_MONTGOMERY) {
|
||||
*bits = ecp->grp.nbits + 1;
|
||||
} else {
|
||||
*bits = ecp->grp.nbits;
|
||||
}
|
||||
|
||||
/* Re-export the data to PSA export format. There is currently no support
|
||||
* for other input formats then the export format, so this is a 1-1
|
||||
* copy operation. */
|
||||
status = mbedtls_psa_ecp_export_key(attributes->type,
|
||||
ecp,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
key_buffer_length);
|
||||
exit:
|
||||
/* Always free the PK object (will also free contained ECP context) */
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
mbedtls_free(ecp);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type,
|
||||
mbedtls_ecp_keypair *ecp,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
|
||||
/* Check whether the public part is loaded */
|
||||
if (mbedtls_ecp_is_zero(&ecp->Q)) {
|
||||
/* Calculate the public key */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_mul(&ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE));
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_point_write_binary(&ecp->grp, &ecp->Q,
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED,
|
||||
data_length,
|
||||
data,
|
||||
data_size));
|
||||
if (status != PSA_SUCCESS) {
|
||||
memset(data, 0, data_size);
|
||||
}
|
||||
|
||||
return status;
|
||||
} else {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_write_key_ext(ecp, data_length, data, data_size));
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_ecp_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
|
||||
status = mbedtls_psa_ecp_load_representation(
|
||||
attributes->type, attributes->bits,
|
||||
key_buffer, key_buffer_size, &ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = mbedtls_psa_ecp_export_key(
|
||||
PSA_KEY_TYPE_ECC_PUBLIC_KEY(
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)),
|
||||
ecp, data, data_size, data_length);
|
||||
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
mbedtls_free(ecp);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
|
||||
psa_status_t mbedtls_psa_ecp_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
|
||||
attributes->type);
|
||||
mbedtls_ecp_group_id grp_id =
|
||||
mbedtls_ecc_group_from_psa(curve, attributes->bits);
|
||||
|
||||
const mbedtls_ecp_curve_info *curve_info =
|
||||
mbedtls_ecp_curve_info_from_grp_id(grp_id);
|
||||
mbedtls_ecp_keypair ecp;
|
||||
|
||||
if (grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
mbedtls_ecp_keypair_init(&ecp);
|
||||
ret = mbedtls_ecp_gen_key(grp_id, &ecp,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_write_key_ext(&ecp, key_buffer_length,
|
||||
key_buffer, key_buffer_size));
|
||||
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE */
|
||||
|
||||
/****************************************************************/
|
||||
/* ECDSA sign/verify */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
|
||||
psa_status_t mbedtls_psa_ecdsa_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
|
||||
uint8_t *signature, size_t signature_size, size_t *signature_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t curve_bytes;
|
||||
mbedtls_mpi r, s;
|
||||
|
||||
status = mbedtls_psa_ecp_load_representation(attributes->type,
|
||||
attributes->bits,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits);
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
|
||||
if (signature_size < 2 * curve_bytes) {
|
||||
ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
|
||||
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
|
||||
mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_ext(
|
||||
&ecp->grp, &r, &s,
|
||||
&ecp->d, hash,
|
||||
hash_length, md_alg,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE));
|
||||
#else
|
||||
ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
|
||||
goto cleanup;
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
|
||||
} else {
|
||||
(void) alg;
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign(&ecp->grp, &r, &s, &ecp->d,
|
||||
hash, hash_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE));
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&r,
|
||||
signature,
|
||||
curve_bytes));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&s,
|
||||
signature + curve_bytes,
|
||||
curve_bytes));
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
if (ret == 0) {
|
||||
*signature_length = 2 * curve_bytes;
|
||||
}
|
||||
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
mbedtls_free(ecp);
|
||||
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_ecp_load_public_part(mbedtls_ecp_keypair *ecp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Check whether the public part is loaded. If not, load it. */
|
||||
if (mbedtls_ecp_is_zero(&ecp->Q)) {
|
||||
ret = mbedtls_ecp_mul(&ecp->grp, &ecp->Q,
|
||||
&ecp->d, &ecp->grp.G,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE);
|
||||
}
|
||||
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_ecdsa_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
|
||||
const uint8_t *signature, size_t signature_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
size_t curve_bytes;
|
||||
mbedtls_mpi r, s;
|
||||
|
||||
(void) alg;
|
||||
|
||||
status = mbedtls_psa_ecp_load_representation(attributes->type,
|
||||
attributes->bits,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits);
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
|
||||
if (signature_length != 2 * curve_bytes) {
|
||||
status = PSA_ERROR_INVALID_SIGNATURE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&r,
|
||||
signature,
|
||||
curve_bytes));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&s,
|
||||
signature + curve_bytes,
|
||||
curve_bytes));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = mbedtls_psa_ecp_load_public_part(ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(mbedtls_ecdsa_verify(&ecp->grp, hash,
|
||||
hash_length, &ecp->Q,
|
||||
&r, &s));
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
mbedtls_free(ecp);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
|
||||
|
||||
/****************************************************************/
|
||||
/* ECDH Key Agreement */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
|
||||
psa_status_t mbedtls_psa_key_agreement_ecdh(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *peer_key, size_t peer_key_length,
|
||||
uint8_t *shared_secret, size_t shared_secret_size,
|
||||
size_t *shared_secret_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type) ||
|
||||
!PSA_ALG_IS_ECDH(alg)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
status = mbedtls_psa_ecp_load_representation(
|
||||
attributes->type,
|
||||
attributes->bits,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
mbedtls_ecp_keypair *their_key = NULL;
|
||||
mbedtls_ecdh_context ecdh;
|
||||
size_t bits = 0;
|
||||
psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(ecp->grp.id, &bits);
|
||||
mbedtls_ecdh_init(&ecdh);
|
||||
|
||||
status = mbedtls_psa_ecp_load_representation(
|
||||
PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve),
|
||||
bits,
|
||||
peer_key,
|
||||
peer_key_length,
|
||||
&their_key);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecdh_get_params(&ecdh, their_key, MBEDTLS_ECDH_THEIRS));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecdh_get_params(&ecdh, ecp, MBEDTLS_ECDH_OURS));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecdh_calc_secret(&ecdh,
|
||||
shared_secret_length,
|
||||
shared_secret, shared_secret_size,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
if (PSA_BITS_TO_BYTES(bits) != *shared_secret_length) {
|
||||
status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
exit:
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_platform_zeroize(shared_secret, shared_secret_size);
|
||||
}
|
||||
mbedtls_ecdh_free(&ecdh);
|
||||
mbedtls_ecp_keypair_free(their_key);
|
||||
mbedtls_free(their_key);
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
mbedtls_free(ecp);
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
|
||||
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
267
Libs/util/third_party/mbedtls/library/psa_crypto_ecp.h
vendored
Normal file
267
Libs/util/third_party/mbedtls/library/psa_crypto_ecp.h
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* PSA ECP layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_ECP_H
|
||||
#define PSA_CRYPTO_ECP_H
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include <mbedtls/ecp.h>
|
||||
|
||||
/** Load the contents of a key buffer into an internal ECP representation
|
||||
*
|
||||
* \param[in] type The type of key contained in \p data.
|
||||
* \param[in] curve_bits The nominal bit-size of the curve.
|
||||
* It must be consistent with the representation
|
||||
* passed in \p data.
|
||||
* This can be 0, in which case the bit-size
|
||||
* is inferred from \p data_length (which is possible
|
||||
* for all key types and representation formats
|
||||
* formats that are currently supported or will
|
||||
* be in the foreseeable future).
|
||||
* \param[in] data The buffer from which to load the representation.
|
||||
* \param[in] data_length The size in bytes of \p data.
|
||||
* \param[out] p_ecp Returns a pointer to an ECP context on success.
|
||||
* The caller is responsible for freeing both the
|
||||
* contents of the context and the context itself
|
||||
* when done.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_ecp_load_representation(psa_key_type_t type,
|
||||
size_t curve_bits,
|
||||
const uint8_t *data,
|
||||
size_t data_length,
|
||||
mbedtls_ecp_keypair **p_ecp);
|
||||
|
||||
/** Load the public part of an internal ECP, if required.
|
||||
*
|
||||
* \param ecp The ECP context to load the public part for.
|
||||
*
|
||||
* \return PSA_SUCCESS on success, otherwise an MPI error.
|
||||
*/
|
||||
|
||||
psa_status_t mbedtls_psa_ecp_load_public_part(mbedtls_ecp_keypair *ecp);
|
||||
|
||||
/** Import an ECP key in binary format.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* import_key entry point. This function behaves as an import_key
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \param[in] attributes The attributes for the key to import.
|
||||
* \param[in] data The buffer containing the key data in import
|
||||
* format.
|
||||
* \param[in] data_length Size of the \p data buffer in bytes.
|
||||
* \param[out] key_buffer The buffer containing the key data in output
|
||||
* format.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. This
|
||||
* size is greater or equal to \p data_length.
|
||||
* \param[out] key_buffer_length The length of the data written in \p
|
||||
* key_buffer in bytes.
|
||||
* \param[out] bits The key size in number of bits.
|
||||
*
|
||||
* \retval #PSA_SUCCESS The ECP key was imported successfully.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The key data is not correctly formatted.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_ecp_import_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data, size_t data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size,
|
||||
size_t *key_buffer_length, size_t *bits);
|
||||
|
||||
/** Export an ECP key to export representation
|
||||
*
|
||||
* \param[in] type The type of key (public/private) to export
|
||||
* \param[in] ecp The internal ECP representation from which to export
|
||||
* \param[out] data The buffer to export to
|
||||
* \param[in] data_size The length of the buffer to export to
|
||||
* \param[out] data_length The amount of bytes written to \p data
|
||||
*/
|
||||
psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type,
|
||||
mbedtls_ecp_keypair *ecp,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length);
|
||||
|
||||
/** Export an ECP public key or the public part of an ECP key pair in binary
|
||||
* format.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* export_public_key entry point. This function behaves as an
|
||||
* export_public_key entry point as defined in the PSA driver interface
|
||||
* specification.
|
||||
*
|
||||
* \param[in] attributes The attributes for the key to export.
|
||||
* \param[in] key_buffer Material or context of the key to export.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[out] data Buffer where the key data is to be written.
|
||||
* \param[in] data_size Size of the \p data buffer in bytes.
|
||||
* \param[out] data_length On success, the number of bytes written in
|
||||
* \p data
|
||||
*
|
||||
* \retval #PSA_SUCCESS The ECP public key was exported successfully.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_ecp_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length);
|
||||
|
||||
/**
|
||||
* \brief Generate an ECP key.
|
||||
*
|
||||
* \note The signature of the function is that of a PSA driver generate_key
|
||||
* entry point.
|
||||
*
|
||||
* \param[in] attributes The attributes for the ECP key to generate.
|
||||
* \param[out] key_buffer Buffer where the key data is to be written.
|
||||
* \param[in] key_buffer_size Size of \p key_buffer in bytes.
|
||||
* \param[out] key_buffer_length On success, the number of bytes written in
|
||||
* \p key_buffer.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The key was successfully generated.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* Key length or type not supported.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of \p key_buffer is too small.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_ecp_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
|
||||
|
||||
/** Sign an already-calculated hash with ECDSA.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* sign_hash entry point. This function behaves as a sign_hash
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \param[in] attributes The attributes of the ECC key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the ECC key context.
|
||||
* format.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg Randomized or deterministic ECDSA algorithm.
|
||||
* \param[in] hash The hash or message to sign.
|
||||
* \param[in] hash_length Size of the \p hash buffer in bytes.
|
||||
* \param[out] signature Buffer where the signature is to be written.
|
||||
* \param[in] signature_size Size of the \p signature buffer in bytes.
|
||||
* \param[out] signature_length On success, the number of bytes
|
||||
* that make up the returned signature value.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p signature buffer is too small. You can
|
||||
* determine a sufficient buffer size by calling
|
||||
* #PSA_SIGN_OUTPUT_SIZE(\c PSA_KEY_TYPE_ECC_KEY_PAIR, \c key_bits,
|
||||
* \p alg) where \c key_bits is the bit-size of the ECC key.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_ecdsa_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
|
||||
uint8_t *signature, size_t signature_size, size_t *signature_length);
|
||||
|
||||
/**
|
||||
* \brief Verify an ECDSA hash or short message signature.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* verify_hash entry point. This function behaves as a verify_hash
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \param[in] attributes The attributes of the ECC key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the ECC key context.
|
||||
* format.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg Randomized or deterministic ECDSA algorithm.
|
||||
* \param[in] hash The hash or message whose signature is to be
|
||||
* verified.
|
||||
* \param[in] hash_length Size of the \p hash buffer in bytes.
|
||||
* \param[in] signature Buffer containing the signature to verify.
|
||||
* \param[in] signature_length Size of the \p signature buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The signature is valid.
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
* The calculation was performed successfully, but the passed
|
||||
* signature is not a valid signature.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_ecdsa_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
|
||||
const uint8_t *signature, size_t signature_length);
|
||||
|
||||
|
||||
/** Perform a key agreement and return the raw ECDH shared secret.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* key_agreement entry point. This function behaves as a key_agreement
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the private key
|
||||
* context.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in
|
||||
* bytes.
|
||||
* \param[in] alg A key agreement algorithm that is
|
||||
* compatible with the type of the key.
|
||||
* \param[in] peer_key The buffer containing the key context
|
||||
* of the peer's public key.
|
||||
* \param[in] peer_key_length Size of the \p peer_key buffer in
|
||||
* bytes.
|
||||
* \param[out] shared_secret The buffer to which the shared secret
|
||||
* is to be written.
|
||||
* \param[in] shared_secret_size Size of the \p shared_secret buffer in
|
||||
* bytes.
|
||||
* \param[out] shared_secret_length On success, the number of bytes that make
|
||||
* up the returned shared secret.
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Shared secret successfully calculated.
|
||||
* \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p alg is not a key agreement algorithm, or
|
||||
* \p private_key is not compatible with \p alg,
|
||||
* or \p peer_key is not valid for \p alg or not compatible with
|
||||
* \p private_key.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p shared_secret_size is too small
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \p alg is not a supported key agreement algorithm.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_key_agreement_ecdh(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *peer_key, size_t peer_key_length,
|
||||
uint8_t *shared_secret, size_t shared_secret_size,
|
||||
size_t *shared_secret_length);
|
||||
#endif /* PSA_CRYPTO_ECP_H */
|
||||
321
Libs/util/third_party/mbedtls/library/psa_crypto_ffdh.c
vendored
Normal file
321
Libs/util/third_party/mbedtls/library/psa_crypto_ffdh.c
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* PSA FFDH layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
/* This header is only needed because it defines
|
||||
* MBEDTLS_DHM_RFC7919_FFDHEXXXX_[P|G]_BIN symbols that are used in
|
||||
* mbedtls_psa_ffdh_set_prime_generator(). Apart from that, this module
|
||||
* only uses bignum functions for arithmetic. */
|
||||
#include <mbedtls/dhm.h>
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_ffdh.h"
|
||||
#include "psa_crypto_random_impl.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
|
||||
static psa_status_t mbedtls_psa_ffdh_set_prime_generator(size_t key_size,
|
||||
mbedtls_mpi *P,
|
||||
mbedtls_mpi *G)
|
||||
{
|
||||
const unsigned char *dhm_P = NULL;
|
||||
const unsigned char *dhm_G = NULL;
|
||||
size_t dhm_size_P = 0;
|
||||
size_t dhm_size_G = 0;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (P == NULL && G == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048)
|
||||
static const unsigned char dhm_P_2048[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN;
|
||||
static const unsigned char dhm_G_2048[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072)
|
||||
static const unsigned char dhm_P_3072[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN;
|
||||
static const unsigned char dhm_G_3072[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096)
|
||||
static const unsigned char dhm_P_4096[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN;
|
||||
static const unsigned char dhm_G_4096[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144)
|
||||
static const unsigned char dhm_P_6144[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN;
|
||||
static const unsigned char dhm_G_6144[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192)
|
||||
static const unsigned char dhm_P_8192[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN;
|
||||
static const unsigned char dhm_G_8192[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 */
|
||||
|
||||
switch (key_size) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048)
|
||||
case sizeof(dhm_P_2048):
|
||||
dhm_P = dhm_P_2048;
|
||||
dhm_G = dhm_G_2048;
|
||||
dhm_size_P = sizeof(dhm_P_2048);
|
||||
dhm_size_G = sizeof(dhm_G_2048);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072)
|
||||
case sizeof(dhm_P_3072):
|
||||
dhm_P = dhm_P_3072;
|
||||
dhm_G = dhm_G_3072;
|
||||
dhm_size_P = sizeof(dhm_P_3072);
|
||||
dhm_size_G = sizeof(dhm_G_3072);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096)
|
||||
case sizeof(dhm_P_4096):
|
||||
dhm_P = dhm_P_4096;
|
||||
dhm_G = dhm_G_4096;
|
||||
dhm_size_P = sizeof(dhm_P_4096);
|
||||
dhm_size_G = sizeof(dhm_G_4096);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144)
|
||||
case sizeof(dhm_P_6144):
|
||||
dhm_P = dhm_P_6144;
|
||||
dhm_G = dhm_G_6144;
|
||||
dhm_size_P = sizeof(dhm_P_6144);
|
||||
dhm_size_G = sizeof(dhm_G_6144);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192)
|
||||
case sizeof(dhm_P_8192):
|
||||
dhm_P = dhm_P_8192;
|
||||
dhm_G = dhm_G_8192;
|
||||
dhm_size_P = sizeof(dhm_P_8192);
|
||||
dhm_size_G = sizeof(dhm_G_8192);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 */
|
||||
default:
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (P != NULL) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(P, dhm_P,
|
||||
dhm_size_P));
|
||||
}
|
||||
if (G != NULL) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(G, dhm_G,
|
||||
dhm_size_G));
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (ret != 0) {
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT ||
|
||||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE ||
|
||||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY ||
|
||||
MBEDTLS_PSA_BUILTIN_ALG_FFDH */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
|
||||
psa_status_t mbedtls_psa_ffdh_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi GX, G, X, P;
|
||||
psa_key_type_t type = attributes->type;
|
||||
|
||||
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
|
||||
if (key_buffer_size > data_size) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
memcpy(data, key_buffer, key_buffer_size);
|
||||
memset(data + key_buffer_size, 0,
|
||||
data_size - key_buffer_size);
|
||||
*data_length = key_buffer_size;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
mbedtls_mpi_init(&GX); mbedtls_mpi_init(&G);
|
||||
mbedtls_mpi_init(&X); mbedtls_mpi_init(&P);
|
||||
|
||||
size_t key_len = PSA_BITS_TO_BYTES(attributes->bits);
|
||||
|
||||
status = mbedtls_psa_ffdh_set_prime_generator(key_len, &P, &G);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer,
|
||||
key_buffer_size));
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&GX, &G, &X, &P, NULL));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&GX, data, key_len));
|
||||
|
||||
*data_length = key_len;
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
|
||||
mbedtls_mpi_free(&X); mbedtls_mpi_free(&GX);
|
||||
|
||||
if (status == PSA_SUCCESS && ret != 0) {
|
||||
status = mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT ||
|
||||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE)
|
||||
psa_status_t mbedtls_psa_ffdh_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
|
||||
{
|
||||
mbedtls_mpi X, P;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi_init(&P); mbedtls_mpi_init(&X);
|
||||
(void) attributes;
|
||||
|
||||
status = mbedtls_psa_ffdh_set_prime_generator(key_buffer_size, &P, NULL);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* RFC7919: Traditional finite field Diffie-Hellman has each peer choose their
|
||||
secret exponent from the range [2, P-2].
|
||||
Select random value in range [3, P-1] and decrease it by 1. */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_random(&X, 3, &P, mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&X, &X, 1));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&X, key_buffer, key_buffer_size));
|
||||
*key_buffer_length = key_buffer_size;
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&P); mbedtls_mpi_free(&X);
|
||||
if (status == PSA_SUCCESS && ret != 0) {
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT)
|
||||
psa_status_t mbedtls_psa_ffdh_import_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data, size_t data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size,
|
||||
size_t *key_buffer_length, size_t *bits)
|
||||
{
|
||||
(void) attributes;
|
||||
|
||||
if (key_buffer_size < data_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
memcpy(key_buffer, data, data_length);
|
||||
*key_buffer_length = data_length;
|
||||
*bits = PSA_BYTES_TO_BITS(data_length);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
|
||||
psa_status_t mbedtls_psa_ffdh_key_agreement(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *shared_secret,
|
||||
size_t shared_secret_size,
|
||||
size_t *shared_secret_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi P, G, X, GY, K;
|
||||
const size_t calculated_shared_secret_size = peer_key_length;
|
||||
|
||||
if (peer_key_length != key_buffer_size ||
|
||||
calculated_shared_secret_size > shared_secret_size) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!PSA_KEY_TYPE_IS_DH_KEY_PAIR(psa_get_key_type(attributes))) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
mbedtls_mpi_init(&P); mbedtls_mpi_init(&G);
|
||||
mbedtls_mpi_init(&X); mbedtls_mpi_init(&GY);
|
||||
mbedtls_mpi_init(&K);
|
||||
|
||||
status = mbedtls_psa_ffdh_set_prime_generator(
|
||||
PSA_BITS_TO_BYTES(attributes->bits), &P, &G);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer,
|
||||
key_buffer_size));
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&GY, peer_key,
|
||||
peer_key_length));
|
||||
|
||||
/* Calculate shared secret public key: K = G^(XY) mod P = GY^X mod P */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&K, &GY, &X, &P, NULL));
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&K, shared_secret,
|
||||
calculated_shared_secret_size));
|
||||
|
||||
*shared_secret_length = calculated_shared_secret_size;
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
|
||||
mbedtls_mpi_free(&X); mbedtls_mpi_free(&GY);
|
||||
mbedtls_mpi_free(&K);
|
||||
|
||||
if (status == PSA_SUCCESS && ret != 0) {
|
||||
status = mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
131
Libs/util/third_party/mbedtls/library/psa_crypto_ffdh.h
vendored
Normal file
131
Libs/util/third_party/mbedtls/library/psa_crypto_ffdh.h
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* PSA FFDH layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_FFDH_H
|
||||
#define PSA_CRYPTO_FFDH_H
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
/** Perform a key agreement and return the FFDH shared secret.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] peer_key The buffer containing the key context
|
||||
* of the peer's public key.
|
||||
* \param[in] peer_key_length Size of the \p peer_key buffer in
|
||||
* bytes.
|
||||
* \param[in] key_buffer The buffer containing the private key
|
||||
* context.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in
|
||||
* bytes.
|
||||
* \param[out] shared_secret The buffer to which the shared secret
|
||||
* is to be written.
|
||||
* \param[in] shared_secret_size Size of the \p shared_secret buffer in
|
||||
* bytes.
|
||||
* \param[out] shared_secret_length On success, the number of bytes that make
|
||||
* up the returned shared secret.
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Shared secret successfully calculated.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p key_buffer_size, \p peer_key_length, \p shared_secret_size
|
||||
* do not match
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_ffdh_key_agreement(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *shared_secret,
|
||||
size_t shared_secret_size,
|
||||
size_t *shared_secret_length);
|
||||
|
||||
/** Export a public key or the public part of a DH key pair in binary format.
|
||||
*
|
||||
* \param[in] attributes The attributes for the key to export.
|
||||
* \param[in] key_buffer Material or context of the key to export.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[out] data Buffer where the key data is to be written.
|
||||
* \param[in] data_size Size of the \p data buffer in bytes.
|
||||
* \param[out] data_length On success, the number of bytes written in
|
||||
* \p data
|
||||
*
|
||||
* \retval #PSA_SUCCESS The public key was exported successfully.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of \p key_buffer is too small.
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_ffdh_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length);
|
||||
|
||||
/**
|
||||
* \brief Generate DH key.
|
||||
*
|
||||
* \note The signature of the function is that of a PSA driver generate_key
|
||||
* entry point.
|
||||
*
|
||||
* \param[in] attributes The attributes for the key to generate.
|
||||
* \param[out] key_buffer Buffer where the key data is to be written.
|
||||
* \param[in] key_buffer_size Size of \p key_buffer in bytes.
|
||||
* \param[out] key_buffer_length On success, the number of bytes written in
|
||||
* \p key_buffer.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The key was generated successfully.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* Key size in bits is invalid.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of \p key_buffer is too small.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_ffdh_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length);
|
||||
|
||||
/**
|
||||
* \brief Import DH key.
|
||||
*
|
||||
* \note The signature of the function is that of a PSA driver import_key
|
||||
* entry point.
|
||||
*
|
||||
* \param[in] attributes The attributes for the key to import.
|
||||
* \param[in] data The buffer containing the key data in import
|
||||
* format.
|
||||
* \param[in] data_length Size of the \p data buffer in bytes.
|
||||
* \param[out] key_buffer The buffer containing the key data in output
|
||||
* format.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. This
|
||||
* size is greater or equal to \p data_length.
|
||||
* \param[out] key_buffer_length The length of the data written in \p
|
||||
* key_buffer in bytes.
|
||||
* \param[out] bits The key size in number of bits.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The key was generated successfully.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of \p key_buffer is too small.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_ffdh_import_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data, size_t data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size,
|
||||
size_t *key_buffer_length, size_t *bits);
|
||||
|
||||
#endif /* PSA_CRYPTO_FFDH_H */
|
||||
470
Libs/util/third_party/mbedtls/library/psa_crypto_hash.c
vendored
Normal file
470
Libs/util/third_party/mbedtls/library/psa_crypto_hash.c
vendored
Normal file
@@ -0,0 +1,470 @@
|
||||
/*
|
||||
* PSA hashing layer on top of Mbed TLS software crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_hash.h"
|
||||
|
||||
#include <mbedtls/error.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_HASH)
|
||||
psa_status_t mbedtls_psa_hash_abort(
|
||||
mbedtls_psa_hash_operation_t *operation)
|
||||
{
|
||||
switch (operation->alg) {
|
||||
case 0:
|
||||
/* The object has (apparently) been initialized but it is not
|
||||
* in use. It's ok to call abort on such an object, and there's
|
||||
* nothing to do. */
|
||||
break;
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
|
||||
case PSA_ALG_MD5:
|
||||
mbedtls_md5_free(&operation->ctx.md5);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
|
||||
case PSA_ALG_RIPEMD160:
|
||||
mbedtls_ripemd160_free(&operation->ctx.ripemd160);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
|
||||
case PSA_ALG_SHA_1:
|
||||
mbedtls_sha1_free(&operation->ctx.sha1);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
|
||||
case PSA_ALG_SHA_224:
|
||||
mbedtls_sha256_free(&operation->ctx.sha256);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
|
||||
case PSA_ALG_SHA_256:
|
||||
mbedtls_sha256_free(&operation->ctx.sha256);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
|
||||
case PSA_ALG_SHA_384:
|
||||
mbedtls_sha512_free(&operation->ctx.sha512);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
|
||||
case PSA_ALG_SHA_512:
|
||||
mbedtls_sha512_free(&operation->ctx.sha512);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224)
|
||||
case PSA_ALG_SHA3_224:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256)
|
||||
case PSA_ALG_SHA3_256:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384)
|
||||
case PSA_ALG_SHA3_384:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
case PSA_ALG_SHA3_512:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
mbedtls_sha3_free(&operation->ctx.sha3);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
operation->alg = 0;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_hash_setup(
|
||||
mbedtls_psa_hash_operation_t *operation,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* A context must be freshly initialized before it can be set up. */
|
||||
if (operation->alg != 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
switch (alg) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
|
||||
case PSA_ALG_MD5:
|
||||
mbedtls_md5_init(&operation->ctx.md5);
|
||||
ret = mbedtls_md5_starts(&operation->ctx.md5);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
|
||||
case PSA_ALG_RIPEMD160:
|
||||
mbedtls_ripemd160_init(&operation->ctx.ripemd160);
|
||||
ret = mbedtls_ripemd160_starts(&operation->ctx.ripemd160);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
|
||||
case PSA_ALG_SHA_1:
|
||||
mbedtls_sha1_init(&operation->ctx.sha1);
|
||||
ret = mbedtls_sha1_starts(&operation->ctx.sha1);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
|
||||
case PSA_ALG_SHA_224:
|
||||
mbedtls_sha256_init(&operation->ctx.sha256);
|
||||
ret = mbedtls_sha256_starts(&operation->ctx.sha256, 1);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
|
||||
case PSA_ALG_SHA_256:
|
||||
mbedtls_sha256_init(&operation->ctx.sha256);
|
||||
ret = mbedtls_sha256_starts(&operation->ctx.sha256, 0);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
|
||||
case PSA_ALG_SHA_384:
|
||||
mbedtls_sha512_init(&operation->ctx.sha512);
|
||||
ret = mbedtls_sha512_starts(&operation->ctx.sha512, 1);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
|
||||
case PSA_ALG_SHA_512:
|
||||
mbedtls_sha512_init(&operation->ctx.sha512);
|
||||
ret = mbedtls_sha512_starts(&operation->ctx.sha512, 0);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224)
|
||||
case PSA_ALG_SHA3_224:
|
||||
mbedtls_sha3_init(&operation->ctx.sha3);
|
||||
ret = mbedtls_sha3_starts(&operation->ctx.sha3, MBEDTLS_SHA3_224);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256)
|
||||
case PSA_ALG_SHA3_256:
|
||||
mbedtls_sha3_init(&operation->ctx.sha3);
|
||||
ret = mbedtls_sha3_starts(&operation->ctx.sha3, MBEDTLS_SHA3_256);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384)
|
||||
case PSA_ALG_SHA3_384:
|
||||
mbedtls_sha3_init(&operation->ctx.sha3);
|
||||
ret = mbedtls_sha3_starts(&operation->ctx.sha3, MBEDTLS_SHA3_384);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
case PSA_ALG_SHA3_512:
|
||||
mbedtls_sha3_init(&operation->ctx.sha3);
|
||||
ret = mbedtls_sha3_starts(&operation->ctx.sha3, MBEDTLS_SHA3_512);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return PSA_ALG_IS_HASH(alg) ?
|
||||
PSA_ERROR_NOT_SUPPORTED :
|
||||
PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (ret == 0) {
|
||||
operation->alg = alg;
|
||||
} else {
|
||||
mbedtls_psa_hash_abort(operation);
|
||||
}
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_hash_clone(
|
||||
const mbedtls_psa_hash_operation_t *source_operation,
|
||||
mbedtls_psa_hash_operation_t *target_operation)
|
||||
{
|
||||
switch (source_operation->alg) {
|
||||
case 0:
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
|
||||
case PSA_ALG_MD5:
|
||||
mbedtls_md5_clone(&target_operation->ctx.md5,
|
||||
&source_operation->ctx.md5);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
|
||||
case PSA_ALG_RIPEMD160:
|
||||
mbedtls_ripemd160_clone(&target_operation->ctx.ripemd160,
|
||||
&source_operation->ctx.ripemd160);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
|
||||
case PSA_ALG_SHA_1:
|
||||
mbedtls_sha1_clone(&target_operation->ctx.sha1,
|
||||
&source_operation->ctx.sha1);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
|
||||
case PSA_ALG_SHA_224:
|
||||
mbedtls_sha256_clone(&target_operation->ctx.sha256,
|
||||
&source_operation->ctx.sha256);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
|
||||
case PSA_ALG_SHA_256:
|
||||
mbedtls_sha256_clone(&target_operation->ctx.sha256,
|
||||
&source_operation->ctx.sha256);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
|
||||
case PSA_ALG_SHA_384:
|
||||
mbedtls_sha512_clone(&target_operation->ctx.sha512,
|
||||
&source_operation->ctx.sha512);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
|
||||
case PSA_ALG_SHA_512:
|
||||
mbedtls_sha512_clone(&target_operation->ctx.sha512,
|
||||
&source_operation->ctx.sha512);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224)
|
||||
case PSA_ALG_SHA3_224:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256)
|
||||
case PSA_ALG_SHA3_256:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384)
|
||||
case PSA_ALG_SHA3_384:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
case PSA_ALG_SHA3_512:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
mbedtls_sha3_clone(&target_operation->ctx.sha3,
|
||||
&source_operation->ctx.sha3);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void) source_operation;
|
||||
(void) target_operation;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
target_operation->alg = source_operation->alg;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_hash_update(
|
||||
mbedtls_psa_hash_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
switch (operation->alg) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
|
||||
case PSA_ALG_MD5:
|
||||
ret = mbedtls_md5_update(&operation->ctx.md5,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
|
||||
case PSA_ALG_RIPEMD160:
|
||||
ret = mbedtls_ripemd160_update(&operation->ctx.ripemd160,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
|
||||
case PSA_ALG_SHA_1:
|
||||
ret = mbedtls_sha1_update(&operation->ctx.sha1,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
|
||||
case PSA_ALG_SHA_224:
|
||||
ret = mbedtls_sha256_update(&operation->ctx.sha256,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
|
||||
case PSA_ALG_SHA_256:
|
||||
ret = mbedtls_sha256_update(&operation->ctx.sha256,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
|
||||
case PSA_ALG_SHA_384:
|
||||
ret = mbedtls_sha512_update(&operation->ctx.sha512,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
|
||||
case PSA_ALG_SHA_512:
|
||||
ret = mbedtls_sha512_update(&operation->ctx.sha512,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224)
|
||||
case PSA_ALG_SHA3_224:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256)
|
||||
case PSA_ALG_SHA3_256:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384)
|
||||
case PSA_ALG_SHA3_384:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
case PSA_ALG_SHA3_512:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
ret = mbedtls_sha3_update(&operation->ctx.sha3,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_hash_finish(
|
||||
mbedtls_psa_hash_operation_t *operation,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t actual_hash_length = PSA_HASH_LENGTH(operation->alg);
|
||||
|
||||
/* Fill the output buffer with something that isn't a valid hash
|
||||
* (barring an attack on the hash and deliberately-crafted input),
|
||||
* in case the caller doesn't check the return status properly. */
|
||||
*hash_length = hash_size;
|
||||
/* If hash_size is 0 then hash may be NULL and then the
|
||||
* call to memset would have undefined behavior. */
|
||||
if (hash_size != 0) {
|
||||
memset(hash, '!', hash_size);
|
||||
}
|
||||
|
||||
if (hash_size < actual_hash_length) {
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (operation->alg) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
|
||||
case PSA_ALG_MD5:
|
||||
ret = mbedtls_md5_finish(&operation->ctx.md5, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
|
||||
case PSA_ALG_RIPEMD160:
|
||||
ret = mbedtls_ripemd160_finish(&operation->ctx.ripemd160, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
|
||||
case PSA_ALG_SHA_1:
|
||||
ret = mbedtls_sha1_finish(&operation->ctx.sha1, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
|
||||
case PSA_ALG_SHA_224:
|
||||
ret = mbedtls_sha256_finish(&operation->ctx.sha256, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
|
||||
case PSA_ALG_SHA_256:
|
||||
ret = mbedtls_sha256_finish(&operation->ctx.sha256, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
|
||||
case PSA_ALG_SHA_384:
|
||||
ret = mbedtls_sha512_finish(&operation->ctx.sha512, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
|
||||
case PSA_ALG_SHA_512:
|
||||
ret = mbedtls_sha512_finish(&operation->ctx.sha512, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224)
|
||||
case PSA_ALG_SHA3_224:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256)
|
||||
case PSA_ALG_SHA3_256:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384)
|
||||
case PSA_ALG_SHA3_384:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
case PSA_ALG_SHA3_512:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
ret = mbedtls_sha3_finish(&operation->ctx.sha3, hash, hash_size);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void) hash;
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
status = mbedtls_to_psa_error(ret);
|
||||
|
||||
exit:
|
||||
if (status == PSA_SUCCESS) {
|
||||
*hash_length = actual_hash_length;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_hash_compute(
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
mbedtls_psa_hash_operation_t operation = MBEDTLS_PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
*hash_length = hash_size;
|
||||
status = mbedtls_psa_hash_setup(&operation, alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
status = mbedtls_psa_hash_update(&operation, input, input_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
status = mbedtls_psa_hash_finish(&operation, hash, hash_size, hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
abort_status = mbedtls_psa_hash_abort(&operation);
|
||||
if (status == PSA_SUCCESS) {
|
||||
return abort_status;
|
||||
} else {
|
||||
return status;
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_HASH */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
211
Libs/util/third_party/mbedtls/library/psa_crypto_hash.h
vendored
Normal file
211
Libs/util/third_party/mbedtls/library/psa_crypto_hash.h
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* PSA hashing layer on top of Mbed TLS software crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_HASH_H
|
||||
#define PSA_CRYPTO_HASH_H
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
/** Calculate the hash (digest) of a message using Mbed TLS routines.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver hash_compute
|
||||
* entry point. This function behaves as a hash_compute entry point as
|
||||
* defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* \param alg The hash algorithm to compute (\c PSA_ALG_XXX value
|
||||
* such that #PSA_ALG_IS_HASH(\p alg) is true).
|
||||
* \param[in] input Buffer containing the message to hash.
|
||||
* \param input_length Size of the \p input buffer in bytes.
|
||||
* \param[out] hash Buffer where the hash is to be written.
|
||||
* \param hash_size Size of the \p hash buffer in bytes.
|
||||
* \param[out] hash_length On success, the number of bytes
|
||||
* that make up the hash value. This is always
|
||||
* #PSA_HASH_LENGTH(\p alg).
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \p alg is not supported
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p hash_size is too small
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_hash_compute(
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length);
|
||||
|
||||
/** Set up a multipart hash operation using Mbed TLS routines.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver hash_setup
|
||||
* entry point. This function behaves as a hash_setup entry point as
|
||||
* defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* If an error occurs at any step after a call to mbedtls_psa_hash_setup(), the
|
||||
* operation will need to be reset by a call to mbedtls_psa_hash_abort(). The
|
||||
* core may call mbedtls_psa_hash_abort() at any time after the operation
|
||||
* has been initialized.
|
||||
*
|
||||
* After a successful call to mbedtls_psa_hash_setup(), the core must
|
||||
* eventually terminate the operation. The following events terminate an
|
||||
* operation:
|
||||
* - A successful call to mbedtls_psa_hash_finish() or mbedtls_psa_hash_verify().
|
||||
* - A call to mbedtls_psa_hash_abort().
|
||||
*
|
||||
* \param[in,out] operation The operation object to set up. It must have
|
||||
* been initialized to all-zero and not yet be in use.
|
||||
* \param alg The hash algorithm to compute (\c PSA_ALG_XXX value
|
||||
* such that #PSA_ALG_IS_HASH(\p alg) is true).
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \p alg is not supported
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The operation state is not valid (it must be inactive).
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_hash_setup(
|
||||
mbedtls_psa_hash_operation_t *operation,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
/** Clone an Mbed TLS hash operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver hash_clone
|
||||
* entry point. This function behaves as a hash_clone entry point as
|
||||
* defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* This function copies the state of an ongoing hash operation to
|
||||
* a new operation object. In other words, this function is equivalent
|
||||
* to calling mbedtls_psa_hash_setup() on \p target_operation with the same
|
||||
* algorithm that \p source_operation was set up for, then
|
||||
* mbedtls_psa_hash_update() on \p target_operation with the same input that
|
||||
* that was passed to \p source_operation. After this function returns, the
|
||||
* two objects are independent, i.e. subsequent calls involving one of
|
||||
* the objects do not affect the other object.
|
||||
*
|
||||
* \param[in] source_operation The active hash operation to clone.
|
||||
* \param[in,out] target_operation The operation object to set up.
|
||||
* It must be initialized but not active.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The \p source_operation state is not valid (it must be active).
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The \p target_operation state is not valid (it must be inactive).
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_hash_clone(
|
||||
const mbedtls_psa_hash_operation_t *source_operation,
|
||||
mbedtls_psa_hash_operation_t *target_operation);
|
||||
|
||||
/** Add a message fragment to a multipart Mbed TLS hash operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver hash_update
|
||||
* entry point. This function behaves as a hash_update entry point as
|
||||
* defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* The application must call mbedtls_psa_hash_setup() before calling this function.
|
||||
*
|
||||
* If this function returns an error status, the operation enters an error
|
||||
* state and must be aborted by calling mbedtls_psa_hash_abort().
|
||||
*
|
||||
* \param[in,out] operation Active hash operation.
|
||||
* \param[in] input Buffer containing the message fragment to hash.
|
||||
* \param input_length Size of the \p input buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The operation state is not valid (it must be active).
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_hash_update(
|
||||
mbedtls_psa_hash_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length);
|
||||
|
||||
/** Finish the calculation of the Mbed TLS-calculated hash of a message.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver hash_finish
|
||||
* entry point. This function behaves as a hash_finish entry point as
|
||||
* defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* The application must call mbedtls_psa_hash_setup() before calling this function.
|
||||
* This function calculates the hash of the message formed by concatenating
|
||||
* the inputs passed to preceding calls to mbedtls_psa_hash_update().
|
||||
*
|
||||
* When this function returns successfully, the operation becomes inactive.
|
||||
* If this function returns an error status, the operation enters an error
|
||||
* state and must be aborted by calling mbedtls_psa_hash_abort().
|
||||
*
|
||||
* \param[in,out] operation Active hash operation.
|
||||
* \param[out] hash Buffer where the hash is to be written.
|
||||
* \param hash_size Size of the \p hash buffer in bytes.
|
||||
* \param[out] hash_length On success, the number of bytes
|
||||
* that make up the hash value. This is always
|
||||
* #PSA_HASH_LENGTH(\c alg) where \c alg is the
|
||||
* hash algorithm that is calculated.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The operation state is not valid (it must be active).
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p hash buffer is too small. You can determine a
|
||||
* sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg)
|
||||
* where \c alg is the hash algorithm that is calculated.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_hash_finish(
|
||||
mbedtls_psa_hash_operation_t *operation,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length);
|
||||
|
||||
/** Abort an Mbed TLS hash operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver hash_abort
|
||||
* entry point. This function behaves as a hash_abort entry point as
|
||||
* defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* Aborting an operation frees all associated resources except for the
|
||||
* \p operation structure itself. Once aborted, the operation object
|
||||
* can be reused for another operation by calling
|
||||
* mbedtls_psa_hash_setup() again.
|
||||
*
|
||||
* You may call this function any time after the operation object has
|
||||
* been initialized by one of the methods described in #psa_hash_operation_t.
|
||||
*
|
||||
* In particular, calling mbedtls_psa_hash_abort() after the operation has been
|
||||
* terminated by a call to mbedtls_psa_hash_abort(), mbedtls_psa_hash_finish() or
|
||||
* mbedtls_psa_hash_verify() is safe and has no effect.
|
||||
*
|
||||
* \param[in,out] operation Initialized hash operation.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_hash_abort(
|
||||
mbedtls_psa_hash_operation_t *operation);
|
||||
|
||||
#endif /* PSA_CRYPTO_HASH_H */
|
||||
92
Libs/util/third_party/mbedtls/library/psa_crypto_invasive.h
vendored
Normal file
92
Libs/util/third_party/mbedtls/library/psa_crypto_invasive.h
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* \file psa_crypto_invasive.h
|
||||
*
|
||||
* \brief PSA cryptography module: invasive interfaces for test only.
|
||||
*
|
||||
* The interfaces in this file are intended for testing purposes only.
|
||||
* They MUST NOT be made available to clients over IPC in integrations
|
||||
* with isolation, and they SHOULD NOT be made available in library
|
||||
* integrations except when building the library for testing.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_INVASIVE_H
|
||||
#define PSA_CRYPTO_INVASIVE_H
|
||||
|
||||
/*
|
||||
* Include the build-time configuration information header. Here, we do not
|
||||
* include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which
|
||||
* is basically just an alias to it. This is to ease the maintenance of the
|
||||
* TF-PSA-Crypto repository which has a different build system and
|
||||
* configuration.
|
||||
*/
|
||||
#include "psa/build_info.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "mbedtls/entropy.h"
|
||||
|
||||
#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
|
||||
/** \brief Configure entropy sources.
|
||||
*
|
||||
* This function may only be called before a call to psa_crypto_init(),
|
||||
* or after a call to mbedtls_psa_crypto_free() and before any
|
||||
* subsequent call to psa_crypto_init().
|
||||
*
|
||||
* This function is only intended for test purposes. The functionality
|
||||
* it provides is also useful for system integrators, but
|
||||
* system integrators should configure entropy drivers instead of
|
||||
* breaking through to the Mbed TLS API.
|
||||
*
|
||||
* \param entropy_init Function to initialize the entropy context
|
||||
* and set up the desired entropy sources.
|
||||
* It is called by psa_crypto_init().
|
||||
* By default this is mbedtls_entropy_init().
|
||||
* This function cannot report failures directly.
|
||||
* To indicate a failure, set the entropy context
|
||||
* to a state where mbedtls_entropy_func() will
|
||||
* return an error.
|
||||
* \param entropy_free Function to free the entropy context
|
||||
* and associated resources.
|
||||
* It is called by mbedtls_psa_crypto_free().
|
||||
* By default this is mbedtls_entropy_free().
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* The caller does not have the permission to configure
|
||||
* entropy sources.
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The library has already been initialized.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
|
||||
void (* entropy_init)(mbedtls_entropy_context *ctx),
|
||||
void (* entropy_free)(mbedtls_entropy_context *ctx));
|
||||
#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
psa_status_t psa_mac_key_can_do(
|
||||
psa_algorithm_t algorithm,
|
||||
psa_key_type_t key_type);
|
||||
|
||||
psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len,
|
||||
uint8_t *input_copy, size_t input_copy_len);
|
||||
|
||||
psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len,
|
||||
uint8_t *output, size_t output_len);
|
||||
|
||||
/*
|
||||
* Test hooks to use for memory unpoisoning/poisoning in copy functions.
|
||||
*/
|
||||
extern void (*psa_input_pre_copy_hook)(const uint8_t *input, size_t input_len);
|
||||
extern void (*psa_input_post_copy_hook)(const uint8_t *input, size_t input_len);
|
||||
extern void (*psa_output_pre_copy_hook)(const uint8_t *output, size_t output_len);
|
||||
extern void (*psa_output_post_copy_hook)(const uint8_t *output, size_t output_len);
|
||||
|
||||
#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
#endif /* PSA_CRYPTO_INVASIVE_H */
|
||||
131
Libs/util/third_party/mbedtls/library/psa_crypto_its.h
vendored
Normal file
131
Libs/util/third_party/mbedtls/library/psa_crypto_its.h
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
/** \file psa_crypto_its.h
|
||||
* \brief Interface of trusted storage that crypto is built on.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_ITS_H
|
||||
#define PSA_CRYPTO_ITS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <psa/crypto_types.h>
|
||||
#include <psa/crypto_values.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Flags used when creating a data entry
|
||||
*/
|
||||
typedef uint32_t psa_storage_create_flags_t;
|
||||
|
||||
/** \brief A type for UIDs used for identifying data
|
||||
*/
|
||||
typedef uint64_t psa_storage_uid_t;
|
||||
|
||||
#define PSA_STORAGE_FLAG_NONE 0 /**< No flags to pass */
|
||||
#define PSA_STORAGE_FLAG_WRITE_ONCE (1 << 0) /**< The data associated with the uid will not be able to be modified or deleted. Intended to be used to set bits in `psa_storage_create_flags_t`*/
|
||||
|
||||
/**
|
||||
* \brief A container for metadata associated with a specific uid
|
||||
*/
|
||||
struct psa_storage_info_t {
|
||||
uint32_t size; /**< The size of the data associated with a uid **/
|
||||
psa_storage_create_flags_t flags; /**< The flags set when the uid was created **/
|
||||
};
|
||||
|
||||
/** Flag indicating that \ref psa_storage_create and \ref psa_storage_set_extended are supported */
|
||||
#define PSA_STORAGE_SUPPORT_SET_EXTENDED (1 << 0)
|
||||
|
||||
#define PSA_ITS_API_VERSION_MAJOR 1 /**< The major version number of the PSA ITS API. It will be incremented on significant updates that may include breaking changes */
|
||||
#define PSA_ITS_API_VERSION_MINOR 1 /**< The minor version number of the PSA ITS API. It will be incremented in small updates that are unlikely to include breaking changes */
|
||||
|
||||
/**
|
||||
* \brief create a new or modify an existing uid/value pair
|
||||
*
|
||||
* \param[in] uid the identifier for the data
|
||||
* \param[in] data_length The size in bytes of the data in `p_data`
|
||||
* \param[in] p_data A buffer containing the data
|
||||
* \param[in] create_flags The flags that the data will be stored with
|
||||
*
|
||||
* \return A status indicating the success/failure of the operation
|
||||
*
|
||||
* \retval #PSA_SUCCESS The operation completed successfully
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided `uid` value was already created with PSA_STORAGE_FLAG_WRITE_ONCE
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED The operation failed because one or more of the flags provided in `create_flags` is not supported or is not valid
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE The operation failed because there was insufficient space on the storage medium
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`)
|
||||
* is invalid, for example is `NULL` or references memory the caller cannot access
|
||||
*/
|
||||
psa_status_t psa_its_set(psa_storage_uid_t uid,
|
||||
uint32_t data_length,
|
||||
const void *p_data,
|
||||
psa_storage_create_flags_t create_flags);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the value associated with a provided uid
|
||||
*
|
||||
* \param[in] uid The uid value
|
||||
* \param[in] data_offset The starting offset of the data requested
|
||||
* \param[in] data_length the amount of data requested (and the minimum allocated size of the `p_data` buffer)
|
||||
* \param[out] p_data The buffer where the data will be placed upon successful completion
|
||||
* \param[out] p_data_length The amount of data returned in the p_data buffer
|
||||
*
|
||||
*
|
||||
* \return A status indicating the success/failure of the operation
|
||||
*
|
||||
* \retval #PSA_SUCCESS The operation completed successfully
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided `uid` value was not found in the storage
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT The operation failed because stored data has been corrupted
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`, `p_data_length`)
|
||||
* is invalid. For example is `NULL` or references memory the caller cannot access.
|
||||
* In addition, this can also happen if an invalid offset was provided.
|
||||
*/
|
||||
psa_status_t psa_its_get(psa_storage_uid_t uid,
|
||||
uint32_t data_offset,
|
||||
uint32_t data_length,
|
||||
void *p_data,
|
||||
size_t *p_data_length);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the metadata about the provided uid
|
||||
*
|
||||
* \param[in] uid The uid value
|
||||
* \param[out] p_info A pointer to the `psa_storage_info_t` struct that will be populated with the metadata
|
||||
*
|
||||
* \return A status indicating the success/failure of the operation
|
||||
*
|
||||
* \retval #PSA_SUCCESS The operation completed successfully
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided uid value was not found in the storage
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT The operation failed because stored data has been corrupted
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_info`)
|
||||
* is invalid, for example is `NULL` or references memory the caller cannot access
|
||||
*/
|
||||
psa_status_t psa_its_get_info(psa_storage_uid_t uid,
|
||||
struct psa_storage_info_t *p_info);
|
||||
|
||||
/**
|
||||
* \brief Remove the provided key and its associated data from the storage
|
||||
*
|
||||
* \param[in] uid The uid value
|
||||
*
|
||||
* \return A status indicating the success/failure of the operation
|
||||
*
|
||||
* \retval #PSA_SUCCESS The operation completed successfully
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided key value was not found in the storage
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided key value was created with PSA_STORAGE_FLAG_WRITE_ONCE
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
|
||||
*/
|
||||
psa_status_t psa_its_remove(psa_storage_uid_t uid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_ITS_H */
|
||||
496
Libs/util/third_party/mbedtls/library/psa_crypto_mac.c
vendored
Normal file
496
Libs/util/third_party/mbedtls/library/psa_crypto_mac.c
vendored
Normal file
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
* PSA MAC layer on top of Mbed TLS software crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_cipher.h"
|
||||
#include "psa_crypto_mac.h"
|
||||
#include <mbedtls/md.h>
|
||||
|
||||
#include <mbedtls/error.h>
|
||||
#include "mbedtls/constant_time.h"
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
|
||||
static psa_status_t psa_hmac_abort_internal(
|
||||
mbedtls_psa_hmac_operation_t *hmac)
|
||||
{
|
||||
mbedtls_platform_zeroize(hmac->opad, sizeof(hmac->opad));
|
||||
return psa_hash_abort(&hmac->hash_ctx);
|
||||
}
|
||||
|
||||
static psa_status_t psa_hmac_setup_internal(
|
||||
mbedtls_psa_hmac_operation_t *hmac,
|
||||
const uint8_t *key,
|
||||
size_t key_length,
|
||||
psa_algorithm_t hash_alg)
|
||||
{
|
||||
uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
|
||||
size_t i;
|
||||
size_t hash_size = PSA_HASH_LENGTH(hash_alg);
|
||||
size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
|
||||
psa_status_t status;
|
||||
|
||||
hmac->alg = hash_alg;
|
||||
|
||||
/* Sanity checks on block_size, to guarantee that there won't be a buffer
|
||||
* overflow below. This should never trigger if the hash algorithm
|
||||
* is implemented correctly. */
|
||||
/* The size checks against the ipad and opad buffers cannot be written
|
||||
* `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
|
||||
* because that triggers -Wlogical-op on GCC 7.3. */
|
||||
if (block_size > sizeof(ipad)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
if (block_size > sizeof(hmac->opad)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
if (block_size < hash_size) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (key_length > block_size) {
|
||||
status = psa_hash_compute(hash_alg, key, key_length,
|
||||
ipad, sizeof(ipad), &key_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
/* A 0-length key is not commonly used in HMAC when used as a MAC,
|
||||
* but it is permitted. It is common when HMAC is used in HKDF, for
|
||||
* example. Don't call `memcpy` in the 0-length because `key` could be
|
||||
* an invalid pointer which would make the behavior undefined. */
|
||||
else if (key_length != 0) {
|
||||
memcpy(ipad, key, key_length);
|
||||
}
|
||||
|
||||
/* ipad contains the key followed by garbage. Xor and fill with 0x36
|
||||
* to create the ipad value. */
|
||||
for (i = 0; i < key_length; i++) {
|
||||
ipad[i] ^= 0x36;
|
||||
}
|
||||
memset(ipad + key_length, 0x36, block_size - key_length);
|
||||
|
||||
/* Copy the key material from ipad to opad, flipping the requisite bits,
|
||||
* and filling the rest of opad with the requisite constant. */
|
||||
for (i = 0; i < key_length; i++) {
|
||||
hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
|
||||
}
|
||||
memset(hmac->opad + key_length, 0x5C, block_size - key_length);
|
||||
|
||||
status = psa_hash_setup(&hmac->hash_ctx, hash_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&hmac->hash_ctx, ipad, block_size);
|
||||
|
||||
cleanup:
|
||||
mbedtls_platform_zeroize(ipad, sizeof(ipad));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static psa_status_t psa_hmac_update_internal(
|
||||
mbedtls_psa_hmac_operation_t *hmac,
|
||||
const uint8_t *data,
|
||||
size_t data_length)
|
||||
{
|
||||
return psa_hash_update(&hmac->hash_ctx, data, data_length);
|
||||
}
|
||||
|
||||
static psa_status_t psa_hmac_finish_internal(
|
||||
mbedtls_psa_hmac_operation_t *hmac,
|
||||
uint8_t *mac,
|
||||
size_t mac_size)
|
||||
{
|
||||
uint8_t tmp[PSA_HASH_MAX_SIZE];
|
||||
psa_algorithm_t hash_alg = hmac->alg;
|
||||
size_t hash_size = 0;
|
||||
size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_hash_finish(&hmac->hash_ctx, tmp, sizeof(tmp), &hash_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
/* From here on, tmp needs to be wiped. */
|
||||
|
||||
status = psa_hash_setup(&hmac->hash_ctx, hash_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&hmac->hash_ctx, hmac->opad, block_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&hmac->hash_ctx, tmp, hash_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_finish(&hmac->hash_ctx, tmp, sizeof(tmp), &hash_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(mac, tmp, mac_size);
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(tmp, hash_size);
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
static psa_status_t cmac_setup(mbedtls_psa_mac_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_DES)
|
||||
/* Mbed TLS CMAC does not accept 3DES with only two keys, nor does it accept
|
||||
* to do CMAC with pure DES, so return NOT_SUPPORTED here. */
|
||||
if (psa_get_key_type(attributes) == PSA_KEY_TYPE_DES &&
|
||||
(psa_get_key_bits(attributes) == 64 ||
|
||||
psa_get_key_bits(attributes) == 128)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
const mbedtls_cipher_info_t *cipher_info =
|
||||
mbedtls_cipher_info_from_psa(
|
||||
PSA_ALG_CMAC,
|
||||
psa_get_key_type(attributes),
|
||||
psa_get_key_bits(attributes),
|
||||
NULL);
|
||||
|
||||
if (cipher_info == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
ret = mbedtls_cipher_setup(&operation->ctx.cmac, cipher_info);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_cipher_cmac_starts(&operation->ctx.cmac,
|
||||
key_buffer,
|
||||
psa_get_key_bits(attributes));
|
||||
exit:
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
|
||||
/* Initialize this driver's MAC operation structure. Once this function has been
|
||||
* called, mbedtls_psa_mac_abort can run and will do the right thing. */
|
||||
static psa_status_t mac_init(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
operation->alg = alg;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
|
||||
mbedtls_cipher_init(&operation->ctx.cmac);
|
||||
status = PSA_SUCCESS;
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
|
||||
if (PSA_ALG_IS_HMAC(operation->alg)) {
|
||||
/* We'll set up the hash operation later in psa_hmac_setup_internal. */
|
||||
operation->ctx.hmac.alg = 0;
|
||||
status = PSA_SUCCESS;
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
|
||||
{
|
||||
(void) operation;
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
memset(operation, 0, sizeof(*operation));
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_abort(mbedtls_psa_mac_operation_t *operation)
|
||||
{
|
||||
if (operation->alg == 0) {
|
||||
/* The object has (apparently) been initialized but it is not
|
||||
* in use. It's ok to call abort on such an object, and there's
|
||||
* nothing to do. */
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
|
||||
mbedtls_cipher_free(&operation->ctx.cmac);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
|
||||
if (PSA_ALG_IS_HMAC(operation->alg)) {
|
||||
psa_hmac_abort_internal(&operation->ctx.hmac);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
|
||||
{
|
||||
/* Sanity check (shouldn't happen: operation->alg should
|
||||
* always have been initialized to a valid value). */
|
||||
goto bad_state;
|
||||
}
|
||||
|
||||
operation->alg = 0;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
|
||||
bad_state:
|
||||
/* If abort is called on an uninitialized object, we can't trust
|
||||
* anything. Wipe the object in case it contains confidential data.
|
||||
* This may result in a memory leak if a pointer gets overwritten,
|
||||
* but it's too late to do anything about this. */
|
||||
memset(operation, 0, sizeof(*operation));
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
static psa_status_t psa_mac_setup(mbedtls_psa_mac_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* A context must be freshly initialized before it can be set up. */
|
||||
if (operation->alg != 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
status = mac_init(operation, alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
if (PSA_ALG_FULL_LENGTH_MAC(alg) == PSA_ALG_CMAC) {
|
||||
/* Key buffer size for CMAC is dictated by the key bits set on the
|
||||
* attributes, and previously validated by the core on key import. */
|
||||
(void) key_buffer_size;
|
||||
status = cmac_setup(operation, attributes, key_buffer);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
|
||||
if (PSA_ALG_IS_HMAC(alg)) {
|
||||
status = psa_hmac_setup_internal(&operation->ctx.hmac,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
PSA_ALG_HMAC_GET_HASH(alg));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
|
||||
{
|
||||
(void) attributes;
|
||||
(void) key_buffer;
|
||||
(void) key_buffer_size;
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_psa_mac_abort(operation);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_sign_setup(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
return psa_mac_setup(operation, attributes,
|
||||
key_buffer, key_buffer_size, alg);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_verify_setup(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
return psa_mac_setup(operation, attributes,
|
||||
key_buffer, key_buffer_size, alg);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_update(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
if (operation->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
|
||||
return mbedtls_to_psa_error(
|
||||
mbedtls_cipher_cmac_update(&operation->ctx.cmac,
|
||||
input, input_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
|
||||
if (PSA_ALG_IS_HMAC(operation->alg)) {
|
||||
return psa_hmac_update_internal(&operation->ctx.hmac,
|
||||
input, input_length);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
|
||||
{
|
||||
/* This shouldn't happen if `operation` was initialized by
|
||||
* a setup function. */
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
static psa_status_t psa_mac_finish_internal(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
uint8_t *mac, size_t mac_size)
|
||||
{
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
|
||||
uint8_t tmp[PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE];
|
||||
int ret = mbedtls_cipher_cmac_finish(&operation->ctx.cmac, tmp);
|
||||
if (ret == 0) {
|
||||
memcpy(mac, tmp, mac_size);
|
||||
}
|
||||
mbedtls_platform_zeroize(tmp, sizeof(tmp));
|
||||
return mbedtls_to_psa_error(ret);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
|
||||
if (PSA_ALG_IS_HMAC(operation->alg)) {
|
||||
return psa_hmac_finish_internal(&operation->ctx.hmac,
|
||||
mac, mac_size);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
|
||||
{
|
||||
/* This shouldn't happen if `operation` was initialized by
|
||||
* a setup function. */
|
||||
(void) operation;
|
||||
(void) mac;
|
||||
(void) mac_size;
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_sign_finish(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (operation->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
status = psa_mac_finish_internal(operation, mac, mac_size);
|
||||
if (status == PSA_SUCCESS) {
|
||||
*mac_length = mac_size;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_verify_finish(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
const uint8_t *mac,
|
||||
size_t mac_length)
|
||||
{
|
||||
uint8_t actual_mac[PSA_MAC_MAX_SIZE];
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (operation->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
/* Consistency check: requested MAC length fits our local buffer */
|
||||
if (mac_length > sizeof(actual_mac)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
status = psa_mac_finish_internal(operation, actual_mac, mac_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (mbedtls_ct_memcmp(mac, actual_mac, mac_length) != 0) {
|
||||
status = PSA_ERROR_INVALID_SIGNATURE;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_compute(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_psa_mac_operation_t operation = MBEDTLS_PSA_MAC_OPERATION_INIT;
|
||||
|
||||
status = psa_mac_setup(&operation,
|
||||
attributes, key_buffer, key_buffer_size,
|
||||
alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (input_length > 0) {
|
||||
status = mbedtls_psa_mac_update(&operation, input, input_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
status = psa_mac_finish_internal(&operation, mac, mac_size);
|
||||
if (status == PSA_SUCCESS) {
|
||||
*mac_length = mac_size;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_psa_mac_abort(&operation);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC || MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
264
Libs/util/third_party/mbedtls/library/psa_crypto_mac.h
vendored
Normal file
264
Libs/util/third_party/mbedtls/library/psa_crypto_mac.h
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* PSA MAC layer on top of Mbed TLS software crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_MAC_H
|
||||
#define PSA_CRYPTO_MAC_H
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
/** Calculate the MAC (message authentication code) of a message using Mbed TLS.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver mac_compute
|
||||
* entry point. This function behaves as a mac_compute entry point as
|
||||
* defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the key to use for
|
||||
* computing the MAC. This buffer contains the key
|
||||
* in export representation as defined by
|
||||
* psa_export_key() (i.e. the raw key bytes).
|
||||
* \param key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param alg The MAC algorithm to use (\c PSA_ALG_XXX value
|
||||
* such that #PSA_ALG_IS_MAC(\p alg) is true).
|
||||
* \param[in] input Buffer containing the input message.
|
||||
* \param input_length Size of the \p input buffer in bytes.
|
||||
* \param[out] mac Buffer where the MAC value is to be written.
|
||||
* \param mac_size Size of the \p mac buffer in bytes.
|
||||
* \param[out] mac_length On success, the number of bytes
|
||||
* that make up the MAC value.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \p alg is not supported.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p mac_size is too small
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_mac_compute(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length);
|
||||
|
||||
/** Set up a multipart MAC calculation operation using Mbed TLS.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver mac_sign_setup
|
||||
* entry point. This function behaves as a mac_sign_setup entry point as
|
||||
* defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* \param[in,out] operation The operation object to set up. It must have
|
||||
* been initialized and not yet in use.
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the key to use for
|
||||
* computing the MAC. This buffer contains the key
|
||||
* in export representation as defined by
|
||||
* psa_export_key() (i.e. the raw key bytes).
|
||||
* \param key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param alg The MAC algorithm to use (\c PSA_ALG_XXX value
|
||||
* such that #PSA_ALG_IS_MAC(\p alg) is true).
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \p alg is not supported.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The operation state is not valid (it must be inactive).
|
||||
*/
|
||||
psa_status_t mbedtls_psa_mac_sign_setup(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
/** Set up a multipart MAC verification operation using Mbed TLS.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver mac_verify_setup
|
||||
* entry point. This function behaves as a mac_verify_setup entry point as
|
||||
* defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* \param[in,out] operation The operation object to set up. It must have
|
||||
* been initialized and not yet in use.
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the key to use for
|
||||
* computing the MAC. This buffer contains the key
|
||||
* in export representation as defined by
|
||||
* psa_export_key() (i.e. the raw key bytes).
|
||||
* \param key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param alg The MAC algorithm to use (\c PSA_ALG_XXX value
|
||||
* such that #PSA_ALG_IS_MAC(\p alg) is true).
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \p alg is not supported.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The operation state is not valid (it must be inactive).
|
||||
*/
|
||||
psa_status_t mbedtls_psa_mac_verify_setup(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
/** Add a message fragment to a multipart MAC operation using Mbed TLS.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver mac_update
|
||||
* entry point. This function behaves as a mac_update entry point as
|
||||
* defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* The PSA core calls mbedtls_psa_mac_sign_setup() or
|
||||
* mbedtls_psa_mac_verify_setup() before calling this function.
|
||||
*
|
||||
* If this function returns an error status, the PSA core aborts the
|
||||
* operation by calling mbedtls_psa_mac_abort().
|
||||
*
|
||||
* \param[in,out] operation Active MAC operation.
|
||||
* \param[in] input Buffer containing the message fragment to add to
|
||||
* the MAC calculation.
|
||||
* \param input_length Size of the \p input buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The operation state is not valid (it must be active).
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_mac_update(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length);
|
||||
|
||||
/** Finish the calculation of the MAC of a message using Mbed TLS.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver mac_sign_finish
|
||||
* entry point. This function behaves as a mac_sign_finish entry point as
|
||||
* defined in the PSA driver interface specification for transparent
|
||||
* drivers.
|
||||
*
|
||||
* The PSA core calls mbedtls_psa_mac_sign_setup() before calling this function.
|
||||
* This function calculates the MAC of the message formed by concatenating
|
||||
* the inputs passed to preceding calls to mbedtls_psa_mac_update().
|
||||
*
|
||||
* Whether this function returns successfully or not, the PSA core subsequently
|
||||
* aborts the operation by calling mbedtls_psa_mac_abort().
|
||||
*
|
||||
* \param[in,out] operation Active MAC operation.
|
||||
* \param[out] mac Buffer where the MAC value is to be written.
|
||||
* \param mac_size Output size requested for the MAC algorithm. The PSA
|
||||
* core guarantees this is a valid MAC length for the
|
||||
* algorithm and key combination passed to
|
||||
* mbedtls_psa_mac_sign_setup(). It also guarantees the
|
||||
* \p mac buffer is large enough to contain the
|
||||
* requested output size.
|
||||
* \param[out] mac_length On success, the number of bytes output to buffer
|
||||
* \p mac, which will be equal to the requested length
|
||||
* \p mac_size.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The operation state is not valid (it must be an active mac sign
|
||||
* operation).
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p mac buffer is too small. A sufficient buffer size
|
||||
* can be determined by calling PSA_MAC_LENGTH().
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_mac_sign_finish(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length);
|
||||
|
||||
/** Finish the calculation of the MAC of a message and compare it with
|
||||
* an expected value using Mbed TLS.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* mac_verify_finish entry point. This function behaves as a
|
||||
* mac_verify_finish entry point as defined in the PSA driver interface
|
||||
* specification for transparent drivers.
|
||||
*
|
||||
* The PSA core calls mbedtls_psa_mac_verify_setup() before calling this
|
||||
* function. This function calculates the MAC of the message formed by
|
||||
* concatenating the inputs passed to preceding calls to
|
||||
* mbedtls_psa_mac_update(). It then compares the calculated MAC with the
|
||||
* expected MAC passed as a parameter to this function.
|
||||
*
|
||||
* Whether this function returns successfully or not, the PSA core subsequently
|
||||
* aborts the operation by calling mbedtls_psa_mac_abort().
|
||||
*
|
||||
* \param[in,out] operation Active MAC operation.
|
||||
* \param[in] mac Buffer containing the expected MAC value.
|
||||
* \param mac_length Length in bytes of the expected MAC value. The PSA
|
||||
* core guarantees that this length is a valid MAC
|
||||
* length for the algorithm and key combination passed
|
||||
* to mbedtls_psa_mac_verify_setup().
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The expected MAC is identical to the actual MAC of the message.
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
* The MAC of the message was calculated successfully, but it
|
||||
* differs from the expected MAC.
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The operation state is not valid (it must be an active mac verify
|
||||
* operation).
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_mac_verify_finish(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
const uint8_t *mac,
|
||||
size_t mac_length);
|
||||
|
||||
/** Abort a MAC operation using Mbed TLS.
|
||||
*
|
||||
* Aborting an operation frees all associated resources except for the
|
||||
* \p operation structure itself. Once aborted, the operation object
|
||||
* can be reused for another operation by calling
|
||||
* mbedtls_psa_mac_sign_setup() or mbedtls_psa_mac_verify_setup() again.
|
||||
*
|
||||
* The PSA core may call this function any time after the operation object has
|
||||
* been initialized by one of the methods described in
|
||||
* #mbedtls_psa_mac_operation_t.
|
||||
*
|
||||
* In particular, calling mbedtls_psa_mac_abort() after the operation has been
|
||||
* terminated by a call to mbedtls_psa_mac_abort(),
|
||||
* mbedtls_psa_mac_sign_finish() or mbedtls_psa_mac_verify_finish() is safe and
|
||||
* has no effect.
|
||||
*
|
||||
* \param[in,out] operation Initialized MAC operation.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_mac_abort(
|
||||
mbedtls_psa_mac_operation_t *operation);
|
||||
|
||||
#endif /* PSA_CRYPTO_MAC_H */
|
||||
571
Libs/util/third_party/mbedtls/library/psa_crypto_pake.c
vendored
Normal file
571
Libs/util/third_party/mbedtls/library/psa_crypto_pake.c
vendored
Normal file
@@ -0,0 +1,571 @@
|
||||
/*
|
||||
* PSA PAKE layer on top of Mbed TLS software crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_pake.h"
|
||||
#include "psa_crypto_slot_management.h"
|
||||
|
||||
#include <mbedtls/ecjpake.h>
|
||||
#include "psa_util_internal.h"
|
||||
|
||||
#include <mbedtls/platform.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* State sequence:
|
||||
*
|
||||
* psa_pake_setup()
|
||||
* |
|
||||
* |-- In any order:
|
||||
* | | psa_pake_set_password_key()
|
||||
* | | psa_pake_set_user()
|
||||
* | | psa_pake_set_peer()
|
||||
* | | psa_pake_set_role()
|
||||
* |
|
||||
* |--- In any order: (First round input before or after first round output)
|
||||
* | |
|
||||
* | |------ In Order
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* | |
|
||||
* | |------ In Order:
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* |
|
||||
* |--- In any order: (Second round input before or after second round output)
|
||||
* | |
|
||||
* | |------ In Order
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* | |
|
||||
* | |------ In Order:
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* |
|
||||
* psa_pake_get_implicit_key()
|
||||
* psa_pake_abort()
|
||||
*/
|
||||
|
||||
/*
|
||||
* Possible sequence of calls to implementation:
|
||||
*
|
||||
* |--- In any order:
|
||||
* | |
|
||||
* | |------ In Order
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_KEY_SHARE)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_ZK_PUBLIC)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_ZK_PROOF)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_KEY_SHARE)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_ZK_PUBLIC)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_ZK_PROOF)
|
||||
* | |
|
||||
* | |------ In Order:
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_KEY_SHARE)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_ZK_PUBLIC)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_ZK_PROOF)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_KEY_SHARE)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_ZK_PUBLIC)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_ZK_PROOF)
|
||||
* |
|
||||
* |--- In any order:
|
||||
* | |
|
||||
* | |------ In Order
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_KEY_SHARE)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_ZK_PUBLIC)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_ZK_PROOF)
|
||||
* | |
|
||||
* | |------ In Order:
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_KEY_SHARE)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_ZK_PUBLIC)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_ZK_PROOF)
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
static psa_status_t mbedtls_ecjpake_to_psa_error(int ret)
|
||||
{
|
||||
switch (ret) {
|
||||
case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_ECP_INVALID_KEY:
|
||||
case MBEDTLS_ERR_ECP_VERIFY_FAILED:
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
|
||||
case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
default:
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
static psa_status_t psa_pake_ecjpake_setup(mbedtls_psa_pake_operation_t *operation)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
mbedtls_ecjpake_init(&operation->ctx.jpake);
|
||||
|
||||
ret = mbedtls_ecjpake_setup(&operation->ctx.jpake,
|
||||
operation->role,
|
||||
MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_ECP_DP_SECP256R1,
|
||||
operation->password,
|
||||
operation->password_len);
|
||||
|
||||
mbedtls_platform_zeroize(operation->password, operation->password_len);
|
||||
|
||||
if (ret != 0) {
|
||||
return mbedtls_ecjpake_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The only two JPAKE user/peer identifiers supported in built-in implementation. */
|
||||
static const uint8_t jpake_server_id[] = { 's', 'e', 'r', 'v', 'e', 'r' };
|
||||
static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' };
|
||||
|
||||
psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation,
|
||||
const psa_crypto_driver_pake_inputs_t *inputs)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t user_len = 0, peer_len = 0, password_len = 0;
|
||||
uint8_t *peer = NULL, *user = NULL;
|
||||
size_t actual_user_len = 0, actual_peer_len = 0, actual_password_len = 0;
|
||||
psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
|
||||
|
||||
status = psa_crypto_driver_pake_get_password_len(inputs, &password_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_user_len(inputs, &user_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_peer_len(inputs, &peer_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_cipher_suite(inputs, &cipher_suite);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
operation->password = mbedtls_calloc(1, password_len);
|
||||
if (operation->password == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
user = mbedtls_calloc(1, user_len);
|
||||
if (user == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
peer = mbedtls_calloc(1, peer_len);
|
||||
if (peer == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_password(inputs, operation->password,
|
||||
password_len, &actual_password_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_user(inputs, user,
|
||||
user_len, &actual_user_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_peer(inputs, peer,
|
||||
peer_len, &actual_peer_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
operation->password_len = actual_password_len;
|
||||
operation->alg = cipher_suite.algorithm;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
if (cipher_suite.algorithm == PSA_ALG_JPAKE) {
|
||||
if (cipher_suite.type != PSA_PAKE_PRIMITIVE_TYPE_ECC ||
|
||||
cipher_suite.family != PSA_ECC_FAMILY_SECP_R1 ||
|
||||
cipher_suite.bits != 256 ||
|
||||
cipher_suite.hash != PSA_ALG_SHA_256) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
const size_t user_peer_len = sizeof(jpake_client_id); // client and server have the same length
|
||||
if (actual_user_len != user_peer_len ||
|
||||
actual_peer_len != user_peer_len) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (memcmp(user, jpake_client_id, actual_user_len) == 0 &&
|
||||
memcmp(peer, jpake_server_id, actual_peer_len) == 0) {
|
||||
operation->role = MBEDTLS_ECJPAKE_CLIENT;
|
||||
} else
|
||||
if (memcmp(user, jpake_server_id, actual_user_len) == 0 &&
|
||||
memcmp(peer, jpake_client_id, actual_peer_len) == 0) {
|
||||
operation->role = MBEDTLS_ECJPAKE_SERVER;
|
||||
} else {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
|
||||
status = psa_pake_ecjpake_setup(operation);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Role has been set, release user/peer buffers. */
|
||||
mbedtls_free(user); mbedtls_free(peer);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#else
|
||||
(void) operation;
|
||||
(void) inputs;
|
||||
#endif
|
||||
{ status = PSA_ERROR_NOT_SUPPORTED; }
|
||||
|
||||
error:
|
||||
mbedtls_free(user); mbedtls_free(peer);
|
||||
/* In case of failure of the setup of a multipart operation, the PSA driver interface
|
||||
* specifies that the core does not call any other driver entry point thus does not
|
||||
* call mbedtls_psa_pake_abort(). Therefore call it here to do the needed clean
|
||||
* up like freeing the memory that may have been allocated to store the password.
|
||||
*/
|
||||
mbedtls_psa_pake_abort(operation);
|
||||
return status;
|
||||
}
|
||||
|
||||
static psa_status_t mbedtls_psa_pake_output_internal(
|
||||
mbedtls_psa_pake_operation_t *operation,
|
||||
psa_crypto_driver_pake_step_t step,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t length;
|
||||
(void) step; // Unused parameter
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
/*
|
||||
* The PSA CRYPTO PAKE and Mbed TLS JPAKE API have a different
|
||||
* handling of output sequencing.
|
||||
*
|
||||
* The Mbed TLS JPAKE API outputs the whole X1+X2 and X2S steps data
|
||||
* at once, on the other side the PSA CRYPTO PAKE api requires
|
||||
* the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X2S to be
|
||||
* retrieved in sequence.
|
||||
*
|
||||
* In order to achieve API compatibility, the whole X1+X2 or X2S steps
|
||||
* data is stored in an intermediate buffer at first step output call,
|
||||
* and data is sliced down by parsing the ECPoint records in order
|
||||
* to return the right parts on each step.
|
||||
*/
|
||||
if (operation->alg == PSA_ALG_JPAKE) {
|
||||
/* Initialize & write round on KEY_SHARE sequences */
|
||||
if (step == PSA_JPAKE_X1_STEP_KEY_SHARE) {
|
||||
ret = mbedtls_ecjpake_write_round_one(&operation->ctx.jpake,
|
||||
operation->buffer,
|
||||
sizeof(operation->buffer),
|
||||
&operation->buffer_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE);
|
||||
if (ret != 0) {
|
||||
return mbedtls_ecjpake_to_psa_error(ret);
|
||||
}
|
||||
|
||||
operation->buffer_offset = 0;
|
||||
} else if (step == PSA_JPAKE_X2S_STEP_KEY_SHARE) {
|
||||
ret = mbedtls_ecjpake_write_round_two(&operation->ctx.jpake,
|
||||
operation->buffer,
|
||||
sizeof(operation->buffer),
|
||||
&operation->buffer_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE);
|
||||
if (ret != 0) {
|
||||
return mbedtls_ecjpake_to_psa_error(ret);
|
||||
}
|
||||
|
||||
operation->buffer_offset = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* mbedtls_ecjpake_write_round_xxx() outputs thing in the format
|
||||
* defined by draft-cragie-tls-ecjpake-01 section 7. The summary is
|
||||
* that the data for each step is prepended with a length byte, and
|
||||
* then they're concatenated. Additionally, the server's second round
|
||||
* output is prepended with a 3-bytes ECParameters structure.
|
||||
*
|
||||
* In PSA, we output each step separately, and don't prepend the
|
||||
* output with a length byte, even less a curve identifier, as that
|
||||
* information is already available.
|
||||
*/
|
||||
if (step == PSA_JPAKE_X2S_STEP_KEY_SHARE &&
|
||||
operation->role == MBEDTLS_ECJPAKE_SERVER) {
|
||||
/* Skip ECParameters, with is 3 bytes (RFC 8422) */
|
||||
operation->buffer_offset += 3;
|
||||
}
|
||||
|
||||
/* Read the length byte then move past it to the data */
|
||||
length = operation->buffer[operation->buffer_offset];
|
||||
operation->buffer_offset += 1;
|
||||
|
||||
if (operation->buffer_offset + length > operation->buffer_length) {
|
||||
return PSA_ERROR_DATA_CORRUPT;
|
||||
}
|
||||
|
||||
if (output_size < length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
memcpy(output,
|
||||
operation->buffer + operation->buffer_offset,
|
||||
length);
|
||||
*output_length = length;
|
||||
|
||||
operation->buffer_offset += length;
|
||||
|
||||
/* Reset buffer after ZK_PROOF sequence */
|
||||
if ((step == PSA_JPAKE_X2_STEP_ZK_PROOF) ||
|
||||
(step == PSA_JPAKE_X2S_STEP_ZK_PROOF)) {
|
||||
mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#else
|
||||
(void) step;
|
||||
(void) output;
|
||||
(void) output_size;
|
||||
(void) output_length;
|
||||
#endif
|
||||
{ return PSA_ERROR_NOT_SUPPORTED; }
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_pake_output(mbedtls_psa_pake_operation_t *operation,
|
||||
psa_crypto_driver_pake_step_t step,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status = mbedtls_psa_pake_output_internal(
|
||||
operation, step, output, output_size, output_length);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static psa_status_t mbedtls_psa_pake_input_internal(
|
||||
mbedtls_psa_pake_operation_t *operation,
|
||||
psa_crypto_driver_pake_step_t step,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
(void) step; // Unused parameter
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
/*
|
||||
* The PSA CRYPTO PAKE and Mbed TLS JPAKE API have a different
|
||||
* handling of input sequencing.
|
||||
*
|
||||
* The Mbed TLS JPAKE API takes the whole X1+X2 or X4S steps data
|
||||
* at once as input, on the other side the PSA CRYPTO PAKE api requires
|
||||
* the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X4S to be
|
||||
* given in sequence.
|
||||
*
|
||||
* In order to achieve API compatibility, each X1+X2 or X4S step data
|
||||
* is stored sequentially in an intermediate buffer and given to the
|
||||
* Mbed TLS JPAKE API on the last step.
|
||||
*
|
||||
* This causes any input error to be only detected on the last step.
|
||||
*/
|
||||
if (operation->alg == PSA_ALG_JPAKE) {
|
||||
/*
|
||||
* Copy input to local buffer and format it as the Mbed TLS API
|
||||
* expects, i.e. as defined by draft-cragie-tls-ecjpake-01 section 7.
|
||||
* The summary is that the data for each step is prepended with a
|
||||
* length byte, and then they're concatenated. Additionally, the
|
||||
* server's second round output is prepended with a 3-bytes
|
||||
* ECParameters structure - which means we have to prepend that when
|
||||
* we're a client.
|
||||
*/
|
||||
if (step == PSA_JPAKE_X4S_STEP_KEY_SHARE &&
|
||||
operation->role == MBEDTLS_ECJPAKE_CLIENT) {
|
||||
/* We only support secp256r1. */
|
||||
/* This is the ECParameters structure defined by RFC 8422. */
|
||||
unsigned char ecparameters[3] = {
|
||||
3, /* named_curve */
|
||||
0, 23 /* secp256r1 */
|
||||
};
|
||||
|
||||
if (operation->buffer_length + sizeof(ecparameters) >
|
||||
sizeof(operation->buffer)) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
memcpy(operation->buffer + operation->buffer_length,
|
||||
ecparameters, sizeof(ecparameters));
|
||||
operation->buffer_length += sizeof(ecparameters);
|
||||
}
|
||||
|
||||
/*
|
||||
* The core checks that input_length is smaller than
|
||||
* PSA_PAKE_INPUT_MAX_SIZE.
|
||||
* Thus no risk of integer overflow here.
|
||||
*/
|
||||
if (operation->buffer_length + input_length + 1 > sizeof(operation->buffer)) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Write the length byte */
|
||||
operation->buffer[operation->buffer_length] = (uint8_t) input_length;
|
||||
operation->buffer_length += 1;
|
||||
|
||||
/* Finally copy the data */
|
||||
memcpy(operation->buffer + operation->buffer_length,
|
||||
input, input_length);
|
||||
operation->buffer_length += input_length;
|
||||
|
||||
/* Load buffer at each last round ZK_PROOF */
|
||||
if (step == PSA_JPAKE_X2_STEP_ZK_PROOF) {
|
||||
ret = mbedtls_ecjpake_read_round_one(&operation->ctx.jpake,
|
||||
operation->buffer,
|
||||
operation->buffer_length);
|
||||
|
||||
mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
|
||||
operation->buffer_length = 0;
|
||||
|
||||
if (ret != 0) {
|
||||
return mbedtls_ecjpake_to_psa_error(ret);
|
||||
}
|
||||
} else if (step == PSA_JPAKE_X4S_STEP_ZK_PROOF) {
|
||||
ret = mbedtls_ecjpake_read_round_two(&operation->ctx.jpake,
|
||||
operation->buffer,
|
||||
operation->buffer_length);
|
||||
|
||||
mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
|
||||
operation->buffer_length = 0;
|
||||
|
||||
if (ret != 0) {
|
||||
return mbedtls_ecjpake_to_psa_error(ret);
|
||||
}
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#else
|
||||
(void) step;
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
#endif
|
||||
{ return PSA_ERROR_NOT_SUPPORTED; }
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_pake_input(mbedtls_psa_pake_operation_t *operation,
|
||||
psa_crypto_driver_pake_step_t step,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
psa_status_t status = mbedtls_psa_pake_input_internal(
|
||||
operation, step, input, input_length);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_pake_get_implicit_key(
|
||||
mbedtls_psa_pake_operation_t *operation,
|
||||
uint8_t *output, size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
if (operation->alg == PSA_ALG_JPAKE) {
|
||||
ret = mbedtls_ecjpake_write_shared_key(&operation->ctx.jpake,
|
||||
output,
|
||||
output_size,
|
||||
output_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE);
|
||||
if (ret != 0) {
|
||||
return mbedtls_ecjpake_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#else
|
||||
(void) output;
|
||||
#endif
|
||||
{ return PSA_ERROR_NOT_SUPPORTED; }
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_pake_abort(mbedtls_psa_pake_operation_t *operation)
|
||||
{
|
||||
mbedtls_zeroize_and_free(operation->password, operation->password_len);
|
||||
operation->password = NULL;
|
||||
operation->password_len = 0;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
if (operation->alg == PSA_ALG_JPAKE) {
|
||||
operation->role = MBEDTLS_ECJPAKE_NONE;
|
||||
mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
mbedtls_ecjpake_free(&operation->ctx.jpake);
|
||||
}
|
||||
#endif
|
||||
|
||||
operation->alg = PSA_ALG_NONE;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_PAKE */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
159
Libs/util/third_party/mbedtls/library/psa_crypto_pake.h
vendored
Normal file
159
Libs/util/third_party/mbedtls/library/psa_crypto_pake.h
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* PSA PAKE layer on top of Mbed TLS software crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_PAKE_H
|
||||
#define PSA_CRYPTO_PAKE_H
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
/** Set the session information for a password-authenticated key exchange.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* pake_setup entry point. This function behaves as a pake_setup
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \param[in,out] operation The operation object to set up. It must have
|
||||
* been initialized but not set up yet.
|
||||
* \param[in] inputs Inputs required for PAKE operation (role, password,
|
||||
* key lifetime, cipher suite)
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The algorithm in \p cipher_suite is not a supported PAKE algorithm,
|
||||
* or the PAKE primitive in \p cipher_suite is not supported or not
|
||||
* compatible with the PAKE algorithm, or the hash algorithm in
|
||||
* \p cipher_suite is not supported or not compatible with the PAKE
|
||||
* algorithm and primitive.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation,
|
||||
const psa_crypto_driver_pake_inputs_t *inputs);
|
||||
|
||||
|
||||
/** Get output for a step of a password-authenticated key exchange.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* pake_output entry point. This function behaves as a pake_output
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \param[in,out] operation Active PAKE operation.
|
||||
* \param step The step of the algorithm for which the output is
|
||||
* requested.
|
||||
* \param[out] output Buffer where the output is to be written in the
|
||||
* format appropriate for this driver \p step. Refer to
|
||||
* the documentation of psa_crypto_driver_pake_step_t for
|
||||
* more information.
|
||||
* \param output_size Size of the \p output buffer in bytes. This must
|
||||
* be at least #PSA_PAKE_OUTPUT_SIZE(\p alg, \p
|
||||
* primitive, \p step) where \p alg and
|
||||
* \p primitive are the PAKE algorithm and primitive
|
||||
* in the operation's cipher suite, and \p step is
|
||||
* the output step.
|
||||
*
|
||||
* \param[out] output_length On success, the number of bytes of the returned
|
||||
* output.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p output buffer is too small.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_pake_output(mbedtls_psa_pake_operation_t *operation,
|
||||
psa_crypto_driver_pake_step_t step,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
/** Provide input for a step of a password-authenticated key exchange.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* pake_input entry point. This function behaves as a pake_input
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \note The core checks that input_length is smaller than PSA_PAKE_INPUT_MAX_SIZE.
|
||||
*
|
||||
* \param[in,out] operation Active PAKE operation.
|
||||
* \param step The driver step for which the input is provided.
|
||||
* \param[in] input Buffer containing the input in the format
|
||||
* appropriate for this \p step. Refer to the
|
||||
* documentation of psa_crypto_driver_pake_step_t
|
||||
* for more information.
|
||||
* \param input_length Size of the \p input buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
* The verification fails for a zero-knowledge input step.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* the \p input is not valid for the \p operation's algorithm, cipher suite
|
||||
* or \p step.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* the \p input is not supported for the \p operation's algorithm, cipher
|
||||
* suite or \p step.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_pake_input(mbedtls_psa_pake_operation_t *operation,
|
||||
psa_crypto_driver_pake_step_t step,
|
||||
const uint8_t *input,
|
||||
size_t input_length);
|
||||
|
||||
/** Get implicitly confirmed shared secret from a PAKE.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* pake_get_implicit_key entry point. This function behaves as a
|
||||
* pake_get_implicit_key entry point as defined in the PSA driver
|
||||
* interface specification for transparent drivers.
|
||||
*
|
||||
* \param[in,out] operation Active PAKE operation.
|
||||
* \param[out] output Output buffer for implicit key.
|
||||
* \param output_size Size of the output buffer in bytes.
|
||||
* \param[out] output_length On success, the number of bytes of the implicit key.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* Input from a PAKE is not supported by the algorithm in the \p output
|
||||
* key derivation operation.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_pake_get_implicit_key(
|
||||
mbedtls_psa_pake_operation_t *operation,
|
||||
uint8_t *output, size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
/** Abort a PAKE operation.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* pake_abort entry point. This function behaves as a pake_abort
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \param[in,out] operation The operation to abort.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_pake_abort(mbedtls_psa_pake_operation_t *operation);
|
||||
|
||||
#endif /* PSA_CRYPTO_PAKE_H */
|
||||
126
Libs/util/third_party/mbedtls/library/psa_crypto_random_impl.h
vendored
Normal file
126
Libs/util/third_party/mbedtls/library/psa_crypto_random_impl.h
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
/** \file psa_crypto_random_impl.h
|
||||
*
|
||||
* \brief PSA crypto random generator implementation abstraction.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_RANDOM_IMPL_H
|
||||
#define PSA_CRYPTO_RANDOM_IMPL_H
|
||||
|
||||
#include "psa_util_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
|
||||
|
||||
typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t;
|
||||
|
||||
#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
|
||||
|
||||
#include "mbedtls/entropy.h"
|
||||
|
||||
/* Choose a DRBG based on configuration and availability */
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#undef MBEDTLS_PSA_HMAC_DRBG_MD_TYPE
|
||||
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
|
||||
#include "mbedtls/hmac_drbg.h"
|
||||
#if defined(MBEDTLS_MD_CAN_SHA512) && defined(MBEDTLS_MD_CAN_SHA256)
|
||||
#include <limits.h>
|
||||
#if SIZE_MAX > 0xffffffff
|
||||
/* Looks like a 64-bit system, so prefer SHA-512. */
|
||||
#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512
|
||||
#else
|
||||
/* Looks like a 32-bit system, so prefer SHA-256. */
|
||||
#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
|
||||
#endif
|
||||
#elif defined(MBEDTLS_MD_CAN_SHA512)
|
||||
#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512
|
||||
#elif defined(MBEDTLS_MD_CAN_SHA256)
|
||||
#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
|
||||
#else
|
||||
#error "No hash algorithm available for HMAC_DBRG."
|
||||
#endif
|
||||
|
||||
#else /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
|
||||
|
||||
#error "No DRBG module available for the psa_crypto module."
|
||||
|
||||
#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
|
||||
|
||||
/* The maximum number of bytes that mbedtls_psa_get_random() is expected to return. */
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
|
||||
#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
|
||||
|
||||
typedef struct {
|
||||
void (* entropy_init)(mbedtls_entropy_context *ctx);
|
||||
void (* entropy_free)(mbedtls_entropy_context *ctx);
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_psa_drbg_context_t drbg;
|
||||
} mbedtls_psa_random_context_t;
|
||||
|
||||
/** Initialize the PSA DRBG.
|
||||
*
|
||||
* \param p_rng Pointer to the Mbed TLS DRBG state.
|
||||
*/
|
||||
static inline void mbedtls_psa_drbg_init(mbedtls_psa_drbg_context_t *p_rng)
|
||||
{
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
mbedtls_ctr_drbg_init(p_rng);
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
mbedtls_hmac_drbg_init(p_rng);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Deinitialize the PSA DRBG.
|
||||
*
|
||||
* \param p_rng Pointer to the Mbed TLS DRBG state.
|
||||
*/
|
||||
static inline void mbedtls_psa_drbg_free(mbedtls_psa_drbg_context_t *p_rng)
|
||||
{
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
mbedtls_ctr_drbg_free(p_rng);
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
mbedtls_hmac_drbg_free(p_rng);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Seed the PSA DRBG.
|
||||
*
|
||||
* \param entropy An entropy context to read the seed from.
|
||||
* \param custom The personalization string.
|
||||
* This can be \c NULL, in which case the personalization
|
||||
* string is empty regardless of the value of \p len.
|
||||
* \param len The length of the personalization string.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure.
|
||||
*/
|
||||
static inline int mbedtls_psa_drbg_seed(mbedtls_psa_drbg_context_t *drbg_ctx,
|
||||
mbedtls_entropy_context *entropy,
|
||||
const unsigned char *custom, size_t len)
|
||||
{
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
return mbedtls_ctr_drbg_seed(drbg_ctx, mbedtls_entropy_func, entropy, custom, len);
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE);
|
||||
return mbedtls_hmac_drbg_seed(drbg_ctx, md_info, mbedtls_entropy_func, entropy, custom, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
|
||||
|
||||
#endif /* PSA_CRYPTO_RANDOM_IMPL_H */
|
||||
705
Libs/util/third_party/mbedtls/library/psa_crypto_rsa.c
vendored
Normal file
705
Libs/util/third_party/mbedtls/library/psa_crypto_rsa.c
vendored
Normal file
@@ -0,0 +1,705 @@
|
||||
/*
|
||||
* PSA RSA layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa/crypto_values.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_random_impl.h"
|
||||
#include "psa_crypto_rsa.h"
|
||||
#include "psa_crypto_hash.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include <mbedtls/rsa.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include "rsa_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
|
||||
/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
|
||||
* that are not a multiple of 8) well. For example, there is only
|
||||
* mbedtls_rsa_get_len(), which returns a number of bytes, and no
|
||||
* way to return the exact bit size of a key.
|
||||
* To keep things simple, reject non-byte-aligned key sizes. */
|
||||
static psa_status_t psa_check_rsa_key_byte_aligned(
|
||||
const mbedtls_rsa_context *rsa)
|
||||
{
|
||||
mbedtls_mpi n;
|
||||
psa_status_t status;
|
||||
mbedtls_mpi_init(&n);
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_rsa_export(rsa, &n, NULL, NULL, NULL, NULL));
|
||||
if (status == PSA_SUCCESS) {
|
||||
if (mbedtls_mpi_bitlen(&n) % 8 != 0) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
mbedtls_mpi_free(&n);
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_rsa_load_representation(
|
||||
psa_key_type_t type, const uint8_t *data, size_t data_length,
|
||||
mbedtls_rsa_context **p_rsa)
|
||||
{
|
||||
psa_status_t status;
|
||||
size_t bits;
|
||||
|
||||
*p_rsa = mbedtls_calloc(1, sizeof(mbedtls_rsa_context));
|
||||
if (*p_rsa == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
mbedtls_rsa_init(*p_rsa);
|
||||
|
||||
/* Parse the data. */
|
||||
if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
|
||||
status = mbedtls_to_psa_error(mbedtls_rsa_parse_key(*p_rsa, data, data_length));
|
||||
} else {
|
||||
status = mbedtls_to_psa_error(mbedtls_rsa_parse_pubkey(*p_rsa, data, data_length));
|
||||
}
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS
|
||||
* supports non-byte-aligned key sizes, but not well. For example,
|
||||
* mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */
|
||||
bits = PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(*p_rsa));
|
||||
if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
status = psa_check_rsa_key_byte_aligned(*p_rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
|
||||
|
||||
#if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
psa_status_t mbedtls_psa_rsa_import_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data, size_t data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size,
|
||||
size_t *key_buffer_length, size_t *bits)
|
||||
{
|
||||
psa_status_t status;
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
|
||||
/* Parse input */
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
data,
|
||||
data_length,
|
||||
&rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*bits = (psa_key_bits_t) PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(rsa));
|
||||
|
||||
/* Re-export the data to PSA export format, such that we can store export
|
||||
* representation in the key slot. Export representation in case of RSA is
|
||||
* the smallest representation that's allowed as input, so a straight-up
|
||||
* allocation of the same size as the input buffer will be large enough. */
|
||||
status = mbedtls_psa_rsa_export_key(attributes->type,
|
||||
rsa,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
key_buffer_length);
|
||||
exit:
|
||||
/* Always free the RSA object */
|
||||
mbedtls_rsa_free(rsa);
|
||||
mbedtls_free(rsa);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) &&
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
psa_status_t mbedtls_psa_rsa_export_key(psa_key_type_t type,
|
||||
mbedtls_rsa_context *rsa,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *end = data + data_size;
|
||||
|
||||
/* PSA Crypto API defines the format of an RSA key as a DER-encoded
|
||||
* representation of the non-encrypted PKCS#1 RSAPrivateKey for a
|
||||
* private key and of the RFC3279 RSAPublicKey for a public key. */
|
||||
if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
|
||||
ret = mbedtls_rsa_write_key(rsa, data, &end);
|
||||
} else {
|
||||
ret = mbedtls_rsa_write_pubkey(rsa, data, &end);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
/* Clean up in case pk_write failed halfway through. */
|
||||
memset(data, 0, data_size);
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
/* The mbedtls_pk_xxx functions write to the end of the buffer.
|
||||
* Move the data to the beginning and erase remaining data
|
||||
* at the original location. */
|
||||
if (2 * (size_t) ret <= data_size) {
|
||||
memcpy(data, data + data_size - ret, ret);
|
||||
memset(data + data_size - ret, 0, ret);
|
||||
} else if ((size_t) ret < data_size) {
|
||||
memmove(data, data + data_size - ret, ret);
|
||||
memset(data + ret, 0, data_size - ret);
|
||||
}
|
||||
|
||||
*data_length = ret;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_rsa_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
|
||||
status = mbedtls_psa_rsa_load_representation(
|
||||
attributes->type, key_buffer, key_buffer_size, &rsa);
|
||||
if (status == PSA_SUCCESS) {
|
||||
status = mbedtls_psa_rsa_export_key(PSA_KEY_TYPE_RSA_PUBLIC_KEY,
|
||||
rsa,
|
||||
data,
|
||||
data_size,
|
||||
data_length);
|
||||
}
|
||||
|
||||
mbedtls_rsa_free(rsa);
|
||||
mbedtls_free(rsa);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
|
||||
static psa_status_t psa_rsa_read_exponent(const uint8_t *e_bytes,
|
||||
size_t e_length,
|
||||
int *exponent)
|
||||
{
|
||||
size_t i;
|
||||
uint32_t acc = 0;
|
||||
|
||||
/* Mbed TLS encodes the public exponent as an int. For simplicity, only
|
||||
* support values that fit in a 32-bit integer, which is larger than
|
||||
* int on just about every platform anyway. */
|
||||
if (e_length > sizeof(acc)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
for (i = 0; i < e_length; i++) {
|
||||
acc = (acc << 8) | e_bytes[i];
|
||||
}
|
||||
if (acc > INT_MAX) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
*exponent = acc;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_rsa_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *custom_data, size_t custom_data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
mbedtls_rsa_context rsa;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int exponent = 65537;
|
||||
|
||||
if (custom_data_length != 0) {
|
||||
status = psa_rsa_read_exponent(custom_data, custom_data_length,
|
||||
&exponent);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_rsa_init(&rsa);
|
||||
ret = mbedtls_rsa_gen_key(&rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
(unsigned int) attributes->bits,
|
||||
exponent);
|
||||
if (ret != 0) {
|
||||
mbedtls_rsa_free(&rsa);
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
status = mbedtls_psa_rsa_export_key(attributes->type,
|
||||
&rsa, key_buffer, key_buffer_size,
|
||||
key_buffer_length);
|
||||
mbedtls_rsa_free(&rsa);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */
|
||||
|
||||
/****************************************************************/
|
||||
/* Sign/verify hashes */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
|
||||
|
||||
/* Decode the hash algorithm from alg and store the mbedtls encoding in
|
||||
* md_alg. Verify that the hash length is acceptable. */
|
||||
static psa_status_t psa_rsa_decode_md_type(psa_algorithm_t alg,
|
||||
size_t hash_length,
|
||||
mbedtls_md_type_t *md_alg)
|
||||
{
|
||||
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
|
||||
*md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
|
||||
|
||||
/* The Mbed TLS RSA module uses an unsigned int for hash length
|
||||
* parameters. Validate that it fits so that we don't risk an
|
||||
* overflow later. */
|
||||
#if SIZE_MAX > UINT_MAX
|
||||
if (hash_length > UINT_MAX) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* For signatures using a hash, the hash length must be correct. */
|
||||
if (alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
|
||||
if (*md_alg == MBEDTLS_MD_NONE) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
if (mbedtls_md_get_size_from_type(*md_alg) != hash_length) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_rsa_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
|
||||
uint8_t *signature, size_t signature_size, size_t *signature_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_md_type_t md_alg;
|
||||
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_rsa_decode_md_type(alg, hash_length, &md_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (signature_size < mbedtls_rsa_get_len(rsa)) {
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
|
||||
if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
|
||||
ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15,
|
||||
MBEDTLS_MD_NONE);
|
||||
if (ret == 0) {
|
||||
ret = mbedtls_rsa_pkcs1_sign(rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
md_alg,
|
||||
(unsigned int) hash_length,
|
||||
hash,
|
||||
signature);
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
|
||||
if (PSA_ALG_IS_RSA_PSS(alg)) {
|
||||
ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
|
||||
|
||||
if (ret == 0) {
|
||||
ret = mbedtls_rsa_rsassa_pss_sign(rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
MBEDTLS_MD_NONE,
|
||||
(unsigned int) hash_length,
|
||||
hash,
|
||||
signature);
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
|
||||
{
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
*signature_length = mbedtls_rsa_get_len(rsa);
|
||||
}
|
||||
status = mbedtls_to_psa_error(ret);
|
||||
|
||||
exit:
|
||||
mbedtls_rsa_free(rsa);
|
||||
mbedtls_free(rsa);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
|
||||
static int rsa_pss_expected_salt_len(psa_algorithm_t alg,
|
||||
const mbedtls_rsa_context *rsa,
|
||||
size_t hash_length)
|
||||
{
|
||||
if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
|
||||
return MBEDTLS_RSA_SALT_LEN_ANY;
|
||||
}
|
||||
/* Otherwise: standard salt length, i.e. largest possible salt length
|
||||
* up to the hash length. */
|
||||
int klen = (int) mbedtls_rsa_get_len(rsa); // known to fit
|
||||
int hlen = (int) hash_length; // known to fit
|
||||
int room = klen - 2 - hlen;
|
||||
if (room < 0) {
|
||||
return 0; // there is no valid signature in this case anyway
|
||||
} else if (room > hlen) {
|
||||
return hlen;
|
||||
} else {
|
||||
return room;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
|
||||
|
||||
psa_status_t mbedtls_psa_rsa_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
|
||||
const uint8_t *signature, size_t signature_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_md_type_t md_alg;
|
||||
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_rsa_decode_md_type(alg, hash_length, &md_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (signature_length != mbedtls_rsa_get_len(rsa)) {
|
||||
status = PSA_ERROR_INVALID_SIGNATURE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
|
||||
if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
|
||||
ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15,
|
||||
MBEDTLS_MD_NONE);
|
||||
if (ret == 0) {
|
||||
ret = mbedtls_rsa_pkcs1_verify(rsa,
|
||||
md_alg,
|
||||
(unsigned int) hash_length,
|
||||
hash,
|
||||
signature);
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
|
||||
if (PSA_ALG_IS_RSA_PSS(alg)) {
|
||||
ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
|
||||
if (ret == 0) {
|
||||
int slen = rsa_pss_expected_salt_len(alg, rsa, hash_length);
|
||||
ret = mbedtls_rsa_rsassa_pss_verify_ext(rsa,
|
||||
md_alg,
|
||||
(unsigned) hash_length,
|
||||
hash,
|
||||
md_alg,
|
||||
slen,
|
||||
signature);
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
|
||||
{
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Mbed TLS distinguishes "invalid padding" from "valid padding but
|
||||
* the rest of the signature is invalid". This has little use in
|
||||
* practice and PSA doesn't report this distinction. */
|
||||
status = (ret == MBEDTLS_ERR_RSA_INVALID_PADDING) ?
|
||||
PSA_ERROR_INVALID_SIGNATURE :
|
||||
mbedtls_to_psa_error(ret);
|
||||
|
||||
exit:
|
||||
mbedtls_rsa_free(rsa);
|
||||
mbedtls_free(rsa);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
|
||||
|
||||
/****************************************************************/
|
||||
/* Asymmetric cryptography */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
static int psa_rsa_oaep_set_padding_mode(psa_algorithm_t alg,
|
||||
mbedtls_rsa_context *rsa)
|
||||
{
|
||||
psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH(alg);
|
||||
mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
|
||||
|
||||
/* Just to get the error status right, as rsa_set_padding() doesn't
|
||||
* distinguish between "bad RSA algorithm" and "unknown hash". */
|
||||
if (mbedtls_md_info_from_type(md_alg) == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
|
||||
|
||||
psa_status_t mbedtls_psa_asymmetric_encrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
const uint8_t *salt,
|
||||
size_t salt_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
(void) key_buffer;
|
||||
(void) key_buffer_size;
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
(void) salt;
|
||||
(void) salt_length;
|
||||
(void) output;
|
||||
(void) output_size;
|
||||
(void) output_length;
|
||||
|
||||
if (PSA_KEY_TYPE_IS_RSA(attributes->type)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto rsa_exit;
|
||||
}
|
||||
|
||||
if (output_size < mbedtls_rsa_get_len(rsa)) {
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
goto rsa_exit;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
|
||||
if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_rsa_pkcs1_encrypt(rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
input_length,
|
||||
input,
|
||||
output));
|
||||
#else
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
|
||||
} else
|
||||
if (PSA_ALG_IS_RSA_OAEP(alg)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
status = mbedtls_to_psa_error(
|
||||
psa_rsa_oaep_set_padding_mode(alg, rsa));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto rsa_exit;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_rsa_rsaes_oaep_encrypt(rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
salt, salt_length,
|
||||
input_length,
|
||||
input,
|
||||
output));
|
||||
#else
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
|
||||
} else {
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
rsa_exit:
|
||||
if (status == PSA_SUCCESS) {
|
||||
*output_length = mbedtls_rsa_get_len(rsa);
|
||||
}
|
||||
|
||||
mbedtls_rsa_free(rsa);
|
||||
mbedtls_free(rsa);
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
|
||||
} else {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_asymmetric_decrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
const uint8_t *salt,
|
||||
size_t salt_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
(void) key_buffer;
|
||||
(void) key_buffer_size;
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
(void) salt;
|
||||
(void) salt_length;
|
||||
(void) output;
|
||||
(void) output_size;
|
||||
(void) output_length;
|
||||
|
||||
*output_length = 0;
|
||||
|
||||
if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto rsa_exit;
|
||||
}
|
||||
|
||||
if (input_length != mbedtls_rsa_get_len(rsa)) {
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto rsa_exit;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
|
||||
|
||||
if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_rsa_pkcs1_decrypt(rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
output_length,
|
||||
input,
|
||||
output,
|
||||
output_size));
|
||||
#else
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
|
||||
} else
|
||||
if (PSA_ALG_IS_RSA_OAEP(alg)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
status = mbedtls_to_psa_error(
|
||||
psa_rsa_oaep_set_padding_mode(alg, rsa));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto rsa_exit;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_rsa_rsaes_oaep_decrypt(rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
salt, salt_length,
|
||||
output_length,
|
||||
input,
|
||||
output,
|
||||
output_size));
|
||||
#else
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
|
||||
} else {
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
rsa_exit:
|
||||
mbedtls_rsa_free(rsa);
|
||||
mbedtls_free(rsa);
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
|
||||
} else {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
321
Libs/util/third_party/mbedtls/library/psa_crypto_rsa.h
vendored
Normal file
321
Libs/util/third_party/mbedtls/library/psa_crypto_rsa.h
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* PSA RSA layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_RSA_H
|
||||
#define PSA_CRYPTO_RSA_H
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include <mbedtls/rsa.h>
|
||||
|
||||
/** Load the contents of a key buffer into an internal RSA representation
|
||||
*
|
||||
* \param[in] type The type of key contained in \p data.
|
||||
* \param[in] data The buffer from which to load the representation.
|
||||
* \param[in] data_length The size in bytes of \p data.
|
||||
* \param[out] p_rsa Returns a pointer to an RSA context on success.
|
||||
* The caller is responsible for freeing both the
|
||||
* contents of the context and the context itself
|
||||
* when done.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_rsa_load_representation(psa_key_type_t type,
|
||||
const uint8_t *data,
|
||||
size_t data_length,
|
||||
mbedtls_rsa_context **p_rsa);
|
||||
|
||||
/** Import an RSA key in binary format.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* import_key entry point. This function behaves as an import_key
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \param[in] attributes The attributes for the key to import.
|
||||
* \param[in] data The buffer containing the key data in import
|
||||
* format.
|
||||
* \param[in] data_length Size of the \p data buffer in bytes.
|
||||
* \param[out] key_buffer The buffer containing the key data in output
|
||||
* format.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. This
|
||||
* size is greater or equal to \p data_length.
|
||||
* \param[out] key_buffer_length The length of the data written in \p
|
||||
* key_buffer in bytes.
|
||||
* \param[out] bits The key size in number of bits.
|
||||
*
|
||||
* \retval #PSA_SUCCESS The RSA key was imported successfully.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The key data is not correctly formatted.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_rsa_import_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data, size_t data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size,
|
||||
size_t *key_buffer_length, size_t *bits);
|
||||
|
||||
/** Export an RSA key to export representation
|
||||
*
|
||||
* \param[in] type The type of key (public/private) to export
|
||||
* \param[in] rsa The internal RSA representation from which to export
|
||||
* \param[out] data The buffer to export to
|
||||
* \param[in] data_size The length of the buffer to export to
|
||||
* \param[out] data_length The amount of bytes written to \p data
|
||||
*/
|
||||
psa_status_t mbedtls_psa_rsa_export_key(psa_key_type_t type,
|
||||
mbedtls_rsa_context *rsa,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length);
|
||||
|
||||
/** Export a public RSA key or the public part of an RSA key pair in binary
|
||||
* format.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* export_public_key entry point. This function behaves as an
|
||||
* export_public_key entry point as defined in the PSA driver interface
|
||||
* specification.
|
||||
*
|
||||
* \param[in] attributes The attributes for the key to export.
|
||||
* \param[in] key_buffer Material or context of the key to export.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[out] data Buffer where the key data is to be written.
|
||||
* \param[in] data_size Size of the \p data buffer in bytes.
|
||||
* \param[out] data_length On success, the number of bytes written in
|
||||
* \p data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS The RSA public key was exported successfully.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_rsa_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length);
|
||||
|
||||
/**
|
||||
* \brief Generate an RSA key.
|
||||
*
|
||||
* \param[in] attributes The attributes for the RSA key to generate.
|
||||
* \param[in] custom_data The public exponent to use.
|
||||
* This can be a null pointer if
|
||||
* \c params_data_length is 0.
|
||||
* \param custom_data_length Length of \p custom_data in bytes.
|
||||
* This can be 0, in which case the
|
||||
* public exponent will be 65537.
|
||||
* \param[out] key_buffer Buffer where the key data is to be written.
|
||||
* \param[in] key_buffer_size Size of \p key_buffer in bytes.
|
||||
* \param[out] key_buffer_length On success, the number of bytes written in
|
||||
* \p key_buffer.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The key was successfully generated.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* Key length or type not supported.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of \p key_buffer is too small.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_rsa_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *custom_data, size_t custom_data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
|
||||
|
||||
/** Sign an already-calculated hash with an RSA private key.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* sign_hash entry point. This function behaves as a sign_hash
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \param[in] attributes The attributes of the RSA key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the RSA key context.
|
||||
* format.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg A signature algorithm that is compatible with
|
||||
* an RSA key.
|
||||
* \param[in] hash The hash or message to sign.
|
||||
* \param[in] hash_length Size of the \p hash buffer in bytes.
|
||||
* \param[out] signature Buffer where the signature is to be written.
|
||||
* \param[in] signature_size Size of the \p signature buffer in bytes.
|
||||
* \param[out] signature_length On success, the number of bytes
|
||||
* that make up the returned signature value.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p signature buffer is too small. You can
|
||||
* determine a sufficient buffer size by calling
|
||||
* #PSA_SIGN_OUTPUT_SIZE(\c PSA_KEY_TYPE_RSA_KEY_PAIR, \c key_bits,
|
||||
* \p alg) where \c key_bits is the bit-size of the RSA key.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_rsa_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
|
||||
uint8_t *signature, size_t signature_size, size_t *signature_length);
|
||||
|
||||
/**
|
||||
* \brief Verify the signature a hash or short message using a public RSA key.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
* verify_hash entry point. This function behaves as a verify_hash
|
||||
* entry point as defined in the PSA driver interface specification for
|
||||
* transparent drivers.
|
||||
*
|
||||
* \param[in] attributes The attributes of the RSA key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the RSA key context.
|
||||
* format.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg A signature algorithm that is compatible with
|
||||
* an RSA key.
|
||||
* \param[in] hash The hash or message whose signature is to be
|
||||
* verified.
|
||||
* \param[in] hash_length Size of the \p hash buffer in bytes.
|
||||
* \param[in] signature Buffer containing the signature to verify.
|
||||
* \param[in] signature_length Size of the \p signature buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The signature is valid.
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
* The calculation was performed successfully, but the passed
|
||||
* signature is not a valid signature.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
*/
|
||||
psa_status_t mbedtls_psa_rsa_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
|
||||
const uint8_t *signature, size_t signature_length);
|
||||
|
||||
/**
|
||||
* \brief Encrypt a short message with a public key.
|
||||
*
|
||||
* \param attributes The attributes for the key to import.
|
||||
* \param key_buffer Buffer where the key data is to be written.
|
||||
* \param key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param input_length Size of the \p input buffer in bytes.
|
||||
* \param[in] salt A salt or label, if supported by the
|
||||
* encryption algorithm.
|
||||
* If the algorithm does not support a
|
||||
* salt, pass \c NULL.
|
||||
* If the algorithm supports an optional
|
||||
* salt and you do not want to pass a salt,
|
||||
* pass \c NULL.
|
||||
*
|
||||
* - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
|
||||
* supported.
|
||||
* \param salt_length Size of the \p salt buffer in bytes.
|
||||
* If \p salt is \c NULL, pass 0.
|
||||
* \param[out] output Buffer where the encrypted message is to
|
||||
* be written.
|
||||
* \param output_size Size of the \p output buffer in bytes.
|
||||
* \param[out] output_length On success, the number of bytes
|
||||
* that make up the returned output.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p output buffer is too small. You can
|
||||
* determine a sufficient buffer size by calling
|
||||
* #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
|
||||
* where \c key_type and \c key_bits are the type and bit-size
|
||||
* respectively of \p key.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The library has not been previously initialized by psa_crypto_init().
|
||||
* It is implementation-dependent whether a failure to initialize
|
||||
* results in this error code.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_asymmetric_encrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
const uint8_t *salt,
|
||||
size_t salt_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
/**
|
||||
* \brief Decrypt a short message with a private key.
|
||||
*
|
||||
* \param attributes The attributes for the key to import.
|
||||
* \param key_buffer Buffer where the key data is to be written.
|
||||
* \param key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] input The message to decrypt.
|
||||
* \param input_length Size of the \p input buffer in bytes.
|
||||
* \param[in] salt A salt or label, if supported by the
|
||||
* encryption algorithm.
|
||||
* If the algorithm does not support a
|
||||
* salt, pass \c NULL.
|
||||
* If the algorithm supports an optional
|
||||
* salt and you do not want to pass a salt,
|
||||
* pass \c NULL.
|
||||
*
|
||||
* - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
|
||||
* supported.
|
||||
* \param salt_length Size of the \p salt buffer in bytes.
|
||||
* If \p salt is \c NULL, pass 0.
|
||||
* \param[out] output Buffer where the decrypted message is to
|
||||
* be written.
|
||||
* \param output_size Size of the \c output buffer in bytes.
|
||||
* \param[out] output_length On success, the number of bytes
|
||||
* that make up the returned output.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of the \p output buffer is too small. You can
|
||||
* determine a sufficient buffer size by calling
|
||||
* #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
|
||||
* where \c key_type and \c key_bits are the type and bit-size
|
||||
* respectively of \p key.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_PADDING \emptydescription
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The library has not been previously initialized by psa_crypto_init().
|
||||
* It is implementation-dependent whether a failure to initialize
|
||||
* results in this error code.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_asymmetric_decrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
const uint8_t *salt,
|
||||
size_t salt_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
#endif /* PSA_CRYPTO_RSA_H */
|
||||
373
Libs/util/third_party/mbedtls/library/psa_crypto_se.c
vendored
Normal file
373
Libs/util/third_party/mbedtls/library/psa_crypto_se.c
vendored
Normal file
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* PSA crypto support for secure element drivers
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
#include "psa_crypto_se.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_ITS_FILE_C)
|
||||
#include "psa_crypto_its.h"
|
||||
#else /* Native ITS implementation */
|
||||
#include "psa/error.h"
|
||||
#include "psa/internal_trusted_storage.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Driver lookup */
|
||||
/****************************************************************/
|
||||
|
||||
/* This structure is identical to psa_drv_se_context_t declared in
|
||||
* `crypto_se_driver.h`, except that some parts are writable here
|
||||
* (non-const, or pointer to non-const). */
|
||||
typedef struct {
|
||||
void *persistent_data;
|
||||
size_t persistent_data_size;
|
||||
uintptr_t transient_data;
|
||||
} psa_drv_se_internal_context_t;
|
||||
|
||||
struct psa_se_drv_table_entry_s {
|
||||
psa_key_location_t location;
|
||||
const psa_drv_se_t *methods;
|
||||
union {
|
||||
psa_drv_se_internal_context_t internal;
|
||||
psa_drv_se_context_t context;
|
||||
} u;
|
||||
};
|
||||
|
||||
static psa_se_drv_table_entry_t driver_table[PSA_MAX_SE_DRIVERS];
|
||||
|
||||
psa_se_drv_table_entry_t *psa_get_se_driver_entry(
|
||||
psa_key_lifetime_t lifetime)
|
||||
{
|
||||
size_t i;
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(lifetime);
|
||||
/* In the driver table, location=0 means an entry that isn't used.
|
||||
* No driver has a location of 0 because it's a reserved value
|
||||
* (which designates transparent keys). Make sure we never return
|
||||
* a driver entry for location 0. */
|
||||
if (location == 0) {
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
|
||||
if (driver_table[i].location == location) {
|
||||
return &driver_table[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const psa_drv_se_t *psa_get_se_driver_methods(
|
||||
const psa_se_drv_table_entry_t *driver)
|
||||
{
|
||||
return driver->methods;
|
||||
}
|
||||
|
||||
psa_drv_se_context_t *psa_get_se_driver_context(
|
||||
psa_se_drv_table_entry_t *driver)
|
||||
{
|
||||
return &driver->u.context;
|
||||
}
|
||||
|
||||
int psa_get_se_driver(psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t **p_methods,
|
||||
psa_drv_se_context_t **p_drv_context)
|
||||
{
|
||||
psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry(lifetime);
|
||||
if (p_methods != NULL) {
|
||||
*p_methods = (driver ? driver->methods : NULL);
|
||||
}
|
||||
if (p_drv_context != NULL) {
|
||||
*p_drv_context = (driver ? &driver->u.context : NULL);
|
||||
}
|
||||
return driver != NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Persistent data management */
|
||||
/****************************************************************/
|
||||
|
||||
static psa_status_t psa_get_se_driver_its_file_uid(
|
||||
const psa_se_drv_table_entry_t *driver,
|
||||
psa_storage_uid_t *uid)
|
||||
{
|
||||
if (driver->location > PSA_MAX_SE_LOCATION) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* ITS file sizes are limited to 32 bits. */
|
||||
if (driver->u.internal.persistent_data_size > UINT32_MAX) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */
|
||||
*uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->location;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_load_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t uid;
|
||||
size_t length;
|
||||
|
||||
status = psa_get_se_driver_its_file_uid(driver, &uid);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Read the amount of persistent data that the driver requests.
|
||||
* If the data in storage is larger, it is truncated. If the data
|
||||
* in storage is smaller, silently keep what is already at the end
|
||||
* of the output buffer. */
|
||||
/* psa_get_se_driver_its_file_uid ensures that the size_t
|
||||
* persistent_data_size is in range, but compilers don't know that,
|
||||
* so cast to reassure them. */
|
||||
return psa_its_get(uid, 0,
|
||||
(uint32_t) driver->u.internal.persistent_data_size,
|
||||
driver->u.internal.persistent_data,
|
||||
&length);
|
||||
}
|
||||
|
||||
psa_status_t psa_save_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t uid;
|
||||
|
||||
status = psa_get_se_driver_its_file_uid(driver, &uid);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* psa_get_se_driver_its_file_uid ensures that the size_t
|
||||
* persistent_data_size is in range, but compilers don't know that,
|
||||
* so cast to reassure them. */
|
||||
return psa_its_set(uid,
|
||||
(uint32_t) driver->u.internal.persistent_data_size,
|
||||
driver->u.internal.persistent_data,
|
||||
0);
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_se_persistent_data(psa_key_location_t location)
|
||||
{
|
||||
psa_storage_uid_t uid;
|
||||
if (location > PSA_MAX_SE_LOCATION) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + location;
|
||||
return psa_its_remove(uid);
|
||||
}
|
||||
|
||||
psa_status_t psa_find_se_slot_for_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_creation_method_t method,
|
||||
psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t *slot_number)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_location_t key_location =
|
||||
PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes));
|
||||
|
||||
/* If the location is wrong, it's a bug in the library. */
|
||||
if (driver->location != key_location) {
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
|
||||
/* If the driver doesn't support key creation in any way, give up now. */
|
||||
if (driver->methods->key_management == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (psa_get_key_slot_number(attributes, slot_number) == PSA_SUCCESS) {
|
||||
/* The application wants to use a specific slot. Allow it if
|
||||
* the driver supports it. On a system with isolation,
|
||||
* the crypto service must check that the application is
|
||||
* permitted to request this slot. */
|
||||
psa_drv_se_validate_slot_number_t p_validate_slot_number =
|
||||
driver->methods->key_management->p_validate_slot_number;
|
||||
if (p_validate_slot_number == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
status = p_validate_slot_number(&driver->u.context,
|
||||
driver->u.internal.persistent_data,
|
||||
attributes, method,
|
||||
*slot_number);
|
||||
} else if (method == PSA_KEY_CREATION_REGISTER) {
|
||||
/* The application didn't specify a slot number. This doesn't
|
||||
* make sense when registering a slot. */
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
} else {
|
||||
/* The application didn't tell us which slot to use. Let the driver
|
||||
* choose. This is the normal case. */
|
||||
psa_drv_se_allocate_key_t p_allocate =
|
||||
driver->methods->key_management->p_allocate;
|
||||
if (p_allocate == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
status = p_allocate(&driver->u.context,
|
||||
driver->u.internal.persistent_data,
|
||||
attributes, method,
|
||||
slot_number);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_se_key(psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t slot_number)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_status_t storage_status;
|
||||
/* Normally a missing method would mean that the action is not
|
||||
* supported. But psa_destroy_key() is not supposed to return
|
||||
* PSA_ERROR_NOT_SUPPORTED: if you can create a key, you should
|
||||
* be able to destroy it. The only use case for a driver that
|
||||
* does not have a way to destroy keys at all is if the keys are
|
||||
* locked in a read-only state: we can use the keys but not
|
||||
* destroy them. Hence, if the driver doesn't support destroying
|
||||
* keys, it's really a lack of permission. */
|
||||
if (driver->methods->key_management == NULL ||
|
||||
driver->methods->key_management->p_destroy == NULL) {
|
||||
return PSA_ERROR_NOT_PERMITTED;
|
||||
}
|
||||
status = driver->methods->key_management->p_destroy(
|
||||
&driver->u.context,
|
||||
driver->u.internal.persistent_data,
|
||||
slot_number);
|
||||
storage_status = psa_save_se_persistent_data(driver);
|
||||
return status == PSA_SUCCESS ? storage_status : status;
|
||||
}
|
||||
|
||||
psa_status_t psa_init_all_se_drivers(void)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
|
||||
psa_se_drv_table_entry_t *driver = &driver_table[i];
|
||||
if (driver->location == 0) {
|
||||
continue; /* skipping unused entry */
|
||||
}
|
||||
const psa_drv_se_t *methods = psa_get_se_driver_methods(driver);
|
||||
if (methods->p_init != NULL) {
|
||||
psa_status_t status = methods->p_init(
|
||||
&driver->u.context,
|
||||
driver->u.internal.persistent_data,
|
||||
driver->location);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
status = psa_save_se_persistent_data(driver);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Driver registration */
|
||||
/****************************************************************/
|
||||
|
||||
psa_status_t psa_register_se_driver(
|
||||
psa_key_location_t location,
|
||||
const psa_drv_se_t *methods)
|
||||
{
|
||||
size_t i;
|
||||
psa_status_t status;
|
||||
|
||||
if (methods->hal_version != PSA_DRV_SE_HAL_VERSION) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
/* Driver table entries are 0-initialized. 0 is not a valid driver
|
||||
* location because it means a transparent key. */
|
||||
MBEDTLS_STATIC_ASSERT(PSA_KEY_LOCATION_LOCAL_STORAGE == 0,
|
||||
"Secure element support requires 0 to mean a local key");
|
||||
|
||||
if (location == PSA_KEY_LOCATION_LOCAL_STORAGE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (location > PSA_MAX_SE_LOCATION) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
|
||||
if (driver_table[i].location == 0) {
|
||||
break;
|
||||
}
|
||||
/* Check that location isn't already in use up to the first free
|
||||
* entry. Since entries are created in order and never deleted,
|
||||
* there can't be a used entry after the first free entry. */
|
||||
if (driver_table[i].location == location) {
|
||||
return PSA_ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
}
|
||||
if (i == PSA_MAX_SE_DRIVERS) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
driver_table[i].location = location;
|
||||
driver_table[i].methods = methods;
|
||||
driver_table[i].u.internal.persistent_data_size =
|
||||
methods->persistent_data_size;
|
||||
|
||||
if (methods->persistent_data_size != 0) {
|
||||
driver_table[i].u.internal.persistent_data =
|
||||
mbedtls_calloc(1, methods->persistent_data_size);
|
||||
if (driver_table[i].u.internal.persistent_data == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
/* Load the driver's persistent data. On first use, the persistent
|
||||
* data does not exist in storage, and is initialized to
|
||||
* all-bits-zero by the calloc call just above. */
|
||||
status = psa_load_se_persistent_data(&driver_table[i]);
|
||||
if (status != PSA_SUCCESS && status != PSA_ERROR_DOES_NOT_EXIST) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
|
||||
error:
|
||||
memset(&driver_table[i], 0, sizeof(driver_table[i]));
|
||||
return status;
|
||||
}
|
||||
|
||||
void psa_unregister_all_se_drivers(void)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
|
||||
if (driver_table[i].u.internal.persistent_data != NULL) {
|
||||
mbedtls_free(driver_table[i].u.internal.persistent_data);
|
||||
}
|
||||
}
|
||||
memset(driver_table, 0, sizeof(driver_table));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* The end */
|
||||
/****************************************************************/
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
192
Libs/util/third_party/mbedtls/library/psa_crypto_se.h
vendored
Normal file
192
Libs/util/third_party/mbedtls/library/psa_crypto_se.h
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* PSA crypto support for secure element drivers
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_SE_H
|
||||
#define PSA_CRYPTO_SE_H
|
||||
|
||||
/*
|
||||
* Include the build-time configuration information header. Here, we do not
|
||||
* include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which
|
||||
* is basically just an alias to it. This is to ease the maintenance of the
|
||||
* TF-PSA-Crypto repository which has a different build system and
|
||||
* configuration.
|
||||
*/
|
||||
#include "psa/build_info.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
/** The maximum location value that this implementation supports
|
||||
* for a secure element.
|
||||
*
|
||||
* This is not a characteristic that each PSA implementation has, but a
|
||||
* limitation of the current implementation due to the constraints imposed
|
||||
* by storage. See #PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE.
|
||||
*
|
||||
* The minimum location value for a secure element is 1, like on any
|
||||
* PSA implementation (0 means a transparent key).
|
||||
*/
|
||||
#define PSA_MAX_SE_LOCATION 255
|
||||
|
||||
/** The base of the range of ITS file identifiers for secure element
|
||||
* driver persistent data.
|
||||
*
|
||||
* We use a slice of the implementation reserved range 0xffff0000..0xffffffff,
|
||||
* specifically the range 0xfffffe00..0xfffffeff. The length of this range
|
||||
* drives the value of #PSA_MAX_SE_LOCATION. The identifier 0xfffffe00 is
|
||||
* actually not used since it corresponds to #PSA_KEY_LOCATION_LOCAL_STORAGE
|
||||
* which doesn't have a driver.
|
||||
*/
|
||||
#define PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE ((psa_key_id_t) 0xfffffe00)
|
||||
|
||||
/** The maximum number of registered secure element driver locations. */
|
||||
#define PSA_MAX_SE_DRIVERS 4
|
||||
|
||||
/** Unregister all secure element drivers.
|
||||
*
|
||||
* \warning Do not call this function while the library is in the initialized
|
||||
* state. This function is only intended to be called at the end
|
||||
* of mbedtls_psa_crypto_free().
|
||||
*/
|
||||
void psa_unregister_all_se_drivers(void);
|
||||
|
||||
/** Initialize all secure element drivers.
|
||||
*
|
||||
* Called from psa_crypto_init().
|
||||
*/
|
||||
psa_status_t psa_init_all_se_drivers(void);
|
||||
|
||||
/** A structure that describes a registered secure element driver.
|
||||
*
|
||||
* A secure element driver table entry contains a pointer to the
|
||||
* driver's method table as well as the driver context structure.
|
||||
*/
|
||||
typedef struct psa_se_drv_table_entry_s psa_se_drv_table_entry_t;
|
||||
|
||||
/** Return the secure element driver information for a lifetime value.
|
||||
*
|
||||
* \param lifetime The lifetime value to query.
|
||||
* \param[out] p_methods On output, if there is a driver,
|
||||
* \c *methods points to its method table.
|
||||
* Otherwise \c *methods is \c NULL.
|
||||
* \param[out] p_drv_context On output, if there is a driver,
|
||||
* \c *drv_context points to its context
|
||||
* structure.
|
||||
* Otherwise \c *drv_context is \c NULL.
|
||||
*
|
||||
* \retval 1
|
||||
* \p lifetime corresponds to a registered driver.
|
||||
* \retval 0
|
||||
* \p lifetime does not correspond to a registered driver.
|
||||
*/
|
||||
int psa_get_se_driver(psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t **p_methods,
|
||||
psa_drv_se_context_t **p_drv_context);
|
||||
|
||||
/** Return the secure element driver table entry for a lifetime value.
|
||||
*
|
||||
* \param lifetime The lifetime value to query.
|
||||
*
|
||||
* \return The driver table entry for \p lifetime, or
|
||||
* \p NULL if \p lifetime does not correspond to a registered driver.
|
||||
*/
|
||||
psa_se_drv_table_entry_t *psa_get_se_driver_entry(
|
||||
psa_key_lifetime_t lifetime);
|
||||
|
||||
/** Return the method table for a secure element driver.
|
||||
*
|
||||
* \param[in] driver The driver table entry to access, or \c NULL.
|
||||
*
|
||||
* \return The driver's method table.
|
||||
* \c NULL if \p driver is \c NULL.
|
||||
*/
|
||||
const psa_drv_se_t *psa_get_se_driver_methods(
|
||||
const psa_se_drv_table_entry_t *driver);
|
||||
|
||||
/** Return the context of a secure element driver.
|
||||
*
|
||||
* \param[in] driver The driver table entry to access, or \c NULL.
|
||||
*
|
||||
* \return A pointer to the driver context.
|
||||
* \c NULL if \p driver is \c NULL.
|
||||
*/
|
||||
psa_drv_se_context_t *psa_get_se_driver_context(
|
||||
psa_se_drv_table_entry_t *driver);
|
||||
|
||||
/** Find a free slot for a key that is to be created.
|
||||
*
|
||||
* This function calls the relevant method in the driver to find a suitable
|
||||
* slot for a key with the given attributes.
|
||||
*
|
||||
* \param[in] attributes Metadata about the key that is about to be created.
|
||||
* \param[in] driver The driver table entry to query.
|
||||
* \param[out] slot_number On success, a slot number that is free in this
|
||||
* secure element.
|
||||
*/
|
||||
psa_status_t psa_find_se_slot_for_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_creation_method_t method,
|
||||
psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t *slot_number);
|
||||
|
||||
/** Destroy a key in a secure element.
|
||||
*
|
||||
* This function calls the relevant driver method to destroy a key
|
||||
* and updates the driver's persistent data.
|
||||
*/
|
||||
psa_status_t psa_destroy_se_key(psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t slot_number);
|
||||
|
||||
/** Load the persistent data of a secure element driver.
|
||||
*
|
||||
* \param driver The driver table entry containing the persistent
|
||||
* data to load from storage.
|
||||
*
|
||||
* \return #PSA_SUCCESS
|
||||
* \return #PSA_ERROR_NOT_SUPPORTED
|
||||
* \return #PSA_ERROR_DOES_NOT_EXIST
|
||||
* \return #PSA_ERROR_STORAGE_FAILURE
|
||||
* \return #PSA_ERROR_DATA_CORRUPT
|
||||
* \return #PSA_ERROR_INVALID_ARGUMENT
|
||||
*/
|
||||
psa_status_t psa_load_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver);
|
||||
|
||||
/** Save the persistent data of a secure element driver.
|
||||
*
|
||||
* \param[in] driver The driver table entry containing the persistent
|
||||
* data to save to storage.
|
||||
*
|
||||
* \return #PSA_SUCCESS
|
||||
* \return #PSA_ERROR_NOT_SUPPORTED
|
||||
* \return #PSA_ERROR_NOT_PERMITTED
|
||||
* \return #PSA_ERROR_NOT_SUPPORTED
|
||||
* \return #PSA_ERROR_INSUFFICIENT_STORAGE
|
||||
* \return #PSA_ERROR_STORAGE_FAILURE
|
||||
* \return #PSA_ERROR_INVALID_ARGUMENT
|
||||
*/
|
||||
psa_status_t psa_save_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver);
|
||||
|
||||
/** Destroy the persistent data of a secure element driver.
|
||||
*
|
||||
* This is currently only used for testing.
|
||||
*
|
||||
* \param[in] location The location identifier for the driver whose
|
||||
* persistent data is to be erased.
|
||||
*/
|
||||
psa_status_t psa_destroy_se_persistent_data(psa_key_location_t location);
|
||||
|
||||
|
||||
/** The storage representation of a key whose data is in a secure element.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t slot_number[sizeof(psa_key_slot_number_t)];
|
||||
} psa_se_key_data_storage_t;
|
||||
|
||||
#endif /* PSA_CRYPTO_SE_H */
|
||||
1131
Libs/util/third_party/mbedtls/library/psa_crypto_slot_management.c
vendored
Normal file
1131
Libs/util/third_party/mbedtls/library/psa_crypto_slot_management.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
344
Libs/util/third_party/mbedtls/library/psa_crypto_slot_management.h
vendored
Normal file
344
Libs/util/third_party/mbedtls/library/psa_crypto_slot_management.h
vendored
Normal file
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* PSA crypto layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_SLOT_MANAGEMENT_H
|
||||
#define PSA_CRYPTO_SLOT_MANAGEMENT_H
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_se.h"
|
||||
|
||||
/** Range of volatile key identifiers.
|
||||
*
|
||||
* The first #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation
|
||||
* range of key identifiers are reserved for volatile key identifiers.
|
||||
*
|
||||
* If \c id is a a volatile key identifier, #PSA_KEY_ID_VOLATILE_MIN - \c id
|
||||
* indicates the key slot containing the volatile key definition. See
|
||||
* psa_crypto_slot_management.c for details.
|
||||
*/
|
||||
|
||||
/** The minimum value for a volatile key identifier.
|
||||
*/
|
||||
#define PSA_KEY_ID_VOLATILE_MIN PSA_KEY_ID_VENDOR_MIN
|
||||
|
||||
/** The maximum value for a volatile key identifier.
|
||||
*/
|
||||
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
|
||||
#define PSA_KEY_ID_VOLATILE_MAX (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN - 1)
|
||||
#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
|
||||
#define PSA_KEY_ID_VOLATILE_MAX \
|
||||
(PSA_KEY_ID_VOLATILE_MIN + MBEDTLS_PSA_KEY_SLOT_COUNT - 1)
|
||||
#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
|
||||
|
||||
/** Test whether a key identifier is a volatile key identifier.
|
||||
*
|
||||
* \param key_id Key identifier to test.
|
||||
*
|
||||
* \retval 1
|
||||
* The key identifier is a volatile key identifier.
|
||||
* \retval 0
|
||||
* The key identifier is not a volatile key identifier.
|
||||
*/
|
||||
static inline int psa_key_id_is_volatile(psa_key_id_t key_id)
|
||||
{
|
||||
return (key_id >= PSA_KEY_ID_VOLATILE_MIN) &&
|
||||
(key_id <= PSA_KEY_ID_VOLATILE_MAX);
|
||||
}
|
||||
|
||||
/** Get the description of a key given its identifier and lock it.
|
||||
*
|
||||
* The descriptions of volatile keys and loaded persistent keys are stored in
|
||||
* key slots. This function returns a pointer to the key slot containing the
|
||||
* description of a key given its identifier.
|
||||
*
|
||||
* In case of a persistent key, the function loads the description of the key
|
||||
* into a key slot if not already done.
|
||||
*
|
||||
* On success, the returned key slot has been registered for reading.
|
||||
* It is the responsibility of the caller to call psa_unregister_read(slot)
|
||||
* when they have finished reading the contents of the slot.
|
||||
*
|
||||
* On failure, `*p_slot` is set to NULL. This ensures that it is always valid
|
||||
* to call psa_unregister_read on the returned slot.
|
||||
*
|
||||
* \param key Key identifier to query.
|
||||
* \param[out] p_slot On success, `*p_slot` contains a pointer to the
|
||||
* key slot containing the description of the key
|
||||
* identified by \p key.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \p *p_slot contains a pointer to the key slot containing the
|
||||
* description of the key identified by \p key.
|
||||
* The key slot counter has been incremented.
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The library has not been initialized.
|
||||
* \retval #PSA_ERROR_INVALID_HANDLE
|
||||
* \p key is not a valid key identifier.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \p key is a persistent key identifier. The implementation does not
|
||||
* have sufficient resources to load the persistent key. This can be
|
||||
* due to a lack of empty key slot, or available memory.
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST
|
||||
* There is no key with key identifier \p key.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
*/
|
||||
psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
|
||||
psa_key_slot_t **p_slot);
|
||||
|
||||
/** Initialize the key slot structures.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Currently this function always succeeds.
|
||||
*/
|
||||
psa_status_t psa_initialize_key_slots(void);
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
|
||||
/* Allow test code to customize the key slice length. We use this in tests
|
||||
* that exhaust the key store to reach a full key store in reasonable time
|
||||
* and memory.
|
||||
*
|
||||
* The length of each slice must be between 1 and
|
||||
* (1 << KEY_ID_SLOT_INDEX_WIDTH) inclusive.
|
||||
*
|
||||
* The length for a given slice index must not change while
|
||||
* the key store is initialized.
|
||||
*/
|
||||
extern size_t (*mbedtls_test_hook_psa_volatile_key_slice_length)(
|
||||
size_t slice_idx);
|
||||
|
||||
/* The number of volatile key slices. */
|
||||
size_t psa_key_slot_volatile_slice_count(void);
|
||||
#endif
|
||||
|
||||
/** Delete all data from key slots in memory.
|
||||
* This function is not thread safe, it wipes every key slot regardless of
|
||||
* state and reader count. It should only be called when no slot is in use.
|
||||
*
|
||||
* This does not affect persistent storage. */
|
||||
void psa_wipe_all_key_slots(void);
|
||||
|
||||
/** Find a free key slot and reserve it to be filled with a key.
|
||||
*
|
||||
* This function finds a key slot that is free,
|
||||
* sets its state to PSA_SLOT_FILLING and then returns the slot.
|
||||
*
|
||||
* On success, the key slot's state is PSA_SLOT_FILLING.
|
||||
* It is the responsibility of the caller to change the slot's state to
|
||||
* PSA_SLOT_EMPTY/FULL once key creation has finished.
|
||||
*
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param[out] volatile_key_id - If null, reserve a cache slot for
|
||||
* a persistent or built-in key.
|
||||
* - If non-null, allocate a slot for
|
||||
* a volatile key. On success,
|
||||
* \p *volatile_key_id is the
|
||||
* identifier corresponding to the
|
||||
* returned slot. It is the caller's
|
||||
* responsibility to set this key identifier
|
||||
* in the attributes.
|
||||
* \param[out] p_slot On success, a pointer to the slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* There were no free key slots.
|
||||
* When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, there was not
|
||||
* enough memory to allocate more slots.
|
||||
* \retval #PSA_ERROR_BAD_STATE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* This function attempted to operate on a key slot which was in an
|
||||
* unexpected state.
|
||||
*/
|
||||
psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
|
||||
psa_key_slot_t **p_slot);
|
||||
|
||||
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
|
||||
/** Return a key slot to the free list.
|
||||
*
|
||||
* Call this function when a slot obtained from psa_reserve_free_key_slot()
|
||||
* is no longer in use.
|
||||
*
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param slice_idx The slice containing the slot.
|
||||
* This is `slot->slice_index` when the slot
|
||||
* is obtained from psa_reserve_free_key_slot().
|
||||
* \param slot The key slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* This function attempted to operate on a key slot which was in an
|
||||
* unexpected state.
|
||||
*/
|
||||
psa_status_t psa_free_key_slot(size_t slice_idx,
|
||||
psa_key_slot_t *slot);
|
||||
#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
|
||||
|
||||
/** Change the state of a key slot.
|
||||
*
|
||||
* This function changes the state of the key slot from expected_state to
|
||||
* new state. If the state of the slot was not expected_state, the state is
|
||||
* unchanged.
|
||||
*
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param[in] slot The key slot.
|
||||
* \param[in] expected_state The current state of the slot.
|
||||
* \param[in] new_state The new state of the slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
The key slot's state variable is new_state.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* The slot's state was not expected_state.
|
||||
*/
|
||||
static inline psa_status_t psa_key_slot_state_transition(
|
||||
psa_key_slot_t *slot, psa_key_slot_state_t expected_state,
|
||||
psa_key_slot_state_t new_state)
|
||||
{
|
||||
if (slot->state != expected_state) {
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
slot->state = new_state;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/** Register as a reader of a key slot.
|
||||
*
|
||||
* This function increments the key slot registered reader counter by one.
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param[in] slot The key slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
The key slot registered reader counter was incremented.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* The reader counter already reached its maximum value and was not
|
||||
* increased, or the slot's state was not PSA_SLOT_FULL.
|
||||
*/
|
||||
static inline psa_status_t psa_register_read(psa_key_slot_t *slot)
|
||||
{
|
||||
if ((slot->state != PSA_SLOT_FULL) ||
|
||||
(slot->var.occupied.registered_readers >= SIZE_MAX)) {
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
slot->var.occupied.registered_readers++;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/** Unregister from reading a key slot.
|
||||
*
|
||||
* This function decrements the key slot registered reader counter by one.
|
||||
* If the state of the slot is PSA_SLOT_PENDING_DELETION,
|
||||
* and there is only one registered reader (the caller),
|
||||
* this function will call psa_wipe_key_slot().
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \note To ease the handling of errors in retrieving a key slot
|
||||
* a NULL input pointer is valid, and the function returns
|
||||
* successfully without doing anything in that case.
|
||||
*
|
||||
* \param[in] slot The key slot.
|
||||
* \retval #PSA_SUCCESS
|
||||
* \p slot is NULL or the key slot reader counter has been
|
||||
* decremented (and potentially wiped) successfully.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* The slot's state was neither PSA_SLOT_FULL nor
|
||||
* PSA_SLOT_PENDING_DELETION.
|
||||
* Or a wipe was attempted and the slot's state was not
|
||||
* PSA_SLOT_PENDING_DELETION.
|
||||
* Or registered_readers was equal to 0.
|
||||
*/
|
||||
psa_status_t psa_unregister_read(psa_key_slot_t *slot);
|
||||
|
||||
/** Wrap a call to psa_unregister_read in the global key slot mutex.
|
||||
*
|
||||
* If threading is disabled, this simply calls psa_unregister_read.
|
||||
*
|
||||
* \note To ease the handling of errors in retrieving a key slot
|
||||
* a NULL input pointer is valid, and the function returns
|
||||
* successfully without doing anything in that case.
|
||||
*
|
||||
* \param[in] slot The key slot.
|
||||
* \retval #PSA_SUCCESS
|
||||
* \p slot is NULL or the key slot reader counter has been
|
||||
* decremented (and potentially wiped) successfully.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* The slot's state was neither PSA_SLOT_FULL nor
|
||||
* PSA_SLOT_PENDING_DELETION.
|
||||
* Or a wipe was attempted and the slot's state was not
|
||||
* PSA_SLOT_PENDING_DELETION.
|
||||
* Or registered_readers was equal to 0.
|
||||
*/
|
||||
psa_status_t psa_unregister_read_under_mutex(psa_key_slot_t *slot);
|
||||
|
||||
/** Test whether a lifetime designates a key in an external cryptoprocessor.
|
||||
*
|
||||
* \param lifetime The lifetime to test.
|
||||
*
|
||||
* \retval 1
|
||||
* The lifetime designates an external key. There should be a
|
||||
* registered driver for this lifetime, otherwise the key cannot
|
||||
* be created or manipulated.
|
||||
* \retval 0
|
||||
* The lifetime designates a key that is volatile or in internal
|
||||
* storage.
|
||||
*/
|
||||
static inline int psa_key_lifetime_is_external(psa_key_lifetime_t lifetime)
|
||||
{
|
||||
return PSA_KEY_LIFETIME_GET_LOCATION(lifetime)
|
||||
!= PSA_KEY_LOCATION_LOCAL_STORAGE;
|
||||
}
|
||||
|
||||
/** Validate a key's location.
|
||||
*
|
||||
* This function checks whether the key's attributes point to a location that
|
||||
* is known to the PSA Core, and returns the driver function table if the key
|
||||
* is to be found in an external location.
|
||||
*
|
||||
* \param[in] lifetime The key lifetime attribute.
|
||||
* \param[out] p_drv On success, when a key is located in external
|
||||
* storage, returns a pointer to the driver table
|
||||
* associated with the key's storage location.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
*/
|
||||
psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime,
|
||||
psa_se_drv_table_entry_t **p_drv);
|
||||
|
||||
/** Validate the persistence of a key.
|
||||
*
|
||||
* \param[in] lifetime The key lifetime attribute.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED The key is persistent but persistent keys
|
||||
* are not supported.
|
||||
*/
|
||||
psa_status_t psa_validate_key_persistence(psa_key_lifetime_t lifetime);
|
||||
|
||||
/** Validate a key identifier.
|
||||
*
|
||||
* \param[in] key The key identifier.
|
||||
* \param[in] vendor_ok Non-zero to indicate that key identifiers in the
|
||||
* vendor range are allowed, volatile key identifiers
|
||||
* excepted \c 0 otherwise.
|
||||
*
|
||||
* \retval <> 0 if the key identifier is valid, 0 otherwise.
|
||||
*/
|
||||
int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok);
|
||||
|
||||
#endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */
|
||||
481
Libs/util/third_party/mbedtls/library/psa_crypto_storage.c
vendored
Normal file
481
Libs/util/third_party/mbedtls/library/psa_crypto_storage.c
vendored
Normal file
@@ -0,0 +1,481 @@
|
||||
/*
|
||||
* PSA persistent key storage
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_storage.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_ITS_FILE_C)
|
||||
#include "psa_crypto_its.h"
|
||||
#else /* Native ITS implementation */
|
||||
#include "psa/error.h"
|
||||
#include "psa/internal_trusted_storage.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Key storage */
|
||||
/****************************************************************/
|
||||
|
||||
/* Determine a file name (ITS file identifier) for the given key identifier.
|
||||
* The file name must be distinct from any file that is used for a purpose
|
||||
* other than storing a key. Currently, the only such file is the random seed
|
||||
* file whose name is PSA_CRYPTO_ITS_RANDOM_SEED_UID and whose value is
|
||||
* 0xFFFFFF52. */
|
||||
static psa_storage_uid_t psa_its_identifier_of_slot(mbedtls_svc_key_id_t key)
|
||||
{
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
|
||||
/* Encode the owner in the upper 32 bits. This means that if
|
||||
* owner values are nonzero (as they are on a PSA platform),
|
||||
* no key file will ever have a value less than 0x100000000, so
|
||||
* the whole range 0..0xffffffff is available for non-key files. */
|
||||
uint32_t unsigned_owner_id = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(key);
|
||||
return ((uint64_t) unsigned_owner_id << 32) |
|
||||
MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key);
|
||||
#else
|
||||
/* Use the key id directly as a file name.
|
||||
* psa_is_key_id_valid() in psa_crypto_slot_management.c
|
||||
* is responsible for ensuring that key identifiers do not have a
|
||||
* value that is reserved for non-key files. */
|
||||
return key;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Load persistent data for the given key slot number.
|
||||
*
|
||||
* This function reads data from a storage backend and returns the data in a
|
||||
* buffer.
|
||||
*
|
||||
* \param key Persistent identifier of the key to be loaded. This
|
||||
* should be an occupied storage location.
|
||||
* \param[out] data Buffer where the data is to be written.
|
||||
* \param data_size Size of the \c data buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
|
||||
*/
|
||||
static psa_status_t psa_crypto_storage_load(
|
||||
const mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
size_t data_length = 0;
|
||||
|
||||
status = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_its_get(data_identifier, 0, (uint32_t) data_size, data, &data_length);
|
||||
if (data_size != data_length) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key)
|
||||
{
|
||||
psa_status_t ret;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
|
||||
ret = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
|
||||
if (ret == PSA_ERROR_DOES_NOT_EXIST) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Store persistent data for the given key slot number.
|
||||
*
|
||||
* This function stores the given data buffer to a persistent storage.
|
||||
*
|
||||
* \param key Persistent identifier of the key to be stored. This
|
||||
* should be an unoccupied storage location.
|
||||
* \param[in] data Buffer containing the data to be stored.
|
||||
* \param data_length The number of bytes
|
||||
* that make up the data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
*/
|
||||
static psa_status_t psa_crypto_storage_store(const mbedtls_svc_key_id_t key,
|
||||
const uint8_t *data,
|
||||
size_t data_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
|
||||
if (psa_is_key_present_in_storage(key) == 1) {
|
||||
return PSA_ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
status = psa_its_set(data_identifier, (uint32_t) data_length, data, 0);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
status = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (data_identifier_info.size != data_length) {
|
||||
status = PSA_ERROR_DATA_INVALID;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (status != PSA_SUCCESS) {
|
||||
/* Remove the file in case we managed to create it but something
|
||||
* went wrong. It's ok if the file doesn't exist. If the file exists
|
||||
* but the removal fails, we're already reporting an error so there's
|
||||
* nothing else we can do. */
|
||||
(void) psa_its_remove(data_identifier);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key)
|
||||
{
|
||||
psa_status_t ret;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
|
||||
ret = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (ret == PSA_ERROR_DOES_NOT_EXIST) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
if (psa_its_remove(data_identifier) != PSA_SUCCESS) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
ret = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (ret != PSA_ERROR_DOES_NOT_EXIST) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get data length for given key slot number.
|
||||
*
|
||||
* \param key Persistent identifier whose stored data length
|
||||
* is to be obtained.
|
||||
* \param[out] data_length The number of bytes that make up the data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
*/
|
||||
static psa_status_t psa_crypto_storage_get_data_length(
|
||||
const mbedtls_svc_key_id_t key,
|
||||
size_t *data_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
|
||||
status = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
*data_length = (size_t) data_identifier_info.size;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Persistent key storage magic header.
|
||||
*/
|
||||
#define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
|
||||
#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH (sizeof(PSA_KEY_STORAGE_MAGIC_HEADER))
|
||||
|
||||
typedef struct {
|
||||
uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
|
||||
uint8_t version[4];
|
||||
uint8_t lifetime[sizeof(psa_key_lifetime_t)];
|
||||
uint8_t type[2];
|
||||
uint8_t bits[2];
|
||||
uint8_t policy[sizeof(psa_key_policy_t)];
|
||||
uint8_t data_len[4];
|
||||
uint8_t key_data[];
|
||||
} psa_persistent_key_storage_format;
|
||||
|
||||
void psa_format_key_data_for_storage(const uint8_t *data,
|
||||
const size_t data_length,
|
||||
const psa_key_attributes_t *attr,
|
||||
uint8_t *storage_data)
|
||||
{
|
||||
psa_persistent_key_storage_format *storage_format =
|
||||
(psa_persistent_key_storage_format *) storage_data;
|
||||
|
||||
memcpy(storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER,
|
||||
PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH);
|
||||
MBEDTLS_PUT_UINT32_LE(0, storage_format->version, 0);
|
||||
MBEDTLS_PUT_UINT32_LE(attr->lifetime, storage_format->lifetime, 0);
|
||||
MBEDTLS_PUT_UINT16_LE((uint16_t) attr->type, storage_format->type, 0);
|
||||
MBEDTLS_PUT_UINT16_LE((uint16_t) attr->bits, storage_format->bits, 0);
|
||||
MBEDTLS_PUT_UINT32_LE(attr->policy.usage, storage_format->policy, 0);
|
||||
MBEDTLS_PUT_UINT32_LE(attr->policy.alg, storage_format->policy, sizeof(uint32_t));
|
||||
MBEDTLS_PUT_UINT32_LE(attr->policy.alg2, storage_format->policy, 2 * sizeof(uint32_t));
|
||||
MBEDTLS_PUT_UINT32_LE(data_length, storage_format->data_len, 0);
|
||||
memcpy(storage_format->key_data, data, data_length);
|
||||
}
|
||||
|
||||
static psa_status_t check_magic_header(const uint8_t *data)
|
||||
{
|
||||
if (memcmp(data, PSA_KEY_STORAGE_MAGIC_HEADER,
|
||||
PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH) != 0) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data,
|
||||
size_t storage_data_length,
|
||||
uint8_t **key_data,
|
||||
size_t *key_data_length,
|
||||
psa_key_attributes_t *attr)
|
||||
{
|
||||
psa_status_t status;
|
||||
const psa_persistent_key_storage_format *storage_format =
|
||||
(const psa_persistent_key_storage_format *) storage_data;
|
||||
uint32_t version;
|
||||
|
||||
if (storage_data_length < sizeof(*storage_format)) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
status = check_magic_header(storage_data);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
version = MBEDTLS_GET_UINT32_LE(storage_format->version, 0);
|
||||
if (version != 0) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
*key_data_length = MBEDTLS_GET_UINT32_LE(storage_format->data_len, 0);
|
||||
if (*key_data_length > (storage_data_length - sizeof(*storage_format)) ||
|
||||
*key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
if (*key_data_length == 0) {
|
||||
*key_data = NULL;
|
||||
} else {
|
||||
*key_data = mbedtls_calloc(1, *key_data_length);
|
||||
if (*key_data == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
memcpy(*key_data, storage_format->key_data, *key_data_length);
|
||||
}
|
||||
|
||||
attr->lifetime = MBEDTLS_GET_UINT32_LE(storage_format->lifetime, 0);
|
||||
attr->type = MBEDTLS_GET_UINT16_LE(storage_format->type, 0);
|
||||
attr->bits = MBEDTLS_GET_UINT16_LE(storage_format->bits, 0);
|
||||
attr->policy.usage = MBEDTLS_GET_UINT32_LE(storage_format->policy, 0);
|
||||
attr->policy.alg = MBEDTLS_GET_UINT32_LE(storage_format->policy, sizeof(uint32_t));
|
||||
attr->policy.alg2 = MBEDTLS_GET_UINT32_LE(storage_format->policy, 2 * sizeof(uint32_t));
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr,
|
||||
const uint8_t *data,
|
||||
const size_t data_length)
|
||||
{
|
||||
size_t storage_data_length;
|
||||
uint8_t *storage_data;
|
||||
psa_status_t status;
|
||||
|
||||
/* All keys saved to persistent storage always have a key context */
|
||||
if (data == NULL || data_length == 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (data_length > PSA_CRYPTO_MAX_STORAGE_SIZE) {
|
||||
return PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
storage_data_length = data_length + sizeof(psa_persistent_key_storage_format);
|
||||
|
||||
storage_data = mbedtls_calloc(1, storage_data_length);
|
||||
if (storage_data == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
psa_format_key_data_for_storage(data, data_length, attr, storage_data);
|
||||
|
||||
status = psa_crypto_storage_store(attr->id,
|
||||
storage_data, storage_data_length);
|
||||
|
||||
mbedtls_zeroize_and_free(storage_data, storage_data_length);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length)
|
||||
{
|
||||
mbedtls_zeroize_and_free(key_data, key_data_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr,
|
||||
uint8_t **data,
|
||||
size_t *data_length)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
uint8_t *loaded_data;
|
||||
size_t storage_data_length = 0;
|
||||
mbedtls_svc_key_id_t key = attr->id;
|
||||
|
||||
status = psa_crypto_storage_get_data_length(key, &storage_data_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
loaded_data = mbedtls_calloc(1, storage_data_length);
|
||||
|
||||
if (loaded_data == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
status = psa_crypto_storage_load(key, loaded_data, storage_data_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_parse_key_data_from_storage(loaded_data, storage_data_length,
|
||||
data, data_length, attr);
|
||||
|
||||
/* All keys saved to persistent storage always have a key context */
|
||||
if (status == PSA_SUCCESS &&
|
||||
(*data == NULL || *data_length == 0)) {
|
||||
status = PSA_ERROR_STORAGE_FAILURE;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_zeroize_and_free(loaded_data, storage_data_length);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Transactions */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
|
||||
|
||||
psa_crypto_transaction_t psa_crypto_transaction;
|
||||
|
||||
psa_status_t psa_crypto_save_transaction(void)
|
||||
{
|
||||
struct psa_storage_info_t p_info;
|
||||
psa_status_t status;
|
||||
status = psa_its_get_info(PSA_CRYPTO_ITS_TRANSACTION_UID, &p_info);
|
||||
if (status == PSA_SUCCESS) {
|
||||
/* This shouldn't happen: we're trying to start a transaction while
|
||||
* there is still a transaction that hasn't been replayed. */
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
} else if (status != PSA_ERROR_DOES_NOT_EXIST) {
|
||||
return status;
|
||||
}
|
||||
return psa_its_set(PSA_CRYPTO_ITS_TRANSACTION_UID,
|
||||
sizeof(psa_crypto_transaction),
|
||||
&psa_crypto_transaction,
|
||||
0);
|
||||
}
|
||||
|
||||
psa_status_t psa_crypto_load_transaction(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
size_t length;
|
||||
status = psa_its_get(PSA_CRYPTO_ITS_TRANSACTION_UID, 0,
|
||||
sizeof(psa_crypto_transaction),
|
||||
&psa_crypto_transaction, &length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
if (length != sizeof(psa_crypto_transaction)) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_crypto_stop_transaction(void)
|
||||
{
|
||||
psa_status_t status = psa_its_remove(PSA_CRYPTO_ITS_TRANSACTION_UID);
|
||||
/* Whether or not updating the storage succeeded, the transaction is
|
||||
* finished now. It's too late to go back, so zero out the in-memory
|
||||
* data. */
|
||||
memset(&psa_crypto_transaction, 0, sizeof(psa_crypto_transaction));
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Random generator state */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
|
||||
psa_status_t mbedtls_psa_storage_inject_entropy(const unsigned char *seed,
|
||||
size_t seed_size)
|
||||
{
|
||||
psa_status_t status;
|
||||
struct psa_storage_info_t p_info;
|
||||
|
||||
status = psa_its_get_info(PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info);
|
||||
|
||||
if (PSA_ERROR_DOES_NOT_EXIST == status) { /* No seed exists */
|
||||
status = psa_its_set(PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0);
|
||||
} else if (PSA_SUCCESS == status) {
|
||||
/* You should not be here. Seed needs to be injected only once */
|
||||
status = PSA_ERROR_NOT_PERMITTED;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* The end */
|
||||
/****************************************************************/
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
385
Libs/util/third_party/mbedtls/library/psa_crypto_storage.h
vendored
Normal file
385
Libs/util/third_party/mbedtls/library/psa_crypto_storage.h
vendored
Normal file
@@ -0,0 +1,385 @@
|
||||
/**
|
||||
* \file psa_crypto_storage.h
|
||||
*
|
||||
* \brief PSA cryptography module: Mbed TLS key storage
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_STORAGE_H
|
||||
#define PSA_CRYPTO_STORAGE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Limit the maximum key size in storage. This should have no effect
|
||||
* since the key size is limited in memory. */
|
||||
#define PSA_CRYPTO_MAX_STORAGE_SIZE (PSA_BITS_TO_BYTES(PSA_MAX_KEY_BITS))
|
||||
/* Sanity check: a file size must fit in 32 bits. Allow a generous
|
||||
* 64kB of metadata. */
|
||||
#if PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000
|
||||
#error "PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000"
|
||||
#endif
|
||||
|
||||
/** The maximum permitted persistent slot number.
|
||||
*
|
||||
* In Mbed Crypto 0.1.0b:
|
||||
* - Using the file backend, all key ids are ok except 0.
|
||||
* - Using the ITS backend, all key ids are ok except 0xFFFFFF52
|
||||
* (#PSA_CRYPTO_ITS_RANDOM_SEED_UID) for which the file contains the
|
||||
* device's random seed (if this feature is enabled).
|
||||
* - Only key ids from 1 to #MBEDTLS_PSA_KEY_SLOT_COUNT are actually used.
|
||||
*
|
||||
* Since we need to preserve the random seed, avoid using that key slot.
|
||||
* Reserve a whole range of key slots just in case something else comes up.
|
||||
*
|
||||
* This limitation will probably become moot when we implement client
|
||||
* separation for key storage.
|
||||
*/
|
||||
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER PSA_KEY_ID_VENDOR_MAX
|
||||
|
||||
/**
|
||||
* \brief Checks if persistent data is stored for the given key slot number
|
||||
*
|
||||
* This function checks if any key data or metadata exists for the key slot in
|
||||
* the persistent storage.
|
||||
*
|
||||
* \param key Persistent identifier to check.
|
||||
*
|
||||
* \retval 0
|
||||
* No persistent data present for slot number
|
||||
* \retval 1
|
||||
* Persistent data present for slot number
|
||||
*/
|
||||
int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key);
|
||||
|
||||
/**
|
||||
* \brief Format key data and metadata and save to a location for given key
|
||||
* slot.
|
||||
*
|
||||
* This function formats the key data and metadata and saves it to a
|
||||
* persistent storage backend. The storage location corresponding to the
|
||||
* key slot must be empty, otherwise this function will fail. This function
|
||||
* should be called after loading the key into an internal slot to ensure the
|
||||
* persistent key is not saved into a storage location corresponding to an
|
||||
* already occupied non-persistent key, as well as ensuring the key data is
|
||||
* validated.
|
||||
*
|
||||
* Note: This function will only succeed for key buffers which are not
|
||||
* empty. If passed a NULL pointer or zero-length, the function will fail
|
||||
* with #PSA_ERROR_INVALID_ARGUMENT.
|
||||
*
|
||||
* \param[in] attr The attributes of the key to save.
|
||||
* The key identifier field in the attributes
|
||||
* determines the key's location.
|
||||
* \param[in] data Buffer containing the key data.
|
||||
* \param data_length The number of bytes that make up the key data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
*/
|
||||
psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr,
|
||||
const uint8_t *data,
|
||||
const size_t data_length);
|
||||
|
||||
/**
|
||||
* \brief Parses key data and metadata and load persistent key for given
|
||||
* key slot number.
|
||||
*
|
||||
* This function reads from a storage backend, parses the key data and
|
||||
* metadata and writes them to the appropriate output parameters.
|
||||
*
|
||||
* Note: This function allocates a buffer and returns a pointer to it through
|
||||
* the data parameter. On successful return, the pointer is guaranteed to be
|
||||
* valid and the buffer contains at least one byte of data.
|
||||
* psa_free_persistent_key_data() must be called on the data buffer
|
||||
* afterwards to zeroize and free this buffer.
|
||||
*
|
||||
* \param[in,out] attr On input, the key identifier field identifies
|
||||
* the key to load. Other fields are ignored.
|
||||
* On success, the attribute structure contains
|
||||
* the key metadata that was loaded from storage.
|
||||
* \param[out] data Pointer to an allocated key data buffer on return.
|
||||
* \param[out] data_length The number of bytes that make up the key data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
|
||||
*/
|
||||
psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr,
|
||||
uint8_t **data,
|
||||
size_t *data_length);
|
||||
|
||||
/**
|
||||
* \brief Remove persistent data for the given key slot number.
|
||||
*
|
||||
* \param key Persistent identifier of the key to remove
|
||||
* from persistent storage.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The key was successfully removed,
|
||||
* or the key did not exist.
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
*/
|
||||
psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key);
|
||||
|
||||
/**
|
||||
* \brief Free the temporary buffer allocated by psa_load_persistent_key().
|
||||
*
|
||||
* This function must be called at some point after psa_load_persistent_key()
|
||||
* to zeroize and free the memory allocated to the buffer in that function.
|
||||
*
|
||||
* \param key_data Buffer for the key data.
|
||||
* \param key_data_length Size of the key data buffer.
|
||||
*
|
||||
*/
|
||||
void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length);
|
||||
|
||||
/**
|
||||
* \brief Formats key data and metadata for persistent storage
|
||||
*
|
||||
* \param[in] data Buffer containing the key data.
|
||||
* \param data_length Length of the key data buffer.
|
||||
* \param[in] attr The core attributes of the key.
|
||||
* \param[out] storage_data Output buffer for the formatted data.
|
||||
*
|
||||
*/
|
||||
void psa_format_key_data_for_storage(const uint8_t *data,
|
||||
const size_t data_length,
|
||||
const psa_key_attributes_t *attr,
|
||||
uint8_t *storage_data);
|
||||
|
||||
/**
|
||||
* \brief Parses persistent storage data into key data and metadata
|
||||
*
|
||||
* \param[in] storage_data Buffer for the storage data.
|
||||
* \param storage_data_length Length of the storage data buffer
|
||||
* \param[out] key_data On output, pointer to a newly allocated buffer
|
||||
* containing the key data. This must be freed
|
||||
* using psa_free_persistent_key_data()
|
||||
* \param[out] key_data_length Length of the key data buffer
|
||||
* \param[out] attr On success, the attribute structure is filled
|
||||
* with the loaded key metadata.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
*/
|
||||
psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data,
|
||||
size_t storage_data_length,
|
||||
uint8_t **key_data,
|
||||
size_t *key_data_length,
|
||||
psa_key_attributes_t *attr);
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/** This symbol is defined if transaction support is required. */
|
||||
#define PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS 1
|
||||
#endif
|
||||
|
||||
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
|
||||
|
||||
/** The type of transaction that is in progress.
|
||||
*/
|
||||
/* This is an integer type rather than an enum for two reasons: to support
|
||||
* unknown values when loading a transaction file, and to ensure that the
|
||||
* type has a known size.
|
||||
*/
|
||||
typedef uint16_t psa_crypto_transaction_type_t;
|
||||
|
||||
/** No transaction is in progress.
|
||||
*
|
||||
* This has the value 0, so zero-initialization sets a transaction's type to
|
||||
* this value.
|
||||
*/
|
||||
#define PSA_CRYPTO_TRANSACTION_NONE ((psa_crypto_transaction_type_t) 0x0000)
|
||||
|
||||
/** A key creation transaction.
|
||||
*
|
||||
* This is only used for keys in an external cryptoprocessor (secure element).
|
||||
* Keys in RAM or in internal storage are created atomically in storage
|
||||
* (simple file creation), so they do not need a transaction mechanism.
|
||||
*/
|
||||
#define PSA_CRYPTO_TRANSACTION_CREATE_KEY ((psa_crypto_transaction_type_t) 0x0001)
|
||||
|
||||
/** A key destruction transaction.
|
||||
*
|
||||
* This is only used for keys in an external cryptoprocessor (secure element).
|
||||
* Keys in RAM or in internal storage are destroyed atomically in storage
|
||||
* (simple file deletion), so they do not need a transaction mechanism.
|
||||
*/
|
||||
#define PSA_CRYPTO_TRANSACTION_DESTROY_KEY ((psa_crypto_transaction_type_t) 0x0002)
|
||||
|
||||
/** Transaction data.
|
||||
*
|
||||
* This type is designed to be serialized by writing the memory representation
|
||||
* and reading it back on the same device.
|
||||
*
|
||||
* \note The transaction mechanism is not thread-safe. There can only be one
|
||||
* single active transaction at a time.
|
||||
* The transaction object is #psa_crypto_transaction.
|
||||
*
|
||||
* \note If an API call starts a transaction, it must complete this transaction
|
||||
* before returning to the application.
|
||||
*
|
||||
* The lifetime of a transaction is the following (note that only one
|
||||
* transaction may be active at a time):
|
||||
*
|
||||
* -# Call psa_crypto_prepare_transaction() to initialize the transaction
|
||||
* object in memory and declare the type of transaction that is starting.
|
||||
* -# Fill in the type-specific fields of #psa_crypto_transaction.
|
||||
* -# Call psa_crypto_save_transaction() to start the transaction. This
|
||||
* saves the transaction data to internal storage.
|
||||
* -# Perform the work of the transaction by modifying files, contacting
|
||||
* external entities, or whatever needs doing. Note that the transaction
|
||||
* may be interrupted by a power failure, so you need to have a way
|
||||
* recover from interruptions either by undoing what has been done
|
||||
* so far or by resuming where you left off.
|
||||
* -# If there are intermediate stages in the transaction, update
|
||||
* the fields of #psa_crypto_transaction and call
|
||||
* psa_crypto_save_transaction() again when each stage is reached.
|
||||
* -# When the transaction is over, call psa_crypto_stop_transaction() to
|
||||
* remove the transaction data in storage and in memory.
|
||||
*
|
||||
* If the system crashes while a transaction is in progress, psa_crypto_init()
|
||||
* calls psa_crypto_load_transaction() and takes care of completing or
|
||||
* rewinding the transaction. This is done in psa_crypto_recover_transaction()
|
||||
* in psa_crypto.c. If you add a new type of transaction, be
|
||||
* sure to add code for it in psa_crypto_recover_transaction().
|
||||
*/
|
||||
typedef union {
|
||||
/* Each element of this union must have the following properties
|
||||
* to facilitate serialization and deserialization:
|
||||
*
|
||||
* - The element is a struct.
|
||||
* - The first field of the struct is `psa_crypto_transaction_type_t type`.
|
||||
* - Elements of the struct are arranged such a way that there is
|
||||
* no padding.
|
||||
*/
|
||||
struct psa_crypto_transaction_unknown_s {
|
||||
psa_crypto_transaction_type_t type;
|
||||
uint16_t unused1;
|
||||
uint32_t unused2;
|
||||
uint64_t unused3;
|
||||
uint64_t unused4;
|
||||
} unknown;
|
||||
/* ::type is #PSA_CRYPTO_TRANSACTION_CREATE_KEY or
|
||||
* #PSA_CRYPTO_TRANSACTION_DESTROY_KEY. */
|
||||
struct psa_crypto_transaction_key_s {
|
||||
psa_crypto_transaction_type_t type;
|
||||
uint16_t unused1;
|
||||
psa_key_lifetime_t lifetime;
|
||||
psa_key_slot_number_t slot;
|
||||
mbedtls_svc_key_id_t id;
|
||||
} key;
|
||||
} psa_crypto_transaction_t;
|
||||
|
||||
/** The single active transaction.
|
||||
*/
|
||||
extern psa_crypto_transaction_t psa_crypto_transaction;
|
||||
|
||||
/** Prepare for a transaction.
|
||||
*
|
||||
* There must not be an ongoing transaction.
|
||||
*
|
||||
* \param type The type of transaction to start.
|
||||
*/
|
||||
static inline void psa_crypto_prepare_transaction(
|
||||
psa_crypto_transaction_type_t type)
|
||||
{
|
||||
psa_crypto_transaction.unknown.type = type;
|
||||
}
|
||||
|
||||
/** Save the transaction data to storage.
|
||||
*
|
||||
* You may call this function multiple times during a transaction to
|
||||
* atomically update the transaction state.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
*/
|
||||
psa_status_t psa_crypto_save_transaction(void);
|
||||
|
||||
/** Load the transaction data from storage, if any.
|
||||
*
|
||||
* This function is meant to be called from psa_crypto_init() to recover
|
||||
* in case a transaction was interrupted by a system crash.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The data about the ongoing transaction has been loaded to
|
||||
* #psa_crypto_transaction.
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST
|
||||
* There is no ongoing transaction.
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
*/
|
||||
psa_status_t psa_crypto_load_transaction(void);
|
||||
|
||||
/** Indicate that the current transaction is finished.
|
||||
*
|
||||
* Call this function at the very end of transaction processing.
|
||||
* This function does not "commit" or "abort" the transaction: the storage
|
||||
* subsystem has no concept of "commit" and "abort", just saving and
|
||||
* removing the transaction information in storage.
|
||||
*
|
||||
* This function erases the transaction data in storage (if any) and
|
||||
* resets the transaction data in memory.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* There was transaction data in storage.
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST
|
||||
* There was no transaction data in storage.
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE
|
||||
* It was impossible to determine whether there was transaction data
|
||||
* in storage, or the transaction data could not be erased.
|
||||
*/
|
||||
psa_status_t psa_crypto_stop_transaction(void);
|
||||
|
||||
/** The ITS file identifier for the transaction data.
|
||||
*
|
||||
* 0xffffffNN = special file; 0x74 = 't' for transaction.
|
||||
*/
|
||||
#define PSA_CRYPTO_ITS_TRANSACTION_UID ((psa_key_id_t) 0xffffff74)
|
||||
|
||||
#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
|
||||
|
||||
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
|
||||
/** Backend side of mbedtls_psa_inject_entropy().
|
||||
*
|
||||
* This function stores the supplied data into the entropy seed file.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* The entropy seed file already exists.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_storage_inject_entropy(const unsigned char *seed,
|
||||
size_t seed_size);
|
||||
#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_STORAGE_H */
|
||||
615
Libs/util/third_party/mbedtls/library/psa_util.c
vendored
Normal file
615
Libs/util/third_party/mbedtls/library/psa_util.c
vendored
Normal file
@@ -0,0 +1,615 @@
|
||||
/*
|
||||
* PSA hashing layer on top of Mbed TLS software crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* This is needed for MBEDTLS_ERR_XXX macros */
|
||||
#include <mbedtls/error.h>
|
||||
|
||||
#if defined(MBEDTLS_ASN1_WRITE_C)
|
||||
#include <mbedtls/asn1write.h>
|
||||
#include <psa/crypto_sizes.h>
|
||||
#endif
|
||||
|
||||
#include "psa_util_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
#if defined(MBEDTLS_MD_LIGHT)
|
||||
#include <mbedtls/md.h>
|
||||
#endif
|
||||
#if defined(MBEDTLS_LMS_C)
|
||||
#include <mbedtls/lms.h>
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
|
||||
#include <mbedtls/ssl.h>
|
||||
#endif
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
|
||||
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
|
||||
#include <mbedtls/rsa.h>
|
||||
#endif
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
#include <mbedtls/ecp.h>
|
||||
#endif
|
||||
#if defined(MBEDTLS_PK_C)
|
||||
#include <mbedtls/pk.h>
|
||||
#endif
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
#include <mbedtls/cipher.h>
|
||||
#endif
|
||||
#include <mbedtls/entropy.h>
|
||||
|
||||
/* PSA_SUCCESS is kept at the top of each error table since
|
||||
* it's the most common status when everything functions properly. */
|
||||
#if defined(MBEDTLS_MD_LIGHT)
|
||||
const mbedtls_error_pair_t psa_to_md_errors[] =
|
||||
{
|
||||
{ PSA_SUCCESS, 0 },
|
||||
{ PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE },
|
||||
{ PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_MD_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_MD_ALLOC_FAILED }
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
const mbedtls_error_pair_t psa_to_cipher_errors[] =
|
||||
{
|
||||
{ PSA_SUCCESS, 0 },
|
||||
{ PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE },
|
||||
{ PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_CIPHER_ALLOC_FAILED }
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_LMS_C)
|
||||
const mbedtls_error_pair_t psa_to_lms_errors[] =
|
||||
{
|
||||
{ PSA_SUCCESS, 0 },
|
||||
{ PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL },
|
||||
{ PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_LMS_BAD_INPUT_DATA }
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
|
||||
const mbedtls_error_pair_t psa_to_ssl_errors[] =
|
||||
{
|
||||
{ PSA_SUCCESS, 0 },
|
||||
{ PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_SSL_ALLOC_FAILED },
|
||||
{ PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE },
|
||||
{ PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_SSL_INVALID_MAC },
|
||||
{ PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_SSL_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_BAD_STATE, MBEDTLS_ERR_SSL_INTERNAL_ERROR },
|
||||
{ PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL }
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
|
||||
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
|
||||
const mbedtls_error_pair_t psa_to_pk_rsa_errors[] =
|
||||
{
|
||||
{ PSA_SUCCESS, 0 },
|
||||
{ PSA_ERROR_NOT_PERMITTED, MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_INVALID_HANDLE, MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE },
|
||||
{ PSA_ERROR_INSUFFICIENT_ENTROPY, MBEDTLS_ERR_RSA_RNG_FAILED },
|
||||
{ PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_RSA_VERIFY_FAILED },
|
||||
{ PSA_ERROR_INVALID_PADDING, MBEDTLS_ERR_RSA_INVALID_PADDING }
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
const mbedtls_error_pair_t psa_to_pk_ecdsa_errors[] =
|
||||
{
|
||||
{ PSA_SUCCESS, 0 },
|
||||
{ PSA_ERROR_NOT_PERMITTED, MBEDTLS_ERR_ECP_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_ECP_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_INVALID_HANDLE, MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE },
|
||||
{ PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL },
|
||||
{ PSA_ERROR_INSUFFICIENT_ENTROPY, MBEDTLS_ERR_ECP_RANDOM_FAILED },
|
||||
{ PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_ECP_VERIFY_FAILED }
|
||||
};
|
||||
#endif
|
||||
|
||||
int psa_generic_status_to_mbedtls(psa_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case PSA_SUCCESS:
|
||||
return 0;
|
||||
case PSA_ERROR_NOT_SUPPORTED:
|
||||
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
|
||||
case PSA_ERROR_CORRUPTION_DETECTED:
|
||||
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
case PSA_ERROR_COMMUNICATION_FAILURE:
|
||||
case PSA_ERROR_HARDWARE_FAILURE:
|
||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
case PSA_ERROR_NOT_PERMITTED:
|
||||
default:
|
||||
return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int psa_status_to_mbedtls(psa_status_t status,
|
||||
const mbedtls_error_pair_t *local_translations,
|
||||
size_t local_errors_num,
|
||||
int (*fallback_f)(psa_status_t))
|
||||
{
|
||||
for (size_t i = 0; i < local_errors_num; i++) {
|
||||
if (status == local_translations[i].psa_status) {
|
||||
return local_translations[i].mbedtls_error;
|
||||
}
|
||||
}
|
||||
return fallback_f(status);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PK_C)
|
||||
int psa_pk_status_to_mbedtls(psa_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case PSA_ERROR_INVALID_HANDLE:
|
||||
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
|
||||
case PSA_ERROR_BUFFER_TOO_SMALL:
|
||||
return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
|
||||
case PSA_ERROR_NOT_SUPPORTED:
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
case PSA_ERROR_INVALID_ARGUMENT:
|
||||
return MBEDTLS_ERR_PK_INVALID_ALG;
|
||||
case PSA_ERROR_NOT_PERMITTED:
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
case PSA_ERROR_INSUFFICIENT_MEMORY:
|
||||
return MBEDTLS_ERR_PK_ALLOC_FAILED;
|
||||
case PSA_ERROR_BAD_STATE:
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
case PSA_ERROR_DATA_CORRUPT:
|
||||
case PSA_ERROR_DATA_INVALID:
|
||||
case PSA_ERROR_STORAGE_FAILURE:
|
||||
return MBEDTLS_ERR_PK_FILE_IO_ERROR;
|
||||
default:
|
||||
return psa_generic_status_to_mbedtls(status);
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_PK_C */
|
||||
|
||||
/****************************************************************/
|
||||
/* Key management */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid,
|
||||
size_t *bits)
|
||||
{
|
||||
switch (grpid) {
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP192R1)
|
||||
case MBEDTLS_ECP_DP_SECP192R1:
|
||||
*bits = 192;
|
||||
return PSA_ECC_FAMILY_SECP_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP224R1)
|
||||
case MBEDTLS_ECP_DP_SECP224R1:
|
||||
*bits = 224;
|
||||
return PSA_ECC_FAMILY_SECP_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP256R1)
|
||||
case MBEDTLS_ECP_DP_SECP256R1:
|
||||
*bits = 256;
|
||||
return PSA_ECC_FAMILY_SECP_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP384R1)
|
||||
case MBEDTLS_ECP_DP_SECP384R1:
|
||||
*bits = 384;
|
||||
return PSA_ECC_FAMILY_SECP_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP521R1)
|
||||
case MBEDTLS_ECP_DP_SECP521R1:
|
||||
*bits = 521;
|
||||
return PSA_ECC_FAMILY_SECP_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_BP256R1)
|
||||
case MBEDTLS_ECP_DP_BP256R1:
|
||||
*bits = 256;
|
||||
return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_BP384R1)
|
||||
case MBEDTLS_ECP_DP_BP384R1:
|
||||
*bits = 384;
|
||||
return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_BP512R1)
|
||||
case MBEDTLS_ECP_DP_BP512R1:
|
||||
*bits = 512;
|
||||
return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_CURVE25519)
|
||||
case MBEDTLS_ECP_DP_CURVE25519:
|
||||
*bits = 255;
|
||||
return PSA_ECC_FAMILY_MONTGOMERY;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP192K1)
|
||||
case MBEDTLS_ECP_DP_SECP192K1:
|
||||
*bits = 192;
|
||||
return PSA_ECC_FAMILY_SECP_K1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP224K1)
|
||||
/* secp224k1 is not and will not be supported in PSA (#3541). */
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP256K1)
|
||||
case MBEDTLS_ECP_DP_SECP256K1:
|
||||
*bits = 256;
|
||||
return PSA_ECC_FAMILY_SECP_K1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_CURVE448)
|
||||
case MBEDTLS_ECP_DP_CURVE448:
|
||||
*bits = 448;
|
||||
return PSA_ECC_FAMILY_MONTGOMERY;
|
||||
#endif
|
||||
default:
|
||||
*bits = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
|
||||
size_t bits)
|
||||
{
|
||||
switch (family) {
|
||||
case PSA_ECC_FAMILY_SECP_R1:
|
||||
switch (bits) {
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_192)
|
||||
case 192:
|
||||
return MBEDTLS_ECP_DP_SECP192R1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_224)
|
||||
case 224:
|
||||
return MBEDTLS_ECP_DP_SECP224R1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_256)
|
||||
case 256:
|
||||
return MBEDTLS_ECP_DP_SECP256R1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_384)
|
||||
case 384:
|
||||
return MBEDTLS_ECP_DP_SECP384R1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_521)
|
||||
case 521:
|
||||
return MBEDTLS_ECP_DP_SECP521R1;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
|
||||
switch (bits) {
|
||||
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
|
||||
case 256:
|
||||
return MBEDTLS_ECP_DP_BP256R1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
|
||||
case 384:
|
||||
return MBEDTLS_ECP_DP_BP384R1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
|
||||
case 512:
|
||||
return MBEDTLS_ECP_DP_BP512R1;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case PSA_ECC_FAMILY_MONTGOMERY:
|
||||
switch (bits) {
|
||||
#if defined(PSA_WANT_ECC_MONTGOMERY_255)
|
||||
case 255:
|
||||
return MBEDTLS_ECP_DP_CURVE25519;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_MONTGOMERY_448)
|
||||
case 448:
|
||||
return MBEDTLS_ECP_DP_CURVE448;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case PSA_ECC_FAMILY_SECP_K1:
|
||||
switch (bits) {
|
||||
#if defined(PSA_WANT_ECC_SECP_K1_192)
|
||||
case 192:
|
||||
return MBEDTLS_ECP_DP_SECP192K1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_SECP_K1_224)
|
||||
/* secp224k1 is not and will not be supported in PSA (#3541). */
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_SECP_K1_256)
|
||||
case 256:
|
||||
return MBEDTLS_ECP_DP_SECP256K1;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return MBEDTLS_ECP_DP_NONE;
|
||||
}
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||
|
||||
#if !defined(SL_TRUSTZONE_NONSECURE)
|
||||
/* Wrapper function allowing the classic API to use the PSA RNG.
|
||||
*
|
||||
* `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
|
||||
* `psa_generate_random(...)`. The state parameter is ignored since the
|
||||
* PSA API doesn't support passing an explicit state.
|
||||
*/
|
||||
int mbedtls_psa_get_random(void *p_rng,
|
||||
unsigned char *output,
|
||||
size_t output_size)
|
||||
{
|
||||
/* This function takes a pointer to the RNG state because that's what
|
||||
* classic mbedtls functions using an RNG expect. The PSA RNG manages
|
||||
* its own state internally and doesn't let the caller access that state.
|
||||
* So we just ignore the state parameter, and in practice we'll pass
|
||||
* NULL. */
|
||||
(void) p_rng;
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
psa_status_t status = psa_generate_random(output, output_size);
|
||||
if (status == PSA_SUCCESS) {
|
||||
return 0;
|
||||
} else {
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
#else
|
||||
(void)output;
|
||||
(void)output_size;
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
}
|
||||
#endif /* SL_TRUSTZONE_NONSECURE */
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
|
||||
#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
|
||||
|
||||
/**
|
||||
* \brief Convert a single raw coordinate to DER ASN.1 format. The output der
|
||||
* buffer is filled backward (i.e. starting from its end).
|
||||
*
|
||||
* \param raw_buf Buffer containing the raw coordinate to be
|
||||
* converted.
|
||||
* \param raw_len Length of raw_buf in bytes. This must be > 0.
|
||||
* \param der_buf_start Pointer to the beginning of the buffer which
|
||||
* will be filled with the DER converted data.
|
||||
* \param der_buf_end End of the buffer used to store the DER output.
|
||||
*
|
||||
* \return On success, the amount of data (in bytes) written to
|
||||
* the DER buffer.
|
||||
* \return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if the provided der
|
||||
* buffer is too small to contain all the converted data.
|
||||
* \return MBEDTLS_ERR_ASN1_INVALID_DATA if the input raw
|
||||
* coordinate is null (i.e. all zeros).
|
||||
*
|
||||
* \warning Raw and der buffer must not be overlapping.
|
||||
*/
|
||||
static int convert_raw_to_der_single_int(const unsigned char *raw_buf, size_t raw_len,
|
||||
unsigned char *der_buf_start,
|
||||
unsigned char *der_buf_end)
|
||||
{
|
||||
unsigned char *p = der_buf_end;
|
||||
int len;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* ASN.1 DER encoding requires minimal length, so skip leading 0s.
|
||||
* Provided input MPIs should not be 0, but as a failsafe measure, still
|
||||
* detect that and return error in case. */
|
||||
while (*raw_buf == 0x00) {
|
||||
++raw_buf;
|
||||
--raw_len;
|
||||
if (raw_len == 0) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
len = (int) raw_len;
|
||||
|
||||
/* Copy the raw coordinate to the end of der_buf. */
|
||||
if ((p - der_buf_start) < len) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
p -= len;
|
||||
memcpy(p, raw_buf, len);
|
||||
|
||||
/* If MSb is 1, ASN.1 requires that we prepend a 0. */
|
||||
if (*p & 0x80) {
|
||||
if ((p - der_buf_start) < 1) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
--p;
|
||||
*p = 0x00;
|
||||
++len;
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der_buf_start, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der_buf_start, MBEDTLS_ASN1_INTEGER));
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
|
||||
unsigned char *der, size_t der_size, size_t *der_len)
|
||||
{
|
||||
unsigned char r[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
|
||||
unsigned char s[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
|
||||
const size_t coordinate_len = PSA_BITS_TO_BYTES(bits);
|
||||
size_t len = 0;
|
||||
unsigned char *p = der + der_size;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (raw_len != (2 * coordinate_len)) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
if (coordinate_len > sizeof(r)) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Since raw and der buffers might overlap, dump r and s before starting
|
||||
* the conversion. */
|
||||
memcpy(r, raw, coordinate_len);
|
||||
memcpy(s, raw + coordinate_len, coordinate_len);
|
||||
|
||||
/* der buffer will initially be written starting from its end so we pick s
|
||||
* first and then r. */
|
||||
ret = convert_raw_to_der_single_int(s, coordinate_len, der, p);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
p -= ret;
|
||||
len += ret;
|
||||
|
||||
ret = convert_raw_to_der_single_int(r, coordinate_len, der, p);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
p -= ret;
|
||||
len += ret;
|
||||
|
||||
/* Add ASN.1 header (len + tag). */
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
/* memmove the content of der buffer to its beginnig. */
|
||||
memmove(der, p, len);
|
||||
*der_len = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert a single integer from ASN.1 DER format to raw.
|
||||
*
|
||||
* \param der Buffer containing the DER integer value to be
|
||||
* converted.
|
||||
* \param der_len Length of the der buffer in bytes.
|
||||
* \param raw Output buffer that will be filled with the
|
||||
* converted data. This should be at least
|
||||
* coordinate_size bytes and it must be zeroed before
|
||||
* calling this function.
|
||||
* \param coordinate_size Size (in bytes) of a single coordinate in raw
|
||||
* format.
|
||||
*
|
||||
* \return On success, the amount of DER data parsed from the
|
||||
* provided der buffer.
|
||||
* \return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the integer tag
|
||||
* is missing in the der buffer.
|
||||
* \return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the integer
|
||||
* is null (i.e. all zeros) or if the output raw buffer
|
||||
* is too small to contain the converted raw value.
|
||||
*
|
||||
* \warning Der and raw buffers must not be overlapping.
|
||||
*/
|
||||
static int convert_der_to_raw_single_int(unsigned char *der, size_t der_len,
|
||||
unsigned char *raw, size_t coordinate_size)
|
||||
{
|
||||
unsigned char *p = der;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t unpadded_len, padding_len = 0;
|
||||
|
||||
/* Get the length of ASN.1 element (i.e. the integer we need to parse). */
|
||||
ret = mbedtls_asn1_get_tag(&p, p + der_len, &unpadded_len,
|
||||
MBEDTLS_ASN1_INTEGER);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* It's invalid to have:
|
||||
* - unpadded_len == 0.
|
||||
* - MSb set without a leading 0x00 (leading 0x00 is checked below). */
|
||||
if (((unpadded_len == 0) || (*p & 0x80) != 0)) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* Skip possible leading zero */
|
||||
if (*p == 0x00) {
|
||||
p++;
|
||||
unpadded_len--;
|
||||
/* It is not allowed to have more than 1 leading zero.
|
||||
* Ignore the case in which unpadded_len = 0 because that's a 0 encoded
|
||||
* in ASN.1 format (i.e. 020100). */
|
||||
if ((unpadded_len > 0) && (*p == 0x00)) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
if (unpadded_len > coordinate_size) {
|
||||
/* Parsed number is longer than the maximum expected value. */
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
padding_len = coordinate_size - unpadded_len;
|
||||
/* raw buffer was already zeroed by the calling function so zero-padding
|
||||
* operation is skipped here. */
|
||||
memcpy(raw + padding_len, p, unpadded_len);
|
||||
p += unpadded_len;
|
||||
|
||||
return (int) (p - der);
|
||||
}
|
||||
|
||||
int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
|
||||
unsigned char *raw, size_t raw_size, size_t *raw_len)
|
||||
{
|
||||
unsigned char raw_tmp[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
|
||||
unsigned char *p = (unsigned char *) der;
|
||||
size_t data_len;
|
||||
size_t coordinate_size = PSA_BITS_TO_BYTES(bits);
|
||||
int ret;
|
||||
|
||||
/* The output raw buffer should be at least twice the size of a raw
|
||||
* coordinate in order to store r and s. */
|
||||
if (raw_size < coordinate_size * 2) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
if (2 * coordinate_size > sizeof(raw_tmp)) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Check that the provided input DER buffer has the right header. */
|
||||
ret = mbedtls_asn1_get_tag(&p, der + der_len, &data_len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(raw_tmp, 0, 2 * coordinate_size);
|
||||
|
||||
/* Extract r */
|
||||
ret = convert_der_to_raw_single_int(p, data_len, raw_tmp, coordinate_size);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
p += ret;
|
||||
data_len -= ret;
|
||||
|
||||
/* Extract s */
|
||||
ret = convert_der_to_raw_single_int(p, data_len, raw_tmp + coordinate_size,
|
||||
coordinate_size);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
p += ret;
|
||||
data_len -= ret;
|
||||
|
||||
/* Check that we consumed all the input der data. */
|
||||
if ((size_t) (p - der) != der_len) {
|
||||
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
memcpy(raw, raw_tmp, 2 * coordinate_size);
|
||||
*raw_len = 2 * coordinate_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */
|
||||
100
Libs/util/third_party/mbedtls/library/psa_util_internal.h
vendored
Normal file
100
Libs/util/third_party/mbedtls/library/psa_util_internal.h
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* \file psa_util_internal.h
|
||||
*
|
||||
* \brief Internal utility functions for use of PSA Crypto.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_PSA_UTIL_INTERNAL_H
|
||||
#define MBEDTLS_PSA_UTIL_INTERNAL_H
|
||||
|
||||
/* Include the public header so that users only need one include. */
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
|
||||
/*************************************************************************
|
||||
* FFDH
|
||||
************************************************************************/
|
||||
|
||||
#define MBEDTLS_PSA_MAX_FFDH_PUBKEY_LENGTH \
|
||||
PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS)
|
||||
|
||||
/*************************************************************************
|
||||
* ECC
|
||||
************************************************************************/
|
||||
|
||||
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH \
|
||||
PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
|
||||
|
||||
#define MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH \
|
||||
PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
|
||||
|
||||
/*************************************************************************
|
||||
* Error translation
|
||||
************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
/* Error codes used by PSA crypto are in -255..-128, fitting in 16 bits. */
|
||||
int16_t psa_status;
|
||||
/* Error codes used by Mbed TLS are in one of the ranges
|
||||
* -127..-1 (low-level) or -32767..-4096 (high-level with a low-level
|
||||
* code optionally added), fitting in 16 bits. */
|
||||
int16_t mbedtls_error;
|
||||
} mbedtls_error_pair_t;
|
||||
|
||||
#if defined(MBEDTLS_MD_LIGHT)
|
||||
extern const mbedtls_error_pair_t psa_to_md_errors[4];
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
extern const mbedtls_error_pair_t psa_to_cipher_errors[4];
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_LMS_C)
|
||||
extern const mbedtls_error_pair_t psa_to_lms_errors[3];
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
extern const mbedtls_error_pair_t psa_to_ssl_errors[7];
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
|
||||
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
|
||||
extern const mbedtls_error_pair_t psa_to_pk_rsa_errors[8];
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
extern const mbedtls_error_pair_t psa_to_pk_ecdsa_errors[7];
|
||||
#endif
|
||||
|
||||
/* Generic fallback function for error translation,
|
||||
* when the received state was not module-specific. */
|
||||
int psa_generic_status_to_mbedtls(psa_status_t status);
|
||||
|
||||
/* This function iterates over provided local error translations,
|
||||
* and if no match was found - calls the fallback error translation function. */
|
||||
int psa_status_to_mbedtls(psa_status_t status,
|
||||
const mbedtls_error_pair_t *local_translations,
|
||||
size_t local_errors_num,
|
||||
int (*fallback_f)(psa_status_t));
|
||||
|
||||
/* The second out of three-stage error handling functions of the pk module,
|
||||
* acts as a fallback after RSA / ECDSA error translation, and if no match
|
||||
* is found, it itself calls psa_generic_status_to_mbedtls. */
|
||||
int psa_pk_status_to_mbedtls(psa_status_t status);
|
||||
|
||||
/* Utility macro to shorten the defines of error translator in modules. */
|
||||
#define PSA_TO_MBEDTLS_ERR_LIST(status, error_list, fallback_f) \
|
||||
psa_status_to_mbedtls(status, error_list, \
|
||||
sizeof(error_list)/sizeof(error_list[0]), \
|
||||
fallback_f)
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
#endif /* MBEDTLS_PSA_UTIL_INTERNAL_H */
|
||||
206
Libs/util/third_party/mbedtls/library/rsa_alt_helpers.h
vendored
Normal file
206
Libs/util/third_party/mbedtls/library/rsa_alt_helpers.h
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
* \file rsa_alt_helpers.h
|
||||
*
|
||||
* \brief Context-independent RSA helper functions
|
||||
*
|
||||
* This module declares some RSA-related helper functions useful when
|
||||
* implementing the RSA interface. These functions are provided in a separate
|
||||
* compilation unit in order to make it easy for designers of alternative RSA
|
||||
* implementations to use them in their own code, as it is conceived that the
|
||||
* functionality they provide will be necessary for most complete
|
||||
* implementations.
|
||||
*
|
||||
* End-users of Mbed TLS who are not providing their own alternative RSA
|
||||
* implementations should not use these functions directly, and should instead
|
||||
* use only the functions declared in rsa.h.
|
||||
*
|
||||
* The interface provided by this module will be maintained through LTS (Long
|
||||
* Term Support) branches of Mbed TLS, but may otherwise be subject to change,
|
||||
* and must be considered an internal interface of the library.
|
||||
*
|
||||
* There are two classes of helper functions:
|
||||
*
|
||||
* (1) Parameter-generating helpers. These are:
|
||||
* - mbedtls_rsa_deduce_primes
|
||||
* - mbedtls_rsa_deduce_private_exponent
|
||||
* - mbedtls_rsa_deduce_crt
|
||||
* Each of these functions takes a set of core RSA parameters and
|
||||
* generates some other, or CRT related parameters.
|
||||
*
|
||||
* (2) Parameter-checking helpers. These are:
|
||||
* - mbedtls_rsa_validate_params
|
||||
* - mbedtls_rsa_validate_crt
|
||||
* They take a set of core or CRT related RSA parameters and check their
|
||||
* validity.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_RSA_ALT_HELPERS_H
|
||||
#define MBEDTLS_RSA_ALT_HELPERS_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "mbedtls/bignum.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \brief Compute RSA prime moduli P, Q from public modulus N=PQ
|
||||
* and a pair of private and public key.
|
||||
*
|
||||
* \note This is a 'static' helper function not operating on
|
||||
* an RSA context. Alternative implementations need not
|
||||
* overwrite it.
|
||||
*
|
||||
* \param N RSA modulus N = PQ, with P, Q to be found
|
||||
* \param E RSA public exponent
|
||||
* \param D RSA private exponent
|
||||
* \param P Pointer to MPI holding first prime factor of N on success
|
||||
* \param Q Pointer to MPI holding second prime factor of N on success
|
||||
*
|
||||
* \return
|
||||
* - 0 if successful. In this case, P and Q constitute a
|
||||
* factorization of N.
|
||||
* - A non-zero error code otherwise.
|
||||
*
|
||||
* \note It is neither checked that P, Q are prime nor that
|
||||
* D, E are modular inverses wrt. P-1 and Q-1. For that,
|
||||
* use the helper function \c mbedtls_rsa_validate_params.
|
||||
*
|
||||
*/
|
||||
int mbedtls_rsa_deduce_primes(mbedtls_mpi const *N, mbedtls_mpi const *E,
|
||||
mbedtls_mpi const *D,
|
||||
mbedtls_mpi *P, mbedtls_mpi *Q);
|
||||
|
||||
/**
|
||||
* \brief Compute RSA private exponent from
|
||||
* prime moduli and public key.
|
||||
*
|
||||
* \note This is a 'static' helper function not operating on
|
||||
* an RSA context. Alternative implementations need not
|
||||
* overwrite it.
|
||||
*
|
||||
* \param P First prime factor of RSA modulus
|
||||
* \param Q Second prime factor of RSA modulus
|
||||
* \param E RSA public exponent
|
||||
* \param D Pointer to MPI holding the private exponent on success.
|
||||
*
|
||||
* \return
|
||||
* - 0 if successful. In this case, D is set to a simultaneous
|
||||
* modular inverse of E modulo both P-1 and Q-1.
|
||||
* - A non-zero error code otherwise.
|
||||
*
|
||||
* \note This function does not check whether P and Q are primes.
|
||||
*
|
||||
*/
|
||||
int mbedtls_rsa_deduce_private_exponent(mbedtls_mpi const *P,
|
||||
mbedtls_mpi const *Q,
|
||||
mbedtls_mpi const *E,
|
||||
mbedtls_mpi *D);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Generate RSA-CRT parameters
|
||||
*
|
||||
* \note This is a 'static' helper function not operating on
|
||||
* an RSA context. Alternative implementations need not
|
||||
* overwrite it.
|
||||
*
|
||||
* \param P First prime factor of N
|
||||
* \param Q Second prime factor of N
|
||||
* \param D RSA private exponent
|
||||
* \param DP Output variable for D modulo P-1
|
||||
* \param DQ Output variable for D modulo Q-1
|
||||
* \param QP Output variable for the modular inverse of Q modulo P.
|
||||
*
|
||||
* \return 0 on success, non-zero error code otherwise.
|
||||
*
|
||||
* \note This function does not check whether P, Q are
|
||||
* prime and whether D is a valid private exponent.
|
||||
*
|
||||
*/
|
||||
int mbedtls_rsa_deduce_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q,
|
||||
const mbedtls_mpi *D, mbedtls_mpi *DP,
|
||||
mbedtls_mpi *DQ, mbedtls_mpi *QP);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Check validity of core RSA parameters
|
||||
*
|
||||
* \note This is a 'static' helper function not operating on
|
||||
* an RSA context. Alternative implementations need not
|
||||
* overwrite it.
|
||||
*
|
||||
* \param N RSA modulus N = PQ
|
||||
* \param P First prime factor of N
|
||||
* \param Q Second prime factor of N
|
||||
* \param D RSA private exponent
|
||||
* \param E RSA public exponent
|
||||
* \param f_rng PRNG to be used for primality check, or NULL
|
||||
* \param p_rng PRNG context for f_rng, or NULL
|
||||
*
|
||||
* \return
|
||||
* - 0 if the following conditions are satisfied
|
||||
* if all relevant parameters are provided:
|
||||
* - P prime if f_rng != NULL (%)
|
||||
* - Q prime if f_rng != NULL (%)
|
||||
* - 1 < N = P * Q
|
||||
* - 1 < D, E < N
|
||||
* - D and E are modular inverses modulo P-1 and Q-1
|
||||
* (%) This is only done if MBEDTLS_GENPRIME is defined.
|
||||
* - A non-zero error code otherwise.
|
||||
*
|
||||
* \note The function can be used with a restricted set of arguments
|
||||
* to perform specific checks only. E.g., calling it with
|
||||
* (-,P,-,-,-) and a PRNG amounts to a primality check for P.
|
||||
*/
|
||||
int mbedtls_rsa_validate_params(const mbedtls_mpi *N, const mbedtls_mpi *P,
|
||||
const mbedtls_mpi *Q, const mbedtls_mpi *D,
|
||||
const mbedtls_mpi *E,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief Check validity of RSA CRT parameters
|
||||
*
|
||||
* \note This is a 'static' helper function not operating on
|
||||
* an RSA context. Alternative implementations need not
|
||||
* overwrite it.
|
||||
*
|
||||
* \param P First prime factor of RSA modulus
|
||||
* \param Q Second prime factor of RSA modulus
|
||||
* \param D RSA private exponent
|
||||
* \param DP MPI to check for D modulo P-1
|
||||
* \param DQ MPI to check for D modulo P-1
|
||||
* \param QP MPI to check for the modular inverse of Q modulo P.
|
||||
*
|
||||
* \return
|
||||
* - 0 if the following conditions are satisfied:
|
||||
* - D = DP mod P-1 if P, D, DP != NULL
|
||||
* - Q = DQ mod P-1 if P, D, DQ != NULL
|
||||
* - QP = Q^-1 mod P if P, Q, QP != NULL
|
||||
* - \c MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if check failed,
|
||||
* potentially including \c MBEDTLS_ERR_MPI_XXX if some
|
||||
* MPI calculations failed.
|
||||
* - \c MBEDTLS_ERR_RSA_BAD_INPUT_DATA if insufficient
|
||||
* data was provided to check DP, DQ or QP.
|
||||
*
|
||||
* \note The function can be used with a restricted set of arguments
|
||||
* to perform specific checks only. E.g., calling it with the
|
||||
* parameters (P, -, D, DP, -, -) will check DP = D mod P-1.
|
||||
*/
|
||||
int mbedtls_rsa_validate_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q,
|
||||
const mbedtls_mpi *D, const mbedtls_mpi *DP,
|
||||
const mbedtls_mpi *DQ, const mbedtls_mpi *QP);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* rsa_alt_helpers.h */
|
||||
121
Libs/util/third_party/mbedtls/library/rsa_internal.h
vendored
Normal file
121
Libs/util/third_party/mbedtls/library/rsa_internal.h
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* \file rsa_internal.h
|
||||
*
|
||||
* \brief Internal-only RSA public-key cryptosystem API.
|
||||
*
|
||||
* This file declares RSA-related functions that are to be used
|
||||
* only from within the Mbed TLS library itself.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_RSA_INTERNAL_H
|
||||
#define MBEDTLS_RSA_INTERNAL_H
|
||||
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "mbedtls/asn1.h"
|
||||
|
||||
/**
|
||||
* \brief Parse a PKCS#1 (ASN.1) encoded private RSA key.
|
||||
*
|
||||
* \param rsa The RSA context where parsed data will be stored.
|
||||
* \param key The buffer that contains the key.
|
||||
* \param keylen The length of the key buffer in bytes.
|
||||
*
|
||||
* \return 0 on success.
|
||||
* \return MBEDTLS_ERR_ASN1_xxx in case of ASN.1 parsing errors.
|
||||
* \return MBEDTLS_ERR_RSA_xxx in case of RSA internal failures while
|
||||
* parsing data.
|
||||
* \return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if validity checks on the
|
||||
* provided key fail.
|
||||
*/
|
||||
int mbedtls_rsa_parse_key(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen);
|
||||
|
||||
/**
|
||||
* \brief Parse a PKCS#1 (ASN.1) encoded public RSA key.
|
||||
*
|
||||
* \param rsa The RSA context where parsed data will be stored.
|
||||
* \param key The buffer that contains the key.
|
||||
* \param keylen The length of the key buffer in bytes.
|
||||
*
|
||||
* \return 0 on success.
|
||||
* \return MBEDTLS_ERR_ASN1_xxx in case of ASN.1 parsing errors.
|
||||
* \return MBEDTLS_ERR_RSA_xxx in case of RSA internal failures while
|
||||
* parsing data.
|
||||
* \return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if validity checks on the
|
||||
* provided key fail.
|
||||
*/
|
||||
int mbedtls_rsa_parse_pubkey(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen);
|
||||
|
||||
/**
|
||||
* \brief Write a PKCS#1 (ASN.1) encoded private RSA key.
|
||||
*
|
||||
* \param rsa The RSA context which contains the data to be written.
|
||||
* \param start Beginning of the buffer that will be filled with the
|
||||
* private key.
|
||||
* \param p End of the buffer that will be filled with the private key.
|
||||
* On successful return, the referenced pointer will be
|
||||
* updated in order to point to the beginning of written data.
|
||||
*
|
||||
* \return On success, the number of bytes written to the output buffer
|
||||
* (i.e. a value > 0).
|
||||
* \return MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the RSA context does not
|
||||
* contain a valid key pair.
|
||||
* \return MBEDTLS_ERR_ASN1_xxx in case of failure while writing to the
|
||||
* output buffer.
|
||||
*
|
||||
* \note The output buffer is filled backward, i.e. starting from its
|
||||
* end and moving toward its start.
|
||||
*/
|
||||
int mbedtls_rsa_write_key(const mbedtls_rsa_context *rsa, unsigned char *start,
|
||||
unsigned char **p);
|
||||
|
||||
/**
|
||||
* \brief Parse a PKCS#1 (ASN.1) encoded public RSA key.
|
||||
*
|
||||
* \param rsa The RSA context which contains the data to be written.
|
||||
* \param start Beginning of the buffer that will be filled with the
|
||||
* private key.
|
||||
* \param p End of the buffer that will be filled with the private key.
|
||||
* On successful return, the referenced pointer will be
|
||||
* updated in order to point to the beginning of written data.
|
||||
*
|
||||
* \return On success, the number of bytes written to the output buffer
|
||||
* (i.e. a value > 0).
|
||||
* \return MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the RSA context does not
|
||||
* contain a valid public key.
|
||||
* \return MBEDTLS_ERR_ASN1_xxx in case of failure while writing to the
|
||||
* output buffer.
|
||||
*
|
||||
* \note The output buffer is filled backward, i.e. starting from its
|
||||
* end and moving toward its start.
|
||||
*/
|
||||
int mbedtls_rsa_write_pubkey(const mbedtls_rsa_context *rsa, unsigned char *start,
|
||||
unsigned char **p);
|
||||
|
||||
#if defined(MBEDTLS_PKCS1_V21)
|
||||
/**
|
||||
* \brief This function is analogue to \c mbedtls_rsa_rsassa_pss_sign().
|
||||
* The only difference between them is that this function is more flexible
|
||||
* on the parameters of \p ctx that are set with \c mbedtls_rsa_set_padding().
|
||||
*
|
||||
* \note Compared to its counterpart, this function:
|
||||
* - does not check the padding setting of \p ctx.
|
||||
* - allows the hash_id of \p ctx to be MBEDTLS_MD_NONE,
|
||||
* in which case it uses \p md_alg as the hash_id.
|
||||
*
|
||||
* \note Refer to \c mbedtls_rsa_rsassa_pss_sign() for a description
|
||||
* of the functioning and parameters of this function.
|
||||
*/
|
||||
int mbedtls_rsa_rsassa_pss_sign_no_mode_check(mbedtls_rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
mbedtls_md_type_t md_alg,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig);
|
||||
#endif /* MBEDTLS_PKCS1_V21 */
|
||||
|
||||
#endif /* rsa_internal.h */
|
||||
980
Libs/util/third_party/mbedtls/library/sha256.c
vendored
Normal file
980
Libs/util/third_party/mbedtls/library/sha256.c
vendored
Normal file
@@ -0,0 +1,980 @@
|
||||
/*
|
||||
* FIPS-180-2 compliant SHA-256 implementation
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
/*
|
||||
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||
*/
|
||||
|
||||
#if defined(__clang__) && (__clang_major__ >= 4)
|
||||
|
||||
/* Ideally, we would simply use MBEDTLS_ARCH_IS_ARMV8_A in the following #if,
|
||||
* but that is defined by build_info.h, and we need this block to happen first. */
|
||||
#if defined(__ARM_ARCH) && (__ARM_ARCH_PROFILE == 'A')
|
||||
#if __ARM_ARCH >= 8
|
||||
#define MBEDTLS_SHA256_ARCH_IS_ARMV8_A
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA256_ARCH_IS_ARMV8_A) && !defined(__ARM_FEATURE_CRYPTO)
|
||||
/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
|
||||
*
|
||||
* The intrinsic declaration are guarded by predefined ACLE macros in clang:
|
||||
* these are normally only enabled by the -march option on the command line.
|
||||
* By defining the macros ourselves we gain access to those declarations without
|
||||
* requiring -march on the command line.
|
||||
*
|
||||
* `arm_neon.h` is included by common.h, so we put these defines
|
||||
* at the top of this file, before any includes.
|
||||
*/
|
||||
#define __ARM_FEATURE_CRYPTO 1
|
||||
/* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions
|
||||
*
|
||||
* `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it
|
||||
* for older compilers.
|
||||
*/
|
||||
#define __ARM_FEATURE_SHA2 1
|
||||
#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG
|
||||
#endif
|
||||
|
||||
#endif /* defined(__clang__) && (__clang_major__ >= 4) */
|
||||
|
||||
/* Ensure that SIG_SETMASK is defined when -std=c99 is used. */
|
||||
#if !defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
|
||||
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if defined(MBEDTLS_ARCH_IS_ARMV8_A)
|
||||
|
||||
# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
|
||||
defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
|
||||
# if !defined(MBEDTLS_HAVE_NEON_INTRINSICS)
|
||||
# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
|
||||
# warning "Target does not support NEON instructions"
|
||||
# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
|
||||
# else
|
||||
# error "Target does not support NEON instructions"
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
|
||||
defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
|
||||
# if defined(__ARMCOMPILER_VERSION)
|
||||
# if __ARMCOMPILER_VERSION <= 6090000
|
||||
# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
|
||||
# endif
|
||||
# pragma clang attribute push (__attribute__((target("sha2"))), apply_to=function)
|
||||
# define MBEDTLS_POP_TARGET_PRAGMA
|
||||
# elif defined(__clang__)
|
||||
# if __clang_major__ < 4
|
||||
# error "A more recent Clang is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
|
||||
# endif
|
||||
# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
|
||||
# define MBEDTLS_POP_TARGET_PRAGMA
|
||||
# elif defined(__GNUC__)
|
||||
/* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some
|
||||
* intrinsics are missing. Missing intrinsics could be worked around.
|
||||
*/
|
||||
# if __GNUC__ < 6
|
||||
# error "A more recent GCC is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
|
||||
# else
|
||||
# pragma GCC push_options
|
||||
# pragma GCC target ("arch=armv8-a+crypto")
|
||||
# define MBEDTLS_POP_TARGET_PRAGMA
|
||||
# endif
|
||||
# else
|
||||
# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
|
||||
# endif
|
||||
# endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
# endif
|
||||
# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
|
||||
# if defined(__unix__)
|
||||
# if defined(__linux__)
|
||||
/* Our preferred method of detection is getauxval() */
|
||||
# include <sys/auxv.h>
|
||||
/* These are not always defined via sys/auxv.h */
|
||||
# if !defined(HWCAP_SHA2)
|
||||
# define HWCAP_SHA2 (1 << 6)
|
||||
# endif
|
||||
# if !defined(HWCAP2_SHA2)
|
||||
# define HWCAP2_SHA2 (1 << 3)
|
||||
# endif
|
||||
# endif
|
||||
/* Use SIGILL on Unix, and fall back to it on Linux */
|
||||
# include <signal.h>
|
||||
# endif
|
||||
# endif
|
||||
#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
|
||||
# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
|
||||
# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
|
||||
/*
|
||||
* Capability detection code comes early, so we can disable
|
||||
* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT if no detection mechanism found
|
||||
*/
|
||||
#if defined(MBEDTLS_ARCH_IS_ARM64) && defined(HWCAP_SHA2)
|
||||
static int mbedtls_a64_crypto_sha256_determine_support(void)
|
||||
{
|
||||
return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0;
|
||||
}
|
||||
#elif defined(MBEDTLS_ARCH_IS_ARM32) && defined(HWCAP2_SHA2)
|
||||
static int mbedtls_a64_crypto_sha256_determine_support(void)
|
||||
{
|
||||
return (getauxval(AT_HWCAP2) & HWCAP2_SHA2) ? 1 : 0;
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
static int mbedtls_a64_crypto_sha256_determine_support(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#include <processthreadsapi.h>
|
||||
|
||||
static int mbedtls_a64_crypto_sha256_determine_support(void)
|
||||
{
|
||||
return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ?
|
||||
1 : 0;
|
||||
}
|
||||
#elif defined(__unix__) && defined(SIG_SETMASK)
|
||||
/* Detection with SIGILL, setjmp() and longjmp() */
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
static jmp_buf return_from_sigill;
|
||||
|
||||
/*
|
||||
* Armv8-A SHA256 support detection via SIGILL
|
||||
*/
|
||||
static void sigill_handler(int signal)
|
||||
{
|
||||
(void) signal;
|
||||
longjmp(return_from_sigill, 1);
|
||||
}
|
||||
|
||||
static int mbedtls_a64_crypto_sha256_determine_support(void)
|
||||
{
|
||||
struct sigaction old_action, new_action;
|
||||
|
||||
sigset_t old_mask;
|
||||
if (sigprocmask(0, NULL, &old_mask)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sigemptyset(&new_action.sa_mask);
|
||||
new_action.sa_flags = 0;
|
||||
new_action.sa_handler = sigill_handler;
|
||||
|
||||
sigaction(SIGILL, &new_action, &old_action);
|
||||
|
||||
static int ret = 0;
|
||||
|
||||
if (setjmp(return_from_sigill) == 0) { /* First return only */
|
||||
/* If this traps, we will return a second time from setjmp() with 1 */
|
||||
#if defined(MBEDTLS_ARCH_IS_ARM64)
|
||||
asm volatile ("sha256h q0, q0, v0.4s" : : : "v0");
|
||||
#else
|
||||
asm volatile ("sha256h.32 q0, q0, q0" : : : "q0");
|
||||
#endif
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
sigaction(SIGILL, &old_action, NULL);
|
||||
sigprocmask(SIG_SETMASK, &old_mask, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#warning "No mechanism to detect ARMV8_CRYPTO found, using C code only"
|
||||
#undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
|
||||
#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */
|
||||
|
||||
#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
|
||||
|
||||
#if !defined(MBEDTLS_SHA256_ALT)
|
||||
|
||||
#define SHA256_BLOCK_SIZE 64
|
||||
|
||||
void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(mbedtls_sha256_context));
|
||||
}
|
||||
|
||||
void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
|
||||
}
|
||||
|
||||
void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
|
||||
const mbedtls_sha256_context *src)
|
||||
{
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 context setup
|
||||
*/
|
||||
int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
|
||||
{
|
||||
#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
|
||||
if (is224 != 0 && is224 != 1) {
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
}
|
||||
#elif defined(MBEDTLS_SHA256_C)
|
||||
if (is224 != 0) {
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
}
|
||||
#else /* defined MBEDTLS_SHA224_C only */
|
||||
if (is224 == 0) {
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
}
|
||||
#endif
|
||||
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
if (is224 == 0) {
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
ctx->state[0] = 0x6A09E667;
|
||||
ctx->state[1] = 0xBB67AE85;
|
||||
ctx->state[2] = 0x3C6EF372;
|
||||
ctx->state[3] = 0xA54FF53A;
|
||||
ctx->state[4] = 0x510E527F;
|
||||
ctx->state[5] = 0x9B05688C;
|
||||
ctx->state[6] = 0x1F83D9AB;
|
||||
ctx->state[7] = 0x5BE0CD19;
|
||||
#endif
|
||||
} else {
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
ctx->state[0] = 0xC1059ED8;
|
||||
ctx->state[1] = 0x367CD507;
|
||||
ctx->state[2] = 0x3070DD17;
|
||||
ctx->state[3] = 0xF70E5939;
|
||||
ctx->state[4] = 0xFFC00B31;
|
||||
ctx->state[5] = 0x68581511;
|
||||
ctx->state[6] = 0x64F98FA7;
|
||||
ctx->state[7] = 0xBEFA4FA4;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
ctx->is224 = is224;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
|
||||
static const uint32_t K[] =
|
||||
{
|
||||
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
|
||||
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
|
||||
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
|
||||
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
|
||||
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
|
||||
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
|
||||
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
|
||||
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
|
||||
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
|
||||
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
|
||||
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
|
||||
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
|
||||
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
|
||||
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
|
||||
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
|
||||
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
|
||||
defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
|
||||
|
||||
#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
|
||||
# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many
|
||||
# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process
|
||||
#endif
|
||||
|
||||
static size_t mbedtls_internal_sha256_process_many_a64_crypto(
|
||||
mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len)
|
||||
{
|
||||
uint32x4_t abcd = vld1q_u32(&ctx->state[0]);
|
||||
uint32x4_t efgh = vld1q_u32(&ctx->state[4]);
|
||||
|
||||
size_t processed = 0;
|
||||
|
||||
for (;
|
||||
len >= SHA256_BLOCK_SIZE;
|
||||
processed += SHA256_BLOCK_SIZE,
|
||||
msg += SHA256_BLOCK_SIZE,
|
||||
len -= SHA256_BLOCK_SIZE) {
|
||||
uint32x4_t tmp, abcd_prev;
|
||||
|
||||
uint32x4_t abcd_orig = abcd;
|
||||
uint32x4_t efgh_orig = efgh;
|
||||
|
||||
uint32x4_t sched0 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 0));
|
||||
uint32x4_t sched1 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 1));
|
||||
uint32x4_t sched2 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 2));
|
||||
uint32x4_t sched3 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 3));
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */
|
||||
/* Untested on BE */
|
||||
sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0)));
|
||||
sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1)));
|
||||
sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2)));
|
||||
sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3)));
|
||||
#endif
|
||||
|
||||
/* Rounds 0 to 3 */
|
||||
tmp = vaddq_u32(sched0, vld1q_u32(&K[0]));
|
||||
abcd_prev = abcd;
|
||||
abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
|
||||
efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
|
||||
|
||||
/* Rounds 4 to 7 */
|
||||
tmp = vaddq_u32(sched1, vld1q_u32(&K[4]));
|
||||
abcd_prev = abcd;
|
||||
abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
|
||||
efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
|
||||
|
||||
/* Rounds 8 to 11 */
|
||||
tmp = vaddq_u32(sched2, vld1q_u32(&K[8]));
|
||||
abcd_prev = abcd;
|
||||
abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
|
||||
efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
|
||||
|
||||
/* Rounds 12 to 15 */
|
||||
tmp = vaddq_u32(sched3, vld1q_u32(&K[12]));
|
||||
abcd_prev = abcd;
|
||||
abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
|
||||
efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
|
||||
|
||||
for (int t = 16; t < 64; t += 16) {
|
||||
/* Rounds t to t + 3 */
|
||||
sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3);
|
||||
tmp = vaddq_u32(sched0, vld1q_u32(&K[t]));
|
||||
abcd_prev = abcd;
|
||||
abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
|
||||
efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
|
||||
|
||||
/* Rounds t + 4 to t + 7 */
|
||||
sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0);
|
||||
tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4]));
|
||||
abcd_prev = abcd;
|
||||
abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
|
||||
efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
|
||||
|
||||
/* Rounds t + 8 to t + 11 */
|
||||
sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1);
|
||||
tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8]));
|
||||
abcd_prev = abcd;
|
||||
abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
|
||||
efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
|
||||
|
||||
/* Rounds t + 12 to t + 15 */
|
||||
sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2);
|
||||
tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12]));
|
||||
abcd_prev = abcd;
|
||||
abcd = vsha256hq_u32(abcd_prev, efgh, tmp);
|
||||
efgh = vsha256h2q_u32(efgh, abcd_prev, tmp);
|
||||
}
|
||||
|
||||
abcd = vaddq_u32(abcd, abcd_orig);
|
||||
efgh = vaddq_u32(efgh, efgh_orig);
|
||||
}
|
||||
|
||||
vst1q_u32(&ctx->state[0], abcd);
|
||||
vst1q_u32(&ctx->state[4], efgh);
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
|
||||
/*
|
||||
* This function is for internal use only if we are building both C and Armv8-A
|
||||
* versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
|
||||
*/
|
||||
static
|
||||
#endif
|
||||
int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
|
||||
const unsigned char data[SHA256_BLOCK_SIZE])
|
||||
{
|
||||
return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data,
|
||||
SHA256_BLOCK_SIZE) ==
|
||||
SHA256_BLOCK_SIZE) ? 0 : -1;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
|
||||
|
||||
#if defined(MBEDTLS_POP_TARGET_PRAGMA)
|
||||
#if defined(__clang__)
|
||||
#pragma clang attribute pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC pop_options
|
||||
#endif
|
||||
#undef MBEDTLS_POP_TARGET_PRAGMA
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
|
||||
#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
|
||||
#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \
|
||||
!defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
|
||||
|
||||
#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
|
||||
#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
|
||||
|
||||
#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
|
||||
#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
|
||||
|
||||
#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
|
||||
#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
|
||||
|
||||
#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
|
||||
#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
|
||||
#define R(t) \
|
||||
( \
|
||||
local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
|
||||
S0(local.W[(t) - 15]) + local.W[(t) - 16] \
|
||||
)
|
||||
|
||||
#define P(a, b, c, d, e, f, g, h, x, K) \
|
||||
do \
|
||||
{ \
|
||||
local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
|
||||
local.temp2 = S2(a) + F0((a), (b), (c)); \
|
||||
(d) += local.temp1; (h) = local.temp1 + local.temp2; \
|
||||
} while (0)
|
||||
|
||||
#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
|
||||
/*
|
||||
* This function is for internal use only if we are building both C and Armv8
|
||||
* versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process()
|
||||
*/
|
||||
static
|
||||
#endif
|
||||
int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx,
|
||||
const unsigned char data[SHA256_BLOCK_SIZE])
|
||||
{
|
||||
struct {
|
||||
uint32_t temp1, temp2, W[64];
|
||||
uint32_t A[8];
|
||||
} local;
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
local.A[i] = ctx->state[i];
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SHA256_SMALLER)
|
||||
for (i = 0; i < 64; i++) {
|
||||
if (i < 16) {
|
||||
local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
|
||||
} else {
|
||||
R(i);
|
||||
}
|
||||
|
||||
P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
|
||||
local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
|
||||
|
||||
local.temp1 = local.A[7]; local.A[7] = local.A[6];
|
||||
local.A[6] = local.A[5]; local.A[5] = local.A[4];
|
||||
local.A[4] = local.A[3]; local.A[3] = local.A[2];
|
||||
local.A[2] = local.A[1]; local.A[1] = local.A[0];
|
||||
local.A[0] = local.temp1;
|
||||
}
|
||||
#else /* MBEDTLS_SHA256_SMALLER */
|
||||
for (i = 0; i < 16; i++) {
|
||||
local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i += 8) {
|
||||
P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
|
||||
local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
|
||||
P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
|
||||
local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
|
||||
P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
|
||||
local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
|
||||
P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
|
||||
local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
|
||||
P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
|
||||
local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
|
||||
P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
|
||||
local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
|
||||
P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
|
||||
local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
|
||||
P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
|
||||
local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
|
||||
}
|
||||
|
||||
for (i = 16; i < 64; i += 8) {
|
||||
P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
|
||||
local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
|
||||
P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
|
||||
local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
|
||||
P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
|
||||
local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
|
||||
P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
|
||||
local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
|
||||
P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
|
||||
local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
|
||||
P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
|
||||
local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
|
||||
P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
|
||||
local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
|
||||
P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
|
||||
local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
|
||||
}
|
||||
#endif /* MBEDTLS_SHA256_SMALLER */
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
ctx->state[i] += local.A[i];
|
||||
}
|
||||
|
||||
/* Zeroise buffers and variables to clear sensitive data from memory. */
|
||||
mbedtls_platform_zeroize(&local, sizeof(local));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
|
||||
|
||||
|
||||
#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
|
||||
|
||||
static size_t mbedtls_internal_sha256_process_many_c(
|
||||
mbedtls_sha256_context *ctx, const uint8_t *data, size_t len)
|
||||
{
|
||||
size_t processed = 0;
|
||||
|
||||
while (len >= SHA256_BLOCK_SIZE) {
|
||||
if (mbedtls_internal_sha256_process_c(ctx, data) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
data += SHA256_BLOCK_SIZE;
|
||||
len -= SHA256_BLOCK_SIZE;
|
||||
|
||||
processed += SHA256_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
#endif /* !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */
|
||||
|
||||
|
||||
#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
|
||||
|
||||
static int mbedtls_a64_crypto_sha256_has_support(void)
|
||||
{
|
||||
static int done = 0;
|
||||
static int supported = 0;
|
||||
|
||||
if (!done) {
|
||||
supported = mbedtls_a64_crypto_sha256_determine_support();
|
||||
done = 1;
|
||||
}
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx,
|
||||
const uint8_t *msg, size_t len)
|
||||
{
|
||||
if (mbedtls_a64_crypto_sha256_has_support()) {
|
||||
return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len);
|
||||
} else {
|
||||
return mbedtls_internal_sha256_process_many_c(ctx, msg, len);
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
|
||||
const unsigned char data[SHA256_BLOCK_SIZE])
|
||||
{
|
||||
if (mbedtls_a64_crypto_sha256_has_support()) {
|
||||
return mbedtls_internal_sha256_process_a64_crypto(ctx, data);
|
||||
} else {
|
||||
return mbedtls_internal_sha256_process_c(ctx, data);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */
|
||||
|
||||
|
||||
/*
|
||||
* SHA-256 process buffer
|
||||
*/
|
||||
int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if (ilen == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = SHA256_BLOCK_SIZE - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if (ctx->total[0] < (uint32_t) ilen) {
|
||||
ctx->total[1]++;
|
||||
}
|
||||
|
||||
if (left && ilen >= fill) {
|
||||
memcpy((void *) (ctx->buffer + left), input, fill);
|
||||
|
||||
if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while (ilen >= SHA256_BLOCK_SIZE) {
|
||||
size_t processed =
|
||||
mbedtls_internal_sha256_process_many(ctx, input, ilen);
|
||||
if (processed < SHA256_BLOCK_SIZE) {
|
||||
return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
input += processed;
|
||||
ilen -= processed;
|
||||
}
|
||||
|
||||
if (ilen > 0) {
|
||||
memcpy((void *) (ctx->buffer + left), input, ilen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 final digest
|
||||
*/
|
||||
int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
|
||||
unsigned char *output)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
uint32_t used;
|
||||
uint32_t high, low;
|
||||
int truncated = 0;
|
||||
|
||||
/*
|
||||
* Add padding: 0x80 then 0x00 until 8 bytes remain for the length
|
||||
*/
|
||||
used = ctx->total[0] & 0x3F;
|
||||
|
||||
ctx->buffer[used++] = 0x80;
|
||||
|
||||
if (used <= 56) {
|
||||
/* Enough room for padding + length in current block */
|
||||
memset(ctx->buffer + used, 0, 56 - used);
|
||||
} else {
|
||||
/* We'll need an extra block */
|
||||
memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used);
|
||||
|
||||
if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memset(ctx->buffer, 0, 56);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add message length
|
||||
*/
|
||||
high = (ctx->total[0] >> 29)
|
||||
| (ctx->total[1] << 3);
|
||||
low = (ctx->total[0] << 3);
|
||||
|
||||
MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
|
||||
MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
|
||||
|
||||
if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Output final state
|
||||
*/
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
|
||||
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
truncated = ctx->is224;
|
||||
#endif
|
||||
if (!truncated) {
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
mbedtls_sha256_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* !MBEDTLS_SHA256_ALT */
|
||||
|
||||
/*
|
||||
* output = SHA-256( input buffer )
|
||||
*/
|
||||
int mbedtls_sha256(const unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char *output,
|
||||
int is224)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_sha256_context ctx;
|
||||
|
||||
#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
|
||||
if (is224 != 0 && is224 != 1) {
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
}
|
||||
#elif defined(MBEDTLS_SHA256_C)
|
||||
if (is224 != 0) {
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
}
|
||||
#else /* defined MBEDTLS_SHA224_C only */
|
||||
if (is224 == 0) {
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
}
|
||||
#endif
|
||||
|
||||
mbedtls_sha256_init(&ctx);
|
||||
|
||||
if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_sha256_free(&ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/*
|
||||
* FIPS-180-2 test vectors
|
||||
*/
|
||||
static const unsigned char sha_test_buf[3][57] =
|
||||
{
|
||||
{ "abc" },
|
||||
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
|
||||
{ "" }
|
||||
};
|
||||
|
||||
static const size_t sha_test_buflen[3] =
|
||||
{
|
||||
3, 56, 1000
|
||||
};
|
||||
|
||||
typedef const unsigned char (sha_test_sum_t)[32];
|
||||
|
||||
/*
|
||||
* SHA-224 test vectors
|
||||
*/
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
static sha_test_sum_t sha224_test_sum[] =
|
||||
{
|
||||
{ 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
|
||||
0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
|
||||
0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
|
||||
0xE3, 0x6C, 0x9D, 0xA7 },
|
||||
{ 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
|
||||
0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
|
||||
0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
|
||||
0x52, 0x52, 0x25, 0x25 },
|
||||
{ 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
|
||||
0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
|
||||
0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
|
||||
0x4E, 0xE7, 0xAD, 0x67 }
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SHA-256 test vectors
|
||||
*/
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
static sha_test_sum_t sha256_test_sum[] =
|
||||
{
|
||||
{ 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
|
||||
0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
|
||||
0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
|
||||
0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
|
||||
{ 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
|
||||
0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
|
||||
0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
|
||||
0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
|
||||
{ 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
|
||||
0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
|
||||
0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
|
||||
0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
static int mbedtls_sha256_common_self_test(int verbose, int is224)
|
||||
{
|
||||
int i, buflen, ret = 0;
|
||||
unsigned char *buf;
|
||||
unsigned char sha256sum[32];
|
||||
mbedtls_sha256_context ctx;
|
||||
|
||||
#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C)
|
||||
sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum;
|
||||
#elif defined(MBEDTLS_SHA256_C)
|
||||
sha_test_sum_t *sha_test_sum = sha256_test_sum;
|
||||
#else
|
||||
sha_test_sum_t *sha_test_sum = sha224_test_sum;
|
||||
#endif
|
||||
|
||||
buf = mbedtls_calloc(1024, sizeof(unsigned char));
|
||||
if (NULL == buf) {
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("Buffer allocation failed\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
mbedtls_sha256_init(&ctx);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1);
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (i == 2) {
|
||||
memset(buf, 'a', buflen = 1000);
|
||||
|
||||
for (int j = 0; j < 1000; j++) {
|
||||
ret = mbedtls_sha256_update(&ctx, buf, buflen);
|
||||
if (ret != 0) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
ret = mbedtls_sha256_update(&ctx, sha_test_buf[i],
|
||||
sha_test_buflen[i]);
|
||||
if (ret != 0) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) {
|
||||
ret = 1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("passed\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("\n");
|
||||
}
|
||||
|
||||
goto exit;
|
||||
|
||||
fail:
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("failed\n");
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_sha256_free(&ctx);
|
||||
mbedtls_free(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
int mbedtls_sha256_self_test(int verbose)
|
||||
{
|
||||
return mbedtls_sha256_common_self_test(verbose, 0);
|
||||
}
|
||||
#endif /* MBEDTLS_SHA256_C */
|
||||
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
int mbedtls_sha224_self_test(int verbose)
|
||||
{
|
||||
return mbedtls_sha256_common_self_test(verbose, 1);
|
||||
}
|
||||
#endif /* MBEDTLS_SHA224_C */
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */
|
||||
154
Libs/util/third_party/mbedtls/library/ssl_ciphersuites_internal.h
vendored
Normal file
154
Libs/util/third_party/mbedtls/library/ssl_ciphersuites_internal.h
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* \file ssl_ciphersuites_internal.h
|
||||
*
|
||||
* \brief Internal part of the public "ssl_ciphersuites.h".
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H
|
||||
#define MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H
|
||||
|
||||
#include "mbedtls/pk.h"
|
||||
|
||||
#if defined(MBEDTLS_PK_C)
|
||||
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg(const mbedtls_ssl_ciphersuite_t *info);
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_algorithm_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(const mbedtls_ssl_ciphersuite_t *info);
|
||||
psa_key_usage_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(const mbedtls_ssl_ciphersuite_t *info);
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg(const mbedtls_ssl_ciphersuite_t *info);
|
||||
#endif /* MBEDTLS_PK_C */
|
||||
|
||||
int mbedtls_ssl_ciphersuite_uses_ec(const mbedtls_ssl_ciphersuite_t *info);
|
||||
int mbedtls_ssl_ciphersuite_uses_psk(const mbedtls_ssl_ciphersuite_t *info);
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED)
|
||||
static inline int mbedtls_ssl_ciphersuite_has_pfs(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
|
||||
static inline int mbedtls_ssl_ciphersuite_no_pfs(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
|
||||
static inline int mbedtls_ssl_ciphersuite_uses_ecdh(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */
|
||||
|
||||
static inline int mbedtls_ssl_ciphersuite_cert_req_allowed(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int mbedtls_ssl_ciphersuite_uses_srv_cert(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED)
|
||||
static inline int mbedtls_ssl_ciphersuite_uses_dhe(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
|
||||
static inline int mbedtls_ssl_ciphersuite_uses_ecdhe(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
|
||||
static inline int mbedtls_ssl_ciphersuite_uses_server_signature(
|
||||
const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
|
||||
|
||||
#endif /* MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H */
|
||||
22
Libs/util/third_party/mbedtls/library/ssl_client.h
vendored
Normal file
22
Libs/util/third_party/mbedtls/library/ssl_client.h
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* TLS 1.2 and 1.3 client-side functions
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_SSL_CLIENT_H
|
||||
#define MBEDTLS_SSL_CLIENT_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C)
|
||||
#include "ssl_misc.h"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_write_client_hello(mbedtls_ssl_context *ssl);
|
||||
|
||||
#endif /* MBEDTLS_SSL_CLIENT_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user