1
0
mirror of https://github.com/bitwarden/mobile synced 2026-01-02 08:33:17 +00:00
Files
mobile/src/iOS.Core/Services/CryptoPrimitiveService.cs
Kyle Spearrin b8d53b0f81 Argon2id KDF (#2309)
* add gcc_flags for libargon2.a

* fix up ios proj

* remove unused tag

* add gcc_flags to ios projects

* ios libargon2 binary

* fix paths in ios project

* update pathing on other projs

* Argon2id primitive

* fix typing issues

* comment

* remove ds store

* [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

* cleanup

* move android libs

* move android libs

* Revert "move android libs"

This reverts commit 0b91b22cd2.

* Revert "move android libs"

This reverts commit 139839c469.

* PR feedback

Co-authored-by: Bernd Schoolmann <mail@quexten.com>
2023-01-25 07:58:36 -05:00

69 lines
2.9 KiB
C#

using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Foundation;
using System;
using System.Runtime.InteropServices;
namespace Bit.iOS.Core.Services
{
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
if (algorithm == CryptoHashAlgorithm.Sha512)
{
keySize = 64;
pseudoRandomAlgorithm = 5; // kCCPRFHmacAlgSHA512
}
else if (algorithm != CryptoHashAlgorithm.Sha256)
{
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;
}
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;
}
// 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);
[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);
}
}