abstract class BlockCipher extends SymmetricKey (View source)

Base Class for all block cipher classes

Constants

MODE_CTR

Encrypt / decrypt using the Counter mode.

Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.

MODE_ECB

Encrypt / decrypt using the Electronic Code Book mode.

MODE_CBC

Encrypt / decrypt using the Code Book Chaining mode.

MODE_CFB

Encrypt / decrypt using the Cipher Feedback mode.

MODE_CFB8

Encrypt / decrypt using the Cipher Feedback mode (8bit)

MODE_OFB

Encrypt / decrypt using the Output Feedback mode.

MODE_GCM

Encrypt / decrypt using Galois/Counter mode.

MODE_STREAM

Encrypt / decrypt using streaming mode.

MODE_MAP

Mode Map

ENGINE_INTERNAL

Base value for the internal implementation $engine switch

ENGINE_EVAL

Base value for the eval() implementation $engine switch

ENGINE_MCRYPT

Base value for the mcrypt implementation $engine switch

ENGINE_OPENSSL

Base value for the openssl implementation $engine switch

ENGINE_LIBSODIUM

Base value for the libsodium implementation $engine switch

ENGINE_OPENSSL_GCM

Base value for the openssl / gcm implementation $engine switch

ENGINE_MAP

Engine Reverse Map

Properties

protected int $mode The Encryption Mode from  SymmetricKey
protected int $block_size The Block Length of the block cipher from  SymmetricKey
protected string $key The Key from  SymmetricKey
protected string $iv The Initialization Vector from  SymmetricKey
protected string $encryptIV A "sliding" Initialization Vector from  SymmetricKey
protected string $decryptIV A "sliding" Initialization Vector from  SymmetricKey
protected bool $continuousBuffer Continuous Buffer status from  SymmetricKey
protected array $enbuffer Encryption buffer for CTR, OFB and CFB modes from  SymmetricKey
protected array $debuffer Decryption buffer for CTR, OFB and CFB modes from  SymmetricKey
protected int $cfb_init_len Optimizing value while CFB-encrypting from  SymmetricKey
protected bool $changed Does internal cipher state need to be (re)initialized? from  SymmetricKey
protected bool $nonIVChanged Does Eval engie need to be (re)initialized? from  SymmetricKey
protected int $engine Holds which crypt engine internaly should be use, which will be determined automatically on __construct() from  SymmetricKey
protected string $cipher_name_mcrypt The mcrypt specific name of the cipher from  SymmetricKey
protected string $cipher_name_openssl The openssl specific name of the cipher from  SymmetricKey
protected string $cipher_name_openssl_ecb The openssl specific name of the cipher in ECB mode from  SymmetricKey
protected callable $inline_crypt The name of the performance-optimized callback function from  SymmetricKey
protected bool $explicit_key_length Has the key length explicitly been set or should it be derived from the key, itself? from  SymmetricKey
protected string $aad Additional authenticated data from  SymmetricKey
protected string $newtag Authentication Tag produced after a round of encryption from  SymmetricKey
protected string $oldtag Authentication Tag to be verified during decryption from  SymmetricKey
protected string $poly1305Key Poly1305 Key from  SymmetricKey
protected bool $usePoly1305 Poly1305 Flag from  SymmetricKey
protected string $nonce Nonce from  SymmetricKey

Methods

__construct(string $mode)

Default Constructor.

setIV(string $iv)

Sets the initialization vector.

enablePoly1305()

Enables Poly1305 mode.

setPoly1305Key(string $key = null)

Enables Poly1305 mode.

setNonce(string $nonce)

Sets the nonce.

setAAD(string $aad)

Sets additional authenticated data

bool
usesIV()

Returns whether or not the algorithm uses an IV

bool
usesNonce()

Returns whether or not the algorithm uses a nonce

int
getKeyLength()

Returns the current key length in bits

int
getBlockLength()

Returns the current block length in bits

int
getBlockLengthInBytes()

Returns the current block length in bytes

setKeyLength(int $length)

Sets the key length.

setKey(string $key)

Sets the key.

bool
setPassword(string $password, string $method = 'pbkdf2', string[] ...$func_args)

Sets the password.

string
encrypt(string $plaintext)

Encrypts a message.

string
decrypt(string $ciphertext)

Decrypts a message.

string
getTag(int $length = 16)

Get the authentication tag

setTag(string $tag)

Sets the authentication tag

string
getIV(string $iv)

Get the IV

