1<?php
2/**
3 * Zend Framework (http://framework.zend.com/)
4 *
5 * @link      http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license   http://framework.zend.com/license/new-bsd New BSD License
8 */
9
10namespace Zend\Crypt\Key\Derivation;
11
12/**
13 * Salted S2K key generation (OpenPGP document, RFC 2440)
14 */
15class SaltedS2k
16{
17    protected static $supportedMhashAlgos = array(
18        'adler32'    => MHASH_ADLER32,
19        'md2'        => MHASH_MD2,
20        'md4'        => MHASH_MD4,
21        'md5'        => MHASH_MD5,
22        'sha1'       => MHASH_SHA1,
23        'sha224'     => MHASH_SHA224,
24        'sha256'     => MHASH_SHA256,
25        'sha384'     => MHASH_SHA384,
26        'sha512'     => MHASH_SHA512,
27        'ripemd128'  => MHASH_RIPEMD128,
28        'ripemd256'  => MHASH_RIPEMD256,
29        'ripemd320'  => MHASH_RIPEMD320,
30        'haval128,3' => MHASH_HAVAL128, // @deprecated use haval128 instead
31        'haval128'   => MHASH_HAVAL128,
32        'haval160,3' => MHASH_HAVAL160, // @deprecated use haval160 instead
33        'haval160'   => MHASH_HAVAL160,
34        'haval192,3' => MHASH_HAVAL192, // @deprecated use haval192 instead
35        'haval192'   => MHASH_HAVAL192,
36        'haval224,3' => MHASH_HAVAL224, // @deprecated use haval224 instead
37        'haval224'   => MHASH_HAVAL224,
38        'haval256,3' => MHASH_HAVAL256, // @deprecated use haval256 instead
39        'haval256'   => MHASH_HAVAL256,
40        'tiger'      => MHASH_TIGER,
41        'tiger128,3' => MHASH_TIGER128, // @deprecated use tiger128 instead
42        'tiger128'   => MHASH_TIGER128,
43        'tiger160,3' => MHASH_TIGER160, // @deprecated use tiger160 instead
44        'tiger160'   => MHASH_TIGER160,
45        'whirpool'   => MHASH_WHIRLPOOL,
46        'snefru256'  => MHASH_SNEFRU256,
47        'gost'       => MHASH_GOST,
48        'crc32'      => MHASH_CRC32,
49        'crc32b'     => MHASH_CRC32B
50    );
51
52    /**
53     * Generate the new key
54     *
55     * @param  string  $hash       The hash algorithm to be used by HMAC
56     * @param  string  $password   The source password/key
57     * @param  int $bytes      The output size in bytes
58     * @param  string  $salt       The salt of the algorithm
59     * @throws Exception\InvalidArgumentException
60     * @return string
61     */
62    public static function calc($hash, $password, $salt, $bytes)
63    {
64        if (!in_array($hash, array_keys(static::$supportedMhashAlgos))) {
65            throw new Exception\InvalidArgumentException("The hash algorithm $hash is not supported by " . __CLASS__);
66        }
67        if (strlen($salt)<8) {
68            throw new Exception\InvalidArgumentException('The salt size must be at least of 8 bytes');
69        }
70        return mhash_keygen_s2k(static::$supportedMhashAlgos[$hash], $password, $salt, $bytes);
71    }
72}
73