Example #1
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)
Example #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
Example #3
0
File: CMAC.py Project: cloudera/hue
    def digest(self):
        """Return the **binary** (non-printable) MAC tag of the message
        that has been authenticated so far.

        :return: The MAC tag, computed over the data processed so far.
                 Binary form.
        :rtype: byte string
        """

        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
    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))
Example #5
0
    def __init__(self, factory, nonce, mac_len, cipher_params):

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

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

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

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

        # Cache for MAC tag
        self._mac_tag = None

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

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

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

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

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

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

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

        # Memory allocated for the underlying block cipher is now owed
        # by the cipher mode
        raw_cipher.release()
Example #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_GCM,
                          nonce=b(""))

        for x in range(1, 128):
            cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=bchr(1) * x)
            cipher.encrypt(bchr(1))
Example #7
0
 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)
Example #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)
Example #9
0
 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)
Example #10
0
 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)
Example #11
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)
Example #12
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)
Example #13
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)
def exportSSHKey(self):
    eb = long_to_bytes(self.e)
    nb = long_to_bytes(self.n)
    if bord(eb[0]) & 0x80:
        eb = bchr(0x00) + eb
    if bord(nb[0]) & 0x80:
        nb = bchr(0x00) + nb
    keyparts = ['ssh-rsa', eb, nb]
    keystring = ''.join([struct.pack(">I", len(kp)) + kp for kp in keyparts])
    return 'ssh-rsa ' + binascii.b2a_base64(keystring)[:-1]
