Wed, 31 Dec 2014 07:53:36 +0100
Correct small whitespace inconsistency, lost while renaming variables.
michael@0 | 1 | /* Any copyright is dedicated to the Public Domain. |
michael@0 | 2 | * http://creativecommons.org/publicdomain/zero/1.0/ */ |
michael@0 | 3 | |
michael@0 | 4 | Cu.import("resource://services-common/utils.js"); |
michael@0 | 5 | Cu.import("resource://services-crypto/utils.js"); |
michael@0 | 6 | |
michael@0 | 7 | // Test vectors from RFC 5869 |
michael@0 | 8 | |
michael@0 | 9 | // Test case 1 |
michael@0 | 10 | |
michael@0 | 11 | let tc1 = { |
michael@0 | 12 | IKM: "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", |
michael@0 | 13 | salt: "000102030405060708090a0b0c", |
michael@0 | 14 | info: "f0f1f2f3f4f5f6f7f8f9", |
michael@0 | 15 | L: 42, |
michael@0 | 16 | PRK: "077709362c2e32df0ddc3f0dc47bba63" + |
michael@0 | 17 | "90b6c73bb50f9c3122ec844ad7c2b3e5", |
michael@0 | 18 | OKM: "3cb25f25faacd57a90434f64d0362f2a" + |
michael@0 | 19 | "2d2d0a90cf1a5a4c5db02d56ecc4c5bf" + |
michael@0 | 20 | "34007208d5b887185865" |
michael@0 | 21 | }; |
michael@0 | 22 | |
michael@0 | 23 | // Test case 2 |
michael@0 | 24 | |
michael@0 | 25 | let tc2 = { |
michael@0 | 26 | IKM: "000102030405060708090a0b0c0d0e0f" + |
michael@0 | 27 | "101112131415161718191a1b1c1d1e1f" + |
michael@0 | 28 | "202122232425262728292a2b2c2d2e2f" + |
michael@0 | 29 | "303132333435363738393a3b3c3d3e3f" + |
michael@0 | 30 | "404142434445464748494a4b4c4d4e4f", |
michael@0 | 31 | salt: "606162636465666768696a6b6c6d6e6f" + |
michael@0 | 32 | "707172737475767778797a7b7c7d7e7f" + |
michael@0 | 33 | "808182838485868788898a8b8c8d8e8f" + |
michael@0 | 34 | "909192939495969798999a9b9c9d9e9f" + |
michael@0 | 35 | "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", |
michael@0 | 36 | info: "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" + |
michael@0 | 37 | "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + |
michael@0 | 38 | "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" + |
michael@0 | 39 | "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" + |
michael@0 | 40 | "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", |
michael@0 | 41 | L: 82, |
michael@0 | 42 | PRK: "06a6b88c5853361a06104c9ceb35b45c" + |
michael@0 | 43 | "ef760014904671014a193f40c15fc244", |
michael@0 | 44 | OKM: "b11e398dc80327a1c8e7f78c596a4934" + |
michael@0 | 45 | "4f012eda2d4efad8a050cc4c19afa97c" + |
michael@0 | 46 | "59045a99cac7827271cb41c65e590e09" + |
michael@0 | 47 | "da3275600c2f09b8367793a9aca3db71" + |
michael@0 | 48 | "cc30c58179ec3e87c14c01d5c1f3434f" + |
michael@0 | 49 | "1d87" |
michael@0 | 50 | }; |
michael@0 | 51 | |
michael@0 | 52 | // Test case 3 |
michael@0 | 53 | |
michael@0 | 54 | let tc3 = { |
michael@0 | 55 | IKM: "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", |
michael@0 | 56 | salt: "", |
michael@0 | 57 | info: "", |
michael@0 | 58 | L: 42, |
michael@0 | 59 | PRK: "19ef24a32c717b167f33a91d6f648bdf" + |
michael@0 | 60 | "96596776afdb6377ac434c1c293ccb04", |
michael@0 | 61 | OKM: "8da4e775a563c18f715f802a063c5a31" + |
michael@0 | 62 | "b8a11f5c5ee1879ec3454e5f3c738d2d" + |
michael@0 | 63 | "9d201395faa4b61a96c8" |
michael@0 | 64 | }; |
michael@0 | 65 | |
michael@0 | 66 | function sha256HMAC(message, key) { |
michael@0 | 67 | let h = CryptoUtils.makeHMACHasher(Ci.nsICryptoHMAC.SHA256, key); |
michael@0 | 68 | return CryptoUtils.digestBytes(message, h); |
michael@0 | 69 | } |
michael@0 | 70 | |
michael@0 | 71 | function _hexToString(hex) { |
michael@0 | 72 | let ret = ""; |
michael@0 | 73 | if (hex.length % 2 != 0) { |
michael@0 | 74 | return false; |
michael@0 | 75 | } |
michael@0 | 76 | |
michael@0 | 77 | for (let i = 0; i < hex.length; i += 2) { |
michael@0 | 78 | let cur = hex[i] + hex[i + 1]; |
michael@0 | 79 | ret += String.fromCharCode(parseInt(cur, 16)); |
michael@0 | 80 | } |
michael@0 | 81 | return ret; |
michael@0 | 82 | } |
michael@0 | 83 | |
michael@0 | 84 | function extract_hex(salt, ikm) { |
michael@0 | 85 | salt = _hexToString(salt); |
michael@0 | 86 | ikm = _hexToString(ikm); |
michael@0 | 87 | return CommonUtils.bytesAsHex(sha256HMAC(ikm, CryptoUtils.makeHMACKey(salt))); |
michael@0 | 88 | } |
michael@0 | 89 | |
michael@0 | 90 | function expand_hex(prk, info, len) { |
michael@0 | 91 | prk = _hexToString(prk); |
michael@0 | 92 | info = _hexToString(info); |
michael@0 | 93 | return CommonUtils.bytesAsHex(CryptoUtils.hkdfExpand(prk, info, len)); |
michael@0 | 94 | } |
michael@0 | 95 | |
michael@0 | 96 | function hkdf_hex(ikm, salt, info, len) { |
michael@0 | 97 | ikm = _hexToString(ikm); |
michael@0 | 98 | if (salt) |
michael@0 | 99 | salt = _hexToString(salt); |
michael@0 | 100 | info = _hexToString(info); |
michael@0 | 101 | return CommonUtils.bytesAsHex(CryptoUtils.hkdf(ikm, salt, info, len)); |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | function run_test() { |
michael@0 | 105 | _("Verifying Test Case 1"); |
michael@0 | 106 | do_check_eq(extract_hex(tc1.salt, tc1.IKM), tc1.PRK); |
michael@0 | 107 | do_check_eq(expand_hex(tc1.PRK, tc1.info, tc1.L), tc1.OKM); |
michael@0 | 108 | do_check_eq(hkdf_hex(tc1.IKM, tc1.salt, tc1.info, tc1.L), tc1.OKM); |
michael@0 | 109 | |
michael@0 | 110 | _("Verifying Test Case 2"); |
michael@0 | 111 | do_check_eq(extract_hex(tc2.salt, tc2.IKM), tc2.PRK); |
michael@0 | 112 | do_check_eq(expand_hex(tc2.PRK, tc2.info, tc2.L), tc2.OKM); |
michael@0 | 113 | do_check_eq(hkdf_hex(tc2.IKM, tc2.salt, tc2.info, tc2.L), tc2.OKM); |
michael@0 | 114 | |
michael@0 | 115 | _("Verifying Test Case 3"); |
michael@0 | 116 | do_check_eq(extract_hex(tc3.salt, tc3.IKM), tc3.PRK); |
michael@0 | 117 | do_check_eq(expand_hex(tc3.PRK, tc3.info, tc3.L), tc3.OKM); |
michael@0 | 118 | do_check_eq(hkdf_hex(tc3.IKM, tc3.salt, tc3.info, tc3.L), tc3.OKM); |
michael@0 | 119 | do_check_eq(hkdf_hex(tc3.IKM, undefined, tc3.info, tc3.L), tc3.OKM); |
michael@0 | 120 | } |