Skip to content

Commit

Permalink
Merge pull request #21 from chrysn-pull-requests/p256
Browse files Browse the repository at this point in the history
Extend cipher suite list
  • Loading branch information
TimothyClaeys authored May 18, 2021
2 parents c1306ad + 35b9c13 commit eba4f93
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 13 deletions.
47 changes: 45 additions & 2 deletions edhoc/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from typing import Callable, Any, TypeVar, NamedTuple

import cbor2
from cose.algorithms import AESCCM1664128, Sha256, EdDSA, AESCCM16128128, Es256
from cose.curves import X25519, Ed25519, P256
from cose.algorithms import AESCCM1664128, Sha256, EdDSA, AESCCM16128128, Es256, A128GCM, A256GCM, Sha384, Es384
from cose.curves import X25519, Ed25519, P256, P384

from edhoc.exceptions import EdhocException

Expand Down Expand Up @@ -109,6 +109,21 @@ def __ge__(self, other: 'CipherSuite'):
def __repr__(self):
return f'<{self.fullname}: {self.identifier}>'

@classmethod
def check_identifiers(cls):
"""Return the algorithm names for the suite in the sequence in which
they are printed in the EDHOC specification, for easy validation of the
classes."""
return (
cls.aead.identifier,
cls.hash.identifier,
cls.dh_curve.identifier,
cls.sign_alg.identifier,
cls.sign_curve.identifier,
cls.app_aead.identifier,
cls.app_hash.identifier,
)


@CipherSuite.register_ciphersuite()
class CipherSuite0(CipherSuite):
Expand Down Expand Up @@ -165,6 +180,34 @@ class CipherSuite3(CipherSuite):
app_aead = AESCCM1664128
app_hash = Sha256

@CipherSuite.register_ciphersuite()
class CipherSuite4(CipherSuite):
identifier = 4
fullname = "SUITE_4"

aead = A128GCM
hash = Sha256
dh_curve = X25519
sign_alg = Es256
sign_curve = P256
app_aead = A128GCM
app_hash = Sha256
assert CipherSuite4.check_identifiers() == (1, -16, 4, -7, 1, 1, -16)

@CipherSuite.register_ciphersuite()
class CipherSuite5(CipherSuite):
identifier = 5
fullname = "SUITE_5"

aead = A256GCM
hash = Sha384
dh_curve = P384
sign_alg = Es384
sign_curve = P384
app_aead = A256GCM
app_hash = Sha384
assert CipherSuite5.check_identifiers() == (3, -43, 2, -35, 2, 3, -43)


class EdhocKDFInfo(NamedTuple):
edhoc_aead_id: int
Expand Down
5 changes: 4 additions & 1 deletion edhoc/roles/edhoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,20 +127,23 @@ def shared_secret(private_key: 'CK', public_key: 'CK') -> bytes:
if public_key.crv == X25519:
d = X25519PrivateKey.from_private_bytes(private_key.d)
x = X25519PublicKey.from_public_bytes(public_key.x)
secret = d.exchange(x)
elif public_key.crv == X448:
d = X448PrivateKey.from_private_bytes(private_key.d)

x = X448PublicKey.from_public_bytes(public_key.x)
secret = d.exchange(x)
elif public_key.crv == P256:
d = ec.derive_private_key(int(hexlify(private_key.d), 16), SECP256R1(), default_backend())

x = ec.EllipticCurvePublicNumbers(int(hexlify(public_key.x), 16),
int(hexlify(public_key.y), 16),
SECP256R1())
x = x.public_key()
secret = d.exchange(ec.ECDH(), x)
else:
raise CoseIllegalCurve(f"{public_key.crv} is unsupported")

secret = d.exchange(x)
return secret

@property
Expand Down
8 changes: 3 additions & 5 deletions edhoc/roles/initiator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from cose import headers
from cose.curves import X448, X25519
from cose.headers import KID
from cose.keys import OKPKey
from cose.keys import OKPKey, EC2Key
from cose.keys.keyops import EncryptOp
from cose.messages import Enc0Message, Sign1Message

Expand Down Expand Up @@ -140,8 +140,7 @@ def local_pubkey(self) -> RPK:
if self.cipher_suite.dh_curve in [X448, X25519]:
return OKPKey(x=self.g_x, crv=self.cipher_suite.dh_curve)
else:
# TODO:
pass
return EC2Key(x=self.g_x, crv=self.cipher_suite.dh_curve)

@property
def remote_pubkey(self) -> RPK:
Expand All @@ -150,8 +149,7 @@ def remote_pubkey(self) -> RPK:
if self.cipher_suite.dh_curve in [X448, X25519]:
return OKPKey(x=self.g_y, crv=self.cipher_suite.dh_curve)
else:
# TODO:
pass
return EC2Key(x=self.g_y, crv=self.cipher_suite.dh_curve)

@property
def local_authkey(self) -> RPK:
Expand Down
10 changes: 5 additions & 5 deletions edhoc/roles/responder.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from cose import headers
from cose.curves import X25519, X448
from cose.headers import KID
from cose.keys import OKPKey
from cose.keys import OKPKey, EC2Key
from cose.keys.keyops import DecryptOp
from cose.messages import Enc0Message, Sign1Message

Expand Down Expand Up @@ -151,11 +151,12 @@ def g_x(self) -> bytes:
def local_pubkey(self) -> RPK:
""" Returns the local ephemeral public key. """

# Is this a good criterion? (Possibly there doesn't need to be a
# distinction; self.cipher_suite.dh_curve.keyclass(...) could do)
if self.cipher_suite.dh_curve in [X448, X25519]:
return OKPKey(x=self.g_y, crv=self.cipher_suite.dh_curve)
else:
# TODO: implement NIST curves
pass
return EC2Key(x=self.g_y, crv=self.cipher_suite.dh_curve)

@property
def remote_pubkey(self) -> RPK:
Expand All @@ -164,8 +165,7 @@ def remote_pubkey(self) -> RPK:
if self.cipher_suite.dh_curve in [X448, X25519]:
return OKPKey(x=self.g_x, crv=self.cipher_suite.dh_curve)
else:
# TODO: implement NIST curves
pass
return EC2Key(x=self.g_x, crv=self.cipher_suite.dh_curve)

@property
def local_authkey(self) -> RPK:
Expand Down

0 comments on commit eba4f93

Please sign in to comment.