41 protected $cache =
null;
46 protected $cacheKey =
null;
51 protected $algorithm =
null;
83 protected $context = [];
91 public static $hashLength = [
113 if ( strlen( $secretKeyMaterial ) < 16 ) {
114 throw new InvalidArgumentException(
"secret was too short." );
116 $this->skm = $secretKeyMaterial;
117 $this->algorithm = $algorithm;
118 $this->cache = $cache;
119 $this->context = is_array( $context ) ? $context : [ $context ];
124 $this->cacheKey = $cache->
makeKey(
'HKDF', mt_rand( 0, 16 ) );
133 if ( $this->lastK ) {
134 $this->cache->set( $this->cacheKey, $this->lastK );
143 if ( $this->salt ==
'' ) {
144 $lastSalt = $this->cache->get( $this->cacheKey );
145 if ( $lastSalt ===
false ) {
152 $lastSalt = random_bytes( 16 );
155 $this->salt = hash( $this->algorithm, $lastSalt,
true );
168 public function generate( $bytes, $context =
'' ) {
169 if ( $this->prk ===
'' ) {
171 $this->prk = self::HKDFExtract(
178 $CTXinfo = implode(
':', array_merge( $this->context, [ $context ] ) );
180 return self::HKDFExpand(
218 public static function HKDF( $hash, $ikm, $salt, $info, $L ) {
219 $prk = self::HKDFExtract( $hash, $salt, $ikm );
220 $okm = self::HKDFExpand( $hash, $prk, $info, $L );
234 private static function HKDFExtract( $hash, $salt, $ikm ) {
235 return hash_hmac( $hash, $ikm, $salt,
true );
252 private static function HKDFExpand( $hash, $prk, $info, $bytes, &$lastK =
'' ) {
253 $hashLen = self::$hashLength[$hash];
254 $rounds = ceil( $bytes / $hashLen );
257 if ( $bytes > 255 * $hashLen ) {
258 throw new InvalidArgumentException(
'Too many bytes requested from HDKFExpand' );
263 for ( $counter = 1; $counter <= $rounds; ++$counter ) {
266 $lastK . $info . chr( $counter ),
273 return substr( $output, 0, $bytes );
generate( $bytes, $context='')
Produce $bytes of secure random data.
getSaltUsingCache()
MW specific salt, cached from last run.
string $lastK
The last block (K(i)) of the most recent expanded key.
__destruct()
Save the last block generated, so the next user will compute a different PRK from the same SKM.
static HKDF( $hash, $ikm, $salt, $info, $L)
RFC5869 defines HKDF in 2 steps, extraction and expansion.
static int[] $hashLength
Round count is computed based on the hash'es output length, which neither php nor openssl seem to pro...
string $algorithm
The hash algorithm being used.
string $salt
binary string, the salt for the HKDF
BagOStuff $cache
The persistent cache.
__construct( $secretKeyMaterial, $algorithm, BagOStuff $cache, $context)
string $cacheKey
Cache key we'll use for our salt.
array $context
a "context information" string CTXinfo (which may be null) See http://eprint.iacr....