mirror of
https://github.com/bitwarden/android.git
synced 2024-12-26 19:08:32 +03:00
[PS-2249] Implement Argon2 (#2293)
* Implement Argon2 * Fix incorrect argon2 type on iOS * Switch argon2 implementation to native bindings * Change argon2 to save iterations instead of memory as 'kdfIterations' * Remove mistakenly added import * Remove unused library
This commit is contained in:
parent
e0401f4098
commit
9613019d4d
12 changed files with 54 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -30,6 +30,7 @@ Components/
|
||||||
[Rr]eleases/
|
[Rr]eleases/
|
||||||
x64/
|
x64/
|
||||||
x86/
|
x86/
|
||||||
|
!src/lib/x86/
|
||||||
build/
|
build/
|
||||||
bld/
|
bld/
|
||||||
[Bb]in/
|
[Bb]in/
|
||||||
|
|
|
@ -169,6 +169,10 @@
|
||||||
<GoogleServicesJson Include="google-services.json" />
|
<GoogleServicesJson Include="google-services.json" />
|
||||||
<GoogleServicesJson Include="google-services.json.enc" />
|
<GoogleServicesJson Include="google-services.json.enc" />
|
||||||
<None Include="fdroid-keystore.jks.enc" />
|
<None Include="fdroid-keystore.jks.enc" />
|
||||||
|
<AndroidNativeLibrary Include="lib\arm64-v8a\libargon2.so" />
|
||||||
|
<AndroidNativeLibrary Include="lib\armeabi-v7a\libargon2.so" />
|
||||||
|
<AndroidNativeLibrary Include="lib\x86\libargon2.so" />
|
||||||
|
<AndroidNativeLibrary Include="lib\x86_64\libargon2.so" />
|
||||||
<None Include="Properties\AndroidManifest.xml" />
|
<None Include="Properties\AndroidManifest.xml" />
|
||||||
<None Include="upload-keystore.jks.enc" />
|
<None Include="upload-keystore.jks.enc" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -5,6 +5,8 @@ using Org.BouncyCastle.Crypto.Digests;
|
||||||
using Org.BouncyCastle.Crypto.Generators;
|
using Org.BouncyCastle.Crypto.Generators;
|
||||||
using Org.BouncyCastle.Crypto.Parameters;
|
using Org.BouncyCastle.Crypto.Parameters;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Java.Lang;
|
||||||
|
|
||||||
namespace Bit.Droid.Services
|
namespace Bit.Droid.Services
|
||||||
{
|
{
|
||||||
|
@ -33,5 +35,15 @@ namespace Bit.Droid.Services
|
||||||
generator.Init(password, salt, iterations);
|
generator.Init(password, salt, iterations);
|
||||||
return ((KeyParameter)generator.GenerateDerivedMacParameters(keySize)).GetKey();
|
return ((KeyParameter)generator.GenerateDerivedMacParameters(keySize)).GetKey();
|
||||||
}
|
}
|
||||||
|
public byte[] Argon2id(byte[] password, byte[] salt, int iterations, int memory, int parallelism)
|
||||||
|
{
|
||||||
|
JavaSystem.LoadLibrary("argon2");
|
||||||
|
var hash = new byte[32];
|
||||||
|
argon2id_hash_raw(iterations, memory, parallelism, password, password.Length, password, salt.Length, hash, 32);
|
||||||
|
return hash.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("argon2", EntryPoint = "argon2id_hash_raw")]
|
||||||
|
internal static extern int argon2id_hash_raw(int timeCost, int memoryCost, int parallelism, byte[] pwd, int pwdlen, byte[] salt, int saltlen, ref byte hash, int hashlen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
src/Android/lib/arm64-v8a/libargon2.so
Executable file
BIN
src/Android/lib/arm64-v8a/libargon2.so
Executable file
Binary file not shown.
BIN
src/Android/lib/armeabi-v7a/libargon2.so
Executable file
BIN
src/Android/lib/armeabi-v7a/libargon2.so
Executable file
Binary file not shown.
BIN
src/Android/lib/x86/libargon2.so
Executable file
BIN
src/Android/lib/x86/libargon2.so
Executable file
Binary file not shown.
BIN
src/Android/lib/x86_64/libargon2.so
Executable file
BIN
src/Android/lib/x86_64/libargon2.so
Executable file
Binary file not shown.
|
@ -10,6 +10,10 @@ namespace Bit.Core.Abstractions
|
||||||
Task<byte[]> Pbkdf2Async(byte[] password, string salt, CryptoHashAlgorithm algorithm, int iterations);
|
Task<byte[]> Pbkdf2Async(byte[] password, string salt, CryptoHashAlgorithm algorithm, int iterations);
|
||||||
Task<byte[]> Pbkdf2Async(string password, byte[] salt, CryptoHashAlgorithm algorithm, int iterations);
|
Task<byte[]> Pbkdf2Async(string password, byte[] salt, CryptoHashAlgorithm algorithm, int iterations);
|
||||||
Task<byte[]> Pbkdf2Async(byte[] password, byte[] salt, CryptoHashAlgorithm algorithm, int iterations);
|
Task<byte[]> Pbkdf2Async(byte[] password, byte[] salt, CryptoHashAlgorithm algorithm, int iterations);
|
||||||
|
Task<byte[]> Argon2Async(string password, string salt, int iterations, int memory, int parallelism);
|
||||||
|
Task<byte[]> Argon2Async(byte[] password, string salt, int iterations, int memory, int parallelism);
|
||||||
|
Task<byte[]> Argon2Async(string password, byte[] salt, int iterations, int memory, int parallelism);
|
||||||
|
Task<byte[]> Argon2Async(byte[] password, byte[] salt, int iterations, int memory, int parallelism);
|
||||||
Task<byte[]> HkdfAsync(byte[] ikm, string salt, string info, int outputByteSize, HkdfAlgorithm algorithm);
|
Task<byte[]> HkdfAsync(byte[] ikm, string salt, string info, int outputByteSize, HkdfAlgorithm algorithm);
|
||||||
Task<byte[]> HkdfAsync(byte[] ikm, byte[] salt, string info, int outputByteSize, HkdfAlgorithm algorithm);
|
Task<byte[]> HkdfAsync(byte[] ikm, byte[] salt, string info, int outputByteSize, HkdfAlgorithm algorithm);
|
||||||
Task<byte[]> HkdfAsync(byte[] ikm, string salt, byte[] info, int outputByteSize, HkdfAlgorithm algorithm);
|
Task<byte[]> HkdfAsync(byte[] ikm, string salt, byte[] info, int outputByteSize, HkdfAlgorithm algorithm);
|
||||||
|
|
|
@ -5,5 +5,6 @@ namespace Bit.Core.Abstractions
|
||||||
public interface ICryptoPrimitiveService
|
public interface ICryptoPrimitiveService
|
||||||
{
|
{
|
||||||
byte[] Pbkdf2(byte[] password, byte[] salt, CryptoHashAlgorithm algorithm, int iterations);
|
byte[] Pbkdf2(byte[] password, byte[] salt, CryptoHashAlgorithm algorithm, int iterations);
|
||||||
|
byte[] Argon2id(byte[] password, byte[] salt, int iterations, int memory, int parallelism);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
{
|
{
|
||||||
public enum KdfType : byte
|
public enum KdfType : byte
|
||||||
{
|
{
|
||||||
PBKDF2_SHA256 = 0
|
PBKDF2_SHA256 = 0,
|
||||||
|
Argon2id = 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,6 +406,14 @@ namespace Bit.Core.Services
|
||||||
key = await _cryptoFunctionService.Pbkdf2Async(password, salt,
|
key = await _cryptoFunctionService.Pbkdf2Async(password, salt,
|
||||||
CryptoHashAlgorithm.Sha256, kdfIterations.Value);
|
CryptoHashAlgorithm.Sha256, kdfIterations.Value);
|
||||||
}
|
}
|
||||||
|
else if (kdf == KdfType.Argon2id)
|
||||||
|
{
|
||||||
|
var iterations = kdfIterations.Value;
|
||||||
|
const int parallelism = 1;
|
||||||
|
const int memory = 1024 * 16; // 16 MiB
|
||||||
|
|
||||||
|
key = await _cryptoFunctionService.Argon2Async(password, salt, iterations, memory, parallelism);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception("Unknown kdf.");
|
throw new Exception("Unknown kdf.");
|
||||||
|
|
|
@ -44,6 +44,28 @@ namespace Bit.Core.Services
|
||||||
return Task.FromResult(_cryptoPrimitiveService.Pbkdf2(password, salt, algorithm, iterations));
|
return Task.FromResult(_cryptoPrimitiveService.Pbkdf2(password, salt, algorithm, iterations));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<byte[]> Argon2Async(string password, string salt, int iterations, int memory, int parallelism)
|
||||||
|
{
|
||||||
|
password = NormalizePassword(password);
|
||||||
|
return Argon2Async(Encoding.UTF8.GetBytes(password), Encoding.UTF8.GetBytes(salt), iterations, memory, parallelism);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<byte[]> Argon2Async(byte[] password, string salt, int iterations, int memory, int parallelism)
|
||||||
|
{
|
||||||
|
return Argon2Async(password, Encoding.UTF8.GetBytes(salt), iterations, memory, parallelism);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<byte[]> Argon2Async(string password, byte[] salt, int iterations, int memory, int parallelism)
|
||||||
|
{
|
||||||
|
password = NormalizePassword(password);
|
||||||
|
return Argon2Async(Encoding.UTF8.GetBytes(password), salt, iterations, memory, parallelism);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<byte[]> Argon2Async(byte[] password, byte[] salt, int iterations, int memory, int parallelism)
|
||||||
|
{
|
||||||
|
return Task.FromResult(_cryptoPrimitiveService.Argon2id(password, salt, iterations, memory, parallelism));
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<byte[]> HkdfAsync(byte[] ikm, string salt, string info, int outputByteSize, HkdfAlgorithm algorithm) =>
|
public async Task<byte[]> HkdfAsync(byte[] ikm, string salt, string info, int outputByteSize, HkdfAlgorithm algorithm) =>
|
||||||
await HkdfAsync(ikm, Encoding.UTF8.GetBytes(salt), Encoding.UTF8.GetBytes(info), outputByteSize, algorithm);
|
await HkdfAsync(ikm, Encoding.UTF8.GetBytes(salt), Encoding.UTF8.GetBytes(info), outputByteSize, algorithm);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue