示例#1
0
    def _th4_input(self) -> CBOR:
        hash_func = config_cose(self.cipher_suite.hash).hash

        input_th = [
            self.transcript(hash_func, self._th3_input), self.msg_3.ciphertext
        ]
        return b''.join([cbor2.dumps(part) for part in input_th])
示例#2
0
    def ciphertext_3(self):
        # TODO: resolve magic key and IV lengths
        iv_bytes = self._hkdf3(13, 'IV_3ae', self._prk3e2m)

        hash_func = config_cose(self.cipher_suite.hash).hash
        # TODO: resolve magic key and IV lengths
        cose_key = self._create_cose_key(self._hkdf3, 16, 'K_3ae',
                                         self._prk3e2m, KeyOps.ENCRYPT)

        # create payload for the COSE_Encrypt0
        payload = [self._p_3ae]

        if self.aad3_cb is not None:
            payload.append(self.aad3_cb())

        payload = b''.join(payload)

        # create the external data for the COSE_Encrypt0
        th_3 = self.transcript(hash_func, self._th3_input)

        # calculate the mac_2 using a COSE_Encrypt0 message
        ciphertext = Enc0Message(payload=payload, external_aad=th_3).encrypt(
            iv_bytes, cose_key)

        return ciphertext
示例#3
0
    def _decrypt(self, ciphertext: bytes) -> bytes:
        # TODO: resolve magic key and IV lengths
        iv_bytes = self._hkdf3(13, 'IV_3ae', self._prk3e2m)

        hash_func = config_cose(self.cipher_suite.hash).hash
        # TODO: resolve magic key and IV lengths
        cose_key = self._create_cose_key(self._hkdf3, 16, 'K_3ae', self._prk3e2m, KeyOps.DECRYPT)

        th_3 = self.transcript(hash_func, self._th3_input)

        return Enc0Message(payload=ciphertext, external_aad=th_3).decrypt(iv_bytes, cose_key)
示例#4
0
    def _prk(self, private_key: Key, pub_key: Key, salt: bytes) -> bytes:
        h = self.cipher_suite.hash
        secret = self.shared_secret(private_key, pub_key)

        prk_2e = hmac.HMAC(algorithm=config_cose(h).hash(),
                           key=salt,
                           backend=default_backend())
        prk_2e.update(secret)

        prk = prk_2e.finalize()
        return prk
示例#5
0
    def shared_secret(private_key: Key, public_key: Key) -> bytes:
        """ Compute the shared secret. """

        if public_key.crv == CoseEllipticCurves.X25519:
            d = X25519PrivateKey.from_private_bytes(private_key.d)
            x = X25519PublicKey.from_public_bytes(public_key.x)
        elif public_key.crv == CoseEllipticCurves.X448:
            d = X448PrivateKey.from_private_bytes(private_key.d)
            x = X448PublicKey.from_public_bytes(public_key.x)
        elif public_key.crv == CoseEllipticCurves.P_256:
            d = ec.derive_private_key(int(hexlify(private_key.d), 16),
                                      config_cose(public_key.crv).curve[1](),
                                      default_backend())

            x = ec.EllipticCurvePublicNumbers(
                int(hexlify(public_key.x), 16), int(hexlify(public_key.y), 16),
                config_cose(public_key.crv).curve[1]())
        else:
            raise CoseIllegalCurve(f"{public_key.crv} is unsupported")

        secret = d.exchange(x)
        return secret
示例#6
0
    def _external_aad(self, transcript: bytes,
                      aad_cb: Callable[..., bytes]) -> CBOR:
        hash_func = config_cose(self.cipher_suite.hash).hash

        aad = [cbor2.dumps(self.transcript(hash_func, transcript)), self.cred]

        if aad_cb is not None:
            ad = aad_cb()

            if ad != b'':
                aad.append(ad)

        aad = b"".join(aad)
        return aad
