[crypto] Allow for AES hardware acceleration

Allow architectures to detect support for AES hardware acceleration at
runtime and to replace the AES algorithm's encrypt() and decrypt()
method pointers with hardware accelerated implementations.

Extend the automated tests to run the AES tests twice: once with
hardware acceleration explicitly disabled (to test the unaccelerated
software implementation) and once with acceleration re-enabled.  Skip
the second test if no hardware acceleration is available: this avoids
unnecessarily repeating the test of the unaccelerated implementation,
and allows a non-zero test count for "aes-hw" to indicate that the
hardware acceleration was tested.  For example:

On a system that supports AES hardware acceleration:

   OK: "aes" 120 tests passed
   OK: "aes-hw" 120 tests passed

On a system that does not support AES hardware acceleration:

   OK: "aes" 120 tests passed
   OK: "aes-hw" 0 tests passed

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2026-09-06 19:46:31 +01:00
parent d916dfcfae
commit c4023b98e3
4 changed files with 113 additions and 3 deletions
+35
View File
@@ -149,6 +149,9 @@ static struct aes_table aes_mixcolumns;
/** AES InvMixColumns lookup table */
static struct aes_table aes_invmixcolumns;
/** AES hardware acceleration mode has been selected */
static int aes_selected;
/**
* Multiply [Inv]MixColumns matrix column by scalar multiplicand
*
@@ -721,6 +724,12 @@ static int aes_setkey ( struct cipher_algorithm *cipher __unused, void *ctx,
uint32_t *end;
uint32_t tmp;
/* Attempt (once) to enable AES hardware acceleration */
if ( ! aes_selected ) {
aes_accelerate();
aes_selected = 1;
}
/* Generate lookup tables, if not already done */
if ( ! aes_mixcolumns.entry[0].byte[0] )
aes_generate();
@@ -808,6 +817,32 @@ static int aes_setkey ( struct cipher_algorithm *cipher __unused, void *ctx,
return 0;
}
/**
* Disable hardware acceleration (for testing)
*
*/
void aes_decelerate ( void ) {
/* Restore original algorithm pointers */
aes_algorithm.encrypt = aes_encrypt;
aes_algorithm.decrypt = aes_decrypt;
DBGC ( &aes_algorithm, "AES disabled hardware acceleration\n" );
/* Mark hardware acceleration mode as selected */
aes_selected = 1;
}
/**
* Check if hardware acceleration is currently enabled (for testing)
*
* @ret is_accelerated AES is using hardware acceleration
*/
int aes_is_accelerated ( void ) {
/* Check if hardware acceleration is enabled */
return ( aes_algorithm.encrypt != aes_encrypt );
}
/** Basic AES algorithm */
struct cipher_algorithm aes_algorithm = {
.name = "aes",
+25
View File
@@ -0,0 +1,25 @@
#ifndef _BITS_AES_H
#define _BITS_AES_H
/** @file
*
* Generic architecture-specific AES acceleration
*
* This file is included only if the architecture does not provide its
* own version of this file.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
FILE_SECBOOT ( PERMITTED );
/**
* Enable hardware AES acceleration
*
*/
static inline __attribute__ (( always_inline )) void aes_accelerate ( void ) {
/* Do nothing */
}
#endif /* _BITS_AES_H */
+7
View File
@@ -50,6 +50,13 @@ extern struct cipher_algorithm aes_ecb_algorithm;
extern struct cipher_algorithm aes_cbc_algorithm;
extern struct cipher_algorithm aes_gcm_algorithm;
/* Allow for architecture-specific hardware acceleration */
#include <bits/aes.h>
void aes_accelerate ( void );
extern void aes_decelerate ( void );
extern int aes_is_accelerated ( void );
int aes_wrap ( const void *kek, const void *src, void *dest, int nblk );
int aes_unwrap ( const void *kek, const void *src, void *dest, int nblk );
+46 -3
View File
@@ -181,8 +181,51 @@ static void aes_test_exec ( void ) {
}
}
/**
* Perform AES self-test with hardware acceleration disabled
*
*/
static void aes_sw_test_exec ( void ) {
/* Disable hardware acceleration */
aes_decelerate();
/* Run tests */
DBG ( "AES hardware acceleration disabled\n" );
aes_test_exec();
/* Restore hardware acceleration (if supported) */
aes_accelerate();
}
/**
* Perform AES self-test with hardware acceleration enabled
*
*/
static void aes_hw_test_exec ( void ) {
/* Attempt to enable hardware acceleration */
aes_accelerate();
/* Do not repeat tests if no hardware acceleration exists */
if ( ! aes_is_accelerated() ) {
DBG ( "AES has no hardware acceleration support\n" );
return;
}
/* Run tests */
DBG ( "AES hardware acceleration enabled\n" );
aes_test_exec();
}
/** AES self-test */
struct self_test aes_test __self_test = {
.name = "aes",
.exec = aes_test_exec,
struct self_test aes_test[] __self_test = {
{
.name = "aes",
.exec = aes_sw_test_exec,
},
{
.name = "aes-hw",
.exec = aes_hw_test_exec,
},
};