Skip to content

Commit 1fdc884

Browse files
authored
Merge pull request #7384 from yuhaoth/pr/add-aes-accelerator-only-mode
AES: Add accelerator only mode
2 parents 505dffd + 0a6272d commit 1fdc884

File tree

12 files changed

+266
-38
lines changed

12 files changed

+266
-38
lines changed

.travis.yml

+24
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,30 @@ jobs:
129129
- tests/scripts/travis-log-failure.sh
130130
- tests/context-info.sh
131131

132+
- name: Arm64 accelerators tests on arm64 host
133+
os: linux
134+
dist: focal
135+
arch: arm64
136+
addons:
137+
apt:
138+
packages:
139+
- gcc
140+
script:
141+
# Do a manual build+test sequence rather than using all.sh.
142+
#
143+
# This is arm64 host only test for no runtime detection case. Internal
144+
# and Open CI do not include Arm64 host, and they check if components
145+
# are be tested. As result, it will always fail on `pre-test-check` in
146+
# them.
147+
- scripts/config.py unset MBEDTLS_AESNI_C
148+
- scripts/config.py unset MBEDTLS_PADLOCK_C
149+
- scripts/config.py set MBEDTLS_AESCE_C
150+
- scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
151+
- make generated_files
152+
- make
153+
- programs/test/selftest aes | grep "using AESCE"
154+
- tests/context-info.sh
155+
132156
after_failure:
133157
- tests/scripts/travis-log-failure.sh
134158

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Features
2+
* New configuration option MBEDTLS_AES_USE_HARDWARE_ONLY introduced. When
3+
using CPU-accelerated AES (e.g., Arm Crypto Extensions), this option
4+
disables the plain C implementation and the run-time detection for the
5+
CPU feature, which reduces code size and avoids the vulnerability of the
6+
plain C implementation.

include/mbedtls/check_config.h

-4
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,6 @@
412412
#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequisites"
413413
#endif
414414

415-
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
416-
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
417-
#endif
418-
419415
#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C)
420416
#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites"
421417
#endif

include/mbedtls/mbedtls_config.h

+14
Original file line numberDiff line numberDiff line change
@@ -4016,4 +4016,18 @@
40164016
*/
40174017
//#define MBEDTLS_ECP_WITH_MPI_UINT
40184018

4019+
/*
4020+
* Disable plain C implementation for AES.
4021+
*
4022+
* When the plain C implementation is enabled, and an implementation using a
4023+
* special CPU feature (such as MBEDTLS_AESCE_C) is also enabled, runtime
4024+
* detection will be used to select between them.
4025+
*
4026+
* If only one implementation is present, runtime detection will not be used.
4027+
* This configuration will crash at runtime if running on a CPU without the
4028+
* necessary features. It will not build unless at least one of MBEDTLS_AESCE_C
4029+
* and/or MBEDTLS_AESNI_C is enabled & present in the build.
4030+
*/
4031+
//#define MBEDTLS_AES_USE_HARDWARE_ONLY
4032+
40194033
/** \} name SECTION: Module configuration options */

library/aes.c

+64-22
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,36 @@
3333
#include "mbedtls/platform.h"
3434
#include "mbedtls/platform_util.h"
3535
#include "mbedtls/error.h"
36+
37+
#if defined(__aarch64__)
38+
#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
39+
#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
40+
#endif
41+
#endif
42+
43+
#if defined(__amd64__) || defined(__x86_64__) || \
44+
((defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC))
45+
#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
46+
#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
47+
#endif
48+
#endif
49+
50+
#if defined(__i386__) || defined(_M_IX86)
51+
#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C)
52+
#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
53+
#endif
54+
55+
#if defined(MBEDTLS_PADLOCK_C)
56+
#if !defined(MBEDTLS_HAVE_ASM)
57+
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
58+
#endif
59+
#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
60+
#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
61+
"MBEDTLS_PADLOCK_C is set"
62+
#endif
63+
#endif
64+
#endif
65+
3666
#if defined(MBEDTLS_PADLOCK_C)
3767
#include "padlock.h"
3868
#endif
@@ -47,7 +77,7 @@
4777

4878
#if !defined(MBEDTLS_AES_ALT)
4979

50-
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
80+
#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
5181
static int aes_padlock_ace = -1;
5282
#endif
5383

