def __init__(self, x, y, curve="p256"):

        try:
            self._curve = _curves[curve]
        except KeyError:
            raise ValueError("Unknown curve name %s" % str(curve))
        self._curve_name = curve

        modulus_bytes = self.size_in_bytes()
        context = self._curve.context

        xb = long_to_bytes(x, modulus_bytes)
        yb = long_to_bytes(y, modulus_bytes)
        if len(xb) != modulus_bytes or len(yb) != modulus_bytes:
            raise ValueError("Incorrect coordinate length")

        self._point = VoidPointer()
        result = _ec_lib.ec_ws_new_point(self._point.address_of(),
                                         c_uint8_ptr(xb), c_uint8_ptr(yb),
                                         c_size_t(modulus_bytes),
                                         context.get())
        if result:
            if result == 15:
                raise ValueError("The EC point does not belong to the curve")
            raise ValueError("Error %d while instantiating an EC point" %
                             result)

        # Ensure that object disposal of this Python object will (eventually)
        # free the memory allocated by the raw library for the EC point
        self._point = SmartPointer(self._point.get(), _ec_lib.ec_free_point)
    def sign(self, msg_hash):
        """Create the PKCS#1 v1.5 signature of a message.

        This function is also called ``RSASSA-PKCS1-V1_5-SIGN`` and
        it is specified in
        `section 8.2.1 of RFC8017 <https://tools.ietf.org/html/rfc8017#page-36>`_.

        :parameter msg_hash:
            This is an object from the :mod:`Crypto.Hash` package.
            It has been used to digest the message to sign.
        :type msg_hash: hash object

        :return: the signature encoded as a *byte string*.
        :raise ValueError: if the RSA key is not long enough for the given hash algorithm.
        :raise TypeError: if the RSA key has no private half.
        """

        # See 8.2.1 in RFC3447
        modBits = Crypto.Util.number.size(self._key.n)
        k = ceil_div(modBits,8) # Convert from bits to bytes

        # Step 1
        em = _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k)
        # Step 2a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 2b (RSASP1)
        m_int = self._key._decrypt(em_int)
        # Step 2c (I2OSP)
        signature = long_to_bytes(m_int, k)
        return signature
Exemple #3
0
    def _compute_mac(self):
        """Compute MAC without any FSM checks."""

        if self._tag:
            return self._tag

        # Step 5 in NIST SP 800-38D, Algorithm 4 - Compute S
        self._pad_cache_and_update()
        self._update(long_to_bytes(8 * self._auth_len, 8))
        self._update(long_to_bytes(8 * self._msg_len, 8))
        s_tag = self._signer.digest()

        # Step 6 - Compute T
        self._tag = self._tag_cipher.encrypt(s_tag)[:self._mac_len]

        return self._tag
 def to_bytes(self, block_size=0):
     if self._value < 0:
         raise ValueError("Conversion only valid for non-negative numbers")
     result = long_to_bytes(self._value, block_size)
     if len(result) > block_size > 0:
         raise ValueError("Value too large to encode")
     return result
Exemple #5
0
def MGF1(mgfSeed, maskLen, hash_gen):
    """Mask Generation Function, described in `B.2.1 of RFC8017
    <https://tools.ietf.org/html/rfc8017>`_.

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

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

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

    :return: the mask, as a *byte string*
    """

    T = b""
    for counter in iter_range(ceil_div(maskLen, hash_gen.digest_size)):
        c = long_to_bytes(counter, 4)
        hobj = hash_gen.new()
        hobj.update(mgfSeed + c)
        T = T + hobj.digest()
    assert (len(T) >= maskLen)
    return T[:maskLen]
