| 
<?phpnamespace ParagonIE\CipherSweet;
 
 use ParagonIE\CipherSweet\Backend\FIPSCrypto;
 use ParagonIE\CipherSweet\Backend\Key\SymmetricKey;
 use ParagonIE\CipherSweet\Backend\ModernCrypto;
 use ParagonIE\CipherSweet\Contract\BackendInterface;
 use ParagonIE\CipherSweet\Contract\KeyProviderInterface;
 use ParagonIE\CipherSweet\Exception\CryptoOperationException;
 use ParagonIE_Sodium_Compat as SodiumCompat;
 
 /**
 * Class CipherSweet
 * @package ParagonIE\CipherSweet
 */
 final class CipherSweet
 {
 /*
 * These domain separation constants has a hamming distance of 4 from each
 * other, for each byte.
 */
 const DS_BIDX = "\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E\x7E";
 const DS_FENC = "\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4\xB4";
 
 /**
 * @var BackendInterface $backend
 */
 private $backend;
 
 /**
 * @var KeyProviderInterface $keyProvider
 */
 private $keyProvider;
 
 /**
 * CipherSweet constructor.
 *
 * @param KeyProviderInterface $keyProvider
 * @param BackendInterface|null $backend
 */
 public function __construct(
 KeyProviderInterface $keyProvider,
 BackendInterface $backend = null
 ) {
 $this->keyProvider = $keyProvider;
 if (\is_null($backend)) {
 $backend = $this->keyProvider->getBackend();
 }
 $this->backend = $backend;
 }
 
 /**
 * @return BackendInterface
 */
 public function getBackend()
 {
 return $this->backend;
 }
 
 /**
 * @param string $tableName
 * @param string $fieldName
 * @param string $indexName
 * @return string
 */
 public function getIndexTypeColumn(
 $tableName,
 $fieldName,
 $indexName
 ) {
 return $this->backend->getIndexTypeColumn(
 $tableName,
 $fieldName,
 $indexName
 );
 }
 
 /**
 * Get the root key for calculating blind index keys for a given
 * EncryptedField instance.
 *
 * Uses a 32 byte prefix for the HKDF "info" parameter, for domain
 * separation.
 *
 * @param string $tableName
 * @param string $fieldName
 *
 * @return SymmetricKey
 * @throws CryptoOperationException
 */
 public function getBlindIndexRootKey($tableName, $fieldName)
 {
 return new SymmetricKey(
 $this->backend,
 Util::HKDF(
 $this->keyProvider->getSymmetricKey(),
 $tableName,
 self::DS_BIDX . $fieldName
 )
 );
 }
 
 /**
 * Get the per-field encryption key.
 *
 * Uses a 32 byte prefix for the HKDF "info" parameter, for domain
 * separation.
 *
 * @param string $tableName
 * @param string $fieldName
 *
 * @return SymmetricKey
 * @throws CryptoOperationException
 */
 public function getFieldSymmetricKey($tableName, $fieldName)
 {
 return new SymmetricKey(
 $this->backend,
 Util::HKDF(
 $this->keyProvider->getSymmetricKey(),
 $tableName,
 self::DS_FENC . $fieldName
 )
 );
 }
 
 /**
 * Return the default backend for a given environment. Note that the
 * stability of the result of this static method should not be depended on.
 *
 * @return BackendInterface
 */
 public static function getDefaultBackend()
 {
 if (SodiumCompat::crypto_pwhash_is_available()) {
 if (PHP_VERSION_ID >= 70000 && \extension_loaded('sodium')) {
 return new ModernCrypto();
 }
 if (PHP_VERSION_ID >= 70000 && \extension_loaded('libsodium')) {
 // This is a little weird but OK
 return new ModernCrypto();
 }
 if (PHP_VERSION_ID < 70000 && \extension_loaded('libsodium')) {
 return new ModernCrypto();
 }
 }
 // FIPS mode will always work... but it only uses FIPS algorithms.
 return new FIPSCrypto();
 }
 }
 
 |