Exemple #1
0
 def __init__(self, logger):
     self.IK = X25519PrivateKey.generate()
     self.SPK = X25519PrivateKey.generate()
     self.OPK = X25519PrivateKey.generate()
     self.peer_keys = defaultdict(dict)
     self.sessions = defaultdict(lambda: SessionState.new())
     self.logger = logger
Exemple #2
0
def load_bob_keys() -> (X25519PrivateKey, X25519PrivateKey, X25519PrivateKey):
    # If existing, load the saved keys for bob.
    # If they do not already exists, generate new keys and save them.
    # Generate OPKb once and do not save it.

    # Returns 3 keys:
    # IK: X25519PrivateKey
    # SPKb: X25519PrivateKey
    # OPKb: X25519PrivateKey

    OPKb = X25519PrivateKey.generate()
    try:
        with open(path_keys_bob, 'rb') as f:
            lines = f.read()
            assert (len(lines) == 2 * key_length)
            IK_bytes = lines[:key_length]
            SPKb_bytes = lines[key_length:]
            IK = deserialize_private_key(IK_bytes)
            SPKb = deserialize_private_key(SPKb_bytes)
            print("Loaded saved keys.")
    except FileNotFoundError:
        print("No keys found. Creating new keys...")
        IK = X25519PrivateKey.generate()
        SPKb = X25519PrivateKey.generate()
        with open(path_keys_bob, 'wb') as f:
            for key in [IK, SPKb]:
                f.write(serialize_private_key(key))
            print("Keys saved.")
        pass
    return (IK, SPKb, OPKb)
 def is_available(cls):
     try:
         X25519PrivateKey.generate()
     except UnsupportedAlgorithm:
         return False
     else:
         return True
Exemple #4
0
def test_x25519_unsupported(backend):
    with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
        X25519PublicKey.from_public_bytes(b"0" * 32)

    with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
        X25519PrivateKey.from_private_bytes(b"0" * 32)

    with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
        X25519PrivateKey.generate()
Exemple #5
0
 def __init__(self):
     self.IdentityPri = X25519PrivateKey.generate()
     self.IdentityPub = self.IdentityPri.public_key()
     self.SignedPri = X25519PrivateKey.generate()
     self.SignedPub = self.SignedPri.public_key()
     self.OneTimePri = X25519PrivateKey.generate()
     self.OneTimePub = self.OneTimePri.public_key()
     self.EphemeralPri = X25519PrivateKey.generate()
     self.EphemeralPub = self.EphemeralPri.public_key()
Exemple #6
0
def test_x25519_unsupported(backend):
    with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
        X25519PublicKey.from_public_bytes(b"0" * 32)

    with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
        X25519PrivateKey.from_private_bytes(b"0" * 32)

    with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
        X25519PrivateKey.generate()
Exemple #7
0
    def __init__ (self):
        # generate pre-key bundle
        # ideally, this is published to a server
        self.IK = X25519PrivateKey.generate ()   # identity key
        self.SPK = X25519PrivateKey.generate ()  # signed pre-key
        self.OPK = X25519PrivateKey.generate () # one time key

        # initiator - boolean to determine whether this client is initating a connection
        # helps with x3dh, i think ... 
        self.init = False
Exemple #8
0
 def __init__(self, name):
     # generate Bob's keys
     self.__name = name
     # Identity
     self.__IPK = X25519PrivateKey.generate()
     # Pre signed key
     self.__SPK = X25519PrivateKey.generate()
     # One time pre key
     self.__OPK = X25519PrivateKey.generate()
     # Ephemeral key
     self.__EFK = X25519PrivateKey.generate()
Exemple #9
0
def isCryptographyAdvanced():
    """
    Check if the cryptography library is present, and if it supports X25519,
    ChaCha20Poly1305 and such (v2.0 or later).
    """
    try:
        from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey  # noqa: E501
        X25519PrivateKey.generate()
    except Exception:
        return False
    else:
        return True
