Browse Source

[test] Generalise cipher tests and use okx()

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>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
c0be4c6861
5 changed files with 192 additions and 213 deletions
  1. 22
    101
      src/tests/aes_test.c
  2. 0
    57
      src/tests/cbc_test.h
  3. 58
    54
      src/tests/cipher_test.c
  4. 111
    0
      src/tests/cipher_test.h
  5. 1
    1
      src/tests/tests.c

src/tests/aes_cbc_test.c → src/tests/aes_test.c View File

@@ -25,7 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 25
 
26 26
 /** @file
27 27
  *
28
- * AES-in-CBC-mode tests
28
+ * AES tests
29 29
  *
30 30
  * These test vectors are provided by NIST as part of the
31 31
  * Cryptographic Toolkit Examples, downloadable from:
@@ -41,88 +41,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
41 41
 #include <string.h>
42 42
 #include <ipxe/aes.h>
43 43
 #include <ipxe/test.h>
44
-#include "cbc_test.h"
44
+#include "cipher_test.h"
45 45
 
46
-/** Define inline key */
47
-#define KEY(...) { __VA_ARGS__ }
48
-
49
-/** Define inline initialisation vector */
50
-#define IV(...) { __VA_ARGS__ }
51
-
52
-/** Define inline plaintext data */
53
-#define PLAINTEXT(...) { __VA_ARGS__ }
54
-
55
-/** Define inline ciphertext data */
56
-#define CIPHERTEXT(...) { __VA_ARGS__ }
57
-
58
-/** An AES-in-CBC-mode test */
59
-struct aes_cbc_test {
60
-	/** Key */
61
-	const void *key;
62
-	/** Length of key */
63
-	size_t key_len;
64
-	/** Initialisation vector */
65
-	const void *iv;
66
-	/** Length of initialisation vector */
67
-	size_t iv_len;
68
-	/** Plaintext */
69
-	const void *plaintext;
70
-	/** Length of plaintext */
71
-	size_t plaintext_len;
72
-	/** Ciphertext */
73
-	const void *ciphertext;
74
-	/** Length of ciphertext */
75
-	size_t ciphertext_len;
76
-};
77
-
78
-/**
79
- * Define an AES-in-CBC-mode test
80
- *
81
- * @v name		Test name
82
- * @v key_array		Key
83
- * @v iv_array		Initialisation vector
84
- * @v plaintext_array	Plaintext
85
- * @v ciphertext_array	Ciphertext
86
- * @ret test		AES-in-CBC-mode test
87
- */
88
-#define AES_CBC_TEST( name, key_array, iv_array, plaintext_array,	\
89
-		      ciphertext_array )				\
90
-	static const uint8_t name ## _key [] = key_array;		\
91
-	static const uint8_t name ## _iv [] = iv_array;			\
92
-	static const uint8_t name ## _plaintext [] = plaintext_array;	\
93
-	static const uint8_t name ## _ciphertext [] = ciphertext_array;	\
94
-	static struct aes_cbc_test name = {				\
95
-		.key = name ## _key,					\
96
-		.key_len = sizeof ( name ## _key ),			\
97
-		.iv = name ## _iv,					\
98
-		.iv_len = sizeof ( name ## _iv ),			\
99
-		.plaintext = name ## _plaintext,			\
100
-		.plaintext_len = sizeof ( name ## _plaintext ),		\
101
-		.ciphertext = name ## _ciphertext,			\
102
-		.ciphertext_len = sizeof ( name ## _ciphertext ),	\
103
-	}
104
-
105
-/**
106
- * Report AES-in-CBC-mode
107
- *
108
- * @v state		HMAC_DRBG internal state
109
- * @v test		Instantiation test
110
- */
111
-#define aes_cbc_ok( test ) do {						\
112
-	struct cipher_algorithm *cipher = &aes_cbc_algorithm;		\
113
-									\
114
-	assert ( (test)->iv_len == cipher->blocksize );			\
115
-	assert ( (test)->plaintext_len == (test)->ciphertext_len );	\
116
-	cbc_encrypt_ok ( cipher, (test)->key, (test)->key_len,		\
117
-			 (test)->iv, (test)->plaintext,			\
118
-			 (test)->ciphertext, (test)->plaintext_len );	\
119
-	cbc_decrypt_ok ( cipher, (test)->key, (test)->key_len,		\
120
-			 (test)->iv, (test)->ciphertext,		\
121
-			 (test)->plaintext, (test)->ciphertext_len );	\
122
-	} while ( 0 )
123
-
124
-/** CBC_AES128 */
125
-AES_CBC_TEST ( test_128,
46
+/** AES-128-CBC */
47
+CIPHER_TEST ( aes_128_cbc, &aes_cbc_algorithm,
126 48
 	KEY ( 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15,
127 49
 	      0x88, 0x09, 0xcf, 0x4f, 0x3c ),
128 50
 	IV ( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
@@ -144,8 +66,8 @@ AES_CBC_TEST ( test_128,
144 66
 		     0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09,
145 67
 		     0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 ) );
146 68
 
147
-/** CBC_AES256 */
148
-AES_CBC_TEST ( test_256,
69
+/** AES-256-CBC */
70
+CIPHER_TEST ( aes_256_cbc, &aes_cbc_algorithm,
149 71
 	KEY ( 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae,
150 72
 	      0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
151 73
 	      0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 ),
@@ -169,29 +91,28 @@ AES_CBC_TEST ( test_256,
169 91
 		     0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b ) );
170 92
 
171 93
 /**
172
- * Perform AES-in-CBC-mode self-test
94
+ * Perform AES self-test
173 95
  *
174 96
  */
175
-static void aes_cbc_test_exec ( void ) {
176
-	struct cipher_algorithm *cipher = &aes_cbc_algorithm;
97
+static void aes_test_exec ( void ) {
98
+	struct cipher_algorithm *cbc = &aes_cbc_algorithm;
99
+	unsigned int keylen;
177 100
 
178 101
 	/* Correctness tests */
179
-	aes_cbc_ok ( &test_128 );
180
-	aes_cbc_ok ( &test_256 );
102
+	cipher_ok ( &aes_128_cbc );
103
+	cipher_ok ( &aes_256_cbc );
181 104
 
182 105
 	/* Speed tests */
183
-	DBG ( "AES128 encryption required %ld cycles per byte\n",
184
-	      cbc_cost_encrypt ( cipher, test_128.key_len ) );
185
-	DBG ( "AES128 decryption required %ld cycles per byte\n",
186
-	      cbc_cost_decrypt ( cipher, test_128.key_len ) );
187
-	DBG ( "AES256 encryption required %ld cycles per byte\n",
188
-	      cbc_cost_encrypt ( cipher, test_256.key_len ) );
189
-	DBG ( "AES256 decryption required %ld cycles per byte\n",
190
-	      cbc_cost_decrypt ( cipher, test_256.key_len ) );
106
+	for ( keylen = 128 ; keylen <= 256 ; keylen += 128 ) {
107
+		DBG ( "AES-%d-CBC encryption required %ld cycles per byte\n",
108
+		      keylen, cipher_cost_encrypt ( cbc, ( keylen / 8 ) ) );
109
+		DBG ( "AES-%d-CBC decryption required %ld cycles per byte\n",
110
+		      keylen, cipher_cost_decrypt ( cbc, ( keylen / 8 ) ) );
111
+	}
191 112
 }
192 113
 
193
-/** AES-in-CBC-mode self-test */
194
-struct self_test aes_cbc_test __self_test = {
195
-	.name = "aes_cbc",
196
-	.exec = aes_cbc_test_exec,
114
+/** AES self-test */
115
+struct self_test aes_test __self_test = {
116
+	.name = "aes",
117
+	.exec = aes_test_exec,
197 118
 };

+ 0
- 57
src/tests/cbc_test.h View File

@@ -1,57 +0,0 @@
1
-#ifndef _CBC_TEST_H
2
-#define _CBC_TEST_H
3
-
4
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
5
-
6
-#include <stdint.h>
7
-#include <ipxe/crypto.h>
8
-#include <ipxe/test.h>
9
-
10
-extern int cbc_test_encrypt ( struct cipher_algorithm *cipher, const void *key,
11
-			      size_t key_len, const void *iv,
12
-			      const void *plaintext,
13
-			      const void *expected_ciphertext, size_t len );
14
-extern int cbc_test_decrypt ( struct cipher_algorithm *cipher, const void *key,
15
-			      size_t key_len, const void *iv,
16
-			      const void *ciphertext,
17
-			      const void *expected_plaintext, size_t len );
18
-extern unsigned long cbc_cost_encrypt ( struct cipher_algorithm *cipher,
19
-					size_t key_len );
20
-extern unsigned long cbc_cost_decrypt ( struct cipher_algorithm *cipher,
21
-					size_t key_len );
22
-
23
-/**
24
- * Report CBC encryption test result
25
- *
26
- * @v cipher			Cipher algorithm
27
- * @v key			Key
28
- * @v key_len			Length of key
29
- * @v iv			Initialisation vector
30
- * @v plaintext			Plaintext data
31
- * @v expected_ciphertext	Expected ciphertext data
32
- * @v len			Length of data
33
- */
34
-#define cbc_encrypt_ok( cipher, key, key_len, iv, plaintext,		\
35
-			expected_ciphertext, len ) do {			\
36
-	ok ( cbc_test_encrypt ( cipher, key, key_len, iv, plaintext,	\
37
-				expected_ciphertext, len ) );		\
38
-	} while ( 0 )
39
-
40
-/**
41
- * Report CBC decryption test result
42
- *
43
- * @v cipher			Cipher algorithm
44
- * @v key			Key
45
- * @v key_len			Length of key
46
- * @v iv			Initialisation vector
47
- * @v ciphertext		Ciphertext data
48
- * @v expected_plaintext	Expected plaintext data
49
- * @v len			Length of data
50
- */
51
-#define cbc_decrypt_ok( cipher, key, key_len, iv, ciphertext,		\
52
-			expected_plaintext, len ) do {			\
53
-	ok ( cbc_test_decrypt ( cipher, key, key_len, iv, ciphertext,	\
54
-				expected_plaintext, len ) );		\
55
-	} while ( 0 )
56
-
57
-#endif /* _CBC_TEST_H */

src/tests/cbc_test.c → src/tests/cipher_test.c View File

@@ -25,7 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 25
 
26 26
 /** @file
27 27
  *
28
- * CBC self-tests
28
+ * Cipher self-tests
29 29
  *
30 30
  */
31 31
 
@@ -38,86 +38,90 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
38 38
 #include <assert.h>
39 39
 #include <ipxe/crypto.h>
40 40
 #include <ipxe/profile.h>
41
-#include "cbc_test.h"
41
+#include <ipxe/test.h>
42
+#include "cipher_test.h"
42 43
 
43 44
 /** Number of sample iterations for profiling */
44 45
 #define PROFILE_COUNT 16
45 46
 
46 47
 /**
47
- * Test CBC encryption
48
+ * Report a cipher encryption test result
48 49
  *
49
- * @v cipher			Cipher algorithm
50
- * @v key			Key
51
- * @v key_len			Length of key
52
- * @v iv			Initialisation vector
53
- * @v plaintext			Plaintext data
54
- * @v expected_ciphertext	Expected ciphertext data
55
- * @v len			Length of data
56
- * @ret ok			Ciphertext is as expected
50
+ * @v test		Cipher test
51
+ * @v file		Test code file
52
+ * @v line		Test code line
57 53
  */
58
-int cbc_test_encrypt ( struct cipher_algorithm *cipher, const void *key,
59
-		       size_t key_len, const void *iv, const void *plaintext,
60
-		       const void *expected_ciphertext, size_t len ) {
54
+void cipher_encrypt_okx ( struct cipher_test *test, const char *file,
55
+			  unsigned int line ) {
56
+	struct cipher_algorithm *cipher = test->cipher;
57
+	size_t len = test->len;
61 58
 	uint8_t ctx[cipher->ctxsize];
62 59
 	uint8_t ciphertext[len];
63
-	int rc;
64 60
 
65 61
 	/* Initialise cipher */
66
-	rc = cipher_setkey ( cipher, ctx, key, key_len );
67
-	assert ( rc == 0 );
68
-	cipher_setiv ( cipher, ctx, iv );
62
+	okx ( cipher_setkey ( cipher, ctx, test->key, test->key_len ) == 0,
63
+	      file, line );
64
+	cipher_setiv ( cipher, ctx, test->iv );
69 65
 
70 66
 	/* Perform encryption */
71
-	cipher_encrypt ( cipher, ctx, plaintext, ciphertext, len );
67
+	cipher_encrypt ( cipher, ctx, test->plaintext, ciphertext, len );
72 68
 
73
-	/* Verify result */
74
-	return ( memcmp ( ciphertext, expected_ciphertext, len ) == 0 );
69
+	/* Compare against expected ciphertext */
70
+	okx ( memcmp ( ciphertext, test->ciphertext, len ) == 0, file, line );
75 71
 }
76 72
 
77 73
 /**
78
- * Test CBC decryption
74
+ * Report a cipher decryption test result
79 75
  *
80
- * @v cipher			Cipher algorithm
81
- * @v key			Key
82
- * @v key_len			Length of key
83
- * @v iv			Initialisation vector
84
- * @v ciphertext		Ciphertext data
85
- * @v expected_plaintext	Expected plaintext data
86
- * @v len			Length of data
87
- * @ret ok			Plaintext is as expected
76
+ * @v test		Cipher test
77
+ * @v file		Test code file
78
+ * @v line		Test code line
88 79
  */
89
-int cbc_test_decrypt ( struct cipher_algorithm *cipher, const void *key,
90
-		       size_t key_len, const void *iv, const void *ciphertext,
91
-		       const void *expected_plaintext, size_t len ) {
80
+void cipher_decrypt_okx ( struct cipher_test *test, const char *file,
81
+			  unsigned int line ) {
82
+	struct cipher_algorithm *cipher = test->cipher;
83
+	size_t len = test->len;
92 84
 	uint8_t ctx[cipher->ctxsize];
93 85
 	uint8_t plaintext[len];
94
-	int rc;
95 86
 
96 87
 	/* Initialise cipher */
97
-	rc = cipher_setkey ( cipher, ctx, key, key_len );
98
-	assert ( rc == 0 );
99
-	cipher_setiv ( cipher, ctx, iv );
88
+	okx ( cipher_setkey ( cipher, ctx, test->key, test->key_len ) == 0,
89
+	      file, line );
90
+	cipher_setiv ( cipher, ctx, test->iv );
100 91
 
101 92
 	/* Perform encryption */
102
-	cipher_decrypt ( cipher, ctx, ciphertext, plaintext, len );
93
+	cipher_decrypt ( cipher, ctx, test->ciphertext, plaintext, len );
94
+
95
+	/* Compare against expected plaintext */
96
+	okx ( memcmp ( plaintext, test->plaintext, len ) == 0, file, line );
97
+}
98
+
99
+/**
100
+ * Report a cipher encryption and decryption test result
101
+ *
102
+ * @v test		Cipher test
103
+ * @v file		Test code file
104
+ * @v line		Test code line
105
+ */
106
+void cipher_okx ( struct cipher_test *test, const char *file,
107
+		  unsigned int line ) {
103 108
 
104
-	/* Verify result */
105
-	return ( memcmp ( plaintext, expected_plaintext, len ) == 0 );
109
+	cipher_encrypt_okx ( test, file, line );
110
+	cipher_decrypt_okx ( test, file, line );
106 111
 }
107 112
 
108 113
 /**
109
- * Calculate CBC encryption or decryption cost
114
+ * Calculate cipher encryption or decryption cost
110 115
  *
111 116
  * @v cipher			Cipher algorithm
112 117
  * @v key_len			Length of key
113 118
  * @v op			Encryption or decryption operation
114 119
  * @ret cost			Cost (in cycles per byte)
115 120
  */
116
-static unsigned long cbc_cost ( struct cipher_algorithm *cipher,
117
-				size_t key_len,
118
-				void ( * op ) ( struct cipher_algorithm *cipher,
119
-						void *ctx, const void *src,
120
-						void *dst, size_t len ) ) {
121
+static unsigned long
122
+cipher_cost ( struct cipher_algorithm *cipher, size_t key_len,
123
+	      void ( * op ) ( struct cipher_algorithm *cipher, void *ctx,
124
+			      const void *src, void *dst, size_t len ) ) {
121 125
 	static uint8_t random[8192]; /* Too large for stack */
122 126
 	uint8_t key[key_len];
123 127
 	uint8_t iv[cipher->blocksize];
@@ -157,25 +161,25 @@ static unsigned long cbc_cost ( struct cipher_algorithm *cipher,
157 161
 }
158 162
 
159 163
 /**
160
- * Calculate CBC encryption cost
164
+ * Calculate cipher encryption cost
161 165
  *
162 166
  * @v cipher			Cipher algorithm
163 167
  * @v key_len			Length of key
164 168
  * @ret cost			Cost (in cycles per byte)
165 169
  */
166
-unsigned long cbc_cost_encrypt ( struct cipher_algorithm *cipher,
167
-				 size_t key_len ) {
168
-	return cbc_cost ( cipher, key_len, cipher_encrypt );
170
+unsigned long cipher_cost_encrypt ( struct cipher_algorithm *cipher,
171
+				    size_t key_len ) {
172
+	return cipher_cost ( cipher, key_len, cipher_encrypt );
169 173
 }
170 174
 
171 175
 /**
172
- * Calculate CBC decryption cost
176
+ * Calculate cipher decryption cost
173 177
  *
174 178
  * @v cipher			Cipher algorithm
175 179
  * @v key_len			Length of key
176 180
  * @ret cost			Cost (in cycles per byte)
177 181
  */
178
-unsigned long cbc_cost_decrypt ( struct cipher_algorithm *cipher,
179
-				 size_t key_len ) {
180
-	return cbc_cost ( cipher, key_len, cipher_decrypt );
182
+unsigned long cipher_cost_decrypt ( struct cipher_algorithm *cipher,
183
+				    size_t key_len ) {
184
+	return cipher_cost ( cipher, key_len, cipher_decrypt );
181 185
 }

+ 111
- 0
src/tests/cipher_test.h View File

@@ -0,0 +1,111 @@
1
+#ifndef _CIPHER_TEST_H
2
+#define _CIPHER_TEST_H
3
+
4
+/** @file
5
+ *
6
+ * Cipher self-tests
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
+
12
+#include <stdint.h>
13
+#include <ipxe/crypto.h>
14
+#include <ipxe/test.h>
15
+
16
+/** A cipher test */
17
+struct cipher_test {
18
+	/** Cipher algorithm */
19
+	struct cipher_algorithm *cipher;
20
+	/** Key */
21
+	const void *key;
22
+	/** Length of key */
23
+	size_t key_len;
24
+	/** Initialisation vector */
25
+	const void *iv;
26
+	/** Length of initialisation vector */
27
+	size_t iv_len;
28
+	/** Plaintext */
29
+	const void *plaintext;
30
+	/** Ciphertext */
31
+	const void *ciphertext;
32
+	/** Length of text */
33
+	size_t len;
34
+};
35
+
36
+/** Define inline key */
37
+#define KEY(...) { __VA_ARGS__ }
38
+
39
+/** Define inline initialisation vector */
40
+#define IV(...) { __VA_ARGS__ }
41
+
42
+/** Define inline plaintext data */
43
+#define PLAINTEXT(...) { __VA_ARGS__ }
44
+
45
+/** Define inline ciphertext data */
46
+#define CIPHERTEXT(...) { __VA_ARGS__ }
47
+
48
+/**
49
+ * Define a cipher test
50
+ *
51
+ * @v name		Test name
52
+ * @v CIPHER		Cipher algorithm
53
+ * @v KEY		Key
54
+ * @v IV		Initialisation vector
55
+ * @v PLAINTEXT		Plaintext
56
+ * @v CIPHERTEXT	Ciphertext
57
+ * @ret test		Cipher test
58
+ */
59
+#define CIPHER_TEST( name, CIPHER, KEY, IV, PLAINTEXT, CIPHERTEXT )	\
60
+	static const uint8_t name ## _key [] = KEY;			\
61
+	static const uint8_t name ## _iv [] = IV;			\
62
+	static const uint8_t name ## _plaintext [] = PLAINTEXT;		\
63
+	static const uint8_t name ## _ciphertext			\
64
+		[ sizeof ( name ## _plaintext ) ] = CIPHERTEXT;		\
65
+	static struct cipher_test name = {				\
66
+		.cipher = CIPHER,					\
67
+		.key = name ## _key,					\
68
+		.key_len = sizeof ( name ## _key ),			\
69
+		.iv = name ## _iv,					\
70
+		.iv_len = sizeof ( name ## _iv ),			\
71
+		.plaintext = name ## _plaintext,			\
72
+		.ciphertext = name ## _ciphertext,			\
73
+		.len = sizeof ( name ## _plaintext ),			\
74
+	}
75
+
76
+extern void cipher_encrypt_okx ( struct cipher_test *test, const char *file,
77
+				 unsigned int line );
78
+extern void cipher_decrypt_okx ( struct cipher_test *test, const char *file,
79
+				 unsigned int line );
80
+extern void cipher_okx ( struct cipher_test *test, const char *file,
81
+			 unsigned int line );
82
+extern unsigned long cipher_cost_encrypt ( struct cipher_algorithm *cipher,
83
+					   size_t key_len );
84
+extern unsigned long cipher_cost_decrypt ( struct cipher_algorithm *cipher,
85
+					   size_t key_len );
86
+
87
+/**
88
+ * Report a cipher encryption test result
89
+ *
90
+ * @v test		Cipher test
91
+ */
92
+#define cipher_encrypt_ok( test ) \
93
+	cipher_encrypt_okx ( test, __FILE__, __LINE__ )
94
+
95
+/**
96
+ * Report a cipher decryption test result
97
+ *
98
+ * @v test		Cipher test
99
+ */
100
+#define cipher_decrypt_ok( test ) \
101
+	cipher_decrypt_okx ( test, __FILE__, __LINE__ )
102
+
103
+/**
104
+ * Report a cipher encryption and decryption test result
105
+ *
106
+ * @v test		Cipher test
107
+ */
108
+#define cipher_ok( test ) \
109
+	cipher_okx ( test, __FILE__, __LINE__ )
110
+
111
+#endif /* _CIPHER_TEST_H */

+ 1
- 1
src/tests/tests.c View File

@@ -50,7 +50,7 @@ REQUIRE_OBJECT ( md5_test );
50 50
 REQUIRE_OBJECT ( sha1_test );
51 51
 REQUIRE_OBJECT ( sha256_test );
52 52
 REQUIRE_OBJECT ( sha512_test );
53
-REQUIRE_OBJECT ( aes_cbc_test );
53
+REQUIRE_OBJECT ( aes_test );
54 54
 REQUIRE_OBJECT ( hmac_drbg_test );
55 55
 REQUIRE_OBJECT ( hash_df_test );
56 56
 REQUIRE_OBJECT ( bigint_test );

Loading…
Cancel
Save