110 if ( strlen( $secretKeyMaterial ) < 16 ) {
111 throw new InvalidArgumentException(
"secret was too short." );
113 $this->skm = $secretKeyMaterial;
121 $this->cacheKey =
$cache->makeKey(
'HKDF', mt_rand( 0, 16 ) );
130 if ( $this->lastK ) {
131 $this->cache->set( $this->cacheKey, $this->lastK );
140 if ( $this->salt ==
'' ) {
141 $lastSalt = $this->cache->get( $this->cacheKey );
142 if ( $lastSalt ===
false ) {
149 $lastSalt = random_bytes( 16 );
152 $this->salt = hash( $this->algorithm, $lastSalt,
true );
165 public function generate( $bytes, $context =
'' ) {
166 if ( $this->prk ===
'' ) {
168 $this->prk = self::HKDFExtract(
175 $CTXinfo = implode(
':', array_merge( $this->context, [
$context ] ) );
177 return self::HKDFExpand(
215 public static function HKDF( $hash, $ikm, $salt, $info, $L ) {
216 $prk = self::HKDFExtract( $hash,
$salt, $ikm );
217 $okm = self::HKDFExpand( $hash,
$prk, $info, $L );
232 return hash_hmac( $hash, $ikm,
$salt,
true );
250 private static function HKDFExpand( $hash, $prk, $info, $bytes, &$lastK =
'' ) {
251 $hashLen = self::$hashLength[$hash];
252 $rounds = ceil( $bytes / $hashLen );
255 if ( $bytes > 255 * $hashLen ) {
256 throw new InvalidArgumentException(
'Too many bytes requested from HDKFExpand' );
261 for ( $counter = 1; $counter <= $rounds; ++$counter ) {
264 $lastK . $info . chr( $counter ),
271 return substr( $output, 0, $bytes );
Class representing a cache/ephemeral data store.
generate( $bytes, $context='')
Produce $bytes of secure random data.
string $skm
The secret key material.
getSaltUsingCache()
MW specific salt, cached from last run.
string $lastK
The last block (K(i)) of the most recent expanded key.
static HKDFExpand( $hash, $prk, $info, $bytes, &$lastK='')
Expand the key with the given context.
__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
string $prk
The pseudorandom key.
static HKDFExtract( $hash, $salt, $ikm)
Extract the PRK, PRK = HMAC(XTS, SKM) Note that the hmac is keyed with XTS (the salt),...
__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....