refactor: selectable hash for pbkdf2

This commit is contained in:
Lukas Lihotzki 2021-03-23 21:29:06 +01:00
parent a25d1932ee
commit 7faf05fe90
4 changed files with 58 additions and 6 deletions

View File

@ -27,7 +27,7 @@ import 'package:encrypt/encrypt.dart';
import '../famedlysdk.dart';
import '../src/database/database.dart';
import '../src/utils/crypto/crypto.dart';
import '../src/utils/crypto/crypto.dart' as uc;
import '../src/utils/run_in_background.dart';
import '../src/utils/run_in_root.dart';
import 'encryption.dart';
@ -155,7 +155,7 @@ class SSSS {
if (info.algorithm != AlgorithmTypes.pbkdf2) {
throw Exception('Unknown algorithm');
}
return await pbkdf2(utf8.encode(passphrase), utf8.encode(info.salt), info.iterations, info.bits ?? 256);
return await uc.pbkdf2(utf8.encode(passphrase), utf8.encode(info.salt), uc.sha512, info.iterations, info.bits ?? 256);
}
void setValidator(String type, FutureOr<bool> Function(String) validator) {

View File

@ -14,6 +14,16 @@ final PKCS5_PBKDF2_HMAC = libcrypto.lookupFunction<
int Function(Pointer<Uint8> pass, int passlen, Pointer<Uint8> salt, int saltlen, int iter, Pointer<NativeType> digest, int keylen, Pointer<Uint8> out)
>('PKCS5_PBKDF2_HMAC');
final EVP_sha1 = libcrypto.lookupFunction<
Pointer<NativeType> Function(),
Pointer<NativeType> Function()
>('EVP_sha1');
final EVP_sha256 = libcrypto.lookupFunction<
Pointer<NativeType> Function(),
Pointer<NativeType> Function()
>('EVP_sha256');
final EVP_sha512 = libcrypto.lookupFunction<
Pointer<NativeType> Function(),
Pointer<NativeType> Function()

View File

@ -5,8 +5,29 @@ import 'dart:typed_data';
import 'subtle.dart';
Future<Uint8List> pbkdf2(Uint8List passphrase, Uint8List salt, int iterations, int bits) async {
abstract class Hash {
Hash._(this.name);
String name;
}
final Hash sha1 = _Sha1();
final Hash sha256 = _Sha256();
final Hash sha512 = _Sha512();
class _Sha1 extends Hash {
_Sha1() : super._('SHA-1');
}
class _Sha256 extends Hash {
_Sha256() : super._('SHA-256');
}
class _Sha512 extends Hash {
_Sha512() : super._('SHA-512');
}
Future<Uint8List> pbkdf2(Uint8List passphrase, Uint8List salt, Hash hash, int iterations, int bits) async {
final raw = await importKey('raw', passphrase, 'PBKDF2', false, ['deriveBits']);
final res = await deriveBits(Pbkdf2Params(name: 'PBKDF2', hash: 'SHA-512', salt: salt, iterations: iterations), raw, bits);
final res = await deriveBits(Pbkdf2Params(name: 'PBKDF2', hash: hash.name, salt: salt, iterations: iterations), raw, bits);
return Uint8List.view(res);
}

View File

@ -4,7 +4,28 @@ import 'package:ffi/ffi.dart';
import 'ffi.dart';
Uint8List pbkdf2(Uint8List passphrase, Uint8List salt, int iterations, int bits) {
abstract class Hash {
Hash._(this.ptr);
Pointer<NativeType> ptr;
}
final Hash sha1 = _Sha1();
final Hash sha256 = _Sha256();
final Hash sha512 = _Sha512();
class _Sha1 extends Hash {
_Sha1() : super._(EVP_sha1());
}
class _Sha256 extends Hash {
_Sha256() : super._(EVP_sha256());
}
class _Sha512 extends Hash {
_Sha512() : super._(EVP_sha512());
}
Uint8List pbkdf2(Uint8List passphrase, Uint8List salt, Hash hash, int iterations, int bits) {
final outLen = bits ~/ 8;
final mem = malloc.call<Uint8>(passphrase.length + salt.length + outLen);
final saltMem = mem.elementAt(passphrase.length);
@ -12,7 +33,7 @@ Uint8List pbkdf2(Uint8List passphrase, Uint8List salt, int iterations, int bits)
try {
mem.asTypedList(passphrase.length).setAll(0, passphrase);
saltMem.asTypedList(salt.length).setAll(0, salt);
PKCS5_PBKDF2_HMAC(mem, passphrase.length, saltMem, salt.length, iterations, EVP_sha512(), outLen, outMem);
PKCS5_PBKDF2_HMAC(mem, passphrase.length, saltMem, salt.length, iterations, hash.ptr, outLen, outMem);
return Uint8List.fromList(outMem.asTypedList(outLen));
} finally {
malloc.free(mem);