|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 * http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 // XXX until bug 937114 is fixed |
|
5 Cu.importGlobalProperties(['btoa']); |
|
6 Cu.import("resource://services-crypto/utils.js"); |
|
7 Cu.import("resource://services-common/utils.js"); |
|
8 |
|
9 let {bytesAsHex: b2h} = CommonUtils; |
|
10 |
|
11 function run_test() { |
|
12 run_next_test(); |
|
13 } |
|
14 |
|
15 add_task(function test_pbkdf2() { |
|
16 let symmKey16 = CryptoUtils.pbkdf2Generate("secret phrase", "DNXPzPpiwn", 4096, 16); |
|
17 do_check_eq(symmKey16.length, 16); |
|
18 do_check_eq(btoa(symmKey16), "d2zG0d2cBfXnRwMUGyMwyg=="); |
|
19 do_check_eq(CommonUtils.encodeBase32(symmKey16), "O5WMNUO5TQC7LZ2HAMKBWIZQZI======"); |
|
20 let symmKey32 = CryptoUtils.pbkdf2Generate("passphrase", "salt", 4096, 32); |
|
21 do_check_eq(symmKey32.length, 32); |
|
22 }); |
|
23 |
|
24 // http://tools.ietf.org/html/rfc6070 |
|
25 // PBKDF2 HMAC-SHA1 Test Vectors |
|
26 add_task(function test_pbkdf2_hmac_sha1() { |
|
27 let pbkdf2 = CryptoUtils.pbkdf2Generate; |
|
28 let vectors = [ |
|
29 {P: "password", // (8 octets) |
|
30 S: "salt", // (4 octets) |
|
31 c: 1, |
|
32 dkLen: 20, |
|
33 DK: h("0c 60 c8 0f 96 1f 0e 71"+ |
|
34 "f3 a9 b5 24 af 60 12 06"+ |
|
35 "2f e0 37 a6"), // (20 octets) |
|
36 }, |
|
37 |
|
38 {P: "password", // (8 octets) |
|
39 S: "salt", // (4 octets) |
|
40 c: 2, |
|
41 dkLen: 20, |
|
42 DK: h("ea 6c 01 4d c7 2d 6f 8c"+ |
|
43 "cd 1e d9 2a ce 1d 41 f0"+ |
|
44 "d8 de 89 57"), // (20 octets) |
|
45 }, |
|
46 |
|
47 {P: "password", // (8 octets) |
|
48 S: "salt", // (4 octets) |
|
49 c: 4096, |
|
50 dkLen: 20, |
|
51 DK: h("4b 00 79 01 b7 65 48 9a"+ |
|
52 "be ad 49 d9 26 f7 21 d0"+ |
|
53 "65 a4 29 c1"), // (20 octets) |
|
54 }, |
|
55 |
|
56 // XXX Uncomment the following test after Bug 968567 lands |
|
57 // |
|
58 // XXX As it stands, I estimate that the CryptoUtils implementation will |
|
59 // take approximately 16 hours in my 2.3GHz MacBook to perform this many |
|
60 // rounds. |
|
61 // |
|
62 // {P: "password", // (8 octets) |
|
63 // S: "salt" // (4 octets) |
|
64 // c: 16777216, |
|
65 // dkLen = 20, |
|
66 // DK: h("ee fe 3d 61 cd 4d a4 e4"+ |
|
67 // "e9 94 5b 3d 6b a2 15 8c"+ |
|
68 // "26 34 e9 84"), // (20 octets) |
|
69 // }, |
|
70 |
|
71 {P: "passwordPASSWORDpassword", // (24 octets) |
|
72 S: "saltSALTsaltSALTsaltSALTsaltSALTsalt", // (36 octets) |
|
73 c: 4096, |
|
74 dkLen: 25, |
|
75 DK: h("3d 2e ec 4f e4 1c 84 9b"+ |
|
76 "80 c8 d8 36 62 c0 e4 4a"+ |
|
77 "8b 29 1a 96 4c f2 f0 70"+ |
|
78 "38"), // (25 octets) |
|
79 |
|
80 }, |
|
81 |
|
82 {P: "pass\0word", // (9 octets) |
|
83 S: "sa\0lt", // (5 octets) |
|
84 c: 4096, |
|
85 dkLen: 16, |
|
86 DK: h("56 fa 6a a7 55 48 09 9d"+ |
|
87 "cc 37 d7 f0 34 25 e0 c3"), // (16 octets) |
|
88 }, |
|
89 ]; |
|
90 |
|
91 for (let v of vectors) { |
|
92 do_check_eq(v.DK, b2h(pbkdf2(v.P, v.S, v.c, v.dkLen))); |
|
93 } |
|
94 }); |
|
95 |
|
96 // I can't find any normative ietf test vectors for pbkdf2 hmac-sha256. |
|
97 // The following vectors are derived with the same inputs as above (the sha1 |
|
98 // test). Results verified by users here: |
|
99 // https://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors |
|
100 add_task(function test_pbkdf2_hmac_sha256() { |
|
101 let pbkdf2 = CryptoUtils.pbkdf2Generate; |
|
102 let vectors = [ |
|
103 {P: "password", // (8 octets) |
|
104 S: "salt", // (4 octets) |
|
105 c: 1, |
|
106 dkLen: 32, |
|
107 DK: h("12 0f b6 cf fc f8 b3 2c"+ |
|
108 "43 e7 22 52 56 c4 f8 37"+ |
|
109 "a8 65 48 c9 2c cc 35 48"+ |
|
110 "08 05 98 7c b7 0b e1 7b"), // (32 octets) |
|
111 }, |
|
112 |
|
113 {P: "password", // (8 octets) |
|
114 S: "salt", // (4 octets) |
|
115 c: 2, |
|
116 dkLen: 32, |
|
117 DK: h("ae 4d 0c 95 af 6b 46 d3"+ |
|
118 "2d 0a df f9 28 f0 6d d0"+ |
|
119 "2a 30 3f 8e f3 c2 51 df"+ |
|
120 "d6 e2 d8 5a 95 47 4c 43"), // (32 octets) |
|
121 }, |
|
122 |
|
123 {P: "password", // (8 octets) |
|
124 S: "salt", // (4 octets) |
|
125 c: 4096, |
|
126 dkLen: 32, |
|
127 DK: h("c5 e4 78 d5 92 88 c8 41"+ |
|
128 "aa 53 0d b6 84 5c 4c 8d"+ |
|
129 "96 28 93 a0 01 ce 4e 11"+ |
|
130 "a4 96 38 73 aa 98 13 4a"), // (32 octets) |
|
131 }, |
|
132 |
|
133 {P: "passwordPASSWORDpassword", // (24 octets) |
|
134 S: "saltSALTsaltSALTsaltSALTsaltSALTsalt", // (36 octets) |
|
135 c: 4096, |
|
136 dkLen: 40, |
|
137 DK: h("34 8c 89 db cb d3 2b 2f"+ |
|
138 "32 d8 14 b8 11 6e 84 cf"+ |
|
139 "2b 17 34 7e bc 18 00 18"+ |
|
140 "1c 4e 2a 1f b8 dd 53 e1"+ |
|
141 "c6 35 51 8c 7d ac 47 e9"), // (40 octets) |
|
142 }, |
|
143 |
|
144 {P: "pass\0word", // (9 octets) |
|
145 S: "sa\0lt", // (5 octets) |
|
146 c: 4096, |
|
147 dkLen: 16, |
|
148 DK: h("89 b6 9d 05 16 f8 29 89"+ |
|
149 "3c 69 62 26 65 0a 86 87"), // (16 octets) |
|
150 }, |
|
151 ]; |
|
152 |
|
153 for (let v of vectors) { |
|
154 do_check_eq(v.DK, |
|
155 b2h(pbkdf2(v.P, v.S, v.c, v.dkLen, Ci.nsICryptoHMAC.SHA256, 32))); |
|
156 } |
|
157 }); |
|
158 |
|
159 // turn formatted test vectors into normal hex strings |
|
160 function h(hexStr) { |
|
161 return hexStr.replace(/\s+/g, ""); |
|
162 } |