Beispiel #1
0
    def test_bytearray(self):
        data = b("1") * 16
        iv = b("\x00") * 6 + b("\xFF\xFF")

        # Encrypt
        cipher1 = AES.new(self.key_128, AES.MODE_CTR,
                          nonce=self.nonce_64,
                          initial_value=iv)
        ref1 = cipher1.encrypt(data)

        cipher2 = AES.new(self.key_128, AES.MODE_CTR,
                          nonce=bytearray(self.nonce_64),
                          initial_value=bytearray(iv))
        ref2 = cipher2.encrypt(bytearray(data))

        self.assertEqual(ref1, ref2)
        self.assertEqual(cipher1.nonce, cipher2.nonce)

        # Decrypt
        cipher3 = AES.new(self.key_128, AES.MODE_CTR,
                          nonce=self.nonce_64,
                          initial_value=iv)
        ref3 = cipher3.decrypt(data)

        cipher4 = AES.new(self.key_128, AES.MODE_CTR,
                          nonce=bytearray(self.nonce_64),
                          initial_value=bytearray(iv))
        ref4 = cipher4.decrypt(bytearray(data))

        self.assertEqual(ref3, ref4)
Beispiel #2
0
    def _start_mac(self):

        assert(self._mac_status == MacStatus.NOT_STARTED)
        assert(None not in (self._assoc_len, self._msg_len))
        assert(isinstance(self._cache, list))

        # Formatting control information and nonce (A.2.1)
        q = 15 - len(self.nonce)  # length of Q, the encoded message length
        flags = (64 * (self._assoc_len > 0) + 8 * ((self._mac_len - 2) // 2) +
                 (q - 1))
        b_0 = bchr(flags) + self.nonce + long_to_bytes(self._msg_len, q)

        # Formatting associated data (A.2.2)
        # Encoded 'a' is concatenated with the associated data 'A'
        assoc_len_encoded = b('')
        if self._assoc_len > 0:
            if self._assoc_len < (2 ** 16 - 2 ** 8):
                enc_size = 2
            elif self._assoc_len < (2 ** 32):
                assoc_len_encoded = b('\xFF\xFE')
                enc_size = 4
            else:
                assoc_len_encoded = b('\xFF\xFF')
                enc_size = 8
            assoc_len_encoded += long_to_bytes(self._assoc_len, enc_size)

        # b_0 and assoc_len_encoded must be processed first
        self._cache.insert(0, b_0)
        self._cache.insert(1, assoc_len_encoded)

        # Process all the data cached so far
        first_data_to_mac = b("").join(self._cache)
        self._cache = b("")
        self._mac_status = MacStatus.PROCESSING_AUTH_DATA
        self._update(first_data_to_mac)
Beispiel #3
0
    def _update(self, assoc_data_pt=b("")):
        """Update the MAC with associated data or plaintext
           (without FSM checks)"""

        if self._mac_status == MacStatus.NOT_STARTED:
            self._cache.append(assoc_data_pt)
            return

        assert(byte_string(self._cache))
        assert(len(self._cache) < self.block_size)

        if len(self._cache) > 0:
            filler = min(self.block_size - len(self._cache),
                         len(assoc_data_pt))
            self._cache += assoc_data_pt[:filler]
            assoc_data_pt = assoc_data_pt[filler:]

            if len(self._cache) < self.block_size:
                return

            # The cache is exactly one block
            self._t = self._mac.encrypt(self._cache)
            self._cache = b("")

        update_len = len(assoc_data_pt) // self.block_size * self.block_size
        self._cache = assoc_data_pt[update_len:]
        if update_len > 0:
            self._t = self._mac.encrypt(assoc_data_pt[:update_len])[-16:]
Beispiel #4
0
    def update(self, msg):
        """Authenticate the next chunk of message.

        Args:
            data (byte string): The next chunk of data
        """

        self._data_size += len(msg)

        if len(self._cache) > 0:
            filler = min(self.digest_size - len(self._cache), len(msg))
            self._cache += msg[:filler]

            if len(self._cache) < self.digest_size:
                return self

            msg = msg[filler:]
            self._update(self._cache)
            self._cache = b("")

        update_len, remain = divmod(len(msg), self.digest_size)
        update_len *= self.digest_size
        if remain > 0:
            self._update(msg[:update_len])
            self._cache = msg[update_len:]
        else:
            self._update(msg)
            self._cache = b("")
        return self
Beispiel #5
0
    def test_nonce_parameter(self):
        # Nonce parameter becomes nonce attribute
        cipher1 = AES.new(self.key_128, AES.MODE_CTR, nonce=self.nonce_64)
        self.assertEqual(cipher1.nonce, self.nonce_64)

        counter = Counter.new(64, prefix=self.nonce_64, initial_value=0)
        cipher2 = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        self.assertEqual(cipher1.nonce, cipher2.nonce)

        pt = get_tag_random("plaintext", 65536)
        self.assertEqual(cipher1.encrypt(pt), cipher2.encrypt(pt))

        # Nonce is implicitly created (for AES) when no parameters are passed
        nonce1 = AES.new(self.key_128, AES.MODE_CTR).nonce
        nonce2 = AES.new(self.key_128, AES.MODE_CTR).nonce
        self.assertNotEqual(nonce1, nonce2)
        self.assertEqual(len(nonce1), 8)

        # Nonce can be zero-length
        cipher = AES.new(self.key_128, AES.MODE_CTR, nonce=b(""))
        self.assertEqual(b(""), cipher.nonce)

        # Nonce and Counter are mutually exclusive
        self.assertRaises(TypeError, AES.new, self.key_128, AES.MODE_CTR,
                          counter=self.ctr_128, nonce=self.nonce_64)
Beispiel #6
0
    def test3(self):

        for keylen, taglen, result in self.tv3:

            key = bchr(0) * (keylen // 8 - 1) + bchr(taglen)
            C = b("")

            for i in range(128):
                S = bchr(0) * i

                N = long_to_bytes(3 * i + 1, 12)
                cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8)
                cipher.update(S)
                C += cipher.encrypt(S) + cipher.encrypt() + cipher.digest()

                N = long_to_bytes(3 * i + 2, 12)
                cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8)
                C += cipher.encrypt(S) + cipher.encrypt() + cipher.digest()

                N = long_to_bytes(3 * i + 3, 12)
                cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8)
                cipher.update(S)
                C += cipher.encrypt() + cipher.digest()

            N = long_to_bytes(385, 12)
            cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8)
            cipher.update(C)
            result2 = cipher.encrypt() + cipher.digest()
            self.assertEqual(unhexlify(b(result)), result2)
    def test_unaligned_data_64(self):
        plaintexts = [ b("7777777") ] * 100

        cipher = DES3.new(self.key_192, DES3.MODE_OPENPGP, self.iv_64)
        ciphertexts = [ cipher.encrypt(x) for x in plaintexts ]
        cipher = DES3.new(self.key_192, DES3.MODE_OPENPGP, self.iv_64)
        self.assertEqual(b("").join(ciphertexts), cipher.encrypt(b("").join(plaintexts)))
