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 67extern "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) 82int 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 */ 100int 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 */ 118void 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 */ 134void 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 */ 151int 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