1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/services/crypto/tests/unit/test_utils_pbkdf2.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,162 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + * http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +// XXX until bug 937114 is fixed 1.8 +Cu.importGlobalProperties(['btoa']); 1.9 +Cu.import("resource://services-crypto/utils.js"); 1.10 +Cu.import("resource://services-common/utils.js"); 1.11 + 1.12 +let {bytesAsHex: b2h} = CommonUtils; 1.13 + 1.14 +function run_test() { 1.15 + run_next_test(); 1.16 +} 1.17 + 1.18 +add_task(function test_pbkdf2() { 1.19 + let symmKey16 = CryptoUtils.pbkdf2Generate("secret phrase", "DNXPzPpiwn", 4096, 16); 1.20 + do_check_eq(symmKey16.length, 16); 1.21 + do_check_eq(btoa(symmKey16), "d2zG0d2cBfXnRwMUGyMwyg=="); 1.22 + do_check_eq(CommonUtils.encodeBase32(symmKey16), "O5WMNUO5TQC7LZ2HAMKBWIZQZI======"); 1.23 + let symmKey32 = CryptoUtils.pbkdf2Generate("passphrase", "salt", 4096, 32); 1.24 + do_check_eq(symmKey32.length, 32); 1.25 +}); 1.26 + 1.27 +// http://tools.ietf.org/html/rfc6070 1.28 +// PBKDF2 HMAC-SHA1 Test Vectors 1.29 +add_task(function test_pbkdf2_hmac_sha1() { 1.30 + let pbkdf2 = CryptoUtils.pbkdf2Generate; 1.31 + let vectors = [ 1.32 + {P: "password", // (8 octets) 1.33 + S: "salt", // (4 octets) 1.34 + c: 1, 1.35 + dkLen: 20, 1.36 + DK: h("0c 60 c8 0f 96 1f 0e 71"+ 1.37 + "f3 a9 b5 24 af 60 12 06"+ 1.38 + "2f e0 37 a6"), // (20 octets) 1.39 + }, 1.40 + 1.41 + {P: "password", // (8 octets) 1.42 + S: "salt", // (4 octets) 1.43 + c: 2, 1.44 + dkLen: 20, 1.45 + DK: h("ea 6c 01 4d c7 2d 6f 8c"+ 1.46 + "cd 1e d9 2a ce 1d 41 f0"+ 1.47 + "d8 de 89 57"), // (20 octets) 1.48 + }, 1.49 + 1.50 + {P: "password", // (8 octets) 1.51 + S: "salt", // (4 octets) 1.52 + c: 4096, 1.53 + dkLen: 20, 1.54 + DK: h("4b 00 79 01 b7 65 48 9a"+ 1.55 + "be ad 49 d9 26 f7 21 d0"+ 1.56 + "65 a4 29 c1"), // (20 octets) 1.57 + }, 1.58 + 1.59 + // XXX Uncomment the following test after Bug 968567 lands 1.60 + // 1.61 + // XXX As it stands, I estimate that the CryptoUtils implementation will 1.62 + // take approximately 16 hours in my 2.3GHz MacBook to perform this many 1.63 + // rounds. 1.64 + // 1.65 + // {P: "password", // (8 octets) 1.66 + // S: "salt" // (4 octets) 1.67 + // c: 16777216, 1.68 + // dkLen = 20, 1.69 + // DK: h("ee fe 3d 61 cd 4d a4 e4"+ 1.70 + // "e9 94 5b 3d 6b a2 15 8c"+ 1.71 + // "26 34 e9 84"), // (20 octets) 1.72 + // }, 1.73 + 1.74 + {P: "passwordPASSWORDpassword", // (24 octets) 1.75 + S: "saltSALTsaltSALTsaltSALTsaltSALTsalt", // (36 octets) 1.76 + c: 4096, 1.77 + dkLen: 25, 1.78 + DK: h("3d 2e ec 4f e4 1c 84 9b"+ 1.79 + "80 c8 d8 36 62 c0 e4 4a"+ 1.80 + "8b 29 1a 96 4c f2 f0 70"+ 1.81 + "38"), // (25 octets) 1.82 + 1.83 + }, 1.84 + 1.85 + {P: "pass\0word", // (9 octets) 1.86 + S: "sa\0lt", // (5 octets) 1.87 + c: 4096, 1.88 + dkLen: 16, 1.89 + DK: h("56 fa 6a a7 55 48 09 9d"+ 1.90 + "cc 37 d7 f0 34 25 e0 c3"), // (16 octets) 1.91 + }, 1.92 + ]; 1.93 + 1.94 + for (let v of vectors) { 1.95 + do_check_eq(v.DK, b2h(pbkdf2(v.P, v.S, v.c, v.dkLen))); 1.96 + } 1.97 +}); 1.98 + 1.99 +// I can't find any normative ietf test vectors for pbkdf2 hmac-sha256. 1.100 +// The following vectors are derived with the same inputs as above (the sha1 1.101 +// test). Results verified by users here: 1.102 +// https://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors 1.103 +add_task(function test_pbkdf2_hmac_sha256() { 1.104 + let pbkdf2 = CryptoUtils.pbkdf2Generate; 1.105 + let vectors = [ 1.106 + {P: "password", // (8 octets) 1.107 + S: "salt", // (4 octets) 1.108 + c: 1, 1.109 + dkLen: 32, 1.110 + DK: h("12 0f b6 cf fc f8 b3 2c"+ 1.111 + "43 e7 22 52 56 c4 f8 37"+ 1.112 + "a8 65 48 c9 2c cc 35 48"+ 1.113 + "08 05 98 7c b7 0b e1 7b"), // (32 octets) 1.114 + }, 1.115 + 1.116 + {P: "password", // (8 octets) 1.117 + S: "salt", // (4 octets) 1.118 + c: 2, 1.119 + dkLen: 32, 1.120 + DK: h("ae 4d 0c 95 af 6b 46 d3"+ 1.121 + "2d 0a df f9 28 f0 6d d0"+ 1.122 + "2a 30 3f 8e f3 c2 51 df"+ 1.123 + "d6 e2 d8 5a 95 47 4c 43"), // (32 octets) 1.124 + }, 1.125 + 1.126 + {P: "password", // (8 octets) 1.127 + S: "salt", // (4 octets) 1.128 + c: 4096, 1.129 + dkLen: 32, 1.130 + DK: h("c5 e4 78 d5 92 88 c8 41"+ 1.131 + "aa 53 0d b6 84 5c 4c 8d"+ 1.132 + "96 28 93 a0 01 ce 4e 11"+ 1.133 + "a4 96 38 73 aa 98 13 4a"), // (32 octets) 1.134 + }, 1.135 + 1.136 + {P: "passwordPASSWORDpassword", // (24 octets) 1.137 + S: "saltSALTsaltSALTsaltSALTsaltSALTsalt", // (36 octets) 1.138 + c: 4096, 1.139 + dkLen: 40, 1.140 + DK: h("34 8c 89 db cb d3 2b 2f"+ 1.141 + "32 d8 14 b8 11 6e 84 cf"+ 1.142 + "2b 17 34 7e bc 18 00 18"+ 1.143 + "1c 4e 2a 1f b8 dd 53 e1"+ 1.144 + "c6 35 51 8c 7d ac 47 e9"), // (40 octets) 1.145 + }, 1.146 + 1.147 + {P: "pass\0word", // (9 octets) 1.148 + S: "sa\0lt", // (5 octets) 1.149 + c: 4096, 1.150 + dkLen: 16, 1.151 + DK: h("89 b6 9d 05 16 f8 29 89"+ 1.152 + "3c 69 62 26 65 0a 86 87"), // (16 octets) 1.153 + }, 1.154 + ]; 1.155 + 1.156 + for (let v of vectors) { 1.157 + do_check_eq(v.DK, 1.158 + b2h(pbkdf2(v.P, v.S, v.c, v.dkLen, Ci.nsICryptoHMAC.SHA256, 32))); 1.159 + } 1.160 +}); 1.161 + 1.162 +// turn formatted test vectors into normal hex strings 1.163 +function h(hexStr) { 1.164 + return hexStr.replace(/\s+/g, ""); 1.165 +}