def get_tests(config={}):
    from .common import make_hash_tests

    tests = []

    test_vectors = load_tests(
        ("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"),
        "ShortMsgKAT_SHA3-384.txt", "KAT SHA-3 384", {"len": lambda x: int(x)})

    test_data = []
    for tv in test_vectors:
        if tv.len == 0:
            tv.msg = b("")
        test_data.append((hexlify(tv.md), tv.msg, tv.desc))

    tests += make_hash_tests(SHA3,
                             "SHA3_384",
                             test_data,
                             digest_size=SHA3.digest_size,
                             oid="2.16.840.1.101.3.4.2.9")
    tests += list_test_cases(APITest)
    return tests
Exemple #2
0
    def runTest(self):
        data = b("\x00\x01\x02")

        # Data can be a bytearray (during initialization)
        ba = bytearray(data)

        h1 = self.module.new(data, **self.extra_params)
        h2 = self.module.new(ba, **self.extra_params)
        ba[:1] = b'\xFF'
        self.assertEqual(h1.digest(), h2.digest())

        # Data can be a bytearray (during operation)
        ba = bytearray(data)

        h1 = self.module.new(**self.extra_params)
        h2 = self.module.new(**self.extra_params)

        h1.update(data)
        h2.update(ba)

        ba[:1] = b'\xFF'
        self.assertEqual(h1.digest(), h2.digest())
Exemple #3
0
    def runTest(self):
        plaintext = a2b_hex(self.plaintext)
        ciphertext = a2b_hex(self.ciphertext)
        assoc_data = []
        if self.assoc_data:
            assoc_data = [a2b_hex(b(x)) for x in self.assoc_data]

        ct = None
        pt = None

        #
        # Repeat the same encryption or decryption twice and verify
        # that the result is always the same
        #
        for i in range(2):
            cipher = self._new()
            decipher = self._new()

            # Only AEAD modes
            for comp in assoc_data:
                cipher.update(comp)
                decipher.update(comp)

            ctX = b2a_hex(cipher.encrypt(plaintext))
            ptX = b2a_hex(decipher.decrypt(ciphertext))

            if ct:
                self.assertEqual(ct, ctX)
                self.assertEqual(pt, ptX)
            ct, pt = ctX, ptX

        self.assertEqual(self.ciphertext, ct)  # encrypt
        self.assertEqual(self.plaintext, pt)  # decrypt

        if self.mac:
            mac = b2a_hex(cipher.digest())
            self.assertEqual(self.mac, mac)
            decipher.verify(a2b_hex(self.mac))
    def _compute_nonce(self, mhash):
        """Generate k in a deterministic way"""

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

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

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

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

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

            # Step h.C (first part)
            nonce = self._bits2int(mask_t)
        return nonce
    def test_streaming(self):
        """Verify that an arbitrary number of bytes can be encrypted/decrypted"""
        from crypto.Hash import SHA1

        segments = (1, 3, 5, 7, 11, 17, 23)
        total = sum(segments)

        pt = b("")
        while len(pt) < total:
            pt += SHA1.new(pt).digest()

        cipher1 = ChaCha20.new(key=b("7") * 32, nonce=b("t") * 8)
        ct = cipher1.encrypt(pt)

        cipher2 = ChaCha20.new(key=b("7") * 32, nonce=b("t") * 8)
        cipher3 = ChaCha20.new(key=b("7") * 32, nonce=b("t") * 8)
        idx = 0
        for segment in segments:
            self.assertEqual(cipher2.decrypt(ct[idx:idx+segment]), pt[idx:idx+segment])
            self.assertEqual(cipher3.encrypt(pt[idx:idx+segment]), ct[idx:idx+segment])
            idx += segment
    def setUp(self):
        # Convert DSA key components from hex strings to integers
        new_keys = {}
        for tag, test_key in list(self.keys.items()):
            new_test_key = TestKey()
            new_test_key.p = t2l(test_key.p)
            new_test_key.q = t2l(test_key.q)
            new_test_key.g = t2l(test_key.g)
            new_test_key.x = t2l(test_key.x)
            new_test_key.y = t2l(test_key.y)
            new_keys[tag] = new_test_key
        self.keys = new_keys

        # Convert signature encoding
        new_signatures = []
        for tv in self.signatures:
            new_tv = TestVector()
            new_tv.message = b(tv[0])  # message
            new_tv.nonce = t2l(tv[1])
            new_tv.result = t2b(tv[2]) + t2b(tv[3])
            new_tv.module = tv[4]
            new_tv.test_key = self.keys[tv[5]]
            new_signatures.append(new_tv)
        self.signatures = new_signatures
    def test_initial_value_bytes_parameter(self):
        # Same result as when passing an integer
        cipher1 = AES.new(self.key_128,
                          AES.MODE_CTR,
                          nonce=self.nonce_64,
                          initial_value=b("\x00") * 6 + b("\xFF\xFF"))
        cipher2 = AES.new(self.key_128,
                          AES.MODE_CTR,
                          nonce=self.nonce_64,
                          initial_value=0xFFFF)
        pt = get_tag_random("plaintext", 65536)
        self.assertEqual(cipher1.encrypt(pt), cipher2.encrypt(pt))

        # Fail if the iv is too large
        self.assertRaises(ValueError,
                          AES.new,
                          self.key_128,
                          AES.MODE_CTR,
                          initial_value=b("5") * 17)
        self.assertRaises(ValueError,
                          AES.new,
                          self.key_128,
                          AES.MODE_CTR,
                          nonce=self.nonce_64,
                          initial_value=b("5") * 9)

        # Fail if the iv is too short
        self.assertRaises(ValueError,
                          AES.new,
                          self.key_128,
                          AES.MODE_CTR,
                          initial_value=b("5") * 15)
        self.assertRaises(ValueError,
                          AES.new,
                          self.key_128,
                          AES.MODE_CTR,
                          nonce=self.nonce_64,
                          initial_value=b("5") * 7)