Exemple #6
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)
Exemple #7
0
def monty_pow(base, exp, modulus):
    max_len = len(long_to_bytes(max(base, exp, modulus)))

    base_b, exp_b, modulus_b = [
        long_to_bytes(x, max_len) for x in (base, exp, modulus)
    ]

    out = create_string_buffer(max_len)
    error = _raw_montgomery.monty_pow(base_b, exp_b, modulus_b, out,
                                      c_size_t(max_len), c_ulonglong(32))

    if error == 2:
        raise ExceptionModulus()
    if error:
        raise ValueError("monty_pow failed with error: %d" % error)

    result = bytes_to_long(get_raw_buffer(out))
    return result
    def verify(self, msg_hash, signature):
        """Check if the  PKCS#1 v1.5 signature over a message is valid.

        This function is also called ``RSASSA-PKCS1-V1_5-VERIFY`` and
        it is specified in
        `section 8.2.2 of RFC8037 <https://tools.ietf.org/html/rfc8017#page-37>`_.

        :parameter msg_hash:
            The hash that was carried out over the message. This is an object
            belonging to the :mod:`Crypto.Hash` module.
        :type parameter: hash object

        :parameter signature:
            The signature that needs to be validated.
        :type signature: byte string

        :raise ValueError: if the signature is not valid.
        """

        # See 8.2.2 in RFC3447
        modBits = Crypto.Util.number.size(self._key.n)
        k = ceil_div(modBits, 8) # Convert from bits to bytes

        # Step 1
        if len(signature) != k:
            raise ValueError("Invalid signature")
        # Step 2a (O2SIP)
        signature_int = bytes_to_long(signature)
        # Step 2b (RSAVP1)
        em_int = self._key._encrypt(signature_int)
        # Step 2c (I2OSP)
        em1 = long_to_bytes(em_int, k)
        # Step 3
        try:
            possible_em1 = [ _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k, True) ]
            # MD2/4/5 hashes always require NULL params in AlgorithmIdentifier.
            # For all others, it is optional.
            try:
                algorithm_is_md = msg_hash.oid.startswith('1.2.840.113549.2.')
            except AttributeError:
                algorithm_is_md = False
            if not algorithm_is_md:  # MD2/MD4/MD5
                possible_em1.append(_EMSA_PKCS1_V1_5_ENCODE(msg_hash, k, False))
        except ValueError:
            raise ValueError("Invalid signature")
        # Step 4
        # By comparing the full encodings (as opposed to checking each
        # of its components one at a time) we avoid attacks to the padding
        # scheme like Bleichenbacher's (see http://www.mail-archive.com/[email protected]/msg06537).
        #
        if em1 not in possible_em1:
            raise ValueError("Invalid signature")
        pass
Exemple #9
0
    def encrypt(self, message):
        """Encrypt a message with PKCS#1 OAEP.

        :param message:
            The message to encrypt, also known as plaintext. It can be of
            variable length, but not longer than the RSA modulus (in bytes)
            minus 2, minus twice the hash output size.
            For instance, if you use RSA 2048 and SHA-256, the longest message
            you can encrypt is 190 byte long.
        :type message: bytes/bytearray/memoryview

        :returns: The ciphertext, as large as the RSA modulus.
        :rtype: bytes

        :raises ValueError:
            if the message is too long.
        """

        # See 7.1.1 in RFC3447
        modBits = crypto.Util.number.size(self._key.n)
        k = ceil_div(modBits, 8)  # Convert from bits to bytes
        hLen = self._hashObj.digest_size
        mLen = len(message)

        # Step 1b
        ps_len = k - mLen - 2 * hLen - 2
        if ps_len < 0:
            raise ValueError("Plaintext is too long.")
        # Step 2a
        lHash = self._hashObj.new(self._label).digest()
        # Step 2b
        ps = b'\x00' * ps_len
        # Step 2c
        db = lHash + ps + b'\x01' + _copy_bytes(None, None, message)
        # Step 2d
        ros = self._randfunc(hLen)
        # Step 2e
        dbMask = self._mgf(ros, k - hLen - 1)
        # Step 2f
        maskedDB = strxor(db, dbMask)
        # Step 2g
        seedMask = self._mgf(maskedDB, hLen)
        # Step 2h
        maskedSeed = strxor(ros, seedMask)
        # Step 2i
        em = b'\x00' + maskedSeed + maskedDB
        # Step 3a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 3b (RSAEP)
        m_int = self._key._encrypt(em_int)
        # Step 3c (I2OSP)
        c = long_to_bytes(m_int, k)
        return c
    def inplace_pow(self, exponent, modulus=None):
        exp_value = int(exponent)
        if exp_value < 0:
            raise ValueError("Exponent must not be negative")

        # No modular reduction
        if modulus is None:
            self._value = pow(self._value, exp_value)
            return self

        # With modular reduction
        mod_value = int(modulus)
        if mod_value < 0:
            raise ValueError("Modulus must be positive")
        if mod_value == 0:
            raise ZeroDivisionError("Modulus cannot be zero")

        # C extension only works with odd moduli
        if (mod_value & 1) == 0:
            self._value = pow(self._value, exp_value, mod_value)
            return self

        max_len = len(long_to_bytes(max(self._value, exp_value, mod_value)))

        base_b = long_to_bytes(self._value, max_len)
        exp_b = long_to_bytes(exp_value, max_len)
        modulus_b = long_to_bytes(mod_value, max_len)

        out = create_string_buffer(max_len)

        error = _raw_montgomery.monty_pow(base_b, exp_b, modulus_b, out,
                                          c_size_t(max_len),
                                          c_ulonglong(getrandbits(64)))

        if error:
            raise ValueError("monty_pow failed with error: %d" % error)

        result = bytes_to_long(get_raw_buffer(out))
        self._value = result
        return self
    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)