Beispiel #8
0
    def _start_mac(self):

        assert(self._mac_status == MacStatus.NOT_STARTED)
        assert(None not in (self._assoc_len, self._msg_len))
        assert(isinstance(self._cache, list))

        # Formatting control information and nonce (A.2.1)
        q = 15 - len(self.nonce)  # length of Q, the encoded message length
        flags = (64 * (self._assoc_len > 0) + 8 * ((self._mac_len - 2) // 2) +
                 (q - 1))
        b_0 = bchr(flags) + self.nonce + long_to_bytes(self._msg_len, q)

        # Formatting associated data (A.2.2)
        # Encoded 'a' is concatenated with the associated data 'A'
        assoc_len_encoded = b('')
        if self._assoc_len > 0:
            if self._assoc_len < (2 ** 16 - 2 ** 8):
                enc_size = 2
            elif self._assoc_len < (2L ** 32):
                assoc_len_encoded = b('\xFF\xFE')
                enc_size = 4
            else:
                assoc_len_encoded = b('\xFF\xFF')
                enc_size = 8
            assoc_len_encoded += long_to_bytes(self._assoc_len, enc_size)
Beispiel #9
0
def import_key(encoded, passphrase=None):
    """Import an ECC key (public or private).

    :Parameters:
      encoded : bytes or a (multi-line) string
        The ECC key to import.

        An ECC public key can be:

        - An X.509 certificate, binary (DER) or ASCII (PEM)
        - An X.509 ``subjectPublicKeyInfo``, binary (DER) or ASCII (PEM)
        - An OpenSSH line (e.g. the content of ``~/.ssh/id_ecdsa``, ASCII)

        An ECC private key can be:

        - In binary format (DER, see section 3 of `RFC5915`_ or `PKCS#8`_)
        - In ASCII format (PEM or OpenSSH)

        Private keys can be in the clear or password-protected.

        For details about the PEM encoding, see `RFC1421`_/`RFC1423`_.

    :Keywords:
      passphrase : byte string
        The passphrase to use for decrypting a private key.
        Encryption may be applied protected at the PEM level or at the PKCS#8 level.
        This parameter is ignored if the key in input is not encrypted.

    :Return: An ECC key object (`EccKey`)

    :Raise ValueError:
        When the given key cannot be parsed (possibly because
        the pass phrase is wrong).

    .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt
    .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt
    .. _RFC5915: http://www.ietf.org/rfc/rfc5915.txt
    .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt
    """

    encoded = tobytes(encoded)
    if passphrase is not None:
        passphrase = tobytes(passphrase)

    # PEM
    if encoded.startswith(b('-----')):
        der_encoded, marker, enc_flag = PEM.decode(tostr(encoded), passphrase)
        if enc_flag:
            passphrase = None
        return _import_der(der_encoded, passphrase)

    # OpenSSH
    if encoded.startswith(b('ecdsa-sha2-')):
        return _import_openssh(encoded)

    # DER
    if bord(encoded[0]) == 0x30:
        return _import_der(encoded, passphrase)

    raise ValueError("ECC key format is not supported")
Beispiel #10
0
    def _transcrypt(self, in_data, trans_func, trans_desc):
        # Last piece to encrypt/decrypt
        if in_data is None:
            out_data = self._transcrypt_aligned(self._cache_P, len(self._cache_P), trans_func, trans_desc)
            self._cache_P = b("")
            return out_data

        # Try to fill up the cache, if it already contains something
        expect_byte_string(in_data)
        prefix = b("")
        if len(self._cache_P) > 0:
            filler = min(16 - len(self._cache_P), len(in_data))
            self._cache_P += in_data[:filler]
            in_data = in_data[filler:]

            if len(self._cache_P) < 16:
                # We could not manage to fill the cache, so there is certainly
                # no output yet.
                return b("")

            # Clear the cache, and proceeding with any other aligned data
            prefix = self._transcrypt_aligned(self._cache_P, len(self._cache_P), trans_func, trans_desc)
            self._cache_P = b("")

        # Process data in multiples of the block size
        trans_len = len(in_data) // 16 * 16
        result = self._transcrypt_aligned(in_data, trans_len, trans_func, trans_desc)
        if prefix:
            result = prefix + result

        # Left-over
        self._cache_P = in_data[trans_len:]

        return result
    def test_unaligned_data_128(self):
        plaintexts = [ b("7777777") ] * 100

        cipher = AES.new(self.key_128, AES.MODE_OPENPGP, self.iv_128)
        ciphertexts = [ cipher.encrypt(x) for x in plaintexts ]
        cipher = AES.new(self.key_128, AES.MODE_OPENPGP, self.iv_128)
        self.assertEqual(b("").join(ciphertexts), cipher.encrypt(b("").join(plaintexts)))
Beispiel #12
0
 def test_iv_with_matching_length(self):
     self.assertRaises(ValueError, AES.new, self.key_128, self.aes_mode,
                       b(""))
     self.assertRaises(ValueError, AES.new, self.key_128, self.aes_mode,
                       self.iv_128[:15])
     self.assertRaises(ValueError, AES.new, self.key_128, self.aes_mode,
                       self.iv_128 + b("0"))
Beispiel #13
0
    def __init__(self, factory, nonce, mac_len, cipher_params):

        if factory.block_size != 16:
            raise ValueError("OCB mode is only available for ciphers" " that operate on 128 bits blocks")

        self.block_size = 16
        """The block size of the underlying cipher, in bytes."""

        self.nonce = nonce
        """Nonce used for this session."""
        if len(nonce) not in range(1, 16):
            raise ValueError("Nonce must be at most 15 bytes long")

        self._mac_len = mac_len
        if not 8 <= mac_len <= 16:
            raise ValueError("MAC tag must be between 8 and 16 bytes long")

        # Cache for MAC tag
        self._mac_tag = None

        # Cache for unaligned associated data
        self._cache_A = b("")

        # Cache for unaligned ciphertext/plaintext
        self._cache_P = b("")

        # Allowed transitions after initialization
        self._next = [self.update, self.encrypt, self.decrypt, self.digest, self.verify]

        # Compute Offset_0
        params_without_key = dict(cipher_params)
        key = params_without_key.pop("key")
        nonce = bchr(self._mac_len << 4 & 0xFF) + bchr(0) * (14 - len(self.nonce)) + bchr(1) + self.nonce
        bottom = bord(nonce[15]) & 0x3F  # 6 bits, 0..63
        ktop = factory.new(key, factory.MODE_ECB, **params_without_key).encrypt(
            nonce[:15] + bchr(bord(nonce[15]) & 0xC0)
        )
        stretch = ktop + strxor(ktop[:8], ktop[1:9])  # 192 bits
        offset_0 = long_to_bytes(bytes_to_long(stretch) >> (64 - bottom), 24)[8:]

        # Create low-level cipher instance
        raw_cipher = factory._create_base_cipher(cipher_params)
        if cipher_params:
            raise TypeError("Unknown keywords: " + str(cipher_params))

        self._state = VoidPointer()
        result = _raw_ocb_lib.OCB_start_operation(
            raw_cipher.get(), offset_0, c_size_t(len(offset_0)), self._state.address_of()
        )
        if result:
            raise ValueError("Error %d while instantiating the OCB mode" % result)

        # Ensure that object disposal of this Python object will (eventually)
        # free the memory allocated by the raw library for the cipher mode
        self._state = SmartPointer(self._state.get(), _raw_ocb_lib.OCB_stop_operation)

        # Memory allocated for the underlying block cipher is now owed
        # by the cipher mode
        raw_cipher.release()
Beispiel #14
0
    def test_either_encrypt_or_decrypt(self):
        cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
        cipher.encrypt(b(""))
        self.assertRaises(TypeError, cipher.decrypt, b(""))

        cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
        cipher.decrypt(b(""))
        self.assertRaises(TypeError, cipher.encrypt, b(""))
Beispiel #15
0
 def digest(self):
     if self._tag:
         return self._tag
     if self._buffer_len>0:
         self.update(b(""))
     left_data = b("").join(self._buffer)
     self._tag = self._digest(left_data)
     return self._tag
    def test_either_encrypt_or_decrypt(self):
        cipher = AES.new(self.key_128, AES.MODE_OPENPGP, self.iv_128)
        eiv = cipher.encrypt(b(""))
        self.assertRaises(TypeError, cipher.decrypt, b(""))

        cipher = AES.new(self.key_128, AES.MODE_OPENPGP, eiv)
        cipher.decrypt(b(""))
        self.assertRaises(TypeError, cipher.encrypt, b(""))
Beispiel #17
0
 def __init__(self, module, params):
     from Crypto import Random
     unittest.TestCase.__init__(self)
     self.module = module
     self.iv = Random.get_random_bytes(module.block_size)
     self.key = b(params['key'])
     self.plaintext = 100 * b(params['plaintext'])
     self.module_name = params.get('module_name', None)
Beispiel #18
0
    def test_either_encrypt_or_decrypt(self):
        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=self.ctr_128)
        cipher.encrypt(b(""))
        self.assertRaises(TypeError, cipher.decrypt, b(""))

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=self.ctr_128)
        cipher.decrypt(b(""))
        self.assertRaises(TypeError, cipher.encrypt, b(""))
