]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[test] Add speed tests for cipher algorithms
authorMichael Brown <mcb30@ipxe.org>
Wed, 26 Sep 2012 14:27:33 +0000 (15:27 +0100)
committerMichael Brown <mcb30@ipxe.org>
Wed, 26 Sep 2012 14:27:33 +0000 (15:27 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/tests/aes_cbc_test.c
src/tests/cbc_test.c
src/tests/cbc_test.h

index 09d38075cc3095824a5ed345314323084cb3c263..4ae3a92e53f3774f8813e9fd8948b9705e98942d 100644 (file)
@@ -169,9 +169,21 @@ AES_CBC_TEST ( test_256,
  *
  */
 static void aes_cbc_test_exec ( void ) {
+       struct cipher_algorithm *cipher = &aes_cbc_algorithm;
 
+       /* Correctness tests */
        aes_cbc_ok ( &test_128 );
        aes_cbc_ok ( &test_256 );
+
+       /* 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 ) );
 }
 
 /** AES-in-CBC-mode self-test */
index 7d7553096d40c3086afadaaf65be3d5a49ec93ca..ada991b219b55fde09ac89ec32522054e57738c3 100644 (file)
@@ -29,9 +29,11 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #undef NDEBUG
 
 #include <stdint.h>
+#include <stdlib.h>
 #include <string.h>
 #include <assert.h>
 #include <ipxe/crypto.h>
+#include <ipxe/profile.h>
 #include "cbc_test.h"
 
 /**
@@ -49,8 +51,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
 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 ) {
-       uint8_t ctx[ cipher->ctxsize ];
-       uint8_t ciphertext[ len ];
+       uint8_t ctx[cipher->ctxsize];
+       uint8_t ciphertext[len];
        int rc;
 
        /* Initialise cipher */
@@ -80,8 +82,8 @@ int cbc_test_encrypt ( struct cipher_algorithm *cipher, const void *key,
 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 ) {
-       uint8_t ctx[ cipher->ctxsize ];
-       uint8_t plaintext[ len ];
+       uint8_t ctx[cipher->ctxsize];
+       uint8_t plaintext[len];
        int rc;
 
        /* Initialise cipher */
@@ -95,3 +97,75 @@ int cbc_test_decrypt ( struct cipher_algorithm *cipher, const void *key,
        /* Verify result */
        return ( memcmp ( plaintext, expected_plaintext, len ) == 0 );
 }
+
+/**
+ * Calculate CBC 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 uint8_t random[8192]; /* Too large for stack */
+       uint8_t key[key_len];
+       uint8_t iv[cipher->blocksize];
+       uint8_t ctx[cipher->ctxsize];
+       union profiler profiler;
+       unsigned long long elapsed;
+       unsigned long cost;
+       unsigned int i;
+       int rc;
+
+       /* Fill buffer with pseudo-random data */
+       srand ( 0x1234568 );
+       for ( i = 0 ; i < sizeof ( random ) ; i++ )
+               random[i] = rand();
+       for ( i = 0 ; i < sizeof ( key ) ; i++ )
+               key[i] = rand();
+       for ( i = 0 ; i < sizeof ( iv ) ; i++ )
+               iv[i] = rand();
+
+       /* Initialise cipher */
+       rc = cipher_setkey ( cipher, ctx, key, key_len );
+       assert ( rc == 0 );
+       cipher_setiv ( cipher, ctx, iv );
+
+       /* Time operation */
+       profile ( &profiler );
+       op ( cipher, ctx, random, random, sizeof ( random ) );
+       elapsed = profile ( &profiler );
+
+       /* Round to nearest whole number of cycles per byte */
+       cost = ( ( elapsed + ( sizeof ( random ) / 2 ) ) / sizeof ( random ) );
+
+       return cost;
+}
+
+/**
+ * Calculate CBC 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 );
+}
+
+/**
+ * Calculate CBC 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 );
+}
index 40356cc3e82a4756321fa0e24e7c8b6140cafdb1..ad9e6f341fad1516e1d5f75807c580f66f5381a7 100644 (file)
@@ -15,6 +15,10 @@ 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