Few more steps
This commit is contained in:
parent
465bdf2bd3
commit
6e0fe271ab
2 changed files with 63 additions and 31 deletions
|
@ -77,6 +77,7 @@ function base64EncArr (aBytes) {
|
|||
*** Type conversion utilities ***
|
||||
*********************************/
|
||||
// Strings/arrays
|
||||
//TODO: Throw all this shit in favor of consistent types
|
||||
var StaticByteBufferProto = new dcodeIO.ByteBuffer().__proto__;
|
||||
var StaticArrayBufferProto = new ArrayBuffer().__proto__;
|
||||
var StaticUint8ArrayProto = new Uint8Array().__proto__;
|
||||
|
@ -108,6 +109,8 @@ function toArrayBuffer(thing) {
|
|||
//TODO: Optimize this for specific cases
|
||||
if (thing === undefined)
|
||||
return undefined;
|
||||
if (thing === Object(thing) && thing.__proto__ == StaticArrayBufferProto)
|
||||
return thing;
|
||||
if (!getStringable(thing))
|
||||
throw "Tried to convert a non-stringable thing of type " + typeof thing + " to an array buffer";
|
||||
var str = getString(thing);
|
||||
|
@ -396,6 +399,8 @@ function getRandomBytes(size) {
|
|||
}
|
||||
}
|
||||
|
||||
var crypto_tests = {};
|
||||
|
||||
(function(crypto, $, undefined) {
|
||||
var createNewKeyPair = function(callback) {
|
||||
var privKey = getRandomBytes(32);
|
||||
|
@ -467,31 +472,39 @@ function getRandomBytes(size) {
|
|||
}
|
||||
|
||||
var HMACSHA256 = function(input, key) {
|
||||
//TODO: return type
|
||||
//TODO: Waaayyyy less type conversion here (probably just means replacing CryptoJS)
|
||||
return CryptoJS.HmacSHA256(
|
||||
CryptoJS.lib.WordArray.create(toArrayBuffer(input)),
|
||||
CryptoJS.enc.Latin1.parse(getString(key)))
|
||||
.toString(CryptoJS.enc.Latin1);
|
||||
}
|
||||
|
||||
crypto_tests.HKDF = function(input, salt, info) {
|
||||
// Specific implementation of RFC 5869 that only returns exactly 64 bytes
|
||||
var PRK = HMACSHA256(input, salt);
|
||||
|
||||
var infoString = getString(info);
|
||||
var T1 = HMACSHA256(infoString + String.fromCharCode(1), PRK);
|
||||
var T2 = HMACSHA256(getString(T1) + infoString + String.fromCharCode(2), PRK);
|
||||
|
||||
return [ T1, T2 ];
|
||||
}
|
||||
|
||||
var HKDF = function(input, salt, info) {
|
||||
var key;
|
||||
// HKDF for TextSecure has a bit of additional handling - salts always end up being 32 bytes
|
||||
if (salt == '') {
|
||||
var key = new ArrayBuffer(32);
|
||||
var uintKey = new Uint8Array(key);
|
||||
salt = new ArrayBuffer(32);
|
||||
var uintKey = new Uint8Array(salt);
|
||||
for (var i = 0; i < 32; i++)
|
||||
uintKey[i] = 0;
|
||||
} else
|
||||
key = toArrayBuffer(salt);
|
||||
}
|
||||
|
||||
if (key.byteLength != 32)
|
||||
salt = toArrayBuffer(salt);
|
||||
|
||||
if (salt.byteLength != 32)
|
||||
throw "Got salt of incorrect length";
|
||||
|
||||
var PRK = HMACSHA256(input, salt);
|
||||
|
||||
HMACSHA256(salt, input);
|
||||
var hkdf = "HKDF(" + input + ", " + salt + ", " + info + ")"; //TODO
|
||||
return [ hkdf.substring(0, 32), hkdf.substring(32, 64) ];
|
||||
return crypto_tests.HKDF(input, salt, info);
|
||||
}
|
||||
|
||||
var decryptPaddedAES = function(ciphertext, key, iv) {
|
||||
|
@ -518,11 +531,11 @@ function getRandomBytes(size) {
|
|||
|
||||
var sharedSecret;
|
||||
ECDHE(theirEphemeralPubKey, ourIdentityPrivKey, function(ecRes) {
|
||||
sharedSecret = ecRes;
|
||||
sharedSecret = getString(ecRes);
|
||||
|
||||
function finishInit() {
|
||||
ECDHE(theirEphemeralPubKey, ourEphemeralPrivKey, function(ecRes) {
|
||||
sharedSecret += ecRes;
|
||||
sharedSecret += getString(ecRes);
|
||||
|
||||
var masterKey = HKDF(sharedSecret, '', "WhisperText");
|
||||
callback({ rootKey: masterKey[0], chainKey: masterKey[1] });
|
||||
|
@ -531,12 +544,12 @@ function getRandomBytes(size) {
|
|||
|
||||
if (isInitiator) {
|
||||
ECDHE(theirIdentityPubKey, ourEphemeralPrivKey, function(ecRes) {
|
||||
sharedSecret = sharedSecret + ecRes;
|
||||
sharedSecret = sharedSecret + getString(ecRes);
|
||||
finishInit();
|
||||
});
|
||||
} else {
|
||||
ECDHE(theirIdentityPubKey, ourEphemeralPrivKey, function(ecRes) {
|
||||
sharedSecret = ecRes + sharedSecret;
|
||||
sharedSecret = getString(ecRes) + sharedSecret;
|
||||
finishInit();
|
||||
});
|
||||
}
|
||||
|
@ -631,7 +644,7 @@ function getRandomBytes(size) {
|
|||
|
||||
var message = decodeWhisperMessageProtobuf(messageProto);
|
||||
|
||||
maybeStepRatchet(session, getString(message.ephemeralKey), message.previousCounter, function() {
|
||||
maybeStepRatchet(session, message.ephemeralKey, message.previousCounter, function() {
|
||||
var chain = session[getString(message.ephemeralKey)];
|
||||
|
||||
fillMessageKeys(chain, message.counter);
|
||||
|
|
47
js/test.js
47
js/test.js
|
@ -114,7 +114,7 @@ registerOnLoadFunction(function() {
|
|||
crypto.generateKeys(function() {
|
||||
callback(true);
|
||||
});
|
||||
}, "Test simple create key");
|
||||
}, "Test simple create key", true);
|
||||
|
||||
TEST(function(callback) {
|
||||
// These are just some random curve25519 test vectors I found online
|
||||
|
@ -167,21 +167,40 @@ registerOnLoadFunction(function() {
|
|||
});
|
||||
}, "Simple Curve25519 test vector");
|
||||
|
||||
TEST(function(callback) {
|
||||
var IKM = new Uint8Array(new ArrayBuffer(22));
|
||||
for (var i = 0; i < 22; i++)
|
||||
IKM[i] = 11;
|
||||
|
||||
var salt = new Uint8Array(new ArrayBuffer(13));
|
||||
for (var i = 0; i < 13; i++)
|
||||
salt[i] = i;
|
||||
|
||||
var info = new Uint8Array(new ArrayBuffer(10));
|
||||
for (var i = 0; i < 10; i++)
|
||||
info[i] = 240 + i;
|
||||
|
||||
var OKM = crypto_tests.HKDF(IKM, salt, info);
|
||||
var T1 = hexToArrayBuffer("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf");
|
||||
var T2 = hexToArrayBuffer("34007208d5b887185865");
|
||||
callback(getString(OKM[0]) == getString(T1) && getString(OKM[1]).substring(0, 10) == getString(T2));
|
||||
}, "HMAC RFC5869 Test vectors");
|
||||
|
||||
var axolotlTestVectors = {
|
||||
aliceIdentityPriv: hexToArrayBuffer("38115e981295947fb6130c3a9521760e9692476143810c64bb502d2a7757f953"),
|
||||
aliceIdentityPub: hexToArrayBuffer("057f6f0cf5a353e3c2fa73774d36b07d491c2ba5285388a4dc7be3b08de4528933"),
|
||||
bobIdentityPriv: hexToArrayBuffer("9069fadc08faaf6265a90a41fd1a9214bc70eb44ab30aa92ea5ad5a6b8609557"),
|
||||
bobIdentityPub: hexToArrayBuffer("05889d0f94f4049fac36cc939c50dabec18c2af8e344f2cdf72cb5b0b02323337c"),
|
||||
aliceLastResort: hexToArrayBuffer("10cd8adcbbf5a0157ed45e3be2e0bde5e91c3cdf77954530ac75c6ae9b8c2458"),
|
||||
bobLastResort: hexToArrayBuffer("9855c7ce178404bb02c6c026103cc7d74d68a12f77d35d03df40a5f2dff6784d"),
|
||||
alicePre0: hexToArrayBuffer("981bea233e094a34f7d564c63515af4691d3059268371c3b26f37a141e4fb553"),
|
||||
alicePre1: hexToArrayBuffer("18b27cac90879c8ba5b1d6eb29d08ee380bac2e1022ead9a7dbe5ddfa0009852"),
|
||||
bobPre0: hexToArrayBuffer("780fc02d2b8ffce8cd6f92233ce28b46a487dafeb97597461b1ed964fb118e5c"),
|
||||
bobPre1: hexToArrayBuffer("c8e218839b33ae6c54d73ef56ad77551b6575e64c5b4acc0f0710b93799c3b56"),
|
||||
aliceToBob: hexToArrayBuffer("08031205414c4943452203424f4228bff1f9c3c92832860122080012210541ef7f7215ffb6260413ab2c95bbd39d5d8d55241de87a6a7fa50ae5d99cbe741a21057f6f0cf5a353e3c2fa73774d36b07d491c2ba5285388a4dc7be3b08de4528933223b220a2105c851726034e7181614e21c6349d33f9bcff4f4becfc08c4422c6606cdc976d2c100018012209bb4876c684c88dd05207274341f4e3aa91"),
|
||||
aliceIdentityPriv: hexToArrayBuffer("d8dab419978a2693f2842691931e4c8aaa09a11e8a94b5817cc4f81a1c474a62"),
|
||||
aliceIdentityPub: hexToArrayBuffer("0502e9e6c0528ea9e44d8cb759aeaa02ae3eccbe3107de4f0815240b414744fd22"),
|
||||
bobIdentityPriv: hexToArrayBuffer("18bd2244222329293a303343759e8e9feb4a4e2771273111528ef97abb6a567e"),
|
||||
bobIdentityPub: hexToArrayBuffer("05b1cb0b5f1e5c93d20a3db2af0ab2512d39d91e6b671ee8e462a62658ba064a5b"),
|
||||
aliceLastResort: hexToArrayBuffer("8825a933b97d40f65ea37701800900f10d8ba6dff6979a5634e0dc6de8d9b24f"),
|
||||
bobLastResort: hexToArrayBuffer("c054dbefd8eee42ff3c1bb873def01f05411304ee07014ff86088c11f57b8e76"),
|
||||
alicePre0: hexToArrayBuffer("384db59677ea9545f1da2c10426b463fb3180bd30d294ad69cd91b44e3a3ad43"),
|
||||
alicePre1: hexToArrayBuffer("a841ece2aab82a0542c59c0daca5bd0ae36bc81b3f375ba0ffcc73ab2feacf6f"),
|
||||
bobPre0: hexToArrayBuffer("10b6b52b867f79e330a5fa3b46fd6a542a1dc21d1103f4d2e8f741c0dd989474"),
|
||||
bobPre1: hexToArrayBuffer("70be59ec978e3aaa95b64635b09ad1a614c2eda2142ac577b1eb6b1ec8e7f270"),
|
||||
aliceToBob: hexToArrayBuffer("08031205414c4943452203424f4228c3dfc6cac92832860122080012210518761fa74e002dbbbb140ca7950fb83a3aab3dd4fb7b75ec87eea17f0cde7e0a1a210502e9e6c0528ea9e44d8cb759aeaa02ae3eccbe3107de4f0815240b414744fd22223b220a2105fbad228c11ab8098c3fcb9c16ff1f9df705dce81ea4b6e3df988148e254270751000180122093cfc98c3bc5557b31ffe8deba6900bcfe6"),
|
||||
plain: hexToArrayBuffer("0a07486920426f6221"),
|
||||
sessionKey: hexToArrayBuffer("03a3a58503e91c9e5ae179fa87bbb755f7afe35a2bffce4932cec2c2fcaa28832389e20000c7e1e7c7365959e4146d98f3620df9"),
|
||||
encryptedMessage: hexToArrayBuffer("41576d4e6f7431327748385470366f724c7735416a62425446767139314c376857757a663854394e54775256326955384f76376265494463587030396634356441506159515a456a6e71704176364852574f3539584e35796d73507548423342716f78594e7136396346424c6e4145766439495a2f6674593835555a586e5668493574704e673946354c56627a4e70474563436672762f6a69393661675837755936335867746342683177412b5967364a472b37626a4a3044542b526e67383579325852705473644d3931794144776b5a744478616d7976412f714746556b37447a7353367061704a364459532b6e35673841457230764f37413d3d"),
|
||||
sessionKey: hexToArrayBuffer("34400f1fde8f3b96beb435c280a6e93b829679b7e948a85c2f7250c6bfd419dd411a0e9cb5f62cd8b39e2ba23e013763169eb40a"),
|
||||
encryptedMessage: hexToArrayBuffer("415733486e6d3165754275487778594d2f4b744a556e63364f67386e45754d6868663054704f486b45494b786c33616a79544552665531354c7539687a426736572f38546b7255583957653542724572724b3867367544554348425257555646774c4662614c67497446722f3242492f56434c31307a49666e2b765457524d324474475a46345a36553869717633566179443273354330417274386d6f48517342524970535a59387841566e584464572f466c4e7632706f6c5a6a2f464e597635552b56335933324552417572327464344a44654e6c544d4c6d4b7456387252384f354d7546626e735074336846456d496d374d7633573039673d3d")
|
||||
};
|
||||
|
||||
// Axolotl test vectors
|
||||
|
|
Loading…
Reference in a new issue