diff options
author | Brian Turek <brian.turek@gmail.com> | 2016-05-13 14:21:17 -0400 |
---|---|---|
committer | Brian Turek <brian.turek@gmail.com> | 2016-05-13 14:21:17 -0400 |
commit | dd994bb47d5d99960278b903a7c42d63174f4c54 (patch) | |
tree | 87ed35ada9b576494da0fa1b1e949897dfbea91a | |
parent | cc4e183a287d3afbdf9d38c65ff8360386ae3fa9 (diff) | |
download | jsSHA-dd994bb47d5d99960278b903a7c42d63174f4c54.zip jsSHA-dd994bb47d5d99960278b903a7c42d63174f4c54.tar.gz jsSHA-dd994bb47d5d99960278b903a7c42d63174f4c54.tar.bz2 |
Fixing problem with inputs over 4 billion bits
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | src/sha_dev.js | 29 |
2 files changed, 23 insertions, 7 deletions
@@ -7,6 +7,7 @@ - Added new input and output type, "ARRAYBUFFER" which is a JavaScript ArrayBuffer - Now keeping smaller build files in NPM (thanks vogievetsky!) +- Fixed problem with hashing strings over 4 billion bits (thanks Eicar!) 2.0.2 (2015-10-31) ========================= diff --git a/src/sha_dev.js b/src/sha_dev.js index 676d2a7..b1601c4 100644 --- a/src/sha_dev.js +++ b/src/sha_dev.js @@ -23,6 +23,10 @@ var SUPPORTED_ALGS = 4 | 2 | 1; (function (global) { "use strict"; + + /* Globals */ + var TWO_PWR_32 = (1 << 16) * (1 << 16); + /** * Int_64 is a object for 2 32-bit numbers emulating a 64-bit number * @@ -1129,7 +1133,7 @@ var SUPPORTED_ALGS = 4 | 2 | 1; */ function finalizeSHA1(remainder, remainderBinLen, processedBinLen, H) { - var i, appendedMessageLength, offset; + var i, appendedMessageLength, offset, totalLen; /* The 65 addition is a hack but it works. The correct number is actually 72 (64 + 8) but the below math fails if @@ -1143,9 +1147,15 @@ var SUPPORTED_ALGS = 4 | 2 | 1; /* Append '1' at the end of the binary string */ remainder[remainderBinLen >>> 5] |= 0x80 << (24 - (remainderBinLen % 32)); /* Append length of binary string in the position such that the new - length is a multiple of 512. Logic does not work for even multiples - of 512 but there can never be even multiples of 512 */ - remainder[offset] = remainderBinLen + processedBinLen; + * length is a multiple of 512. Logic does not work for even multiples + * of 512 but there can never be even multiples of 512. JavaScript + * numbers are limited to 2^53 so it's "safe" to treat the totalLen as + * a 64-bit integer. */ + totalLen = remainderBinLen + processedBinLen; + remainder[offset] = totalLen & 0xFFFFFFFF; + /* Bitwise operators treat the operand as a 32-bit number so need to + * use hacky division and round to get access to upper 32-ish bits */ + remainder[offset - 1] = (totalLen / TWO_PWR_32) | 0; appendedMessageLength = remainder.length; @@ -1356,7 +1366,7 @@ var SUPPORTED_ALGS = 4 | 2 | 1; */ function finalizeSHA2(remainder, remainderBinLen, processedBinLen, H, variant) { - var i, appendedMessageLength, offset, retVal, binaryStringInc; + var i, appendedMessageLength, offset, retVal, binaryStringInc, totalLen; if ((variant === "SHA-224" || variant === "SHA-256") && (2 & SUPPORTED_ALGS)) @@ -1392,8 +1402,13 @@ var SUPPORTED_ALGS = 4 | 2 | 1; /* Append '1' at the end of the binary string */ remainder[remainderBinLen >>> 5] |= 0x80 << (24 - remainderBinLen % 32); /* Append length of binary string in the position such that the new - * length is correct */ - remainder[offset] = remainderBinLen + processedBinLen; + * length is correct. JavaScript numbers are limited to 2^53 so it's + * "safe" to treat the totalLen as a 64-bit integer. */ + totalLen = remainderBinLen + processedBinLen; + remainder[offset] = totalLen & 0xFFFFFFFF; + /* Bitwise operators treat the operand as a 32-bit number so need to + * use hacky division and round to get access to upper 32-ish bits */ + remainder[offset - 1] = (totalLen / TWO_PWR_32) | 0; appendedMessageLength = remainder.length; |