1 /** 2 * \file aesni.h 3 * 4 * \brief AES-NI for hardware AES acceleration on some Intel processors 5 * 6 * \warning These functions are only for internal use by other library 7 * functions; you must not call them directly. 8 */ 9 /* 10 * Copyright The Mbed TLS Contributors 11 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 12 */ 13 #ifndef MBEDTLS_AESNI_H 14 #define MBEDTLS_AESNI_H 15 16 #if !defined(MBEDTLS_CONFIG_FILE) 17 #include "mbedtls/config.h" 18 #else 19 #include MBEDTLS_CONFIG_FILE 20 #endif 21 22 #include "mbedtls/aes.h" 23 24 #define MBEDTLS_AESNI_AES 0x02000000u 25 #define MBEDTLS_AESNI_CLMUL 0x00000002u 26 27 #if !defined(MBEDTLS_HAVE_X86_64) && \ 28 (defined(__amd64__) || defined(__x86_64__) || \ 29 defined(_M_X64) || defined(_M_AMD64)) && \ 30 !defined(_M_ARM64EC) 31 #define MBEDTLS_HAVE_X86_64 32 #endif 33 34 #if !defined(MBEDTLS_HAVE_X86) && \ 35 (defined(__i386__) || defined(_M_IX86)) 36 #define MBEDTLS_HAVE_X86 37 #endif 38 39 #if defined(MBEDTLS_AESNI_C) && \ 40 (defined(MBEDTLS_HAVE_X86_64) || defined(MBEDTLS_HAVE_X86)) 41 42 /* Can we do AESNI with intrinsics? 43 * (Only implemented with certain compilers, only for certain targets.) 44 * 45 * NOTE: MBEDTLS_AESNI_HAVE_INTRINSICS and MBEDTLS_AESNI_HAVE_CODE are internal 46 * macros that may change in future releases. 47 */ 48 #undef MBEDTLS_AESNI_HAVE_INTRINSICS 49 #if defined(_MSC_VER) 50 /* Visual Studio supports AESNI intrinsics since VS 2008 SP1. We only support 51 * VS 2013 and up for other reasons anyway, so no need to check the version. */ 52 #define MBEDTLS_AESNI_HAVE_INTRINSICS 53 #endif 54 /* GCC-like compilers: currently, we only support intrinsics if the requisite 55 * target flag is enabled when building the library (e.g. `gcc -mpclmul -msse2` 56 * or `clang -maes -mpclmul`). */ 57 #if defined(__GNUC__) && defined(__AES__) && defined(__PCLMUL__) 58 #define MBEDTLS_AESNI_HAVE_INTRINSICS 59 #endif 60 61 /* Choose the implementation of AESNI, if one is available. */ 62 #undef MBEDTLS_AESNI_HAVE_CODE 63 /* To minimize disruption when releasing the intrinsics-based implementation, 64 * favor the assembly-based implementation if it's available. We intend to 65 * revise this in a later release of Mbed TLS 3.x. In the long run, we will 66 * likely remove the assembly implementation. */ 67 #if defined(MBEDTLS_HAVE_ASM) && \ 68 defined(__GNUC__) && defined(MBEDTLS_HAVE_X86_64) 69 /* Can we do AESNI with inline assembly? 70 * (Only implemented with gas syntax, only for 64-bit.) 71 */ 72 #define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly 73 #elif defined(MBEDTLS_AESNI_HAVE_INTRINSICS) 74 #define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics 75 #endif 76 77 #if defined(MBEDTLS_AESNI_HAVE_CODE) 78 79 #ifdef __cplusplus 80 extern "C" { 81 #endif 82 83 /** 84 * \brief Internal function to detect the AES-NI feature in CPUs. 85 * 86 * \note This function is only for internal use by other library 87 * functions; you must not call it directly. 88 * 89 * \param what The feature to detect 90 * (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL) 91 * 92 * \return 1 if CPU has support for the feature, 0 otherwise 93 */ 94 int mbedtls_aesni_has_support(unsigned int what); 95 96 /** 97 * \brief Internal AES-NI AES-ECB block encryption and decryption 98 * 99 * \note This function is only for internal use by other library 100 * functions; you must not call it directly. 101 * 102 * \param ctx AES context 103 * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT 104 * \param input 16-byte input block 105 * \param output 16-byte output block 106 * 107 * \return 0 on success (cannot fail) 108 */ 109 int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx, 110 int mode, 111 const unsigned char input[16], 112 unsigned char output[16]); 113 114 /** 115 * \brief Internal GCM multiplication: c = a * b in GF(2^128) 116 * 117 * \note This function is only for internal use by other library 118 * functions; you must not call it directly. 119 * 120 * \param c Result 121 * \param a First operand 122 * \param b Second operand 123 * 124 * \note Both operands and result are bit strings interpreted as 125 * elements of GF(2^128) as per the GCM spec. 126 */ 127 void mbedtls_aesni_gcm_mult(unsigned char c[16], 128 const unsigned char a[16], 129 const unsigned char b[16]); 130 131 /** 132 * \brief Internal round key inversion. This function computes 133 * decryption round keys from the encryption round keys. 134 * 135 * \note This function is only for internal use by other library 136 * functions; you must not call it directly. 137 * 138 * \param invkey Round keys for the equivalent inverse cipher 139 * \param fwdkey Original round keys (for encryption) 140 * \param nr Number of rounds (that is, number of round keys minus one) 141 */ 142 void mbedtls_aesni_inverse_key(unsigned char *invkey, 143 const unsigned char *fwdkey, 144 int nr); 145 146 /** 147 * \brief Internal key expansion for encryption 148 * 149 * \note This function is only for internal use by other library 150 * functions; you must not call it directly. 151 * 152 * \param rk Destination buffer where the round keys are written 153 * \param key Encryption key 154 * \param bits Key size in bits (must be 128, 192 or 256) 155 * 156 * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH 157 */ 158 int mbedtls_aesni_setkey_enc(unsigned char *rk, 159 const unsigned char *key, 160 size_t bits); 161 162 #ifdef __cplusplus 163 } 164 #endif 165 166 #endif /* MBEDTLS_AESNI_HAVE_CODE */ 167 #endif /* MBEDTLS_AESNI_C && (MBEDTLS_HAVE_X86_64 || MBEDTLS_HAVE_X86) */ 168 169 #endif /* MBEDTLS_AESNI_H */ 170