Merge pull request #4418 from timvandermeij/crypto-syntax

Making src/core/crypto.js adhere to the style guide
This commit is contained in:
Jonas Jenwald 2014-03-09 12:34:44 +01:00
commit 46487e3931

View File

@ -25,8 +25,9 @@ var ARCFourCipher = (function ARCFourCipherClosure() {
this.b = 0;
var s = new Uint8Array(256);
var i, j = 0, tmp, keyLength = key.length;
for (i = 0; i < 256; ++i)
for (i = 0; i < 256; ++i) {
s[i] = i;
}
for (i = 0; i < 256; ++i) {
tmp = s[i];
j = (j + tmp + key[i % keyLength]) & 0xFF;
@ -86,12 +87,14 @@ var calculateMD5 = (function calculateMD5Closure() {
var paddedLength = (length + 72) & ~63; // data + 9 extra bytes
var padded = new Uint8Array(paddedLength);
var i, j, n;
for (i = 0; i < length; ++i)
for (i = 0; i < length; ++i) {
padded[i] = data[offset++];
}
padded[i++] = 0x80;
n = paddedLength - 8;
while (i < n)
while (i < n) {
padded[i++] = 0;
}
padded[i++] = (length << 3) & 0xFF;
padded[i++] = (length >> 5) & 0xFF;
padded[i++] = (length >> 13) & 0xFF;
@ -135,18 +138,17 @@ var calculateMD5 = (function calculateMD5Closure() {
h3 = (h3 + d) | 0;
}
return new Uint8Array([
h0 & 0xFF, (h0 >> 8) & 0xFF, (h0 >> 16) & 0xFF, (h0 >>> 24) & 0xFF,
h1 & 0xFF, (h1 >> 8) & 0xFF, (h1 >> 16) & 0xFF, (h1 >>> 24) & 0xFF,
h2 & 0xFF, (h2 >> 8) & 0xFF, (h2 >> 16) & 0xFF, (h2 >>> 24) & 0xFF,
h3 & 0xFF, (h3 >> 8) & 0xFF, (h3 >> 16) & 0xFF, (h3 >>> 24) & 0xFF
h0 & 0xFF, (h0 >> 8) & 0xFF, (h0 >> 16) & 0xFF, (h0 >>> 24) & 0xFF,
h1 & 0xFF, (h1 >> 8) & 0xFF, (h1 >> 16) & 0xFF, (h1 >>> 24) & 0xFF,
h2 & 0xFF, (h2 >> 8) & 0xFF, (h2 >> 16) & 0xFF, (h2 >>> 24) & 0xFF,
h3 & 0xFF, (h3 >> 8) & 0xFF, (h3 >> 16) & 0xFF, (h3 >>> 24) & 0xFF
]);
}
return hash;
})();
var NullCipher = (function NullCipherClosure() {
function NullCipher() {
}
function NullCipher() {}
NullCipher.prototype = {
decryptBlock: function NullCipher_decryptBlock(data) {
@ -302,8 +304,9 @@ var AES128Cipher = (function AES128CipherClosure() {
var i, j, k;
var t, u, v;
// AddRoundKey
for (j = 0, k = 160; j < 16; ++j, ++k)
for (j = 0, k = 160; j < 16; ++j, ++k) {
state[j] ^= key[k];
}
for (i = 9; i >= 1; --i) {
// InvShiftRows
t = state[13]; state[13] = state[9]; state[9] = state[5];
@ -313,11 +316,13 @@ var AES128Cipher = (function AES128CipherClosure() {
t = state[15]; u = state[11]; v = state[7]; state[15] = state[3];
state[11] = t; state[7] = u; state[3] = v;
// InvSubBytes
for (j = 0; j < 16; ++j)
for (j = 0; j < 16; ++j) {
state[j] = inv_s[state[j]];
}
// AddRoundKey
for (j = 0, k = i * 16; j < 16; ++j, ++k)
for (j = 0, k = i * 16; j < 16; ++j, ++k) {
state[j] ^= key[k];
}
// InvMixColumns
for (j = 0; j < 16; j += 4) {
var s0 = mix[state[j]], s1 = mix[state[j + 1]],
@ -359,13 +364,15 @@ var AES128Cipher = (function AES128CipherClosure() {
for (i = 0; i < sourceLength; ++i) {
buffer[bufferLength] = data[i];
++bufferLength;
if (bufferLength < 16)
if (bufferLength < 16) {
continue;
}
// buffer is full, decrypting
var plain = decrypt128(buffer, this.key);
// xor-ing the IV vector to get plain text
for (j = 0; j < 16; ++j)
for (j = 0; j < 16; ++j) {
plain[j] ^= iv[j];
}
iv = buffer;
result.push(plain);
buffer = new Uint8Array(16);
@ -387,8 +394,9 @@ var AES128Cipher = (function AES128CipherClosure() {
result[result.length - 1] = lastBlock.subarray(0, 16 - lastBlock[15]);
}
var output = new Uint8Array(outputLength);
for (i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16)
for (i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) {
output.set(result[i], j);
}
return output;
}
@ -397,8 +405,9 @@ var AES128Cipher = (function AES128CipherClosure() {
var i, sourceLength = data.length;
var buffer = this.buffer, bufferLength = this.bufferPosition;
// waiting for IV values -- they are at the start of the stream
for (i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength)
for (i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) {
buffer[bufferLength] = data[i];
}
if (bufferLength < 16) {
// need more data
this.bufferLength = bufferLength;
@ -453,22 +462,25 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
var hashData = new Uint8Array(hashDataSize), i = 0, j, n;
if (password) {
n = Math.min(32, password.length);
for (; i < n; ++i)
for (; i < n; ++i) {
hashData[i] = password[i];
}
}
j = 0;
while (i < 32) {
hashData[i++] = defaultPasswordBytes[j++];
}
// as now the padded password in the hashData[0..i]
for (j = 0, n = ownerPassword.length; j < n; ++j)
for (j = 0, n = ownerPassword.length; j < n; ++j) {
hashData[i++] = ownerPassword[j];
}
hashData[i++] = flags & 0xFF;
hashData[i++] = (flags >> 8) & 0xFF;
hashData[i++] = (flags >> 16) & 0xFF;
hashData[i++] = (flags >>> 24) & 0xFF;
for (j = 0, n = fileId.length; j < n; ++j)
for (j = 0, n = fileId.length; j < n; ++j) {
hashData[i++] = fileId[j];
}
if (revision >= 4 && !encryptMetadata) {
hashData[i++] = 0xFF;
hashData[i++] = 0xFF;
@ -479,46 +491,53 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
var keyLengthInBytes = keyLength >> 3;
if (revision >= 3) {
for (j = 0; j < 50; ++j) {
hash = calculateMD5(hash, 0, keyLengthInBytes);
hash = calculateMD5(hash, 0, keyLengthInBytes);
}
}
var encryptionKey = hash.subarray(0, keyLengthInBytes);
var cipher, checkData;
if (revision >= 3) {
for (i = 0; i < 32; ++i)
for (i = 0; i < 32; ++i) {
hashData[i] = defaultPasswordBytes[i];
for (j = 0, n = fileId.length; j < n; ++j)
}
for (j = 0, n = fileId.length; j < n; ++j) {
hashData[i++] = fileId[j];
}
cipher = new ARCFourCipher(encryptionKey);
var checkData = cipher.encryptBlock(calculateMD5(hashData, 0, i));
n = encryptionKey.length;
var derivedKey = new Uint8Array(n), k;
for (j = 1; j <= 19; ++j) {
for (k = 0; k < n; ++k)
for (k = 0; k < n; ++k) {
derivedKey[k] = encryptionKey[k] ^ j;
}
cipher = new ARCFourCipher(derivedKey);
checkData = cipher.encryptBlock(checkData);
}
for (j = 0, n = checkData.length; j < n; ++j) {
if (userPassword[j] != checkData[j])
if (userPassword[j] != checkData[j]) {
return null;
}
}
} else {
cipher = new ARCFourCipher(encryptionKey);
checkData = cipher.encryptBlock(defaultPasswordBytes);
for (j = 0, n = checkData.length; j < n; ++j) {
if (userPassword[j] != checkData[j])
if (userPassword[j] != checkData[j]) {
return null;
}
}
}
return encryptionKey;
}
function decodeUserPassword(password, ownerPassword, revision, keyLength) {
var hashData = new Uint8Array(32), i = 0, j, n;
n = Math.min(32, password.length);
for (; i < n; ++i)
for (; i < n; ++i) {
hashData[i] = password[i];
}
j = 0;
while (i < 32) {
hashData[i++] = defaultPasswordBytes[j++];
@ -527,7 +546,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
var keyLengthInBytes = keyLength >> 3;
if (revision >= 3) {
for (j = 0; j < 50; ++j) {
hash = calculateMD5(hash, 0, hash.length);
hash = calculateMD5(hash, 0, hash.length);
}
}
@ -536,8 +555,9 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
userPassword = ownerPassword;
var derivedKey = new Uint8Array(keyLengthInBytes), k;
for (j = 19; j >= 0; j--) {
for (k = 0; k < keyLengthInBytes; ++k)
for (k = 0; k < keyLengthInBytes; ++k) {
derivedKey[k] = hash[k] ^ j;
}
cipher = new ARCFourCipher(derivedKey);
userPassword = cipher.encryptBlock(userPassword);
}
@ -552,31 +572,36 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
function CipherTransformFactory(dict, fileId, password) {
var filter = dict.get('Filter');
if (!isName(filter) || filter.name != 'Standard')
if (!isName(filter) || filter.name != 'Standard') {
error('unknown encryption method');
}
this.dict = dict;
var algorithm = dict.get('V');
if (!isInt(algorithm) ||
(algorithm != 1 && algorithm != 2 && algorithm != 4))
(algorithm != 1 && algorithm != 2 && algorithm != 4)) {
error('unsupported encryption algorithm');
}
this.algorithm = algorithm;
var keyLength = dict.get('Length') || 40;
if (!isInt(keyLength) ||
keyLength < 40 || (keyLength % 8) !== 0)
keyLength < 40 || (keyLength % 8) !== 0) {
error('invalid key length');
}
// prepare keys
var ownerPassword = stringToBytes(dict.get('O')).subarray(0, 32);
var userPassword = stringToBytes(dict.get('U')).subarray(0, 32);
var flags = dict.get('P');
var revision = dict.get('R');
var encryptMetadata = algorithm == 4 && // meaningful when V is 4
dict.get('EncryptMetadata') !== false; // makes true as default value
var encryptMetadata = (algorithm == 4 && // meaningful when V is 4
dict.get('EncryptMetadata') !== false); // makes true as default value
this.encryptMetadata = encryptMetadata;
var fileIdBytes = stringToBytes(fileId);
var passwordBytes;
if (password)
if (password) {
passwordBytes = stringToBytes(password);
}
var encryptionKey = prepareKeyData(fileIdBytes, passwordBytes,
ownerPassword, userPassword, flags,
@ -593,9 +618,10 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
revision, keyLength, encryptMetadata);
}
if (!encryptionKey)
if (!encryptionKey) {
throw new PasswordException('Incorrect Password',
PasswordResponses.INCORRECT_PASSWORD);
}
this.encryptionKey = encryptionKey;
@ -609,8 +635,9 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
function buildObjectKey(num, gen, encryptionKey, isAes) {
var key = new Uint8Array(encryptionKey.length + 9), i, n;
for (i = 0, n = encryptionKey.length; i < n; ++i)
for (i = 0, n = encryptionKey.length; i < n; ++i) {
key[i] = encryptionKey[i];
}
key[i++] = num & 0xFF;
key[i++] = (num >> 8) & 0xFF;
key[i++] = (num >> 16) & 0xFF;
@ -629,8 +656,9 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
function buildCipherConstructor(cf, name, num, gen, key) {
var cryptFilter = cf.get(name.name);
var cfm;
if (cryptFilter !== null && cryptFilter !== undefined)
if (cryptFilter !== null && cryptFilter !== undefined) {
cfm = cryptFilter.get('CFM');
}
if (!cfm || cfm.name == 'None') {
return function cipherTransformFactoryBuildCipherConstructorNone() {
return new NullCipher();
@ -638,14 +666,12 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
}
if ('V2' == cfm.name) {
return function cipherTransformFactoryBuildCipherConstructorV2() {
return new ARCFourCipher(
buildObjectKey(num, gen, key, false));
return new ARCFourCipher(buildObjectKey(num, gen, key, false));
};
}
if ('AESV2' == cfm.name) {
return function cipherTransformFactoryBuildCipherConstructorAESV2() {
return new AES128Cipher(
buildObjectKey(num, gen, key, true));
return new AES128Cipher(buildObjectKey(num, gen, key, true));
};
}
error('Unknown crypto method');
@ -657,9 +683,9 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
if (this.algorithm == 4) {
return new CipherTransform(
buildCipherConstructor(this.cf, this.stmf,
num, gen, this.encryptionKey),
num, gen, this.encryptionKey),
buildCipherConstructor(this.cf, this.strf,
num, gen, this.encryptionKey));
num, gen, this.encryptionKey));
}
// algorithms 1 and 2
var key = buildObjectKey(num, gen, this.encryptionKey, false);