]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[test] Generalise cipher tests and use okx()
authorMichael Brown <mcb30@ipxe.org>
Mon, 27 Jul 2015 13:00:57 +0000 (14:00 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 27 Jul 2015 15:04:38 +0000 (16:04 +0100)
Generalise the existing support for performing CBC-mode block cipher
tests, and update the code to use okx() for neater reporting of test
results.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/tests/aes_test.c [moved from src/tests/aes_cbc_test.c with 54% similarity]
src/tests/cbc_test.h [deleted file]
src/tests/cipher_test.c [moved from src/tests/cbc_test.c with 57% similarity]
src/tests/cipher_test.h [new file with mode: 0644]
src/tests/tests.c

similarity index 54%
rename from src/tests/aes_cbc_test.c
rename to src/tests/aes_test.c
index 1b9f4da9945505c85196d08c0c354cfa946bb1fb..bc23cba527515015ba67b28eeeb06ba5d584d3ec 100644 (file)
@@ -25,7 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 /** @file
  *
- * AES-in-CBC-mode tests
+ * AES tests
  *
  * These test vectors are provided by NIST as part of the
  * Cryptographic Toolkit Examples, downloadable from:
@@ -41,88 +41,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <string.h>
 #include <ipxe/aes.h>
 #include <ipxe/test.h>
-#include "cbc_test.h"
+#include "cipher_test.h"
 
-/** Define inline key */
-#define KEY(...) { __VA_ARGS__ }
-
-/** Define inline initialisation vector */
-#define IV(...) { __VA_ARGS__ }
-
-/** Define inline plaintext data */
-#define PLAINTEXT(...) { __VA_ARGS__ }
-
-/** Define inline ciphertext data */
-#define CIPHERTEXT(...) { __VA_ARGS__ }
-
-/** An AES-in-CBC-mode test */
-struct aes_cbc_test {
-       /** Key */
-       const void *key;
-       /** Length of key */
-       size_t key_len;
-       /** Initialisation vector */
-       const void *iv;
-       /** Length of initialisation vector */
-       size_t iv_len;
-       /** Plaintext */
-       const void *plaintext;
-       /** Length of plaintext */
-       size_t plaintext_len;
-       /** Ciphertext */
-       const void *ciphertext;
-       /** Length of ciphertext */
-       size_t ciphertext_len;
-};
-
-/**
- * Define an AES-in-CBC-mode test
- *
- * @v name             Test name
- * @v key_array                Key
- * @v iv_array         Initialisation vector
- * @v plaintext_array  Plaintext
- * @v ciphertext_array Ciphertext
- * @ret test           AES-in-CBC-mode test
- */
-#define AES_CBC_TEST( name, key_array, iv_array, plaintext_array,      \
-                     ciphertext_array )                                \
-       static const uint8_t name ## _key [] = key_array;               \
-       static const uint8_t name ## _iv [] = iv_array;                 \
-       static const uint8_t name ## _plaintext [] = plaintext_array;   \
-       static const uint8_t name ## _ciphertext [] = ciphertext_array; \
-       static struct aes_cbc_test name = {                             \
-               .key = name ## _key,                                    \
-               .key_len = sizeof ( name ## _key ),                     \
-               .iv = name ## _iv,                                      \
-               .iv_len = sizeof ( name ## _iv ),                       \
-               .plaintext = name ## _plaintext,                        \
-               .plaintext_len = sizeof ( name ## _plaintext ),         \
-               .ciphertext = name ## _ciphertext,                      \
-               .ciphertext_len = sizeof ( name ## _ciphertext ),       \
-       }
-
-/**
- * Report AES-in-CBC-mode
- *
- * @v state            HMAC_DRBG internal state
- * @v test             Instantiation test
- */
-#define aes_cbc_ok( test ) do {                                                \
-       struct cipher_algorithm *cipher = &aes_cbc_algorithm;           \
-                                                                       \
-       assert ( (test)->iv_len == cipher->blocksize );                 \
-       assert ( (test)->plaintext_len == (test)->ciphertext_len );     \
-       cbc_encrypt_ok ( cipher, (test)->key, (test)->key_len,          \
-                        (test)->iv, (test)->plaintext,                 \
-                        (test)->ciphertext, (test)->plaintext_len );   \
-       cbc_decrypt_ok ( cipher, (test)->key, (test)->key_len,          \
-                        (test)->iv, (test)->ciphertext,                \
-                        (test)->plaintext, (test)->ciphertext_len );   \
-       } while ( 0 )
-
-/** CBC_AES128 */
-AES_CBC_TEST ( test_128,
+/** AES-128-CBC */
+CIPHER_TEST ( aes_128_cbc, &aes_cbc_algorithm,
        KEY ( 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15,
              0x88, 0x09, 0xcf, 0x4f, 0x3c ),
        IV ( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
@@ -144,8 +66,8 @@ AES_CBC_TEST ( test_128,
                     0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09,
                     0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 ) );
 
-/** CBC_AES256 */
-AES_CBC_TEST ( test_256,
+/** AES-256-CBC */
+CIPHER_TEST ( aes_256_cbc, &aes_cbc_algorithm,
        KEY ( 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae,
              0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
              0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 ),
@@ -169,29 +91,28 @@ AES_CBC_TEST ( test_256,
                     0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b ) );
 
 /**
- * Perform AES-in-CBC-mode self-test
+ * Perform AES self-test
  *
  */
-static void aes_cbc_test_exec ( void ) {
-       struct cipher_algorithm *cipher = &aes_cbc_algorithm;
+static void aes_test_exec ( void ) {
+       struct cipher_algorithm *cbc = &aes_cbc_algorithm;
+       unsigned int keylen;
 
        /* Correctness tests */
-       aes_cbc_ok ( &test_128 );
-       aes_cbc_ok ( &test_256 );
+       cipher_ok ( &aes_128_cbc );
+       cipher_ok ( &aes_256_cbc );
 
        /* Speed tests */
-       DBG ( "AES128 encryption required %ld cycles per byte\n",
-             cbc_cost_encrypt ( cipher, test_128.key_len ) );
-       DBG ( "AES128 decryption required %ld cycles per byte\n",
-             cbc_cost_decrypt ( cipher, test_128.key_len ) );
-       DBG ( "AES256 encryption required %ld cycles per byte\n",
-             cbc_cost_encrypt ( cipher, test_256.key_len ) );
-       DBG ( "AES256 decryption required %ld cycles per byte\n",
-             cbc_cost_decrypt ( cipher, test_256.key_len ) );
+       for ( keylen = 128 ; keylen <= 256 ; keylen += 128 ) {
+               DBG ( "AES-%d-CBC encryption required %ld cycles per byte\n",
+                     keylen, cipher_cost_encrypt ( cbc, ( keylen / 8 ) ) );
+               DBG ( "AES-%d-CBC decryption required %ld cycles per byte\n",
+                     keylen, cipher_cost_decrypt ( cbc, ( keylen / 8 ) ) );
+       }
 }
 
-/** AES-in-CBC-mode self-test */
-struct self_test aes_cbc_test __self_test = {
-       .name = "aes_cbc",
-       .exec = aes_cbc_test_exec,
+/** AES self-test */
+struct self_test aes_test __self_test = {
+       .name = "aes",
+       .exec = aes_test_exec,
 };
diff --git a/src/tests/cbc_test.h b/src/tests/cbc_test.h
deleted file mode 100644 (file)
index 059b090..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef _CBC_TEST_H
-#define _CBC_TEST_H
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <ipxe/crypto.h>
-#include <ipxe/test.h>
-
-extern int cbc_test_encrypt ( struct cipher_algorithm *cipher, const void *key,
-                             size_t key_len, const void *iv,
-                             const void *plaintext,
-                             const void *expected_ciphertext, size_t len );
-extern int cbc_test_decrypt ( struct cipher_algorithm *cipher, const void *key,
-                             size_t key_len, const void *iv,
-                             const void *ciphertext,
-                             const void *expected_plaintext, size_t len );
-extern unsigned long cbc_cost_encrypt ( struct cipher_algorithm *cipher,
-                                       size_t key_len );
-extern unsigned long cbc_cost_decrypt ( struct cipher_algorithm *cipher,
-                                       size_t key_len );
-
-/**
- * Report CBC encryption test result
- *
- * @v cipher                   Cipher algorithm
- * @v key                      Key
- * @v key_len                  Length of key
- * @v iv                       Initialisation vector
- * @v plaintext                        Plaintext data
- * @v expected_ciphertext      Expected ciphertext data
- * @v len                      Length of data
- */
-#define cbc_encrypt_ok( cipher, key, key_len, iv, plaintext,           \
-                       expected_ciphertext, len ) do {                 \
-       ok ( cbc_test_encrypt ( cipher, key, key_len, iv, plaintext,    \
-                               expected_ciphertext, len ) );           \
-       } while ( 0 )
-
-/**
- * Report CBC decryption test result
- *
- * @v cipher                   Cipher algorithm
- * @v key                      Key
- * @v key_len                  Length of key
- * @v iv                       Initialisation vector
- * @v ciphertext               Ciphertext data
- * @v expected_plaintext       Expected plaintext data
- * @v len                      Length of data
- */
-#define cbc_decrypt_ok( cipher, key, key_len, iv, ciphertext,          \
-                       expected_plaintext, len ) do {                  \
-       ok ( cbc_test_decrypt ( cipher, key, key_len, iv, ciphertext,   \
-                               expected_plaintext, len ) );            \
-       } while ( 0 )
-
-#endif /* _CBC_TEST_H */
similarity index 57%
rename from src/tests/cbc_test.c
rename to src/tests/cipher_test.c
index 0751ca2f384c8cd3facb1b33957c0e94c9bc82fd..800d6c138c76de8a9d1606e23506f11705eb70c7 100644 (file)
@@ -25,7 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 /** @file
  *
- * CBC self-tests
+ * Cipher self-tests
  *
  */
 
@@ -38,86 +38,90 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <assert.h>
 #include <ipxe/crypto.h>
 #include <ipxe/profile.h>
-#include "cbc_test.h"
+#include <ipxe/test.h>
+#include "cipher_test.h"
 
 /** Number of sample iterations for profiling */
 #define PROFILE_COUNT 16
 
 /**
- * Test CBC encryption
+ * Report a cipher encryption test result
  *
- * @v cipher                   Cipher algorithm
- * @v key                      Key
- * @v key_len                  Length of key
- * @v iv                       Initialisation vector
- * @v plaintext                        Plaintext data
- * @v expected_ciphertext      Expected ciphertext data
- * @v len                      Length of data
- * @ret ok                     Ciphertext is as expected
+ * @v test             Cipher test
+ * @v file             Test code file
+ * @v line             Test code line
  */
-int cbc_test_encrypt ( struct cipher_algorithm *cipher, const void *key,
-                      size_t key_len, const void *iv, const void *plaintext,
-                      const void *expected_ciphertext, size_t len ) {
+void cipher_encrypt_okx ( struct cipher_test *test, const char *file,
+                         unsigned int line ) {
+       struct cipher_algorithm *cipher = test->cipher;
+       size_t len = test->len;
        uint8_t ctx[cipher->ctxsize];
        uint8_t ciphertext[len];
-       int rc;
 
        /* Initialise cipher */
-       rc = cipher_setkey ( cipher, ctx, key, key_len );
-       assert ( rc == 0 );
-       cipher_setiv ( cipher, ctx, iv );
+       okx ( cipher_setkey ( cipher, ctx, test->key, test->key_len ) == 0,
+             file, line );
+       cipher_setiv ( cipher, ctx, test->iv );
 
        /* Perform encryption */
-       cipher_encrypt ( cipher, ctx, plaintext, ciphertext, len );
+       cipher_encrypt ( cipher, ctx, test->plaintext, ciphertext, len );
 
-       /* Verify result */
-       return ( memcmp ( ciphertext, expected_ciphertext, len ) == 0 );
+       /* Compare against expected ciphertext */
+       okx ( memcmp ( ciphertext, test->ciphertext, len ) == 0, file, line );
 }
 
 /**
- * Test CBC decryption
+ * Report a cipher decryption test result
  *
- * @v cipher                   Cipher algorithm
- * @v key                      Key
- * @v key_len                  Length of key
- * @v iv                       Initialisation vector
- * @v ciphertext               Ciphertext data
- * @v expected_plaintext       Expected plaintext data
- * @v len                      Length of data
- * @ret ok                     Plaintext is as expected
+ * @v test             Cipher test
+ * @v file             Test code file
+ * @v line             Test code line
  */
-int cbc_test_decrypt ( struct cipher_algorithm *cipher, const void *key,
-                      size_t key_len, const void *iv, const void *ciphertext,
-                      const void *expected_plaintext, size_t len ) {
+void cipher_decrypt_okx ( struct cipher_test *test, const char *file,
+                         unsigned int line ) {
+       struct cipher_algorithm *cipher = test->cipher;
+       size_t len = test->len;
        uint8_t ctx[cipher->ctxsize];
        uint8_t plaintext[len];
-       int rc;
 
        /* Initialise cipher */
-       rc = cipher_setkey ( cipher, ctx, key, key_len );
-       assert ( rc == 0 );
-       cipher_setiv ( cipher, ctx, iv );
+       okx ( cipher_setkey ( cipher, ctx, test->key, test->key_len ) == 0,
+             file, line );
+       cipher_setiv ( cipher, ctx, test->iv );
 
        /* Perform encryption */
-       cipher_decrypt ( cipher, ctx, ciphertext, plaintext, len );
+       cipher_decrypt ( cipher, ctx, test->ciphertext, plaintext, len );
+
+       /* Compare against expected plaintext */
+       okx ( memcmp ( plaintext, test->plaintext, len ) == 0, file, line );
+}
+
+/**
+ * Report a cipher encryption and decryption test result
+ *
+ * @v test             Cipher test
+ * @v file             Test code file
+ * @v line             Test code line
+ */
+void cipher_okx ( struct cipher_test *test, const char *file,
+                 unsigned int line ) {
 
-       /* Verify result */
-       return ( memcmp ( plaintext, expected_plaintext, len ) == 0 );
+       cipher_encrypt_okx ( test, file, line );
+       cipher_decrypt_okx ( test, file, line );
 }
 
 /**
- * Calculate CBC encryption or decryption cost
+ * Calculate cipher encryption or decryption cost
  *
  * @v cipher                   Cipher algorithm
  * @v key_len                  Length of key
  * @v op                       Encryption or decryption operation
  * @ret cost                   Cost (in cycles per byte)
  */
-static unsigned long cbc_cost ( struct cipher_algorithm *cipher,
-                               size_t key_len,
-                               void ( * op ) ( struct cipher_algorithm *cipher,
-                                               void *ctx, const void *src,
-                                               void *dst, size_t len ) ) {
+static unsigned long
+cipher_cost ( struct cipher_algorithm *cipher, size_t key_len,
+             void ( * op ) ( struct cipher_algorithm *cipher, void *ctx,
+                             const void *src, void *dst, size_t len ) ) {
        static uint8_t random[8192]; /* Too large for stack */
        uint8_t key[key_len];
        uint8_t iv[cipher->blocksize];
@@ -157,25 +161,25 @@ static unsigned long cbc_cost ( struct cipher_algorithm *cipher,
 }
 
 /**
- * Calculate CBC encryption cost
+ * Calculate cipher encryption cost
  *
  * @v cipher                   Cipher algorithm
  * @v key_len                  Length of key
  * @ret cost                   Cost (in cycles per byte)
  */
-unsigned long cbc_cost_encrypt ( struct cipher_algorithm *cipher,
-                                size_t key_len ) {
-       return cbc_cost ( cipher, key_len, cipher_encrypt );
+unsigned long cipher_cost_encrypt ( struct cipher_algorithm *cipher,
+                                   size_t key_len ) {
+       return cipher_cost ( cipher, key_len, cipher_encrypt );
 }
 
 /**
- * Calculate CBC decryption cost
+ * Calculate cipher decryption cost
  *
  * @v cipher                   Cipher algorithm
  * @v key_len                  Length of key
  * @ret cost                   Cost (in cycles per byte)
  */
-unsigned long cbc_cost_decrypt ( struct cipher_algorithm *cipher,
-                                size_t key_len ) {
-       return cbc_cost ( cipher, key_len, cipher_decrypt );
+unsigned long cipher_cost_decrypt ( struct cipher_algorithm *cipher,
+                                   size_t key_len ) {
+       return cipher_cost ( cipher, key_len, cipher_decrypt );
 }
diff --git a/src/tests/cipher_test.h b/src/tests/cipher_test.h
new file mode 100644 (file)
index 0000000..d7c5aef
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef _CIPHER_TEST_H
+#define _CIPHER_TEST_H
+
+/** @file
+ *
+ * Cipher self-tests
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/crypto.h>
+#include <ipxe/test.h>
+
+/** A cipher test */
+struct cipher_test {
+       /** Cipher algorithm */
+       struct cipher_algorithm *cipher;
+       /** Key */
+       const void *key;
+       /** Length of key */
+       size_t key_len;
+       /** Initialisation vector */
+       const void *iv;
+       /** Length of initialisation vector */
+       size_t iv_len;
+       /** Plaintext */
+       const void *plaintext;
+       /** Ciphertext */
+       const void *ciphertext;
+       /** Length of text */
+       size_t len;
+};
+
+/** Define inline key */
+#define KEY(...) { __VA_ARGS__ }
+
+/** Define inline initialisation vector */
+#define IV(...) { __VA_ARGS__ }
+
+/** Define inline plaintext data */
+#define PLAINTEXT(...) { __VA_ARGS__ }
+
+/** Define inline ciphertext data */
+#define CIPHERTEXT(...) { __VA_ARGS__ }
+
+/**
+ * Define a cipher test
+ *
+ * @v name             Test name
+ * @v CIPHER           Cipher algorithm
+ * @v KEY              Key
+ * @v IV               Initialisation vector
+ * @v PLAINTEXT                Plaintext
+ * @v CIPHERTEXT       Ciphertext
+ * @ret test           Cipher test
+ */
+#define CIPHER_TEST( name, CIPHER, KEY, IV, PLAINTEXT, CIPHERTEXT )    \
+       static const uint8_t name ## _key [] = KEY;                     \
+       static const uint8_t name ## _iv [] = IV;                       \
+       static const uint8_t name ## _plaintext [] = PLAINTEXT;         \
+       static const uint8_t name ## _ciphertext                        \
+               [ sizeof ( name ## _plaintext ) ] = CIPHERTEXT;         \
+       static struct cipher_test name = {                              \
+               .cipher = CIPHER,                                       \
+               .key = name ## _key,                                    \
+               .key_len = sizeof ( name ## _key ),                     \
+               .iv = name ## _iv,                                      \
+               .iv_len = sizeof ( name ## _iv ),                       \
+               .plaintext = name ## _plaintext,                        \
+               .ciphertext = name ## _ciphertext,                      \
+               .len = sizeof ( name ## _plaintext ),                   \
+       }
+
+extern void cipher_encrypt_okx ( struct cipher_test *test, const char *file,
+                                unsigned int line );
+extern void cipher_decrypt_okx ( struct cipher_test *test, const char *file,
+                                unsigned int line );
+extern void cipher_okx ( struct cipher_test *test, const char *file,
+                        unsigned int line );
+extern unsigned long cipher_cost_encrypt ( struct cipher_algorithm *cipher,
+                                          size_t key_len );
+extern unsigned long cipher_cost_decrypt ( struct cipher_algorithm *cipher,
+                                          size_t key_len );
+
+/**
+ * Report a cipher encryption test result
+ *
+ * @v test             Cipher test
+ */
+#define cipher_encrypt_ok( test ) \
+       cipher_encrypt_okx ( test, __FILE__, __LINE__ )
+
+/**
+ * Report a cipher decryption test result
+ *
+ * @v test             Cipher test
+ */
+#define cipher_decrypt_ok( test ) \
+       cipher_decrypt_okx ( test, __FILE__, __LINE__ )
+
+/**
+ * Report a cipher encryption and decryption test result
+ *
+ * @v test             Cipher test
+ */
+#define cipher_ok( test ) \
+       cipher_okx ( test, __FILE__, __LINE__ )
+
+#endif /* _CIPHER_TEST_H */
index 97e510f6e314150bb7ba197e68828481cfdb226d..0e6afee6e584e55eb927784e07dbb4664ee37fdd 100644 (file)
@@ -50,7 +50,7 @@ REQUIRE_OBJECT ( md5_test );
 REQUIRE_OBJECT ( sha1_test );
 REQUIRE_OBJECT ( sha256_test );
 REQUIRE_OBJECT ( sha512_test );
-REQUIRE_OBJECT ( aes_cbc_test );
+REQUIRE_OBJECT ( aes_test );
 REQUIRE_OBJECT ( hmac_drbg_test );
 REQUIRE_OBJECT ( hash_df_test );
 REQUIRE_OBJECT ( bigint_test );