def test_initiator_message3(initiator, test_vectors):
    initiator.msg_1 = MessageOne.decode(test_vectors['I']['message_1'])
    initiator.msg_2 = MessageTwo.decode(test_vectors['R']['message_2'])

    crv = CoseEllipticCurves(CipherSuite(initiator._selected_cipher).dh_curve)
    hash_func = config_cose(CipherSuite(initiator._selected_cipher).hash).hash

    assert initiator.data_2 == test_vectors['R']['data_2']
    assert initiator._th2_input == test_vectors['R']['input_th_2']
    assert initiator._prk2e == test_vectors['R']['prk_2e']
    assert initiator._prk3e2m == test_vectors['R']['prk_3e2m']
    assert initiator.transcript(
        hash_func, initiator._th2_input) == test_vectors['R']['th_2']

    assert initiator._decrypt(
        initiator.msg_2.ciphertext) == test_vectors['R']['p_2e']

    assert initiator.shared_secret(initiator.ephemeral_key,
                                   OKP(x=initiator.g_y,
                                       crv=crv)) == test_vectors['S']['g_xy']
    assert initiator.data_3 == test_vectors['I']['data_3']
    assert initiator._th3_input == test_vectors['I']['input_th_3']
    assert initiator.transcript(
        hash_func, initiator._th3_input) == test_vectors['I']['th_3']
    assert initiator.cred_id == test_vectors['I']['id_cred']
    assert initiator._prk4x3m == test_vectors['I']['prk_4x3m']
    assert initiator._external_aad(
        initiator._th3_input,
        initiator.aad3_cb) == test_vectors['I']['eaad_3m']
    assert initiator._hkdf3(16, 'K_3m',
                            initiator._prk4x3m) == test_vectors['I']['k_3m']
    assert initiator._hkdf3(13, 'IV_3m',
                            initiator._prk4x3m) == test_vectors['I']['iv_3m']
    assert initiator._mac(initiator._hkdf3, 'K_3m', 16, 'IV_3m', 13,
                          initiator._th3_input, initiator._prk4x3m,
                          initiator.aad2_cb) == test_vectors['I']['mac3']
    assert initiator.signature_or_mac3(
        test_vectors['I']['mac3']) == test_vectors['I']['sign_or_mac3']
    assert initiator._p_3ae == test_vectors['I']['p_3ae']
    assert initiator._hkdf3(16, 'K_3ae',
                            initiator._prk3e2m) == test_vectors['I']['k_3ae']
    assert initiator._hkdf3(13, 'IV_3ae',
                            initiator._prk3e2m) == test_vectors['I']['iv_3ae']
    assert initiator.ciphertext_3 == test_vectors['I']['ciphertext_3']

    assert initiator.create_message_three(
        test_vectors['R']['message_2']) == test_vectors['I']['message_3']
示例#8
0
    def _hkdf_expand(self, length: int, label: str, prk: bytes,
                     transcript: bytes) -> bytes:
        """
        Derive the encryption key and the IV to protect the COSE_Encrypt0 message in the EDHOC message 2.

        :return:
        """
        hash_func = config_cose(self.cipher_suite.hash).hash

        info = EdhocKDFInfo(edhoc_aead_id=self.cipher_suite.aead,
                            transcript_hash=self.transcript(
                                hash_func, transcript),
                            label=label,
                            length=length)

        derived_bytes = HKDFExpand(algorithm=hash_func(),
                                   length=info.length,
                                   info=info.encode(),
                                   backend=default_backend()).derive(prk)

        return derived_bytes
def test_responder_message2(responder, test_vectors):
    responder.msg_1 = MessageOne.decode(test_vectors['I']['message_1'])

    hash_func = config_cose(CipherSuite(
        responder.msg_1.selected_cipher).hash).hash
    crv = CoseEllipticCurves(
        CipherSuite(responder.msg_1.selected_cipher).dh_curve)

    assert responder.shared_secret(responder.ephemeral_key,
                                   OKP(x=responder.g_x,
                                       crv=crv)) == test_vectors['S']['g_xy']
    assert responder._prk2e == test_vectors['R']['prk_2e']
    assert responder._prk3e2m == test_vectors['R']['prk_3e2m']
    assert responder.data_2 == test_vectors['R']['data_2']
    assert responder._th2_input == test_vectors['R']['input_th_2']
    assert responder.cred_id == test_vectors['R']['id_cred']
    assert responder.transcript(
        hash_func, responder._th2_input) == test_vectors['R']['th_2']
    assert responder._external_aad(
        responder._th2_input,
        responder.aad2_cb) == test_vectors['R']['eaad_2m']
    assert responder._hkdf2(
        16, 'K_2m', prk=responder._prk3e2m) == test_vectors['R']['k_2m']
    assert responder._hkdf2(
        13, 'IV_2m', prk=responder._prk3e2m) == test_vectors['R']['iv_2m']
    assert responder._mac(responder._hkdf2, 'K_2m', 16, 'IV_2m', 13,
                          responder._th2_input, responder._prk3e2m,
                          responder.aad2_cb) == test_vectors['R']['mac2']
    assert responder.signature_or_mac2(
        test_vectors['R']['mac2']) == test_vectors['R']['sign_or_mac2']
    assert responder._p_2e == test_vectors['R']['p_2e']
    assert responder._hkdf2(len(responder._p_2e), 'K_2e',
                            prk=responder._prk2e) == test_vectors['R']['k_2e']
    assert responder.ciphertext_2 == test_vectors['R']['ciphertext_2']

    assert responder.create_message_two(
        test_vectors['I']['message_1']) == test_vectors['R']['message_2']
示例#10
0
 def exporter(self, label: str, length: int):
     hash_func = config_cose(self.cipher_suite.hash).hash
     return self._hkdf_expand(length, label, self._prk4x3m,
                              self.transcript(hash_func, self._th4_input))