Exemple #10
0
def isCryptographyAdvanced():
    """
    Check if the cryptography library is present, and if it supports X25519,
    ChaCha20Poly1305 and such (v2.0 or later).
    """
    try:
        from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey  # noqa: E501
        X25519PrivateKey.generate()
    except Exception:
        return False
    else:
        return True
 def get_shared_secret(client_private_key, server_public_key,
                       cryptographic_group):
     # x25519 (x00 x1d)
     if cryptographic_group == b"\x00\x1d":
         private_key = X25519PrivateKey.from_private_bytes(
             client_private_key)
         public_key = X25519PublicKey.from_public_bytes(server_public_key)
         return private_key.exchange(public_key)
     # x448 (x00 x1e)
     elif cryptographic_group == b"\x00\x1e":
         private_key = X448PrivateKey.from_private_bytes(client_private_key)
         public_key = X448PublicKey.from_public_bytes(server_public_key)
         return private_key.exchange(public_key)
     # secp256r1 (x00 x17)
     elif cryptographic_group == b"\x00\x17":
         return Crypto_Helper.get_shared_secret_secpr1(
             client_private_key, server_public_key, SECP256R1)
     # secp384r1 (x00 x18)
     elif cryptographic_group == b"\x00\x18":
         return Crypto_Helper.get_shared_secret_secpr1(
             client_private_key, server_public_key, SECP384R1)
     # secp521r1 (x00 x19)
     elif cryptographic_group == b"\x00\x19":
         return Crypto_Helper.get_shared_secret_secpr1(
             client_private_key, server_public_key, SECP521R1)
Exemple #12
0
    def accept(self):
        """Accept an incoming connection & initialize the encryption layer for that client

        Returns
        -------
        returns (socket, addr) of the client
        """

        clt, addr = super().accept()

        # Generate a private key
        server_key = X25519PrivateKey.generate()

        pubkey = server_key.public_key().public_bytes(encoding=Encoding.Raw,
                                                      format=PublicFormat.Raw)

        data = clt.recv(32)  # Receive client public Key
        clt.sendall(pubkey)  # send public key to client

        public_key = X25519PublicKey.from_public_bytes(data)

        # get Shared key
        shared_key = server_key.exchange(public_key)
        shared_key = HKDF(algorithm=hashes.SHA256(),
                          length=48,
                          salt=None,
                          info=b'handshake data',
                          backend=default_backend()).derive(shared_key)

        encrypted_socket = wrap_socket(clt, False, handshaked=True)
        encrypted_socket.cipher = Cipher(algorithms.AES(shared_key[0:32]),
                                         modes.CBC(shared_key[32:]),
                                         backend=default_backend())

        return encrypted_socket, addr
Exemple #13
0
    def _handshake(self):
        """Open a socket to address, port and initialize the encryption layer by exchanging a key using X25519.
        The key is used as an AES key throughout the communication.

        Returns
        -------
        return itself
        """
        private_key = X25519PrivateKey.generate()
        pubkey = private_key.public_key().public_bytes(encoding=Encoding.Raw,
                                                       format=PublicFormat.Raw)

        # send client public key
        super().send(pubkey)

        # receive server public Key
        data = super().recv(32)

        # from public key get shared_key
        server_key = X25519PublicKey.from_public_bytes(data)
        shared_key = private_key.exchange(server_key)

        key = HKDF(algorithm=hashes.SHA256(),
                   length=48,
                   salt=None,
                   info=b'handshake data',
                   backend=default_backend()).derive(shared_key)

        self.cipher = Cipher(algorithms.AES(key[0:32]),
                             modes.CBC(key[32:]),
                             backend=default_backend())

        return self
Exemple #14
0
def modify(packet):
    pkt = dpkt.ip6.IP6(packet.get_payload())

    if is_icmp_neighbour_message(pkt):
        packet.accept()
        return

    global client_id

    aes_key_text = pkt.data[:256]
    aes_key_text = asymmetrickeys.decrypt(aes_key_text)
    nonce = struct.unpack(">I", pkt.data[256:260])[0]
    public_ecdhe_key = pkt.data[260:292]
    ci = struct.unpack(">I", pkt.data[292:296])[0]

    aes_key = AESGCM(aes_key_text)

    decrypted_block = bytes(
        aes_key.decrypt(bytes(nonce), pkt.data[296:-288], ''))

    ip_b = decrypted_block[:16]

    # --- Header 2

    header_2 = pkt.data[-288:]

    ecdhe = X25519PrivateKey.generate()

    shared_key = ecdhe.exchange(
        X25519PublicKey.from_public_bytes(public_ecdhe_key))

    derived_key = HKDF(algorithm=hashes.SHA512(),
                       length=32,
                       info=None,
                       salt=None,
                       backend=default_backend()).derive(shared_key)

    key = AESGCM(derived_key)

    nonce = random.randint(0, 4294967295)

    encrypted_header = key.encrypt(bytes(nonce), header_2, '')

    signature = sign(ecdhe.public_key().public_bytes(), asymmetrickeys)

    header_2 = ecdhe.public_key().public_bytes() + signature + struct.pack(
        ">I", nonce) + encrypted_header + struct.pack(">I", client_id)

    client_id = client_id + 1

    # Finalize packet

    pkt.data = decrypted_block[16:] + header_2
    pkt.plen = len(pkt.data)

    pkt.dst = ip_b

    sockfd.sendto(bytes(pkt), (socket.inet_ntop(socket.AF_INET6, ip_b), 0))

    packet.drop()
