#pragma once #include #include #include /* Can we do AESNI with inline assembly? * (Only implemented with gas syntax, only for 64-bit.) */ #if defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__)) && !defined(MBEDTLS_HAVE_X86_64) #define MBEDTLS_AESNI_C #define MBEDTLS_HAVE_X86_64 #endif #if !defined(MBEDTLS_HAVE_ARM64) #if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) #define MBEDTLS_AESCE_C #define MBEDTLS_HAVE_ARM64 #endif #endif #define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */ #define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */ /* Error codes in range 0x0020-0x0022 */ /** Invalid key length. */ #define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /** Invalid data input length. */ #define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /* Error codes in range 0x0021-0x0025 */ /** Invalid input data. */ #define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 #if !defined(__BYTE_ORDER__) static const uint16_t mbedtls_byte_order_detector = { 0x100 }; #define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01) #else #define MBEDTLS_IS_BIG_ENDIAN ((__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__)) #endif /* !defined(__BYTE_ORDER__) */ /* * 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) #define MBEDTLS_BSWAP32 __rev #endif #ifdef __cplusplus extern "C" { #endif /** * 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 */ /** * \brief The AES context-type definition. */ typedef struct mbedtls_aes_context { int nr; /*!< The number of rounds. */ size_t rk_offset; /*!< The offset in array elements to AES round keys in the buffer. */ uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can hold 32 extra Bytes, which can be used for one of the following purposes:
  • Alignment if VIA padlock is used.
  • Simplifying key expansion in the 256-bit case by generating an extra round key.
*/ } mbedtls_aes_context; /** * \brief This function initializes the specified AES context. * * It must be the first API called before using * the context. * * \param ctx The AES context to initialize. This must not be \c NULL. */ void mbedtls_aes_init(mbedtls_aes_context *ctx); /** * \brief This function releases and clears the specified AES context. * * \param ctx The AES context to clear. * If this is \c NULL, this function does nothing. * Otherwise, the context must have been at least initialized. */ void mbedtls_aes_free(mbedtls_aes_context *ctx); /** * \brief This function sets the encryption key. * * \param ctx The AES context to which the key should be bound. * It must be initialized. * \param key The encryption key. * This must be a readable buffer of size \p keybits bits. * \param keybits The size of data passed in bits. Valid options are: *
  • 128 bits
  • *
  • 192 bits
  • *
  • 256 bits
* * \return \c 0 on success. * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. */ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits); /** * \brief This function sets the decryption key. * * \param ctx The AES context to which the key should be bound. * It must be initialized. * \param key The decryption key. * This must be a readable buffer of size \p keybits bits. * \param keybits The size of data passed. Valid options are: *
  • 128 bits
  • *
  • 192 bits
  • *
  • 256 bits
* * \return \c 0 on success. * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. */ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits); /** * \brief This function performs an AES single-block encryption or * decryption operation. * * It performs the operation defined in the \p mode parameter * (encrypt or decrypt), on the input data buffer defined in * the \p input parameter. * * mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or * mbedtls_aes_setkey_dec() must be called before the first * call to this API with the same context. * * \param ctx The AES context to use for encryption or decryption. * It must be initialized and bound to a key. * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or * #MBEDTLS_AES_DECRYPT. * \param input The buffer holding the input data. * It must be readable and at least \c 16 Bytes long. * \param output The buffer where the output data will be written. * It must be writeable and at least \c 16 Bytes long. * \return \c 0 on success. */ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16]); #ifdef __cplusplus } #endif