Exemple #12
0
    def __imul__(self, scalar):
        """Multiply this point by a scalar"""

        if scalar < 0:
            raise ValueError(
                "Scalar multiplication is only defined for non-negative integers"
            )
        sb = long_to_bytes(scalar)
        result = _ec_lib.ec_ws_scalar(self._point.get(), c_uint8_ptr(sb),
                                      c_size_t(len(sb)),
                                      c_ulonglong(getrandbits(64)))
        if result:
            raise ValueError("Error %d during scalar multiplication" % result)
        return self
Exemple #13
0
    def testVerify2(self):
        # Verify that decryption fails if ciphertext is not as long as
        # RSA modulus
        cipher = PKCS.new(self.key1024)
        self.assertRaises(ValueError, cipher.decrypt, '\x00' * 127, "---")
        self.assertRaises(ValueError, cipher.decrypt, '\x00' * 129, "---")

        # Verify that decryption fails if there are less then 8 non-zero padding
        # bytes
        pt = b('\x00\x02' + '\xFF' * 7 + '\x00' + '\x45' * 118)
        pt_int = bytes_to_long(pt)
        ct_int = self.key1024._encrypt(pt_int)
        ct = long_to_bytes(ct_int, 128)
        self.assertEqual("---", cipher.decrypt(ct, "---"))
    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 = struct.pack("B", 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)
Exemple #15
0
def init_p521():
    p = 0x000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
    b = 0x00000051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00
    order = 0x000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409
    Gx = 0x000000c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66
    Gy = 0x0000011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650

    p521_modulus = long_to_bytes(p, 66)
    p521_b = long_to_bytes(b, 66)
    p521_order = long_to_bytes(order, 66)

    ec_p521_context = VoidPointer()
    result = _ec_lib.ec_ws_new_context(ec_p521_context.address_of(),
                                       c_uint8_ptr(p521_modulus),
                                       c_uint8_ptr(p521_b),
                                       c_uint8_ptr(p521_order),
                                       c_size_t(len(p521_modulus)),
                                       c_ulonglong(getrandbits(64)))
    if result:
        raise ImportError("Error %d initializing P-521 context" % result)

    context = SmartPointer(ec_p521_context.get(), _ec_lib.ec_free_context)
    p521 = _Curve(
        Integer(p),
        Integer(b),
        Integer(order),
        Integer(Gx),
        Integer(Gy),
        None,
        521,
        "1.3.132.0.35",  # SEC 2
        context,
        "NIST P-521",
        "ecdsa-sha2-nistp521")
    global p521_names
    _curves.update(dict.fromkeys(p521_names, p521))
Exemple #16
0
def init_p384():
    p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff
    b = 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef
    order = 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973
    Gx = 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760aB7
    Gy = 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5F

    p384_modulus = long_to_bytes(p, 48)
    p384_b = long_to_bytes(b, 48)
    p384_order = long_to_bytes(order, 48)

    ec_p384_context = VoidPointer()
    result = _ec_lib.ec_ws_new_context(ec_p384_context.address_of(),
                                       c_uint8_ptr(p384_modulus),
                                       c_uint8_ptr(p384_b),
                                       c_uint8_ptr(p384_order),
                                       c_size_t(len(p384_modulus)),
                                       c_ulonglong(getrandbits(64)))
    if result:
        raise ImportError("Error %d initializing P-384 context" % result)

    context = SmartPointer(ec_p384_context.get(), _ec_lib.ec_free_context)
    p384 = _Curve(
        Integer(p),
        Integer(b),
        Integer(order),
        Integer(Gx),
        Integer(Gy),
        None,
        384,
        "1.3.132.0.34",  # SEC 2
        context,
        "NIST P-384",
        "ecdsa-sha2-nistp384")
    global p384_names
    _curves.update(dict.fromkeys(p384_names, p384))