Beispiel #19
0
    def test_unaligned_data_64(self):
        cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64)
        for wrong_length in range(1,8):
            self.assertRaises(ValueError, cipher.encrypt, b("5") * wrong_length)

        cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64)
        for wrong_length in range(1,8):
            self.assertRaises(ValueError, cipher.decrypt, b("5") * wrong_length)
Beispiel #20
0
    def test_unaligned_data_128(self):
        cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
        for wrong_length in range(1,16):
            self.assertRaises(ValueError, cipher.encrypt, b("5") * wrong_length)

        cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
        for wrong_length in range(1,16):
            self.assertRaises(ValueError, cipher.decrypt, b("5") * wrong_length)
Beispiel #21
0
 def test_copy(self):
     h = self.BLAKE2.new(digest_bits=self.max_bits, data=b("init"))
     h2 = h.copy()
     self.assertEqual(h.digest(), h2.digest())
     h.update(b("second"))
     self.assertNotEqual(h.digest(), h2.digest())
     h2.update(b("second"))
     self.assertEqual(h.digest(), h2.digest())
Beispiel #22
0
    def test_either_encrypt_or_decrypt(self):
        cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96)
        cipher.encrypt(b(""))
        self.assertRaises(TypeError, cipher.decrypt, b(""))

        cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96)
        cipher.decrypt(b(""))
        self.assertRaises(TypeError, cipher.encrypt, b(""))
