Beispiel #1
21
    def test_round_trip(self):
        pt = b("A") * 1024
        c1 = ChaCha20.new(key=b("5") * 32, nonce=b("6") * 8)
        c2 = ChaCha20.new(key=b("5") * 32, nonce=b("6") * 8)
        ct = c1.encrypt(pt)
        self.assertEqual(c2.decrypt(ct), pt)

        self.assertEqual(c1.encrypt(b("")), b(""))
        self.assertEqual(c2.decrypt(b("")), b(""))
    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:]
 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"))
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")
    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.assertEquals(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)))
    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)))
    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 #10
0
 def __init__(self, module, params):
     from Cryptodome 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)
    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 #12
0
    def test_either_encrypt_or_decrypt(self):
        cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
        cipher.encrypt(b("xyz"))
        self.assertRaises(TypeError, cipher.decrypt, b("xyz"))

        cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
        cipher.decrypt(b("xyz"))
        self.assertRaises(TypeError, cipher.encrypt, b("xyz"))
    def test_unaligned_data_128(self):
        cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
        for wrong_length in xrange(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 xrange(1,16):
            self.assertRaises(ValueError, cipher.decrypt, b("5") * wrong_length)
    def test_unaligned_data_64(self):
        cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64)
        for wrong_length in xrange(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 xrange(1,8):
            self.assertRaises(ValueError, cipher.decrypt, b("5") * wrong_length)
    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(""))
    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(""))
    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))
    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)
    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 `Cryptodome.Hash.MD5`.
        :Type digestmod:
            A hash module or object instantiated from `Cryptodome.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)
    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)))
    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 #22
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)
    def runTest(self):
        key = binascii.a2b_hex(b(self.key))
        data = binascii.a2b_hex(b(self.input))

        # Strip whitespace from the expected string (which should be in lowercase-hex)
        expected = b("".join(self.result.split()))

        h = self.module.new(key, **self.params)
        h.update(data)
        out1_bin = h.digest()
        out1 = binascii.b2a_hex(h.digest())
        out2 = h.hexdigest()

        # Verify that correct MAC does not raise any exception
        h.hexverify(out1)
        h.verify(out1_bin)

        # Verify that incorrect MAC does raise ValueError exception
        wrong_mac = strxor_c(out1_bin, 255)
        self.assertRaises(ValueError, h.verify, wrong_mac)
        self.assertRaises(ValueError, h.hexverify, "4556")

        h = self.module.new(key, data, **self.params)

        out3 = h.hexdigest()
        out4 = binascii.b2a_hex(h.digest())

        # Test .copy()
        h2 = h.copy()
        h.update(b("blah blah blah"))  # Corrupt the original hash object
        out5 = binascii.b2a_hex(h2.digest())    # The copied hash object should return the correct result

        # PY3K: Check that hexdigest() returns str and digest() returns bytes
        if sys.version_info[0] > 2:
            self.assertTrue(isinstance(h.digest(), type(b(""))))
            self.assertTrue(isinstance(h.hexdigest(), type("")))

        # PY3K: Check that .hexverify() accepts bytes or str
        if sys.version_info[0] > 2:
            h.hexverify(h.hexdigest())
            h.hexverify(h.hexdigest().encode('ascii'))

        # PY3K: hexdigest() should return str, and digest() should return bytes
        self.assertEqual(expected, out1)
        if sys.version_info[0] == 2:
            self.assertEqual(expected, out2)
            self.assertEqual(expected, out3)
        else:
            self.assertEqual(expected.decode(), out2)
            self.assertEqual(expected.decode(), out3)
        self.assertEqual(expected, out4)
        self.assertEqual(expected, out5)
Beispiel #24
0
def _import_openssh(encoded):
    keystring = binascii.a2b_base64(encoded.split(b(' '))[1])

    keyparts = []
    while len(keystring) > 4:
        l = struct.unpack(">I", keystring[:4])[0]
        keyparts.append(keystring[4:4 + l])
        keystring = keystring[4 + l:]

    if keyparts[1] != b("nistp256"):
        raise ValueError("Unsupported ECC curve")

    return _import_public_der(_curve.oid, keyparts[2])
Beispiel #25
0
    def _export_openssh(self):
        assert not self.has_private()

        desc = "ecdsa-sha2-nistp256"

        # Uncompressed form
        order_bytes = _curve.order.size_in_bytes()
        public_key = (bchr(4) +
                      self.pointQ.x.to_bytes(order_bytes) +
                      self.pointQ.y.to_bytes(order_bytes))

        comps = (tobytes(desc), b("nistp256"), public_key)
        blob = b("").join([ struct.pack(">I", len(x)) + x for x in comps])
        return desc + " " + tostr(binascii.b2a_base64(blob))
    def __init__(self, key, *args, **kwargs):
        """Initialize an ARC4 cipher object

        See also `new()` at the module level."""

        if len(args) > 0:
            ndrop = args[0]
            args = args[1:]
        else:
            ndrop = kwargs.pop('drop', 0)

        if len(key) not in key_size:
            raise ValueError("Incorrect ARC4 key length (%d bytes)" %
                             len(key))

        expect_byte_string(key)

        self._state = VoidPointer()
        result = _raw_arc4_lib.ARC4_stream_init(key,
                                                c_size_t(len(key)),
                                                self._state.address_of())
        if result != 0:
            raise ValueError("Error %d while creating the ARC4 cipher"
                             % result)
        self._state = SmartPointer(self._state.get(),
                                   _raw_arc4_lib.ARC4_stream_destroy)

        if ndrop > 0:
            # This is OK even if the cipher is used for decryption,
            # since encrypt and decrypt are actually the same thing
            # with ARC4.
            self.encrypt(b('\x00') * ndrop)

        self.block_size = 1
        self.key_size = len(key)
Beispiel #27
0
def MGF1(mgfSeed, maskLen, hash_gen):
    """Mask Generation Function, described in `B.2.1 of RFC8017
    <https://tools.ietf.org/html/rfc8017>`_.

    :param mfgSeed:
        seed from which the mask is generated
    :type mfgSeed: byte string

    :param maskLen:
        intended length in bytes of the mask
    :type maskLen: integer

    :param hash_gen:
        A module or a hash object from :mod:`Cryptodome.Hash`
    :type hash_object:

    :return: the mask, as a *byte string*
    """
    T = b("")
    for counter in xrange(ceil_div(maskLen, hash_gen.digest_size)):
        c = long_to_bytes(counter, 4)
        hobj = hash_gen.new()
        hobj.update(mgfSeed + c)
        T = T + hobj.digest()
    assert(len(T) >= maskLen)
    return T[:maskLen]
    def test_IV_iv_attributes(self):
        cipher = AES.new(self.key_128, AES.MODE_OPENPGP, self.iv_128)
        eiv = cipher.encrypt(b(""))
        self.assertEqual(cipher.iv, self.iv_128)

        cipher = AES.new(self.key_128, AES.MODE_OPENPGP, eiv)
        self.assertEqual(cipher.iv, self.iv_128)
    def encode(self):
        """Return the DER BIT STRING, fully encoded as a
        binary string."""

        # Add padding count byte
        self.payload = b('\x00') + self.value
        return DerObject.encode(self)
    def test_digest(self):
        h = self.shake.new()
        digest = h.read(90)

        # read returns a byte string of the right length
        self.failUnless(isinstance(digest, type(b("digest"))))
        self.assertEqual(len(digest), 90)
 def test_valid_multiple_encrypt_or_decrypt(self):
     for method_name in "encrypt", "decrypt":
         for auth_data in (None, b("333"), self.data_128,
                           self.data_128 + b("3")):
             if auth_data is None:
                 assoc_len = None
             else:
                 assoc_len = len(auth_data)
             cipher = AES.new(self.key_128,
                              AES.MODE_OCB,
                              nonce=self.nonce_96)
             if auth_data is not None:
                 cipher.update(auth_data)
             method = getattr(cipher, method_name)
             method(self.data_128)
             method(self.data_128)
             method(self.data_128)
             method(self.data_128)
             method()
Beispiel #32
0
    def test_longer_assoc_data_than_declared(self):
        # More than zero
        cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96,
                         assoc_len=0)
        self.assertRaises(ValueError, cipher.update, b("1"))

        # Too large
        cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=self.nonce_96,
                         assoc_len=15)
        self.assertRaises(ValueError, cipher.update, self.data_128)
Beispiel #33
0
 def test_byte_or_string_passphrase(self):
     encoded1 = ref_private.export_key(format="PEM",
                                       use_pkcs8=False,
                                       passphrase="secret",
                                       randfunc=get_fixed_prng())
     encoded2 = ref_private.export_key(format="PEM",
                                       use_pkcs8=False,
                                       passphrase=b("secret"),
                                       randfunc=get_fixed_prng())
     self.assertEqual(encoded1, encoded2)
    def _create_ctr_cipher(self, mac_tag):
        """Create a new CTR cipher from the MAC in SIV mode"""

        tag_int = bytes_to_long(mac_tag)
        return self._factory.new(self._subkey_cipher,
                                 self._factory.MODE_CTR,
                                 initial_value=tag_int ^
                                 (tag_int & 0x8000000080000000L),
                                 nonce=b(""),
                                 **self._cipher_params)
Beispiel #35
0
    def runTest(self):

        key = RSA.generate(1280)
        signer = pss.new(key)
        hash_names = ("MD2", "MD4", "MD5", "RIPEMD160", "SHA1", "SHA224",
                      "SHA256", "SHA384", "SHA512", "SHA3_224", "SHA3_256",
                      "SHA3_384", "SHA3_512")

        for name in hash_names:
            hashed = load_hash_by_name(name).new(b("Test"))
            signer.sign(hashed)

        from Cryptodome.Hash import BLAKE2b, BLAKE2s
        for hash_size in (20, 32, 48, 64):
            hashed_b = BLAKE2b.new(digest_bytes=hash_size, data=b("Test"))
            signer.sign(hashed_b)
        for hash_size in (16, 20, 28, 32):
            hashed_s = BLAKE2s.new(digest_bytes=hash_size, data=b("Test"))
            signer.sign(hashed_s)
Beispiel #36
0
    def test_negative_unapproved_hashes(self):
        """Verify that unapproved hashes are rejected"""

        from Cryptodome.Hash import RIPEMD160

        self.description = "Unapproved hash (RIPEMD160) test"
        hash_obj = RIPEMD160.new()
        signer = DSS.new(self.key_priv, 'fips-186-3')
        self.assertRaises(ValueError, signer.sign, hash_obj)
        self.assertRaises(ValueError, signer.verify, hash_obj, b("\x00") * 40)
    def runTest(self):

        for tv in self.test_vectors:
            digest_bytes = len(tv)
            next_data = b("")
            for _ in xrange(100):
                h = self.BLAKE2.new(digest_bytes=digest_bytes)
                h.update(next_data)
                next_data = h.digest() + next_data
            self.assertEqual(h.digest(), tv)
Beispiel #38
0
def import_key(encoded, passphrase=None):
    """Import an ECC key (public or private).

    Args:
      encoded (bytes or 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`_.

      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.

    Returns:
      :class:`EccKey` : a new ECC key object

    Raises:
      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
        try:
            result = _import_der(der_encoded, passphrase)
        except UnsupportedEccFeature, uef:
            raise uef
        except ValueError:
            raise ValueError("Invalid DER encoding inside the PEM file")
Beispiel #39
0
    def test_message_chunks(self):
        # Validate that both associated data and plaintext/ciphertext
        # can be broken up in chunks of arbitrary length

        auth_data = get_tag_random("authenticated data", 127)
        plaintext = get_tag_random("plaintext", 127)

        cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
        cipher.update(auth_data)
        ciphertext, ref_mac = cipher.encrypt_and_digest(plaintext)

        def break_up(data, chunk_length):
            return [data[i:i+chunk_length] for i in range(0, len(data),
                    chunk_length)]

        # Encryption
        for chunk_length in 1, 2, 3, 7, 10, 13, 16, 40, 80, 128:

            cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)

            for chunk in break_up(auth_data, chunk_length):
                cipher.update(chunk)
            pt2 = b("")
            for chunk in break_up(ciphertext, chunk_length):
                pt2 += cipher.decrypt(chunk)
            pt2 += cipher.decrypt()
            self.assertEqual(plaintext, pt2)
            cipher.verify(ref_mac)

        # Decryption
        for chunk_length in 1, 2, 3, 7, 10, 13, 16, 40, 80, 128:

            cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)

            for chunk in break_up(auth_data, chunk_length):
                cipher.update(chunk)
            ct2 = b("")
            for chunk in break_up(plaintext, chunk_length):
                ct2 += cipher.encrypt(chunk)
            ct2 += cipher.encrypt()
            self.assertEqual(ciphertext, ct2)
            self.assertEqual(cipher.digest(), ref_mac)
    def test_nonce_length(self):
        # nonce can be of any length (but not empty)
        self.assertRaises(ValueError,
                          AES.new,
                          self.key_256,
                          AES.MODE_SIV,
                          nonce=b(""))

        for x in range(1, 128):
            cipher = AES.new(self.key_256, AES.MODE_SIV, nonce=bchr(1) * x)
            cipher.encrypt(bchr(1))
Beispiel #41
0
 def test_valid_multiple_encrypt_or_decrypt(self):
     # Only possible if msg_len is declared in advance
     for method_name in "encrypt", "decrypt":
         for auth_data in (None, b("333"), self.data_128,
                           self.data_128 + b("3")):
             if auth_data is None:
                 assoc_len = None
             else:
                 assoc_len = len(auth_data)
             cipher = AES.new(self.key_128, AES.MODE_CCM,
                              nonce=self.nonce_96,
                              msg_len=64,
                              assoc_len=assoc_len)
             if auth_data is not None:
                 cipher.update(auth_data)
             method = getattr(cipher, method_name)
             method(self.data_128)
             method(self.data_128)
             method(self.data_128)
             method(self.data_128)
Beispiel #42
0
    def __init__(self, value=b(''), implicit=None, explicit=None):
        """Initialize the DER object as a BIT STRING.

        :Parameters:
          value : byte string or DER object
            The initial, packed bit string.
            If not specified, the bit string is empty.
          implicit : integer
            The IMPLICIT tag to use for the encoded object.
            It overrides the universal tag for OCTET STRING (3).
          explicit : integer
            The EXPLICIT tag to use for the encoded object.
        """
        DerObject.__init__(self, 0x03, b(''), implicit, False, explicit)

        # The bitstring value (packed)
        if isinstance(value, DerObject):
            self.value = value.encode()
        else:
            self.value = value
Beispiel #43
0
    def test_nonce_length(self):
        # nonce cannot be empty
        self.assertRaises(ValueError, AES.new, self.key_128, AES.MODE_OCB,
                          nonce=b(""))

        # nonce can be up to 15 bytes long
        for length in range(1, 16):
            AES.new(self.key_128, AES.MODE_OCB, nonce=self.data[:length])

        self.assertRaises(ValueError, AES.new, self.key_128, AES.MODE_OCB,
                          nonce=self.data)
Beispiel #44
0
    def runTest(self):
        key = RSA.generate(1024)
        hashed = SHA1.new(b("Test"))
        good_signature = PKCS1_PSS.new(key).sign(hashed)
        verifier = PKCS1_PSS.new(key.publickey())

        self.assertEqual(verifier.verify(hashed, good_signature), True)

        # Flip a few bits in the signature
        bad_signature = strxor(good_signature, bchr(1) * len(good_signature))
        self.assertEqual(verifier.verify(hashed, bad_signature), False)
Beispiel #45
0
    def runTest(self):
        key = RSA.importKey(PKCS1_15_NoParams.rsakey)
        hashed = SHA1.new(b("Test"))
        good_signature = PKCS1_v1_5.new(key).sign(hashed)
        verifier = PKCS1_v1_5.new(key.publickey())

        self.assertEqual(verifier.verify(hashed, good_signature), True)

        # Flip a few bits in the signature
        bad_signature = strxor(good_signature, bchr(1) * len(good_signature))
        self.assertEqual(verifier.verify(hashed, bad_signature), False)
    def update(self, msg):
        """Continue authentication of a message by consuming
        the next chunk of data.

        Repeated calls are equivalent to a single call with
        the concatenation of all the arguments. In other words:

           >>> m.update(a); m.update(b)

        is equivalent to:

           >>> m.update(a+b)

        :Parameters:
          msg : byte string
            The next chunk of the message being authenticated
        """

        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 #47
0
    def __init__(self, value=b(''), implicit=None):
        """Initialize the DER object as an OCTET STRING.

        :Parameters:
          value : byte string
            The initial payload of the object.
            If not specified, the payload is empty.

          implicit : integer
            The IMPLICIT tag to use for the encoded object.
            It overrides the universal tag for OCTET STRING (4).
        """
        DerObject.__init__(self, 0x04, value, implicit, False)
Beispiel #48
0
    def testVerify1(self):
        for test in self._testData:
            key = RSA.importKey(test[0])
            expected_pt = b(test[1])
            ct = t2b(test[2])
            cipher = PKCS.new(key)

            # The real test
            pt = cipher.decrypt(ct, None)
            self.assertEqual(pt, expected_pt)

            pt = cipher.decrypt(ct, b'\xFF' * len(expected_pt))
            self.assertEqual(pt, expected_pt)
    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
Beispiel #50
0
    def runTest(self):
        plaintext = a2b_hex(self.plaintext)
        ciphertext = a2b_hex(self.ciphertext)

        # The cipher should work like a stream cipher

        # Test counter mode encryption, 3 bytes at a time
        ct3 = []
        cipher = self._new()
        for i in range(0, len(plaintext), 3):
            ct3.append(cipher.encrypt(plaintext[i:i+3]))
        ct3 = b2a_hex(b("").join(ct3))
        self.assertEqual(self.ciphertext, ct3)  # encryption (3 bytes at a time)

        # Test counter mode decryption, 3 bytes at a time
        pt3 = []
        cipher = self._new()
        for i in range(0, len(ciphertext), 3):
            pt3.append(cipher.encrypt(ciphertext[i:i+3]))
        # PY3K: This is meant to be text, do not change to bytes (data)
        pt3 = b2a_hex(b("").join(pt3))
        self.assertEqual(self.plaintext, pt3)  # decryption (3 bytes at a time)
Beispiel #51
0
def new(**kwargs):
    """Create a new hash object.

    Args:
        data (byte string/array):
            Optional. The very first chunk of the message to hash.
            It is equivalent to an early call to :meth:`BLAKE2b_Hash.update`.
        digest_bytes (integer):
            Optional. The size of the digest, in bytes (1 to 64). Default is 64.
        digest_bits (integer):
            Optional and alternative to ``digest_bytes``.
            The size of the digest, in bits (8 to 512, in steps of 8).
            Default is 512.
        key (byte string):
            Optional. The key to use to compute the MAC (1 to 64 bytes).
            If not specified, no key will be used.
        update_after_digest (boolean):
            Optional. By default, a hash object cannot be updated anymore after
            the digest is computed. When this flag is ``True``, such check
            is no longer enforced.

    Returns:
        A :class:`BLAKE2b_Hash` hash object
    """

    data = kwargs.pop("data", None)
    update_after_digest = kwargs.pop("update_after_digest", False)

    digest_bytes = kwargs.pop("digest_bytes", None)
    digest_bits = kwargs.pop("digest_bits", None)
    if None not in (digest_bytes, digest_bits):
        raise TypeError("Only one digest parameter must be provided")
    if (None, None) == (digest_bytes, digest_bits):
        digest_bytes = 64
    if digest_bytes is not None:
        if not (1 <= digest_bytes <= 64):
            raise ValueError("'digest_bytes' not in range 1..64")
    else:
        if not (8 <= digest_bits <= 512) or (digest_bits % 8):
            raise ValueError("'digest_bytes' not in range 8..512, "
                             "with steps of 8")
        digest_bytes = digest_bits // 8

    key = kwargs.pop("key", b(""))
    if len(key) > 64:
        raise ValueError("BLAKE2s key cannot exceed 64 bytes")

    if kwargs:
        raise TypeError("Unknown parameters: " + str(kwargs))

    return BLAKE2b_Hash(data, key, digest_bytes, update_after_digest)
Beispiel #52
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)
Beispiel #53
0
    def testVerify2(self):
        # Verify that decryption fails if ciphertext is not as long as
        # RSA modulus
        cipher = PKCS.new(self.key1024)
        self.assertRaises(ValueError, cipher.decrypt, '\x00' * 127, "---")
        self.assertRaises(ValueError, cipher.decrypt, '\x00' * 129, "---")

        # Verify that decryption fails if there are less then 8 non-zero padding
        # bytes
        pt = b('\x00\x02' + '\xFF' * 7 + '\x00' + '\x45' * 118)
        pt_int = bytes_to_long(pt)
        ct_int = self.key1024._encrypt(pt_int)
        ct = long_to_bytes(ct_int, 128)
        self.assertEqual("---", cipher.decrypt(ct, "---"))
Beispiel #54
0
    def __init__(self, value=0, implicit=None, explicit=None):
        """Initialize the DER object as an INTEGER.

                :Parameters:
                  value : integer
                    The value of the integer.

                  implicit : integer
                    The IMPLICIT tag to use for the encoded object.
                    It overrides the universal tag for INTEGER (2).
                """

        DerObject.__init__(self, 0x02, b(''), implicit, False, explicit)
        self.value = value  # The integer value
Beispiel #55
0
    def __init__(self, value='', implicit=None, explicit=None):
        """Initialize the DER object as an OBJECT ID.

        :Parameters:
          value : string
            The initial Object Identifier (e.g. "1.2.0.0.6.2").
          implicit : integer
            The IMPLICIT tag to use for the encoded object.
            It overrides the universal tag for OBJECT ID (6).
          explicit : integer
            The EXPLICIT tag to use for the encoded object.
        """
        DerObject.__init__(self, 0x06, b(''), implicit, False, explicit)
        self.value = value
Beispiel #56
0
    def _decodeFromStream(self, s):
        """Decode a complete DER BIT STRING DER from a file."""

        # Fill-up self.payload
        DerObject._decodeFromStream(self, s)

        if self.payload and bord(self.payload[0]) != 0:
            raise ValueError("Not a valid BIT STRING")

        # Fill-up self.value
        self.value = b('')
        # Remove padding count byte
        if self.payload:
            self.value = self.payload[1:]
    def test_new_positive(self):

        h = self.BLAKE2.new(digest_bits=self.max_bits)
        for new_func in self.BLAKE2.new, h.new:

            for dbits in xrange(8, self.max_bits + 1, 8):
                hobj = new_func(digest_bits=dbits)
                self.assertEqual(hobj.digest_size, dbits // 8)

            for dbytes in xrange(1, self.max_bytes + 1):
                hobj = new_func(digest_bytes=dbytes)
                self.assertEqual(hobj.digest_size, dbytes)

            digest1 = new_func(data=b("\x90"),
                               digest_bytes=self.max_bytes).digest()
            digest2 = new_func(digest_bytes=self.max_bytes).update(
                b("\x90")).digest()
            self.assertEqual(digest1, digest2)

            new_func(data=b("A"), key=b("5"), digest_bytes=self.max_bytes)

        hobj = h.new()
        self.assertEqual(hobj.digest_size, self.max_bytes)
Beispiel #58
0
    def encode(self):
        """Return the DER INTEGER, fully encoded as a
                binary string."""

        number = self.value
        self.payload = b('')
        while True:
            self.payload = bchr(int(number & 255)) + self.payload
            if 128 <= number <= 255:
                self.payload = bchr(0x00) + self.payload
            if -128 <= number <= 255:
                break
            number >>= 8
        return DerObject.encode(self)
Beispiel #59
0
 def test_seek_tv(self):
     # Test Vector #4, A.1 from
     # http://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
     key = bchr(0) + bchr(255) + bchr(0) * 30
     nonce = bchr(0) * 8
     cipher = ChaCha20.new(key=key, nonce=nonce)
     cipher.seek(64 * 2)
     expected_key_stream = unhexlify(
         b("72d54dfbf12ec44b362692df94137f32"
           "8fea8da73990265ec1bbbea1ae9af0ca"
           "13b25aa26cb4a648cb9b9d1be65b2c09"
           "24a66c54d545ec1b7374f4872e99f096"))
     ct = cipher.encrypt(bchr(0) * len(expected_key_stream))
     self.assertEqual(expected_key_stream, ct)
Beispiel #60
0
    def __init__(self, key, msg=b(""), digestmod=None):

        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)