Exemple #8
0
    def __init__(self, module, params):
        unittest.TestCase.__init__(self)
        self.module = module

        # Extract the parameters
        params = params.copy()
        self.description = _extract(params, 'description')
        self.key = b(_extract(params, 'key'))
        self.plaintext = b(_extract(params, 'plaintext'))
        self.ciphertext = b(_extract(params, 'ciphertext'))
        self.module_name = _extract(params, 'module_name', None)
        self.assoc_data = _extract(params, 'assoc_data', None)
        self.mac = _extract(params, 'mac', None)
        if self.assoc_data:
            self.mac = b(self.mac)

        mode = _extract(params, 'mode', None)
        self.mode_name = str(mode)

        if mode is not None:
            # Block cipher
            self.mode = getattr(self.module, "MODE_" + mode)

            self.iv = _extract(params, 'iv', None)
            if self.iv is None:
                self.iv = _extract(params, 'nonce', None)
            if self.iv is not None:
                self.iv = b(self.iv)

        else:
            # Stream cipher
            self.mode = None
            self.iv = _extract(params, 'iv', None)
            if self.iv is not None:
                self.iv = b(self.iv)

        self.extra_params = params
 def test_new_positive(self):
     cipher = ChaCha20.new(key=b("0")*32, nonce=b"0"*8)
     self.assertEqual(cipher.nonce, b"0" * 8)
     cipher = ChaCha20.new(key=b("0")*32, nonce=b"0"*12)
     self.assertEqual(cipher.nonce, b"0" * 12)
