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