2019-03-28 20:43:50 +01:00
|
|
|
|
using Bit.Core.Abstractions;
|
|
|
|
|
using Bit.Core.Enums;
|
|
|
|
|
using Foundation;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
2019-04-09 03:38:17 +02:00
|
|
|
|
namespace Bit.iOS.Core.Services
|
2019-03-28 20:43:50 +01:00
|
|
|
|
{
|
|
|
|
|
public class CryptoPrimitiveService : ICryptoPrimitiveService
|
|
|
|
|
{
|
|
|
|
|
private const uint PBKDFAlgorithm = 2; // kCCPBKDF2
|
|
|
|
|
|
|
|
|
|
public byte[] Pbkdf2(byte[] password, byte[] salt, CryptoHashAlgorithm algorithm, int iterations)
|
|
|
|
|
{
|
|
|
|
|
uint keySize = 32;
|
|
|
|
|
uint pseudoRandomAlgorithm = 3; // kCCPRFHmacAlgSHA256
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (algorithm == CryptoHashAlgorithm.Sha512)
|
2019-03-28 20:43:50 +01:00
|
|
|
|
{
|
|
|
|
|
keySize = 64;
|
|
|
|
|
pseudoRandomAlgorithm = 5; // kCCPRFHmacAlgSHA512
|
|
|
|
|
}
|
2020-03-28 14:16:28 +01:00
|
|
|
|
else if (algorithm != CryptoHashAlgorithm.Sha256)
|
2019-03-28 20:43:50 +01:00
|
|
|
|
{
|
|
|
|
|
throw new ArgumentException("Unsupported PBKDF2 algorithm.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var keyData = new NSMutableData();
|
|
|
|
|
keyData.Length = keySize;
|
|
|
|
|
|
|
|
|
|
var passwordData = NSData.FromArray(password);
|
|
|
|
|
var saltData = NSData.FromArray(salt);
|
|
|
|
|
|
|
|
|
|
var result = CCKeyCerivationPBKDF(PBKDFAlgorithm, passwordData.Bytes, passwordData.Length, saltData.Bytes,
|
|
|
|
|
saltData.Length, pseudoRandomAlgorithm, Convert.ToUInt32(iterations), keyData.MutableBytes,
|
|
|
|
|
keyData.Length);
|
|
|
|
|
|
|
|
|
|
byte[] keyBytes = new byte[keyData.Length];
|
|
|
|
|
Marshal.Copy(keyData.Bytes, keyBytes, 0, Convert.ToInt32(keyData.Length));
|
|
|
|
|
return keyBytes;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-25 13:58:36 +01:00
|
|
|
|
public byte[] Argon2id(byte[] password, byte[] salt, int iterations, int memory, int parallelism)
|
|
|
|
|
{
|
|
|
|
|
uint keySize = 32;
|
|
|
|
|
var keyData = new NSMutableData();
|
|
|
|
|
keyData.Length = keySize;
|
|
|
|
|
|
|
|
|
|
var passwordData = NSData.FromArray(password);
|
|
|
|
|
var saltData = NSData.FromArray(salt);
|
|
|
|
|
|
|
|
|
|
argon2id_hash_raw(iterations, memory, parallelism, passwordData.Bytes, passwordData.Length,
|
|
|
|
|
saltData.Bytes, saltData.Length, keyData.MutableBytes, keyData.Length);
|
|
|
|
|
|
|
|
|
|
var keyBytes = new byte[keyData.Length];
|
|
|
|
|
Marshal.Copy(keyData.Bytes, keyBytes, 0, Convert.ToInt32(keyData.Length));
|
|
|
|
|
return keyBytes;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-28 20:43:50 +01:00
|
|
|
|
// ref: http://opensource.apple.com/source/CommonCrypto/CommonCrypto-55010/CommonCrypto/CommonKeyDerivation.h
|
|
|
|
|
[DllImport(ObjCRuntime.Constants.libSystemLibrary, EntryPoint = "CCKeyDerivationPBKDF")]
|
|
|
|
|
private extern static int CCKeyCerivationPBKDF(uint algorithm, IntPtr password, nuint passwordLen,
|
|
|
|
|
IntPtr salt, nuint saltLen, uint prf, nuint rounds, IntPtr derivedKey, nuint derivedKeyLength);
|
2023-01-25 13:58:36 +01:00
|
|
|
|
|
|
|
|
|
[DllImport("__Internal", EntryPoint = "argon2id_hash_raw")]
|
|
|
|
|
private static extern int argon2id_hash_raw(int timeCost, int memoryCost, int parallelism, IntPtr pwd,
|
|
|
|
|
nuint pwdlen, IntPtr salt, nuint saltlen, IntPtr hash, nuint hashlen);
|
2019-03-28 20:43:50 +01:00
|
|
|
|
}
|
|
|
|
|
}
|