def import_key(extern_key, passphrase=None):
    """Import an RSA key (public or private half), encoded in standard
    form.

    Args:
      extern_key (string or byte string):
        The RSA key to import.

        The following formats are supported for an RSA **public key**:

        - X.509 certificate (binary or PEM format)
        - X.509 ``subjectPublicKeyInfo`` DER SEQUENCE (binary or PEM
          encoding)
        - `PKCS#1`_ ``RSAPublicKey`` DER SEQUENCE (binary or PEM encoding)
        - OpenSSH (textual public key only)

        The following formats are supported for an RSA **private key**:

        - PKCS#1 ``RSAPrivateKey`` DER SEQUENCE (binary or PEM encoding)
        - `PKCS#8`_ ``PrivateKeyInfo`` or ``EncryptedPrivateKeyInfo``
          DER SEQUENCE (binary or PEM encoding)
        - OpenSSH (textual public key only)

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

        The private key may be encrypted by means of a certain pass phrase
        either at the PEM level or at the PKCS#8 level.

      passphrase (string):
        In case of an encrypted private key, this is the pass phrase from
        which the decryption key is derived.

    Returns: An RSA key object (:class:`RsaKey`).

    Raises:
      ValueError/IndexError/TypeError:
        When the given key cannot be parsed (possibly because the pass
        phrase is wrong).

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

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

    if extern_key.startswith(b('-----')):
        # This is probably a PEM encoded key.
        (der, marker, enc_flag) = PEM.decode(tostr(extern_key), passphrase)
        if enc_flag:
            passphrase = None
        return _import_keyDER(der, passphrase)

    if extern_key.startswith(b('ssh-rsa ')):
        # This is probably an OpenSSH key
        keystring = binascii.a2b_base64(extern_key.split(b(' '))[1])
        keyparts = []
        while len(keystring) > 4:
            l = struct.unpack(">I", keystring[:4])[0]
            keyparts.append(keystring[4:4 + l])
            keystring = keystring[4 + l:]
        e = Integer.from_bytes(keyparts[1])
        n = Integer.from_bytes(keyparts[2])
        return construct([n, e])

    if bord(extern_key[0]) == 0x30:
        # This is probably a DER encoded key
        return _import_keyDER(extern_key, passphrase)

    raise ValueError("RSA key format is not supported")
 def runTest(self):
     for (key, nonce, stream) in self.tv:
         c = ChaCha20.new(key=unhexlify(b(key)), nonce=unhexlify(b(nonce)))
         ct = unhexlify(b(stream))
         pt = b("\x00") * len(ct)
         self.assertEqual(c.encrypt(pt), ct)
Exemple #12
0
 def testMemoryview(self):
     pt = b("XER")
     cipher = PKCS.new(self.key1024)
     ct = cipher.encrypt(memoryview(bytearray(pt)))
     pt2 = cipher.decrypt(memoryview(bytearray(ct)))
     self.assertEqual(pt, pt2)
    def export_key(self,
                   format='PEM',
                   passphrase=None,
                   pkcs=1,
                   protection=None,
                   randfunc=None):
        """Export this RSA key.

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

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

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

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

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

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

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

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

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

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

                1. A 16 byte Triple DES key is derived from the passphrase
                   using :func:`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)
    def __init__(self,
                 asn1Id=None,
                 payload=b(''),
                 implicit=None,
                 constructed=False,
                 explicit=None):
        """Initialize the DER object according to a specific ASN.1 type.

                :Parameters:
                  asn1Id : integer
                    The universal DER tag number for this object
                    (e.g. 0x10 for a SEQUENCE).
                    If None, the tag is not known yet.

                  payload : byte string
                    The initial payload of the object (that it,
                    the content octets).
                    If not specified, the payload is empty.

                  implicit : integer
                    The IMPLICIT tag number to use for the encoded object.
                    It overrides the universal tag *asn1Id*.

                  constructed : bool
                    True when the ASN.1 type is *constructed*.
                    False when it is *primitive*.

                  explicit : integer
                    The EXPLICIT tag number to use for the encoded object.
                """

        if asn1Id is None:
            # The tag octet will be read in with ``decode``
            self._tag_octet = None
            return
        asn1Id = self._convertTag(asn1Id)

        self.payload = payload

        # In a BER/DER identifier octet:
        # * bits 4-0 contain the tag value
        # * bit 5 is set if the type is 'constructed'
        #   and unset if 'primitive'
        # * bits 7-6 depend on the encoding class
        #
        # Class        | Bit 7, Bit 6
        # ----------------------------------
        # universal    |   0      0
        # application  |   0      1
        # context-spec |   1      0 (default for IMPLICIT/EXPLICIT)
        # private      |   1      1
        #
        if None not in (explicit, implicit):
            raise ValueError("Explicit and implicit tags are"
                             " mutually exclusive")

        if implicit is not None:
            self._tag_octet = 0x80 | 0x20 * constructed | self._convertTag(
                implicit)
            return

        if explicit is not None:
            self._tag_octet = 0xA0 | self._convertTag(explicit)
            self._inner_tag_octet = 0x20 * constructed | asn1Id
            return

        self._tag_octet = 0x20 * constructed | asn1Id
 def test_null_encryption_decryption(self):
     for func in "encrypt", "decrypt":
         cipher = AES.new(self.key_128, AES.MODE_CTR, counter=self.ctr_128)
         result = getattr(cipher, func)(b(""))
         self.assertEqual(result, b(""))
    def __init__(self):
        """Initialize the DER object as a NULL."""

        DerObject.__init__(self, 0x05, b(''), None, False)
def _EMSA_PKCS1_V1_5_ENCODE(msg_hash, emLen, with_hash_parameters=True):
    """
    Implement the ``EMSA-PKCS1-V1_5-ENCODE`` function, as defined
    in PKCS#1 v2.1 (RFC3447, 9.2).

    ``_EMSA-PKCS1-V1_5-ENCODE`` actually accepts the message ``M`` as input,
    and hash it internally. Here, we expect that the message has already
    been hashed instead.

    :Parameters:
     msg_hash : hash object
            The hash object that holds the digest of the message being signed.
     emLen : int
            The length the final encoding must have, in bytes.
     with_hash_parameters : bool
            If True (default), include NULL parameters for the hash
            algorithm in the ``digestAlgorithm`` SEQUENCE.

    :attention: the early standard (RFC2313) stated that ``DigestInfo``
        had to be BER-encoded. This means that old signatures
        might have length tags in indefinite form, which
        is not supported in DER. Such encoding cannot be
        reproduced by this function.

    :Return: An ``emLen`` byte long string that encodes the hash.
    """

    # First, build the ASN.1 DER object DigestInfo:
    #
    #   DigestInfo ::= SEQUENCE {
    #       digestAlgorithm AlgorithmIdentifier,
    #       digest OCTET STRING
    #   }
    #
    # where digestAlgorithm identifies the hash function and shall be an
    # algorithm ID with an OID in the set PKCS1-v1-5DigestAlgorithms.
    #
    #   PKCS1-v1-5DigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
    #       { OID id-md2 PARAMETERS NULL    }|
    #       { OID id-md5 PARAMETERS NULL    }|
    #       { OID id-sha1 PARAMETERS NULL   }|
    #       { OID id-sha256 PARAMETERS NULL }|
    #       { OID id-sha384 PARAMETERS NULL }|
    #       { OID id-sha512 PARAMETERS NULL }
    #   }
    #
    # Appendix B.1 also says that for SHA-1/-2 algorithms, the parameters
    # should be omitted. They may be present, but when they are, they shall
    # have NULL value.

    digestAlgo = DerSequence([ DerObjectId(msg_hash.oid).encode() ])

    if with_hash_parameters:
        digestAlgo.append(DerNull().encode())

    digest      = DerOctetString(msg_hash.digest())
    digestInfo  = DerSequence([
                    digestAlgo.encode(),
                    digest.encode()
                    ]).encode()

    # We need at least 11 bytes for the remaining data: 3 fixed bytes and
    # at least 8 bytes of padding).
    if emLen<len(digestInfo)+11:
        raise TypeError("Selected hash algorith has a too long digest (%d bytes)." % len(digest))
    PS = bchr(0xFF) * (emLen - len(digestInfo) - 3)
    return b("\x00\x01") + PS + bchr(0x00) + digestInfo
Exemple #18
0
 def runTest(self):
     self.assertRaises(TypeError, self.module.new, a2b_hex(self.key),
                       self.module.MODE_ECB, b(""))
Exemple #19
0
def import_key(encoded, passphrase=None):
    """Import an ECC key (public or private).

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

        An ECC **public** key can be:

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

        An ECC **private** key can be:

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

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

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

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

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

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

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

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

    # PEM
    if encoded.startswith(b('-----')):
        der_encoded, marker, enc_flag = PEM.decode(tostr(encoded), passphrase)
        if enc_flag:
            passphrase = None
        try:
            result = _import_der(der_encoded, passphrase)
        except UnsupportedEccFeature as uef:
            raise uef
        except ValueError:
            raise ValueError("Invalid DER encoding inside the PEM file")
        return result

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

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

    raise ValueError("ECC key format is not supported")
Exemple #20
0
def _EMSA_PSS_VERIFY(mhash, em, emBits, mgf, sLen):
    """
    Implement the ``EMSA-PSS-VERIFY`` function, as defined
    in PKCS#1 v2.1 (RFC3447, 9.1.2).

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

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

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

    emLen = ceil_div(emBits, 8)

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

    # Step 1 and 2 have been already done
    # Step 3
    if emLen < mhash.digest_size + sLen + 2:
        return False
    # Step 4
    if ord(em[-1:]) != 0xBC:
        raise ValueError("Incorrect signature")
    # Step 5
    maskedDB = em[:emLen - mhash.digest_size - 1]
    h = em[emLen - mhash.digest_size - 1:-1]
    # Step 6
    if lmask & bord(em[0]):
        raise ValueError("Incorrect signature")
    # Step 7
    dbMask = mgf(h, emLen - mhash.digest_size - 1)
    # Step 8
    db = strxor(maskedDB, dbMask)
    # Step 9
    db = bchr(bord(db[0]) & ~lmask) + db[1:]
    # Step 10
    if not db.startswith(
            bchr(0) * (emLen - mhash.digest_size - sLen - 2) + bchr(1)):
        raise ValueError("Incorrect signature")
    # Step 11
    if sLen > 0:
        salt = db[-sLen:]
    else:
        salt = b("")
    # Step 12
    m_prime = bchr(0) * 8 + mhash.digest() + salt
    # Step 13
    hobj = mhash.new()
    hobj.update(m_prime)
    hp = hobj.digest()
    # Step 14
    if h != hp:
        raise ValueError("Incorrect signature")
 def test_update_after_read(self):
     mac = self.shake.new()
     mac.update(b("rrrr"))
     mac.read(90)
     self.assertRaises(TypeError, mac.update, b("ttt"))
class SHAKE256Test(SHAKETest):
    shake = SHAKE256


class SHAKEVectors(unittest.TestCase):
    pass


test_vectors_128 = load_tests(
    ("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"),
    "ShortMsgKAT_SHAKE128.txt", "Short Messages KAT SHAKE128",
    {"len": lambda x: int(x)})

for idx, tv in enumerate(test_vectors_128):
    if tv.len == 0:
        data = b("")
    else:
        data = tobytes(tv.msg)

    def new_test(self, data=data, result=tv.md):
        hobj = SHAKE128.new(data=data)
        digest = hobj.read(len(result))
        self.assertEqual(digest, result)

    setattr(SHAKEVectors, "test_128_%d" % idx, new_test)

test_vectors_256 = load_tests(
    ("Crypto", "SelfTest", "Hash", "test_vectors", "SHA3"),
    "ShortMsgKAT_SHAKE256.txt", "Short Messages KAT SHAKE256",
    {"len": lambda x: int(x)})
 def test_new_negative(self):
     new = ChaCha20.new
     self.assertRaises(TypeError, new)
     self.assertRaises(TypeError, new, nonce=b("0"))
     self.assertRaises(ValueError, new, nonce=b("0")*8, key=b("0"))
     self.assertRaises(ValueError, new, nonce=b("0"), key=b("0")*32)
Exemple #24
0
    def test_null_encryption_decryption(self):
        cipher = AES.new(self.key_128, AES.MODE_OPENPGP, self.iv_128)
        eiv = cipher.encrypt(b(""))

        cipher = AES.new(self.key_128, AES.MODE_OPENPGP, eiv)
        self.assertEqual(cipher.decrypt(b("")), b(""))
 def runTest(self):
     """ARC2 with keylength > 128"""
     key = b("x") * 16384
     self.assertRaises(ValueError, ARC2.new, key, ARC2.MODE_ECB)
 def runTest(self):
     """Crypto.Random.new()"""
     # Import the Random module and try to use it
     from crypto import Random
     randobj = Random.new()
     x = randobj.read(16)
     y = randobj.read(16)
     self.assertNotEqual(x, y)
     z = Random.get_random_bytes(16)
     self.assertNotEqual(x, z)
     self.assertNotEqual(y, z)
     # Test the Random.random module, which
     # implements a subset of Python's random API
     # Not implemented:
     # seed(), getstate(), setstate(), jumpahead()
     # random(), uniform(), triangular(), betavariate()
     # expovariate(), gammavariate(), gauss(),
     # longnormvariate(), normalvariate(),
     # vonmisesvariate(), paretovariate()
     # weibullvariate()
     # WichmannHill(), whseed(), SystemRandom()
     from crypto.Random import random
     x = random.getrandbits(16*8)
     y = random.getrandbits(16*8)
     self.assertNotEqual(x, y)
     # Test randrange
     if x>y:
         start = y
         stop = x
     else:
         start = x
         stop = y
     for step in range(1,10):
         x = random.randrange(start,stop,step)
         y = random.randrange(start,stop,step)
         self.assertNotEqual(x, y)
         self.assertEqual(start <= x < stop, True)
         self.assertEqual(start <= y < stop, True)
         self.assertEqual((x - start) % step, 0)
         self.assertEqual((y - start) % step, 0)
     for i in range(10):
         self.assertEqual(random.randrange(1,2), 1)
     self.assertRaises(ValueError, random.randrange, start, start)
     self.assertRaises(ValueError, random.randrange, stop, start, step)
     self.assertRaises(TypeError, random.randrange, start, stop, step, step)
     self.assertRaises(TypeError, random.randrange, start, stop, "1")
     self.assertRaises(TypeError, random.randrange, "1", stop, step)
     self.assertRaises(TypeError, random.randrange, 1, "2", step)
     self.assertRaises(ValueError, random.randrange, start, stop, 0)
     # Test randint
     x = random.randint(start,stop)
     y = random.randint(start,stop)
     self.assertNotEqual(x, y)
     self.assertEqual(start <= x <= stop, True)
     self.assertEqual(start <= y <= stop, True)
     for i in range(10):
         self.assertEqual(random.randint(1,1), 1)
     self.assertRaises(ValueError, random.randint, stop, start)
     self.assertRaises(TypeError, random.randint, start, stop, step)
     self.assertRaises(TypeError, random.randint, "1", stop)
     self.assertRaises(TypeError, random.randint, 1, "2")
     # Test choice
     seq = list(range(10000))
     x = random.choice(seq)
     y = random.choice(seq)
     self.assertNotEqual(x, y)
     self.assertEqual(x in seq, True)
     self.assertEqual(y in seq, True)
     for i in range(10):
         self.assertEqual(random.choice((1,2,3)) in (1,2,3), True)
     self.assertEqual(random.choice([1,2,3]) in [1,2,3], True)
     if sys.version_info[0] is 3:
         self.assertEqual(random.choice(bytearray(b('123'))) in bytearray(b('123')), True)
     self.assertEqual(1, random.choice([1]))
     self.assertRaises(IndexError, random.choice, [])
     self.assertRaises(TypeError, random.choice, 1)
     # Test shuffle. Lacks random parameter to specify function.
     # Make copies of seq
     seq = list(range(500))
     x = list(seq)
     y = list(seq)
     random.shuffle(x)
     random.shuffle(y)
     self.assertNotEqual(x, y)
     self.assertEqual(len(seq), len(x))
     self.assertEqual(len(seq), len(y))
     for i in range(len(seq)):
        self.assertEqual(x[i] in seq, True)
        self.assertEqual(y[i] in seq, True)
        self.assertEqual(seq[i] in x, True)
        self.assertEqual(seq[i] in y, True)
     z = [1]
     random.shuffle(z)
     self.assertEqual(z, [1])
     if sys.version_info[0] == 3:
         z = bytearray(b('12'))
         random.shuffle(z)
         self.assertEqual(b('1') in z, True)
         self.assertRaises(TypeError, random.shuffle, b('12'))
     self.assertRaises(TypeError, random.shuffle, 1)
     self.assertRaises(TypeError, random.shuffle, "11")
     self.assertRaises(TypeError, random.shuffle, (1,2))
     # 2to3 wraps a list() around it, alas - but I want to shoot
     # myself in the foot here! :D
     # if sys.version_info[0] == 3:
         # self.assertRaises(TypeError, random.shuffle, range(3))
     # Test sample
     x = random.sample(seq, 20)
     y = random.sample(seq, 20)
     self.assertNotEqual(x, y)
     for i in range(20):
        self.assertEqual(x[i] in seq, True)
        self.assertEqual(y[i] in seq, True)
     z = random.sample([1], 1)
     self.assertEqual(z, [1])
     z = random.sample((1,2,3), 1)
     self.assertEqual(z[0] in (1,2,3), True)
     z = random.sample("123", 1)
     self.assertEqual(z[0] in "123", True)
     z = random.sample(list(range(3)), 1)
     self.assertEqual(z[0] in range(3), True)
     if sys.version_info[0] == 3:
             z = random.sample(b("123"), 1)
             self.assertEqual(z[0] in b("123"), True)
             z = random.sample(bytearray(b("123")), 1)
             self.assertEqual(z[0] in bytearray(b("123")), True)
     self.assertRaises(TypeError, random.sample, 1)
Exemple #27
0
 def __init__(self, module, params):
     unittest.TestCase.__init__(self)
     self.module = module
     self.key = b(params['key'])
 def test_null_encryption_decryption(self):
     for func in "encrypt", "decrypt":
         cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
         result = getattr(cipher, func)(b(""))
         self.assertEqual(result, b(""))
def decode(pem_data, passphrase=None):
    """Decode a PEM block into binary.

    Args:
      pem_data (string):
        The PEM block.
      passphrase (byte string):
        If given and the PEM block is encrypted,
        the key will be derived from the passphrase.

    Returns:
      A tuple with the binary data, the marker string, and a boolean to
      indicate if decryption was performed.

    Raises:
      ValueError: if decoding fails, if the PEM file is encrypted and no passphrase has
                  been provided or if the passphrase is incorrect.
    """

    # Verify Pre-Encapsulation Boundary
    r = re.compile("\s*-----BEGIN (.*)-----\s+")
    m = r.match(pem_data)
    if not m:
        raise ValueError("Not a valid PEM pre boundary")
    marker = m.group(1)

    # Verify Post-Encapsulation Boundary
    r = re.compile("-----END (.*)-----\s*$")
    m = r.search(pem_data)
    if not m or m.group(1) != marker:
        raise ValueError("Not a valid PEM post boundary")

    # Removes spaces and slit on lines
    lines = pem_data.replace(" ", '').split()

    # Decrypts, if necessary
    if lines[1].startswith('Proc-Type:4,ENCRYPTED'):
        if not passphrase:
            raise ValueError("PEM is encrypted, but no passphrase available")
        DEK = lines[2].split(':')
        if len(DEK) != 2 or DEK[0] != 'DEK-Info':
            raise ValueError("PEM encryption format not supported.")
        algo, salt = DEK[1].split(',')
        salt = unhexlify(tobytes(salt))
        if algo == "DES-CBC":
            # This is EVP_BytesToKey in OpenSSL
            key = PBKDF1(passphrase, salt, 8, 1, MD5)
            objdec = DES.new(key, DES.MODE_CBC, salt)
        elif algo == "DES-EDE3-CBC":
            # Note that EVP_BytesToKey is note exactly the same as PBKDF1
            key = PBKDF1(passphrase, salt, 16, 1, MD5)
            key += PBKDF1(key + passphrase, salt, 8, 1, MD5)
            objdec = DES3.new(key, DES3.MODE_CBC, salt)
        elif algo == "AES-128-CBC":
            key = PBKDF1(passphrase, salt[:8], 16, 1, MD5)
            objdec = AES.new(key, AES.MODE_CBC, salt)
        else:
            raise ValueError("Unsupport PEM encryption algorithm (%s)." % algo)
        lines = lines[2:]
    else:
        objdec = None

    # Decode body
    data = a2b_base64(b(''.join(lines[1:-1])))
    enc_flag = False
    if objdec:
        data = unpad(objdec.decrypt(data), objdec.block_size)
        enc_flag = True

    return (data, marker, enc_flag)
    def test_new_positive2(self):

        digest1 = keccak.new(data=b("\x90"), digest_bytes=64).digest()
        digest2 = keccak.new(digest_bytes=64).update(b("\x90")).digest()
        self.assertEqual(digest1, digest2)