Exemplo n.º 1
0
    def _export_subjectPublicKeyInfo(self, compress):
    
        # See 2.2 in RFC5480 and 2.3.3 in SEC1
        # The first byte is:
        # - 0x02:   compressed, only X-coordinate, Y-coordinate is even
        # - 0x03:   compressed, only X-coordinate, Y-coordinate is odd
        # - 0x04:   uncompressed, X-coordinate is followed by Y-coordinate
        #
        # PAI is in theory encoded as 0x00.

        order_bytes = _curve.order.size_in_bytes()

        if compress:
            first_byte = 2 + self.pointQ.y.is_odd()
            public_key = (bchr(first_byte) +
                          self.pointQ.x.to_bytes(order_bytes))
        else:
            public_key = (bchr(4) +
                          self.pointQ.x.to_bytes(order_bytes) +
                          self.pointQ.y.to_bytes(order_bytes))

        unrestricted_oid = "1.2.840.10045.2.1"
        return _create_subject_public_key_info(unrestricted_oid,
                                               public_key,
                                               DerObjectId(_curve.oid))
Exemplo n.º 2
0
    def digest(self):
        """Return the **binary** (non-printable) MAC of the message that has
        been authenticated so far.

        This method does not change the state of the MAC object.
        You can continue updating the object after calling this function.

        :Return: A byte string of `digest_size` bytes. It may contain non-ASCII
         characters, including null bytes.
        """

        if self._mac_tag is not None:
            return self._mac_tag

        if self._data_size > self._max_size:
            raise ValueError("MAC is unsafe for this message")

        if len(self._cache) == 0 and self._before_last_ct is not None:
            ## Last block was full
            pt = strxor(strxor(self._before_last_ct, self._k1), self._last_pt)
        else:
            ## Last block is partial (or message length is zero)
            ext = self._cache + bchr(0x80) +\
                    bchr(0) * (self.digest_size - len(self._cache) - 1)
            pt = strxor(strxor(self._last_ct, self._k2), ext)

        cipher = self._factory.new(self._key,
                                   self._factory.MODE_ECB,
                                   **self._cipher_params)
        self._mac_tag = cipher.encrypt(pt)

        return self._mac_tag
Exemplo n.º 3
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)
Exemplo n.º 4
0
    def runTest(self):
        self.assertRaises(ValueError, ARC2.new, bchr(0) * 4, ARC2.MODE_ECB)
        self.assertRaises(ValueError, ARC2.new, bchr(0) * 129, ARC2.MODE_ECB)

        self.assertRaises(ValueError, ARC2.new, bchr(0) * 16, ARC2.MODE_ECB,
                          effective_keylen=39)
        self.assertRaises(ValueError, ARC2.new, bchr(0) * 16, ARC2.MODE_ECB,
                          effective_keylen=1025)
 def test_update(self):
     pieces = [bchr(10) * 200, bchr(20) * 300]
     h = keccak.new(digest_bytes=64)
     h.update(pieces[0]).update(pieces[1])
     digest = h.digest()
     h = keccak.new(digest_bytes=64)
     h.update(pieces[0] + pieces[1])
     self.assertEqual(h.digest(), digest)
Exemplo n.º 6
0
    def test_nonce_length(self):
        # nonce can be of any length (but not empty)
        self.assertRaises(ValueError, AES.new, self.key_128, AES.MODE_EAX,
                          nonce=b(""))

        for x in range(1, 128):
            cipher = AES.new(self.key_128, AES.MODE_EAX, nonce=bchr(1) * x)
            cipher.encrypt(bchr(1))
 def test_update(self):
     pieces = [bchr(10) * 200, bchr(20) * 300]
     h = self.BLAKE2.new(digest_bytes=self.max_bytes)
     h.update(pieces[0]).update(pieces[1])
     digest = h.digest()
     h = self.BLAKE2.new(digest_bytes=self.max_bytes)
     h.update(pieces[0] + pieces[1])
     self.assertEqual(h.digest(), digest)
Exemplo n.º 8
0
 def _definite_form(length):
         """Build length octets according to BER/DER
         definite form.
         """
         if length > 127:
                 encoding = long_to_bytes(length)
                 return bchr(len(encoding) + 128) + encoding
         return bchr(length)
 def test_update(self):
     pieces = [bchr(10) * 200, bchr(20) * 300]
     h = self.shake.new()
     h.update(pieces[0]).update(pieces[1])
     digest = h.read(10)
     h = self.shake.new()
     h.update(pieces[0] + pieces[1])
     self.assertEqual(h.read(10), digest)
Exemplo n.º 10
0
 def test_nonce_length(self):
     self.assertRaises(ValueError, AES.new, self.key_128, AES.MODE_CCM,
                       nonce=b(""))
     self.assertRaises(ValueError, AES.new, self.key_128, AES.MODE_CCM,
                       nonce=bchr(1) * 6)
     self.assertRaises(ValueError, AES.new, self.key_128, AES.MODE_CCM,
                       nonce=bchr(1) * 14)
     for x in range(7, 13 + 1):
         AES.new(self.key_128, AES.MODE_CCM, nonce=bchr(1) * x)
Exemplo n.º 11
0
    def test_wrap_around(self):
        counter = Counter.new(8, prefix=bchr(9) * 15)

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        cipher.encrypt(bchr(9) * 16 * 255)
        self.assertRaises(OverflowError, cipher.encrypt, bchr(9) * 16)

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        cipher.decrypt(bchr(9) * 16 * 255)
        self.assertRaises(OverflowError, cipher.decrypt, bchr(9) * 16)
