Beispiel #1
0
 /**
  * @dataProvider vectorsP521
  * @group large
  */
 public function testP521($k, $x, $y)
 {
     $base = new \fpoirotte\Pssht\ECC\Point('0x00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66', '0x011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650');
     $expected = new \fpoirotte\Pssht\ECC\Point($x, $y);
     $actual = $base->multiply(\fpoirotte\Pssht\ECC\Curve::getCurve('nistp521'), $k);
     $this->assertSame(gmp_strval($expected->x, 16), gmp_strval($actual->x, 16));
     $this->assertSame(gmp_strval($expected->y, 16), gmp_strval($actual->y, 16));
 }
Beispiel #2
0
 protected function createResponse(\fpoirotte\Pssht\Wire\Decoder $decoder, \fpoirotte\Pssht\Transport $transport, array &$context, $hostAlgo)
 {
     $kexAlgo = $context['kexAlgo'];
     $kexAlgo = new $kexAlgo();
     $curveName = str_replace('ecdh-sha2-', '', $kexAlgo::getName());
     $cls = str_replace('nist', 'NIST', $curveName);
     $cls = "\\fpoirotte\\Pssht\\Messages\\KEX\\ECDH\\INIT\\{$cls}";
     $message = $cls::unserialize($decoder);
     $curve = \fpoirotte\Pssht\ECC\Curve::getCurve($curveName);
     return new \fpoirotte\Pssht\Messages\KEX\ECDH\REPLY\RFC5656($curve, $message, $context['serverKeys'][$hostAlgo], $transport->getEncryptor(), $kexAlgo, $context['kex']['server'], $context['kex']['client'], $context['identity']['server'], $context['identity']['client']);
 }
Beispiel #3
0
 public static function getCurve()
 {
     return \fpoirotte\Pssht\ECC\Curve::getCurve('nistp521');
 }
Beispiel #4
0
 public static function add(\fpoirotte\Pssht\ECC\Curve $curve, \fpoirotte\Pssht\ECC\Point $P, \fpoirotte\Pssht\ECC\Point $Q)
 {
     $mod = $curve->getModulus();
     $xP = $P->coordinates['x'];
     $yP = $P->coordinates['y'];
     $xQ = $Q->coordinates['x'];
     $yQ = $Q->coordinates['y'];
     if (!gmp_cmp($xP, $xQ) && !gmp_cmp($yP, $yQ)) {
         $alphanum = gmp_add(gmp_mul('3', gmp_pow($xP, '2')), $curve->getA());
         $alphaden = gmp_mul('2', $yP);
     } else {
         $alphanum = gmp_sub($yQ, $yP);
         $alphaden = gmp_sub($xQ, $xP);
     }
     $bezout = gmp_gcdext($alphaden, $mod);
     $alpha = gmp_mod(gmp_mul($alphanum, $bezout['s']), $mod);
     $xR = gmp_sub(gmp_sub(gmp_pow($alpha, '2'), $xP), $xQ);
     $yR = gmp_sub(gmp_mul($alpha, gmp_sub($xP, $xR)), $yP);
     return new static(gmp_mod(gmp_add($xR, $mod), $mod), gmp_mod(gmp_add($yR, $mod), $mod));
 }
Beispiel #5
0
 public function setUp()
 {
     \fpoirotte\Pssht\ECC\Curve::initialize();
 }