string
openssl_translate_mode()

phpseclib <-> OpenSSL Mode Mapper

enablePadding()

Pad "packets".

disablePadding()

Do not pad packets.

enableContinuousBuffer()

Treat consecutive "packets" as if they are a continuous buffer.

disableContinuousBuffer()

Treat consecutive packets as if they are a discontinuous buffer.

bool
isValidEngineHelper(int $engine)

Test for engine validity

bool
isValidEngine(string $engine)

Test for engine validity

setPreferredEngine(string $engine)

Sets the preferred crypt engine

getEngine()

Returns the engine currently being utilized

setEngine()

Sets the engine as appropriate

string
encryptBlock(string $in)

Encrypts a block

string
decryptBlock(string $in)

Decrypts a block

setupKey()

Setup the key (expansion)

setup()

Setup the self::ENGINE_INTERNAL $engine

string
pad(string $text)

Pads a string

string
unpad(string $text)

Unpads a string.

string
createInlineCryptFunction(array $cipher_code)

Creates the performance-optimized function for en/decrypt()

static int
safe_intval(string $x)

Convert float to int

static string
safe_intval_inline()

eval()'able string for in-line float to int

static string
nullPad128(string $str)

NULL pads a string to be a multiple of 128

string
poly1305(string $text)

Calculates Poly1305 MAC

Details

__construct(string $mode)

Default Constructor.

$mode could be:

  • ecb

  • cbc

  • ctr

  • cfb

  • cfb8

  • ofb

  • gcm

Parameters

string $mode

Exceptions

BadModeException if an invalid / unsupported mode is provided

setIV(string $iv)

Sets the initialization vector.

setIV() is not required when ecb or gcm modes are being used.

{@internal Can be overwritten by a sub class, but does not have to be}

Parameters

string $iv

Exceptions

LengthException if the IV length isn't equal to the block size
BadMethodCallException if an IV is provided when one shouldn't be

enablePoly1305()

Enables Poly1305 mode.

Once enabled Poly1305 cannot be disabled.

Exceptions

BadMethodCallException if Poly1305 is enabled whilst in GCM mode

setPoly1305Key(string $key = null)

Enables Poly1305 mode.

Once enabled Poly1305 cannot be disabled. If $key is not passed then an attempt to call createPoly1305Key will be made.

Parameters

string $key optional

Exceptions

LengthException if the key isn't long enough
BadMethodCallException if Poly1305 is enabled whilst in GCM mode

setNonce(string $nonce)

Sets the nonce.

setNonce() is only required when gcm is used

Parameters

string $nonce

Exceptions

BadMethodCallException if an nonce is provided when one shouldn't be

setAAD(string $aad)

Sets additional authenticated data

setAAD() is only used by gcm or in poly1305 mode

Parameters

string $aad

Exceptions

BadMethodCallException if mode isn't GCM or if poly1305 isn't being utilized

bool usesIV()

Returns whether or not the algorithm uses an IV

Return Value

bool

bool usesNonce()

Returns whether or not the algorithm uses a nonce

Return Value

bool

int getKeyLength()

Returns the current key length in bits

Return Value

int

int getBlockLength()

Returns the current block length in bits

Return Value

int

int getBlockLengthInBytes()

Returns the current block length in bytes

Return Value

int

setKeyLength(int $length)

Sets the key length.

Keys with explicitly set lengths need to be treated accordingly

Parameters

int $length

setKey(string $key)

Sets the key.

The min/max length(s) of the key depends on the cipher which is used. If the key not fits the length(s) of the cipher it will paded with null bytes up to the closest valid key length. If the key is more than max length, we trim the excess bits.

If the key is not explicitly set, it'll be assumed to be all null bytes.

{@internal Could, but not must, extend by the child Crypt_* class}

Parameters

string $key

bool setPassword(string $password, string $method = 'pbkdf2', string[] ...$func_args)

Sets the password.

Depending on what $method is set to, setPassword()'s (optional) parameters are as follows: {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1: $hash, $salt, $count, $dkLen

    Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php

{@internal Could, but not must, extend by the child Crypt_* class}

Parameters

string $password
string $method
string[] ...$func_args

Return Value

bool

Exceptions

LengthException if pbkdf1 is being used and the derived key length exceeds the hash length

See also

r y

string encrypt(string $plaintext)

Encrypts a message.

$plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following URL:

{@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}

An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does. strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that length.

{@internal Could, but not must, extend by the child Crypt_* class}