Exemple #17
0
def init_p256():
    p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff
    b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
    order = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551
    Gx = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296
    Gy = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5

    p256_modulus = long_to_bytes(p, 32)
    p256_b = long_to_bytes(b, 32)
    p256_order = long_to_bytes(order, 32)

    ec_p256_context = VoidPointer()
    result = _ec_lib.ec_ws_new_context(ec_p256_context.address_of(),
                                       c_uint8_ptr(p256_modulus),
                                       c_uint8_ptr(p256_b),
                                       c_uint8_ptr(p256_order),
                                       c_size_t(len(p256_modulus)),
                                       c_ulonglong(getrandbits(64)))
    if result:
        raise ImportError("Error %d initializing P-256 context" % result)

    context = SmartPointer(ec_p256_context.get(), _ec_lib.ec_free_context)
    p256 = _Curve(
        Integer(p),
        Integer(b),
        Integer(order),
        Integer(Gx),
        Integer(Gy),
        None,
        256,
        "1.2.840.10045.3.1.7",  # ANSI X9.62
        context,
        "NIST P-256",
        "ecdsa-sha2-nistp256")
    global p256_names
    _curves.update(dict.fromkeys(p256_names, p256))
    def encrypt(self, message):
        """Produce the PKCS#1 v1.5 encryption of a message.

        This function is named ``RSAES-PKCS1-V1_5-ENCRYPT``, and it is specified in
        `section 7.2.1 of RFC8017
        <https://tools.ietf.org/html/rfc8017#page-28>`_.

        :param message:
            The message to encrypt, also known as plaintext. It can be of
            variable length, but not longer than the RSA modulus (in bytes) minus 11.
        :type message: bytes/bytearray/memoryview

        :Returns: A byte string, the ciphertext in which the message is encrypted.
            It is as long as the RSA modulus (in bytes).

        :Raises ValueError:
            If the RSA key length is not sufficiently long to deal with the given
            message.
        """

        # See 7.2.1 in RFC8017
        modBits = Crypto.Util.number.size(self._key.n)
        k = ceil_div(modBits, 8)  # Convert from bits to bytes
        mLen = len(message)

        # Step 1
        if mLen > k - 11:
            raise ValueError("Plaintext is too long.")
        # Step 2a
        ps = []
        while len(ps) != k - mLen - 3:
            new_byte = self._randfunc(1)
            if bord(new_byte[0]) == 0x00:
                continue
            ps.append(new_byte)
        ps = b"".join(ps)
        assert (len(ps) == k - mLen - 3)
        # Step 2b
        em = b'\x00\x02' + ps + b'\x00' + _copy_bytes(None, None, message)
        # Step 3a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 3b (RSAEP)
        m_int = self._key._encrypt(em_int)
        # Step 3c (I2OSP)
        c = long_to_bytes(m_int, k)
        return c
Exemple #19
0
    def verify(self, msg_hash, signature):
        """Check if the  PKCS#1 PSS signature over a message is valid.

        This function is also called ``RSASSA-PSS-VERIFY`` and
        it is specified in
        `section 8.1.2 of RFC8037 <https://tools.ietf.org/html/rfc8017#section-8.1.2>`_.

        :parameter msg_hash:
            The hash that was carried out over the message. This is an object
            belonging to the :mod:`crypto.Hash` module.
        :type parameter: hash object

        :parameter signature:
            The signature that needs to be validated.
        :type signature: bytes

        :raise ValueError: if the signature is not valid.
        """

        # Set defaults for salt length and mask generation function
        if self._saltLen is None:
            sLen = msg_hash.digest_size
        else:
            sLen = self._saltLen
        if self._mgfunc:
            mgf = self._mgfunc
        else:
            mgf = lambda x, y: MGF1(x, y, msg_hash)

        modBits = crypto.Util.number.size(self._key.n)

        # See 8.1.2 in RFC3447
        k = ceil_div(modBits, 8)  # Convert from bits to bytes
        # Step 1
        if len(signature) != k:
            raise ValueError("Incorrect signature")
        # Step 2a (O2SIP)
        signature_int = bytes_to_long(signature)
        # Step 2b (RSAVP1)
        em_int = self._key._encrypt(signature_int)
        # Step 2c (I2OSP)
        emLen = ceil_div(modBits - 1, 8)
        em = long_to_bytes(em_int, emLen)
        # Step 3/4
        _EMSA_PSS_VERIFY(msg_hash, em, modBits - 1, mgf, sLen)
