]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Add concept of additional data to cipher algorithms
authorMichael Brown <mcb30@ipxe.org>
Mon, 24 Oct 2022 17:49:43 +0000 (18:49 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 25 Oct 2022 12:21:30 +0000 (13:21 +0100)
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>
src/include/ipxe/crypto.h
src/tests/aes_test.c
src/tests/cipher_test.c
src/tests/cipher_test.h

index 931be050280641f1d128089ae9b87b284d3a2d87..d41448024c80801a0da6974345eeb8e612ad23bb 100644 (file)
@@ -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.
         */
index ad66c734ce52aaf5ba5bc6b428bc0f3f95959c20..e7201fca6c7731641c698ba10822fe9206c9eda8 100644 (file)
@@ -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,
index 5361502ffc22b91390a4cc279a0c944cdba3ac03..c49b4b69bd947a7f64f6371d869e5dd458a58227 100644 (file)
@@ -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 */
index d7c5aef8fc8bdffe7e29cbadd428452b852c504d..4139a7788c47b382cb65e8550585f4712bfe4877 100644 (file)
@@ -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 ),                   \