132b31808SJens Wiklander /** 232b31808SJens Wiklander * \file aesni.h 332b31808SJens Wiklander * 432b31808SJens Wiklander * \brief AES-NI for hardware AES acceleration on some Intel processors 532b31808SJens Wiklander * 632b31808SJens Wiklander * \warning These functions are only for internal use by other library 732b31808SJens Wiklander * functions; you must not call them directly. 832b31808SJens Wiklander */ 932b31808SJens Wiklander /* 1032b31808SJens Wiklander * Copyright The Mbed TLS Contributors 11*b0563631STom Van Eyck * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 1232b31808SJens Wiklander */ 1332b31808SJens Wiklander #ifndef MBEDTLS_AESNI_H 1432b31808SJens Wiklander #define MBEDTLS_AESNI_H 1532b31808SJens Wiklander 1632b31808SJens Wiklander #include "mbedtls/build_info.h" 1732b31808SJens Wiklander 1832b31808SJens Wiklander #include "mbedtls/aes.h" 1932b31808SJens Wiklander 2032b31808SJens Wiklander #define MBEDTLS_AESNI_AES 0x02000000u 2132b31808SJens Wiklander #define MBEDTLS_AESNI_CLMUL 0x00000002u 2232b31808SJens Wiklander 23*b0563631STom Van Eyck #if defined(MBEDTLS_AESNI_C) && \ 24*b0563631STom Van Eyck (defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_X86)) 2532b31808SJens Wiklander 2632b31808SJens Wiklander /* Can we do AESNI with intrinsics? 2732b31808SJens Wiklander * (Only implemented with certain compilers, only for certain targets.) 2832b31808SJens Wiklander */ 2932b31808SJens Wiklander #undef MBEDTLS_AESNI_HAVE_INTRINSICS 30*b0563631STom Van Eyck #if defined(_MSC_VER) && !defined(__clang__) 3132b31808SJens Wiklander /* Visual Studio supports AESNI intrinsics since VS 2008 SP1. We only support 3232b31808SJens Wiklander * VS 2013 and up for other reasons anyway, so no need to check the version. */ 3332b31808SJens Wiklander #define MBEDTLS_AESNI_HAVE_INTRINSICS 3432b31808SJens Wiklander #endif 3532b31808SJens Wiklander /* GCC-like compilers: currently, we only support intrinsics if the requisite 3632b31808SJens Wiklander * target flag is enabled when building the library (e.g. `gcc -mpclmul -msse2` 3732b31808SJens Wiklander * or `clang -maes -mpclmul`). */ 38*b0563631STom Van Eyck #if (defined(__GNUC__) || defined(__clang__)) && defined(__AES__) && defined(__PCLMUL__) 39*b0563631STom Van Eyck #define MBEDTLS_AESNI_HAVE_INTRINSICS 40*b0563631STom Van Eyck #endif 41*b0563631STom Van Eyck /* For 32-bit, we only support intrinsics */ 42*b0563631STom Van Eyck #if defined(MBEDTLS_ARCH_IS_X86) && (defined(__GNUC__) || defined(__clang__)) 4332b31808SJens Wiklander #define MBEDTLS_AESNI_HAVE_INTRINSICS 4432b31808SJens Wiklander #endif 4532b31808SJens Wiklander 46*b0563631STom Van Eyck /* Choose the implementation of AESNI, if one is available. 47*b0563631STom Van Eyck * 48*b0563631STom Van Eyck * Favor the intrinsics-based implementation if it's available, for better 49*b0563631STom Van Eyck * maintainability. 50*b0563631STom Van Eyck * Performance is about the same (see #7380). 51*b0563631STom Van Eyck * In the long run, we will likely remove the assembly implementation. */ 52*b0563631STom Van Eyck #if defined(MBEDTLS_AESNI_HAVE_INTRINSICS) 5332b31808SJens Wiklander #define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics 54*b0563631STom Van Eyck #elif defined(MBEDTLS_HAVE_ASM) && \ 55*b0563631STom Van Eyck (defined(__GNUC__) || defined(__clang__)) && defined(MBEDTLS_ARCH_IS_X64) 56*b0563631STom Van Eyck /* Can we do AESNI with inline assembly? 57*b0563631STom Van Eyck * (Only implemented with gas syntax, only for 64-bit.) 58*b0563631STom Van Eyck */ 59*b0563631STom Van Eyck #define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly 60*b0563631STom Van Eyck #else 61*b0563631STom Van Eyck #error "MBEDTLS_AESNI_C defined, but neither intrinsics nor assembly available" 6232b31808SJens Wiklander #endif 6332b31808SJens Wiklander 6432b31808SJens Wiklander #if defined(MBEDTLS_AESNI_HAVE_CODE) 6532b31808SJens Wiklander 6632b31808SJens Wiklander #ifdef __cplusplus 6732b31808SJens Wiklander extern "C" { 6832b31808SJens Wiklander #endif 6932b31808SJens Wiklander 7032b31808SJens Wiklander /** 7132b31808SJens Wiklander * \brief Internal function to detect the AES-NI feature in CPUs. 7232b31808SJens Wiklander * 7332b31808SJens Wiklander * \note This function is only for internal use by other library 7432b31808SJens Wiklander * functions; you must not call it directly. 7532b31808SJens Wiklander * 7632b31808SJens Wiklander * \param what The feature to detect 7732b31808SJens Wiklander * (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL) 7832b31808SJens Wiklander * 7932b31808SJens Wiklander * \return 1 if CPU has support for the feature, 0 otherwise 8032b31808SJens Wiklander */ 81*b0563631STom Van Eyck #if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) 8232b31808SJens Wiklander int mbedtls_aesni_has_support(unsigned int what); 83*b0563631STom Van Eyck #else 84*b0563631STom Van Eyck #define mbedtls_aesni_has_support(what) 1 85*b0563631STom Van Eyck #endif 8632b31808SJens Wiklander 8732b31808SJens Wiklander /** 8832b31808SJens Wiklander * \brief Internal AES-NI AES-ECB block encryption and decryption 8932b31808SJens Wiklander * 9032b31808SJens Wiklander * \note This function is only for internal use by other library 9132b31808SJens Wiklander * functions; you must not call it directly. 9232b31808SJens Wiklander * 9332b31808SJens Wiklander * \param ctx AES context 9432b31808SJens Wiklander * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT 9532b31808SJens Wiklander * \param input 16-byte input block 9632b31808SJens Wiklander * \param output 16-byte output block 9732b31808SJens Wiklander * 9832b31808SJens Wiklander * \return 0 on success (cannot fail) 9932b31808SJens Wiklander */ 10032b31808SJens Wiklander int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx, 10132b31808SJens Wiklander int mode, 10232b31808SJens Wiklander const unsigned char input[16], 10332b31808SJens Wiklander unsigned char output[16]); 10432b31808SJens Wiklander 10532b31808SJens Wiklander /** 10632b31808SJens Wiklander * \brief Internal GCM multiplication: c = a * b in GF(2^128) 10732b31808SJens Wiklander * 10832b31808SJens Wiklander * \note This function is only for internal use by other library 10932b31808SJens Wiklander * functions; you must not call it directly. 11032b31808SJens Wiklander * 11132b31808SJens Wiklander * \param c Result 11232b31808SJens Wiklander * \param a First operand 11332b31808SJens Wiklander * \param b Second operand 11432b31808SJens Wiklander * 11532b31808SJens Wiklander * \note Both operands and result are bit strings interpreted as 11632b31808SJens Wiklander * elements of GF(2^128) as per the GCM spec. 11732b31808SJens Wiklander */ 11832b31808SJens Wiklander void mbedtls_aesni_gcm_mult(unsigned char c[16], 11932b31808SJens Wiklander const unsigned char a[16], 12032b31808SJens Wiklander const unsigned char b[16]); 12132b31808SJens Wiklander 122*b0563631STom Van Eyck #if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) 12332b31808SJens Wiklander /** 12432b31808SJens Wiklander * \brief Internal round key inversion. This function computes 12532b31808SJens Wiklander * decryption round keys from the encryption round keys. 12632b31808SJens Wiklander * 12732b31808SJens Wiklander * \note This function is only for internal use by other library 12832b31808SJens Wiklander * functions; you must not call it directly. 12932b31808SJens Wiklander * 13032b31808SJens Wiklander * \param invkey Round keys for the equivalent inverse cipher 13132b31808SJens Wiklander * \param fwdkey Original round keys (for encryption) 13232b31808SJens Wiklander * \param nr Number of rounds (that is, number of round keys minus one) 13332b31808SJens Wiklander */ 13432b31808SJens Wiklander void mbedtls_aesni_inverse_key(unsigned char *invkey, 13532b31808SJens Wiklander const unsigned char *fwdkey, 13632b31808SJens Wiklander int nr); 137*b0563631STom Van Eyck #endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ 13832b31808SJens Wiklander 13932b31808SJens Wiklander /** 14032b31808SJens Wiklander * \brief Internal key expansion for encryption 14132b31808SJens Wiklander * 14232b31808SJens Wiklander * \note This function is only for internal use by other library 14332b31808SJens Wiklander * functions; you must not call it directly. 14432b31808SJens Wiklander * 14532b31808SJens Wiklander * \param rk Destination buffer where the round keys are written 14632b31808SJens Wiklander * \param key Encryption key 14732b31808SJens Wiklander * \param bits Key size in bits (must be 128, 192 or 256) 14832b31808SJens Wiklander * 14932b31808SJens Wiklander * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH 15032b31808SJens Wiklander */ 15132b31808SJens Wiklander int mbedtls_aesni_setkey_enc(unsigned char *rk, 15232b31808SJens Wiklander const unsigned char *key, 15332b31808SJens Wiklander size_t bits); 15432b31808SJens Wiklander 15532b31808SJens Wiklander #ifdef __cplusplus 15632b31808SJens Wiklander } 15732b31808SJens Wiklander #endif 15832b31808SJens Wiklander 15932b31808SJens Wiklander #endif /* MBEDTLS_AESNI_HAVE_CODE */ 160*b0563631STom Van Eyck #endif /* MBEDTLS_AESNI_C && (MBEDTLS_ARCH_IS_X64 || MBEDTLS_ARCH_IS_X86) */ 16132b31808SJens Wiklander 16232b31808SJens Wiklander #endif /* MBEDTLS_AESNI_H */ 163