Beispiel #23
0
    def test_new_positive(self):

        xof1 = self.shake.new()
        xof2 = self.shake.new(data=b("90"))
        xof3 = self.shake.new().update(b("90"))

        self.assertNotEqual(xof1.read(10), xof2.read(10))
        xof3.read(10)
        self.assertEqual(xof2.read(10), xof3.read(10))
Beispiel #24
0
    def test_init(self):
        # Verify that nonce can be passed in the old way (3rd parameter)
        # or in the new way ('nonce' parameter)
        ct, mac = self._create_cipher().encrypt_and_digest(b("XXX"))

        cipher = AES.new(self.key, AES.MODE_OCB, bchr(0)*15)
        ct2, mac2 = cipher.encrypt_and_digest(b("XXX"))
        self.assertEquals(ct, ct2)
        self.assertEquals(mac, mac2)
Beispiel #25
0
    def runTest(self):

        for key_size, result in self.test_vectors:
            next_data = b("")
            for _ in xrange(100):
                h = self.BLAKE2.new(digest_bytes=self.max_bytes, key=b("A" * key_size))
                h.update(next_data)
                next_data = h.digest() + next_data
            self.assertEqual(h.digest(), result)
Beispiel #26
0
    def test_update_chaining(self):
        cipher = self._create_cipher()
        cipher.update(b("XXX")).update(b("YYY"))
        mac = cipher.digest()

        cipher = self._create_cipher()
        cipher.update(b("XXXYYY"))
        mac2 = cipher.digest()

        self.assertEquals(mac, mac2)
