Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Commit

Permalink
protect mac comparisons from timing attacks
Browse files Browse the repository at this point in the history
  • Loading branch information
kspearrin committed Apr 27, 2017
1 parent b3e94b1 commit 7d0a34f
Showing 1 changed file with 13 additions and 11 deletions.
24 changes: 13 additions & 11 deletions src/app/services/cryptoService.js
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ angular
if (key.macKey && encPieces.length > 2) {
var macBytes = forge.util.decode64(encPieces[2]);
var computedMacBytes = computeMac(ctBytes, ivBytes, key.macKey, false);
if (!bytesAreEqual(macBytes, computedMacBytes)) {
if (!macsEqual(key.macKey, macBytes, computedMacBytes)) {
console.error('MAC failed.');
return null;
}
Expand Down Expand Up @@ -431,18 +431,20 @@ angular
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;
}
// Safely compare two MACs in a way that protects against timing attacks.
// ref: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/
function macsEqual(macKey, mac1, mac2) {
var hmac = forge.hmac.create();

var result = 0;
for (var i = 0; i < a.length; i++) {
result |= a[i] ^ b[i];
}
hmac.start('sha256', macKey);
hmac.update(mac1);
mac1 = hmac.digest().getBytes();

hmac.start(null, null);
hmac.update(mac2);
mac2 = hmac.digest().getBytes();

return result === 0;
return mac1 === mac2;
}

function SymmetricCryptoKey(keyBytes, b64KeyBytes, encType) {
Expand Down

0 comments on commit 7d0a34f

Please sign in to comment.