Added generic EAX and CCM implementations.
This commit is contained in:
parent
8e94ad2fcb
commit
dddc412922
14 changed files with 4530 additions and 13 deletions
|
|
@ -127,7 +127,7 @@ extern "C" {
|
|||
*
|
||||
* - Nonce, plaintext and additional authenticated data all consist
|
||||
* in an integral number of bytes. There is no provision to use
|
||||
* elements whose lengh in bits is not a multiple of 8.
|
||||
* elements whose length in bits is not a multiple of 8.
|
||||
*
|
||||
* Each AEAD algorithm has its own requirements and limits on the sizes
|
||||
* of additional data and plaintext. This API does not provide any
|
||||
|
|
@ -169,6 +169,9 @@ extern "C" {
|
|||
* Note that there is no OOP method for context initialisation: the
|
||||
* various AEAD algorithms have different requirements that would not
|
||||
* map well to a single initialisation API.
|
||||
*
|
||||
* The OOP API is not provided for CCM, due to its specific requirements
|
||||
* (length of plaintext must be known in advance).
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -213,7 +216,7 @@ struct br_aead_class_ {
|
|||
*
|
||||
* \param cc AEAD context structure.
|
||||
* \param data pointer to additional authenticated data.
|
||||
* \param len length of additiona authenticated data (in bytes).
|
||||
* \param len length of additional authenticated data (in bytes).
|
||||
*/
|
||||
void (*aad_inject)(const br_aead_class **cc,
|
||||
const void *data, size_t len);
|
||||
|
|
@ -266,6 +269,8 @@ struct br_aead_class_ {
|
|||
* `check_tag()` function may be used to compute and check the
|
||||
* tag value.
|
||||
*
|
||||
* Tag length depends on the AEAD algorithm.
|
||||
*
|
||||
* \param cc AEAD context structure.
|
||||
* \param tag destination buffer for the tag.
|
||||
*/
|
||||
|
|
@ -282,11 +287,44 @@ struct br_aead_class_ {
|
|||
* data or the tag was altered in transit, normally leading to
|
||||
* wholesale rejection of the complete message.
|
||||
*
|
||||
* Tag length depends on the AEAD algorithm.
|
||||
*
|
||||
* \param cc AEAD context structure.
|
||||
* \param tag tag value to compare with (16 bytes).
|
||||
* \param tag tag value to compare with.
|
||||
* \return 1 on success (exact match of tag value), 0 otherwise.
|
||||
*/
|
||||
uint32_t (*check_tag)(const br_aead_class **cc, const void *tag);
|
||||
|
||||
/**
|
||||
* \brief Compute authentication tag (with truncation).
|
||||
*
|
||||
* This function is similar to `get_tag()`, except that the tag
|
||||
* length is provided. Some AEAD algorithms allow several tag
|
||||
* lengths, usually by truncating the normal tag. Shorter tags
|
||||
* mechanically increase success probability of forgeries.
|
||||
* The range of allowed tag lengths depends on the algorithm.
|
||||
*
|
||||
* \param cc AEAD context structure.
|
||||
* \param tag destination buffer for the tag.
|
||||
* \param len tag length (in bytes).
|
||||
*/
|
||||
void (*get_tag_trunc)(const br_aead_class **cc, void *tag, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Compute and check authentication tag (with truncation).
|
||||
*
|
||||
* This function is similar to `check_tag()` except that it
|
||||
* works over an explicit tag length. See `get_tag()` for a
|
||||
* discussion of explicit tag lengths; the range of allowed tag
|
||||
* lengths depends on the algorithm.
|
||||
*
|
||||
* \param cc AEAD context structure.
|
||||
* \param tag tag value to compare with.
|
||||
* \param len tag length (in bytes).
|
||||
* \return 1 on success (exact match of tag value), 0 otherwise.
|
||||
*/
|
||||
uint32_t (*check_tag_trunc)(const br_aead_class **cc,
|
||||
const void *tag, size_t len);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -379,7 +417,7 @@ void br_gcm_reset(br_gcm_context *ctx, const void *iv, size_t len);
|
|||
*
|
||||
* \param ctx GCM context structure.
|
||||
* \param data pointer to additional authenticated data.
|
||||
* \param len length of additiona authenticated data (in bytes).
|
||||
* \param len length of additional authenticated data (in bytes).
|
||||
*/
|
||||
void br_gcm_aad_inject(br_gcm_context *ctx, const void *data, size_t len);
|
||||
|
||||
|
|
@ -449,11 +487,478 @@ void br_gcm_get_tag(br_gcm_context *ctx, void *tag);
|
|||
*/
|
||||
uint32_t br_gcm_check_tag(br_gcm_context *ctx, const void *tag);
|
||||
|
||||
/**
|
||||
* \brief Compute GCM authentication tag (with truncation).
|
||||
*
|
||||
* This function is similar to `br_gcm_get_tag()`, except that it allows
|
||||
* the tag to be truncated to a smaller length. The intended tag length
|
||||
* is provided as `len` (in bytes); it MUST be no more than 16, but
|
||||
* it may be smaller. Note that decreasing tag length mechanically makes
|
||||
* forgeries easier; NIST SP 800-38D specifies that the tag length shall
|
||||
* lie between 12 and 16 bytes (inclusive), but may be truncated down to
|
||||
* 4 or 8 bytes, for specific applications that can tolerate it. It must
|
||||
* also be noted that successful forgeries leak information on the
|
||||
* authentication key, making subsequent forgeries easier. Therefore,
|
||||
* tag truncation, and in particular truncation to sizes lower than 12
|
||||
* bytes, shall be envisioned only with great care.
|
||||
*
|
||||
* The tag is written in the provided `tag` buffer. This call terminates
|
||||
* the GCM run: no data may be processed with that GCM context
|
||||
* afterwards, until `br_gcm_reset()` is called to initiate a new GCM
|
||||
* run.
|
||||
*
|
||||
* The tag value must normally be sent along with the encrypted data.
|
||||
* When decrypting, the tag value must be recomputed and compared with
|
||||
* the received tag: if the two tag values differ, then either the tag
|
||||
* or the encrypted data was altered in transit. As an alternative to
|
||||
* this function, the `br_gcm_check_tag_trunc()` function can be used to
|
||||
* compute and check the tag value.
|
||||
*
|
||||
* \param ctx GCM context structure.
|
||||
* \param tag destination buffer for the tag.
|
||||
* \param len tag length (16 bytes or less).
|
||||
*/
|
||||
void br_gcm_get_tag_trunc(br_gcm_context *ctx, void *tag, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Compute and check GCM authentication tag (with truncation).
|
||||
*
|
||||
* This function is an alternative to `br_gcm_get_tag_trunc()`, normally used
|
||||
* on the receiving end (i.e. when decrypting value). The tag value is
|
||||
* recomputed and compared with the provided tag value. If they match, 1
|
||||
* is returned; on mismatch, 0 is returned. A returned value of 0 means
|
||||
* that the data or the tag was altered in transit, normally leading to
|
||||
* wholesale rejection of the complete message.
|
||||
*
|
||||
* Tag length MUST be 16 bytes or less. The normal GCM tag length is 16
|
||||
* bytes. See `br_check_tag_trunc()` for some discussion on the potential
|
||||
* perils of truncating authentication tags.
|
||||
*
|
||||
* \param ctx GCM context structure.
|
||||
* \param tag tag value to compare with.
|
||||
* \param len tag length (in bytes).
|
||||
* \return 1 on success (exact match of tag value), 0 otherwise.
|
||||
*/
|
||||
uint32_t br_gcm_check_tag_trunc(br_gcm_context *ctx,
|
||||
const void *tag, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Class instance for GCM.
|
||||
*/
|
||||
extern const br_aead_class br_gcm_vtable;
|
||||
|
||||
/**
|
||||
* \brief Context structure for EAX.
|
||||
*
|
||||
* EAX is an AEAD mode that combines a block cipher in CTR mode with
|
||||
* CBC-MAC using the same block cipher and the same key, to provide
|
||||
* authenticated encryption:
|
||||
*
|
||||
* - Any block cipher with 16-byte blocks can be used with EAX
|
||||
* (technically, other block sizes are defined as well, but this
|
||||
* is not implemented by these functions; shorter blocks also
|
||||
* imply numerous security issues).
|
||||
*
|
||||
* - The nonce can have any length, as long as nonce values are
|
||||
* not reused (thus, if nonces are randomly selected, the nonce
|
||||
* size should be such that reuse probability is negligible).
|
||||
*
|
||||
* - Additional authenticated data length is unlimited.
|
||||
*
|
||||
* - Message length is unlimited.
|
||||
*
|
||||
* - The authentication tag has length 16 bytes.
|
||||
*
|
||||
* The EAX initialisation function receives as parameter an
|
||||
* _initialised_ block cipher implementation context, with the secret
|
||||
* key already set. A pointer to that context will be kept within the
|
||||
* EAX context structure. It is up to the caller to allocate and
|
||||
* initialise that block cipher context.
|
||||
*/
|
||||
typedef struct {
|
||||
/** \brief Pointer to vtable for this context. */
|
||||
const br_aead_class *vtable;
|
||||
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
const br_block_ctrcbc_class **bctx;
|
||||
unsigned char L2[16];
|
||||
unsigned char L4[16];
|
||||
unsigned char nonce[16];
|
||||
unsigned char head[16];
|
||||
unsigned char ctr[16];
|
||||
unsigned char cbcmac[16];
|
||||
unsigned char buf[16];
|
||||
size_t ptr;
|
||||
#endif
|
||||
} br_eax_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize an EAX context.
|
||||
*
|
||||
* A block cipher implementation, with its initialised context
|
||||
* structure, is provided. The block cipher MUST use 16-byte blocks in
|
||||
* CTR + CBC-MAC mode, and its secret key MUST have been already set in
|
||||
* the provided context. The parameters are linked in the EAX context.
|
||||
*
|
||||
* After this function has been called, the `br_eax_reset()` function must
|
||||
* be called, to provide the nonce for EAX computation.
|
||||
*
|
||||
* \param ctx EAX context structure.
|
||||
* \param bctx block cipher context (already initialised with secret key).
|
||||
*/
|
||||
void br_eax_init(br_eax_context *ctx, const br_block_ctrcbc_class **bctx);
|
||||
|
||||
/**
|
||||
* \brief Reset an EAX context.
|
||||
*
|
||||
* This function resets an already initialised EAX context for a new
|
||||
* computation run. Implementations and keys are conserved. This function
|
||||
* can be called at any time; it cancels any ongoing EAX computation that
|
||||
* uses the provided context structure.
|
||||
*
|
||||
* It is critical to EAX security that nonce values are not repeated for
|
||||
* the same encryption key. Nonces can have arbitrary length. If nonces
|
||||
* are randomly generated, then a nonce length of at least 128 bits (16
|
||||
* bytes) is recommended, to make nonce reuse probability sufficiently
|
||||
* low.
|
||||
*
|
||||
* \param ctx EAX context structure.
|
||||
* \param nonce EAX nonce to use.
|
||||
* \param len EAX nonce length (in bytes).
|
||||
*/
|
||||
void br_eax_reset(br_eax_context *ctx, const void *nonce, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Inject additional authenticated data into EAX.
|
||||
*
|
||||
* The provided data is injected into a running EAX computation. Additional
|
||||
* data must be injected _before_ the call to `br_eax_flip()`.
|
||||
* Additional data can be injected in several chunks of arbitrary length;
|
||||
* the total amount of additional authenticated data is unlimited.
|
||||
*
|
||||
* \param ctx EAX context structure.
|
||||
* \param data pointer to additional authenticated data.
|
||||
* \param len length of additional authenticated data (in bytes).
|
||||
*/
|
||||
void br_eax_aad_inject(br_eax_context *ctx, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Finish injection of additional authenticated data into EAX.
|
||||
*
|
||||
* This function MUST be called before beginning the actual encryption
|
||||
* or decryption (with `br_eax_run()`), even if no additional authenticated
|
||||
* data was injected. No additional authenticated data may be injected
|
||||
* after this function call.
|
||||
*
|
||||
* \param ctx EAX context structure.
|
||||
*/
|
||||
void br_eax_flip(br_eax_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Encrypt or decrypt some data with EAX.
|
||||
*
|
||||
* Data encryption or decryption can be done after `br_eax_flip()`
|
||||
* has been called on the context. If `encrypt` is non-zero, then the
|
||||
* provided data shall be plaintext, and it is encrypted in place.
|
||||
* Otherwise, the data shall be ciphertext, and it is decrypted in place.
|
||||
*
|
||||
* Data may be provided in several chunks of arbitrary length.
|
||||
*
|
||||
* \param ctx EAX context structure.
|
||||
* \param encrypt non-zero for encryption, zero for decryption.
|
||||
* \param data data to encrypt or decrypt.
|
||||
* \param len data length (in bytes).
|
||||
*/
|
||||
void br_eax_run(br_eax_context *ctx, int encrypt, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Compute EAX authentication tag.
|
||||
*
|
||||
* Compute the EAX authentication tag. The tag is a 16-byte value which
|
||||
* is written in the provided `tag` buffer. This call terminates the
|
||||
* EAX run: no data may be processed with that EAX context afterwards,
|
||||
* until `br_eax_reset()` is called to initiate a new EAX run.
|
||||
*
|
||||
* The tag value must normally be sent along with the encrypted data.
|
||||
* When decrypting, the tag value must be recomputed and compared with
|
||||
* the received tag: if the two tag values differ, then either the tag
|
||||
* or the encrypted data was altered in transit. As an alternative to
|
||||
* this function, the `br_eax_check_tag()` function can be used to
|
||||
* compute and check the tag value.
|
||||
*
|
||||
* \param ctx EAX context structure.
|
||||
* \param tag destination buffer for the tag (16 bytes).
|
||||
*/
|
||||
void br_eax_get_tag(br_eax_context *ctx, void *tag);
|
||||
|
||||
/**
|
||||
* \brief Compute and check EAX authentication tag.
|
||||
*
|
||||
* This function is an alternative to `br_eax_get_tag()`, normally used
|
||||
* on the receiving end (i.e. when decrypting value). The tag value is
|
||||
* recomputed and compared with the provided tag value. If they match, 1
|
||||
* is returned; on mismatch, 0 is returned. A returned value of 0 means
|
||||
* that the data or the tag was altered in transit, normally leading to
|
||||
* wholesale rejection of the complete message.
|
||||
*
|
||||
* \param ctx EAX context structure.
|
||||
* \param tag tag value to compare with (16 bytes).
|
||||
* \return 1 on success (exact match of tag value), 0 otherwise.
|
||||
*/
|
||||
uint32_t br_eax_check_tag(br_eax_context *ctx, const void *tag);
|
||||
|
||||
/**
|
||||
* \brief Compute EAX authentication tag (with truncation).
|
||||
*
|
||||
* This function is similar to `br_eax_get_tag()`, except that it allows
|
||||
* the tag to be truncated to a smaller length. The intended tag length
|
||||
* is provided as `len` (in bytes); it MUST be no more than 16, but
|
||||
* it may be smaller. Note that decreasing tag length mechanically makes
|
||||
* forgeries easier; NIST SP 800-38D specifies that the tag length shall
|
||||
* lie between 12 and 16 bytes (inclusive), but may be truncated down to
|
||||
* 4 or 8 bytes, for specific applications that can tolerate it. It must
|
||||
* also be noted that successful forgeries leak information on the
|
||||
* authentication key, making subsequent forgeries easier. Therefore,
|
||||
* tag truncation, and in particular truncation to sizes lower than 12
|
||||
* bytes, shall be envisioned only with great care.
|
||||
*
|
||||
* The tag is written in the provided `tag` buffer. This call terminates
|
||||
* the EAX run: no data may be processed with that EAX context
|
||||
* afterwards, until `br_eax_reset()` is called to initiate a new EAX
|
||||
* run.
|
||||
*
|
||||
* The tag value must normally be sent along with the encrypted data.
|
||||
* When decrypting, the tag value must be recomputed and compared with
|
||||
* the received tag: if the two tag values differ, then either the tag
|
||||
* or the encrypted data was altered in transit. As an alternative to
|
||||
* this function, the `br_eax_check_tag_trunc()` function can be used to
|
||||
* compute and check the tag value.
|
||||
*
|
||||
* \param ctx EAX context structure.
|
||||
* \param tag destination buffer for the tag.
|
||||
* \param len tag length (16 bytes or less).
|
||||
*/
|
||||
void br_eax_get_tag_trunc(br_eax_context *ctx, void *tag, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Compute and check EAX authentication tag (with truncation).
|
||||
*
|
||||
* This function is an alternative to `br_eax_get_tag_trunc()`, normally used
|
||||
* on the receiving end (i.e. when decrypting value). The tag value is
|
||||
* recomputed and compared with the provided tag value. If they match, 1
|
||||
* is returned; on mismatch, 0 is returned. A returned value of 0 means
|
||||
* that the data or the tag was altered in transit, normally leading to
|
||||
* wholesale rejection of the complete message.
|
||||
*
|
||||
* Tag length MUST be 16 bytes or less. The normal EAX tag length is 16
|
||||
* bytes. See `br_check_tag_trunc()` for some discussion on the potential
|
||||
* perils of truncating authentication tags.
|
||||
*
|
||||
* \param ctx EAX context structure.
|
||||
* \param tag tag value to compare with.
|
||||
* \param len tag length (in bytes).
|
||||
* \return 1 on success (exact match of tag value), 0 otherwise.
|
||||
*/
|
||||
uint32_t br_eax_check_tag_trunc(br_eax_context *ctx,
|
||||
const void *tag, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Class instance for EAX.
|
||||
*/
|
||||
extern const br_aead_class br_eax_vtable;
|
||||
|
||||
/**
|
||||
* \brief Context structure for CCM.
|
||||
*
|
||||
* CCM is an AEAD mode that combines a block cipher in CTR mode with
|
||||
* CBC-MAC using the same block cipher and the same key, to provide
|
||||
* authenticated encryption:
|
||||
*
|
||||
* - Any block cipher with 16-byte blocks can be used with CCM
|
||||
* (technically, other block sizes are defined as well, but this
|
||||
* is not implemented by these functions; shorter blocks also
|
||||
* imply numerous security issues).
|
||||
*
|
||||
* - The authentication tag length, and plaintext length, MUST be
|
||||
* known when starting processing data. Plaintext and ciphertext
|
||||
* can still be provided by chunks, but the total size must match
|
||||
* the value provided upon initialisation.
|
||||
*
|
||||
* - The nonce length is constrained betwen 7 and 13 bytes (inclusive).
|
||||
* Furthermore, the plaintext length, when encoded, must fit over
|
||||
* 15-nonceLen bytes; thus, if the nonce has length 13 bytes, then
|
||||
* the plaintext length cannot exceed 65535 bytes.
|
||||
*
|
||||
* - Additional authenticated data length is practically unlimited
|
||||
* (formal limit is at 2^64 bytes).
|
||||
*
|
||||
* - The authentication tag has length 4 to 16 bytes (even values only).
|
||||
*
|
||||
* The CCM initialisation function receives as parameter an
|
||||
* _initialised_ block cipher implementation context, with the secret
|
||||
* key already set. A pointer to that context will be kept within the
|
||||
* CCM context structure. It is up to the caller to allocate and
|
||||
* initialise that block cipher context.
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
const br_block_ctrcbc_class **bctx;
|
||||
unsigned char ctr[16];
|
||||
unsigned char cbcmac[16];
|
||||
unsigned char tagmask[16];
|
||||
unsigned char buf[16];
|
||||
size_t ptr;
|
||||
size_t tag_len;
|
||||
#endif
|
||||
} br_ccm_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize a CCM context.
|
||||
*
|
||||
* A block cipher implementation, with its initialised context
|
||||
* structure, is provided. The block cipher MUST use 16-byte blocks in
|
||||
* CTR + CBC-MAC mode, and its secret key MUST have been already set in
|
||||
* the provided context. The parameters are linked in the CCM context.
|
||||
*
|
||||
* After this function has been called, the `br_ccm_reset()` function must
|
||||
* be called, to provide the nonce for CCM computation.
|
||||
*
|
||||
* \param ctx CCM context structure.
|
||||
* \param bctx block cipher context (already initialised with secret key).
|
||||
*/
|
||||
void br_ccm_init(br_ccm_context *ctx, const br_block_ctrcbc_class **bctx);
|
||||
|
||||
/**
|
||||
* \brief Reset a CCM context.
|
||||
*
|
||||
* This function resets an already initialised CCM context for a new
|
||||
* computation run. Implementations and keys are conserved. This function
|
||||
* can be called at any time; it cancels any ongoing CCM computation that
|
||||
* uses the provided context structure.
|
||||
*
|
||||
* The `aad_len` parameter contains the total length, in bytes, of the
|
||||
* additional authenticated data. It may be zero. That length MUST be
|
||||
* exact.
|
||||
*
|
||||
* The `data_len` parameter contains the total length, in bytes, of the
|
||||
* data that will be injected (plaintext or ciphertext). That length MUST
|
||||
* be exact. Moreover, that length MUST be less than 2^(8*(15-nonce_len)).
|
||||
*
|
||||
* The nonce length (`nonce_len`), in bytes, must be in the 7..13 range
|
||||
* (inclusive).
|
||||
*
|
||||
* The tag length (`tag_len`), in bytes, must be in the 4..16 range, and
|
||||
* be an even integer. Short tags mechanically allow for higher forgery
|
||||
* probabilities; hence, tag sizes smaller than 12 bytes shall be used only
|
||||
* with care.
|
||||
*
|
||||
* It is critical to CCM security that nonce values are not repeated for
|
||||
* the same encryption key. Random generation of nonces is not generally
|
||||
* recommended, due to the relatively small maximum nonce value.
|
||||
*
|
||||
* Returned value is 1 on success, 0 on error. An error is reported if
|
||||
* the tag or nonce length is out of range, or if the
|
||||
* plaintext/ciphertext length cannot be encoded with the specified
|
||||
* nonce length.
|
||||
*
|
||||
* \param ctx CCM context structure.
|
||||
* \param nonce CCM nonce to use.
|
||||
* \param nonce_len CCM nonce length (in bytes, 7 to 13).
|
||||
* \param aad_len additional authenticated data length (in bytes).
|
||||
* \param data_len plaintext/ciphertext length (in bytes).
|
||||
* \param tag_len tag length (in bytes).
|
||||
* \return 1 on success, 0 on error.
|
||||
*/
|
||||
int br_ccm_reset(br_ccm_context *ctx, const void *nonce, size_t nonce_len,
|
||||
uint64_t aad_len, uint64_t data_len, size_t tag_len);
|
||||
|
||||
/**
|
||||
* \brief Inject additional authenticated data into CCM.
|
||||
*
|
||||
* The provided data is injected into a running CCM computation. Additional
|
||||
* data must be injected _before_ the call to `br_ccm_flip()`.
|
||||
* Additional data can be injected in several chunks of arbitrary length,
|
||||
* but the total amount MUST exactly match the value which was provided
|
||||
* to `br_ccm_reset()`.
|
||||
*
|
||||
* \param ctx CCM context structure.
|
||||
* \param data pointer to additional authenticated data.
|
||||
* \param len length of additional authenticated data (in bytes).
|
||||
*/
|
||||
void br_ccm_aad_inject(br_ccm_context *ctx, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Finish injection of additional authenticated data into CCM.
|
||||
*
|
||||
* This function MUST be called before beginning the actual encryption
|
||||
* or decryption (with `br_ccm_run()`), even if no additional authenticated
|
||||
* data was injected. No additional authenticated data may be injected
|
||||
* after this function call.
|
||||
*
|
||||
* \param ctx CCM context structure.
|
||||
*/
|
||||
void br_ccm_flip(br_ccm_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Encrypt or decrypt some data with CCM.
|
||||
*
|
||||
* Data encryption or decryption can be done after `br_ccm_flip()`
|
||||
* has been called on the context. If `encrypt` is non-zero, then the
|
||||
* provided data shall be plaintext, and it is encrypted in place.
|
||||
* Otherwise, the data shall be ciphertext, and it is decrypted in place.
|
||||
*
|
||||
* Data may be provided in several chunks of arbitrary length, provided
|
||||
* that the total length exactly matches the length provided to the
|
||||
* `br_ccm_reset()` call.
|
||||
*
|
||||
* \param ctx CCM context structure.
|
||||
* \param encrypt non-zero for encryption, zero for decryption.
|
||||
* \param data data to encrypt or decrypt.
|
||||
* \param len data length (in bytes).
|
||||
*/
|
||||
void br_ccm_run(br_ccm_context *ctx, int encrypt, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Compute CCM authentication tag.
|
||||
*
|
||||
* Compute the CCM authentication tag. This call terminates the CCM
|
||||
* run: all data must have been injected with `br_ccm_run()` (in zero,
|
||||
* one or more successive calls). After this function has been called,
|
||||
* no more data can br processed; a `br_ccm_reset()` call is required
|
||||
* to start a new message.
|
||||
*
|
||||
* The tag length was provided upon context initialisation (last call
|
||||
* to `br_ccm_reset()`); it is returned by this function.
|
||||
*
|
||||
* The tag value must normally be sent along with the encrypted data.
|
||||
* When decrypting, the tag value must be recomputed and compared with
|
||||
* the received tag: if the two tag values differ, then either the tag
|
||||
* or the encrypted data was altered in transit. As an alternative to
|
||||
* this function, the `br_ccm_check_tag()` function can be used to
|
||||
* compute and check the tag value.
|
||||
*
|
||||
* \param ctx CCM context structure.
|
||||
* \param tag destination buffer for the tag (up to 16 bytes).
|
||||
* \return the tag length (in bytes).
|
||||
*/
|
||||
size_t br_ccm_get_tag(br_ccm_context *ctx, void *tag);
|
||||
|
||||
/**
|
||||
* \brief Compute and check CCM authentication tag.
|
||||
*
|
||||
* This function is an alternative to `br_ccm_get_tag()`, normally used
|
||||
* on the receiving end (i.e. when decrypting value). The tag value is
|
||||
* recomputed and compared with the provided tag value. If they match, 1
|
||||
* is returned; on mismatch, 0 is returned. A returned value of 0 means
|
||||
* that the data or the tag was altered in transit, normally leading to
|
||||
* wholesale rejection of the complete message.
|
||||
*
|
||||
* \param ctx CCM context structure.
|
||||
* \param tag tag value to compare with (up to 16 bytes).
|
||||
* \return 1 on success (exact match of tag value), 0 otherwise.
|
||||
*/
|
||||
uint32_t br_ccm_check_tag(br_ccm_context *ctx, const void *tag);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -136,6 +136,73 @@ extern "C" {
|
|||
* chunked processing, provided that each chunk length (except possibly
|
||||
* the last one) is a multiple of the block size.
|
||||
*
|
||||
* - `br_xxx_ctrcbc_keys`
|
||||
*
|
||||
* Context structure that contains the subkeys resulting from the
|
||||
* key expansion. These subkeys are appropriate for doing combined
|
||||
* CTR encryption/decryption and CBC-MAC, as used in the CCM and EAX
|
||||
* authenticated encryption modes. The structure first field is
|
||||
* called `vtable` and points to the appropriate OOP structure.
|
||||
*
|
||||
* - `br_xxx_ctrcbc_init(br_xxx_ctr_keys *ctx, const void *key, size_t len)`
|
||||
*
|
||||
* Perform key expansion: subkeys for combined CTR
|
||||
* encryption/decryption and CBC-MAC are computed and written in the
|
||||
* provided context structure. The key length MUST be adequate for
|
||||
* the implemented block cipher. This function also sets the
|
||||
* `vtable` field.
|
||||
*
|
||||
* - `br_xxx_ctrcbc_encrypt(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len)`
|
||||
*
|
||||
* Perform CTR encryption of some data, and CBC-MAC. Processing is
|
||||
* done "in place" (the output data replaces the input data). This
|
||||
* function applies CTR encryption on the data, using a full
|
||||
* block-size counter (i.e. for 128-bit blocks, the counter is
|
||||
* incremented as a 128-bit value). The 'ctr' array contains the
|
||||
* initial value for the counter (used in the first block) and it is
|
||||
* updated with the new value after data processing. The 'cbcmac'
|
||||
* value shall point to a block-sized value which is used as IV for
|
||||
* CBC-MAC, computed over the encrypted data (output of CTR
|
||||
* encryption); the resulting CBC-MAC is written over 'cbcmac' on
|
||||
* output.
|
||||
*
|
||||
* The data length MUST be a multiple of the block size.
|
||||
*
|
||||
* - `br_xxx_ctrcbc_decrypt(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len)`
|
||||
*
|
||||
* Perform CTR decryption of some data, and CBC-MAC. Processing is
|
||||
* done "in place" (the output data replaces the input data). This
|
||||
* function applies CTR decryption on the data, using a full
|
||||
* block-size counter (i.e. for 128-bit blocks, the counter is
|
||||
* incremented as a 128-bit value). The 'ctr' array contains the
|
||||
* initial value for the counter (used in the first block) and it is
|
||||
* updated with the new value after data processing. The 'cbcmac'
|
||||
* value shall point to a block-sized value which is used as IV for
|
||||
* CBC-MAC, computed over the encrypted data (input of CTR
|
||||
* encryption); the resulting CBC-MAC is written over 'cbcmac' on
|
||||
* output.
|
||||
*
|
||||
* The data length MUST be a multiple of the block size.
|
||||
*
|
||||
* - `br_xxx_ctrcbc_ctr(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *data, size_t len)`
|
||||
*
|
||||
* Perform CTR encryption or decryption of the provided data. The
|
||||
* data is processed "in place" (the output data replaces the input
|
||||
* data). A full block-sized counter is applied (i.e. for 128-bit
|
||||
* blocks, the counter is incremented as a 128-bit value). The 'ctr'
|
||||
* array contains the initial value for the counter (used in the
|
||||
* first block), and it is updated with the new value after data
|
||||
* processing.
|
||||
*
|
||||
* The data length MUST be a multiple of the block size.
|
||||
*
|
||||
* - `br_xxx_ctrcbc_mac(const br_xxx_ctrcbc_keys *ctx, void *cbcmac, const void *data, size_t len)`
|
||||
*
|
||||
* Compute CBC-MAC over the provided data. The IV for CBC-MAC is
|
||||
* provided as 'cbcmac'; the output is written over the same array.
|
||||
* The data itself is untouched. The data length MUST be a multiple
|
||||
* of the block size.
|
||||
*
|
||||
*
|
||||
* It shall be noted that the key expansion functions return `void`. If
|
||||
* the provided key length is not allowed, then there will be no error
|
||||
|
|
@ -176,6 +243,41 @@ extern "C" {
|
|||
*
|
||||
* Pointer to the encryption/decryption function.
|
||||
*
|
||||
* For combined CTR/CBC-MAC encryption, the `vtable` has a slightly
|
||||
* different structure:
|
||||
*
|
||||
* - `context_size`
|
||||
*
|
||||
* The size (in bytes) of the context structure for subkeys.
|
||||
*
|
||||
* - `block_size`
|
||||
*
|
||||
* The cipher block size (in bytes).
|
||||
*
|
||||
* - `log_block_size`
|
||||
*
|
||||
* The base-2 logarithm of cipher block size (e.g. 4 for blocks
|
||||
* of 16 bytes).
|
||||
*
|
||||
* - `init`
|
||||
*
|
||||
* Pointer to the key expansion function.
|
||||
*
|
||||
* - `encrypt`
|
||||
*
|
||||
* Pointer to the CTR encryption + CBC-MAC function.
|
||||
*
|
||||
* - `decrypt`
|
||||
*
|
||||
* Pointer to the CTR decryption + CBC-MAC function.
|
||||
*
|
||||
* - `ctr`
|
||||
*
|
||||
* Pointer to the CTR encryption/decryption function.
|
||||
*
|
||||
* - `mac`
|
||||
*
|
||||
* Pointer to the CBC-MAC function.
|
||||
*
|
||||
* For block cipher "`xxx`", static, constant instances of these
|
||||
* structures are defined, under the names:
|
||||
|
|
@ -183,6 +285,7 @@ extern "C" {
|
|||
* - `br_xxx_cbcenc_vtable`
|
||||
* - `br_xxx_cbcdec_vtable`
|
||||
* - `br_xxx_ctr_vtable`
|
||||
* - `br_xxx_ctrcbc_vtable`
|
||||
*
|
||||
*
|
||||
* ## Implemented Block Ciphers
|
||||
|
|
@ -460,6 +563,132 @@ struct br_block_ctr_class_ {
|
|||
const void *iv, uint32_t cc, void *data, size_t len);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Class type for combined CTR and CBC-MAC implementations.
|
||||
*
|
||||
* A `br_block_ctrcbc_class` instance points to the functions implementing
|
||||
* a specific block cipher, when used in CTR mode for encrypting or
|
||||
* decrypting data, along with CBC-MAC.
|
||||
*/
|
||||
typedef struct br_block_ctrcbc_class_ br_block_ctrcbc_class;
|
||||
struct br_block_ctrcbc_class_ {
|
||||
/**
|
||||
* \brief Size (in bytes) of the context structure appropriate
|
||||
* for containing subkeys.
|
||||
*/
|
||||
size_t context_size;
|
||||
|
||||
/**
|
||||
* \brief Size of individual blocks (in bytes).
|
||||
*/
|
||||
unsigned block_size;
|
||||
|
||||
/**
|
||||
* \brief Base-2 logarithm of the size of individual blocks,
|
||||
* expressed in bytes.
|
||||
*/
|
||||
unsigned log_block_size;
|
||||
|
||||
/**
|
||||
* \brief Initialisation function.
|
||||
*
|
||||
* This function sets the `vtable` field in the context structure.
|
||||
* The key length MUST be one of the key lengths supported by
|
||||
* the implementation.
|
||||
*
|
||||
* \param ctx context structure to initialise.
|
||||
* \param key secret key.
|
||||
* \param key_len key length (in bytes).
|
||||
*/
|
||||
void (*init)(const br_block_ctrcbc_class **ctx,
|
||||
const void *key, size_t key_len);
|
||||
|
||||
/**
|
||||
* \brief Run the CTR encryption + CBC-MAC.
|
||||
*
|
||||
* The `ctr` parameter points to the counter; its length shall
|
||||
* be equal to the block size. It is updated by this function
|
||||
* as encryption proceeds.
|
||||
*
|
||||
* The `cbcmac` parameter points to the IV for CBC-MAC. The MAC
|
||||
* is computed over the encrypted data (output of CTR
|
||||
* encryption). Its length shall be equal to the block size. The
|
||||
* computed CBC-MAC value is written over the `cbcmac` array.
|
||||
*
|
||||
* The data to encrypt is updated "in place". Its length (`len`
|
||||
* bytes) MUST be a multiple of the block size.
|
||||
*
|
||||
* \param ctx context structure (already initialised).
|
||||
* \param ctr counter for CTR encryption (initial and final).
|
||||
* \param cbcmac IV and output buffer for CBC-MAC.
|
||||
* \param data data to encrypt.
|
||||
* \param len data length (in bytes).
|
||||
*/
|
||||
void (*encrypt)(const br_block_ctrcbc_class *const *ctx,
|
||||
void *ctr, void *cbcmac, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Run the CTR decryption + CBC-MAC.
|
||||
*
|
||||
* The `ctr` parameter points to the counter; its length shall
|
||||
* be equal to the block size. It is updated by this function
|
||||
* as decryption proceeds.
|
||||
*
|
||||
* The `cbcmac` parameter points to the IV for CBC-MAC. The MAC
|
||||
* is computed over the encrypted data (i.e. before CTR
|
||||
* decryption). Its length shall be equal to the block size. The
|
||||
* computed CBC-MAC value is written over the `cbcmac` array.
|
||||
*
|
||||
* The data to decrypt is updated "in place". Its length (`len`
|
||||
* bytes) MUST be a multiple of the block size.
|
||||
*
|
||||
* \param ctx context structure (already initialised).
|
||||
* \param ctr counter for CTR encryption (initial and final).
|
||||
* \param cbcmac IV and output buffer for CBC-MAC.
|
||||
* \param data data to decrypt.
|
||||
* \param len data length (in bytes).
|
||||
*/
|
||||
void (*decrypt)(const br_block_ctrcbc_class *const *ctx,
|
||||
void *ctr, void *cbcmac, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Run the CTR encryption/decryption only.
|
||||
*
|
||||
* The `ctr` parameter points to the counter; its length shall
|
||||
* be equal to the block size. It is updated by this function
|
||||
* as decryption proceeds.
|
||||
*
|
||||
* The data to decrypt is updated "in place". Its length (`len`
|
||||
* bytes) MUST be a multiple of the block size.
|
||||
*
|
||||
* \param ctx context structure (already initialised).
|
||||
* \param ctr counter for CTR encryption (initial and final).
|
||||
* \param data data to decrypt.
|
||||
* \param len data length (in bytes).
|
||||
*/
|
||||
void (*ctr)(const br_block_ctrcbc_class *const *ctx,
|
||||
void *ctr, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Run the CBC-MAC only.
|
||||
*
|
||||
* The `cbcmac` parameter points to the IV for CBC-MAC. The MAC
|
||||
* is computed over the encrypted data (i.e. before CTR
|
||||
* decryption). Its length shall be equal to the block size. The
|
||||
* computed CBC-MAC value is written over the `cbcmac` array.
|
||||
*
|
||||
* The data is unmodified. Its length (`len` bytes) MUST be a
|
||||
* multiple of the block size.
|
||||
*
|
||||
* \param ctx context structure (already initialised).
|
||||
* \param cbcmac IV and output buffer for CBC-MAC.
|
||||
* \param data data to decrypt.
|
||||
* \param len data length (in bytes).
|
||||
*/
|
||||
void (*mac)(const br_block_ctrcbc_class *const *ctx,
|
||||
void *cbcmac, const void *data, size_t len);
|
||||
};
|
||||
|
||||
/*
|
||||
* Traditional, table-based AES implementation. It is fast, but uses
|
||||
* internal tables (in particular a 1 kB table for encryption, another
|
||||
|
|
@ -517,6 +746,22 @@ typedef struct {
|
|||
#endif
|
||||
} br_aes_big_ctr_keys;
|
||||
|
||||
/**
|
||||
* \brief Context for AES subkeys (`aes_big` implementation, CTR encryption
|
||||
* and decryption + CBC-MAC).
|
||||
*
|
||||
* 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_ctrcbc_class *vtable;
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
uint32_t skey[60];
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
} br_aes_big_ctrcbc_keys;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CBC encryption (`aes_big` implementation).
|
||||
*/
|
||||
|
|
@ -533,6 +778,12 @@ extern const br_block_cbcdec_class br_aes_big_cbcdec_vtable;
|
|||
*/
|
||||
extern const br_block_ctr_class br_aes_big_ctr_vtable;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CTR encryption/decryption + CBC-MAC
|
||||
* (`aes_big` implementation).
|
||||
*/
|
||||
extern const br_block_ctrcbc_class br_aes_big_ctrcbc_vtable;
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CBC encryption
|
||||
* (`aes_big` implementation).
|
||||
|
|
@ -566,6 +817,17 @@ void br_aes_big_cbcdec_init(br_aes_big_cbcdec_keys *ctx,
|
|||
void br_aes_big_ctr_init(br_aes_big_ctr_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CTR + CBC-MAC
|
||||
* (`aes_big` implementation).
|
||||
*
|
||||
* \param ctx context to initialise.
|
||||
* \param key secret key.
|
||||
* \param len secret key length (in bytes).
|
||||
*/
|
||||
void br_aes_big_ctrcbc_init(br_aes_big_ctrcbc_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC encryption with AES (`aes_big` implementation).
|
||||
*
|
||||
|
|
@ -594,13 +856,59 @@ void br_aes_big_cbcdec_run(const br_aes_big_cbcdec_keys *ctx, void *iv,
|
|||
* \param ctx context (already initialised).
|
||||
* \param iv IV (constant, 12 bytes).
|
||||
* \param cc initial block counter value.
|
||||
* \param data data to decrypt (updated).
|
||||
* \param data data to encrypt or decrypt (updated).
|
||||
* \param len data length (in bytes).
|
||||
* \return new block counter value.
|
||||
*/
|
||||
uint32_t br_aes_big_ctr_run(const br_aes_big_ctr_keys *ctx,
|
||||
const void *iv, uint32_t cc, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR encryption + CBC-MAC with AES (`aes_big` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to encrypt (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_big_ctrcbc_encrypt(const br_aes_big_ctrcbc_keys *ctx,
|
||||
void *ctr, void *cbcmac, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR decryption + CBC-MAC with AES (`aes_big` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to decrypt (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_big_ctrcbc_decrypt(const br_aes_big_ctrcbc_keys *ctx,
|
||||
void *ctr, void *cbcmac, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR encryption/decryption with AES (`aes_big` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param data data to MAC (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_big_ctrcbc_ctr(const br_aes_big_ctrcbc_keys *ctx,
|
||||
void *ctr, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC-MAC with AES (`aes_big` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to MAC (unmodified).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_big_ctrcbc_mac(const br_aes_big_ctrcbc_keys *ctx,
|
||||
void *cbcmac, const void *data, size_t len);
|
||||
|
||||
/*
|
||||
* AES implementation optimized for size. It is slower than the
|
||||
* traditional table-based AES implementation, but requires much less
|
||||
|
|
@ -658,6 +966,22 @@ typedef struct {
|
|||
#endif
|
||||
} br_aes_small_ctr_keys;
|
||||
|
||||
/**
|
||||
* \brief Context for AES subkeys (`aes_small` implementation, CTR encryption
|
||||
* and decryption + CBC-MAC).
|
||||
*
|
||||
* 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_ctrcbc_class *vtable;
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
uint32_t skey[60];
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
} br_aes_small_ctrcbc_keys;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CBC encryption (`aes_small` implementation).
|
||||
*/
|
||||
|
|
@ -674,6 +998,12 @@ extern const br_block_cbcdec_class br_aes_small_cbcdec_vtable;
|
|||
*/
|
||||
extern const br_block_ctr_class br_aes_small_ctr_vtable;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CTR encryption/decryption + CBC-MAC
|
||||
* (`aes_small` implementation).
|
||||
*/
|
||||
extern const br_block_ctrcbc_class br_aes_small_ctrcbc_vtable;
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CBC encryption
|
||||
* (`aes_small` implementation).
|
||||
|
|
@ -707,6 +1037,17 @@ void br_aes_small_cbcdec_init(br_aes_small_cbcdec_keys *ctx,
|
|||
void br_aes_small_ctr_init(br_aes_small_ctr_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CTR + CBC-MAC
|
||||
* (`aes_small` implementation).
|
||||
*
|
||||
* \param ctx context to initialise.
|
||||
* \param key secret key.
|
||||
* \param len secret key length (in bytes).
|
||||
*/
|
||||
void br_aes_small_ctrcbc_init(br_aes_small_ctrcbc_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC encryption with AES (`aes_small` implementation).
|
||||
*
|
||||
|
|
@ -742,6 +1083,52 @@ void br_aes_small_cbcdec_run(const br_aes_small_cbcdec_keys *ctx, void *iv,
|
|||
uint32_t br_aes_small_ctr_run(const br_aes_small_ctr_keys *ctx,
|
||||
const void *iv, uint32_t cc, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR encryption + CBC-MAC with AES (`aes_small` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to encrypt (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_small_ctrcbc_encrypt(const br_aes_small_ctrcbc_keys *ctx,
|
||||
void *ctr, void *cbcmac, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR decryption + CBC-MAC with AES (`aes_small` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to decrypt (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_small_ctrcbc_decrypt(const br_aes_small_ctrcbc_keys *ctx,
|
||||
void *ctr, void *cbcmac, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR encryption/decryption with AES (`aes_small` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param data data to MAC (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_small_ctrcbc_ctr(const br_aes_small_ctrcbc_keys *ctx,
|
||||
void *ctr, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC-MAC with AES (`aes_small` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to MAC (unmodified).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_small_ctrcbc_mac(const br_aes_small_ctrcbc_keys *ctx,
|
||||
void *cbcmac, const void *data, size_t len);
|
||||
|
||||
/*
|
||||
* Constant-time AES implementation. Its size is similar to that of
|
||||
* 'aes_big', and its performance is similar to that of 'aes_small' (faster
|
||||
|
|
@ -798,6 +1185,22 @@ typedef struct {
|
|||
#endif
|
||||
} br_aes_ct_ctr_keys;
|
||||
|
||||
/**
|
||||
* \brief Context for AES subkeys (`aes_ct` implementation, CTR encryption
|
||||
* and decryption + CBC-MAC).
|
||||
*
|
||||
* 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_ctrcbc_class *vtable;
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
uint32_t skey[60];
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
} br_aes_ct_ctrcbc_keys;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CBC encryption (`aes_ct` implementation).
|
||||
*/
|
||||
|
|
@ -814,6 +1217,12 @@ extern const br_block_cbcdec_class br_aes_ct_cbcdec_vtable;
|
|||
*/
|
||||
extern const br_block_ctr_class br_aes_ct_ctr_vtable;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CTR encryption/decryption + CBC-MAC
|
||||
* (`aes_ct` implementation).
|
||||
*/
|
||||
extern const br_block_ctrcbc_class br_aes_ct_ctrcbc_vtable;
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CBC encryption
|
||||
* (`aes_ct` implementation).
|
||||
|
|
@ -847,6 +1256,17 @@ void br_aes_ct_cbcdec_init(br_aes_ct_cbcdec_keys *ctx,
|
|||
void br_aes_ct_ctr_init(br_aes_ct_ctr_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CTR + CBC-MAC
|
||||
* (`aes_ct` implementation).
|
||||
*
|
||||
* \param ctx context to initialise.
|
||||
* \param key secret key.
|
||||
* \param len secret key length (in bytes).
|
||||
*/
|
||||
void br_aes_ct_ctrcbc_init(br_aes_ct_ctrcbc_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC encryption with AES (`aes_ct` implementation).
|
||||
*
|
||||
|
|
@ -882,6 +1302,52 @@ void br_aes_ct_cbcdec_run(const br_aes_ct_cbcdec_keys *ctx, void *iv,
|
|||
uint32_t br_aes_ct_ctr_run(const br_aes_ct_ctr_keys *ctx,
|
||||
const void *iv, uint32_t cc, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR encryption + CBC-MAC with AES (`aes_ct` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to encrypt (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_ct_ctrcbc_encrypt(const br_aes_ct_ctrcbc_keys *ctx,
|
||||
void *ctr, void *cbcmac, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR decryption + CBC-MAC with AES (`aes_ct` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to decrypt (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_ct_ctrcbc_decrypt(const br_aes_ct_ctrcbc_keys *ctx,
|
||||
void *ctr, void *cbcmac, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR encryption/decryption with AES (`aes_ct` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param data data to MAC (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_ct_ctrcbc_ctr(const br_aes_ct_ctrcbc_keys *ctx,
|
||||
void *ctr, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC-MAC with AES (`aes_ct` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to MAC (unmodified).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_ct_ctrcbc_mac(const br_aes_ct_ctrcbc_keys *ctx,
|
||||
void *cbcmac, const void *data, size_t len);
|
||||
|
||||
/*
|
||||
* 64-bit constant-time AES implementation. It is similar to 'aes_ct'
|
||||
* but uses 64-bit registers, making it about twice faster than 'aes_ct'
|
||||
|
|
@ -940,6 +1406,22 @@ typedef struct {
|
|||
#endif
|
||||
} br_aes_ct64_ctr_keys;
|
||||
|
||||
/**
|
||||
* \brief Context for AES subkeys (`aes_ct64` implementation, CTR encryption
|
||||
* and decryption + CBC-MAC).
|
||||
*
|
||||
* 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_ctrcbc_class *vtable;
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
uint64_t skey[30];
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
} br_aes_ct64_ctrcbc_keys;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CBC encryption (`aes_ct64` implementation).
|
||||
*/
|
||||
|
|
@ -956,6 +1438,12 @@ extern const br_block_cbcdec_class br_aes_ct64_cbcdec_vtable;
|
|||
*/
|
||||
extern const br_block_ctr_class br_aes_ct64_ctr_vtable;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CTR encryption/decryption + CBC-MAC
|
||||
* (`aes_ct64` implementation).
|
||||
*/
|
||||
extern const br_block_ctrcbc_class br_aes_ct64_ctrcbc_vtable;
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CBC encryption
|
||||
* (`aes_ct64` implementation).
|
||||
|
|
@ -989,6 +1477,17 @@ void br_aes_ct64_cbcdec_init(br_aes_ct64_cbcdec_keys *ctx,
|
|||
void br_aes_ct64_ctr_init(br_aes_ct64_ctr_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CTR + CBC-MAC
|
||||
* (`aes_ct64` implementation).
|
||||
*
|
||||
* \param ctx context to initialise.
|
||||
* \param key secret key.
|
||||
* \param len secret key length (in bytes).
|
||||
*/
|
||||
void br_aes_ct64_ctrcbc_init(br_aes_ct64_ctrcbc_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC encryption with AES (`aes_ct64` implementation).
|
||||
*
|
||||
|
|
@ -1024,6 +1523,52 @@ void br_aes_ct64_cbcdec_run(const br_aes_ct64_cbcdec_keys *ctx, void *iv,
|
|||
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);
|
||||
|
||||
/**
|
||||
* \brief CTR encryption + CBC-MAC with AES (`aes_ct64` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to encrypt (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_ct64_ctrcbc_encrypt(const br_aes_ct64_ctrcbc_keys *ctx,
|
||||
void *ctr, void *cbcmac, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR decryption + CBC-MAC with AES (`aes_ct64` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to decrypt (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_ct64_ctrcbc_decrypt(const br_aes_ct64_ctrcbc_keys *ctx,
|
||||
void *ctr, void *cbcmac, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR encryption/decryption with AES (`aes_ct64` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param data data to MAC (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_ct64_ctrcbc_ctr(const br_aes_ct64_ctrcbc_keys *ctx,
|
||||
void *ctr, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC-MAC with AES (`aes_ct64` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to MAC (unmodified).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_ct64_ctrcbc_mac(const br_aes_ct64_ctrcbc_keys *ctx,
|
||||
void *cbcmac, const void *data, size_t len);
|
||||
|
||||
/*
|
||||
* AES implementation using AES-NI opcodes (x86 platform).
|
||||
*/
|
||||
|
|
@ -1083,6 +1628,24 @@ typedef struct {
|
|||
#endif
|
||||
} br_aes_x86ni_ctr_keys;
|
||||
|
||||
/**
|
||||
* \brief Context for AES subkeys (`aes_x86ni` implementation, CTR encryption
|
||||
* and decryption + CBC-MAC).
|
||||
*
|
||||
* 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_ctrcbc_class *vtable;
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
union {
|
||||
unsigned char skni[16 * 15];
|
||||
} skey;
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
} br_aes_x86ni_ctrcbc_keys;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CBC encryption (`aes_x86ni` implementation).
|
||||
*
|
||||
|
|
@ -1111,6 +1674,16 @@ extern const br_block_cbcdec_class br_aes_x86ni_cbcdec_vtable;
|
|||
*/
|
||||
extern const br_block_ctr_class br_aes_x86ni_ctr_vtable;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CTR encryption/decryption + CBC-MAC
|
||||
* (`aes_x86ni` 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_x86ni_ctrcbc_get_vtable()`.
|
||||
*/
|
||||
extern const br_block_ctrcbc_class br_aes_x86ni_ctrcbc_vtable;
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CBC encryption
|
||||
* (`aes_x86ni` implementation).
|
||||
|
|
@ -1144,6 +1717,17 @@ void br_aes_x86ni_cbcdec_init(br_aes_x86ni_cbcdec_keys *ctx,
|
|||
void br_aes_x86ni_ctr_init(br_aes_x86ni_ctr_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CTR + CBC-MAC
|
||||
* (`aes_x86ni` implementation).
|
||||
*
|
||||
* \param ctx context to initialise.
|
||||
* \param key secret key.
|
||||
* \param len secret key length (in bytes).
|
||||
*/
|
||||
void br_aes_x86ni_ctrcbc_init(br_aes_x86ni_ctrcbc_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC encryption with AES (`aes_x86ni` implementation).
|
||||
*
|
||||
|
|
@ -1179,6 +1763,52 @@ void br_aes_x86ni_cbcdec_run(const br_aes_x86ni_cbcdec_keys *ctx, void *iv,
|
|||
uint32_t br_aes_x86ni_ctr_run(const br_aes_x86ni_ctr_keys *ctx,
|
||||
const void *iv, uint32_t cc, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR encryption + CBC-MAC with AES (`aes_x86ni` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to encrypt (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_x86ni_ctrcbc_encrypt(const br_aes_x86ni_ctrcbc_keys *ctx,
|
||||
void *ctr, void *cbcmac, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR decryption + CBC-MAC with AES (`aes_x86ni` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to decrypt (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_x86ni_ctrcbc_decrypt(const br_aes_x86ni_ctrcbc_keys *ctx,
|
||||
void *ctr, void *cbcmac, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR encryption/decryption with AES (`aes_x86ni` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param ctr counter for CTR (16 bytes, updated).
|
||||
* \param data data to MAC (updated).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_x86ni_ctrcbc_ctr(const br_aes_x86ni_ctrcbc_keys *ctx,
|
||||
void *ctr, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC-MAC with AES (`aes_x86ni` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param cbcmac IV for CBC-MAC (updated).
|
||||
* \param data data to MAC (unmodified).
|
||||
* \param len data length (in bytes, MUST be a multiple of 16).
|
||||
*/
|
||||
void br_aes_x86ni_ctrcbc_mac(const br_aes_x86ni_ctrcbc_keys *ctx,
|
||||
void *cbcmac, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Obtain the `aes_x86ni` AES-CBC (encryption) implementation, if
|
||||
* available.
|
||||
|
|
@ -1188,7 +1818,7 @@ uint32_t br_aes_x86ni_ctr_run(const br_aes_x86ni_ctr_keys *ctx,
|
|||
* 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`.
|
||||
* \return the `aes_x86ni` AES-CBC (encryption) implementation, or `NULL`.
|
||||
*/
|
||||
const br_block_cbcenc_class *br_aes_x86ni_cbcenc_get_vtable(void);
|
||||
|
||||
|
|
@ -1201,7 +1831,7 @@ const br_block_cbcenc_class *br_aes_x86ni_cbcenc_get_vtable(void);
|
|||
* 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`.
|
||||
* \return the `aes_x86ni` AES-CBC (decryption) implementation, or `NULL`.
|
||||
*/
|
||||
const br_block_cbcdec_class *br_aes_x86ni_cbcdec_get_vtable(void);
|
||||
|
||||
|
|
@ -1213,10 +1843,23 @@ const br_block_cbcdec_class *br_aes_x86ni_cbcdec_get_vtable(void);
|
|||
* 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`.
|
||||
* \return the `aes_x86ni` AES-CTR implementation, or `NULL`.
|
||||
*/
|
||||
const br_block_ctr_class *br_aes_x86ni_ctr_get_vtable(void);
|
||||
|
||||
/**
|
||||
* \brief Obtain the `aes_x86ni` AES-CTR + CBC-MAC implementation, if
|
||||
* available.
|
||||
*
|
||||
* This function returns a pointer to `br_aes_x86ni_ctrcbc_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_x86ni` AES-CTR implementation, or `NULL`.
|
||||
*/
|
||||
const br_block_ctrcbc_class *br_aes_x86ni_ctrcbc_get_vtable(void);
|
||||
|
||||
/*
|
||||
* AES implementation using POWER8 opcodes.
|
||||
*/
|
||||
|
|
@ -1452,6 +2095,22 @@ typedef union {
|
|||
br_aes_pwr8_ctr_keys c_pwr8;
|
||||
} br_aes_gen_ctr_keys;
|
||||
|
||||
/**
|
||||
* \brief Aggregate structure large enough to be used as context for
|
||||
* subkeys (CTR encryption/decryption + CBC-MAC) for all AES implementations.
|
||||
*/
|
||||
typedef union {
|
||||
const br_block_ctrcbc_class *vtable;
|
||||
br_aes_big_ctrcbc_keys c_big;
|
||||
br_aes_small_ctrcbc_keys c_small;
|
||||
br_aes_ct_ctrcbc_keys c_ct;
|
||||
br_aes_ct64_ctrcbc_keys c_ct64;
|
||||
/* FIXME
|
||||
br_aes_x86ni_ctrcbc_keys c_x86ni;
|
||||
br_aes_pwr8_ctrcbc_keys c_pwr8;
|
||||
*/
|
||||
} br_aes_gen_ctrcbc_keys;
|
||||
|
||||
/*
|
||||
* Traditional, table-based implementation for DES/3DES. Since tables are
|
||||
* used, cache-timing attacks are conceptually possible.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue