test_crypto_crypt.js (7069B)
1 const { WeaveCrypto } = ChromeUtils.importESModule( 2 "moz-src:///services/crypto/modules/WeaveCrypto.sys.mjs" 3 ); 4 5 var cryptoSvc = new WeaveCrypto(); 6 7 add_task(async function test_key_memoization() { 8 let cryptoGlobal = cryptoSvc._getCrypto(); 9 let oldImport = cryptoGlobal.subtle.importKey; 10 if (!oldImport) { 11 _("Couldn't swizzle crypto.subtle.importKey; returning."); 12 return; 13 } 14 15 let iv = cryptoSvc.generateRandomIV(); 16 let key = await cryptoSvc.generateRandomKey(); 17 let c = 0; 18 cryptoGlobal.subtle.importKey = function ( 19 format, 20 keyData, 21 algo, 22 extractable, 23 usages 24 ) { 25 c++; 26 return oldImport.call( 27 cryptoGlobal.subtle, 28 format, 29 keyData, 30 algo, 31 extractable, 32 usages 33 ); 34 }; 35 36 // Encryption should cause a single counter increment. 37 Assert.equal(c, 0); 38 let cipherText = await cryptoSvc.encrypt("Hello, world.", key, iv); 39 Assert.equal(c, 1); 40 cipherText = await cryptoSvc.encrypt("Hello, world.", key, iv); 41 Assert.equal(c, 1); 42 43 // ... as should decryption. 44 await cryptoSvc.decrypt(cipherText, key, iv); 45 await cryptoSvc.decrypt(cipherText, key, iv); 46 await cryptoSvc.decrypt(cipherText, key, iv); 47 Assert.equal(c, 2); 48 49 // Un-swizzle. 50 cryptoGlobal.subtle.importKey = oldImport; 51 }); 52 53 // Just verify that it gets populated with the correct bytes. 54 add_task(async function test_makeUint8Array() { 55 ChromeUtils.importESModule("resource://gre/modules/ctypes.sys.mjs"); 56 57 let item1 = cryptoSvc.makeUint8Array("abcdefghi", false); 58 Assert.ok(item1); 59 for (let i = 0; i < 8; ++i) { 60 Assert.equal(item1[i], "abcdefghi".charCodeAt(i)); 61 } 62 }); 63 64 add_task(async function test_encrypt_decrypt() { 65 // First, do a normal run with expected usage... Generate a random key and 66 // iv, encrypt and decrypt a string. 67 var iv = cryptoSvc.generateRandomIV(); 68 Assert.equal(iv.length, 24); 69 70 var key = await cryptoSvc.generateRandomKey(); 71 Assert.equal(key.length, 44); 72 73 var mySecret = "bacon is a vegetable"; 74 var cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 75 Assert.equal(cipherText.length, 44); 76 77 var clearText = await cryptoSvc.decrypt(cipherText, key, iv); 78 Assert.equal(clearText.length, 20); 79 80 // Did the text survive the encryption round-trip? 81 Assert.equal(clearText, mySecret); 82 Assert.notEqual(cipherText, mySecret); // just to be explicit 83 84 // Do some more tests with a fixed key/iv, to check for reproducable results. 85 key = "St1tFCor7vQEJNug/465dQ=="; 86 iv = "oLjkfrLIOnK2bDRvW4kXYA=="; 87 88 _("Testing small IV."); 89 mySecret = "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo="; 90 let shortiv = "YWJj"; 91 let err; 92 try { 93 await cryptoSvc.encrypt(mySecret, key, shortiv); 94 } catch (ex) { 95 err = ex; 96 } 97 Assert.ok(!!err); 98 99 _("Testing long IV."); 100 let longiv = "gsgLRDaxWvIfKt75RjuvFWERt83FFsY2A0TW+0b2iVk="; 101 try { 102 await cryptoSvc.encrypt(mySecret, key, longiv); 103 } catch (ex) { 104 err = ex; 105 } 106 Assert.ok(!!err); 107 108 // Test small input sizes 109 mySecret = ""; 110 cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 111 clearText = await cryptoSvc.decrypt(cipherText, key, iv); 112 Assert.equal(cipherText, "OGQjp6mK1a3fs9k9Ml4L3w=="); 113 Assert.equal(clearText, mySecret); 114 115 mySecret = "x"; 116 cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 117 clearText = await cryptoSvc.decrypt(cipherText, key, iv); 118 Assert.equal(cipherText, "96iMl4vhOxFUW/lVHHzVqg=="); 119 Assert.equal(clearText, mySecret); 120 121 mySecret = "xx"; 122 cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 123 clearText = await cryptoSvc.decrypt(cipherText, key, iv); 124 Assert.equal(cipherText, "olpPbETRYROCSqFWcH2SWg=="); 125 Assert.equal(clearText, mySecret); 126 127 mySecret = "xxx"; 128 cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 129 clearText = await cryptoSvc.decrypt(cipherText, key, iv); 130 Assert.equal(cipherText, "rRbpHGyVSZizLX/x43Wm+Q=="); 131 Assert.equal(clearText, mySecret); 132 133 mySecret = "xxxx"; 134 cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 135 clearText = await cryptoSvc.decrypt(cipherText, key, iv); 136 Assert.equal(cipherText, "HeC7miVGDcpxae9RmiIKAw=="); 137 Assert.equal(clearText, mySecret); 138 139 // Test non-ascii input 140 // ("testuser1" using similar-looking glyphs) 141 mySecret = String.fromCharCode(355, 277, 349, 357, 533, 537, 101, 345, 185); 142 cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 143 clearText = await cryptoSvc.decrypt(cipherText, key, iv); 144 Assert.equal(cipherText, "Pj4ixByXoH3SU3JkOXaEKPgwRAWplAWFLQZkpJd5Kr4="); 145 Assert.equal(clearText, mySecret); 146 147 // Tests input spanning a block boundary (AES block size is 16 bytes) 148 mySecret = "123456789012345"; 149 cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 150 clearText = await cryptoSvc.decrypt(cipherText, key, iv); 151 Assert.equal(cipherText, "e6c5hwphe45/3VN/M0bMUA=="); 152 Assert.equal(clearText, mySecret); 153 154 mySecret = "1234567890123456"; 155 cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 156 clearText = await cryptoSvc.decrypt(cipherText, key, iv); 157 Assert.equal(cipherText, "V6aaOZw8pWlYkoIHNkhsP1JOIQF87E2vTUvBUQnyV04="); 158 Assert.equal(clearText, mySecret); 159 160 mySecret = "12345678901234567"; 161 cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 162 clearText = await cryptoSvc.decrypt(cipherText, key, iv); 163 Assert.equal(cipherText, "V6aaOZw8pWlYkoIHNkhsP5GvxWJ9+GIAS6lXw+5fHTI="); 164 Assert.equal(clearText, mySecret); 165 166 key = "iz35tuIMq4/H+IYw2KTgow=="; 167 iv = "TJYrvva2KxvkM8hvOIvWp3=="; 168 mySecret = "i like pie"; 169 170 cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 171 clearText = await cryptoSvc.decrypt(cipherText, key, iv); 172 Assert.equal(cipherText, "DLGx8BWqSCLGG7i/xwvvxg=="); 173 Assert.equal(clearText, mySecret); 174 175 key = "c5hG3YG+NC61FFy8NOHQak1ZhMEWO79bwiAfar2euzI="; 176 iv = "gsgLRDaxWvIfKt75RjuvFW=="; 177 mySecret = "i like pie"; 178 179 cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 180 clearText = await cryptoSvc.decrypt(cipherText, key, iv); 181 Assert.equal(cipherText, "o+ADtdMd8ubzNWurS6jt0Q=="); 182 Assert.equal(clearText, mySecret); 183 184 key = "St1tFCor7vQEJNug/465dQ=="; 185 iv = "oLjkfrLIOnK2bDRvW4kXYA=="; 186 mySecret = "does thunder read testcases?"; 187 cipherText = await cryptoSvc.encrypt(mySecret, key, iv); 188 Assert.equal(cipherText, "T6fik9Ros+DB2ablH9zZ8FWZ0xm/szSwJjIHZu7sjPs="); 189 190 var badkey = "badkeybadkeybadkeybadk=="; 191 var badiv = "badivbadivbadivbadivbad="; 192 var badcipher = "crapinputcrapinputcrapinputcrapinputcrapinp="; 193 var failure; 194 195 try { 196 failure = false; 197 clearText = await cryptoSvc.decrypt(cipherText, badkey, iv); 198 } catch (e) { 199 failure = true; 200 } 201 Assert.ok(failure); 202 203 try { 204 failure = false; 205 clearText = await cryptoSvc.decrypt(cipherText, key, badiv); 206 } catch (e) { 207 failure = true; 208 } 209 Assert.ok(failure); 210 211 try { 212 failure = false; 213 clearText = await cryptoSvc.decrypt(cipherText, badkey, badiv); 214 } catch (e) { 215 failure = true; 216 } 217 Assert.ok(failure); 218 219 try { 220 failure = false; 221 clearText = await cryptoSvc.decrypt(badcipher, key, iv); 222 } catch (e) { 223 failure = true; 224 } 225 Assert.ok(failure); 226 });