/**1* \file aesni.h2*3* \brief AES-NI for hardware AES acceleration on some Intel processors4*5* \warning These functions are only for internal use by other library6* functions; you must not call them directly.7*/8/*9* Copyright The Mbed TLS Contributors10* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later11*/12#ifndef MBEDTLS_AESNI_H13#define MBEDTLS_AESNI_H1415#include "mbedtls/build_info.h"1617#include "mbedtls/aes.h"1819#define MBEDTLS_AESNI_AES 0x02000000u20#define MBEDTLS_AESNI_CLMUL 0x00000002u2122#if defined(MBEDTLS_AESNI_C) && \23(defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_X86))2425/* Can we do AESNI with intrinsics?26* (Only implemented with certain compilers, only for certain targets.)27*/28#undef MBEDTLS_AESNI_HAVE_INTRINSICS29#if defined(_MSC_VER) && !defined(__clang__)30/* Visual Studio supports AESNI intrinsics since VS 2008 SP1. We only support31* VS 2013 and up for other reasons anyway, so no need to check the version. */32#define MBEDTLS_AESNI_HAVE_INTRINSICS33#endif34/* GCC-like compilers: currently, we only support intrinsics if the requisite35* target flag is enabled when building the library (e.g. `gcc -mpclmul -msse2`36* or `clang -maes -mpclmul`). */37#if (defined(__GNUC__) || defined(__clang__)) && defined(__AES__) && defined(__PCLMUL__)38#define MBEDTLS_AESNI_HAVE_INTRINSICS39#endif40/* For 32-bit, we only support intrinsics */41#if defined(MBEDTLS_ARCH_IS_X86) && (defined(__GNUC__) || defined(__clang__))42#define MBEDTLS_AESNI_HAVE_INTRINSICS43#endif4445/* Choose the implementation of AESNI, if one is available.46*47* Favor the intrinsics-based implementation if it's available, for better48* maintainability.49* Performance is about the same (see #7380).50* In the long run, we will likely remove the assembly implementation. */51#if defined(MBEDTLS_AESNI_HAVE_INTRINSICS)52#define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics53#elif defined(MBEDTLS_HAVE_ASM) && \54(defined(__GNUC__) || defined(__clang__)) && defined(MBEDTLS_ARCH_IS_X64)55/* Can we do AESNI with inline assembly?56* (Only implemented with gas syntax, only for 64-bit.)57*/58#define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly59#else60#error "MBEDTLS_AESNI_C defined, but neither intrinsics nor assembly available"61#endif6263#if defined(MBEDTLS_AESNI_HAVE_CODE)6465#ifdef __cplusplus66extern "C" {67#endif6869/**70* \brief Internal function to detect the AES-NI feature in CPUs.71*72* \note This function is only for internal use by other library73* functions; you must not call it directly.74*75* \param what The feature to detect76* (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL)77*78* \return 1 if CPU has support for the feature, 0 otherwise79*/80#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)81int mbedtls_aesni_has_support(unsigned int what);82#else83#define mbedtls_aesni_has_support(what) 184#endif8586/**87* \brief Internal AES-NI AES-ECB block encryption and decryption88*89* \note This function is only for internal use by other library90* functions; you must not call it directly.91*92* \param ctx AES context93* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT94* \param input 16-byte input block95* \param output 16-byte output block96*97* \return 0 on success (cannot fail)98*/99int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx,100int mode,101const unsigned char input[16],102unsigned char output[16]);103104/**105* \brief Internal GCM multiplication: c = a * b in GF(2^128)106*107* \note This function is only for internal use by other library108* functions; you must not call it directly.109*110* \param c Result111* \param a First operand112* \param b Second operand113*114* \note Both operands and result are bit strings interpreted as115* elements of GF(2^128) as per the GCM spec.116*/117void mbedtls_aesni_gcm_mult(unsigned char c[16],118const unsigned char a[16],119const unsigned char b[16]);120121#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)122/**123* \brief Internal round key inversion. This function computes124* decryption round keys from the encryption round keys.125*126* \note This function is only for internal use by other library127* functions; you must not call it directly.128*129* \param invkey Round keys for the equivalent inverse cipher130* \param fwdkey Original round keys (for encryption)131* \param nr Number of rounds (that is, number of round keys minus one)132*/133void mbedtls_aesni_inverse_key(unsigned char *invkey,134const unsigned char *fwdkey,135int nr);136#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */137138/**139* \brief Internal key expansion for encryption140*141* \note This function is only for internal use by other library142* functions; you must not call it directly.143*144* \param rk Destination buffer where the round keys are written145* \param key Encryption key146* \param bits Key size in bits (must be 128, 192 or 256)147*148* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH149*/150int mbedtls_aesni_setkey_enc(unsigned char *rk,151const unsigned char *key,152size_t bits);153154#ifdef __cplusplus155}156#endif157158#endif /* MBEDTLS_AESNI_HAVE_CODE */159#endif /* MBEDTLS_AESNI_C && (MBEDTLS_ARCH_IS_X64 || MBEDTLS_ARCH_IS_X86) */160161#endif /* MBEDTLS_AESNI_H */162163164