/** * Set up our key pair * * @param EncryptionSecretKey $secret */ protected function setupKeyPair(EncryptionSecretKey $secret) { $this->secretKey = $secret; $this->publicKey = $this->secretKey->derivePublicKey(); }
/** * Unseal the contents of a file. * * @param ReadOnlyFile $input * @param MutableFile $output * @param EncryptionSecretKey $secretKey * @return bool * @throws CannotPerformOperation * @throws InvalidMessage */ protected static function unsealData(ReadOnlyFile $input, MutableFile $output, EncryptionSecretKey $secretKey) : bool { $publicKey = $secretKey->derivePublicKey(); // Is the file at least as long as a header? if ($input->getSize() < Halite::VERSION_TAG_LEN) { throw new InvalidMessage("Input file is too small to have been encrypted by Halite."); } // Parse the header, ensuring we get 4 bytes $header = $input->readBytes(Halite::VERSION_TAG_LEN); // Load the config $config = self::getConfig($header, 'seal'); if ($input->getSize() < $config->SHORTEST_CIPHERTEXT_LENGTH) { throw new InvalidMessage("Input file is too small to have been encrypted by Halite."); } // Let's grab the public key and salt $ephPublic = $input->readBytes($config->PUBLICKEY_BYTES); $hkdfSalt = $input->readBytes($config->HKDF_SALT_LEN); // Generate the same nonce, as per sealData() $nonce = \Sodium\crypto_generichash($ephPublic . $publicKey->getRawKeyMaterial(), '', \Sodium\CRYPTO_STREAM_NONCEBYTES); // Create a key object out of the public key: $ephemeral = new EncryptionPublicKey(new HiddenString($ephPublic)); $key = AsymmetricCrypto::getSharedSecret($secretKey, $ephemeral, true); unset($ephemeral); list($encKey, $authKey) = self::splitKeys($key, $hkdfSalt, $config); // We no longer need the original key after we split it unset($key); $mac = \Sodium\crypto_generichash_init($authKey); \Sodium\crypto_generichash_update($mac, $header); \Sodium\crypto_generichash_update($mac, $ephPublic); \Sodium\crypto_generichash_update($mac, $hkdfSalt); $oldMACs = self::streamVerify($input, Util::safeStrcpy($mac), $config); // We no longer need this: \Sodium\memzero($hkdfSalt); $ret = self::streamDecrypt($input, $output, new EncryptionKey(new HiddenString($encKey)), $nonce, $mac, $config, $oldMACs); unset($encKey); unset($authKey); unset($nonce); unset($mac); unset($config); unset($oldMACs); return $ret; }