Beispiel #27
0
    def test_invalid_multiple_encrypt(self):
        # Without AAD
        cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96)
        cipher.encrypt(b("xxx"))
        self.assertRaises(TypeError, cipher.encrypt, b("xxx"))

        # With AAD
        cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=self.nonce_96)
        cipher.update(b("yyy"))
        cipher.encrypt(b("xxx"))
        self.assertRaises(TypeError, cipher.encrypt, b("xxx"))
Beispiel #28
0
    def __init__(self, key, msg=b(""), digestmod=None):
        """Create a new HMAC object.

        :Parameters:
          key : byte string
            secret key for the MAC object.
            It must be long enough to match the expected security level of the
            MAC. However, there is no benefit in using keys longer than the
            `digest_size` of the underlying hash algorithm.
          msg : byte string
            The very first chunk of the message to authenticate.
            It is equivalent to an early call to `update()`. Optional.
        :Parameter digestmod:
            The hash algorithm the HMAC is based on.
            Default is `Crypto.Hash.MD5`.
        :Type digestmod:
            A hash module or object instantiated from `Crypto.Hash`
        """

        if digestmod is None:
            digestmod = MD5

        if msg is None:
            msg = b("")

        #: Size of the MAC tag
        self.digest_size = digestmod.digest_size

        self._digestmod = digestmod

        try:
            if len(key) <= digestmod.block_size:
                # Step 1 or 2
                key_0 = key + bchr(0) * (digestmod.block_size - len(key))
            else:
                # Step 3
                hash_k = digestmod.new(key).digest()
                key_0 = hash_k + bchr(0) * (digestmod.block_size - len(hash_k))
        except AttributeError:
            # Not all hash types have "block_size"
            raise ValueError("Hash type incompatible to HMAC")

        # Step 4
        key_0_ipad = strxor(key_0, bchr(0x36) * len(key_0))

        # Start step 5 and 6
        self._inner = digestmod.new(key_0_ipad)
        self._inner.update(msg)

        # Step 7
        key_0_opad = strxor(key_0, bchr(0x5c) * len(key_0))

        # Start step 8 and 9
        self._outer = digestmod.new(key_0_opad)