Parameters

string $plaintext

Return Value

string $ciphertext

See also

\self::decrypt()

string decrypt(string $ciphertext)

Decrypts a message.

If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until it is.

{@internal Could, but not must, extend by the child Crypt_* class}

Parameters

string $ciphertext

Return Value

string $plaintext

Exceptions

LengthException if we're inside a block cipher and the ciphertext length is not a multiple of the block size

See also

\self::encrypt()

string getTag(int $length = 16)

Get the authentication tag

Only used in GCM or Poly1305 mode

Parameters

int $length optional

Return Value

string

Exceptions

LengthException if $length isn't of a sufficient length
RuntimeException if GCM mode isn't being used

See also

\self::encrypt()

setTag(string $tag)

Sets the authentication tag

Only used in GCM mode

Parameters

string $tag

Exceptions

LengthException if $length isn't of a sufficient length
RuntimeException if GCM mode isn't being used

See also

\self::decrypt()

protected string getIV(string $iv)

Get the IV

mcrypt requires an IV even if ECB is used

Parameters

string $iv

Return Value

string

See also

\self::encrypt()
\self::decrypt()

protected string openssl_translate_mode()

phpseclib <-> OpenSSL Mode Mapper

May need to be overwritten by classes extending this one in some cases

Return Value

string

enablePadding()

Pad "packets".

Block ciphers working by encrypting between their specified [$this->]block_size at a time If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to pad the input so that it is of the proper length.

Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH, where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is transmitted separately)

See also

\self::disablePadding()

disablePadding()

Do not pad packets.

See also

\self::enablePadding()

enableContinuousBuffer()

Treat consecutive "packets" as if they are a continuous buffer.

Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets will yield different outputs:

echo $rijndael->encrypt(substr($plaintext, 0, 16)); echo $rijndael->encrypt(substr($plaintext, 16, 16)); echo $rijndael->encrypt($plaintext);

The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates another, as demonstrated with the following:

$rijndael->encrypt(substr($plaintext, 0, 16)); echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));

With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different outputs. The reason is due to the fact that the initialization vector's change after every encryption / decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.

Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt*() object changes after each encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), however, they are also less intuitive and more likely to cause you problems.

{@internal Could, but not must, extend by the child Crypt_* class}

See also

\self::disableContinuousBuffer()

disableContinuousBuffer()

Treat consecutive packets as if they are a discontinuous buffer.

The default behavior.

{@internal Could, but not must, extend by the child Crypt_* class}

See also

\self::enableContinuousBuffer()

protected bool isValidEngineHelper(int $engine)

Test for engine validity

Parameters

int $engine

Return Value

bool

See also

\self::__construct()

bool isValidEngine(string $engine)

Test for engine validity

Parameters

string $engine

Return Value

bool

See also

\self::__construct()

setPreferredEngine(string $engine)

Sets the preferred crypt engine

Currently, $engine could be:

  • libsodium[very fast]

  • OpenSSL [very fast]

  • mcrypt [fast]

  • Eval [slow]

  • PHP [slowest]

If the preferred crypt engine is not available the fastest available one will be used

Parameters

string $engine

See also

\self::__construct()

getEngine()

Returns the engine currently being utilized

See also

\self::setEngine()

protected setEngine()

Sets the engine as appropriate

See also

\self::__construct()

abstract protected string encryptBlock(string $in)

Encrypts a block

Note: Must be extended by the child \phpseclib3\Crypt* class

Parameters

string $in

Return Value

string

abstract protected string decryptBlock(string $in)

Decrypts a block

Note: Must be extended by the child \phpseclib3\Crypt* class

Parameters

string $in

Return Value

string

abstract protected setupKey()

Setup the key (expansion)

Only used if $engine == self::ENGINE_INTERNAL

Note: Must extend by the child \phpseclib3\Crypt* class

See also

\self::setup()

protected setup()

Setup the self::ENGINE_INTERNAL $engine

(re)init, if necessary, the internal cipher $engine and flush all $buffers Used (only) if $engine == self::ENGINE_INTERNAL

_setup() will be called each time if $changed === true typically this happens when using one or more of following public methods:

  • setKey()

  • setIV()

  • disableContinuousBuffer()

  • First run of encrypt() / decrypt() with no init-settings

{@internal setup() is always called before en/decryption.}

{@internal Could, but not must, extend by the child Crypt_* class}

See also

\self::setKey()
\self::setIV()
\self::disableContinuousBuffer()

