aboutsummaryrefslogtreecommitdiffstats
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.tar.gz
[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 931be0502..d41448024 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 ad66c734c..e7201fca6 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 5361502ff..c49b4b69b 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 d7c5aef8f..4139a7788 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 ), \