1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/services/crypto/component/tests/unit/test_jpake.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,289 @@ 1.4 +const Cc = Components.classes; 1.5 +const Ci = Components.interfaces; 1.6 + 1.7 +// Ensure PSM is initialized. 1.8 +Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports); 1.9 + 1.10 +function do_check_throws(func) { 1.11 + let have_error = false; 1.12 + try { 1.13 + func(); 1.14 + } catch(ex) { 1.15 + dump("Was expecting an exception. Caught: " + ex + "\n"); 1.16 + have_error = true; 1.17 + } 1.18 + do_check_true(have_error); 1.19 +} 1.20 + 1.21 +function test_success() { 1.22 + let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.23 + .createInstance(Ci.nsISyncJPAKE); 1.24 + let b = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.25 + .createInstance(Ci.nsISyncJPAKE); 1.26 + 1.27 + let a_gx1 = {}; 1.28 + let a_gv1 = {}; 1.29 + let a_r1 = {}; 1.30 + let a_gx2 = {}; 1.31 + let a_gv2 = {}; 1.32 + let a_r2 = {}; 1.33 + 1.34 + let b_gx1 = {}; 1.35 + let b_gv1 = {}; 1.36 + let b_r1 = {}; 1.37 + let b_gx2 = {}; 1.38 + let b_gv2 = {}; 1.39 + let b_r2 = {}; 1.40 + 1.41 + a.round1("alice", a_gx1, a_gv1, a_r1, a_gx2, a_gv2, a_r2); 1.42 + b.round1("bob", b_gx1, b_gv1, b_r1, b_gx2, b_gv2, b_r2); 1.43 + 1.44 + let a_A = {}; 1.45 + let a_gva = {}; 1.46 + let a_ra = {}; 1.47 + 1.48 + let b_A = {}; 1.49 + let b_gva = {}; 1.50 + let b_ra = {}; 1.51 + 1.52 + a.round2("bob", "sekrit", b_gx1.value, b_gv1.value, b_r1.value, 1.53 + b_gx2.value, b_gv2.value, b_r2.value, a_A, a_gva, a_ra); 1.54 + b.round2("alice", "sekrit", a_gx1.value, a_gv1.value, a_r1.value, 1.55 + a_gx2.value, a_gv2.value, a_r2.value, b_A, b_gva, b_ra); 1.56 + 1.57 + let a_aes = {}; 1.58 + let a_hmac = {}; 1.59 + let b_aes = {}; 1.60 + let b_hmac = {}; 1.61 + 1.62 + a.final(b_A.value, b_gva.value, b_ra.value, "ohai", a_aes, a_hmac); 1.63 + b.final(a_A.value, a_gva.value, a_ra.value, "ohai", b_aes, b_hmac); 1.64 + 1.65 + do_check_eq(a_aes.value, b_aes.value); 1.66 + do_check_eq(a_hmac.value, b_hmac.value); 1.67 +} 1.68 + 1.69 +function test_failure(modlen) { 1.70 + let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.71 + .createInstance(Ci.nsISyncJPAKE); 1.72 + let b = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.73 + .createInstance(Ci.nsISyncJPAKE); 1.74 + 1.75 + let a_gx1 = {}; 1.76 + let a_gv1 = {}; 1.77 + let a_r1 = {}; 1.78 + let a_gx2 = {}; 1.79 + let a_gv2 = {}; 1.80 + let a_r2 = {}; 1.81 + 1.82 + let b_gx1 = {}; 1.83 + let b_gv1 = {}; 1.84 + let b_r1 = {}; 1.85 + let b_gx2 = {}; 1.86 + let b_gv2 = {}; 1.87 + let b_r2 = {}; 1.88 + 1.89 + a.round1("alice", a_gx1, a_gv1, a_r1, a_gx2, a_gv2, a_r2); 1.90 + b.round1("bob", b_gx1, b_gv1, b_r1, b_gx2, b_gv2, b_r2); 1.91 + 1.92 + let a_A = {}; 1.93 + let a_gva = {}; 1.94 + let a_ra = {}; 1.95 + 1.96 + let b_A = {}; 1.97 + let b_gva = {}; 1.98 + let b_ra = {}; 1.99 + 1.100 + // Note how the PINs are different (secret vs. sekrit) 1.101 + a.round2("bob", "secret", b_gx1.value, b_gv1.value, b_r1.value, 1.102 + b_gx2.value, b_gv2.value, b_r2.value, a_A, a_gva, a_ra); 1.103 + b.round2("alice", "sekrit", a_gx1.value, a_gv1.value, a_r1.value, 1.104 + a_gx2.value, a_gv2.value, a_r2.value, b_A, b_gva, b_ra); 1.105 + 1.106 + let a_aes = {}; 1.107 + let a_hmac = {}; 1.108 + let b_aes = {}; 1.109 + let b_hmac = {}; 1.110 + 1.111 + a.final(b_A.value, b_gva.value, b_ra.value, "ohai", a_aes, a_hmac); 1.112 + b.final(a_A.value, a_gva.value, a_ra.value, "ohai", b_aes, b_hmac); 1.113 + 1.114 + do_check_neq(a_aes.value, b_aes.value); 1.115 + do_check_neq(a_hmac.value, b_hmac.value); 1.116 +} 1.117 + 1.118 +function test_same_signerids() { 1.119 + let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.120 + .createInstance(Ci.nsISyncJPAKE); 1.121 + let b = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.122 + .createInstance(Ci.nsISyncJPAKE); 1.123 + 1.124 + let gx1 = {}; 1.125 + let gv1 = {}; 1.126 + let r1 = {}; 1.127 + let gx2 = {}; 1.128 + let gv2 = {}; 1.129 + let r2 = {}; 1.130 + 1.131 + a.round1("alice", {}, {}, {}, {}, {}, {}); 1.132 + b.round1("alice", gx1, gv1, r1, gx2, gv2, r2); 1.133 + do_check_throws(function() { 1.134 + a.round2("alice", "sekrit", gx1.value, gv1.value, r1.value, 1.135 + gx2.value, gv2.value, r2.value, {}, {}, {}); 1.136 + }); 1.137 +} 1.138 + 1.139 +function test_bad_zkp() { 1.140 + let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.141 + .createInstance(Ci.nsISyncJPAKE); 1.142 + let b = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.143 + .createInstance(Ci.nsISyncJPAKE); 1.144 + 1.145 + let gx1 = {}; 1.146 + let gv1 = {}; 1.147 + let r1 = {}; 1.148 + let gx2 = {}; 1.149 + let gv2 = {}; 1.150 + let r2 = {}; 1.151 + 1.152 + a.round1("alice", {}, {}, {}, {}, {}, {}); 1.153 + b.round1("bob", gx1, gv1, r1, gx2, gv2, r2); 1.154 + do_check_throws(function() { 1.155 + a.round2("invalid", "sekrit", gx1.value, gv1.value, r1.value, 1.156 + gx2.value, gv2.value, r2.value, {}, {}, {}); 1.157 + }); 1.158 +} 1.159 + 1.160 +function test_x4_zero() { 1.161 + // The PKCS#11 API for J-PAKE does not allow us to choose any of the nonces. 1.162 + // In order to test the defence against x4 (mod p) == 1, we had to generate 1.163 + // our own signed nonces using a the FreeBL JPAKE_Sign function directly. 1.164 + // To verify the signatures are accurate, pass the given value of R as the 1.165 + // "testRandom" parameter to FreeBL's JPAKE_Sign, along with the given values 1.166 + // for X and GX, using signerID "alice". Then verify that each GV returned 1.167 + // from JPAKE_Sign matches the value specified here. 1.168 + let test = function(badGX, badX_GV, badX_R) { 1.169 + let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.170 + .createInstance(Ci.nsISyncJPAKE); 1.171 + let b = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.172 + .createInstance(Ci.nsISyncJPAKE); 1.173 + 1.174 + let a_gx1 = {}; 1.175 + let a_gv1 = {}; 1.176 + let a_r1 = {}; 1.177 + let a_gx2 = {}; 1.178 + let a_gv2 = {}; 1.179 + let a_r2 = {}; 1.180 + 1.181 + let b_gx1 = {}; 1.182 + let b_gv1 = {}; 1.183 + let b_r1 = {}; 1.184 + let b_gx2 = {}; 1.185 + let b_gv2 = {}; 1.186 + let b_r2 = {}; 1.187 + 1.188 + a.round1("alice", a_gx1, a_gv1, a_r1, a_gx2, a_gv2, a_r2); 1.189 + b.round1("bob", b_gx1, b_gv1, b_r1, b_gx2, b_gv2, b_r2); 1.190 + 1.191 + // Replace the g^x2 generated by A with the given illegal value. 1.192 + a_gx2.value = badGX; 1.193 + a_gv2.value = badX_GV; 1.194 + a_r2.value = badX_R; 1.195 + 1.196 + let b_A = {}; 1.197 + let b_gva = {}; 1.198 + let b_ra = {}; 1.199 + 1.200 + do_check_throws(function() { 1.201 + b.round2("alice", "secret", a_gx1.value, a_gv1.value, a_r1.value, 1.202 + a_gx2.value, a_gv2.value, a_r2.value, b_A, b_gva, b_ra); 1.203 + }); 1.204 + }; 1.205 + 1.206 + // g^x is NIST 3072's p + 1, (p + 1) mod p == 1, x == 0 1.207 + test("90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD61037E56258A7795A1C" 1.208 + + "7AD46076982CE6BB956936C6AB4DCFE05E6784586940CA544B9B2140E1EB523F" 1.209 + + "009D20A7E7880E4E5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA1" 1.210 + + "29F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D3485261CD068699B" 1.211 + + "6BA58A1DDBBEF6DB51E8FE34E8A78E542D7BA351C21EA8D8F1D29F5D5D159394" 1.212 + + "87E27F4416B0CA632C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0" 1.213 + + "E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0EE6F29AF7F642773E" 1.214 + + "BE8CD5402415A01451A840476B2FCEB0E388D30D4B376C37FE401C2A2C2F941D" 1.215 + + "AD179C540C1C8CE030D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504F" 1.216 + + "B0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C560EA878DE87C11E3D" 1.217 + + "597F1FEA742D73EEC7F37BE43949EF1A0D15C3F3E3FC0A8335617055AC91328E" 1.218 + + "C22B50FC15B941D3D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB74", 1.219 + "5386107A0DD4A96ECF8D9BCF864BDE23AAEF13351F5550D777A32C1FEC165ED67AE51" 1.220 + + "66C3876AABC1FED1A0993754F3AEE256530F529548F8FE010BC0D070175569845" 1.221 + + "CF009AD24BC897A9CA1F18E1A9CE421DD54FD93AB528BC2594B47791713165276" 1.222 + + "7B76903190C3DCD2076FEC1E61FFFC32D1B07273B06EA2889E66FCBFD41FE8984" 1.223 + + "5FCE36056B09D1F20E58BB6BAA07A32796F11998BEF0AB3D387E2FB4FE3073FEB" 1.224 + + "634BA91709010A70DA29C06F8F92D638C4F158680EAFEB5E0E323BD7DACB671C0" 1.225 + + "BA3EDEEAB5CAA243CABAB28E7205AC9A0AAEAFE132635DAC7FE001C19F880A96E" 1.226 + + "395C42536D694F81B4F44DC66D7D6FBE933C56ABF585837291D8751C18EB1F3FB" 1.227 + + "620582E6A7B795D699E38C270863A289583CB9D07651E6BA3B82BC656B49BD09B" 1.228 + + "6B8C27F370120C7CB89D0829BE51D56356EA836012E9204FF4D1CA8B1B7F9C768" 1.229 + + "4BB2B0F226FD4042EEBAD931FDBD4F81F8425B305752F5E37FFA2B73BB5A034EC" 1.230 + + "7EEF5AAC92EA212897E3A2B8961D2147710ECCE127B942AB2", 1.231 + "05CC4DF005FE006C11111624E14806E4A904A4D1D6A53E795AC7867A960CD4FD"); 1.232 + 1.233 + // x == 0 implies g^x == 1 1.234 + test("01", 1.235 + "488759644532FA7C53E5239F2A365D4B9189582BDD2967A1852FE56568382B65" 1.236 + + "C66BDFCD9B581EAEF4BB497CAF1290ECDFA47A1D1658DC5DC9248D9A4135" 1.237 + + "DC70B6A8497CDF117236841FA18500DC696A92EEF5000ABE68E9C75B37BC" 1.238 + + "6A722126BE728163AA90A6B03D5585994D3403557EEF08E819C72D143BBC" 1.239 + + "CDF74559645066CB3607E1B0430365356389FC8FB3D66FD2B6E2E834EC23" 1.240 + + "0B0234956752D07F983C918488C8E5A124B062D50B44C5E6FB36BCB03E39" 1.241 + + "0385B17CF8062B6688371E6AF5915C2B1AAA31C9294943CC6DC1B994FC09" 1.242 + + "49CA31828B83F3D6DFB081B26045DFD9F10092588B63F1D6E68881A06522" 1.243 + + "5A417CA9555B036DE89D349AC794A43EB28FE320F9A321F06A9364C88B54" 1.244 + + "99EEF4816375B119824ACC9AA56D1340B6A49D05F855DE699B351012028C" 1.245 + + "CA43001F708CC61E71CA3849935BEEBABC0D268CD41B8D2B8DCA705FDFF8" 1.246 + + "1DAA772DA96EDEA0B291FD5C0C1B8EFE5318D37EBC1BFF53A9DDEC4171A6" 1.247 + + "479E341438970058E25C8F2BCDA6166C8BF1B065C174", 1.248 + "8B2BACE575179D762F6F2FFDBFF00B497C07766AB3EED9961447CF6F43D06A97"); 1.249 +} 1.250 + 1.251 +function test_invalid_input_round2() { 1.252 + let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.253 + .createInstance(Ci.nsISyncJPAKE); 1.254 + 1.255 + a.round1("alice", {}, {}, {}, {}, {}, {}); 1.256 + do_check_throws(function() { 1.257 + a.round2("invalid", "sekrit", "some", "real", "garbage", 1.258 + "even", "more", "garbage", {}, {}, {}); 1.259 + }); 1.260 +} 1.261 + 1.262 +function test_invalid_input_final() { 1.263 + let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.264 + .createInstance(Ci.nsISyncJPAKE); 1.265 + let b = Cc["@mozilla.org/services-crypto/sync-jpake;1"] 1.266 + .createInstance(Ci.nsISyncJPAKE); 1.267 + 1.268 + let gx1 = {}; 1.269 + let gv1 = {}; 1.270 + let r1 = {}; 1.271 + let gx2 = {}; 1.272 + let gv2 = {}; 1.273 + let r2 = {}; 1.274 + 1.275 + a.round1("alice", {}, {}, {}, {}, {}, {}); 1.276 + b.round1("bob", gx1, gv1, r1, gx2, gv2, r2); 1.277 + a.round2("bob", "sekrit", gx1.value, gv1.value, r1.value, 1.278 + gx2.value, gv2.value, r2.value, {}, {}, {}); 1.279 + do_check_throws(function() { 1.280 + a.final("some", "garbage", "alright", "foobar-info", {}, {}); 1.281 + }); 1.282 +} 1.283 + 1.284 +function run_test() { 1.285 + test_x4_zero(); 1.286 + test_success(); 1.287 + test_failure(); 1.288 + test_same_signerids(); 1.289 + test_bad_zkp(); 1.290 + test_invalid_input_round2(); 1.291 + test_invalid_input_final(); 1.292 +}