• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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