Преглед на файлове

[test] Add NIST self-tests for AES128 and AES256 in CBC mode

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown преди 12 години
родител
ревизия
1f238bc69e
променени са 4 файла, в които са добавени 330 реда и са изтрити 0 реда
  1. 180
    0
      src/tests/aes_cbc_test.c
  2. 96
    0
      src/tests/cbc_test.c
  3. 53
    0
      src/tests/cbc_test.h
  4. 1
    0
      src/tests/tests.c

+ 180
- 0
src/tests/aes_cbc_test.c Целия файл

@@ -0,0 +1,180 @@
1
+/*
2
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+/** @file
22
+ *
23
+ * AES-in-CBC-mode tests
24
+ *
25
+ * These test vectors are provided by NIST as part of the
26
+ * Cryptographic Toolkit Examples, downloadable from:
27
+ *
28
+ *    http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CBC.pdf
29
+ *
30
+ */
31
+
32
+/* Forcibly enable assertions */
33
+#undef NDEBUG
34
+
35
+#include <assert.h>
36
+#include <string.h>
37
+#include <ipxe/aes.h>
38
+#include <ipxe/test.h>
39
+#include "cbc_test.h"
40
+
41
+/** Define inline key */
42
+#define KEY(...) { __VA_ARGS__ }
43
+
44
+/** Define inline initialisation vector */
45
+#define IV(...) { __VA_ARGS__ }
46
+
47
+/** Define inline plaintext data */
48
+#define PLAINTEXT(...) { __VA_ARGS__ }
49
+
50
+/** Define inline ciphertext data */
51
+#define CIPHERTEXT(...) { __VA_ARGS__ }
52
+
53
+/** An AES-in-CBC-mode test */
54
+struct aes_cbc_test {
55
+	/** Key */
56
+	const void *key;
57
+	/** Length of key */
58
+	size_t key_len;
59
+	/** Initialisation vector */
60
+	const void *iv;
61
+	/** Length of initialisation vector */
62
+	size_t iv_len;
63
+	/** Plaintext */
64
+	const void *plaintext;
65
+	/** Length of plaintext */
66
+	size_t plaintext_len;
67
+	/** Ciphertext */
68
+	const void *ciphertext;
69
+	/** Length of ciphertext */
70
+	size_t ciphertext_len;
71
+};
72
+
73
+/**
74
+ * Define an AES-in-CBC-mode test
75
+ *
76
+ * @v name		Test name
77
+ * @v key_array		Key
78
+ * @v iv_array		Initialisation vector
79
+ * @v plaintext_array	Plaintext
80
+ * @v ciphertext_array	Ciphertext
81
+ * @ret test		AES-in-CBC-mode test
82
+ */
83
+#define AES_CBC_TEST( name, key_array, iv_array, plaintext_array,	\
84
+		      ciphertext_array )				\
85
+	static const uint8_t name ## _key [] = key_array;		\
86
+	static const uint8_t name ## _iv [] = iv_array;			\
87
+	static const uint8_t name ## _plaintext [] = plaintext_array;	\
88
+	static const uint8_t name ## _ciphertext [] = ciphertext_array;	\
89
+	static const struct aes_cbc_test name = {			\
90
+		.key = name ## _key,					\
91
+		.key_len = sizeof ( name ## _key ),			\
92
+		.iv = name ## _iv,					\
93
+		.iv_len = sizeof ( name ## _iv ),			\
94
+		.plaintext = name ## _plaintext,			\
95
+		.plaintext_len = sizeof ( name ## _plaintext ),		\
96
+		.ciphertext = name ## _ciphertext,			\
97
+		.ciphertext_len = sizeof ( name ## _ciphertext ),	\
98
+	}
99
+
100
+/**
101
+ * Report AES-in-CBC-mode
102
+ *
103
+ * @v state		HMAC_DRBG internal state
104
+ * @v test		Instantiation test
105
+ */
106
+#define aes_cbc_ok( test ) do {						\
107
+	struct cipher_algorithm *cipher = &aes_cbc_algorithm;		\
108
+									\
109
+	assert ( (test)->iv_len == cipher->blocksize );			\
110
+	assert ( (test)->plaintext_len == (test)->ciphertext_len );	\
111
+	cbc_encrypt_ok ( cipher, (test)->key, (test)->key_len,		\
112
+			 (test)->iv, (test)->plaintext,			\
113
+			 (test)->ciphertext, (test)->plaintext_len );	\
114
+	cbc_decrypt_ok ( cipher, (test)->key, (test)->key_len,		\
115
+			 (test)->iv, (test)->ciphertext,		\
116
+			 (test)->plaintext, (test)->ciphertext_len );	\
117
+	} while ( 0 )
118
+
119
+/** CBC_AES128 */
120
+AES_CBC_TEST ( test_128,
121
+	KEY ( 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15,
122
+	      0x88, 0x09, 0xcf, 0x4f, 0x3c ),
123
+	IV ( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
124
+	     0x0b, 0x0c, 0x0d, 0x0e, 0x0f ),
125
+	PLAINTEXT ( 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
126
+		    0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
127
+		    0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
128
+		    0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
129
+		    0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
130
+		    0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
131
+		    0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
132
+		    0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 ),
133
+	CIPHERTEXT ( 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
134
+		     0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
135
+		     0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee,
136
+		     0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
137
+		     0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b,
138
+		     0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
139
+		     0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09,
140
+		     0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 ) );
141
+
142
+/** CBC_AES256 */
143
+AES_CBC_TEST ( test_256,
144
+	KEY ( 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae,
145
+	      0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
146
+	      0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 ),
147
+	IV ( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
148
+	     0x0b, 0x0c, 0x0d, 0x0e, 0x0f ),
149
+	PLAINTEXT ( 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
150
+		    0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
151
+		    0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
152
+		    0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
153
+		    0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
154
+		    0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
155
+		    0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
156
+		    0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 ),
157
+	CIPHERTEXT ( 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
158
+		     0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
159
+		     0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
160
+		     0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
161
+		     0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
162
+		     0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
163
+		     0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
164
+		     0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b ) );
165
+
166
+/**
167
+ * Perform AES-in-CBC-mode self-test
168
+ *
169
+ */
170
+static void aes_cbc_test_exec ( void ) {
171
+
172
+	aes_cbc_ok ( &test_128 );
173
+	aes_cbc_ok ( &test_256 );
174
+}
175
+
176
+/** AES-in-CBC-mode self-test */
177
+struct self_test aes_cbc_test __self_test = {
178
+	.name = "aes_cbc",
179
+	.exec = aes_cbc_test_exec,
180
+};

+ 96
- 0
src/tests/cbc_test.c Целия файл

@@ -0,0 +1,96 @@
1
+/*
2
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+/** @file
22
+ *
23
+ * CBC self-tests
24
+ *
25
+ */
26
+
27
+/* Forcibly enable assertions */
28
+#undef NDEBUG
29
+
30
+#include <stdint.h>
31
+#include <string.h>
32
+#include <assert.h>
33
+#include <ipxe/crypto.h>
34
+#include "cbc_test.h"
35
+
36
+/**
37
+ * Test CBC encryption
38
+ *
39
+ * @v cipher			Cipher algorithm
40
+ * @v key			Key
41
+ * @v key_len			Length of key
42
+ * @v iv			Initialisation vector
43
+ * @v plaintext			Plaintext data
44
+ * @v expected_ciphertext	Expected ciphertext data
45
+ * @v len			Length of data
46
+ * @ret ok			Ciphertext is as expected
47
+ */
48
+int cbc_test_encrypt ( struct cipher_algorithm *cipher, const void *key,
49
+		       size_t key_len, const void *iv, const void *plaintext,
50
+		       const void *expected_ciphertext, size_t len ) {
51
+	uint8_t ctx[ cipher->ctxsize ];
52
+	uint8_t ciphertext[ len ];
53
+	int rc;
54
+
55
+	/* Initialise cipher */
56
+	rc = cipher_setkey ( cipher, ctx, key, key_len );
57
+	assert ( rc == 0 );
58
+	cipher_setiv ( cipher, ctx, iv );
59
+
60
+	/* Perform encryption */
61
+	cipher_encrypt ( cipher, ctx, plaintext, ciphertext, len );
62
+
63
+	/* Verify result */
64
+	return ( memcmp ( ciphertext, expected_ciphertext, len ) == 0 );
65
+}
66
+
67
+/**
68
+ * Test CBC decryption
69
+ *
70
+ * @v cipher			Cipher algorithm
71
+ * @v key			Key
72
+ * @v key_len			Length of key
73
+ * @v iv			Initialisation vector
74
+ * @v ciphertext		Ciphertext data
75
+ * @v expected_plaintext	Expected plaintext data
76
+ * @v len			Length of data
77
+ * @ret ok			Plaintext is as expected
78
+ */
79
+int cbc_test_decrypt ( struct cipher_algorithm *cipher, const void *key,
80
+		       size_t key_len, const void *iv, const void *ciphertext,
81
+		       const void *expected_plaintext, size_t len ) {
82
+	uint8_t ctx[ cipher->ctxsize ];
83
+	uint8_t plaintext[ len ];
84
+	int rc;
85
+
86
+	/* Initialise cipher */
87
+	rc = cipher_setkey ( cipher, ctx, key, key_len );
88
+	assert ( rc == 0 );
89
+	cipher_setiv ( cipher, ctx, iv );
90
+
91
+	/* Perform encryption */
92
+	cipher_decrypt ( cipher, ctx, ciphertext, plaintext, len );
93
+
94
+	/* Verify result */
95
+	return ( memcmp ( plaintext, expected_plaintext, len ) == 0 );
96
+}

+ 53
- 0
src/tests/cbc_test.h Целия файл

@@ -0,0 +1,53 @@
1
+#ifndef _CBC_TEST_H
2
+#define _CBC_TEST_H
3
+
4
+FILE_LICENCE ( GPL2_OR_LATER );
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
+
19
+/**
20
+ * Report CBC encryption test result
21
+ *
22
+ * @v cipher			Cipher algorithm
23
+ * @v key			Key
24
+ * @v key_len			Length of key
25
+ * @v iv			Initialisation vector
26
+ * @v plaintext			Plaintext data
27
+ * @v expected_ciphertext	Expected ciphertext data
28
+ * @v len			Length of data
29
+ */
30
+#define cbc_encrypt_ok( cipher, key, key_len, iv, plaintext,		\
31
+			expected_ciphertext, len ) do {			\
32
+	ok ( cbc_test_encrypt ( cipher, key, key_len, iv, plaintext,	\
33
+				expected_ciphertext, len ) );		\
34
+	} while ( 0 )
35
+
36
+/**
37
+ * Report CBC decryption test result
38
+ *
39
+ * @v cipher			Cipher algorithm
40
+ * @v key			Key
41
+ * @v key_len			Length of key
42
+ * @v iv			Initialisation vector
43
+ * @v ciphertext		Ciphertext data
44
+ * @v expected_plaintext	Expected plaintext data
45
+ * @v len			Length of data
46
+ */
47
+#define cbc_decrypt_ok( cipher, key, key_len, iv, ciphertext,		\
48
+			expected_plaintext, len ) do {			\
49
+	ok ( cbc_test_decrypt ( cipher, key, key_len, iv, ciphertext,	\
50
+				expected_plaintext, len ) );		\
51
+	} while ( 0 )
52
+
53
+#endif /* _CBC_TEST_H */

+ 1
- 0
src/tests/tests.c Целия файл

@@ -30,5 +30,6 @@ REQUIRE_OBJECT ( byteswap_test );
30 30
 REQUIRE_OBJECT ( md5_test );
31 31
 REQUIRE_OBJECT ( sha1_test );
32 32
 REQUIRE_OBJECT ( sha256_test );
33
+REQUIRE_OBJECT ( aes_cbc_test );
33 34
 REQUIRE_OBJECT ( hmac_drbg_test );
34 35
 REQUIRE_OBJECT ( hash_df_test );

Loading…
Отказ
Запис