Exemplo n.º 12
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 `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)
Exemplo n.º 13
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)
Exemplo n.º 14
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)
Exemplo n.º 15
0
    def verify(self, received_mac_tag):
        """Validate the *binary* MAC tag.

        The caller invokes this function at the very end.

        This method checks if the decrypted message is indeed valid
        (that is, if the key is correct) and it has not been
        tampered with while in transit.

        :Parameters:
          received_mac_tag : byte string
            This is the *binary* MAC, as received from the sender.
        :Raises MacMismatchError:
            if the MAC does not match. The message has been tampered with
            or the key is incorrect.
        """

        if self.verify not in self._next:
            raise TypeError("verify() cannot be called" " when encrypting a message")
        self._next = [self.verify]

        if not self._mac_tag:
            tag = bchr(0) * self.block_size
            for i in xrange(3):
                tag = strxor(tag, self._omac[i].digest())
            self._mac_tag = tag[: self._mac_len]

        secret = get_random_bytes(16)

        mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag)
        mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag)

        if mac1.digest() != mac2.digest():
            raise ValueError("MAC check failed")
Exemplo n.º 16
0
    def encode(self):
        """Return the DER OBJECT ID, fully encoded as a
        binary string."""

        comps = [int(x) for x in self.value.split(".")]
        if len(comps) < 2:
            raise ValueError("Not a valid Object Identifier string")
        self.payload = bchr(40*comps[0]+comps[1])
        for v in comps[2:]:
            enc = []
            while v:
                enc.insert(0, (v & 0x7F) | 0x80)
                v >>= 7
            enc[-1] &= 0x7F
            self.payload += b''.join([bchr(x) for x in enc])
        return DerObject.encode(self)
Exemplo n.º 17
0
    def _export_private_der(self, include_ec_params=True):

        assert self.has_private()

        # ECPrivateKey ::= SEQUENCE {
        #           version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
        #           privateKey     OCTET STRING,
        #           parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
        #           publicKey  [1] BIT STRING OPTIONAL
        #    }

        # Public key - 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))

        seq = [1,
               DerOctetString(self.d.to_bytes(order_bytes)),
               DerObjectId(_curve.oid, explicit=0),
               DerBitString(public_key, explicit=1)]

        if not include_ec_params:
            del seq[2]

        return DerSequence(seq).encode()
Exemplo n.º 18
0
def adjust_key_parity(key_in):
    """Set the parity bits in a TDES key.

    :param key_in: the TDES key whose bits need to be adjusted
    :type key_in: byte string

    :returns: a copy of ``key_in``, with the parity bits correctly set
    :rtype: byte string

    :raises ValueError: if the TDES key is not 16 or 24 bytes long
    :raises ValueError: if the TDES key degenerates into Single DES
    """

    def parity_byte(key_byte):
        parity = 1
        for i in range(1, 8):
            parity ^= (key_byte >> i) & 1
        return (key_byte & 0xFE) | parity

    if len(key_in) not in key_size:
        raise ValueError("Not a valid TDES key")

    key_out = b"".join([ bchr(parity_byte(bord(x))) for x in key_in ])

    if key_out[:8] == key_out[8:16] or key_out[-16:-8] == key_out[-8:]:
        raise ValueError("Triple DES key degenerates to single DES")

    return key_out
Exemplo n.º 19
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)
Exemplo n.º 20
0
    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_and_digest(b'\x01')
Exemplo n.º 21
0
        def encode(self):
                """Return this DER element, fully encoded as a binary byte string."""

                # Concatenate identifier octets, length octets,
                # and contents octets

                output_payload = self.payload

                # In case of an EXTERNAL tag, first encode the inner
                # element.
                if hasattr(self, "_inner_tag_octet"):
                    output_payload = (bchr(self._inner_tag_octet) +
                                      self._definite_form(len(self.payload)) +
                                      self.payload)

                return (bchr(self._tag_octet) +
                        self._definite_form(len(output_payload)) +
                        output_payload)
Exemplo n.º 22
0
    def _export_openssh(self, compress):
        if self.has_private():
            raise ValueError("Cannot export OpenSSH private keys")

        desc = "ecdsa-sha2-nistp256"
        order_bytes = _curve.order.size_in_bytes()
        
        if compress:
            first_byte = 2 + self.pointQ.y.is_odd()
            public_key = (bchr(first_byte) +
                          self.pointQ.x.to_bytes(order_bytes))
        else:
            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))
Exemplo n.º 23
0
    def test_degradation(self):
        sub_key1 = bchr(1) * 8
        sub_key2 = bchr(255) * 8

        # K1 == K2
        self.assertRaises(ValueError, DES3.adjust_key_parity,
                          sub_key1 * 2 + sub_key2)

        # K2 == K3
        self.assertRaises(ValueError, DES3.adjust_key_parity,
                          sub_key1 + sub_key2 * 2)

        # K1 == K2 == K3
        self.assertRaises(ValueError, DES3.adjust_key_parity,
                          sub_key1 * 3)

        # K1 == K2 (with different parity)
        self.assertRaises(ValueError, DES3.adjust_key_parity,
                          sub_key1  + strxor_c(sub_key1, 1) + sub_key2)
    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)
Exemplo n.º 25
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)
Exemplo n.º 26
0
    def _pad_cache_and_update(self):

        assert(self._mac_status != MacStatus.NOT_STARTED)
        assert(byte_string(self._cache))
        assert(len(self._cache) < self.block_size)

        # Associated data is concatenated with the least number
        # of zero bytes (possibly none) to reach alignment to
        # the 16 byte boundary (A.2.3)
        len_cache = len(self._cache)
        if len_cache > 0:
            self._update(bchr(0) * (self.block_size - len_cache))
Exemplo n.º 27
0
    def _pad_cache_and_update(self):
        assert(len(self._cache) < 16)

        # The authenticated data A is concatenated to the minimum
        # number of zero bytes (possibly none) such that the
        # - ciphertext C is aligned to the 16 byte boundary.
        #   See step 5 in section 7.1
        # - ciphertext C is aligned to the 16 byte boundary.
        #   See step 6 in section 7.2
        len_cache = len(self._cache)
        if len_cache > 0:
            self._update(bchr(0) * (16 - len_cache))
Exemplo n.º 28
0
    def _export_subjectPublicKeyInfo(self):

        # 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))

        unrestricted_oid = "1.2.840.10045.2.1"
        return _create_subject_public_key_info(unrestricted_oid,
                                               public_key,
                                               DerObjectId(_curve.oid))
Exemplo n.º 29
0
    def _compute_nonce(self, mhash):
        """Generate k in a deterministic way"""

        # See section 3.2 in RFC6979.txt
        # Step a
        h1 = mhash.digest()
        # Step b
        mask_v = bchr(1) * mhash.digest_size
        # Step c
        nonce_k = bchr(0) * mhash.digest_size

        for int_oct in 0, 1:
            # Step d/f
            nonce_k = HMAC.new(nonce_k,
                               mask_v + bchr(int_oct) +
                               self._int2octets(self._private_key) +
                               self._bits2octets(h1), mhash).digest()
            # Step e/g
            mask_v = HMAC.new(nonce_k, mask_v, mhash).digest()

        nonce = -1
        while not (0 < nonce < self._order):
            # Step h.C (second part)
            if nonce != -1:
                nonce_k = HMAC.new(nonce_k, mask_v + bchr(0),
                                   mhash).digest()
                mask_v = HMAC.new(nonce_k, mask_v, mhash).digest()

            # Step h.A
            mask_t = b("")

            # Step h.B
            while len(mask_t) < self._order_bytes:
                mask_v = HMAC.new(nonce_k, mask_v, mhash).digest()
                mask_t += mask_v

            # Step h.C (first part)
            nonce = self._bits2int(mask_t)
        return nonce
Exemplo n.º 30
0
    def runTest(self):
        key = b'0' * 16
        h = SHA256.new()

        for length in range(160):
            nonce = '{0:04d}'.format(length).encode('utf-8')
            data = bchr(length) * length
            cipher = AES.new(key, AES.MODE_GCM, nonce=nonce, **self._extra_params)
            ct, tag = cipher.encrypt_and_digest(data)
            h.update(ct)
            h.update(tag)

        self.assertEqual(h.hexdigest(), "7b7eb1ffbe67a2e53a912067c0ec8e62ebc7ce4d83490ea7426941349811bdf4")
Exemplo n.º 31
0
    def test_asn1_encoding(self):
        """Verify ASN.1 encoding"""

        self.description = "ASN.1 encoding test"
        hash_obj = SHA256.new()
        signer = DSS.new(self.key_priv, 'fips-186-3', 'der')
        signature = signer.sign(hash_obj)

        # Verify that output looks like a DER SEQUENCE
        self.assertEqual(bord(signature[0]), 48)
        signer.verify(hash_obj, signature)

        # Verify that ASN.1 parsing fails as expected
        signature = bchr(7) + signature[1:]
        self.assertRaises(ValueError, signer.verify, hash_obj, signature)
    def random(cls, **kwargs):
        """Generate a random natural integer of a certain size.

        :Keywords:
          exact_bits : positive integer
            The length in bits of the resulting random Integer number.
            The number is guaranteed to fulfil the relation:

                2^bits > result >= 2^(bits - 1)

          max_bits : positive integer
            The maximum length in bits of the resulting random Integer number.
            The number is guaranteed to fulfil the relation:

                2^bits > result >=0

          randfunc : callable
            A function that returns a random byte string. The length of the
            byte string is passed as parameter. Optional.
            If not provided (or ``None``), randomness is read from the system RNG.

        :Return: a Integer object
        """

        exact_bits = kwargs.pop("exact_bits", None)
        max_bits = kwargs.pop("max_bits", None)
        randfunc = kwargs.pop("randfunc", None)

        if randfunc is None:
            randfunc = Random.new().read

        if exact_bits is None and max_bits is None:
            raise ValueError(
                "Either 'exact_bits' or 'max_bits' must be specified")

        if exact_bits is not None and max_bits is not None:
            raise ValueError(
                "'exact_bits' and 'max_bits' are mutually exclusive")

        bits = exact_bits or max_bits
        bytes_needed = ((bits - 1) // 8) + 1
        significant_bits_msb = 8 - (bytes_needed * 8 - bits)
        msb = bord(randfunc(1)[0])
        if exact_bits is not None:
            msb |= 1 << (significant_bits_msb - 1)
        msb &= (1 << significant_bits_msb) - 1

        return cls.from_bytes(bchr(msb) + randfunc(bytes_needed - 1))
    def __init__(self, subkey):
        assert len(subkey) == 16

        expect_byte_string(subkey)
        self._exp_key = VoidPointer()
        result = _raw_galois_lib.ghash_expand(subkey,
                                              self._exp_key.address_of())
        if result:
            raise ValueError("Error %d while expanding the GMAC key" % result)

        self._exp_key = SmartPointer(self._exp_key.get(),
                                     _raw_galois_lib.ghash_destroy)

        self._last_y = create_string_buffer(16)
        for i in xrange(16):
            self._last_y[i] = bchr(0)
Exemplo n.º 34
0
    def encode(self):
        """Return the DER OBJECT ID, fully encoded as a
        binary string."""

        comps = map(int, self.value.split("."))
        if len(comps) < 2:
            raise ValueError("Not a valid Object Identifier string")
        self.payload = bchr(40 * comps[0] + comps[1])
        for v in comps[2:]:
            enc = []
            while v:
                enc.insert(0, (v & 0x7F) | 0x80)
                v >>= 7
            enc[-1] &= 0x7F
            self.payload += b('').join(map(bchr, enc))
        return DerObject.encode(self)
Exemplo n.º 35
0
def adjust_key_parity(key_in):
    """Return the TDES key with parity bits correctly set"""
    def parity_byte(key_byte):
        parity = 1
        for i in range(1, 8):
            parity ^= (key_byte >> i) & 1
        return (key_byte & 0xFE) | parity

    if len(key_in) not in key_size:
        raise ValueError("Not a valid TDES key")

    key_out = b("").join([bchr(parity_byte(bord(x))) for x in key_in])

    if key_out[:8] == key_out[8:16] or key_out[-16:-8] == key_out[-8:]:
        raise ValueError("Triple DES key degenerates to single DES")

    return key_out
Exemplo n.º 36
0
def _decrypt(key, ciphertext):
    modBits = size(key.n)
    k = ceil_div(modBits, 8)  # Convert from bits to bytes

    # Step 1
    if len(ciphertext) != k:
        raise ValueError("Ciphertext with incorrect length.")
    # Step 2a (O2SIP)
    ct_int = bytes_to_long(bstr(ciphertext))
    # Step 2b (RSADP)
    m_int = pow(Integer(ct_int), key._e, key._n)
    # Complete step 2c (I2OSP)
    em = long_to_bytes(m_int, k)
    # Step 3
    sep = em.find(bchr(0x00), 2)
    # Step 4
    return em[sep + 1:]
Exemplo n.º 37
0
def bcrypt(password, cost, salt=None):
    """Hash a password into a key, using the OpenBSD bcrypt protocol.

    Args:
      password (byte string or string):
        The secret password or pass phrase.
        It must be at most 72 bytes long.
        It must not contain the zero byte.
        Unicode strings will be encoded as UTF-8.
      cost (integer):
        The exponential factor that makes it slower to compute the hash.
        It must be in the range 4 to 31.
        A value of at least 12 is recommended.
      salt (byte string):
        Optional. Random byte string to thwarts dictionary and rainbow table
        attacks. It must be 16 bytes long.
        If not passed, a random value is generated.

    Return (byte string):
        The bcrypt hash

    Raises:
        ValueError: if password is longer than 72 bytes or if it contains the zero byte

   """

    password = tobytes(password, "utf-8")

    if password.find(bchr(0)[0]) != -1:
        raise ValueError("The password contains the zero byte")

    if len(password) < 72:
        password += b"\x00"

    if salt is None:
        salt = get_random_bytes(16)
    if len(salt) != 16:
        raise ValueError("bcrypt salt must be 16 bytes long")

    ctext = _bcrypt_hash(password, cost, salt, b"OrpheanBeholderScryDoubt",
                         True)

    cost_enc = b"$" + bstr(str(cost).zfill(2))
    salt_enc = b"$" + _bcrypt_encode(salt)
    hash_enc = _bcrypt_encode(ctext[:-1])  # only use 23 bytes, not 24
    return b"$2a" + cost_enc + salt_enc + hash_enc
Exemplo n.º 38
0
    def test_wrap_around(self):
        # Counter is only 8 bits, so we can only encrypt/decrypt 256 blocks (=4096 bytes)
        counter = Counter.new(8, prefix=bchr(9) * 15)
        max_bytes = 4096

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        cipher.encrypt(b'9' * max_bytes)
        self.assertRaises(OverflowError, cipher.encrypt, b'9')

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        self.assertRaises(OverflowError, cipher.encrypt, b'9' * (max_bytes + 1))

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        cipher.decrypt(b'9' * max_bytes)
        self.assertRaises(OverflowError, cipher.decrypt, b'9')

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        self.assertRaises(OverflowError, cipher.decrypt, b'9' * (max_bytes + 1))
Exemplo n.º 39
0
    def _export_openssh(self, compress):
        if self.has_private():
            raise ValueError("Cannot export OpenSSH private keys")

        desc = "ecdsa-sha2-nistp256"
        order_bytes = _curve.order.size_in_bytes()

        if compress:
            first_byte = 2 + self.pointQ.y.is_odd()
            public_key = (bchr(first_byte) +
                          self.pointQ.x.to_bytes(order_bytes))
        else:
            public_key = (b'\x04' + 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))
Exemplo n.º 40
0
    def runTest(self):
        key = b'0' * 16
        h = SHA256.new()

        for length in range(160):
            nonce = '{0:04d}'.format(length).encode('utf-8')
            data = bchr(length) * length
            cipher = AES.new(key,
                             AES.MODE_GCM,
                             nonce=nonce,
                             **self._extra_params)
            ct, tag = cipher.encrypt_and_digest(data)
            h.update(ct)
            h.update(tag)

        self.assertEqual(
            h.hexdigest(),
            "7b7eb1ffbe67a2e53a912067c0ec8e62ebc7ce4d83490ea7426941349811bdf4")
Exemplo n.º 41
0
    def _export_openssh(self, compress):
        if self.has_private():
            raise ValueError("Cannot export OpenSSH private keys")

        desc = self._curve.openssh
        modulus_bytes = self.pointQ.size_in_bytes()

        if compress:
            first_byte = 2 + self.pointQ.y.is_odd()
            public_key = (bchr(first_byte) +
                          self.pointQ.x.to_bytes(modulus_bytes))
        else:
            public_key = (b'\x04' + self.pointQ.x.to_bytes(modulus_bytes) +
                          self.pointQ.y.to_bytes(modulus_bytes))

        middle = desc.split("-")[2]
        comps = (tobytes(desc), tobytes(middle), public_key)
        blob = b"".join([struct.pack(">I", len(x)) + x for x in comps])
        return desc + " " + tostr(binascii.b2a_base64(blob))
Exemplo n.º 42
0
    def __init__(self, factory, key, iv, cipher_params):

        #: The block size of the underlying cipher, in bytes.
        self.block_size = factory.block_size

        self._done_first_block = False  # True after the first encryption

        # Instantiate a temporary cipher to process the IV
        IV_cipher = factory.new(
                        key,
                        factory.MODE_CFB,
                        IV=bchr(0) * self.block_size,
                        segment_size=self.block_size * 8,
                        **cipher_params)

        # The cipher will be used for...
        if len(iv) == self.block_size:
            # ... encryption
            self._encrypted_IV = IV_cipher.encrypt(iv + iv[-2:])
        elif len(iv) == self.block_size + 2:
            # ... decryption
            self._encrypted_IV = iv
            # Last two bytes are for a deprecated "quick check" feature that
            # should not be used. (https://eprint.iacr.org/2005/033)
            iv = IV_cipher.decrypt(iv)[:-2]
        else:
            raise ValueError("Length of IV must be %d or %d bytes"
                             " for MODE_OPENPGP"
                             % (self.block_size, self.block_size + 2))

        self.iv = self.IV = bstr(iv)

        # Instantiate the cipher for the real PGP data
        self._cipher = factory.new(
                            key,
                            factory.MODE_CFB,
                            IV=self._encrypted_IV[-self.block_size:],
                            segment_size=self.block_size * 8,
                            **cipher_params)
Exemplo n.º 43
0
    def __init__(self, factory, key, iv, cipher_params):

        #: The block size of the underlying cipher, in bytes.
        self.block_size = factory.block_size

        self._done_first_block = False  # True after the first encryption

        # Instantiate a temporary cipher to process the IV
        IV_cipher = factory.new(key,
                                factory.MODE_CFB,
                                IV=bchr(0) * self.block_size,
                                segment_size=self.block_size * 8,
                                **cipher_params)

        # The cipher will be used for...
        if len(iv) == self.block_size:
            # ... encryption
            self._encrypted_IV = IV_cipher.encrypt(iv + iv[-2:])
        elif len(iv) == self.block_size + 2:
            # ... decryption
            self._encrypted_IV = iv
            iv = IV_cipher.decrypt(iv)
            if iv[-2:] != iv[-4:-2]:
                raise ValueError("Failed integrity check for OPENPGP IV")
            iv = iv[:-2]
        else:
            raise ValueError("Length of IV must be %d or %d bytes"
                             " for MODE_OPENPGP" %
                             (self.block_size, self.block_size + 2))

        self.iv = self.IV = iv

        # Instantiate the cipher for the real PGP data
        self._cipher = factory.new(key,
                                   factory.MODE_CFB,
                                   IV=self._encrypted_IV[-self.block_size:],
                                   segment_size=self.block_size * 8,
                                   **cipher_params)
Exemplo n.º 44
0
    def _export_subjectPublicKeyInfo(self, compress):

        # See 2.2 in RFC5480 and 2.3.3 in SEC1
        # The first byte is:
        # - 0x02:   compressed, only X-coordinate, Y-coordinate is even
        # - 0x03:   compressed, only X-coordinate, Y-coordinate is odd
        # - 0x04:   uncompressed, X-coordinate is followed by Y-coordinate
        #
        # PAI is in theory encoded as 0x00.

        order_bytes = _curve.order.size_in_bytes()

        if compress:
            first_byte = 2 + self.pointQ.y.is_odd()
            public_key = (bchr(first_byte) +
                          self.pointQ.x.to_bytes(order_bytes))
        else:
            public_key = (b'\x04' + self.pointQ.x.to_bytes(order_bytes) +
                          self.pointQ.y.to_bytes(order_bytes))

        unrestricted_oid = "1.2.840.10045.2.1"
        return _create_subject_public_key_info(unrestricted_oid, public_key,
                                               DerObjectId(_curve.oid))
Exemplo n.º 45
0
    def digest(self):
        """Compute the *binary* MAC tag.

        The caller invokes this function at the very end.

        This method returns the MAC that shall be sent to the receiver,
        together with the ciphertext.

        :Return: the MAC, as a byte string.
        """

        if self.digest not in self._next:
            raise TypeError("digest() cannot be called when decrypting"
                            " or validating a message")
        self._next = [self.digest]

        if not self._mac_tag:
            tag = bchr(0) * self.block_size
            for i in xrange(3):
                tag = strxor(tag, self._omac[i].digest())
            self._mac_tag = tag[:self._mac_len]

        return self._mac_tag
Exemplo n.º 46
0
    def to_bytes(self, block_size=0):
        """Convert the number into a byte string.

        This method encodes the number in network order and prepends
        as many zero bytes as required. It only works for non-negative
        values.

        :Parameters:
          block_size : integer
            The exact size the output byte string must have.
            If zero, the string has the minimal length.
        :Returns:
          A byte string.
        :Raise ValueError:
          If the value is negative or if ``block_size`` is
          provided and the length of the byte string would exceed it.
        """

        if self < 0:
            raise ValueError("Conversion only valid for non-negative numbers")

        buf_len = (_gmp.mpz_sizeinbase(self._mpz_p, 2) + 7) // 8
        if buf_len > block_size > 0:
            raise ValueError("Number is too big to convert to byte string"
                             "of prescribed length")
        buf = create_string_buffer(buf_len)

        _gmp.mpz_export(
            buf,
            null_pointer,  # Ignore countp
            1,  # Big endian
            c_size_t(1),  # Each word is 1 byte long
            0,  # Endianess within a word - not relevant
            c_size_t(0),  # No nails
            self._mpz_p)

        return bchr(0) * max(0, block_size - buf_len) + get_raw_buffer(buf)
Exemplo n.º 47
0
 def newMGF(seed,maskLen):
     global mgfcalls
     mgfcalls += 1
     return bchr(0x00)*maskLen
Exemplo n.º 48
0
    def __init__(self, factory, key, nonce, mac_len, cipher_params):

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

        if len(nonce) == 0:
            raise ValueError("Nonce cannot be empty")
        if not byte_string(nonce):
            raise TypeError("Nonce must be a byte string")

        self.nonce = nonce
        """Nonce"""

        self._factory = factory
        self._key = key
        self._tag = None  # Cache for MAC tag

        self._mac_len = mac_len
        if not (4 <= mac_len <= 16):
            raise ValueError("Parameter 'mac_len' must be in the range 4..16")

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

        self._no_more_assoc_data = False

        # Length of associated data
        self._auth_len = 0

        # Length of the ciphertext or plaintext
        self._msg_len = 0

        # Step 1 in SP800-38D, Algorithm 4 (encryption) - Compute H
        # See also Algorithm 5 (decryption)
        hash_subkey = factory.new(key,
                                  self._factory.MODE_ECB,
                                  **cipher_params
                                  ).encrypt(bchr(0) * 16)

        # Step 2 - Compute J0 (integer, not byte string!)
        if len(nonce) == 12:
            self._j0 = bytes_to_long(nonce + b("\x00\x00\x00\x01"))
        else:
            fill = (16 - (len(nonce) % 16)) % 16 + 8
            ghash_in = (nonce +
                        bchr(0) * fill +
                        long_to_bytes(8 * len(nonce), 8))
            self._j0 = bytes_to_long(_GHASH(hash_subkey)
                                     .update(ghash_in)
                                     .digest())

        # Step 3 - Prepare GCTR cipher for encryption/decryption
        self._cipher = factory.new(key,
                                   self._factory.MODE_CTR,
                                   initial_value=self._j0 + 1,
                                   nonce=b(""),
                                   **cipher_params)

        # Step 5 - Bootstrat GHASH
        self._signer = _GHASH(hash_subkey)

        # Step 6 - Prepare GCTR cipher for GMAC
        self._tag_cipher = factory.new(key,
                                       self._factory.MODE_CTR,
                                       initial_value=self._j0,
                                       nonce=b(""),
                                       **cipher_params)

        # Cache for data to authenticate
        self._cache = b("")

        self._status = MacStatus.PROCESSING_AUTH_DATA
    def __init__(self, factory, key, nonce, mac_len, msg_len, assoc_len,
                 cipher_params):

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

        self.nonce = nonce
        """The nonce used for this cipher instance"""

        self._factory = factory
        self._key = key
        self._mac_len = mac_len
        self._msg_len = msg_len
        self._assoc_len = assoc_len
        self._cipher_params = cipher_params

        self._mac_tag = None  # Cache for MAC tag

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

        # MAC tag length (Tlen)
        if mac_len not in (4, 6, 8, 10, 12, 14, 16):
            raise ValueError("Parameter 'mac_len' must be even"
                             " and in the range 4..16 (not %d)" % mac_len)

        # Nonce value
        if not (nonce and 7 <= len(nonce) <= 13):
            raise ValueError("Length of parameter 'nonce' must be"
                             " in the range 7..13 bytes")

        # Create MAC object (the tag will be the last block
        # bytes worth of ciphertext)
        self._mac = self._factory.new(key,
                                      factory.MODE_CBC,
                                      iv=bchr(0) * 16,
                                      **cipher_params)
        self._mac_status = MacStatus.NOT_STARTED
        self._t = None

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

        # Cumulative lengths
        self._cumul_assoc_len = 0
        self._cumul_msg_len = 0

        # Cache for unaligned associated data/plaintext.
        # This is a list, but when the MAC starts, it will become a binary
        # string no longer than the block size.
        self._cache = []

        # Start CTR cipher, by formatting the counter (A.3)
        q = 15 - len(nonce)  # length of Q, the encoded message length
        self._cipher = self._factory.new(key,
                                         self._factory.MODE_CTR,
                                         nonce=bchr(q - 1) + nonce,
                                         **cipher_params)

        # S_0, step 6 in 6.1 for j=0
        self._s_0 = self._cipher.encrypt(bchr(0) * 16)

        # Try to start the MAC
        if None not in (assoc_len, msg_len):
            self._start_mac()
def _EMSA_PSS_ENCODE(mhash, emBits, randFunc, mgf, sLen):
    """
    Implement the ``EMSA-PSS-ENCODE`` function, as defined
    in PKCS#1 v2.1 (RFC3447, 9.1.1).

    The original ``EMSA-PSS-ENCODE`` actually accepts the message ``M``
    as input, and hash it internally. Here, we expect that the message
    has already been hashed instead.

    :Parameters:
      mhash : hash object
        The hash object that holds the digest of the message being signed.
      emBits : int
        Maximum length of the final encoding, in bits.
      randFunc : callable
        An RNG function that accepts as only parameter an int, and returns
        a string of random bytes, to be used as salt.
      mgf : callable
        A mask generation function that accepts two parameters: a string to
        use as seed, and the lenth of the mask to generate, in bytes.
      sLen : int
        Length of the salt, in bytes.

    :Return: An ``emLen`` byte long string that encodes the hash
      (with ``emLen = \ceil(emBits/8)``).

    :Raise ValueError:
        When digest or salt length are too big.
    """

    emLen = ceil_div(emBits, 8)

    # Bitmask of digits that fill up
    lmask = 0
    for i in iter_range(8 * emLen - emBits):
        lmask = lmask >> 1 | 0x80

    # Step 1 and 2 have been already done
    # Step 3
    if emLen < mhash.digest_size + sLen + 2:
        raise ValueError("Digest or salt length are too long"
                         " for given key size.")
    # Step 4
    salt = randFunc(sLen)
    # Step 5
    m_prime = bchr(0) * 8 + mhash.digest() + salt
    # Step 6
    h = mhash.new()
    h.update(m_prime)
    # Step 7
    ps = bchr(0) * (emLen - sLen - mhash.digest_size - 2)
    # Step 8
    db = ps + bchr(1) + salt
    # Step 9
    dbMask = mgf(h.digest(), emLen - mhash.digest_size - 1)
    # Step 10
    maskedDB = strxor(db, dbMask)
    # Step 11
    maskedDB = bchr(bord(maskedDB[0]) & ~lmask) + maskedDB[1:]
    # Step 12
    em = maskedDB + h.digest() + bchr(0xBC)
    return em
 def test_invalid_nonce_length(self):
     key = bchr(1) * 16
     self.assertRaises(ValueError, Salsa20.new, key, bchr(0) * 7)
     self.assertRaises(ValueError, Salsa20.new, key, bchr(0) * 9)
def _EMSA_PSS_VERIFY(mhash, em, emBits, mgf, sLen):
    """
    Implement the ``EMSA-PSS-VERIFY`` function, as defined
    in PKCS#1 v2.1 (RFC3447, 9.1.2).

    ``EMSA-PSS-VERIFY`` actually accepts the message ``M`` as input,
    and hash it internally. Here, we expect that the message has already
    been hashed instead.

    :Parameters:
      mhash : hash object
        The hash object that holds the digest of the message to be verified.
      em : string
        The signature to verify, therefore proving that the sender really
        signed the message that was received.
      emBits : int
        Length of the final encoding (em), in bits.
      mgf : callable
        A mask generation function that accepts two parameters: a string to
        use as seed, and the lenth of the mask to generate, in bytes.
      sLen : int
        Length of the salt, in bytes.

    :Raise ValueError:
        When the encoding is inconsistent, or the digest or salt lengths
        are too big.
    """

    emLen = ceil_div(emBits, 8)

    # Bitmask of digits that fill up
    lmask = 0
    for i in iter_range(8 * emLen - emBits):
        lmask = lmask >> 1 | 0x80

    # Step 1 and 2 have been already done
    # Step 3
    if emLen < mhash.digest_size + sLen + 2:
        raise ValueError("Incorrect signature")
    # Step 4
    if ord(em[-1:]) != 0xBC:
        raise ValueError("Incorrect signature")
    # Step 5
    maskedDB = em[:emLen - mhash.digest_size - 1]
    h = em[emLen - mhash.digest_size - 1:-1]
    # Step 6
    if lmask & bord(em[0]):
        raise ValueError("Incorrect signature")
    # Step 7
    dbMask = mgf(h, emLen - mhash.digest_size - 1)
    # Step 8
    db = strxor(maskedDB, dbMask)
    # Step 9
    db = bchr(bord(db[0]) & ~lmask) + db[1:]
    # Step 10
    if not db.startswith(
            bchr(0) * (emLen - mhash.digest_size - sLen - 2) + bchr(1)):
        raise ValueError("Incorrect signature")
    # Step 11
    if sLen > 0:
        salt = db[-sLen:]
    else:
        salt = b""
    # Step 12
    m_prime = bchr(0) * 8 + mhash.digest() + salt
    # Step 13
    hobj = mhash.new()
    hobj.update(m_prime)
    hp = hobj.digest()
    # Step 14
    if h != hp:
        raise ValueError("Incorrect signature")
Exemplo n.º 53
0
def import_openssh_private_generic(data, password):
    # https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.key?annotate=HEAD
    # https://github.com/openssh/openssh-portable/blob/master/sshkey.c
    # https://coolaj86.com/articles/the-openssh-private-key-format/
    # https://coolaj86.com/articles/the-ssh-public-key-format/

    if not data.startswith(b'openssh-key-v1\x00'):
        raise ValueError("Incorrect magic value")
    data = data[15:]

    ciphername, data = read_string(data)
    kdfname, data = read_string(data)
    kdfoptions, data = read_bytes(data)
    number_of_keys, data = read_int4(data)

    if number_of_keys != 1:
        raise ValueError("We only handle 1 key at a time")

    _, data = read_string(data)  # Public key
    encrypted, data = read_bytes(data)
    if data:
        raise ValueError("Too much data")

    if len(encrypted) % 8 != 0:
        raise ValueError("Incorrect payload length")

    # Decrypt if necessary
    if ciphername == 'none':
        decrypted = encrypted
    else:
        if (ciphername, kdfname) != ('aes256-ctr', 'bcrypt'):
            raise ValueError("Unsupported encryption scheme %s/%s" %
                             (ciphername, kdfname))

        salt, kdfoptions = read_bytes(kdfoptions)
        iterations, kdfoptions = read_int4(kdfoptions)

        if len(salt) != 16:
            raise ValueError("Incorrect salt length")
        if kdfoptions:
            raise ValueError("Too much data in kdfoptions")

        pwd_sha512 = SHA512.new(password).digest()
        # We need 32+16 = 48 bytes, therefore 2 bcrypt outputs are sufficient
        stripes = []
        constant = b"OxychromaticBlowfishSwatDynamite"
        for count in range(1, 3):
            salt_sha512 = SHA512.new(salt + struct.pack(">I", count)).digest()
            out_le = _bcrypt_hash(pwd_sha512, 6, salt_sha512, constant, False)
            out = struct.pack("<IIIIIIII", *struct.unpack(">IIIIIIII", out_le))
            acc = bytearray(out)
            for _ in range(1, iterations):
                out_le = _bcrypt_hash(pwd_sha512, 6,
                                      SHA512.new(out).digest(), constant,
                                      False)
                out = struct.pack("<IIIIIIII",
                                  *struct.unpack(">IIIIIIII", out_le))
                strxor(acc, out, output=acc)
            stripes.append(acc[:24])

        result = b"".join([bchr(a) + bchr(b) for (a, b) in zip(*stripes)])

        cipher = AES.new(result[:32],
                         AES.MODE_CTR,
                         nonce=b"",
                         initial_value=result[32:32 + 16])
        decrypted = cipher.decrypt(encrypted)

    checkint1, decrypted = read_int4(decrypted)
    checkint2, decrypted = read_int4(decrypted)
    if checkint1 != checkint2:
        raise ValueError("Incorrect checksum")
    ssh_name, decrypted = read_string(decrypted)

    return ssh_name, decrypted
Exemplo n.º 54
0
    def export_key(self,
                   format='PEM',
                   passphrase=None,
                   pkcs=1,
                   protection=None,
                   randfunc=None):
        """Export this RSA key.

        Args:
          format (string):
            The format to use for wrapping the key:

            - *'PEM'*. (*Default*) Text encoding, done according to `RFC1421`_/`RFC1423`_.
            - *'DER'*. Binary encoding.
            - *'OpenSSH'*. Textual encoding, done according to OpenSSH specification.
              Only suitable for public keys (not private keys).

          passphrase (string):
            (*For private keys only*) The pass phrase used for protecting the output.

          pkcs (integer):
            (*For private keys only*) The ASN.1 structure to use for
            serializing the key. Note that even in case of PEM
            encoding, there is an inner ASN.1 DER structure.

            With ``pkcs=1`` (*default*), the private key is encoded in a
            simple `PKCS#1`_ structure (``RSAPrivateKey``).

            With ``pkcs=8``, the private key is encoded in a `PKCS#8`_ structure
            (``PrivateKeyInfo``).

            .. note::
                This parameter is ignored for a public key.
                For DER and PEM, an ASN.1 DER ``SubjectPublicKeyInfo``
                structure is always used.

          protection (string):
            (*For private keys only*)
            The encryption scheme to use for protecting the private key.

            If ``None`` (default), the behavior depends on :attr:`format`:

            - For *'DER'*, the *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*
              scheme is used. The following operations are performed:

                1. A 16 byte Triple DES key is derived from the passphrase
                   using :func:`Cryptodome.Protocol.KDF.PBKDF2` with 8 bytes salt,
                   and 1 000 iterations of :mod:`Cryptodome.Hash.HMAC`.
                2. The private key is encrypted using CBC.
                3. The encrypted key is encoded according to PKCS#8.

            - For *'PEM'*, the obsolete PEM encryption scheme is used.
              It is based on MD5 for key derivation, and Triple DES for encryption.

            Specifying a value for :attr:`protection` is only meaningful for PKCS#8
            (that is, ``pkcs=8``) and only if a pass phrase is present too.

            The supported schemes for PKCS#8 are listed in the
            :mod:`Cryptodome.IO.PKCS8` module (see :attr:`wrap_algo` parameter).

          randfunc (callable):
            A function that provides random bytes. Only used for PEM encoding.
            The default is :func:`Cryptodome.Random.get_random_bytes`.

        Returns:
          byte string: the encoded key

        Raises:
          ValueError:when the format is unknown or when you try to encrypt a private
            key with *DER* format and PKCS#1.

        .. warning::
            If you don't provide a pass phrase, the private key will be
            exported in the clear!

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

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

        if randfunc is None:
            randfunc = Random.get_random_bytes

        if format == 'OpenSSH':
            e_bytes, n_bytes = [x.to_bytes() for x in (self._e, self._n)]
            if bord(e_bytes[0]) & 0x80:
                e_bytes = bchr(0) + e_bytes
            if bord(n_bytes[0]) & 0x80:
                n_bytes = bchr(0) + n_bytes
            keyparts = [b('ssh-rsa'), e_bytes, n_bytes]
            keystring = b('').join(
                [struct.pack(">I", len(kp)) + kp for kp in keyparts])
            return b('ssh-rsa ') + binascii.b2a_base64(keystring)[:-1]

        # DER format is always used, even in case of PEM, which simply
        # encodes it into BASE64.
        if self.has_private():
            binary_key = DerSequence([
                0, self.n, self.e, self.d, self.p, self.q,
                self.d % (self.p - 1), self.d % (self.q - 1),
                Integer(self.q).inverse(self.p)
            ]).encode()
            if pkcs == 1:
                key_type = 'RSA PRIVATE KEY'
                if format == 'DER' and passphrase:
                    raise ValueError("PKCS#1 private key cannot be encrypted")
            else:  # PKCS#8
                if format == 'PEM' and protection is None:
                    key_type = 'PRIVATE KEY'
                    binary_key = PKCS8.wrap(binary_key, oid, None)
                else:
                    key_type = 'ENCRYPTED PRIVATE KEY'
                    if not protection:
                        protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
                    binary_key = PKCS8.wrap(binary_key, oid, passphrase,
                                            protection)
                    passphrase = None
        else:
            key_type = "PUBLIC KEY"
            binary_key = _create_subject_public_key_info(
                oid, DerSequence([self.n, self.e]))

        if format == 'DER':
            return binary_key
        if format == 'PEM':
            pem_str = PEM.encode(binary_key, key_type, passphrase, randfunc)
            return tobytes(pem_str)

        raise ValueError(
            "Unknown key format '%s'. Cannot export the RSA key." % format)
    def runTest(self):

        nonce = bchr(0) * 8
        for key_length in (15, 30, 33):
            key = bchr(1) * key_length
            self.assertRaises(ValueError, Salsa20.new, key, nonce)