Beispiel #6
0
 /**
  * Construct a new SSH_MSG_KEXDH_REPLY message.
  *
  *  \param fpoirotte::Pssht::ECC::Curve $curve
  *      Elliptic curve in use.
  *
  *  \param fpoirotte::Pssht::Messages::KEX::ECDH::INIT::RFC5656 $kexDHInit
  *      Client's contribution to the Diffie-Hellman Key Exchange.
  *
  *  \param fpoirotte::Pssht::PublicKeyInterface $key
  *      Server's public key.
  *
  *  \param fpoirotte::Pssht::EncryptionInterface $encryptionAlgo
  *      Encryption algorithm in use.
  *
  *  \param fpoirotte::Pssht::KEXInterface $kexAlgo
  *      Key exchange algorithm to use.
  *
  *  \param fpoirotte::Pssht::Messages::KEXINIT $serverKEX
  *      Algorithms supported by the server.
  *
  *  \param fpoirotte::Pssht::Messages::KEXINIT $clientKEX
  *      Algorithms supported by the client.
  *
  *  \param string $serverIdent
  *      Server's identification string
  *
  *  \param string $clientIdent
  *      Client's identification string
  */
 public function __construct(\fpoirotte\Pssht\ECC\Curve $curve, \fpoirotte\Pssht\Messages\KEX\ECDH\INIT\RFC5656 $kexDHInit, \fpoirotte\Pssht\PublicKeyInterface $key, \fpoirotte\Pssht\EncryptionInterface $encryptionAlgo, \fpoirotte\Pssht\KEXInterface $kexAlgo, \fpoirotte\Pssht\Messages\KEXINIT $serverKEX, \fpoirotte\Pssht\Messages\KEXINIT $clientKEX, $serverIdent, $clientIdent)
 {
     if (!is_string($serverIdent)) {
         throw new \InvalidArgumentException();
     }
     if (!is_string($clientIdent)) {
         throw new \InvalidArgumentException();
     }
     $len = strlen(gmp_strval($curve->getOrder(), 2));
     $len = ceil($len / 8);
     $randBytes = openssl_random_pseudo_bytes($len);
     $d_S = gmp_mod(gmp_init(bin2hex($randBytes), 16), $curve->getModulus());
     $this->Q_S = $curve->getGenerator()->multiply($curve, $d_S);
     $Q_C = $kexDHInit->getQ();
     /// @FIXME this is not optimal...
     $algorithms = \fpoirotte\Pssht\Algorithms::factory();
     $cls = $algorithms->getClass('PublicKey', 'ecdsa-sha2-' . $curve->getName());
     $clientPK = new $cls($Q_C);
     if (!$clientPK->isValid()) {
         throw new \InvalidArgumentException();
     }
     // EC Co-factor DH (sec1-v2, section 3.3.2).
     $P = $Q_C->multiply($curve, gmp_mul($curve->getCofactor(), $d_S));
     if ($P->isIdentity($curve)) {
         throw new \InvalidArgumentException();
     }
     $this->K = $P->x;
     $this->curve = $curve;
     $this->K_S = $key;
     $this->kexDHInit = $kexDHInit;
     $this->kexAlgo = $kexAlgo;
     $this->serverKEX = $serverKEX;
     $this->clientKEX = $clientKEX;
     $this->serverIdent = $serverIdent;
     $this->clientIdent = $clientIdent;
     $msgId = chr(\fpoirotte\Pssht\Messages\KEXINIT::getMessageId());
     // $sub is used to create the structure for the hashing function.
     $sub = new \fpoirotte\Pssht\Wire\Encoder(new \fpoirotte\Pssht\Buffer());
     $this->K_S->serialize($sub);
     $K_S = $sub->getBuffer()->get(0);
     $sub->encodeString($this->clientIdent);
     $sub->encodeString($this->serverIdent);
     // $sub2 is used to compute the value
     // of various fields inside the structure.
     $sub2 = new \fpoirotte\Pssht\Wire\Encoder(new \fpoirotte\Pssht\Buffer());
     $sub2->encodeBytes($msgId);
     // Add message identifier.
     $this->clientKEX->serialize($sub2);
     $sub->encodeString($sub2->getBuffer()->get(0));
     $sub2->encodeBytes($msgId);
     // Add message identifier.
     $this->serverKEX->serialize($sub2);
     $sub->encodeString($sub2->getBuffer()->get(0));
     $sub->encodeString($K_S);
     $sub->encodeString($Q_C->serialize($curve));
     $sub->encodeString($this->Q_S->serialize($curve));
     $sub->encodeMpint($this->K);
     $logging = \Plop\Plop::getInstance();
     $origData = $sub->getBuffer()->get(0);
     $data = wordwrap(bin2hex($origData), 4, ' ', true);
     $data = wordwrap($data, 32 + 7, PHP_EOL, true);
     $logging->debug("Signature payload:\r\n%s", array($data));
     $this->H = $this->kexAlgo->hash($origData);
 }