Exemple #20
0
    def sign(self, msg_hash):
        """Produce the DSA/ECDSA signature of a message.

        :parameter msg_hash:
            The hash that was carried out over the message.
            The object belongs to the :mod:`crypto.Hash` package.

            Under mode *'fips-186-3'*, the hash must be a FIPS
            approved secure hash (SHA-1 or a member of the SHA-2 family),
            of cryptographic strength appropriate for the DSA key.
            For instance, a 3072/256 DSA key can only be used
            in combination with SHA-512.
        :type msg_hash: hash object

        :return: The signature as a *byte string*
        :raise ValueError: if the hash algorithm is incompatible to the (EC)DSA key
        :raise TypeError: if the (EC)DSA key has no private half
        """

        if not self._valid_hash(msg_hash):
            raise ValueError("Hash is not sufficiently strong")

        # Generate the nonce k (critical!)
        nonce = self._compute_nonce(msg_hash)

        # Perform signature using the raw API
        z = Integer.from_bytes(msg_hash.digest()[:self._order_bytes])
        sig_pair = self._key._sign(z, nonce)

        # Encode the signature into a single byte string
        if self._encoding == 'binary':
            output = b"".join(
                [long_to_bytes(x, self._order_bytes) for x in sig_pair])
        else:
            # Dss-sig  ::=  SEQUENCE  {
            #   r   INTEGER,
            #   s   INTEGER
            # }
            # Ecdsa-Sig-Value  ::=  SEQUENCE  {
            #   r   INTEGER,
            #   s   INTEGER
            # }
            output = DerSequence(sig_pair).encode()

        return output
Exemple #21
0
    def sign(self, msg_hash):
        """Create the PKCS#1 PSS signature of a message.

        This function is also called ``RSASSA-PSS-SIGN`` and
        it is specified in
        `section 8.1.1 of RFC8017 <https://tools.ietf.org/html/rfc8017#section-8.1.1>`_.

        :parameter msg_hash:
            This is an object from the :mod:`crypto.Hash` package.
            It has been used to digest the message to sign.
        :type msg_hash: hash object

        :return: the signature encoded as a *byte string*.
        :raise ValueError: if the RSA key is not long enough for the given hash algorithm.
        :raise TypeError: if the RSA key has no private half.
        """

        # Set defaults for salt length and mask generation function
        if self._saltLen is None:
            sLen = msg_hash.digest_size
        else:
            sLen = self._saltLen

        if self._mgfunc is None:
            mgf = lambda x, y: MGF1(x, y, msg_hash)
        else:
            mgf = self._mgfunc

        modBits = crypto.Util.number.size(self._key.n)

        # See 8.1.1 in RFC3447
        k = ceil_div(modBits, 8)  # k is length in bytes of the modulus
        # Step 1
        em = _EMSA_PSS_ENCODE(msg_hash, modBits - 1, self._randfunc, mgf, sLen)
        # Step 2a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 2b (RSASP1)
        m_int = self._key._decrypt(em_int)
        # Step 2c (I2OSP)
        signature = long_to_bytes(m_int, k)
        return signature
    def encode(self):
        """Return the field element, encoded as a 16 byte string."""

        return long_to_bytes(self._value, 16)
 def _double(self, bs):
     doubled = bytes_to_long(bs) << 1
     if bord(bs[0]) & 0x80:
         doubled ^= 0x87
     return long_to_bytes(doubled, len(bs))[-len(bs):]
 def __init__(self, randomness):
     length = len(randomness)
     self._idx = 0
     # Fix required to get the right K (see how randint() works!)
     self._randomness = long_to_bytes(bytes_to_long(randomness) - 1, length)
    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 = _copy_bytes(None, None, nonce)
        """Nonce used for this session."""
        if len(nonce) not in range(1, 16):
            raise ValueError("Nonce must be at most 15 bytes long")
        if not is_buffer(nonce):
            raise TypeError("Nonce must be bytes, bytearray or memoryview")

        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 = (struct.pack('B', self._mac_len << 4 & 0xFF) + b'\x00' *
                 (14 - len(nonce)) + b'\x01' + self.nonce)

        bottom_bits = bord(nonce[15]) & 0x3F  # 6 bits, 0..63
        top_bits = bord(nonce[15]) & 0xC0  # 2 bits

        ktop_cipher = factory.new(key, factory.MODE_ECB, **params_without_key)
        ktop = ktop_cipher.encrypt(struct.pack('15sB', nonce[:15], top_bits))

        stretch = ktop + strxor(ktop[:8], ktop[1:9])  # 192 bits
        offset_0 = long_to_bytes(
            bytes_to_long(stretch) >> (64 - bottom_bits), 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()
Exemple #26
0
    def __init__(self, factory, key, nonce, mac_len, cipher_params, ghash_c):

        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 is_buffer(nonce):
            raise TypeError("Nonce must be bytes, bytearray or memoryview")

        # See NIST SP 800 38D, 5.2.1.1
        if len(nonce) > 2**64 - 1:
            raise ValueError("Nonce exceeds maximum length")

        self.nonce = _copy_bytes(None, None, nonce)
        """Nonce"""

        self._factory = factory
        self._key = _copy_bytes(None, None, 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(b'\x00' * 16)

        # Step 2 - Compute J0
        if len(self.nonce) == 12:
            j0 = self.nonce + b"\x00\x00\x00\x01"
        else:
            fill = (16 - (len(nonce) % 16)) % 16 + 8
            ghash_in = (self.nonce + b'\x00' * fill +
                        long_to_bytes(8 * len(nonce), 8))
            j0 = _GHASH(hash_subkey, ghash_c).update(ghash_in).digest()

        # Step 3 - Prepare GCTR cipher for encryption/decryption
        nonce_ctr = j0[:12]
        iv_ctr = (bytes_to_long(j0) + 1) & 0xFFFFFFFF
        self._cipher = factory.new(key,
                                   self._factory.MODE_CTR,
                                   initial_value=iv_ctr,
                                   nonce=nonce_ctr,
                                   **cipher_params)

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

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

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

        self._status = MacStatus.PROCESSING_AUTH_DATA
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 : bytes/bytearray/memoryview
        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 bytes/bytearray/memoryview
        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):
            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(struct.pack('B', initial_value & 255))
        initial_value >>= 8
    words += [b'\x00'] * 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)
