62 lines
1.9 KiB
Dart
62 lines
1.9 KiB
Dart
import 'dart:typed_data';
|
|
|
|
import 'package:pointycastle/api.dart';
|
|
import 'package:pointycastle/key_derivators/api.dart';
|
|
import 'package:pointycastle/src/impl/base_key_derivator.dart';
|
|
import 'package:pointycastle/src/registry/registry.dart';
|
|
|
|
class ConcatKDFDerivator extends BaseKeyDerivator {
|
|
/// Intended for internal use.
|
|
static final FactoryConfig factoryConfig =
|
|
DynamicFactoryConfig.suffix(KeyDerivator, '/ConcatKDF', (_, Match match) {
|
|
final digestName = match.group(1);
|
|
final digest = Digest(digestName!);
|
|
return () {
|
|
return ConcatKDFDerivator(digest);
|
|
};
|
|
});
|
|
|
|
final Digest _digest;
|
|
late final HkdfParameters _parameters;
|
|
|
|
ConcatKDFDerivator(this._digest);
|
|
|
|
@override
|
|
String get algorithmName => '${_digest.algorithmName}/ConcatKDF';
|
|
|
|
@override
|
|
int deriveKey(Uint8List inp, int inpOff, Uint8List out, int outOff) {
|
|
_digest.reset();
|
|
|
|
var reps = _getReps(_parameters.desiredKeyLength, _digest.digestSize * 8);
|
|
var output = Uint8List(reps * _digest.digestSize);
|
|
var counter = Uint8List(4);
|
|
for (var i = 1; i <= reps; i++) {
|
|
var counterInt = i.toUnsigned(32);
|
|
counter[0] = (counterInt >> 24) & 255;
|
|
counter[1] = (counterInt >> 16) & 255;
|
|
counter[2] = (counterInt >> 8) & 255;
|
|
counter[3] = counterInt & 255;
|
|
_digest.update(counter, 0, 4);
|
|
_digest.update(_parameters.ikm, 0, _parameters.ikm.length);
|
|
_digest.update(_parameters.salt ?? inp.sublist(inpOff), 0,
|
|
_parameters.salt?.length ?? inp.sublist(inpOff).length);
|
|
_digest.doFinal(output, (i - 1) * _digest.digestSize);
|
|
}
|
|
|
|
out.setAll(outOff, output.getRange(0, keySize));
|
|
return keySize;
|
|
}
|
|
|
|
int _getReps(int keydatalen, int messagedigestlen) {
|
|
return (keydatalen / messagedigestlen).ceil();
|
|
}
|
|
|
|
@override
|
|
void init(covariant HkdfParameters params) {
|
|
_parameters = params;
|
|
}
|
|
|
|
@override
|
|
int get keySize => (_parameters.desiredKeyLength / 8).ceil();
|
|
}
|