mirror of https://github.com/ipxe/ipxe.git
[crypto] Add concept of additional data to cipher algorithms
Some ciphers (such as GCM) support the concept of additional authenticated data, which does not appear in the ciphertext but may affect the operation of the cipher. Allow cipher_encrypt() and cipher_decrypt() to be called with a NULL destination buffer in order to pass additional data. Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/785/head
parent
8e478e648f
commit
0c383bf00a
|
@ -54,25 +54,25 @@ struct cipher_algorithm {
|
|||
size_t blocksize;
|
||||
/** Set key
|
||||
*
|
||||
* @v ctx Context
|
||||
* @v key Key
|
||||
* @v keylen Key length
|
||||
* @ret rc Return status code
|
||||
* @v ctx Context
|
||||
* @v key Key
|
||||
* @v keylen Key length
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ( * setkey ) ( void *ctx, const void *key, size_t keylen );
|
||||
/** Set initialisation vector
|
||||
*
|
||||
* @v ctx Context
|
||||
* @v iv Initialisation vector
|
||||
* @v ivlen Initialisation vector length
|
||||
* @v ctx Context
|
||||
* @v iv Initialisation vector
|
||||
* @v ivlen Initialisation vector length
|
||||
*/
|
||||
void ( * setiv ) ( void *ctx, const void *iv, size_t ivlen );
|
||||
/** Encrypt data
|
||||
*
|
||||
* @v ctx Context
|
||||
* @v src Data to encrypt
|
||||
* @v dst Buffer for encrypted data
|
||||
* @v len Length of data
|
||||
* @v ctx Context
|
||||
* @v src Data to encrypt
|
||||
* @v dst Buffer for encrypted data, or NULL for additional data
|
||||
* @v len Length of data
|
||||
*
|
||||
* @v len is guaranteed to be a multiple of @c blocksize.
|
||||
*/
|
||||
|
@ -80,10 +80,10 @@ struct cipher_algorithm {
|
|||
size_t len );
|
||||
/** Decrypt data
|
||||
*
|
||||
* @v ctx Context
|
||||
* @v src Data to decrypt
|
||||
* @v dst Buffer for decrypted data
|
||||
* @v len Length of data
|
||||
* @v ctx Context
|
||||
* @v src Data to decrypt
|
||||
* @v dst Buffer for decrypted data, or NULL for additional data
|
||||
* @v len Length of data
|
||||
*
|
||||
* @v len is guaranteed to be a multiple of @c blocksize.
|
||||
*/
|
||||
|
|
|
@ -86,7 +86,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
|
||||
/** AES-128-ECB (same test as AES-128-Core) */
|
||||
CIPHER_TEST ( aes_128_ecb, &aes_ecb_algorithm,
|
||||
AES_KEY_NIST_128, AES_IV_NIST_DUMMY, AES_PLAINTEXT_NIST,
|
||||
AES_KEY_NIST_128, AES_IV_NIST_DUMMY, ADDITIONAL(), AES_PLAINTEXT_NIST,
|
||||
CIPHERTEXT ( 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
|
||||
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
|
||||
0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d,
|
||||
|
@ -98,7 +98,7 @@ CIPHER_TEST ( aes_128_ecb, &aes_ecb_algorithm,
|
|||
|
||||
/** AES-128-CBC */
|
||||
CIPHER_TEST ( aes_128_cbc, &aes_cbc_algorithm,
|
||||
AES_KEY_NIST_128, AES_IV_NIST_CBC, AES_PLAINTEXT_NIST,
|
||||
AES_KEY_NIST_128, AES_IV_NIST_CBC, ADDITIONAL(), AES_PLAINTEXT_NIST,
|
||||
CIPHERTEXT ( 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
|
||||
0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
|
||||
0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee,
|
||||
|
@ -110,7 +110,7 @@ CIPHER_TEST ( aes_128_cbc, &aes_cbc_algorithm,
|
|||
|
||||
/** AES-192-ECB (same test as AES-192-Core) */
|
||||
CIPHER_TEST ( aes_192_ecb, &aes_ecb_algorithm,
|
||||
AES_KEY_NIST_192, AES_IV_NIST_DUMMY, AES_PLAINTEXT_NIST,
|
||||
AES_KEY_NIST_192, AES_IV_NIST_DUMMY, ADDITIONAL(), AES_PLAINTEXT_NIST,
|
||||
CIPHERTEXT ( 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f,
|
||||
0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc,
|
||||
0x97, 0x41, 0x04, 0x84, 0x6d, 0x0a, 0xd3, 0xad,
|
||||
|
@ -122,7 +122,7 @@ CIPHER_TEST ( aes_192_ecb, &aes_ecb_algorithm,
|
|||
|
||||
/** AES-192-CBC */
|
||||
CIPHER_TEST ( aes_192_cbc, &aes_cbc_algorithm,
|
||||
AES_KEY_NIST_192, AES_IV_NIST_CBC, AES_PLAINTEXT_NIST,
|
||||
AES_KEY_NIST_192, AES_IV_NIST_CBC, ADDITIONAL(), AES_PLAINTEXT_NIST,
|
||||
CIPHERTEXT ( 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d,
|
||||
0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8,
|
||||
0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4,
|
||||
|
@ -134,7 +134,7 @@ CIPHER_TEST ( aes_192_cbc, &aes_cbc_algorithm,
|
|||
|
||||
/** AES-256-ECB (same test as AES-256-Core) */
|
||||
CIPHER_TEST ( aes_256_ecb, &aes_ecb_algorithm,
|
||||
AES_KEY_NIST_256, AES_IV_NIST_DUMMY, AES_PLAINTEXT_NIST,
|
||||
AES_KEY_NIST_256, AES_IV_NIST_DUMMY, ADDITIONAL(), AES_PLAINTEXT_NIST,
|
||||
CIPHERTEXT ( 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c,
|
||||
0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8,
|
||||
0x59, 0x1c, 0xcb, 0x10, 0xd4, 0x10, 0xed, 0x26,
|
||||
|
@ -146,7 +146,7 @@ CIPHER_TEST ( aes_256_ecb, &aes_ecb_algorithm,
|
|||
|
||||
/** AES-256-CBC */
|
||||
CIPHER_TEST ( aes_256_cbc, &aes_cbc_algorithm,
|
||||
AES_KEY_NIST_256, AES_IV_NIST_CBC, AES_PLAINTEXT_NIST,
|
||||
AES_KEY_NIST_256, AES_IV_NIST_CBC, ADDITIONAL(), AES_PLAINTEXT_NIST,
|
||||
CIPHERTEXT ( 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
|
||||
0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
|
||||
0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
|
||||
|
|
|
@ -63,6 +63,12 @@ void cipher_encrypt_okx ( struct cipher_test *test, const char *file,
|
|||
file, line );
|
||||
cipher_setiv ( cipher, ctx, test->iv, test->iv_len );
|
||||
|
||||
/* Process additional data, if applicable */
|
||||
if ( test->additional_len ) {
|
||||
cipher_encrypt ( cipher, ctx, test->additional, NULL,
|
||||
test->additional_len );
|
||||
}
|
||||
|
||||
/* Perform encryption */
|
||||
cipher_encrypt ( cipher, ctx, test->plaintext, ciphertext, len );
|
||||
|
||||
|
@ -89,7 +95,13 @@ void cipher_decrypt_okx ( struct cipher_test *test, const char *file,
|
|||
file, line );
|
||||
cipher_setiv ( cipher, ctx, test->iv, test->iv_len );
|
||||
|
||||
/* Perform encryption */
|
||||
/* Process additional data, if applicable */
|
||||
if ( test->additional_len ) {
|
||||
cipher_decrypt ( cipher, ctx, test->additional, NULL,
|
||||
test->additional_len );
|
||||
}
|
||||
|
||||
/* Perform decryption */
|
||||
cipher_decrypt ( cipher, ctx, test->ciphertext, plaintext, len );
|
||||
|
||||
/* Compare against expected plaintext */
|
||||
|
|
|
@ -25,6 +25,10 @@ struct cipher_test {
|
|||
const void *iv;
|
||||
/** Length of initialisation vector */
|
||||
size_t iv_len;
|
||||
/** Additional data */
|
||||
const void *additional;
|
||||
/** Length of additional data */
|
||||
size_t additional_len;
|
||||
/** Plaintext */
|
||||
const void *plaintext;
|
||||
/** Ciphertext */
|
||||
|
@ -39,6 +43,9 @@ struct cipher_test {
|
|||
/** Define inline initialisation vector */
|
||||
#define IV(...) { __VA_ARGS__ }
|
||||
|
||||
/** Define inline additional data */
|
||||
#define ADDITIONAL(...) { __VA_ARGS__ }
|
||||
|
||||
/** Define inline plaintext data */
|
||||
#define PLAINTEXT(...) { __VA_ARGS__ }
|
||||
|
||||
|
@ -52,13 +59,16 @@ struct cipher_test {
|
|||
* @v CIPHER Cipher algorithm
|
||||
* @v KEY Key
|
||||
* @v IV Initialisation vector
|
||||
* @v ADDITIONAL Additional data
|
||||
* @v PLAINTEXT Plaintext
|
||||
* @v CIPHERTEXT Ciphertext
|
||||
* @ret test Cipher test
|
||||
*/
|
||||
#define CIPHER_TEST( name, CIPHER, KEY, IV, PLAINTEXT, CIPHERTEXT ) \
|
||||
#define CIPHER_TEST( name, CIPHER, KEY, IV, ADDITIONAL, PLAINTEXT, \
|
||||
CIPHERTEXT ) \
|
||||
static const uint8_t name ## _key [] = KEY; \
|
||||
static const uint8_t name ## _iv [] = IV; \
|
||||
static const uint8_t name ## _additional [] = ADDITIONAL; \
|
||||
static const uint8_t name ## _plaintext [] = PLAINTEXT; \
|
||||
static const uint8_t name ## _ciphertext \
|
||||
[ sizeof ( name ## _plaintext ) ] = CIPHERTEXT; \
|
||||
|
@ -68,6 +78,8 @@ struct cipher_test {
|
|||
.key_len = sizeof ( name ## _key ), \
|
||||
.iv = name ## _iv, \
|
||||
.iv_len = sizeof ( name ## _iv ), \
|
||||
.additional = name ## _additional, \
|
||||
.additional_len = sizeof ( name ## _additional ), \
|
||||
.plaintext = name ## _plaintext, \
|
||||
.ciphertext = name ## _ciphertext, \
|
||||
.len = sizeof ( name ## _plaintext ), \
|
||||
|
|
Loading…
Reference in New Issue