aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-10-24 18:49:43 +0100
committerMichael Brown <mcb30@ipxe.org>2022-10-25 13:21:30 +0100
commit0c383bf00afbef1a9cfe02829d1bc6ee46e1c16b (patch)
treeac5e0bca148bd881a6e01fdb55591d5fb8ba9447
parent8e478e648fb68ac6f07e4e5cd80a5c1fefcb1cf5 (diff)
downloadipxe-0c383bf00afbef1a9cfe02829d1bc6ee46e1c16b.zip
ipxe-0c383bf00afbef1a9cfe02829d1bc6ee46e1c16b.tar.gz
ipxe-0c383bf00afbef1a9cfe02829d1bc6ee46e1c16b.tar.bz2
[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>
-rw-r--r--src/include/ipxe/crypto.h30
-rw-r--r--src/tests/aes_test.c12
-rw-r--r--src/tests/cipher_test.c14
-rw-r--r--src/tests/cipher_test.h14
4 files changed, 47 insertions, 23 deletions
diff --git a/src/include/ipxe/crypto.h b/src/include/ipxe/crypto.h
index 931be05..d414480 100644
--- a/src/include/ipxe/crypto.h
+++ b/src/include/ipxe/crypto.h
@@ -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.
*/
diff --git a/src/tests/aes_test.c b/src/tests/aes_test.c
index ad66c73..e7201fc 100644
--- a/src/tests/aes_test.c
+++ b/src/tests/aes_test.c
@@ -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,
diff --git a/src/tests/cipher_test.c b/src/tests/cipher_test.c
index 5361502..c49b4b6 100644
--- a/src/tests/cipher_test.c
+++ b/src/tests/cipher_test.c
@@ -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 */
diff --git a/src/tests/cipher_test.h b/src/tests/cipher_test.h
index d7c5aef..4139a77 100644
--- a/src/tests/cipher_test.h
+++ b/src/tests/cipher_test.h
@@ -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 ), \