Exemple #15
0
def wg_derive_pubkey(privkey):
    privkey_data = base64.b64decode(privkey.encode("ascii"))
    x = X25519PrivateKey.from_private_bytes(privkey_data)
    p = x.public_key()
    pubkey_data = p.public_bytes(Encoding.Raw, PublicFormat.Raw)
    pubkey = base64.b64encode(pubkey_data)
    return pubkey.decode("ascii")
Exemple #16
0
    def encrypt(self, plaintext):
        """
        Encrypts information for the identity.

        :param plaintext: The plaintext to be encrypted as *bytes*.
        :returns: Ciphertext token as *bytes*.
        :raises: *KeyError* if the instance does not hold a public key.
        """
        if self.pub != None:
            ephemeral_key = X25519PrivateKey.generate()
            ephemeral_pub_bytes = ephemeral_key.public_key().public_bytes(
                encoding=serialization.Encoding.Raw,
                format=serialization.PublicFormat.Raw)

            shared_key = ephemeral_key.exchange(self.pub)
            derived_key = derived_key = HKDF(
                algorithm=hashes.SHA256(),
                length=32,
                salt=self.get_salt(),
                info=self.get_context(),
            ).derive(shared_key)

            fernet = Fernet(base64.urlsafe_b64encode(derived_key))
            ciphertext = base64.urlsafe_b64decode(fernet.encrypt(plaintext))
            token = ephemeral_pub_bytes + ciphertext

            return token
        else:
            raise KeyError(
                "Encryption failed because identity does not hold a public key"
            )
Exemple #17
0
    def generate_key(
            algorithm: CoseAlgorithms,
            key_ops: KeyOps,
            curve_type: CoseEllipticCurves = CoseEllipticCurves.X25519
    ) -> 'OKP':
        """
        Generate a random OKP COSE key object.

        :param algorithm: Specify the CoseAlgorithm to use.
        :param key_ops: Specify the key operation (KeyOps).
        :param curve_type: Specify curve, must be X25519 or X448.
        """

        if curve_type == CoseEllipticCurves.X25519:
            private_key = X25519PrivateKey.generate()
        elif curve_type == CoseEllipticCurves.X448:
            private_key = X448PrivateKey.generate()
        else:
            raise CoseIllegalCurve(
                f"curve must be of type {CoseEllipticCurves.X25519} or {CoseEllipticCurves.X448}"
            )

        encoding = Encoding(serialization.Encoding.Raw)
        private_format = PrivateFormat(serialization.PrivateFormat.Raw)
        public_format = PublicFormat(serialization.PublicFormat.Raw)
        encryption = serialization.NoEncryption()

        return OKP(alg=CoseAlgorithms(algorithm),
                   key_ops=KeyOps(key_ops),
                   crv=CoseEllipticCurves(curve_type),
                   x=private_key.public_key().public_bytes(
                       encoding, public_format),
                   d=private_key.private_bytes(encoding, private_format,
                                               encryption))
Exemple #18
0
    def __init__(self, test, src, port):
        super(VppWgInterface, self).__init__(test)

        self.port = port
        self.src = src
        self.private_key = X25519PrivateKey.generate()
        self.public_key = self.private_key.public_key()
Exemple #19
0
 def test_public_bytes_bad_args(self, backend):
     key = X25519PrivateKey.generate().public_key()
     with pytest.raises(ValueError):
         key.public_bytes(
             None,
             serialization.PublicFormat.Raw  # type: ignore[arg-type]
         )
Exemple #20
0
 def register(cls, password: bytes):
     """
     Generate a new account.
     :param password The password for encrypting the keys.
     :return a Registration.
     """
     reg = cls()
     # gen signature keypair
     sign_object = Ed25519PrivateKey.generate()
     reg.sign_pub = sign_object.public_key().public_bytes(
         serialization.Encoding.Raw, serialization.PublicFormat.Raw)
     sign = sign_object.private_bytes(serialization.Encoding.Raw,
                                      serialization.PrivateFormat.Raw,
                                      serialization.NoEncryption())
     reg.sign_sig = sign_object.sign(sign)
     # the private signature key's hash become the account's ID
     reg.identity = blake2b(sign).digest()
     # gen encryption keypair
     xchg_object = X25519PrivateKey.generate()
     reg.xchg_pub = xchg_object.public_key().public_bytes(
         serialization.Encoding.Raw, serialization.PublicFormat.Raw)
     xchg = xchg_object.private_bytes(serialization.Encoding.Raw,
                                      serialization.PrivateFormat.Raw,
                                      serialization.NoEncryption())
     reg.xchg_sig = sign_object.sign(xchg)
     # encrypt the private keys
     reg.set_passwd(sign, xchg, password)
     return reg