Exemplo n.º 56
0
 def test_default_nonce(self):
     cipher1 = ChaCha20.new(key=bchr(1) * 32)
     cipher2 = ChaCha20.new(key=bchr(1) * 32)
     self.assertEquals(len(cipher1.nonce), 8)
     self.assertNotEqual(cipher1.nonce, cipher2.nonce)
Exemplo n.º 57
0
 def func(x):
     if (bord(x[0]) & 0x80):
         return bchr(0) + x
     else:
         return x
    def __init__(self, key, msg=None, ciphermod=None, cipher_params=None):
        """Create a new CMAC object.

        :Parameters:
          key : byte string
            secret key for the CMAC object.
            The key must be valid for the underlying cipher algorithm.
            For instance, it must be 16 bytes long for AES-128.
          msg : byte string
            The very first chunk of the message to authenticate.
            It is equivalent to an early call to `update`. Optional.
          ciphermod : module
            A cipher module from `Cryptodome.Cipher`.
            The cipher's block size has to be 128 bits.
            It is recommended to use `Cryptodome.Cipher.AES`.
          cipher_params : dictionary
            Extra keywords to use when creating a new cipher.
        """

        if ciphermod is None:
            raise TypeError("ciphermod must be specified (try AES)")

        self._key = key
        self._factory = ciphermod
        if cipher_params is None:
            self._cipher_params = {}
        else:
            self._cipher_params = dict(cipher_params)

        # Section 5.3 of NIST SP 800 38B and Appendix B
        if ciphermod.block_size == 8:
            const_Rb = 0x1B
            self._max_size = 8 * (2**21)
        elif ciphermod.block_size == 16:
            const_Rb = 0x87
            self._max_size = 16 * (2**48)
        else:
            raise TypeError("CMAC requires a cipher with a block size"
                            "of 8 or 16 bytes, not %d" %
                            (ciphermod.block_size, ))

        # Size of the final MAC tag, in bytes
        self.digest_size = ciphermod.block_size
        self._mac_tag = None

        # Compute sub-keys
        zero_block = bchr(0) * ciphermod.block_size
        cipher = ciphermod.new(key, ciphermod.MODE_ECB, **self._cipher_params)
        l = cipher.encrypt(zero_block)
        if bord(l[0]) & 0x80:
            self._k1 = _shift_bytes(l, const_Rb)
        else:
            self._k1 = _shift_bytes(l)
        if bord(self._k1[0]) & 0x80:
            self._k2 = _shift_bytes(self._k1, const_Rb)
        else:
            self._k2 = _shift_bytes(self._k1)

        # Initialize CBC cipher with zero IV
        self._cbc = ciphermod.new(key, ciphermod.MODE_CBC, zero_block,
                                  **self._cipher_params)

        # Cache for outstanding data to authenticate
        self._cache = b("")

        # Last two pieces of ciphertext produced
        self._last_ct = self._last_pt = zero_block
        self._before_last_ct = None

        # Counter for total message size
        self._data_size = 0

        if msg:
            self.update(msg)
Exemplo n.º 59
0
 def testDecrypt2(self):
         # Simplest possible negative tests
         for ct_size in (127,128,129):
             cipher = PKCS.new(self.key1024)
             self.assertRaises(ValueError, cipher.decrypt, bchr(0x00)*ct_size)
    def test_default_nonce(self):

        cipher1 = Salsa20.new(bchr(1) * 16)
        cipher2 = Salsa20.new(bchr(1) * 16)
        self.assertEqual(len(cipher1.nonce), 8)
        self.assertNotEqual(cipher1.nonce, cipher2.nonce)