folder reorganization

This commit is contained in:
cttynul
2019-04-23 14:32:53 +02:00
parent 659751b2f4
commit 8e7ee78a87
1195 changed files with 267003 additions and 2 deletions
+115
View File
@@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
#
# Cipher/AES.py : AES
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""AES symmetric cipher
AES `(Advanced Encryption Standard)`__ is a symmetric block cipher standardized
by NIST_ . It has a fixed data block size of 16 bytes.
Its keys can be 128, 192, or 256 bits long.
AES is very fast and secure, and it is the de facto standard for symmetric
encryption.
As an example, encryption can be done as follows:
>>> from Crypto.Cipher import AES
>>> from Crypto import Random
>>>
>>> key = b'Sixteen byte key'
>>> iv = Random.new().read(AES.block_size)
>>> cipher = AES.new(key, AES.MODE_CFB, iv)
>>> msg = iv + cipher.encrypt(b'Attack at dawn')
.. __: http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
.. _NIST: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
:undocumented: __revision__, __package__
"""
__revision__ = "$Id$"
from Crypto.Cipher import blockalgo
from Crypto.Cipher import _AES
class AESCipher (blockalgo.BlockAlgo):
"""AES cipher object"""
def __init__(self, key, *args, **kwargs):
"""Initialize an AES cipher object
See also `new()` at the module level."""
blockalgo.BlockAlgo.__init__(self, _AES, key, *args, **kwargs)
def new(key, *args, **kwargs):
"""Create a new AES cipher
:Parameters:
key : byte string
The secret key to use in the symmetric cipher.
It must be 16 (*AES-128*), 24 (*AES-192*), or 32 (*AES-256*) bytes long.
:Keywords:
mode : a *MODE_** constant
The chaining mode to use for encryption or decryption.
Default is `MODE_ECB`.
IV : byte string
The initialization vector to use for encryption or decryption.
It is ignored for `MODE_ECB` and `MODE_CTR`.
For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption
and `block_size` +2 bytes for decryption (in the latter case, it is
actually the *encrypted* IV which was prefixed to the ciphertext).
It is mandatory.
For all other modes, it must be `block_size` bytes longs. It is optional and
when not present it will be given a default value of all zeroes.
counter : callable
(*Only* `MODE_CTR`). A stateful function that returns the next
*counter block*, which is a byte string of `block_size` bytes.
For better performance, use `Crypto.Util.Counter`.
segment_size : integer
(*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext
are segmented in.
It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8.
:Return: an `AESCipher` object
"""
return AESCipher(key, *args, **kwargs)
#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`.
MODE_ECB = 1
#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`.
MODE_CBC = 2
#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`.
MODE_CFB = 3
#: This mode should not be used.
MODE_PGP = 4
#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`.
MODE_OFB = 5
#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`.
MODE_CTR = 6
#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`.
MODE_OPENPGP = 7
#: Size of a data block (in bytes)
block_size = 16
#: Size of a key (in bytes)
key_size = ( 16, 24, 32 )
Binary file not shown.
+83
View File
@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Symmetric- and asymmetric-key encryption algorithms.
Encryption algorithms transform plaintext in some way that
is dependent on a key or key pair, producing ciphertext.
Symmetric algorithms
--------------------
Encryption can easily be reversed, if (and, hopefully, only if)
one knows the same key.
In other words, sender and receiver share the same key.
The symmetric encryption modules here all support the interface described in PEP
272, "API for Block Encryption Algorithms".
If you don't know which algorithm to choose, use AES because it's
standard and has undergone a fair bit of examination.
======================== ======= ========================
Module name Type Description
======================== ======= ========================
`Crypto.Cipher.AES` Block Advanced Encryption Standard
`Crypto.Cipher.ARC2` Block Alleged RC2
`Crypto.Cipher.ARC4` Stream Alleged RC4
`Crypto.Cipher.Blowfish` Block Blowfish
`Crypto.Cipher.CAST` Block CAST
`Crypto.Cipher.DES` Block The Data Encryption Standard.
Very commonly used in the past,
but today its 56-bit keys are too small.
`Crypto.Cipher.DES3` Block Triple DES.
`Crypto.Cipher.XOR` Stream The simple XOR cipher.
======================== ======= ========================
Asymmetric algorithms
---------------------
For asymmetric algorithms, the key to be used for decryption is totally
different and cannot be derived in a feasible way from the key used
for encryption. Put differently, sender and receiver each own one half
of a key pair. The encryption key is often called ``public`` whereas
the decryption key is called ``private``.
========================== =======================
Module name Description
========================== =======================
`Crypto.Cipher.PKCS1_v1_5` PKCS#1 v1.5 encryption, based on RSA key pairs
`Crypto.Cipher.PKCS1_OAEP` PKCS#1 OAEP encryption, based on RSA key pairs
========================== =======================
:undocumented: __revision__, __package__, _AES, _ARC2, _ARC4, _Blowfish
_CAST, _DES, _DES3, _XOR
"""
__all__ = ['AES', 'ARC2', 'ARC4',
'Blowfish', 'CAST', 'DES', 'DES3',
'XOR',
'PKCS1_v1_5', 'PKCS1_OAEP'
]
__revision__ = "$Id$"
+296
View File
@@ -0,0 +1,296 @@
# -*- coding: utf-8 -*-
#
# Cipher/blockalgo.py
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Module with definitions common to all block ciphers."""
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
from Crypto.Util.py3compat import *
#: *Electronic Code Book (ECB)*.
#: This is the simplest encryption mode. Each of the plaintext blocks
#: is directly encrypted into a ciphertext block, independently of
#: any other block. This mode exposes frequency of symbols
#: in your plaintext. Other modes (e.g. *CBC*) should be used instead.
#:
#: See `NIST SP800-38A`_ , Section 6.1 .
#:
#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
MODE_ECB = 1
#: *Cipher-Block Chaining (CBC)*. Each of the ciphertext blocks depends
#: on the current and all previous plaintext blocks. An Initialization Vector
#: (*IV*) is required.
#:
#: The *IV* is a data block to be transmitted to the receiver.
#: The *IV* can be made public, but it must be authenticated by the receiver and
#: it should be picked randomly.
#:
#: See `NIST SP800-38A`_ , Section 6.2 .
#:
#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
MODE_CBC = 2
#: *Cipher FeedBack (CFB)*. This mode is similar to CBC, but it transforms
#: the underlying block cipher into a stream cipher. Plaintext and ciphertext
#: are processed in *segments* of **s** bits. The mode is therefore sometimes
#: labelled **s**-bit CFB. An Initialization Vector (*IV*) is required.
#:
#: When encrypting, each ciphertext segment contributes to the encryption of
#: the next plaintext segment.
#:
#: This *IV* is a data block to be transmitted to the receiver.
#: The *IV* can be made public, but it should be picked randomly.
#: Reusing the same *IV* for encryptions done with the same key lead to
#: catastrophic cryptographic failures.
#:
#: See `NIST SP800-38A`_ , Section 6.3 .
#:
#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
MODE_CFB = 3
#: This mode should not be used.
MODE_PGP = 4
#: *Output FeedBack (OFB)*. This mode is very similar to CBC, but it
#: transforms the underlying block cipher into a stream cipher.
#: The keystream is the iterated block encryption of an Initialization Vector (*IV*).
#:
#: The *IV* is a data block to be transmitted to the receiver.
#: The *IV* can be made public, but it should be picked randomly.
#:
#: Reusing the same *IV* for encryptions done with the same key lead to
#: catastrophic cryptograhic failures.
#:
#: See `NIST SP800-38A`_ , Section 6.4 .
#:
#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
MODE_OFB = 5
#: *CounTeR (CTR)*. This mode is very similar to ECB, in that
#: encryption of one block is done independently of all other blocks.
#: Unlike ECB, the block *position* contributes to the encryption and no
#: information leaks about symbol frequency.
#:
#: Each message block is associated to a *counter* which must be unique
#: across all messages that get encrypted with the same key (not just within
#: the same message). The counter is as big as the block size.
#:
#: Counters can be generated in several ways. The most straightword one is
#: to choose an *initial counter block* (which can be made public, similarly
#: to the *IV* for the other modes) and increment its lowest **m** bits by
#: one (modulo *2^m*) for each block. In most cases, **m** is chosen to be half
#: the block size.
#:
#: Reusing the same *initial counter block* for encryptions done with the same
#: key lead to catastrophic cryptograhic failures.
#:
#: See `NIST SP800-38A`_ , Section 6.5 (for the mode) and Appendix B (for how
#: to manage the *initial counter block*).
#:
#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
MODE_CTR = 6
#: OpenPGP. This mode is a variant of CFB, and it is only used in PGP and OpenPGP_ applications.
#: An Initialization Vector (*IV*) is required.
#:
#: Unlike CFB, the IV is not transmitted to the receiver. Instead, the *encrypted* IV is.
#: The IV is a random data block. Two of its bytes are duplicated to act as a checksum
#: for the correctness of the key. The encrypted IV is therefore 2 bytes longer than
#: the clean IV.
#:
#: .. _OpenPGP: http://tools.ietf.org/html/rfc4880
MODE_OPENPGP = 7
def _getParameter(name, index, args, kwargs, default=None):
"""Find a parameter in tuple and dictionary arguments a function receives"""
param = kwargs.get(name)
if len(args)>index:
if param:
raise ValueError("Parameter '%s' is specified twice" % name)
param = args[index]
return param or default
class BlockAlgo:
"""Class modelling an abstract block cipher."""
def __init__(self, factory, key, *args, **kwargs):
self.mode = _getParameter('mode', 0, args, kwargs, default=MODE_ECB)
self.block_size = factory.block_size
if self.mode != MODE_OPENPGP:
self._cipher = factory.new(key, *args, **kwargs)
self.IV = self._cipher.IV
else:
# OPENPGP mode. For details, see 13.9 in RCC4880.
#
# A few members are specifically created for this mode:
# - _encrypted_iv, set in this constructor
# - _done_first_block, set to True after the first encryption
# - _done_last_block, set to True after a partial block is processed
self._done_first_block = False
self._done_last_block = False
self.IV = _getParameter('iv', 1, args, kwargs)
if not self.IV:
raise ValueError("MODE_OPENPGP requires an IV")
# Instantiate a temporary cipher to process the IV
IV_cipher = factory.new(key, MODE_CFB,
b('\x00')*self.block_size, # IV for CFB
segment_size=self.block_size*8)
# The cipher will be used for...
if len(self.IV) == self.block_size:
# ... encryption
self._encrypted_IV = IV_cipher.encrypt(
self.IV + self.IV[-2:] + # Plaintext
b('\x00')*(self.block_size-2) # Padding
)[:self.block_size+2]
elif len(self.IV) == self.block_size+2:
# ... decryption
self._encrypted_IV = self.IV
self.IV = IV_cipher.decrypt(self.IV + # Ciphertext
b('\x00')*(self.block_size-2) # Padding
)[:self.block_size+2]
if self.IV[-2:] != self.IV[-4:-2]:
raise ValueError("Failed integrity check for OPENPGP IV")
self.IV = self.IV[:-2]
else:
raise ValueError("Length of IV must be %d or %d bytes for MODE_OPENPGP"
% (self.block_size, self.block_size+2))
# Instantiate the cipher for the real PGP data
self._cipher = factory.new(key, MODE_CFB,
self._encrypted_IV[-self.block_size:],
segment_size=self.block_size*8)
def encrypt(self, plaintext):
"""Encrypt data with the key and the parameters set at initialization.
The cipher object is stateful; encryption of a long block
of data can be broken up in two or more calls to `encrypt()`.
That is, the statement:
>>> c.encrypt(a) + c.encrypt(b)
is always equivalent to:
>>> c.encrypt(a+b)
That also means that you cannot reuse an object for encrypting
or decrypting other data with the same key.
This function does not perform any padding.
- For `MODE_ECB`, `MODE_CBC`, and `MODE_OFB`, *plaintext* length
(in bytes) must be a multiple of *block_size*.
- For `MODE_CFB`, *plaintext* length (in bytes) must be a multiple
of *segment_size*/8.
- For `MODE_CTR`, *plaintext* can be of any length.
- For `MODE_OPENPGP`, *plaintext* must be a multiple of *block_size*,
unless it is the last chunk of the message.
:Parameters:
plaintext : byte string
The piece of data to encrypt.
:Return:
the encrypted data, as a byte string. It is as long as
*plaintext* with one exception: when encrypting the first message
chunk with `MODE_OPENPGP`, the encypted IV is prepended to the
returned ciphertext.
"""
if self.mode == MODE_OPENPGP:
padding_length = (self.block_size - len(plaintext) % self.block_size) % self.block_size
if padding_length>0:
# CFB mode requires ciphertext to have length multiple of block size,
# but PGP mode allows the last block to be shorter
if self._done_last_block:
raise ValueError("Only the last chunk is allowed to have length not multiple of %d bytes",
self.block_size)
self._done_last_block = True
padded = plaintext + b('\x00')*padding_length
res = self._cipher.encrypt(padded)[:len(plaintext)]
else:
res = self._cipher.encrypt(plaintext)
if not self._done_first_block:
res = self._encrypted_IV + res
self._done_first_block = True
return res
return self._cipher.encrypt(plaintext)
def decrypt(self, ciphertext):
"""Decrypt data with the key and the parameters set at initialization.
The cipher object is stateful; decryption of a long block
of data can be broken up in two or more calls to `decrypt()`.
That is, the statement:
>>> c.decrypt(a) + c.decrypt(b)
is always equivalent to:
>>> c.decrypt(a+b)
That also means that you cannot reuse an object for encrypting
or decrypting other data with the same key.
This function does not perform any padding.
- For `MODE_ECB`, `MODE_CBC`, and `MODE_OFB`, *ciphertext* length
(in bytes) must be a multiple of *block_size*.
- For `MODE_CFB`, *ciphertext* length (in bytes) must be a multiple
of *segment_size*/8.
- For `MODE_CTR`, *ciphertext* can be of any length.
- For `MODE_OPENPGP`, *plaintext* must be a multiple of *block_size*,
unless it is the last chunk of the message.
:Parameters:
ciphertext : byte string
The piece of data to decrypt.
:Return: the decrypted data (byte string, as long as *ciphertext*).
"""
if self.mode == MODE_OPENPGP:
padding_length = (self.block_size - len(ciphertext) % self.block_size) % self.block_size
if padding_length>0:
# CFB mode requires ciphertext to have length multiple of block size,
# but PGP mode allows the last block to be shorter
if self._done_last_block:
raise ValueError("Only the last chunk is allowed to have length not multiple of %d bytes",
self.block_size)
self._done_last_block = True
padded = ciphertext + b('\x00')*padding_length
res = self._cipher.decrypt(padded)[:len(ciphertext)]
else:
res = self._cipher.decrypt(ciphertext)
return res
return self._cipher.decrypt(ciphertext)