Beispiel #29
0
    def test_unaligned_data_64(self):
        plaintexts = [ b("7777777") ] * 100
        cipher = DES3.new(self.key_192, AES.MODE_CTR, counter=self.ctr_64)
        ciphertexts = [ cipher.encrypt(x) for x in plaintexts ]
        cipher = DES3.new(self.key_192, AES.MODE_CTR, counter=self.ctr_64)
        self.assertEqual(b("").join(ciphertexts), cipher.encrypt(b("").join(plaintexts)))

        cipher = DES3.new(self.key_192, AES.MODE_CTR, counter=self.ctr_64)
        ciphertexts = [ cipher.encrypt(x) for x in plaintexts ]
        cipher = DES3.new(self.key_192, AES.MODE_CTR, counter=self.ctr_64)
        self.assertEqual(b("").join(ciphertexts), cipher.encrypt(b("").join(plaintexts)))
Beispiel #30
0
        def test_template(self, factory=factory, key_size=key_size):
            cipher = factory.new(get_tag_random("cipher", key_size),
                                 factory.MODE_EAX,
                                 nonce=b("nonce"))
            ct, mac = cipher.encrypt_and_digest(b("plaintext"))

            cipher = factory.new(get_tag_random("cipher", key_size),
                                 factory.MODE_EAX,
                                 nonce=b("nonce"))
            pt2 = cipher.decrypt_and_verify(ct, mac)

            self.assertEqual(b("plaintext"), pt2)
Beispiel #31
0
 def test_null_encryption_decryption(self):
     for func in "encrypt", "decrypt":
         cipher = AES.new(self.key_128, AES.MODE_CTR, counter=self.ctr_128)
         result = getattr(cipher, func)(b(""))
         self.assertEqual(result, b(""))