protected string pad(string $text)

Pads a string

Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize. $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to chr($this->block_size - (strlen($text) % $this->block_size)

If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless and padding will, hence forth, be enabled.

Parameters

string $text

Return Value

string

Exceptions

LengthException if padding is disabled and the plaintext's length is not a multiple of the block size

See also

\self::unpad()

protected string unpad(string $text)

Unpads a string.

If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong and false will be returned.

Parameters

string $text

Return Value

string

Exceptions

LengthException if the ciphertext's length is not a multiple of the block size

See also

\self::pad()

protected string createInlineCryptFunction(array $cipher_code)

Creates the performance-optimized function for en/decrypt()

Internally for phpseclib developers:

_createInlineCryptFunction():

  • merge the $cipher_code [setup'ed by _setupInlineCrypt()] with the current [$this->]mode of operation code

  • create the $inline function, which called by encrypt() / decrypt() as its replacement to speed up the en/decryption operations.

  • return the name of the created $inline callback function

  • used to speed up en/decryption

The main reason why can speed up things [up to 50%] this way are:

  • using variables more effective then regular. (ie no use of expensive arrays but integers $k_0, $k_1 ... or even, for example, the pure $key[] values hardcoded)

  • avoiding 1000's of function calls of ie _encryptBlock() but inlining the crypt operations. in the mode of operation for() loop.

  • full loop unroll the (sometimes key-dependent) rounds avoiding this way ++$i counters and runtime-if's etc...

The basic code architectur of the generated $inline en/decrypt() lambda function, in pseudo php, is:

+----------------------------------------------------------------------------------------------+ | callback $inline = create_function: | | lambda_function_0001_crypt_ECB($action, $text) | | { | | INSERT PHP CODE OF: | | $cipher_code['init_crypt']; // general init code. | | // ie: $sbox'es declarations used for | | // encrypt and decrypt'ing. | | | | switch ($action) { | | case 'encrypt': | | INSERT PHP CODE OF: | | $cipher_code['init_encrypt']; // encrypt sepcific init code. | | ie: specified $key or $box | | declarations for encrypt'ing. | | | | foreach ($ciphertext) { | | $in = $block_size of $ciphertext; | | | | INSERT PHP CODE OF: | | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: | | // strlen($in) == $this->block_size | | // here comes the cipher algorithm in action | | // for encryption. | | // $cipher_code['encrypt_block'] has to | | // encrypt the content of the $in variable | | | | $plaintext .= $in; | | } | | return $plaintext; | | | | case 'decrypt': | | INSERT PHP CODE OF: | | $cipher_code['init_decrypt']; // decrypt sepcific init code | | ie: specified $key or $box | | declarations for decrypt'ing. | | foreach ($plaintext) { | | $in = $block_size of $plaintext; | | | | INSERT PHP CODE OF: | | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always | | // strlen($in) == $this->block_size | | // here comes the cipher algorithm in action | | // for decryption. | | // $cipher_code['decrypt_block'] has to | | // decrypt the content of the $in variable | | $ciphertext .= $in; | | } | | return $ciphertext; | | } | | } | +----------------------------------------------------------------------------------------------+

See also the \phpseclib3\Crypt*::_setupInlineCrypt()'s for productive inline $cipher_code's how they works.

Structure of: $cipher_code = [ 'init_crypt' => (string) '', // optional 'init_encrypt' => (string) '', // optional 'init_decrypt' => (string) '', // optional 'encrypt_block' => (string) '', // required 'decrypt_block' => (string) '' // required ];

Parameters

array $cipher_code

Return Value

string (the name of the created callback function)

See also

\self::setupInlineCrypt()
\self::encrypt()
\self::decrypt()

static protected int safe_intval(string $x)

Convert float to int

On ARM CPUs converting floats to ints doesn't always work

Parameters

string $x

Return Value

int

static protected string safe_intval_inline()

eval()'able string for in-line float to int

Return Value

string

static protected string nullPad128(string $str)

NULL pads a string to be a multiple of 128

Parameters

string $str

Return Value

string

See also

\self::decrypt()
\self::encrypt()
\self::setupGCM()

protected string poly1305(string $text)

Calculates Poly1305 MAC

On my system ChaCha20, with libsodium, takes 0.5s. With this custom Poly1305 implementation it takes 1.2s.

Parameters

string $text

Return Value

string

See also

\self::decrypt()
\self::encrypt()