From 2c1994805b2c53df12ae244736aba6c568b7ed83 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 29 Nov 2018 10:05:28 -0600 Subject: [PATCH] ECDSA: make it so hash can't be changed for Ed25519 / Ed448 --- phpseclib/Crypt/Common/AsymmetricKey.php | 16 ++++++++ phpseclib/Crypt/ECDSA.php | 50 +++++++++++++++++++++--- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/phpseclib/Crypt/Common/AsymmetricKey.php b/phpseclib/Crypt/Common/AsymmetricKey.php index fa90c129..a95f7e80 100644 --- a/phpseclib/Crypt/Common/AsymmetricKey.php +++ b/phpseclib/Crypt/Common/AsymmetricKey.php @@ -151,6 +151,14 @@ abstract class AsymmetricKey */ private $hmac; + /** + * Hash manually set? + * + * @var bool + * @access private + */ + protected $hashManuallySet = false; + /** * Available Engines * @@ -284,6 +292,12 @@ abstract class AsymmetricKey */ protected function load($key, $type) { + if ($key instanceof self) { + $this->hmac = $key->hmac; + + return; + } + $components = false; if ($type === false) { foreach (self::$plugins[static::ALGORITHM]['Keys'] as $format) { @@ -594,6 +608,8 @@ abstract class AsymmetricKey { $this->hash = new Hash($hash); $this->hmac = new Hash($hash); + + $this->hashManuallySet = true; } /** diff --git a/phpseclib/Crypt/ECDSA.php b/phpseclib/Crypt/ECDSA.php index 4af8c4fd..7bd27347 100644 --- a/phpseclib/Crypt/ECDSA.php +++ b/phpseclib/Crypt/ECDSA.php @@ -37,6 +37,7 @@ use phpseclib\File\ASN1; use phpseclib\File\ASN1\Maps\ECParameters; use phpseclib\Crypt\ECDSA\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib\Crypt\ECDSA\Curves\Ed25519; +use phpseclib\Crypt\ECDSA\Curves\Ed448; use phpseclib\Crypt\ECDSA\Keys\PKCS1; use phpseclib\Crypt\ECDSA\Keys\PKCS8; use phpseclib\Crypt\ECDSA\Signature\ASN1 as ASN1Signature; @@ -198,20 +199,28 @@ class ECDSA extends AsymmetricKey $this->QA = $key->QA; $this->curve = $key->curve; $this->parametersFormat = $key->parametersFormat; + $this->hash = $key->hash; + + parent::load($key, false); return true; } $components = parent::load($key, $type); if ($components === false) { - $this->format = null; - $this->dA = null; - $this->QA = null; - $this->curve = null; - + $this->clearKey(); return false; } + if ($components['curve'] instanceof Ed25519 && $this->hashManuallySet && $this->hash->getHash() != 'sha512') { + $this->clearKey(); + throw new \RuntimeException('Ed25519 only supports sha512 as a hash'); + } + if ($components['curve'] instanceof Ed448 && $this->hashManuallySet && $this->hash->getHash() != 'shake256-912') { + $this->clearKey(); + throw new \RuntimeException('Ed448 only supports shake256 with a length of 114 bytes'); + } + $this->curve = $components['curve']; $this->QA = $components['QA']; $this->dA = isset($components['dA']) ? $components['dA'] : null; @@ -219,6 +228,19 @@ class ECDSA extends AsymmetricKey return true; } + /** + * Removes a key + * + * @access private + */ + private function clearKey() + { + $this->format = null; + $this->dA = null; + $this->QA = null; + $this->curve = null; + } + /** * Returns the curve * @@ -439,6 +461,24 @@ class ECDSA extends AsymmetricKey $this->context = $context; } + /** + * Determines which hashing function should be used + * + * @access public + * @param string $hash + */ + public function setHash($hash) + { + if ($this->curve instanceof Ed25519 && $this->hash != 'sha512') { + throw new \RuntimeException('Ed25519 only supports sha512 as a hash'); + } + if ($this->curve instanceof Ed448 && $this->hash != 'shake256-912') { + throw new \RuntimeException('Ed448 only supports shake256 with a length of 114 bytes'); + } + + parent::setHash($hash); + } + /** * Create a signature *