Skip to content

Commit

Permalink
Add MAC Validation
Browse files Browse the repository at this point in the history
  • Loading branch information
justindbaur committed Jul 16, 2023
1 parent f2f389e commit cddbb7b
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 6 deletions.
19 changes: 17 additions & 2 deletions extensions/Bitwarden.Core/src/Types/EncryptedString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ private static byte[] DecryptAes256(ReadOnlySpan<char> encryptionPart, Symmetric
throw new FormatException();
}

// TODO: Validate mac

Span<byte> data = stackalloc byte[dataPart.Length];
converted = Convert.TryFromBase64Chars(dataPart, data, out bytesWritten);
if (!converted)
Expand All @@ -71,6 +69,15 @@ private static byte[] DecryptAes256(ReadOnlySpan<char> encryptionPart, Symmetric
}

data = data[..bytesWritten];

Span<byte> validatedMac = stackalloc byte[32];
ValidateMac(symmetricCryptoKey.Mac, iv, data, validatedMac);

if (!validatedMac.SequenceEqual(mac))
{
throw new FormatException("Invalid MAC");
}

Span<byte> output = stackalloc byte[data.Length];

using var aes = Aes.Create();
Expand Down Expand Up @@ -105,6 +112,14 @@ public static EncryptedString Parse(ReadOnlySpan<char> s)
return new EncryptedString(type, encryptionPart);
}

private static void ValidateMac(Span<byte> macKey, ReadOnlySpan<byte> iv, ReadOnlySpan<byte> data, Span<byte> destination)
{
var hmac = IncrementalHash.CreateHMAC(HashAlgorithmName.SHA256, macKey);
hmac.AppendData(iv);
hmac.AppendData(data);
hmac.TryGetCurrentHash(destination, out _);
}

public static bool TryParse(ReadOnlySpan<char> s, [MaybeNullWhen(false)] out EncryptedString result)
{
try
Expand Down
8 changes: 4 additions & 4 deletions extensions/Bitwarden.Core/src/Types/SymmetricCryptoKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ public class SymmetricCryptoKey : ISpanParsable<SymmetricCryptoKey>
const int KeyLength = 32;
const int MacLength = 32;

private readonly ReadOnlyMemory<byte> _rawData;
private readonly byte[] _rawData;

public ReadOnlyMemory<byte> Key => _rawData[..KeyLength];
public ReadOnlyMemory<byte> Mac => _rawData.Length == KeyLength + MacLength ? _rawData[KeyLength..] : default;
public byte[] Key => _rawData[..KeyLength];
public byte[]? Mac => _rawData.Length == KeyLength + MacLength ? _rawData[KeyLength..] : default;

private SymmetricCryptoKey(ReadOnlySpan<byte> rawData)
{
Expand Down Expand Up @@ -99,6 +99,6 @@ public static bool TryParse(ReadOnlySpan<char> s, [MaybeNullWhen(false)] out Sym

public override string ToString()
{
return Convert.ToBase64String(_rawData.Span);
return Convert.ToBase64String(_rawData);
}
}

0 comments on commit cddbb7b

Please sign in to comment.