Exemple #28
0
    def _int2octets(self, int_mod_q):
        """See 2.3.3 in RFC6979"""

        assert 0 < int_mod_q < self._order
        return long_to_bytes(int_mod_q, self._order_bytes)
def _shift_bytes(bs, xor_lsb=0):
    num = (bytes_to_long(bs) << 1) ^ xor_lsb
    return long_to_bytes(num, len(bs))[-len(bs):]
Exemple #30
0
    def decrypt(self, ciphertext):
        """Decrypt a message with PKCS#1 OAEP.

        :param ciphertext: The encrypted message.
        :type ciphertext: bytes/bytearray/memoryview

        :returns: The original message (plaintext).
        :rtype: bytes

        :raises ValueError:
            if the ciphertext has the wrong length, or if decryption
            fails the integrity check (in which case, the decryption
            key is probably wrong).
        :raises TypeError:
            if the RSA key has no private half (i.e. you are trying
            to decrypt using a public key).
        """

        # See 7.1.2 in RFC3447
        modBits = crypto.Util.number.size(self._key.n)
        k = ceil_div(modBits, 8)  # Convert from bits to bytes
        hLen = self._hashObj.digest_size

        # Step 1b and 1c
        if len(ciphertext) != k or k < hLen + 2:
            raise ValueError("Ciphertext with incorrect length.")
        # Step 2a (O2SIP)
        ct_int = bytes_to_long(ciphertext)
        # Step 2b (RSADP)
        m_int = self._key._decrypt(ct_int)
        # Complete step 2c (I2OSP)
        em = long_to_bytes(m_int, k)
        # Step 3a
        lHash = self._hashObj.new(self._label).digest()
        # Step 3b
        y = em[0]
        # y must be 0, but we MUST NOT check it here in order not to
        # allow attacks like Manger's (http://dl.acm.org/citation.cfm?id=704143)
        maskedSeed = em[1:hLen + 1]
        maskedDB = em[hLen + 1:]
        # Step 3c
        seedMask = self._mgf(maskedDB, hLen)
        # Step 3d
        seed = strxor(maskedSeed, seedMask)
        # Step 3e
        dbMask = self._mgf(seed, k - hLen - 1)
        # Step 3f
        db = strxor(maskedDB, dbMask)
        # Step 3g
        one_pos = db[hLen:].find(b'\x01')
        lHash1 = db[:hLen]
        invalid = bord(y) | int(one_pos < 0)
        hash_compare = strxor(lHash1, lHash)
        for x in hash_compare:
            invalid |= bord(x)
        for x in db[hLen:one_pos]:
            invalid |= bord(x)
        if invalid != 0:
            raise ValueError("Incorrect decryption.")
        # Step 4
        return db[hLen + one_pos + 1:]