* | 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 |
*
* 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.
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). */
#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
#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
#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
*/
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 POWER8
+ * crypto opcodes are available on the currently running CPU. If either
+ * of these conditions is not met, then this function returns `NULL`.
+ *
+ * \return the `aes_pwr8` 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 POWER8
+ * crypto opcodes are available on the currently running CPU. If either
+ * of these conditions is not met, then this function returns `NULL`.
+ *
+ * \return the `aes_pwr8` 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 POWER8 crypto
+ * opcodes are available on the currently running CPU. If either of
+ * these conditions is not met, then this function returns `NULL`.
+ *
+ * \return the `aes_pwr8` 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.
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;
/**
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;
/**
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;
/*
void *data, size_t len, const void *aad, size_t aad_len,
void *tag, br_chacha20_run ichacha, int encrypt);
+/**
+ * \brief ChaCha20+Poly1305 AEAD implementation (ctmulq).
+ *
+ * This implementation uses 64-bit multiplications (result over 128 bits).
+ * It is available only on platforms that offer such a primitive (in
+ * practice, 64-bit architectures). Use `br_poly1305_ctmulq_get()` to
+ * dynamically obtain a pointer to that function, or 0 if not supported.
+ *
+ * \see br_poly1305_run
+ *
+ * \param key secret key (32 bytes).
+ * \param iv nonce (12 bytes).
+ * \param data data to encrypt or decrypt.
+ * \param len data length (in bytes).
+ * \param aad additional authenticated data.
+ * \param aad_len length of additional authenticated data (in bytes).
+ * \param tag output buffer for the authentication tag.
+ * \param ichacha implementation of ChaCha20.
+ * \param encrypt non-zero for encryption, zero for decryption.
+ */
+void br_poly1305_ctmulq_run(const void *key, const void *iv,
+ void *data, size_t len, const void *aad, size_t aad_len,
+ void *tag, br_chacha20_run ichacha, int encrypt);
+
+/**
+ * \brief Get the ChaCha20+Poly1305 "ctmulq" implementation, if available.
+ *
+ * This function returns a pointer to the `br_poly1305_ctmulq_run()`
+ * function if supported on the current platform; otherwise, it returns 0.
+ *
+ * \return the ctmulq ChaCha20+Poly1305 implementation, or 0.
+ */
+br_poly1305_run br_poly1305_ctmulq_get(void);
+
#endif