blob: 41617c2f4a0b80a458bfe7cea5d3609779d25790 [file] [log] [blame]
Andrey Andreev912831f2014-02-04 17:21:37 +02001<?php
2
3class Encryption_test extends CI_TestCase {
4
5 public function set_up()
6 {
Andrey Andreev50ccc382014-02-04 23:30:06 +02007 $this->ci_set_config('encryption_key', "\xd0\xc9\x08\xc4\xde\x52\x12\x6e\xf8\xcc\xdb\x03\xea\xa0\x3a\x5c");
Andrey Andreev912831f2014-02-04 17:21:37 +02008 $this->encryption = new CI_Encryption();
9 $this->ci_instance_var('encryption', $this->encryption);
10 }
11
12 // --------------------------------------------------------------------
13
Andrey Andreev50ccc382014-02-04 23:30:06 +020014 public function test_portability()
15 {
16 if ( ! $this->encryption->drivers['mcrypt'] OR ! $this->encryption->drivers['openssl'])
17 {
18 $this->markTestAsSkipped('Both MCrypt and OpenSSL support are required for portability tests.');
19 return;
20 }
21
22 $message = 'This is a message encrypted via MCrypt and decrypted via OpenSSL, or vice-versa.';
23
Andrey Andreevf4017672014-02-05 18:51:15 +020024 // Format is: <Cipher name>, <Cipher mode>, <Key size>
Andrey Andreev50ccc382014-02-04 23:30:06 +020025 $portable = array(
Andrey Andreevf4017672014-02-05 18:51:15 +020026 array('aes-128', 'cbc', 16),
27 array('aes-128', 'cfb', 16),
28 array('aes-128', 'cfb8', 16),
29 array('aes-128', 'ofb', 16),
30 array('aes-128', 'ecb', 16),
31 array('aes-128', 'ctr', 16),
32 array('aes-192', 'cbc', 24),
33 array('aes-192', 'cfb', 24),
34 array('aes-192', 'cfb8', 24),
35 array('aes-192', 'ofb', 24),
36 array('aes-192', 'ecb', 24),
37 array('aes-192', 'ctr', 24),
38 array('aes-256', 'cbc', 32),
39 array('aes-256', 'cfb', 32),
40 array('aes-256', 'cfb8', 32),
41 array('aes-256', 'ofb', 32),
42 array('aes-256', 'ecb', 32),
43 array('aes-256', 'ctr', 32),
44 array('des', 'cbc', 7),
45 array('des', 'cfb', 7),
46 array('des', 'cfb8', 7),
47 array('des', 'ofb', 7),
48 array('des', 'ecb', 7),
49 array('tripledes', 'cbc', 7),
50 array('tripledes', 'cfb', 7),
51 array('tripledes', 'cfb8', 7),
52 array('tripledes', 'ofb', 7),
53 array('tripledes', 'cbc', 14),
54 array('tripledes', 'cfb', 14),
55 array('tripledes', 'cfb8', 14),
56 array('tripledes', 'ofb', 14),
57 array('tripledes', 'cbc', 21),
58 array('tripledes', 'cfb', 21),
59 array('tripledes', 'cfb8', 21),
60 array('tripledes', 'ofb', 21),
61 array('blowfish', 'cbc', 16),
62 array('blowfish', 'cfb', 16),
63 array('blowfish', 'ofb', 16),
64 array('blowfish', 'ecb', 16),
65 array('blowfish', 'cbc', 56),
66 array('blowfish', 'cfb', 56),
67 array('blowfish', 'ofb', 56),
68 array('blowfish', 'ecb', 56),
Andrey Andreeve8088d62014-02-06 05:01:48 +020069 array('cast5', 'cbc', 5),
70 array('cast5', 'cfb', 5),
71 array('cast5', 'ofb', 5),
72 array('cast5', 'ecb', 5),
73 array('cast5', 'cbc', 8),
74 array('cast5', 'cfb', 8),
75 array('cast5', 'ofb', 8),
76 array('cast5', 'ecb', 8),
77 array('cast5', 'cbc', 10),
78 array('cast5', 'cfb', 10),
79 array('cast5', 'ofb', 10),
80 array('cast5', 'ecb', 10),
81 array('cast5', 'cbc', 16),
82 array('cast5', 'cfb', 16),
83 array('cast5', 'ofb', 16),
84 array('cast5', 'ecb', 16),
85 array('rc4', 'stream', 5),
86 array('rc4', 'stream', 8),
87 array('rc4', 'stream', 16),
88 array('rc4', 'stream', 32),
89 array('rc4', 'stream', 64),
90 array('rc4', 'stream', 128),
91 array('rc4', 'stream', 256)
Andrey Andreev50ccc382014-02-04 23:30:06 +020092 );
93 $driver_index = array('mcrypt', 'openssl');
94
95 foreach ($portable as &$test)
96 {
97 // Add some randomness to the selected driver
98 $driver = mt_rand(0,1);
99 $params = array(
Andrey Andreev8d33a9a2014-02-05 23:11:23 +0200100 'driver' => $driver_index[$driver],
Andrey Andreevf4017672014-02-05 18:51:15 +0200101 'cipher' => $test[0],
102 'mode' => $test[1],
Andrey Andreev50ccc382014-02-04 23:30:06 +0200103 'key' => openssl_random_pseudo_bytes($test[2])
104 );
105
Andrey Andreev8d33a9a2014-02-05 23:11:23 +0200106 $this->encryption->initialize($params);
107 $ciphertext = $this->encryption->encrypt($message);
Andrey Andreev50ccc382014-02-04 23:30:06 +0200108
109 $driver = (int) ! $driver;
Andrey Andreev8d33a9a2014-02-05 23:11:23 +0200110 $params['driver'] = $driver_index[$driver];
Andrey Andreev50ccc382014-02-04 23:30:06 +0200111
Andrey Andreev8d33a9a2014-02-05 23:11:23 +0200112 $this->encryption->initialize($params);
113 $this->assertEquals($message, $this->encryption->decrypt($ciphertext));
Andrey Andreev50ccc382014-02-04 23:30:06 +0200114 }
115 }
116
117 // --------------------------------------------------------------------
118
Andrey Andreev912831f2014-02-04 17:21:37 +0200119 public function test_hkdf()
120 {
121 // Test vectors are described in RFC5869, Appendix A(1-3).
122 // Vectors 4-7 cover SHA-1, which we don't support.
123 //
124 // URL: https://tools.ietf.org/rfc/rfc5869.txt
125 //
126 // Our implementation doesn't split into hkdf_extract(), hkdf_expand()
127 // and therefore we can't test for the PRK value (it is included below
128 // just for consistency, hence why it's also commented out).
129 //
130 // As long as OKM is correct, then we're all fine though.
131 $vectors = array(
132 // Appendix A.1: Basic test case with SHA-256
133 array(
134 'digest' => 'sha256',
135 'ikm' => "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
136 'salt' => "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c",
137 'length' => 42,
138 'info' => "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9",
139// 'prk' => "\x07\x77\x09\x36\x2c\x2e\x32\xdf\x0d\xdc\x3f\x0d\xc4\x7b\xba\x63\x90\xb6\xc7\x3b\xb5\x0f\x9c\x31\x22\xec\x84\x4a\xd7\xc2\xb3\xe5",
140 'okm' => "\x3c\xb2\x5f\x25\xfa\xac\xd5\x7a\x90\x43\x4f\x64\xd0\x36\x2f\x2a\x2d\x2d\x0a\x90\xcf\x1a\x5a\x4c\x5d\xb0\x2d\x56\xec\xc4\xc5\xbf\x34\x00\x72\x08\xd5\xb8\x87\x18\x58\x65"
141 ),
142 // Appendix A.2: Test with SHA-256 and longer inputs/outputs
143 array(
144 'digest' => 'sha256',
145 'ikm' => "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f",
146 'salt' => "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf",
147 'length' => 82,
148 'info' => "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
149// 'prk' => "\x06\xa6\xb8\x8c\x58\x53\x36\x1a\x06\x10\x4c\x9c\xeb\x35\xb4\x5c\xef\x76\x00\x14\x90\x46\x71\x01\x4a\x19\x3f\x40\xc1\x5f\xc2\x44",
150 'okm' => "\xb1\x1e\x39\x8d\xc8\x03\x27\xa1\xc8\xe7\xf7\x8c\x59\x6a\x49\x34\x4f\x01\x2e\xda\x2d\x4e\xfa\xd8\xa0\x50\xcc\x4c\x19\xaf\xa9\x7c\x59\x04\x5a\x99\xca\xc7\x82\x72\x71\xcb\x41\xc6\x5e\x59\x0e\x09\xda\x32\x75\x60\x0c\x2f\x09\xb8\x36\x77\x93\xa9\xac\xa3\xdb\x71\xcc\x30\xc5\x81\x79\xec\x3e\x87\xc1\x4c\x01\xd5\xc1\xf3\x43\x4f\x1d\x87",
151 ),
152 // Appendix A.3: Test with SHA-256 and zero-length salt/info
153 array(
154 'digest' => 'sha256',
155 'ikm' => "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
156 'salt' => "",
157 'length' => 42,
158 'info' => "",
159// 'prk' => "\x19\xef\x24\xa3\x2c\x71\x7b\x16\x7f\x33\xa9\x1d\x6f\x64\x8b\xdf\x96\x59\x67\x76\xaf\xdb\x63\x77\xac\x43\x4c\x1c\x29\x3c\xcb\x04",
160 'okm' => "\x8d\xa4\xe7\x75\xa5\x63\xc1\x8f\x71\x5f\x80\x2a\x06\x3c\x5a\x31\xb8\xa1\x1f\x5c\x5e\xe1\x87\x9e\xc3\x45\x4e\x5f\x3c\x73\x8d\x2d\x9d\x20\x13\x95\xfa\xa4\xb6\x1a\x96\xc8",
161 )
162 );
163
164 foreach ($vectors as $test)
165 {
166 $this->assertEquals(
167 $test['okm'],
168 $this->encryption->hkdf(
169 $test['ikm'],
170 $test['digest'],
171 $test['salt'],
172 $test['length'],
173 $test['info']
174 )
175 );
176 }
177
178 // Test default length, it must match the digest size
179 $this->assertEquals(64, strlen($this->encryption->hkdf('foobar', 'sha512')));
180
181 // Test maximum length (RFC5869 says that it must be up to 255 times the digest size)
182 $this->assertEquals(12240, strlen($this->encryption->hkdf('foobar', 'sha384', NULL, 48 * 255)));
183 $this->assertFalse($this->encryption->hkdf('foobar', 'sha224', NULL, 28 * 255 + 1));
184 }
185
186}