2016-08-01 07:06:12 +03:00
|
|
|
|
using Bit.App.Abstractions;
|
|
|
|
|
using Foundation;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
2016-08-02 03:23:46 +03:00
|
|
|
|
namespace Bit.iOS.Core.Services
|
2016-08-01 07:06:12 +03:00
|
|
|
|
{
|
2016-08-02 03:23:46 +03:00
|
|
|
|
public class CommonCryptoKeyDerivationService : IKeyDerivationService
|
2016-08-01 07:06:12 +03:00
|
|
|
|
{
|
|
|
|
|
private const uint PBKDFAlgorithm = 2; // PBKDF2
|
|
|
|
|
private const uint PseudoRandomAlgorithm = 3; // SHA256
|
2016-08-02 03:23:46 +03:00
|
|
|
|
private const uint KeyLength = 32; // 256 bit
|
2016-08-01 07:06:12 +03:00
|
|
|
|
|
2016-08-02 03:23:46 +03:00
|
|
|
|
public byte[] DeriveKey(byte[] password, byte[] salt, uint rounds)
|
2016-08-01 07:06:12 +03:00
|
|
|
|
{
|
2016-08-02 03:23:46 +03:00
|
|
|
|
var passwordData = NSData.FromArray(password);
|
|
|
|
|
var saltData = NSData.FromArray(salt);
|
2016-08-01 07:06:12 +03:00
|
|
|
|
|
|
|
|
|
var keyData = new NSMutableData();
|
2016-08-02 03:23:46 +03:00
|
|
|
|
keyData.Length = KeyLength;
|
|
|
|
|
var result = CCKeyCerivationPBKDF(PBKDFAlgorithm, passwordData.Bytes, passwordData.Length, saltData.Bytes,
|
|
|
|
|
saltData.Length, PseudoRandomAlgorithm, rounds, keyData.MutableBytes, keyData.Length);
|
2016-08-01 07:06:12 +03:00
|
|
|
|
|
|
|
|
|
byte[] keyBytes = new byte[keyData.Length];
|
|
|
|
|
Marshal.Copy(keyData.Bytes, keyBytes, 0, Convert.ToInt32(keyData.Length));
|
|
|
|
|
return keyBytes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ref: http://opensource.apple.com//source/CommonCrypto/CommonCrypto-55010/CommonCrypto/CommonKeyDerivation.h
|
|
|
|
|
[DllImport(ObjCRuntime.Constants.libSystemLibrary, EntryPoint = "CCKeyDerivationPBKDF")]
|
2016-08-02 03:23:46 +03:00
|
|
|
|
private extern static int CCKeyCerivationPBKDF(uint algorithm, IntPtr password, nuint passwordLen,
|
2016-08-01 07:06:12 +03:00
|
|
|
|
IntPtr salt, nuint saltLen, uint prf, nuint rounds, IntPtr derivedKey, nuint derivedKeyLength);
|
|
|
|
|
}
|
|
|
|
|
}
|