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