michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: // XXX until bug 937114 is fixed michael@0: Cu.importGlobalProperties(['btoa']); michael@0: Cu.import("resource://services-crypto/utils.js"); michael@0: Cu.import("resource://services-common/utils.js"); michael@0: michael@0: let {bytesAsHex: b2h} = CommonUtils; michael@0: michael@0: function run_test() { michael@0: run_next_test(); michael@0: } michael@0: michael@0: add_task(function test_pbkdf2() { michael@0: let symmKey16 = CryptoUtils.pbkdf2Generate("secret phrase", "DNXPzPpiwn", 4096, 16); michael@0: do_check_eq(symmKey16.length, 16); michael@0: do_check_eq(btoa(symmKey16), "d2zG0d2cBfXnRwMUGyMwyg=="); michael@0: do_check_eq(CommonUtils.encodeBase32(symmKey16), "O5WMNUO5TQC7LZ2HAMKBWIZQZI======"); michael@0: let symmKey32 = CryptoUtils.pbkdf2Generate("passphrase", "salt", 4096, 32); michael@0: do_check_eq(symmKey32.length, 32); michael@0: }); michael@0: michael@0: // http://tools.ietf.org/html/rfc6070 michael@0: // PBKDF2 HMAC-SHA1 Test Vectors michael@0: add_task(function test_pbkdf2_hmac_sha1() { michael@0: let pbkdf2 = CryptoUtils.pbkdf2Generate; michael@0: let vectors = [ michael@0: {P: "password", // (8 octets) michael@0: S: "salt", // (4 octets) michael@0: c: 1, michael@0: dkLen: 20, michael@0: DK: h("0c 60 c8 0f 96 1f 0e 71"+ michael@0: "f3 a9 b5 24 af 60 12 06"+ michael@0: "2f e0 37 a6"), // (20 octets) michael@0: }, michael@0: michael@0: {P: "password", // (8 octets) michael@0: S: "salt", // (4 octets) michael@0: c: 2, michael@0: dkLen: 20, michael@0: DK: h("ea 6c 01 4d c7 2d 6f 8c"+ michael@0: "cd 1e d9 2a ce 1d 41 f0"+ michael@0: "d8 de 89 57"), // (20 octets) michael@0: }, michael@0: michael@0: {P: "password", // (8 octets) michael@0: S: "salt", // (4 octets) michael@0: c: 4096, michael@0: dkLen: 20, michael@0: DK: h("4b 00 79 01 b7 65 48 9a"+ michael@0: "be ad 49 d9 26 f7 21 d0"+ michael@0: "65 a4 29 c1"), // (20 octets) michael@0: }, michael@0: michael@0: // XXX Uncomment the following test after Bug 968567 lands michael@0: // michael@0: // XXX As it stands, I estimate that the CryptoUtils implementation will michael@0: // take approximately 16 hours in my 2.3GHz MacBook to perform this many michael@0: // rounds. michael@0: // michael@0: // {P: "password", // (8 octets) michael@0: // S: "salt" // (4 octets) michael@0: // c: 16777216, michael@0: // dkLen = 20, michael@0: // DK: h("ee fe 3d 61 cd 4d a4 e4"+ michael@0: // "e9 94 5b 3d 6b a2 15 8c"+ michael@0: // "26 34 e9 84"), // (20 octets) michael@0: // }, michael@0: michael@0: {P: "passwordPASSWORDpassword", // (24 octets) michael@0: S: "saltSALTsaltSALTsaltSALTsaltSALTsalt", // (36 octets) michael@0: c: 4096, michael@0: dkLen: 25, michael@0: DK: h("3d 2e ec 4f e4 1c 84 9b"+ michael@0: "80 c8 d8 36 62 c0 e4 4a"+ michael@0: "8b 29 1a 96 4c f2 f0 70"+ michael@0: "38"), // (25 octets) michael@0: michael@0: }, michael@0: michael@0: {P: "pass\0word", // (9 octets) michael@0: S: "sa\0lt", // (5 octets) michael@0: c: 4096, michael@0: dkLen: 16, michael@0: DK: h("56 fa 6a a7 55 48 09 9d"+ michael@0: "cc 37 d7 f0 34 25 e0 c3"), // (16 octets) michael@0: }, michael@0: ]; michael@0: michael@0: for (let v of vectors) { michael@0: do_check_eq(v.DK, b2h(pbkdf2(v.P, v.S, v.c, v.dkLen))); michael@0: } michael@0: }); michael@0: michael@0: // I can't find any normative ietf test vectors for pbkdf2 hmac-sha256. michael@0: // The following vectors are derived with the same inputs as above (the sha1 michael@0: // test). Results verified by users here: michael@0: // https://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors michael@0: add_task(function test_pbkdf2_hmac_sha256() { michael@0: let pbkdf2 = CryptoUtils.pbkdf2Generate; michael@0: let vectors = [ michael@0: {P: "password", // (8 octets) michael@0: S: "salt", // (4 octets) michael@0: c: 1, michael@0: dkLen: 32, michael@0: DK: h("12 0f b6 cf fc f8 b3 2c"+ michael@0: "43 e7 22 52 56 c4 f8 37"+ michael@0: "a8 65 48 c9 2c cc 35 48"+ michael@0: "08 05 98 7c b7 0b e1 7b"), // (32 octets) michael@0: }, michael@0: michael@0: {P: "password", // (8 octets) michael@0: S: "salt", // (4 octets) michael@0: c: 2, michael@0: dkLen: 32, michael@0: DK: h("ae 4d 0c 95 af 6b 46 d3"+ michael@0: "2d 0a df f9 28 f0 6d d0"+ michael@0: "2a 30 3f 8e f3 c2 51 df"+ michael@0: "d6 e2 d8 5a 95 47 4c 43"), // (32 octets) michael@0: }, michael@0: michael@0: {P: "password", // (8 octets) michael@0: S: "salt", // (4 octets) michael@0: c: 4096, michael@0: dkLen: 32, michael@0: DK: h("c5 e4 78 d5 92 88 c8 41"+ michael@0: "aa 53 0d b6 84 5c 4c 8d"+ michael@0: "96 28 93 a0 01 ce 4e 11"+ michael@0: "a4 96 38 73 aa 98 13 4a"), // (32 octets) michael@0: }, michael@0: michael@0: {P: "passwordPASSWORDpassword", // (24 octets) michael@0: S: "saltSALTsaltSALTsaltSALTsaltSALTsalt", // (36 octets) michael@0: c: 4096, michael@0: dkLen: 40, michael@0: DK: h("34 8c 89 db cb d3 2b 2f"+ michael@0: "32 d8 14 b8 11 6e 84 cf"+ michael@0: "2b 17 34 7e bc 18 00 18"+ michael@0: "1c 4e 2a 1f b8 dd 53 e1"+ michael@0: "c6 35 51 8c 7d ac 47 e9"), // (40 octets) michael@0: }, michael@0: michael@0: {P: "pass\0word", // (9 octets) michael@0: S: "sa\0lt", // (5 octets) michael@0: c: 4096, michael@0: dkLen: 16, michael@0: DK: h("89 b6 9d 05 16 f8 29 89"+ michael@0: "3c 69 62 26 65 0a 86 87"), // (16 octets) michael@0: }, michael@0: ]; michael@0: michael@0: for (let v of vectors) { michael@0: do_check_eq(v.DK, michael@0: b2h(pbkdf2(v.P, v.S, v.c, v.dkLen, Ci.nsICryptoHMAC.SHA256, 32))); michael@0: } michael@0: }); michael@0: michael@0: // turn formatted test vectors into normal hex strings michael@0: function h(hexStr) { michael@0: return hexStr.replace(/\s+/g, ""); michael@0: }