@@ -542,7 +572,7 @@ void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
542572
* Note that the offset is in units of elements of buf, i.e. 32-bit words,
543573
* i.e. an offset of 1 means 4 bytes and so on.
544574
*/
545-
#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
575+
#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
546576
(defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
547577
#define MAY_NEED_TO_ALIGN
548578
#endif
@@ -554,7 +584,7 @@ static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
554584
#if defined(MAY_NEED_TO_ALIGN)
555585
int align_16_bytes = 0;
556586

557-
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
587+
#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
558588
if (aes_padlock_ace == -1) {
559589
aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
560590
}
@@ -595,7 +625,6 @@ static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
595625
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
596626
unsigned int keybits)
597627
{
598-
unsigned int i;
599628
uint32_t *RK;
600629

601630
switch (keybits) {
@@ -629,14 +658,15 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
629658
}
630659
#endif
631660

632-
for (i = 0; i < (keybits >> 5); i++) {
661+
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
662+
for (unsigned int i = 0; i < (keybits >> 5); i++) {
633663
RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
634664
}
635665

636666
switch (ctx->nr) {
637667
case 10:
638668

639-
for (i = 0; i < 10; i++, RK += 4) {
669+
for (unsigned int i = 0; i < 10; i++, RK += 4) {
640670
RK[4] = RK[0] ^ RCON[i] ^
641671
((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
642672
((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
@@ -652,7 +682,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
652682
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
653683
case 12:
654684

655-
for (i = 0; i < 8; i++, RK += 6) {
685+
for (unsigned int i = 0; i < 8; i++, RK += 6) {
656686
RK[6] = RK[0] ^ RCON[i] ^
657687
((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
658688
((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
@@ -669,7 +699,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
669699

670700
case 14:
671701

672-
for (i = 0; i < 7; i++, RK += 8) {
702+
for (unsigned int i = 0; i < 7; i++, RK += 8) {
673703
RK[8] = RK[0] ^ RCON[i] ^
674704
((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
675705
((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
@@ -695,6 +725,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
695725
}
696726

697727
return 0;
728+
#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
698729
}
699730
#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
700731

@@ -705,10 +736,13 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
705736
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
706737
unsigned int keybits)
707738
{
708-
int i, j, ret;
739+
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
740+
uint32_t *SK;
741+
#endif
742+
int ret;
709743
mbedtls_aes_context cty;
710744
uint32_t *RK;
711-
uint32_t *SK;
745+
712746

713747
mbedtls_aes_init(&cty);
714748

@@ -740,15 +774,16 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
740774
}
741775
#endif
742776

777+
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
743778
SK = cty.buf + cty.rk_offset + cty.nr * 4;
744779

745780
*RK++ = *SK++;
746781
*RK++ = *SK++;
747782
*RK++ = *SK++;
748783
*RK++ = *SK++;
749-
750-
for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
751-
for (j = 0; j < 4; j++, SK++) {
784+
SK -= 8;
785+
for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
786+
for (int j = 0; j < 4; j++, SK++) {
752787
*RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
753788
AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
754789
AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
@@ -760,7 +795,7 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
760795
*RK++ = *SK++;
761796
*RK++ = *SK++;
762797
*RK++ = *SK++;
763-
798+
#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
764799
exit:
765800
mbedtls_aes_free(&cty);
766801

@@ -1062,17 +1097,20 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
10621097
}
10631098
#endif
10641099

1065-
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1100+
#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
10661101
if (aes_padlock_ace > 0) {
10671102
return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
10681103
}
10691104
#endif
10701105

1106+
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
10711107
if (mode == MBEDTLS_AES_ENCRYPT) {
10721108
return mbedtls_internal_aes_encrypt(ctx, input, output);
10731109
} else {
10741110
return mbedtls_internal_aes_decrypt(ctx, input, output);
10751111
}
1112+
#endif
1113+
10761114
}
10771115

10781116
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@@ -1103,7 +1141,7 @@ int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
11031141
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
11041142
}
11051143

1106-
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1144+
#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
11071145
if (aes_padlock_ace > 0) {
11081146
if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
11091147
return 0;
@@ -1855,11 +1893,6 @@ int mbedtls_aes_self_test(int verbose)
18551893
#if defined(MBEDTLS_AES_ALT)
18561894
mbedtls_printf(" AES note: alternative implementation.\n");
18571895
#else /* MBEDTLS_AES_ALT */
1858-
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1859-
if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1860-
mbedtls_printf(" AES note: using VIA Padlock.\n");
1861-
} else
1862-
#endif
18631896
#if defined(MBEDTLS_AESNI_HAVE_CODE)
18641897
#if MBEDTLS_AESNI_HAVE_CODE == 1
18651898
mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
@@ -1872,12 +1905,21 @@ int mbedtls_aes_self_test(int verbose)
18721905
mbedtls_printf(" AES note: using AESNI.\n");
18731906
} else
18741907
#endif
1908+
#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
1909+
if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1910+
mbedtls_printf(" AES note: using VIA Padlock.\n");
1911+
} else
1912+
#endif
18751913
#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
18761914
if (mbedtls_aesce_has_support()) {
18771915
mbedtls_printf(" AES note: using AESCE.\n");
18781916
} else
18791917
#endif
1880-
mbedtls_printf(" AES note: built-in implementation.\n");
1918+
{
1919+
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1920+
mbedtls_printf(" AES note: built-in implementation.\n");
1921+
#endif
1922+
}
18811923
#endif /* MBEDTLS_AES_ALT */
18821924
}
18831925

library/aesce.c

+2
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
#include <sys/auxv.h>
100100
#endif
101101

102+
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
102103
/*
103104
* AES instruction support detection routine
104105
*/
@@ -113,6 +114,7 @@ int mbedtls_aesce_has_support(void)
113114
return 1;
114115
#endif
115116
}
117+
#endif
116118

117119
/* Single round of AESCE encryption */
118120
#define AESCE_ENCRYPT_ROUND \

library/aesce.h

+5
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@ extern "C" {
4747
*
4848
* \return 1 if CPU has support for the feature, 0 otherwise
4949
*/
50+
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
5051
int mbedtls_aesce_has_support(void);
52+
#else
53+
#define mbedtls_aesce_has_support() 1
54+
#endif
55+
5156

5257
/**
5358
* \brief Internal AES-ECB block encryption and decryption

library/aesni.c

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <immintrin.h>
4242
#endif
4343

44+
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
4445
/*
4546
* AES-NI support detection routine
4647
*/
@@ -70,6 +71,7 @@ int mbedtls_aesni_has_support(unsigned int what)
7071

7172
return (c & what) != 0;
7273
}
74+
#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
7375

7476
#if MBEDTLS_AESNI_HAVE_CODE == 2
7577

library/aesni.h

+21-5
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,20 @@
3535
/* Can we do AESNI with inline assembly?
3636
* (Only implemented with gas syntax, only for 64-bit.)
3737
*/
38-
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
39-
(defined(__amd64__) || defined(__x86_64__)) && \
40-
!defined(MBEDTLS_HAVE_X86_64)
38+
#if !defined(MBEDTLS_HAVE_X86_64) && \
39+
(defined(__amd64__) || defined(__x86_64__) || \
40+
defined(_M_X64) || defined(_M_AMD64)) && \
41+
!defined(_M_ARM64EC)
4142
#define MBEDTLS_HAVE_X86_64
4243
#endif
4344

44-
#if defined(MBEDTLS_AESNI_C)
45+
#if !defined(MBEDTLS_HAVE_X86) && \
46+
(defined(__i386__) || defined(_M_IX86))
47+
#define MBEDTLS_HAVE_X86
48+
#endif
49+
50+
#if defined(MBEDTLS_AESNI_C) && \
51+
(defined(MBEDTLS_HAVE_X86_64) || defined(MBEDTLS_HAVE_X86))
4552

4653
/* Can we do AESNI with intrinsics?
4754
* (Only implemented with certain compilers, only for certain targets.)
@@ -67,8 +74,13 @@
6774
* In the long run, we will likely remove the assembly implementation. */
6875
#if defined(MBEDTLS_AESNI_HAVE_INTRINSICS)
6976
#define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics
70-
#elif defined(MBEDTLS_HAVE_X86_64)
77+
#elif defined(MBEDTLS_HAVE_ASM) && \
78+
defined(__GNUC__) && defined(MBEDTLS_HAVE_X86_64)
7179
#define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly
80+
#elif defined(__GNUC__)
81+
# error "Must use `-mpclmul -msse2 -maes` for MBEDTLS_AESNI_C"
82+
#else
83+
#error "MBEDTLS_AESNI_C defined, but neither intrinsics nor assembly available"
7284
#endif
7385

7486
#if defined(MBEDTLS_AESNI_HAVE_CODE)
@@ -88,7 +100,11 @@ extern "C" {
88100
*
89101
* \return 1 if CPU has support for the feature, 0 otherwise
90102
*/
103+
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
91104
int mbedtls_aesni_has_support(unsigned int what);
105+
#else
106+
#define mbedtls_aesni_has_support(what) 1
107+
#endif
92108

93109
/**
94110
* \brief Internal AES-NI AES-ECB block encryption and decryption

0 commit comments

Comments
 (0)