New AES and GHASH implementations using POWER8 crypto opcodes.
This commit is contained in:
parent
f0c0046601
commit
db8f1b6645
16 changed files with 3186 additions and 27 deletions
|
|
@ -192,6 +192,7 @@
|
|||
* | aes_ct | AES | 16 | 16, 24 and 32 |
|
||||
* | aes_ct64 | AES | 16 | 16, 24 and 32 |
|
||||
* | aes_x86ni | AES | 16 | 16, 24 and 32 |
|
||||
* | aes_pwr8 | AES | 16 | 16, 24 and 32 |
|
||||
* | des_ct | DES/3DES | 8 | 8, 16 and 24 |
|
||||
* | des_tab | DES/3DES | 8 | 8, 16 and 24 |
|
||||
*
|
||||
|
|
@ -225,9 +226,11 @@
|
|||
* operations (i.e. CTR, and CBC decryption, but not CBC encryption).
|
||||
*
|
||||
* `aes_x86ni` exists only on x86 architectures (32-bit and 64-bit). It
|
||||
* uses the AES-NI opcodes when available; if the opcodes are not present,
|
||||
* then it automatically fall backs on an appropriate constant-time
|
||||
* implementation (`aes_ct` for 32-bit, `aes_ct64` for 64-bit).
|
||||
* uses the AES-NI opcodes when available.
|
||||
*
|
||||
* `aes_pwr8` exists only on PowerPC / POWER architectures (32-bit and
|
||||
* 64-bit, both little-endian and big-endian). It uses the AES opcodes
|
||||
* present in POWER8 and later.
|
||||
*
|
||||
* `des_tab` is a classic, table-based implementation of DES/3DES. It
|
||||
* is not constant-time.
|
||||
|
|
@ -1001,9 +1004,7 @@ uint32_t br_aes_ct64_ctr_run(const br_aes_ct64_ctr_keys *ctx,
|
|||
const void *iv, uint32_t cc, void *data, size_t len);
|
||||
|
||||
/*
|
||||
* AES implementation using AES-NI opcode (x86 platform). When the
|
||||
* opcodes are not present, this falls back to "ct" or "ct64" (depending
|
||||
* on architecture).
|
||||
* AES implementation using AES-NI opcodes (x86 platform).
|
||||
*/
|
||||
|
||||
/** \brief AES block size (16 bytes). */
|
||||
|
|
@ -1021,12 +1022,6 @@ typedef struct {
|
|||
#ifndef BR_DOXYGEN_IGNORE
|
||||
union {
|
||||
unsigned char skni[16 * 15];
|
||||
struct {
|
||||
uint32_t skey[60];
|
||||
} fallback_ct;
|
||||
struct {
|
||||
uint64_t skey[30];
|
||||
} fallback_ct64;
|
||||
} skey;
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
|
|
@ -1044,12 +1039,6 @@ typedef struct {
|
|||
#ifndef BR_DOXYGEN_IGNORE
|
||||
union {
|
||||
unsigned char skni[16 * 15];
|
||||
struct {
|
||||
uint32_t skey[60];
|
||||
} fallback_ct;
|
||||
struct {
|
||||
uint64_t skey[30];
|
||||
} fallback_ct64;
|
||||
} skey;
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
|
|
@ -1068,12 +1057,6 @@ typedef struct {
|
|||
#ifndef BR_DOXYGEN_IGNORE
|
||||
union {
|
||||
unsigned char skni[16 * 15];
|
||||
struct {
|
||||
uint32_t skey[60];
|
||||
} fallback_ct;
|
||||
struct {
|
||||
uint64_t skey[30];
|
||||
} fallback_ct64;
|
||||
} skey;
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
|
|
@ -1213,6 +1196,199 @@ const br_block_cbcdec_class *br_aes_x86ni_cbcdec_get_vtable(void);
|
|||
*/
|
||||
const br_block_ctr_class *br_aes_x86ni_ctr_get_vtable(void);
|
||||
|
||||
/*
|
||||
* AES implementation using POWER8 opcodes.
|
||||
*/
|
||||
|
||||
/** \brief AES block size (16 bytes). */
|
||||
#define br_aes_pwr8_BLOCK_SIZE 16
|
||||
|
||||
/**
|
||||
* \brief Context for AES subkeys (`aes_pwr8` implementation, CBC encryption).
|
||||
*
|
||||
* First field is a pointer to the vtable; it is set by the initialisation
|
||||
* function. Other fields are not supposed to be accessed by user code.
|
||||
*/
|
||||
typedef struct {
|
||||
/** \brief Pointer to vtable for this context. */
|
||||
const br_block_cbcenc_class *vtable;
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
union {
|
||||
unsigned char skni[16 * 15];
|
||||
} skey;
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
} br_aes_pwr8_cbcenc_keys;
|
||||
|
||||
/**
|
||||
* \brief Context for AES subkeys (`aes_pwr8` implementation, CBC decryption).
|
||||
*
|
||||
* First field is a pointer to the vtable; it is set by the initialisation
|
||||
* function. Other fields are not supposed to be accessed by user code.
|
||||
*/
|
||||
typedef struct {
|
||||
/** \brief Pointer to vtable for this context. */
|
||||
const br_block_cbcdec_class *vtable;
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
union {
|
||||
unsigned char skni[16 * 15];
|
||||
} skey;
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
} br_aes_pwr8_cbcdec_keys;
|
||||
|
||||
/**
|
||||
* \brief Context for AES subkeys (`aes_pwr8` implementation, CTR encryption
|
||||
* and decryption).
|
||||
*
|
||||
* First field is a pointer to the vtable; it is set by the initialisation
|
||||
* function. Other fields are not supposed to be accessed by user code.
|
||||
*/
|
||||
typedef struct {
|
||||
/** \brief Pointer to vtable for this context. */
|
||||
const br_block_ctr_class *vtable;
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
union {
|
||||
unsigned char skni[16 * 15];
|
||||
} skey;
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
} br_aes_pwr8_ctr_keys;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CBC encryption (`aes_pwr8` implementation).
|
||||
*
|
||||
* Since this implementation might be omitted from the library, or the
|
||||
* AES opcode unavailable on the current CPU, a pointer to this class
|
||||
* instance should be obtained through `br_aes_pwr8_cbcenc_get_vtable()`.
|
||||
*/
|
||||
extern const br_block_cbcenc_class br_aes_pwr8_cbcenc_vtable;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CBC decryption (`aes_pwr8` implementation).
|
||||
*
|
||||
* Since this implementation might be omitted from the library, or the
|
||||
* AES opcode unavailable on the current CPU, a pointer to this class
|
||||
* instance should be obtained through `br_aes_pwr8_cbcdec_get_vtable()`.
|
||||
*/
|
||||
extern const br_block_cbcdec_class br_aes_pwr8_cbcdec_vtable;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CTR encryption and decryption
|
||||
* (`aes_pwr8` implementation).
|
||||
*
|
||||
* Since this implementation might be omitted from the library, or the
|
||||
* AES opcode unavailable on the current CPU, a pointer to this class
|
||||
* instance should be obtained through `br_aes_pwr8_ctr_get_vtable()`.
|
||||
*/
|
||||
extern const br_block_ctr_class br_aes_pwr8_ctr_vtable;
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CBC encryption
|
||||
* (`aes_pwr8` implementation).
|
||||
*
|
||||
* \param ctx context to initialise.
|
||||
* \param key secret key.
|
||||
* \param len secret key length (in bytes).
|
||||
*/
|
||||
void br_aes_pwr8_cbcenc_init(br_aes_pwr8_cbcenc_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CBC decryption
|
||||
* (`aes_pwr8` implementation).
|
||||
*
|
||||
* \param ctx context to initialise.
|
||||
* \param key secret key.
|
||||
* \param len secret key length (in bytes).
|
||||
*/
|
||||
void br_aes_pwr8_cbcdec_init(br_aes_pwr8_cbcdec_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CTR encryption
|
||||
* and decryption (`aes_pwr8` implementation).
|
||||
*
|
||||
* \param ctx context to initialise.
|
||||
* \param key secret key.
|
||||
* \param len secret key length (in bytes).
|
||||
*/
|
||||
void br_aes_pwr8_ctr_init(br_aes_pwr8_ctr_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC encryption with AES (`aes_pwr8` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param iv IV (updated).
|
||||
* \param data data to encrypt (updated).
|
||||
* \param len data length (in bytes, MUST be multiple of 16).
|
||||
*/
|
||||
void br_aes_pwr8_cbcenc_run(const br_aes_pwr8_cbcenc_keys *ctx, void *iv,
|
||||
void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC decryption with AES (`aes_pwr8` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param iv IV (updated).
|
||||
* \param data data to decrypt (updated).
|
||||
* \param len data length (in bytes, MUST be multiple of 16).
|
||||
*/
|
||||
void br_aes_pwr8_cbcdec_run(const br_aes_pwr8_cbcdec_keys *ctx, void *iv,
|
||||
void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR encryption and decryption with AES (`aes_pwr8` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param iv IV (constant, 12 bytes).
|
||||
* \param cc initial block counter value.
|
||||
* \param data data to decrypt (updated).
|
||||
* \param len data length (in bytes).
|
||||
* \return new block counter value.
|
||||
*/
|
||||
uint32_t br_aes_pwr8_ctr_run(const br_aes_pwr8_ctr_keys *ctx,
|
||||
const void *iv, uint32_t cc, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Obtain the `aes_pwr8` AES-CBC (encryption) implementation, if
|
||||
* available.
|
||||
*
|
||||
* This function returns a pointer to `br_aes_pwr8_cbcenc_vtable`, if
|
||||
* that implementation was compiled in the library _and_ the x86 AES
|
||||
* opcodes are available on the currently running CPU. If either of
|
||||
* these conditions is not met, then this function returns `NULL`.
|
||||
*
|
||||
* \return the `aes_x868ni` AES-CBC (encryption) implementation, or `NULL`.
|
||||
*/
|
||||
const br_block_cbcenc_class *br_aes_pwr8_cbcenc_get_vtable(void);
|
||||
|
||||
/**
|
||||
* \brief Obtain the `aes_pwr8` AES-CBC (decryption) implementation, if
|
||||
* available.
|
||||
*
|
||||
* This function returns a pointer to `br_aes_pwr8_cbcdec_vtable`, if
|
||||
* that implementation was compiled in the library _and_ the x86 AES
|
||||
* opcodes are available on the currently running CPU. If either of
|
||||
* these conditions is not met, then this function returns `NULL`.
|
||||
*
|
||||
* \return the `aes_x868ni` AES-CBC (decryption) implementation, or `NULL`.
|
||||
*/
|
||||
const br_block_cbcdec_class *br_aes_pwr8_cbcdec_get_vtable(void);
|
||||
|
||||
/**
|
||||
* \brief Obtain the `aes_pwr8` AES-CTR implementation, if available.
|
||||
*
|
||||
* This function returns a pointer to `br_aes_pwr8_ctr_vtable`, if
|
||||
* that implementation was compiled in the library _and_ the x86 AES
|
||||
* opcodes are available on the currently running CPU. If either of
|
||||
* these conditions is not met, then this function returns `NULL`.
|
||||
*
|
||||
* \return the `aes_x868ni` AES-CTR implementation, or `NULL`.
|
||||
*/
|
||||
const br_block_ctr_class *br_aes_pwr8_ctr_get_vtable(void);
|
||||
|
||||
/**
|
||||
* \brief Aggregate structure large enough to be used as context for
|
||||
* subkeys (CBC encryption) for all AES implementations.
|
||||
|
|
@ -1224,6 +1400,7 @@ typedef union {
|
|||
br_aes_ct_cbcenc_keys c_ct;
|
||||
br_aes_ct64_cbcenc_keys c_ct64;
|
||||
br_aes_x86ni_cbcenc_keys c_x86ni;
|
||||
br_aes_pwr8_cbcenc_keys c_pwr8;
|
||||
} br_aes_gen_cbcenc_keys;
|
||||
|
||||
/**
|
||||
|
|
@ -1237,6 +1414,7 @@ typedef union {
|
|||
br_aes_ct_cbcdec_keys c_ct;
|
||||
br_aes_ct64_cbcdec_keys c_ct64;
|
||||
br_aes_x86ni_cbcdec_keys c_x86ni;
|
||||
br_aes_pwr8_cbcdec_keys c_pwr8;
|
||||
} br_aes_gen_cbcdec_keys;
|
||||
|
||||
/**
|
||||
|
|
@ -1250,6 +1428,7 @@ typedef union {
|
|||
br_aes_ct_ctr_keys c_ct;
|
||||
br_aes_ct64_ctr_keys c_ct64;
|
||||
br_aes_x86ni_ctr_keys c_x86ni;
|
||||
br_aes_pwr8_ctr_keys c_pwr8;
|
||||
} br_aes_gen_ctr_keys;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1309,4 +1309,30 @@ void br_ghash_pclmul(void *y, const void *h, const void *data, size_t len);
|
|||
*/
|
||||
br_ghash br_ghash_pclmul_get(void);
|
||||
|
||||
/**
|
||||
* \brief GHASH implementation using the POWER8 opcodes.
|
||||
*
|
||||
* This implementation is available only on POWER8 platforms (and later).
|
||||
* To safely obtain a pointer to this function when supported (or 0
|
||||
* otherwise), use `br_ghash_pwr8_get()`.
|
||||
*
|
||||
* \param y the array to update.
|
||||
* \param h the GHASH key.
|
||||
* \param data the input data (may be `NULL` if `len` is zero).
|
||||
* \param len the input data length (in bytes).
|
||||
*/
|
||||
void br_ghash_pwr8(void *y, const void *h, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Obtain the `pwr8` GHASH implementation, if available.
|
||||
*
|
||||
* If the `pwr8` implementation was compiled in the library (depending
|
||||
* on the compiler abilities) _and_ the local CPU appears to support the
|
||||
* opcode, then this function will return a pointer to the
|
||||
* `br_ghash_pwr8()` function. Otherwise, it will return `0`.
|
||||
*
|
||||
* \return the `pwr8` GHASH implementation, or `0`.
|
||||
*/
|
||||
br_ghash br_ghash_pwr8_get(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue