PageRenderTime 39ms CodeModel.GetById 18ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/services/crypto/tests/unit/test_crypto_crypt.js

http://github.com/zpao/v8monkey
JavaScript | 265 lines | 202 code | 47 blank | 16 comment | 11 complexity | a7031d132563ffd155e4e896eedd1038 MD5 | raw file
  1Cu.import("resource://services-crypto/WeaveCrypto.js");
  2
  3let cryptoSvc = new WeaveCrypto();
  4
  5function 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
 22function 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
 54function 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
 66function 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.
 81function 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
 91function 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
109function 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}