Example #15
0
    def __init__(self, key, msg=b(""), digestmod=None):
        """Create a new HMAC object.

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

        if digestmod is None:
            digestmod = MD5

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

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

        self._digestmod = digestmod

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

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

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

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

        # Start step 8 and 9
        self._outer = digestmod.new(key_0_opad)
Example #16
0
    def test_mac_length(self):
        pt = bchr(9) * 100

        self.assertRaises(ValueError, AES.new, self.key, AES.MODE_OCB, nonce=bchr(0)*15, mac_len=7)
        self.assertRaises(ValueError, AES.new, self.key, AES.MODE_OCB, nonce=bchr(0)*15, mac_len=17)

        ct, mac = self._create_cipher().encrypt_and_digest(pt)
        self.assertEquals(len(mac), 16)

        for mac_len in xrange(8, 16+1):
            ct, mac = self._create_cipher(mac_len=mac_len).encrypt_and_digest(pt)
            self.assertEquals(len(mac), mac_len)
Example #17
0
    def test_round_trip(self):
        aad = bchr(8) * 100
        pt = bchr(9) * 100

        cipher = self._create_cipher()
        cipher.update(aad)
        ct, mac = cipher.encrypt_and_digest(pt)

        cipher = self._create_cipher()
        cipher.update(aad)
        pt2 = cipher.decrypt_and_verify(ct, mac)
        self.assertEquals(pt, pt2)
Example #18
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)
Example #19
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
Example #20
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)
Example #21
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 range(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")
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 xrange(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
Example #23
0
    def _start_mac(self):

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

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

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

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

        # Process all the data cached so far
        first_data_to_mac = b("").join(self._cache)
        self._cache = b("")
        self._mac_status = MacStatus.PROCESSING_AUTH_DATA
        self._update(first_data_to_mac)
Example #24
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()
Example #25
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)
Example #26
0
def test_aes_encrypt(data=DATA, nonce=NONCE):
    """
    AES Encrypt (256 Bit, CBC Mode, PKCS #7 Padding)
    """
    size = AES.block_size - (len(data) % AES.block_size)
    data = tobytes(data) + (bchr(size) * size)
    data = AES.new(nonce[:32], AES.MODE_CBC, nonce[32:]).encrypt(data)
    return base64.b64encode(data), len(data)
Example #27
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')
Example #28
0
    def __init__(self, factory, key, nonce, mac_len, cipher_params):
        """EAX cipher mode"""

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

        self.nonce = nonce
        """The nonce originally used to create the object."""

        self._mac_len = mac_len
        self._mac_tag = None  # Cache for MAC tag

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

        # MAC tag length
        if not (4 <= self._mac_len <= self.block_size):
            raise ValueError("Parameter 'mac_len' must not be larger than %d"
                             % self.block_size)

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

        self._omac = [
                CMAC.new(key,
                         bchr(0) * (self.block_size - 1) + bchr(i),
                         ciphermod=factory,
                         cipher_params=cipher_params)
                for i in range(0, 3)
                ]

        # Compute MAC of nonce
        self._omac[0].update(nonce)
        self._signer = self._omac[1]

        # MAC of the nonce is also the initial counter for CTR encryption
        counter_int = bytes_to_long(self._omac[0].digest())
        self._cipher = factory.new(key,
                                   factory.MODE_CTR,
                                   initial_value=counter_int,
                                   nonce=b(""),
                                   **cipher_params)
Example #29
0
    def test_init(self):
        # Verify that nonce can be passed in the old way (3rd parameter)
        # or in the new way ('nonce' parameter)
        ct, mac = self._create_cipher().encrypt_and_digest(b("XXX"))

        cipher = AES.new(self.key, AES.MODE_OCB, bchr(0)*15)
        ct2, mac2 = cipher.encrypt_and_digest(b("XXX"))
        self.assertEquals(ct, ct2)
        self.assertEquals(mac, mac2)
Example #30
0
        def encrypt(self, data):
            nonce = Random.get_random_bytes(Pssst._Key.NONCE_SIZE)
            size = AES.block_size - (len(data) % AES.block_size)
            data = tobytes(data) + (bchr(size) * size)

            data = AES.new(nonce[:32], AES.MODE_CBC, nonce[32:]).encrypt(data)
            nonce = PKCS1_OAEP.new(self.key).encrypt(nonce)

            return (data, nonce)
Example #31
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
    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")
Example #33
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))
Example #34
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 xrange(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
Example #35
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(),
            '1057d9559f55227fd4e36bab8716ebcfe6671b5603fdceb046a33591175ee5e4')
Example #36
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))
Example #37
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))
Example #38
0
    def down_transform(self, byte_sequence: bytes, last: bool = False):
        if self._finished_last:
            return bytes([])

        first = self._first
        if first:
            initialization_vector = byte_sequence[:AES.block_size]
            self._aes = AES.new(self._key, AES.MODE_CBC, initialization_vector)
            self._first = False
        decrypted_data = self._aes.decrypt(
            byte_sequence[AES.block_size:]) if first else self._aes.decrypt(
                byte_sequence)
        # Cut padding
        if last:
            padding = bord(decrypted_data[-1])
            if decrypted_data[-padding:] != bchr(padding) * padding:
                raise ValueError('PKCS#7 padding is incorrect')
            self._finished_last = True
            return decrypted_data[:-padding]
        return decrypted_data
Example #39
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)
Example #40
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.

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

        unrestricted_oid = "1.2.840.10045.2.1"
        return _create_subject_public_key_info(unrestricted_oid, public_key,
                                               DerObjectId(self._curve.oid))
Example #41
0
    def test_byte_by_byte_confidentiality(self):
        pt = bchr(3) * 101
        ct, mac = self._create_cipher().encrypt_and_digest(pt)

        # Encryption
        cipher = self._create_cipher()
        ct2 = b("")
        for x in range(len(pt)):
            ct2 += cipher.encrypt(pt[x:x + 1])
        ct2 += cipher.encrypt()
        mac2 = cipher.digest()

        self.assertEqual(ct, ct2)
        self.assertEqual(mac, mac2)

        # Decryption
        cipher = self._create_cipher()
        pt2 = b("")
        for x in range(len(ct)):
            pt2 += cipher.decrypt(ct[x:x + 1])
        pt2 += cipher.decrypt()
        self.assertEqual(pt, pt2)
        cipher.verify(mac)
Example #42
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
Example #43
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)
    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)
 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 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)
Example #47
0
def pkcs7pad(msg, blocklen):
    paddinglen = blocklen - len(msg) % blocklen
    padding = bchr(paddinglen) * paddinglen
    return msg + padding
Example #48
0
 def newMGF(seed,maskLen):
     global mgfcalls
     mgfcalls += 1
     return bchr(0x00)*maskLen
Example #49
0
 def runTest(self):
     self.assertRaises(ValueError, Blowfish.new,
                       bchr(0) * 4, Blowfish.MODE_ECB)
     self.assertRaises(ValueError, Blowfish.new,
                       bchr(0) * 57, Blowfish.MODE_ECB)
Example #50
0
 def pad(data_to_pad, block_size):
     padding_len = block_size - len(data_to_pad) % block_size
     padding = bchr(padding_len) * padding_len
     return data_to_pad + padding
 def test_default_nonce(self):
     cipher1 = ChaCha20.new(key=bchr(1) * 32)
     cipher2 = ChaCha20.new(key=bchr(1) * 32)
     self.assertEqual(len(cipher1.nonce), 8)
     self.assertNotEqual(cipher1.nonce, cipher2.nonce)
Example #52
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)
Example #54
0
def _create_ctr_cipher(factory, **kwargs):
    """Instantiate a cipher object that performs CTR encryption/decryption.

    :Parameters:
      factory : module
        The underlying block cipher, a module from ``Crypto.Cipher``.

    :Keywords:
      nonce : binary string/array
        The fixed part at the beginning of the counter block - the rest is
        the counter number that gets increased when processing the next block.
        The nonce must be such that no two messages are encrypted under the
        same key and the same nonce.

        The nonce must be shorter than the block size (it can have
        zero length; the counter is then as long as the block).

        If this parameter is not present, a random nonce will be created with
        length equal to half the block size. No random nonce shorter than
        64 bits will be created though - you must really think through all
        security consequences of using such a short block size.

      initial_value : posive integer or byte string/array
        The initial value for the counter. If not present, the cipher will
        start counting from 0. The value is incremented by one for each block.
        The counter number is encoded in big endian mode.

      counter : object
        Instance of ``Crypto.Util.Counter``, which allows full customization
        of the counter block. This parameter is incompatible to both ``nonce``
        and ``initial_value``.

    Any other keyword will be passed to the underlying block cipher.
    See the relevant documentation for details (at least ``key`` will need
    to be present).
    """

    cipher_state = factory._create_base_cipher(kwargs)

    counter = kwargs.pop("counter", None)
    nonce = kwargs.pop("nonce", None)
    initial_value = kwargs.pop("initial_value", None)
    if kwargs:
        raise TypeError("Invalid parameters for CTR mode: %s" % str(kwargs))

    if counter is not None and (nonce, initial_value) != (None, None):
        raise TypeError("'counter' and 'nonce'/'initial_value'"
                        " are mutually exclusive")

    if counter is None:
        # Crypto.Util.Counter is not used
        if nonce is None:
            if factory.block_size < 16:
                raise TypeError("Impossible to create a safe nonce for short"
                                " block sizes")
            nonce = get_random_bytes(factory.block_size // 2)
        else:
            if len(nonce) >= factory.block_size:
                raise ValueError("Nonce is too long")

        # What is not nonce is counter
        counter_len = factory.block_size - len(nonce)

        if initial_value is None:
            initial_value = 0

        if isinstance(initial_value, (int, long)):
            if (1 << (counter_len * 8)) - 1 < initial_value:
                raise ValueError("Initial counter value is too large")
            initial_counter_block = nonce + long_to_bytes(
                initial_value, counter_len)
        else:
            if len(initial_value) != counter_len:
                raise ValueError(
                    "Incorrect length for counter byte string (%d bytes, expected %d)"
                    % (len(initial_value), counter_len))
            initial_counter_block = nonce + initial_value

        return CtrMode(
            cipher_state,
            initial_counter_block,
            len(nonce),  # prefix
            counter_len,
            False)  # little_endian

    # Crypto.Util.Counter is used

    # 'counter' used to be a callable object, but now it is
    # just a dictionary for backward compatibility.
    _counter = dict(counter)
    try:
        counter_len = _counter.pop("counter_len")
        prefix = _counter.pop("prefix")
        suffix = _counter.pop("suffix")
        initial_value = _counter.pop("initial_value")
        little_endian = _counter.pop("little_endian")
    except KeyError:
        raise TypeError("Incorrect counter object"
                        " (use Crypto.Util.Counter.new)")

    # Compute initial counter block
    words = []
    while initial_value > 0:
        words.append(bchr(initial_value & 255))
        initial_value >>= 8
    words += [bchr(0)] * max(0, counter_len - len(words))
    if not little_endian:
        words.reverse()
    initial_counter_block = prefix + b("").join(words) + suffix

    if len(initial_counter_block) != factory.block_size:
        raise ValueError("Size of the counter block (%d bytes) must match"
                         " block size (%d)" %
                         (len(initial_counter_block), factory.block_size))

    return CtrMode(cipher_state, initial_counter_block, len(prefix),
                   counter_len, little_endian)
Example #55
0
    def exportKey(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:`Crypto.Protocol.KDF.PBKDF2` with 8 bytes salt,
                   and 1 000 iterations of :mod:`Crypto.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:`Crypto.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:`Crypto.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)
Example #56
0
    def __init__(self, key, msg=None, ciphermod=None, cipher_params=None):

        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)
Example #57
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 runTest(self):
     self.assertRaises(ValueError, CAST.new, bchr(0) * 4, CAST.MODE_ECB)
     self.assertRaises(ValueError, CAST.new, bchr(0) * 17, CAST.MODE_ECB)
Example #59
0
    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 = bstr(nonce)
        """The nonce used for this cipher instance"""

        self._factory = factory
        self._key = bstr(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 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