Exemple #21
0
    def load_private_key(self, prv_bytes):
        """
        Load a private key into the instance.

        :param prv_bytes: The private key as *bytes*.
        :returns: True if the key was loaded, otherwise False.
        """
        try:
            self.prv_bytes = prv_bytes[:Identity.KEYSIZE // 8 // 2]
            self.prv = X25519PrivateKey.from_private_bytes(self.prv_bytes)
            self.sig_prv_bytes = prv_bytes[Identity.KEYSIZE // 8 // 2:]
            self.sig_prv = Ed25519PrivateKey.from_private_bytes(
                self.sig_prv_bytes)

            self.pub = self.prv.public_key()
            self.pub_bytes = self.pub.public_bytes(
                encoding=serialization.Encoding.Raw,
                format=serialization.PublicFormat.Raw)

            self.sig_pub = self.sig_prv.public_key()
            self.sig_pub_bytes = self.sig_pub.public_bytes(
                encoding=serialization.Encoding.Raw,
                format=serialization.PublicFormat.Raw)

            self.update_hashes()

            return True

        except Exception as e:
            raise e
            RNS.log("Failed to load identity key", RNS.LOG_ERROR)
            RNS.log("The contained exception was: " + str(e), RNS.LOG_ERROR)
            return False
def keygen_public(key_size, alg, hash_alg, curve):
    if alg == 'rsa':
        key_pair = RSA.generate(key_size)
        priv_key = key_pair.exportKey()
        pub_key = key_pair.publickey().exportKey()
        priv_key_dict = {'alg' : 'rsa', 'type' : 'private',
                         'size': key_size, 'hash' : hash_alg, 'key' : priv_key}
        pub_key_dict = {'alg' : 'rsa', 'type' : 'public',
                        'size': key_size, 'hash' : hash_alg, 'key' : pub_key}
        #return priv_key_dict, pub_key_dict
        return [priv_key_dict, pub_key_dict]
    elif alg == 'ECC':
        if curve == 'X25519':
            key_pair = X25519PrivateKey.generate()
            pub_key = key_pair.public_key().public_bytes()
            priv_key_dict = {'alg' : 'ecc', 'curve' : 'x25519', 'type' : 'private',
                             'hash' : hash_alg, 'key': key_pair}
            pub_key_dict = {'alg' : 'ecc', 'curve' : 'x25519', 'type' : 'public',
                            'hash' : hash_alg, 'key' : pub_key}
        elif curve == 'P-256': #SECP256r1
            key_pair = ec.generate_private_key(ec.SECP256R1(), default_backend())
            priv_key = key_pair.private_bytes(encoding=serialization.Encoding.PEM,
                                              format=serialization.PrivateFormat.PKCS8,
                                              encryption_algorithm=serializtion.NoEncryption)
            pub_key = key_pair.public_key().public_bytes(encoding=serialization.Encoding.PEM,
                                                         format=serialization.PublicFormat.SubjectPublicKeyInfo)
            priv_key_dict = {'alg' : 'ecc', 'curve' : 'p256', 'type' : 'private',
            'hash' : hash_alg, 'key': priv_key}
            pub_key_dict = {'alg' : 'ecc', 'curve' : 'p256', 'type' : 'public',
                            'hash' : hash_alg, 'key' : pub_key}
        return priv_key_dict, pub_key_dict
    else:
        print('SA_ERROR:', alg, 'not yet implemented.', flush = True)
Exemple #23
0
    def create_keys(self):
        self.prv = X25519PrivateKey.generate()
        self.prv_bytes = self.prv.private_bytes(
            encoding=serialization.Encoding.Raw,
            format=serialization.PrivateFormat.Raw,
            encryption_algorithm=serialization.NoEncryption())

        self.sig_prv = Ed25519PrivateKey.generate()
        self.sig_prv_bytes = self.sig_prv.private_bytes(
            encoding=serialization.Encoding.Raw,
            format=serialization.PrivateFormat.Raw,
            encryption_algorithm=serialization.NoEncryption())

        self.pub = self.prv.public_key()
        self.pub_bytes = self.pub.public_bytes(
            encoding=serialization.Encoding.Raw,
            format=serialization.PublicFormat.Raw)

        self.sig_pub = self.sig_prv.public_key()
        self.sig_pub_bytes = self.sig_pub.public_bytes(
            encoding=serialization.Encoding.Raw,
            format=serialization.PublicFormat.Raw)

        self.update_hashes()

        RNS.log("Identity keys created for " + RNS.prettyhexrep(self.hash),
                RNS.LOG_VERBOSE)
Exemple #24
0
    def __init__(self,
                 private_key,
                 ephemeral_public,
                 encryption_alg="AES-PMAC-SIV",
                 digest_alg=hashes.SHA256(),
                 salt=None):
        """
        Create an XSTREAM decryptor object using our private key and an ephemeral public key

        :param private_key: 32-byte X25519 private key (i.e. private scalar)
        :param ephemeral_public: 32-byte X25519 ephemeral public key from XSTREAM encryption
        :param encryption_alg: symmetric encryption algorithm to use with STREAM (default "AES-PMAC-SIV")
        :param digest_alg: digest algorithm to use with HKDF (default "SHA256")
        :param salt: (optional) salt value to pass to HKDF (default None)
        """

        # Perform an X25519 elliptic curve Diffie-Hellman operation and use
        # the resulting shared secret to derive a symmetric key (using HKDF)
        symmetric_key = kdf(
            private_key=X25519PrivateKey._from_private_bytes(private_key),
            public_key=X25519PublicKey.from_public_bytes(ephemeral_public),
            digest_alg=digest_alg,
            length=SYMMETRIC_KEY_SIZE,
            salt=salt)

        super(Decryptor, self).__init__(encryption_alg, symmetric_key, NONCE)
Exemple #25
0
def isCryptographyAdvanced():
    """
    Check if the cryptography module is present, and if it supports X25519,
    ChaCha20Poly1305 and such.

    Notes:
    - cryptography >= 2.0 is required
    - OpenSSL >= 1.1.0 is required
    """
    try:
        from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey  # noqa: E501
        X25519PrivateKey.generate()
    except Exception:
        return False
    else:
        return True
Exemple #26
0
    def x25519_key_derivation(
            self,
            public_key: 'OKP',
            context: CoseKDFContext = b'',
            alg: Optional[CoseAlgorithms] = None,
            curve: Optional[CoseEllipticCurves] = None) -> Tuple[bytes, bytes]:

        self._check_key_conf(alg, KeyOps.DERIVE_KEY, public_key, curve)

        try:
            alg_cfg = config(CoseAlgorithms(self.alg))
        except KeyError as err:
            raise CoseIllegalAlgorithm(err)

        p = X25519PublicKey.from_public_bytes(public_key.x)
        d = X25519PrivateKey.from_private_bytes(self.d)

        shared_secret = d.exchange(p)

        derived_key = alg_cfg.kdf(
            algorithm=alg_cfg.hash(),
            length=int(context.supp_pub_info.key_data_length / 8),
            salt=None,
            info=context.encode(),
            backend=default_backend()).derive(shared_secret)

        return shared_secret, derived_key
Exemple #27
0
def modify(packet):
    pkt = dpkt.ip6.IP6(packet.get_payload())

    if is_icmp_neighbour_message(pkt):
        packet.accept()
        return

    aes_key_text = pkt.data[:256]
    aes_key_text = asymmetrickeya.decrypt(aes_key_text)
    nonce = struct.unpack(">I", pkt.data[256:260])[0]
    ecdhe = pkt.data[260:292]
    ci = struct.unpack(">I", pkt.data[292:296])[0]

    aes_key = AESGCM(aes_key_text)

    decrypted_block = bytes(aes_key.decrypt(bytes(nonce), pkt.data[296:], ''))

    ip_s = decrypted_block[:16]

    ecdhe_ac = X25519PrivateKey.generate()
    signature = sign(ecdhe_ac.public_key().public_bytes(), asymmetrickeya)

    pkt.data = decrypted_block[16:] + ecdhe_ac.public_key().public_bytes(
    ) + signature
    pkt.plen = len(pkt.data)

    pkt.dst = ip_s

    sockfd.sendto(bytes(pkt), (socket.inet_ntop(socket.AF_INET6, ip_s), 0))

    packet.drop()
Exemple #28
0
    def test_profileA(self):
        hn_privkey = unhexlify(
            'c53c22208b61860b06c62e5406a7b330c2b577aa5558981510d128247d38bd1d')
        hn_pubkey = unhexlify(
            '5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650')
        eph_privkey = unhexlify(
            'c80949f13ebe61af4ebdbd293ea4f942696b9e815d7e8f0096bbf6ed7de62256')
        eph_pubkey = unhexlify(
            'b2e92f836055a255837debf850b528997ce0201cb82adfe4be1f587d07d8457d')
        shared_key = unhexlify(
            '028ddf890ec83cdf163947ce45f6ec1a0e3070ea5fe57e2b1f05139f3e82422a')
        #
        plaintext = bytes.fromhex('00012080f6')
        ciphertext = unhexlify('cb02352410')
        mactag = unhexlify('cddd9e730ef3fa87')

        x1 = X25519(eph_privkey)
        x2 = X25519(hn_privkey)

        ue = ECIES_UE(profile='A')
        ue.EC.priv_key = X25519PrivateKey.from_private_bytes(eph_privkey)
        hn = ECIES_HN(profile='A', hn_priv_key=hn_privkey)
        ue.generate_sharedkey(hn_pubkey, fresh=False)
        ue_pk, ue_ct, ue_mac = ue.protect(plaintext)
        hn_ct = hn.unprotect(ue_pk, ue_ct, ue_mac)

        self.assertEqual(x1.get_pubkey(), eph_pubkey)
        self.assertEqual(x1.generate_sharedkey(hn_pubkey), shared_key)
        self.assertEqual(x2.get_pubkey(), hn_pubkey)
        self.assertEqual(x2.generate_sharedkey(eph_pubkey), shared_key)
        self.assertEqual(ue_ct, ciphertext)
        self.assertEqual(ue_mac, mactag)
        self.assertEqual(hn_ct, plaintext)
Exemple #29
0
 def ecies_hkdf(self, enckey, plainkey):
     if isinstance(enckey, ecdsa.ECDSA256P1Public):
         newpk = ec.generate_private_key(ec.SECP256R1(), default_backend())
         shared = newpk.exchange(ec.ECDH(), enckey._get_public())
     else:
         newpk = X25519PrivateKey.generate()
         shared = newpk.exchange(enckey._get_public())
     derived_key = HKDF(algorithm=hashes.SHA256(),
                        length=48,
                        salt=None,
                        info=b'MCUBoot_ECIES_v1',
                        backend=default_backend()).derive(shared)
     encryptor = Cipher(algorithms.AES(derived_key[:16]),
                        modes.CTR(bytes([0] * 16)),
                        backend=default_backend()).encryptor()
     cipherkey = encryptor.update(plainkey) + encryptor.finalize()
     mac = hmac.HMAC(derived_key[16:],
                     hashes.SHA256(),
                     backend=default_backend())
     mac.update(cipherkey)
     ciphermac = mac.finalize()
     if isinstance(enckey, ecdsa.ECDSA256P1Public):
         pubk = newpk.public_key().public_bytes(
             encoding=Encoding.X962, format=PublicFormat.UncompressedPoint)
     else:
         pubk = newpk.public_key().public_bytes(encoding=Encoding.Raw,
                                                format=PublicFormat.Raw)
     return cipherkey, ciphermac, pubk
Exemple #30
0
    def generate(
            public_key,
            encryption_alg="AES-PMAC-SIV",
            digest_alg=hashes.SHA256(),
            salt=None,
            csrng=os.urandom,
    ):
        """
        Generate an XSTREAM encryptor object with a random ephemeral key

        :param public_key: 32-byte X25519 public key (i.e. compressed Montgomery-u coordinate)
        :param encryption_alg: symmetric encryption algorithm to use with STREAM (default "AES-PMAC-SIV")
        :param digest_alg: digest algorithm to use with HKDF (default "SHA256")
        :param salt: (optional) salt value to pass to HKDF (default None)
        :param csrng: (optional) secure random number generator used to generate ephemeral key (default os.urandom)
        :return: STREAM encryptor and ephemeral public key
        """
        ephemeral_scalar = X25519PrivateKey._from_private_bytes(
            csrng(X25519_KEY_SIZE))

        symmetric_key = kdf(
            private_key=ephemeral_scalar,
            public_key=X25519PublicKey.from_public_bytes(public_key),
            digest_alg=digest_alg,
            length=SYMMETRIC_KEY_SIZE,
            salt=salt)

        enc = Encryptor(encryption_alg, symmetric_key, NONCE)
        return enc, ephemeral_scalar.public_key().public_bytes()
    def __init__(self):
        self.s = socket.socket()
        host = socket.gethostname()
        port = 12345
        self.s.connect((host, port))

        self.messages = []

        private_key_bob = X25519PrivateKey.generate()
        public_key_bob = private_key_bob.public_key()

        peer_public_alice_raw = (self.s.recv(2048))
        #print(peer_public_alice_raw)

        self.s.send(public_key_bob.public_bytes(Encoding.Raw,
                                                PublicFormat.Raw))

        peer_public_alice = X25519PublicKey.from_public_bytes(
            peer_public_alice_raw)
        shared_key = private_key_bob.exchange(peer_public_alice)

        derived_key = HKDF(algorithm=hashes.SHA256(),
                           length=32,
                           salt=None,
                           info=b'handshake data',
                           backend=default_backend()).derive(shared_key)
        self.f = Fernet(base64.urlsafe_b64encode(derived_key))
        t = threading.Thread(target=self.recvMessages, args=(self.s, ))
        t.start()
Exemple #32
0
def generate_public_private_key():
    """
    generate_public_private_key uses curve25519 to generate a public and
    private key pair
    """
    private_key = X25519PrivateKey.generate()
    return private_key.public_key(), private_key
Exemple #33
0
 def test_buffer_protocol(self, backend):
     private_bytes = bytearray(os.urandom(32))
     key = X25519PrivateKey.from_private_bytes(private_bytes)
     assert key.private_bytes(
         serialization.Encoding.Raw,
         serialization.PrivateFormat.Raw,
         serialization.NoEncryption()
     ) == private_bytes
Exemple #34
0
 def test_rfc7748(self, vector, backend):
     private = binascii.unhexlify(vector["input_scalar"])
     public = binascii.unhexlify(vector["input_u"])
     shared_key = binascii.unhexlify(vector["output_u"])
     private_key = X25519PrivateKey.from_private_bytes(private)
     public_key = X25519PublicKey.from_public_bytes(public)
     computed_shared_key = private_key.exchange(public_key)
     assert computed_shared_key == shared_key
Exemple #35
0
def key_exchange():
    key_pair = X25519PrivateKey.generate()
    public_key = key_pair.public_key()
    peer_public_key = X25519PublicKey.from_public_bytes(base64.b64decode(request.get_json().get('data').encode('utf-8')))
    secret = key_pair.exchange(peer_public_key)
    id = base64.b64encode(urandom(16)).decode('utf-8')
    users[id] = secret
    return jsonify({'id': id, 'public_key': base64.b64encode(
        public_key.public_bytes(encoding=serialization.Encoding.Raw,
                                format=serialization.PublicFormat.Raw)).decode('utf-8')})
Exemple #36
0
    def test_rfc7748_1000_iteration(self, backend):
        old_private = private = public = binascii.unhexlify(
            b"090000000000000000000000000000000000000000000000000000000000"
            b"0000"
        )
        shared_key = binascii.unhexlify(
            b"684cf59ba83309552800ef566f2f4d3c1c3887c49360e3875f2eb94d9953"
            b"2c51"
        )
        private_key = X25519PrivateKey.from_private_bytes(private)
        public_key = X25519PublicKey.from_public_bytes(public)
        for _ in range(1000):
            computed_shared_key = private_key.exchange(public_key)
            private_key = X25519PrivateKey.from_private_bytes(
                computed_shared_key
            )
            public_key = X25519PublicKey.from_public_bytes(old_private)
            old_private = computed_shared_key

        assert computed_shared_key == shared_key
Exemple #37
0
def isCryptographyAdvanced():
    """
    Check if the cryptography library is present, and if it supports X25519,
    ChaCha20Poly1305 and such (v2.0 or later).
    """
    try:
        import cryptography
    except ImportError:
        return False
    from distutils.version import LooseVersion
    lib_valid = LooseVersion(cryptography.__version__) >= LooseVersion("2.0")
    if not lib_valid:
        return False

    try:
        from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
        X25519PrivateKey.generate()
    except:
        return False
    else:
        return True
Exemple #38
0
 def test_pub_priv_bytes_raw(self, private_bytes, public_bytes, backend):
     private_key = X25519PrivateKey.from_private_bytes(private_bytes)
     assert private_key.private_bytes(
         serialization.Encoding.Raw,
         serialization.PrivateFormat.Raw,
         serialization.NoEncryption()
     ) == private_bytes
     assert private_key.public_key().public_bytes(
         serialization.Encoding.Raw, serialization.PublicFormat.Raw
     ) == public_bytes
     public_key = X25519PublicKey.from_public_bytes(public_bytes)
     assert public_key.public_bytes(
         serialization.Encoding.Raw, serialization.PublicFormat.Raw
     ) == public_bytes
Exemple #39
0
 def test_null_shared_key_raises_error(self, backend):
     """
     The vector used here is taken from wycheproof's x25519 test vectors
     """
     public = binascii.unhexlify(
         "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157"
     )
     private = binascii.unhexlify(
         "78f1e8edf14481b389448dac8f59c70b038e7cf92ef2c7eff57a72466e115296"
     )
     private_key = X25519PrivateKey.from_private_bytes(
         private
     )
     public_key = X25519PublicKey.from_public_bytes(public)
     with pytest.raises(ValueError):
         private_key.exchange(public_key)
Exemple #40
0
    def test_invalid_public_bytes(self, backend):
        key = X25519PrivateKey.generate().public_key()
        with pytest.raises(ValueError):
            key.public_bytes(
                serialization.Encoding.Raw,
                serialization.PublicFormat.SubjectPublicKeyInfo
            )

        with pytest.raises(ValueError):
            key.public_bytes(
                serialization.Encoding.PEM,
                serialization.PublicFormat.PKCS1
            )

        with pytest.raises(ValueError):
            key.public_bytes(
                serialization.Encoding.PEM,
                serialization.PublicFormat.Raw
            )
Exemple #41
0
def test_x25519(backend, wycheproof):
    assert list(wycheproof.testgroup.items()) == [("curve", "curve25519")]

    private_key = X25519PrivateKey.from_private_bytes(
        binascii.unhexlify(wycheproof.testcase["private"])
    )
    public_key = X25519PublicKey.from_public_bytes(
        binascii.unhexlify(wycheproof.testcase["public"])
    )

    assert wycheproof.valid or wycheproof.acceptable

    expected = binascii.unhexlify(wycheproof.testcase["shared"])
    if expected == b"\x00" * 32:
        assert wycheproof.acceptable
        # OpenSSL returns an error on all zeros shared key
        with pytest.raises(ValueError):
            private_key.exchange(public_key)
    else:
        assert private_key.exchange(public_key) == expected
Exemple #42
0
    def test_invalid_private_bytes(self, backend):
        key = X25519PrivateKey.generate()
        with pytest.raises(ValueError):
            key.private_bytes(
                serialization.Encoding.Raw,
                serialization.PrivateFormat.Raw,
                None
            )

        with pytest.raises(ValueError):
            key.private_bytes(
                serialization.Encoding.Raw,
                serialization.PrivateFormat.PKCS8,
                None
            )

        with pytest.raises(ValueError):
            key.private_bytes(
                serialization.Encoding.PEM,
                serialization.PrivateFormat.Raw,
                serialization.NoEncryption()
            )
Exemple #43
0
 def test_deprecated_public_bytes(self, backend):
     key = X25519PrivateKey.generate().public_key()
     with pytest.warns(utils.DeprecatedIn25):
         key.public_bytes()
Exemple #44
0
 def test_generate(self, backend):
     key = X25519PrivateKey.generate()
     assert key
     assert key.public_key()
Exemple #45
0
 def test_invalid_type_exchange(self, backend):
     key = X25519PrivateKey.generate()
     with pytest.raises(TypeError):
         key.exchange(object())
Exemple #46
0
    def test_invalid_length_from_private_bytes(self, backend):
        with pytest.raises(ValueError):
            X25519PrivateKey.from_private_bytes(b"a" * 31)

        with pytest.raises(ValueError):
            X25519PrivateKey.from_private_bytes(b"a" * 33)
Exemple #47
0
 def test_round_trip_private_serialization(self, encoding, fmt, encryption,
                                           passwd, load_func, backend):
     key = X25519PrivateKey.generate()
     serialized = key.private_bytes(encoding, fmt, encryption)
     loaded_key = load_func(serialized, passwd, backend)
     assert isinstance(loaded_key, X25519PrivateKey)
Exemple #48
0
 def test_public_bytes_bad_args(self, backend):
     key = X25519PrivateKey.generate().public_key()
     with pytest.raises(ValueError):
         key.public_bytes(None, serialization.PublicFormat.Raw)
     with pytest.raises(ValueError):
         key.public_bytes(serialization.Encoding.Raw)
Exemple #49
0
 def test_public_bytes(self, private_bytes, public_bytes, backend):
     private_key = X25519PrivateKey._from_private_bytes(private_bytes)
     assert private_key.public_key().public_bytes() == public_bytes
     public_key = X25519PublicKey.from_public_bytes(public_bytes)
     assert public_key.public_bytes() == public_bytes
 def __generate_key(self):
     # Generate private and public key pair for client
     self.client_private_key = X25519PrivateKey.generate()
     self.client_public_key  = self.client_private_key.public_key().public_bytes()