services/crypto/tests/unit/test_crypto_crypt.js

branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
equal deleted inserted replaced
-1:000000000000 0:3d06398a2146
1 Cu.import("resource://services-crypto/WeaveCrypto.js");
2
3 let cryptoSvc = new WeaveCrypto();
4
5 function run_test() {
6
7 if ("makeSECItem" in cryptoSvc) // Only for js-ctypes WeaveCrypto.
8 test_makeSECItem();
9
10 if (this.gczeal) {
11 _("Running crypto tests with gczeal(2).");
12 gczeal(2);
13 }
14 test_bug_617650();
15 test_encrypt_decrypt();
16 test_SECItem_byteCompressInts();
17 test_key_memoization();
18 if (this.gczeal)
19 gczeal(0);
20 }
21
22 function test_key_memoization() {
23 let oldImport = cryptoSvc.nss && cryptoSvc.nss.PK11_ImportSymKey;
24 if (!oldImport) {
25 _("Couldn't swizzle PK11_ImportSymKey; returning.");
26 return;
27 }
28
29 let iv = cryptoSvc.generateRandomIV();
30 let key = cryptoSvc.generateRandomKey();
31 let c = 0;
32 cryptoSvc.nss.PK11_ImportSymKey = function(slot, type, origin, operation, key, wincx) {
33 c++;
34 return oldImport(slot, type, origin, operation, key, wincx);
35 }
36
37 // Encryption should cause a single counter increment.
38 do_check_eq(c, 0);
39 let cipherText = cryptoSvc.encrypt("Hello, world.", key, iv);
40 do_check_eq(c, 1);
41 let cipherText = cryptoSvc.encrypt("Hello, world.", key, iv);
42 do_check_eq(c, 1);
43
44 // ... as should decryption.
45 cryptoSvc.decrypt(cipherText, key, iv);
46 cryptoSvc.decrypt(cipherText, key, iv);
47 cryptoSvc.decrypt(cipherText, key, iv);
48 do_check_eq(c, 2);
49
50 // Un-swizzle.
51 cryptoSvc.nss.PK11_ImportSymKey = oldImport;
52 }
53
54 function multiple_decrypts(iterations) {
55 let iv = cryptoSvc.generateRandomIV();
56 let key = cryptoSvc.generateRandomKey();
57 let cipherText = cryptoSvc.encrypt("Hello, world.", key, iv);
58
59 for (let i = 0; i < iterations; ++i) {
60 let clearText = cryptoSvc.decrypt(cipherText, key, iv);
61 do_check_eq(clearText + " " + i, "Hello, world. " + i);
62 }
63 _("Done with multiple_decrypts.");
64 }
65
66 function test_bug_617650() {
67 if (this.gczeal) {
68 gczeal(2);
69 // Few iterations, because gczeal(2) is expensive... and makes it fail much faster!
70 _("gczeal set to 2; attempting 10 iterations of multiple_decrypts.");
71 multiple_decrypts(10);
72 gczeal(0);
73 } else {
74 // We can't use gczeal on non-debug builds, so try lots of reps instead.
75 _("No gczeal (non-debug build?); attempting 10,000 iterations of multiple_decrypts.");
76 multiple_decrypts(10000);
77 }
78 }
79
80 // Just verify that it gets populated with the correct bytes.
81 function test_makeSECItem() {
82 Components.utils.import("resource://gre/modules/ctypes.jsm");
83
84 let item1 = cryptoSvc.makeSECItem("abcdefghi", false);
85 do_check_true(!item1.isNull());
86 let intData = ctypes.cast(item1.contents.data, ctypes.uint8_t.array(8).ptr).contents;
87 for (let i = 0; i < 8; ++i)
88 do_check_eq(intData[i], "abcdefghi".charCodeAt(i));
89 }
90
91 function test_SECItem_byteCompressInts() {
92 Components.utils.import("resource://gre/modules/ctypes.jsm");
93
94 let item1 = cryptoSvc.makeSECItem("abcdefghi", false);
95 do_check_true(!item1.isNull());
96 let intData = ctypes.cast(item1.contents.data, ctypes.uint8_t.array(8).ptr).contents;
97
98 // Fill it too short.
99 cryptoSvc.byteCompressInts("MMM", intData, 8);
100 for (let i = 0; i < 3; ++i)
101 do_check_eq(intData[i], [77, 77, 77][i]);
102
103 // Fill it too much. Doesn't buffer overrun.
104 cryptoSvc.byteCompressInts("NNNNNNNNNNNNNNNN", intData, 8);
105 for (let i = 0; i < 8; ++i)
106 do_check_eq(intData[i], "NNNNNNNNNNNNNNNN".charCodeAt(i));
107 }
108
109 function test_encrypt_decrypt() {
110
111 // First, do a normal run with expected usage... Generate a random key and
112 // iv, encrypt and decrypt a string.
113 var iv = cryptoSvc.generateRandomIV();
114 do_check_eq(iv.length, 24);
115
116 var key = cryptoSvc.generateRandomKey();
117 do_check_eq(key.length, 44);
118
119 var mySecret = "bacon is a vegetable";
120 var cipherText = cryptoSvc.encrypt(mySecret, key, iv);
121 do_check_eq(cipherText.length, 44);
122
123 var clearText = cryptoSvc.decrypt(cipherText, key, iv);
124 do_check_eq(clearText.length, 20);
125
126 // Did the text survive the encryption round-trip?
127 do_check_eq(clearText, mySecret);
128 do_check_neq(cipherText, mySecret); // just to be explicit
129
130
131 // Do some more tests with a fixed key/iv, to check for reproducable results.
132 key = "St1tFCor7vQEJNug/465dQ==";
133 iv = "oLjkfrLIOnK2bDRvW4kXYA==";
134
135 _("Testing small IV.");
136 mySecret = "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=";
137 shortiv = "YWJj"; // "abc": Less than 16.
138 let err;
139 try {
140 cryptoSvc.encrypt(mySecret, key, shortiv);
141 } catch (ex) {
142 err = ex;
143 }
144 do_check_true(!!err);
145
146 // Test small input sizes
147 mySecret = "";
148 cipherText = cryptoSvc.encrypt(mySecret, key, iv);
149 clearText = cryptoSvc.decrypt(cipherText, key, iv);
150 do_check_eq(cipherText, "OGQjp6mK1a3fs9k9Ml4L3w==");
151 do_check_eq(clearText, mySecret);
152
153 mySecret = "x";
154 cipherText = cryptoSvc.encrypt(mySecret, key, iv);
155 clearText = cryptoSvc.decrypt(cipherText, key, iv);
156 do_check_eq(cipherText, "96iMl4vhOxFUW/lVHHzVqg==");
157 do_check_eq(clearText, mySecret);
158
159 mySecret = "xx";
160 cipherText = cryptoSvc.encrypt(mySecret, key, iv);
161 clearText = cryptoSvc.decrypt(cipherText, key, iv);
162 do_check_eq(cipherText, "olpPbETRYROCSqFWcH2SWg==");
163 do_check_eq(clearText, mySecret);
164
165 mySecret = "xxx";
166 cipherText = cryptoSvc.encrypt(mySecret, key, iv);
167 clearText = cryptoSvc.decrypt(cipherText, key, iv);
168 do_check_eq(cipherText, "rRbpHGyVSZizLX/x43Wm+Q==");
169 do_check_eq(clearText, mySecret);
170
171 mySecret = "xxxx";
172 cipherText = cryptoSvc.encrypt(mySecret, key, iv);
173 clearText = cryptoSvc.decrypt(cipherText, key, iv);
174 do_check_eq(cipherText, "HeC7miVGDcpxae9RmiIKAw==");
175 do_check_eq(clearText, mySecret);
176
177 // Test non-ascii input
178 // ("testuser1" using similar-looking glyphs)
179 mySecret = String.fromCharCode(355, 277, 349, 357, 533, 537, 101, 345, 185);
180 cipherText = cryptoSvc.encrypt(mySecret, key, iv);
181 clearText = cryptoSvc.decrypt(cipherText, key, iv);
182 do_check_eq(cipherText, "Pj4ixByXoH3SU3JkOXaEKPgwRAWplAWFLQZkpJd5Kr4=");
183 do_check_eq(clearText, mySecret);
184
185 // Tests input spanning a block boundary (AES block size is 16 bytes)
186 mySecret = "123456789012345";
187 cipherText = cryptoSvc.encrypt(mySecret, key, iv);
188 clearText = cryptoSvc.decrypt(cipherText, key, iv);
189 do_check_eq(cipherText, "e6c5hwphe45/3VN/M0bMUA==");
190 do_check_eq(clearText, mySecret);
191
192 mySecret = "1234567890123456";
193 cipherText = cryptoSvc.encrypt(mySecret, key, iv);
194 clearText = cryptoSvc.decrypt(cipherText, key, iv);
195 do_check_eq(cipherText, "V6aaOZw8pWlYkoIHNkhsP1JOIQF87E2vTUvBUQnyV04=");
196 do_check_eq(clearText, mySecret);
197
198 mySecret = "12345678901234567";
199 cipherText = cryptoSvc.encrypt(mySecret, key, iv);
200 clearText = cryptoSvc.decrypt(cipherText, key, iv);
201 do_check_eq(cipherText, "V6aaOZw8pWlYkoIHNkhsP5GvxWJ9+GIAS6lXw+5fHTI=");
202 do_check_eq(clearText, mySecret);
203
204
205 key = "iz35tuIMq4/H+IYw2KTgow==";
206 iv = "TJYrvva2KxvkM8hvOIvWp3xgjTXgq5Ss";
207 mySecret = "i like pie";
208
209 cipherText = cryptoSvc.encrypt(mySecret, key, iv);
210 clearText = cryptoSvc.decrypt(cipherText, key, iv);
211 do_check_eq(cipherText, "DLGx8BWqSCLGG7i/xwvvxg==");
212 do_check_eq(clearText, mySecret);
213
214 key = "c5hG3YG+NC61FFy8NOHQak1ZhMEWO79bwiAfar2euzI=";
215 iv = "gsgLRDaxWvIfKt75RjuvFWERt83FFsY2A0TW+0b2iVk=";
216 mySecret = "i like pie";
217
218 cipherText = cryptoSvc.encrypt(mySecret, key, iv);
219 clearText = cryptoSvc.decrypt(cipherText, key, iv);
220 do_check_eq(cipherText, "o+ADtdMd8ubzNWurS6jt0Q==");
221 do_check_eq(clearText, mySecret);
222
223 key = "St1tFCor7vQEJNug/465dQ==";
224 iv = "oLjkfrLIOnK2bDRvW4kXYA==";
225 mySecret = "does thunder read testcases?";
226 cipherText = cryptoSvc.encrypt(mySecret, key, iv);
227 do_check_eq(cipherText, "T6fik9Ros+DB2ablH9zZ8FWZ0xm/szSwJjIHZu7sjPs=");
228
229 var badkey = "badkeybadkeybadkeybadk==";
230 var badiv = "badivbadivbadivbadivbad=";
231 var badcipher = "crapinputcrapinputcrapinputcrapinputcrapinp=";
232 var failure;
233
234 try {
235 failure = false;
236 clearText = cryptoSvc.decrypt(cipherText, badkey, iv);
237 } catch (e) {
238 failure = true;
239 }
240 do_check_true(failure);
241
242 try {
243 failure = false;
244 clearText = cryptoSvc.decrypt(cipherText, key, badiv);
245 } catch (e) {
246 failure = true;
247 }
248 do_check_true(failure);
249
250 try {
251 failure = false;
252 clearText = cryptoSvc.decrypt(cipherText, badkey, badiv);
253 } catch (e) {
254 failure = true;
255 }
256 do_check_true(failure);
257
258 try {
259 failure = false;
260 clearText = cryptoSvc.decrypt(badcipher, key, iv);
261 } catch (e) {
262 failure = true;
263 }
264 do_check_true(failure);
265 }

mercurial