constant time equality for mac check on decrypt

This commit is contained in:
Kyle Spearrin 2017-04-27 11:35:30 -04:00
parent 4eee908f2f
commit b3e94b13f7
1 changed files with 20 additions and 5 deletions

View File

@ -270,7 +270,7 @@ angular
var cipherString = iv + '|' + ct; var cipherString = iv + '|' + ct;
if (key.macKey) { if (key.macKey) {
var mac = computeMac(ctBytes, ivBytes, key.macKey); var mac = computeMac(ctBytes, ivBytes, key.macKey, true);
cipherString = cipherString + '|' + mac; cipherString = cipherString + '|' + mac;
} }
@ -356,8 +356,9 @@ angular
var ctBytes = forge.util.decode64(encPieces[1]); var ctBytes = forge.util.decode64(encPieces[1]);
if (key.macKey && encPieces.length > 2) { if (key.macKey && encPieces.length > 2) {
var computedMac = computeMac(ctBytes, ivBytes, key.macKey); var macBytes = forge.util.decode64(encPieces[2]);
if (computedMac !== encPieces[2]) { var computedMacBytes = computeMac(ctBytes, ivBytes, key.macKey, false);
if (!bytesAreEqual(macBytes, computedMacBytes)) {
console.error('MAC failed.'); console.error('MAC failed.');
return null; return null;
} }
@ -422,12 +423,26 @@ angular
return decBytes; return decBytes;
}; };
function computeMac(ct, iv, macKey) { function computeMac(ct, iv, macKey, b64Output) {
var hmac = forge.hmac.create(); var hmac = forge.hmac.create();
hmac.start('sha256', macKey); hmac.start('sha256', macKey);
hmac.update(iv + ct); hmac.update(iv + ct);
var mac = hmac.digest(); var mac = hmac.digest();
return forge.util.encode64(mac.getBytes()); return b64Output ? forge.util.encode64(mac.getBytes()) : mac.getBytes();
}
// Constant time comparison. This removes the early-out optimizations of normal equality checks.
function bytesAreEqual(a, b) {
if (a.length !== b.length) {
return false;
}
var result = 0;
for (var i = 0; i < a.length; i++) {
result |= a[i] ^ b[i];
}
return result === 0;
} }
function SymmetricCryptoKey(keyBytes, b64KeyBytes, encType) { function SymmetricCryptoKey(keyBytes, b64KeyBytes, encType) {