mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
tests/pkg_edhoc: initial import
This commit is contained in:
parent
4cef100781
commit
fda3cbc60a
39
tests/pkg_edhoc_c/Makefile
Normal file
39
tests/pkg_edhoc_c/Makefile
Normal file
@ -0,0 +1,39 @@
|
||||
include ../Makefile.tests_common
|
||||
|
||||
# Edhoc related packages
|
||||
USEPKG += edhoc-c
|
||||
USEMODULE += edhoc-c_crypto_tinycrypt
|
||||
# USEMODULE += edhoc-c_crypto_wolfssl
|
||||
USEMODULE += edhoc-c_cbor_nanocbor
|
||||
|
||||
# Include packages that pull up and auto-init the link layer.
|
||||
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
|
||||
USEMODULE += gnrc_netdev_default
|
||||
|
||||
USEMODULE += auto_init_gnrc_netif
|
||||
# Specify the mandatory networking modules for IPv6 and UDP
|
||||
USEMODULE += gnrc_ipv6_router_default
|
||||
USEMODULE += sock_udp
|
||||
# Additional networking modules that can be dropped if not needed
|
||||
USEMODULE += gnrc_icmpv6_echo
|
||||
USEMODULE += nanocoap_sock
|
||||
|
||||
# include this for printing IP addresses
|
||||
USEMODULE += shell
|
||||
USEMODULE += shell_commands
|
||||
USEMODULE += ps
|
||||
USEMODULE += xtimer
|
||||
|
||||
# This is an optimized stack value based on testing, if you observe
|
||||
# a segmentation fault please increase this stack size.
|
||||
CFLAGS += -DTHREAD_STACKSIZE_MAIN=3*THREAD_STACKSIZE_LARGE
|
||||
|
||||
# Include responder code
|
||||
CONFIG_INITIATOR ?= 1
|
||||
CFLAGS += -DCONFIG_INITIATOR=$(CONFIG_INITIATOR)
|
||||
# Include responder code
|
||||
CONFIG_RESPONDER ?= 1
|
||||
CFLAGS += -DCONFIG_RESPONDER=$(CONFIG_RESPONDER)
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
include $(RIOTMAKE)/default-radio-settings.inc.mk
|
51
tests/pkg_edhoc_c/Makefile.ci
Normal file
51
tests/pkg_edhoc_c/Makefile.ci
Normal file
@ -0,0 +1,51 @@
|
||||
BOARD_INSUFFICIENT_MEMORY := \
|
||||
airfy-beacon \
|
||||
b-l072z-lrwan1 \
|
||||
blackpill \
|
||||
blackpill-128kib \
|
||||
bluepill \
|
||||
bluepill-128kib \
|
||||
bluepill-stm32f030c8 \
|
||||
calliope-mini \
|
||||
cc1350-launchpad \
|
||||
cc2650-launchpad \
|
||||
cc2650stk \
|
||||
e104-bt5010a-tb \
|
||||
e104-bt5011a-tb \
|
||||
hifive1 \
|
||||
hifive1b \
|
||||
i-nucleo-lrwan1 \
|
||||
im880b \
|
||||
lsn50 \
|
||||
maple-mini \
|
||||
microbit \
|
||||
nrf51dk \
|
||||
nrf51dongle \
|
||||
nrf6310 \
|
||||
nucleo-f030r8 \
|
||||
nucleo-f031k6 \
|
||||
nucleo-f042k6 \
|
||||
nucleo-f070rb \
|
||||
nucleo-f072rb \
|
||||
nucleo-f103rb \
|
||||
nucleo-f302r8 \
|
||||
nucleo-f303k8 \
|
||||
nucleo-f334r8 \
|
||||
nucleo-l011k4 \
|
||||
nucleo-l031k6 \
|
||||
nucleo-l053r8 \
|
||||
nucleo-l073rz \
|
||||
olimexino-stm32 \
|
||||
opencm904 \
|
||||
samd10-xmini \
|
||||
saml10-xpro \
|
||||
saml11-xpro \
|
||||
slstk3400a \
|
||||
spark-core \
|
||||
stk3200 \
|
||||
stm32f030f4-demo \
|
||||
stm32f0discovery \
|
||||
stm32l0538-disco \
|
||||
stm32mp157c-dk2 \
|
||||
yunjia-nrf51822 \
|
||||
#
|
418
tests/pkg_edhoc_c/README.md
Normal file
418
tests/pkg_edhoc_c/README.md
Normal file
@ -0,0 +1,418 @@
|
||||
# EDHOC-C test application
|
||||
|
||||
This test application sets up a RIOT node that can run as an EDHOC handshake
|
||||
initiator and/or responder. The handshake can be run between two RIOT nodes or
|
||||
between a RIOT node and a Linux host or for testing purposes the node can
|
||||
perform an auto-handshake.
|
||||
|
||||
In this example credentials based on LAKE IETF WG are used. These are RPK keys.
|
||||
Normally different credentials should be used depending on the authentication
|
||||
method, but currently no validation is done so the same credentials can be
|
||||
used for any method.
|
||||
|
||||
## EDHOC handshake between host and RIOT node
|
||||
|
||||
### Pre-requisites
|
||||
|
||||
- install [py-edhoc](https://github.com/openwsn-berkeley/py-edhoc):
|
||||
|
||||
```
|
||||
$ pip install edhoc
|
||||
```
|
||||
|
||||
This will install two cli utils `edhoc-responder` and `edhoc-initiator` to
|
||||
facilitate testing.
|
||||
|
||||
#### `native`
|
||||
|
||||
- if using native set up a tap interface:
|
||||
|
||||
```
|
||||
$ sudo ip tuntap add tap0 mode tap user ${USER}
|
||||
$ sudo ip link set tap0 up
|
||||
```
|
||||
|
||||
#### physical `BOARD`
|
||||
|
||||
- If using any other (non-emulated) `BOARD` then in one terminal:
|
||||
|
||||
```
|
||||
$ sudo dist/tools/ethos/setup_network.sh riot0 2001:db8::/64
|
||||
```
|
||||
|
||||
This will create a tap interface called `riot0`, owned by the user. It will
|
||||
also run an instance of uhcpcd, which starts serving the prefix
|
||||
`2001:db8::/64`. Keep the shell open as long as you need the network.
|
||||
Make sure to exit the "make term" instance from the next section *before*
|
||||
exiting this, as otherwise the "riot0" interface doesn't get cleaned up
|
||||
properly.
|
||||
|
||||
### Responder
|
||||
|
||||
Find out the ipv6 address of the device is by running the `ifconfig`
|
||||
command in the shell.
|
||||
|
||||
```
|
||||
ifconfig
|
||||
Starting the shell
|
||||
> ifconfig
|
||||
ifconfig
|
||||
Iface 5 HWaddr: 0A:94:29:80:74:23
|
||||
L2-PDU:1500 MTU:1500 HL:64 RTR
|
||||
RTR_ADV
|
||||
Source address length: 6
|
||||
Link type: wired
|
||||
inet6 addr: fe80::894:29ff:fe80:7423 scope: link VAL
|
||||
inet6 group: ff02::2
|
||||
inet6 group: ff02::1
|
||||
inet6 group: ff02::1:ff80:7423
|
||||
```
|
||||
|
||||
In this case its `fe80::894:29ff:fe80:7423` and since we setup `tap0` as
|
||||
the tap interface the device is reachable at `[fe80::894:29ff:fe80:7423%tap0]`.
|
||||
|
||||
Initiate the handshake by running the `edhoc-initiator` cli tool:
|
||||
|
||||
```
|
||||
$ edhoc-initiator fe80::894:29ff:fe80:7423%tap0]
|
||||
INFO:root:POST (EdhocState.MSG_1_SENT) b'\x01\x00X \x89\x8f\xf7\x9a\x02\x06z\x16\xea\x1e\xcc\xb9\x0f\xa5"F\xf5\xaaM\xd6\xec\x07k\xba\x02Y\xd9\x04\xb7\xec\x8b\x0c@'
|
||||
INFO:root:CHANGED (EdhocState.MSG_1_SENT) b'X q\xa3\xd5\x99\xc2\x1d\xa1\x89\x02\xa1\xae\xa8\x10\xb2\xb68,\xcd\x8d_\x9b\xf0\x19R\x81uL^\xbc\xaf0\x1e\x13XP\x99\xd58\x01\xa7%\xbf\xd6\xa4\xe7\x1d\x04\x84\xb7U\xec8=\xf7z\x91n\xc0\xdb\xc0+\xba|!\xa2\x00\x80{OX_r\x8bg\x1a\xd6x\xa4:\xac\xd3;x\xeb\xd5f\xcd\x00O\xc6\xf1\xd4\x06\xf0\x1d\x97\x04\xe7\x05\xb2\x15R\xa9\xeb(\xea1j\xb6P7\xd7\x17\x86.'
|
||||
INFO:root:POST (EdhocState.MSG_3_SENT) b'\x01\x00X \x89\x8f\xf7\x9a\x02\x06z\x16\xea\x1e\xcc\xb9\x0f\xa5"F\xf5\xaaM\xd6\xec\x07k\xba\x02Y\xd9\x04\xb7\xec\x8b\x0c@'
|
||||
INFO:root:EDHOC key exchange successfully completed:
|
||||
INFO:root: - connection IDr: b'+'
|
||||
INFO:root: - connection IDi: b''
|
||||
INFO:root: - aead algorithm: AES_CCM_16_64_128
|
||||
INFO:root: - hash algorithm: SHA_256
|
||||
INFO:root: - OSCORE secret : b'Y!1k\xae\x12\xc9\xc4\xd2\xb9\xfb \xcc\x1a\x12\xdd'
|
||||
INFO:root: - OSCORE salt : b'\xad\xf9\xfd\xbed\x98\xa3\x02'
|
||||
```
|
||||
|
||||
And on the device (responder):
|
||||
|
||||
```
|
||||
> [responder]: received an EDHOC message (len 37)
|
||||
0x01 0x00 0x58 0x20 0x89 0x8f 0xf7 0x9a
|
||||
0x02 0x06 0x7a 0x16 0xea 0x1e 0xcc 0xb9
|
||||
0x0f 0xa5 0x22 0x46 0xf5 0xaa 0x4d 0xd6
|
||||
0xec 0x07 0x6b 0xba 0x02 0x59 0xd9 0x04
|
||||
0xb7 0xec 0x8b 0x0c 0x40
|
||||
|
||||
[responder]: sending msg2 (117 bytes)
|
||||
0x58 0x20 0x71 0xa3 0xd5 0x99 0xc2 0x1d
|
||||
0xa1 0x89 0x02 0xa1 0xae 0xa8 0x10 0xb2
|
||||
0xb6 0x38 0x2c 0xcd 0x8d 0x5f 0x9b 0xf0
|
||||
0x19 0x52 0x81 0x75 0x4c 0x5e 0xbc 0xaf
|
||||
0x30 0x1e 0x13 0x58 0x50 0x99 0xd5 0x38
|
||||
0x01 0xa7 0x25 0xbf 0xd6 0xa4 0xe7 0x1d
|
||||
0x04 0x84 0xb7 0x55 0xec 0x38 0x3d 0xf7
|
||||
0x7a 0x91 0x6e 0xc0 0xdb 0xc0 0x2b 0xba
|
||||
0x7c 0x21 0xa2 0x00 0x80 0x7b 0x4f 0x58
|
||||
0x5f 0x72 0x8b 0x67 0x1a 0xd6 0x78 0xa4
|
||||
0x3a 0xac 0xd3 0x3b 0x78 0xeb 0xd5 0x66
|
||||
0xcd 0x00 0x4f 0xc6 0xf1 0xd4 0x06 0xf0
|
||||
0x1d 0x97 0x04 0xe7 0x05 0xb2 0x15 0x52
|
||||
0xa9 0xeb 0x28 0xea 0x31 0x6a 0xb6 0x50
|
||||
0x37 0xd7 0x17 0x86 0x2e
|
||||
|
||||
[responder]: received an EDHOC message (len 91)
|
||||
0x13 0x58 0x58 0x2d 0x88 0xff 0x86 0xda
|
||||
0x47 0x48 0x2c 0x0d 0xfa 0x55 0x9a 0xc8
|
||||
0x24 0xa4 0xa7 0x83 0xd8 0x70 0xc9 0xdb
|
||||
0xa4 0x78 0x05 0xe8 0xaa 0xfb 0xad 0x69
|
||||
0x74 0xc4 0x96 0x46 0x58 0x65 0x03 0xfa
|
||||
0x9b 0xbf 0x3e 0x00 0x01 0x2c 0x03 0x7e
|
||||
0xaf 0x56 0xe4 0x5e 0x30 0x19 0x20 0x83
|
||||
0x9b 0x81 0x3a 0x53 0xf6 0xd4 0xc5 0x57
|
||||
0x48 0x0f 0x6c 0x79 0x7d 0x5b 0x76 0xf0
|
||||
0xe4 0x62 0xf5 0xf5 0x7a 0x3d 0xb6 0xd2
|
||||
0xb5 0x0c 0x32 0x31 0x9f 0x34 0x0f 0x4a
|
||||
0xc5 0xaf 0x9a
|
||||
|
||||
[responder]: finalize exchange
|
||||
[responder]: handshake successfully completed
|
||||
```
|
||||
|
||||
### Initiator
|
||||
|
||||
First find out the local ipv6 address of the tap interface:
|
||||
|
||||
```
|
||||
ifconfig tap0
|
||||
tap0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
|
||||
inet6 fe80::894:29ff:fe80:7422 prefixlen 64 scopeid 0x20<link>
|
||||
ether 0a:94:29:80:74:22 txqueuelen 1000 (Ethernet)
|
||||
RX packets 68 bytes 5962 (5.9 KB)
|
||||
RX errors 0 dropped 0 overruns 0 frame 0
|
||||
TX packets 542 bytes 55480 (55.4 KB)
|
||||
TX errors 0 dropped 1 overruns 0 carrier 0 collisions 0
|
||||
```
|
||||
|
||||
In this case its `fe80::894:29ff:fe80:7422`. Next start the `py-edhoc`
|
||||
based responder.
|
||||
|
||||
```
|
||||
$ edhoc-reponder
|
||||
INFO:root:Booting CoAP server
|
||||
INFO:root:Initializing 'core' resource
|
||||
INFO:root:Initializing 'edhoc' resource
|
||||
```
|
||||
|
||||
Now from the RIOT shell initiate the handshake:
|
||||
|
||||
```
|
||||
Starting the shell
|
||||
> ini handshake fe80::894:29ff:fe80:7422 5683
|
||||
init handshake fe80::894:29ff:fe80:7422 5683
|
||||
[initiator]: sending message (37 bytes)
|
||||
0x01 0x00 0x58 0x20 0x71 0xa3 0xd5 0x99
|
||||
0xc2 0x1d 0xa1 0x89 0x02 0xa1 0xae 0xa8
|
||||
0x10 0xb2 0xb6 0x38 0x2c 0xcd 0x8d 0x5f
|
||||
0x9b 0xf0 0x19 0x52 0x81 0x75 0x4c 0x5e
|
||||
0xbc 0xaf 0x30 0x1e 0x13
|
||||
|
||||
[initiator]: send 37 bytes to fe80::894:29ff:fe80:7422 on port 5683
|
||||
|
||||
[initiator]: received a message (124 bytes):
|
||||
0x58 0x20 0x71 0xa3 0xd5 0x99 0xc2 0x1d
|
||||
0xa1 0x89 0x02 0xa1 0xae 0xa8 0x10 0xb2
|
||||
0xb6 0x38 0x2c 0xcd 0x8d 0x5f 0x9b 0xf0
|
||||
0x19 0x52 0x81 0x75 0x4c 0x5e 0xbc 0xaf
|
||||
0x30 0x1e 0x13 0x58 0x50 0x99 0xe1 0x3b
|
||||
0xa4 0x65 0x44 0x44 0xe8 0xb6 0xd4 0x04
|
||||
0x01 0x1e 0x01 0xa3 0x29 0xa3 0x26 0x05
|
||||
0x45 0x99 0x33 0x95 0xf9 0x34 0x2b 0x43
|
||||
0xa7 0x54 0xf9 0xe1 0x8b 0x0f 0xdc 0x46
|
||||
0xc2 0xcc 0x4e 0x25 0x24 0x77 0xe0 0x83
|
||||
0x52 0x0b 0xf4 0x36 0x74 0x53 0xb6 0x2b
|
||||
0xbf 0x3e 0x14 0xb7 0xb0 0xea 0x0e 0xee
|
||||
0x84 0xc5 0x5b 0x9e 0x64 0xfc 0x03 0x97
|
||||
0xc0 0x45 0x18 0x6d 0x14 0xdb 0x88 0x8c
|
||||
0x73 0x2f 0x95 0x52 0xf5 0x68 0xd1 0x61
|
||||
0x56 0x6c 0xd1 0x61
|
||||
|
||||
[initiator]: sending message (91 bytes)
|
||||
0x13 0x58 0x58 0x49 0x7a 0x3e 0x46 0xac
|
||||
0xa1 0x36 0xbf 0xff 0xb9 0x5c 0x00 0x46
|
||||
0x89 0x69 0x68 0x4a 0xe8 0x2d 0x83 0xf0
|
||||
0xe5 0xc5 0xe3 0x3f 0x8f 0x17 0xdf 0x7c
|
||||
0x72 0xe1 0xf2 0x9e 0x7a 0x2a 0xe8 0x88
|
||||
0x75 0x16 0xd2 0x6a 0xe3 0xa7 0x73 0x76
|
||||
0xe8 0xe5 0x22 0x14 0x43 0x6d 0xb0 0x37
|
||||
0xb8 0x48 0x31 0xf3 0xa9 0xb3 0xfc 0x82
|
||||
0x9c 0x4a 0x92 0x19 0x2c 0x3e 0x4a 0xfe
|
||||
0x42 0x6c 0x11 0x39 0x6c 0x48 0x48 0x06
|
||||
0x6b 0xf0 0xed 0x2e 0xff 0x16 0x91 0x08
|
||||
0xf4 0xee 0x6e
|
||||
|
||||
[initiator]: send 91 bytes to fe80::894:29ff:fe80:7422 on port 5683
|
||||
|
||||
[initiator]: handshake successfully completed
|
||||
```
|
||||
|
||||
And on the `edhoc-responder`:
|
||||
|
||||
```
|
||||
INFO:root:CHANGED (EdhocState.MSG_2_SENT) b'X q\xa3\xd5\x99\xc2\x1d\xa1\x89\x02\xa1\xae\xa8\x10\xb2\xb68,\xcd\x8d_\x9b\xf0\x19R\x81uL^\xbc\xaf0\x1e\x13XP\x99\xe1;\xa4eDD\xe8\xb6\xd4\x04\x01\x1e\x01\xa3)\xa3&\x05E\x993\x95\xf94+C\xa7T\xf9\xe1\x8b\x0f\xdcF\xc2\xccN%$w\xe0\x83R\x0b\xf46tS\xb6+\xbf>\x14\xb7\xb0\xea\x0e\xee\x84\xc5[\x9ed\xfc\x03\x97\xc0E\x18m\x14\xdb\x88\x8cs/\x95R\xf5'
|
||||
INFO:root:POST (EdhocState.MSG_2_SENT) b'\x13XXIz>F\xac\xa16\xbf\xff\xb9\\\x00F\x89ihJ\xe8-\x83\xf0\xe5\xc5\xe3?\x8f\x17\xdf|r\xe1\xf2\x9ez*\xe8\x88u\x16\xd2j\xe3\xa7sv\xe8\xe5"\x14Cm\xb07\xb8H1\xf3\xa9\xb3\xfc\x82\x9cJ\x92\x19,>J\xfeBl\x119lHH\x06k\xf0\xed.\xff\x16\x91\x08\xf4\xeen'
|
||||
INFO:root:EDHOC key exchange successfully completed:
|
||||
INFO:root: - connection IDr: b'+'
|
||||
INFO:root: - connection IDi: b'+'
|
||||
INFO:root: - aead algorithm: AES_CCM_16_64_128
|
||||
INFO:root: - hash algorithm: SHA_256
|
||||
INFO:root: - OSCORE secret : b'\xd8\x1e\xa3@\xec\xe3?3\xe1\xfe\x8a\x1d\x0c|\xd0\xbe'
|
||||
INFO:root: - OSCORE salt : b'\x87\xf9J\xf7\x82Tq\xa3'
|
||||
```
|
||||
|
||||
Congratulations you have performed an EDHOC handshake fo your HOST to
|
||||
a RIOT node running as the initiator and responder. In all cases you can
|
||||
now derive symmetric encryption keys from the shared master secret, in this
|
||||
case a shell command `initiator/responder oscore` is available that derives
|
||||
keys that could be used for an OSCORE context:
|
||||
|
||||
```
|
||||
> ini oscore
|
||||
init oscore
|
||||
OSCORE secret:
|
||||
0x43 0x83 0x97 0xe7 0xa8 0x3b 0xd7 0x35
|
||||
0xdf 0x0d 0x47 0xdc 0x45 0x44 0xa4 0x63
|
||||
|
||||
OSCORE salt:
|
||||
0x22 0x3b 0x3c 0xb1 0x03 0xc8 0xa3 0xd0
|
||||
```
|
||||
|
||||
## EDHOC handshake between two RIOT nodes
|
||||
|
||||
### Pre-requisites
|
||||
|
||||
#### `native`
|
||||
|
||||
- if using `native` `BOARD`'s then create two tap interfaces linked
|
||||
through a bridge:
|
||||
|
||||
```
|
||||
sudo dist/tools/tapsetup/tapsetup -c 2
|
||||
```
|
||||
|
||||
- bootstrap the `BOARD`s and specify the tap interface to use for each
|
||||
|
||||
```
|
||||
PORT=tap0 make -C tests/pkg_edhoc_c all term
|
||||
PORT=tap1 make -C tests/pkg_edhoc_c all term
|
||||
```
|
||||
|
||||
#### physical `BOARD`s
|
||||
|
||||
- for other `BOARD`s make sure the chosen `BOARD`s has a netdev
|
||||
through which they will be able to communicate.
|
||||
|
||||
- bootstrap the `BOARD`s
|
||||
|
||||
```
|
||||
make -C tests/pkg_edhoc_c flash term
|
||||
```
|
||||
|
||||
### Perform the handshake
|
||||
|
||||
One of the devices shall be the initiator and the other one the responder.
|
||||
Both are already setup to listen for the first message.
|
||||
|
||||
In the shell of the node that will act as the responder identify its ipv6
|
||||
address:
|
||||
|
||||
```
|
||||
Starting the shell
|
||||
> ifconfig
|
||||
ifconfig
|
||||
Iface 5 HWaddr: D6:76:BB:62:F2:AE
|
||||
L2-PDU:1500 MTU:1500 HL:64 RTR
|
||||
RTR_ADV
|
||||
Source address length: 6
|
||||
Link type: wired
|
||||
inet6 addr: fe80::d476:bbff:fe62:f2ae scope: link VAL
|
||||
inet6 group: ff02::2
|
||||
inet6 group: ff02::1
|
||||
inet6 group: ff02::1:ff62:f2ae
|
||||
```
|
||||
|
||||
In this case `fe80::d476:bbff:fe62:f2ae`.
|
||||
|
||||
From the initiator now start the handshake:
|
||||
|
||||
```
|
||||
initiator handshake fe80::d476:bbff:fe62:f2ae 5683
|
||||
```
|
||||
|
||||
Yo should see the different messages being exchanged on both nodes, and
|
||||
now both can derive OSCORE keys as well with the `responder/initiator oscore`
|
||||
command:
|
||||
|
||||
- initiator:
|
||||
|
||||
```
|
||||
> ini handshake fe80::d476:bbff:fe62:f2ae 5683
|
||||
init handshake fe80::d476:bbff:fe62:f2ae 5683
|
||||
[initiator]: sending message (37 bytes)
|
||||
0x01 0x00 0x58 0x20 0x71 0xa3 0xd5 0x99
|
||||
0xc2 0x1d 0xa1 0x89 0x02 0xa1 0xae 0xa8
|
||||
0x10 0xb2 0xb6 0x38 0x2c 0xcd 0x8d 0x5f
|
||||
0x9b 0xf0 0x19 0x52 0x81 0x75 0x4c 0x5e
|
||||
0xbc 0xaf 0x30 0x1e 0x13
|
||||
[initiator]: send 37 bytes to fe80::d476:bbff:fe62:f2ae on port 5683
|
||||
|
||||
[initiator]: received a message (126 bytes):
|
||||
0x58 0x20 0x71 0xa3 0xd5 0x99 0xc2 0x1d
|
||||
0xa1 0x89 0x02 0xa1 0xae 0xa8 0x10 0xb2
|
||||
0xb6 0x38 0x2c 0xcd 0x8d 0x5f 0x9b 0xf0
|
||||
0x19 0x52 0x81 0x75 0x4c 0x5e 0xbc 0xaf
|
||||
0x30 0x1e 0x13 0x58 0x50 0x99 0xe1 0x3b
|
||||
0xa4 0x65 0x44 0x44 0xe8 0xb6 0xd4 0x04
|
||||
0x01 0x1e 0x01 0xa3 0x29 0xa3 0x26 0x05
|
||||
0x45 0x99 0x33 0x95 0xf9 0x34 0x2b 0x43
|
||||
0xa7 0x54 0xf9 0xe1 0x8b 0x0f 0xdc 0x46
|
||||
0xc2 0xcc 0x4e 0x25 0x24 0x77 0xe0 0x83
|
||||
0x52 0x0b 0xf4 0x36 0x74 0x53 0xb6 0x2b
|
||||
0xbf 0x3e 0x14 0xb7 0xb0 0xea 0x0e 0xee
|
||||
0x84 0xc5 0x5b 0x9e 0x64 0xfc 0x03 0x97
|
||||
0xc0 0x45 0x18 0x6d 0x14 0xdb 0x88 0x8c
|
||||
0x73 0x2f 0x95 0x52 0xf5 0x60 0x56 0x6c
|
||||
0xa1 0x60 0x56 0x70 0xa1 0x60
|
||||
[initiator]: sending message (91 bytes)
|
||||
0x13 0x58 0x58 0x49 0x7a 0x3e 0x46 0xac
|
||||
0xa1 0x36 0xbf 0xff 0xb9 0x5c 0x00 0x46
|
||||
0x89 0x69 0x68 0x4a 0xe8 0x2d 0x83 0xf0
|
||||
0xe5 0xc5 0xe3 0x3f 0x8f 0x17 0xdf 0x7c
|
||||
0x72 0xe1 0xf2 0x9e 0x7a 0x2a 0xe8 0x88
|
||||
0x75 0x16 0xd2 0x6a 0xe3 0xa7 0x73 0x76
|
||||
0xe8 0xe5 0x22 0x14 0x43 0x6d 0xb0 0x37
|
||||
0xb8 0x48 0x31 0xf3 0xa9 0xb3 0xfc 0x82
|
||||
0x9c 0x4a 0x92 0x19 0x2c 0x3e 0x4a 0xfe
|
||||
0x42 0x6c 0x11 0x39 0x6c 0x48 0x48 0x06
|
||||
0x6b 0xf0 0xed 0x2e 0xff 0x16 0x91 0x08
|
||||
0xf4 0xee 0x6e
|
||||
[initiator]: send 91 bytes to fe80::d476:bbff:fe62:f2ae on port 5683
|
||||
|
||||
[initiator]: handshake successfully completed
|
||||
```
|
||||
|
||||
- responder:
|
||||
|
||||
```
|
||||
> [responder]: received an EDHOC message (len 37)
|
||||
0x01 0x00 0x58 0x20 0x71 0xa3 0xd5 0x99
|
||||
0xc2 0x1d 0xa1 0x89 0x02 0xa1 0xae 0xa8
|
||||
0x10 0xb2 0xb6 0x38 0x2c 0xcd 0x8d 0x5f
|
||||
0x9b 0xf0 0x19 0x52 0x81 0x75 0x4c 0x5e
|
||||
0xbc 0xaf 0x30 0x1e 0x13
|
||||
[responder]: sending msg2 (117 bytes)
|
||||
0x58 0x20 0x71 0xa3 0xd5 0x99 0xc2 0x1d
|
||||
0xa1 0x89 0x02 0xa1 0xae 0xa8 0x10 0xb2
|
||||
0xb6 0x38 0x2c 0xcd 0x8d 0x5f 0x9b 0xf0
|
||||
0x19 0x52 0x81 0x75 0x4c 0x5e 0xbc 0xaf
|
||||
0x30 0x1e 0x13 0x58 0x50 0x99 0xe1 0x3b
|
||||
0xa4 0x65 0x44 0x44 0xe8 0xb6 0xd4 0x04
|
||||
0x01 0x1e 0x01 0xa3 0x29 0xa3 0x26 0x05
|
||||
0x45 0x99 0x33 0x95 0xf9 0x34 0x2b 0x43
|
||||
0xa7 0x54 0xf9 0xe1 0x8b 0x0f 0xdc 0x46
|
||||
0xc2 0xcc 0x4e 0x25 0x24 0x77 0xe0 0x83
|
||||
0x52 0x0b 0xf4 0x36 0x74 0x53 0xb6 0x2b
|
||||
0xbf 0x3e 0x14 0xb7 0xb0 0xea 0x0e 0xee
|
||||
0x84 0xc5 0x5b 0x9e 0x64 0xfc 0x03 0x97
|
||||
0xc0 0x45 0x18 0x6d 0x14 0xdb 0x88 0x8c
|
||||
0x73 0x2f 0x95 0x52 0xf5
|
||||
[responder]: received an EDHOC message (len 91)
|
||||
0x13 0x58 0x58 0x49 0x7a 0x3e 0x46 0xac
|
||||
0xa1 0x36 0xbf 0xff 0xb9 0x5c 0x00 0x46
|
||||
0x89 0x69 0x68 0x4a 0xe8 0x2d 0x83 0xf0
|
||||
0xe5 0xc5 0xe3 0x3f 0x8f 0x17 0xdf 0x7c
|
||||
0x72 0xe1 0xf2 0x9e 0x7a 0x2a 0xe8 0x88
|
||||
0x75 0x16 0xd2 0x6a 0xe3 0xa7 0x73 0x76
|
||||
0xe8 0xe5 0x22 0x14 0x43 0x6d 0xb0 0x37
|
||||
0xb8 0x48 0x31 0xf3 0xa9 0xb3 0xfc 0x82
|
||||
0x9c 0x4a 0x92 0x19 0x2c 0x3e 0x4a 0xfe
|
||||
0x42 0x6c 0x11 0x39 0x6c 0x48 0x48 0x06
|
||||
0x6b 0xf0 0xed 0x2e 0xff 0x16 0x91 0x08
|
||||
0xf4 0xee 0x6e
|
||||
[responder]: finalize exchange
|
||||
[responder]: handshake successfully completed
|
||||
```
|
||||
|
||||
- oscore keys:
|
||||
|
||||
```
|
||||
> ini oscore
|
||||
init oscore
|
||||
OSCORE secret:
|
||||
0x43 0x83 0x97 0xe7 0xa8 0x3b 0xd7 0x35
|
||||
0xdf 0x0d 0x47 0xdc 0x45 0x44 0xa4 0x63
|
||||
|
||||
OSCORE salt:
|
||||
0x22 0x3b 0x3c 0xb1 0x03 0xc8 0xa3 0xd0
|
||||
```
|
||||
|
||||
## EDHOC automatic test
|
||||
|
||||
As long as a BOARD with a netdev interface is used is as simple as:
|
||||
|
||||
```
|
||||
$ make -C tests/pkg_edhoc_c flash test-with-config
|
||||
```
|
141
tests/pkg_edhoc_c/common.c
Normal file
141
tests/pkg_edhoc_c/common.c
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief EDHOC initiator/responder common setup code
|
||||
*
|
||||
* @author Timothy Claeys <timothy.claeys@inria.fr>
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "kernel_defines.h"
|
||||
#include "edhoc/edhoc.h"
|
||||
#include "edhoc_keys.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define CRED_DB_SIZE ARRAY_SIZE(cred_db)
|
||||
|
||||
int _cred_cb(const uint8_t *k, size_t k_len, const uint8_t **o, size_t *o_len)
|
||||
{
|
||||
for (uint8_t i = 0; i < (uint8_t)CRED_DB_SIZE; i++) {
|
||||
if (cred_db[i].id_len == k_len) {
|
||||
if (memcmp(cred_db[i].id, k, k_len) == 0) {
|
||||
*o = cred_db[i].cred;
|
||||
*o_len = cred_db[i].cred_len;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
*o = NULL;
|
||||
*o_len = 0;
|
||||
return EDHOC_ERR_INVALID_CRED_ID;
|
||||
}
|
||||
|
||||
void print_bstr(const uint8_t *bstr, size_t bstr_len)
|
||||
{
|
||||
for (size_t i = 0; i < bstr_len; i++) {
|
||||
if ((i + 1) % 8 == 0) {
|
||||
printf("0x%02x \n", bstr[i]);
|
||||
}
|
||||
else {
|
||||
printf("0x%02x ", bstr[i]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int edhoc_setup(edhoc_ctx_t *ctx, edhoc_conf_t *conf, edhoc_role_t role,
|
||||
cose_key_t *auth_key, cred_id_t *cred_id, rpk_t *rpk,
|
||||
void *hash_ctx)
|
||||
{
|
||||
/* clear/init context and configuration */
|
||||
edhoc_ctx_init(ctx);
|
||||
edhoc_conf_init(conf);
|
||||
cred_id_init(cred_id);
|
||||
cred_rpk_init(rpk);
|
||||
cose_key_init(auth_key);
|
||||
|
||||
/* only for testing load preset keys for role */
|
||||
const uint8_t *cbor_auth_key = NULL;
|
||||
const uint8_t *cbor_rpk = NULL;
|
||||
const uint8_t *cbor_rpk_id = NULL;
|
||||
size_t cbor_auth_key_len = 0;
|
||||
size_t cbor_rpk_len = 0;
|
||||
size_t cbor_rpk_id_len;
|
||||
|
||||
if (role == EDHOC_IS_RESPONDER) {
|
||||
DEBUG_PUTS("[edhoc]: setting up responder");
|
||||
cbor_auth_key = resp_cbor_auth_key;
|
||||
cbor_auth_key_len = sizeof(resp_cbor_auth_key);
|
||||
cbor_rpk = resp_cbor_rpk;
|
||||
cbor_rpk_len = sizeof(resp_cbor_rpk);
|
||||
cbor_rpk_id = resp_cbor_rpk_id;
|
||||
cbor_rpk_id_len = sizeof(resp_cbor_rpk_id);
|
||||
}
|
||||
else {
|
||||
DEBUG_PUTS("[edhoc]: setting up initiator");
|
||||
cbor_auth_key = init_cbor_auth_key;
|
||||
cbor_auth_key_len = sizeof(init_cbor_auth_key);
|
||||
cbor_rpk = init_cbor_rpk;
|
||||
cbor_rpk_len = sizeof(init_cbor_rpk);
|
||||
cbor_rpk_id = init_cbor_rpk_id;
|
||||
cbor_rpk_id_len = sizeof(init_cbor_rpk_id);
|
||||
}
|
||||
|
||||
DEBUG_PUTS("[edhoc]: load private authentication key");
|
||||
if (cose_key_from_cbor(auth_key, cbor_auth_key, cbor_auth_key_len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG_PUTS("[edhoc]: load and set CBOR RPK");
|
||||
if (cred_rpk_from_cbor(rpk, cbor_rpk, cbor_rpk_len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG_PUTS("[edhoc]: load credential identifier information");
|
||||
if (cred_id_from_cbor(cred_id, cbor_rpk_id, cbor_rpk_id_len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG_PUTS("[edhoc]: set up EDHOC callbacks and role");
|
||||
edhoc_conf_setup_ad_callbacks(conf, NULL, NULL, NULL);
|
||||
if (edhoc_conf_setup_role(conf, role) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG_PUTS("[edhoc]: set up EDHOC credentials");
|
||||
if (edhoc_conf_setup_credentials(conf, auth_key, CRED_TYPE_RPK, rpk, cred_id, _cred_cb) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG_PUTS("[edhoc]: EDHOC context setup");
|
||||
edhoc_ctx_setup(ctx, conf, hash_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void edhoc_oscore_exporter(edhoc_ctx_t *ctx, uint8_t *secret, size_t secret_len,
|
||||
uint8_t *salt, size_t salt_len)
|
||||
{
|
||||
edhoc_exporter(ctx, "OSCORE secret", secret_len, secret, secret_len);
|
||||
edhoc_exporter(ctx, "OSCORE salt", salt_len, salt, salt_len);
|
||||
|
||||
puts("OSCORE secret:");
|
||||
print_bstr(secret, secret_len);
|
||||
puts("OSCORE salt:");
|
||||
print_bstr(salt, salt_len);
|
||||
}
|
175
tests/pkg_edhoc_c/edhoc_keys.h
Normal file
175
tests/pkg_edhoc_c/edhoc_keys.h
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Certificates and keys for the edhoc example. This values
|
||||
* are taken from the IETF lake WG test vectors, specifically
|
||||
* test vector 34900, see:
|
||||
* https://github.com/lake-wg/edhoc/blob/5ef58e6ee998f4b9aca4b53b35e87375ca356f32/test-vectors-05/vectors.txt
|
||||
*
|
||||
* @author Timothy Claeys <timothy.claeys@inria.fr>
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef EDHOC_KEYS_H
|
||||
#define EDHOC_KEYS_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "kernel_defines.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* initiator CBOR-encoded authentication key */
|
||||
static const uint8_t init_cbor_auth_key[] = {
|
||||
0xa4, 0x01, 0x01, 0x20, 0x06, 0x21, 0x58, 0x20,
|
||||
0x2c, 0x44, 0x0c, 0xc1, 0x21, 0xf8, 0xd7, 0xf2,
|
||||
0x4c, 0x3b, 0x0e, 0x41, 0xae, 0xda, 0xfe, 0x9c,
|
||||
0xaa, 0x4f, 0x4e, 0x7a, 0xbb, 0x83, 0x5e, 0xc3,
|
||||
0x0f, 0x1d, 0xe8, 0x8a, 0xdb, 0x96, 0xff, 0x71,
|
||||
0x23, 0x58, 0x20, 0x2b, 0xbe, 0xa6, 0x55, 0xc2,
|
||||
0x33, 0x71, 0xc3, 0x29, 0xcf, 0xbd, 0x3b, 0x1f,
|
||||
0x02, 0xc6, 0xc0, 0x62, 0x03, 0x38, 0x37, 0xb8,
|
||||
0xb5, 0x90, 0x99, 0xa4, 0x43, 0x6f, 0x66, 0x60,
|
||||
0x81, 0xb0, 0x8e
|
||||
};
|
||||
|
||||
/* initiator CBOR-encoded ephemeral key */
|
||||
static const uint8_t init_cbor_eph_key[] = {
|
||||
0xa4, 0x01, 0x01, 0x20, 0x04, 0x21, 0x58, 0x20,
|
||||
0x8d, 0x3e, 0xf5, 0x6d, 0x1b, 0x75, 0x0a, 0x43,
|
||||
0x51, 0xd6, 0x8a, 0xc2, 0x50, 0xa0, 0xe8, 0x83,
|
||||
0x79, 0x0e, 0xfc, 0x80, 0xa5, 0x38, 0xa4, 0x44,
|
||||
0xee, 0x9e, 0x2b, 0x57, 0xe2, 0x44, 0x1a, 0x7c,
|
||||
0x23, 0x58, 0x20, 0xae, 0x11, 0xa0, 0xdb, 0x86,
|
||||
0x3c, 0x02, 0x27, 0xe5, 0x39, 0x92, 0xfe, 0xb8,
|
||||
0xf5, 0x92, 0x4c, 0x50, 0xd0, 0xa7, 0xba, 0x6e,
|
||||
0xea, 0xb4, 0xad, 0x1f, 0xf2, 0x45, 0x72, 0xf4,
|
||||
0xf5, 0x7c, 0xfa
|
||||
};
|
||||
|
||||
/* initiator CBOR-encoded RPK */
|
||||
static const uint8_t init_cbor_rpk[] = {
|
||||
0xa4, 0x01, 0x01, 0x20, 0x04, 0x21, 0x58, 0x20,
|
||||
0x2c, 0x44, 0x0c, 0xc1, 0x21, 0xf8, 0xd7, 0xf2,
|
||||
0x4c, 0x3b, 0x0e, 0x41, 0xae, 0xda, 0xfe, 0x9c,
|
||||
0xaa, 0x4f, 0x4e, 0x7a, 0xbb, 0x83, 0x5e, 0xc3,
|
||||
0x0f, 0x1d, 0xe8, 0x8a, 0xdb, 0x96, 0xff, 0x71,
|
||||
0x6c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x20, 0x6e, 0x61, 0x6d, 0x65, 0x60
|
||||
};
|
||||
|
||||
/* initiator CBOR-encoded rpk identifier */
|
||||
static const uint8_t init_cbor_rpk_id[] = {
|
||||
0xa1, 0x04, 0x41, 0x23
|
||||
};
|
||||
|
||||
/* initiator CBOR-encoded rpk identifier */
|
||||
static const uint8_t init_cbor_rpk_id_value[] = {
|
||||
0x23
|
||||
};
|
||||
|
||||
/* initiator session identifier preset */
|
||||
static const uint8_t init_cid[] = {
|
||||
0x16
|
||||
};
|
||||
|
||||
/* responder CBOR-encoded authentication key */
|
||||
static const uint8_t resp_cbor_auth_key[] = {
|
||||
0xa4, 0x01, 0x01, 0x20, 0x06, 0x21, 0x58, 0x20,
|
||||
0xa3, 0xff, 0x26, 0x35, 0x95, 0xbe, 0xb3, 0x77,
|
||||
0xd1, 0xa0, 0xce, 0x1d, 0x04, 0xda, 0xd2, 0xd4,
|
||||
0x09, 0x66, 0xac, 0x6b, 0xcb, 0x62, 0x20, 0x51,
|
||||
0xb8, 0x46, 0x59, 0x18, 0x4d, 0x5d, 0x9a, 0x32,
|
||||
0x23, 0x58, 0x20, 0xbb, 0x50, 0x1a, 0xac, 0x67,
|
||||
0xb9, 0xa9, 0x5f, 0x97, 0xe0, 0xed, 0xed, 0x6b,
|
||||
0x82, 0xa6, 0x62, 0x93, 0x4f, 0xbb, 0xfc, 0x7a,
|
||||
0xd1, 0xb7, 0x4c, 0x1f, 0xca, 0xd6, 0x6a, 0x07,
|
||||
0x94, 0x22, 0xd0
|
||||
};
|
||||
|
||||
/* responder CBOR-encoded ephemeral key */
|
||||
static const uint8_t resp_cbor_eph_key[] = {
|
||||
0xa4, 0x01, 0x01, 0x20, 0x04, 0x21, 0x58, 0x20,
|
||||
0x52, 0xfb, 0xa0, 0xbd, 0xc8, 0xd9, 0x53, 0xdd,
|
||||
0x86, 0xce, 0x1a, 0xb2, 0xfd, 0x7c, 0x05, 0xa4,
|
||||
0x65, 0x8c, 0x7c, 0x30, 0xaf, 0xdb, 0xfc, 0x33,
|
||||
0x01, 0x04, 0x70, 0x69, 0x45, 0x1b, 0xaf, 0x35,
|
||||
0x23, 0x58, 0x20, 0xc6, 0x46, 0xcd, 0xdc, 0x58,
|
||||
0x12, 0x6e, 0x18, 0x10, 0x5f, 0x01, 0xce, 0x35,
|
||||
0x05, 0x6e, 0x5e, 0xbc, 0x35, 0xf4, 0xd4, 0xcc,
|
||||
0x51, 0x07, 0x49, 0xa3, 0xa5, 0xe0, 0x69, 0xc1,
|
||||
0x16, 0x16, 0x9a
|
||||
};
|
||||
|
||||
/* responder CBOR-encoded RPK */
|
||||
static const uint8_t resp_cbor_rpk[] = {
|
||||
0xa4, 0x01, 0x01, 0x20, 0x04, 0x21, 0x58, 0x20,
|
||||
0xa3, 0xff, 0x26, 0x35, 0x95, 0xbe, 0xb3, 0x77,
|
||||
0xd1, 0xa0, 0xce, 0x1d, 0x04, 0xda, 0xd2, 0xd4,
|
||||
0x09, 0x66, 0xac, 0x6b, 0xcb, 0x62, 0x20, 0x51,
|
||||
0xb8, 0x46, 0x59, 0x18, 0x4d, 0x5d, 0x9a, 0x32,
|
||||
0x6c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x20, 0x6e, 0x61, 0x6d, 0x65, 0x60
|
||||
};
|
||||
|
||||
|
||||
/* responder CBOR-encoded rpk identifier */
|
||||
static const uint8_t resp_cbor_rpk_id[] = {
|
||||
0xa1, 0x04, 0x41, 0x05
|
||||
};
|
||||
|
||||
/* responder CBOR-encoded rpk identifier */
|
||||
static const uint8_t resp_cbor_rpk_id_value[] = {
|
||||
0x05
|
||||
};
|
||||
|
||||
/* responder session identifier preset */
|
||||
static const uint8_t resp_cid[] = {
|
||||
0x00
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Credential database entry
|
||||
*/
|
||||
typedef struct {
|
||||
const uint8_t *id; /**< credential id pointer */
|
||||
size_t id_len; /**< credential id length */
|
||||
const uint8_t *cred; /**< credential pointer */
|
||||
size_t cred_len; /**< credential length */
|
||||
} cred_db_entry_t;
|
||||
|
||||
/* credential database */
|
||||
static const cred_db_entry_t cred_db[] = {
|
||||
{
|
||||
resp_cbor_rpk_id_value,
|
||||
sizeof(resp_cbor_rpk_id_value),
|
||||
resp_cbor_rpk,
|
||||
sizeof(resp_cbor_rpk)
|
||||
},
|
||||
{
|
||||
init_cbor_rpk_id_value,
|
||||
sizeof(init_cbor_rpk_id_value),
|
||||
init_cbor_rpk,
|
||||
sizeof(init_cbor_rpk)
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EDHOC_KEYS_H */
|
294
tests/pkg_edhoc_c/initiator.c
Normal file
294
tests/pkg_edhoc_c/initiator.c
Normal file
@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief EDHOC coap initiator implementation
|
||||
*
|
||||
* @author Timothy Claeys <timothy.claeys@inria.fr>
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "net/ipv6.h"
|
||||
#include "net/nanocoap_sock.h"
|
||||
#include "shell.h"
|
||||
|
||||
#include "edhoc/edhoc.h"
|
||||
#include "edhoc_keys.h"
|
||||
|
||||
#if IS_USED(MODULE_WOLFSSL)
|
||||
#include "wolfssl/wolfcrypt/sha256.h"
|
||||
#elif IS_USED(MODULE_TINYCRYPT)
|
||||
#include "tinycrypt/sha256.h"
|
||||
#endif
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define COAP_BUF_SIZE (256U)
|
||||
|
||||
#if IS_ACTIVE(CONFIG_INITIATOR)
|
||||
|
||||
extern void print_bstr(const uint8_t *bstr, size_t bstr_len);
|
||||
extern int edhoc_setup(edhoc_ctx_t *ctx, edhoc_conf_t *conf, edhoc_role_t role,
|
||||
cose_key_t *auth_key, cred_id_t *cred_id, rpk_t *rpk,
|
||||
void *hash_ctx);
|
||||
extern void edhoc_oscore_exporter(edhoc_ctx_t *ctx, uint8_t *secret, size_t secret_len,
|
||||
uint8_t *salt, size_t salt_len);
|
||||
|
||||
static edhoc_ctx_t _ctx;
|
||||
static edhoc_conf_t _conf;
|
||||
static rpk_t _rpk;
|
||||
static cred_id_t _cred_id;
|
||||
static cose_key_t _auth_key;
|
||||
#if IS_USED(MODULE_WOLFSSL)
|
||||
static wc_Sha256 _sha_i;
|
||||
#elif IS_USED(MODULE_TINYCRYPT)
|
||||
struct tc_sha256_state_struct _sha_i;
|
||||
#endif
|
||||
static uint8_t _method;
|
||||
static uint8_t _suite;
|
||||
|
||||
static ssize_t _send(coap_pkt_t *pkt, size_t len, char *addr_str, uint16_t port)
|
||||
{
|
||||
ipv6_addr_t addr;
|
||||
sock_udp_ep_t remote;
|
||||
|
||||
remote.family = AF_INET6;
|
||||
remote.port = port;
|
||||
|
||||
/* parse for interface */
|
||||
char *iface = ipv6_addr_split_iface(addr_str);
|
||||
if (!iface) {
|
||||
if (gnrc_netif_numof() == 1) {
|
||||
/* assign the single interface found in gnrc_netif_numof() */
|
||||
remote.netif = (uint16_t)gnrc_netif_iter(NULL)->pid;
|
||||
}
|
||||
else {
|
||||
remote.netif = SOCK_ADDR_ANY_NETIF;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int pid = atoi(iface);
|
||||
if (gnrc_netif_get_by_pid(pid) == NULL) {
|
||||
puts("[initiator]: interface not valid");
|
||||
return 0;
|
||||
}
|
||||
remote.netif = pid;
|
||||
}
|
||||
|
||||
/* parse destination address */
|
||||
if (ipv6_addr_from_str(&addr, addr_str) == NULL) {
|
||||
puts("[initiator]: unable to parse destination address");
|
||||
return 0;
|
||||
}
|
||||
if ((remote.netif == SOCK_ADDR_ANY_NETIF) && ipv6_addr_is_link_local(&addr)) {
|
||||
puts("[initiator]: must specify interface for link local target");
|
||||
return 0;
|
||||
}
|
||||
memcpy(&remote.addr.ipv6[0], &addr.u8[0], sizeof(addr.u8));
|
||||
|
||||
return nanocoap_request(pkt, NULL, &remote, len);
|
||||
}
|
||||
|
||||
static ssize_t _build_coap_pkt(coap_pkt_t *pkt, uint8_t *buf, ssize_t buflen,
|
||||
uint8_t *payload, ssize_t payload_len)
|
||||
{
|
||||
uint8_t token[2] = { 0xDA, 0xEC };
|
||||
ssize_t len = 0;
|
||||
|
||||
/* set pkt buffer */
|
||||
pkt->hdr = (coap_hdr_t *)buf;
|
||||
/* build header, confirmed message always post */
|
||||
ssize_t hdrlen = coap_build_hdr(pkt->hdr, COAP_TYPE_CON, token,
|
||||
sizeof(token), COAP_METHOD_POST, 1);
|
||||
coap_pkt_init(pkt, buf, buflen, hdrlen);
|
||||
coap_opt_add_string(pkt, COAP_OPT_URI_PATH, "/.well-known/edhoc", '/');
|
||||
coap_opt_add_uint(pkt, COAP_OPT_CONTENT_FORMAT, COAP_FORMAT_OCTET);
|
||||
len = coap_opt_finish(pkt, COAP_OPT_FINISH_PAYLOAD);
|
||||
/* copy msg payload */
|
||||
pkt->payload_len = payload_len;
|
||||
memcpy(pkt->payload, payload, payload_len);
|
||||
len += pkt->payload_len;
|
||||
return len;
|
||||
}
|
||||
|
||||
int _handshake_cmd(int argc, char **argv)
|
||||
{
|
||||
uint8_t buf[COAP_BUF_SIZE] = { 0 };
|
||||
coap_pkt_t pkt;
|
||||
ssize_t len = 0;
|
||||
uint16_t port = COAP_PORT;
|
||||
uint8_t msg[COAP_BUF_SIZE];
|
||||
ssize_t msg_len = 0;
|
||||
|
||||
/* correlation value is transport specific */
|
||||
corr_t corr = CORR_1_2;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("usage: %s <addr>[%%iface] <port>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
if (argc == 3) {
|
||||
port = atoi(argv[2]);
|
||||
}
|
||||
|
||||
/* reset state */
|
||||
_ctx.state = EDHOC_WAITING;
|
||||
|
||||
if ((msg_len = edhoc_create_msg1(&_ctx, corr, _method, _suite, msg, sizeof(msg))) > 0) {
|
||||
printf("[initiator]: sending msg1 (%d bytes):\n", (int) msg_len);
|
||||
print_bstr(msg, msg_len);
|
||||
_build_coap_pkt(&pkt, buf, sizeof(buf), msg, msg_len);
|
||||
len = _send(&pkt, COAP_BUF_SIZE, argv[1], port);
|
||||
}
|
||||
else {
|
||||
puts("[initiator]: failed to create msg1");
|
||||
return -1;
|
||||
}
|
||||
if (len < 0) {
|
||||
puts("[initiator]: failed to send msg1");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("[initiator]: received a message (%d bytes):\n", pkt.payload_len);
|
||||
print_bstr(pkt.payload, pkt.payload_len);
|
||||
|
||||
if ((msg_len = edhoc_create_msg3(&_ctx, pkt.payload, pkt.payload_len, msg, sizeof(msg))) > 0) {
|
||||
printf("[initiator]: sending msg3 (%d bytes):\n", (int) msg_len);
|
||||
print_bstr(msg, msg_len);
|
||||
_build_coap_pkt(&pkt, buf, sizeof(buf), msg, msg_len);
|
||||
len = _send(&pkt, COAP_BUF_SIZE, argv[1], port);
|
||||
}
|
||||
else {
|
||||
puts("[initiator]: failed to create msg3");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (edhoc_init_finalize(&_ctx)) {
|
||||
puts("[initiator]: handshake failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
puts("[initiator]: handshake successfully completed");
|
||||
|
||||
printf("[initiator]: Transcript hash 4 (%d bytes):\n", EDHOC_DIGEST_SIZE);
|
||||
print_bstr(_ctx.session.th4, EDHOC_DIGEST_SIZE);
|
||||
|
||||
_ctx.state = EDHOC_FINALIZED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _print_initiator_usage(void)
|
||||
{
|
||||
puts("Usage:");
|
||||
puts("\tinit set method <sgn-sgn|sgn-stat|stat-sgn|stat-stat>:"
|
||||
" choose authentication method [initiator-responder]");
|
||||
puts("\tinit set suite <0|1>: choose cypher-suit, only 0 and 1 support");
|
||||
puts("\tinit handshake <addr>[%%iface] <port>: start handshake");
|
||||
puts("\tinit oscore: derive OSCORE secret and salt");
|
||||
}
|
||||
|
||||
static int _set_cmd(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
_print_initiator_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "method")) {
|
||||
if (!strcmp(argv[2], "sgn-sgn")) {
|
||||
_method = EDHOC_AUTH_SIGN_SIGN;
|
||||
}
|
||||
else if (!strcmp(argv[2], "sgn-stat")) {
|
||||
_method = EDHOC_AUTH_SIGN_STATIC;
|
||||
}
|
||||
else if (!strcmp(argv[2], "stat-sgn")) {
|
||||
_method = EDHOC_AUTH_STATIC_SIGN;
|
||||
}
|
||||
else if (!strcmp(argv[2], "stat-stat")) {
|
||||
_method = EDHOC_AUTH_STATIC_STATIC;
|
||||
}
|
||||
else {
|
||||
printf("error: invalid method %s, sgn-sgn|sgn-stat|stat-sgn|stat-stat\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "suite")) {
|
||||
uint8_t suite = atoi(argv[2]);
|
||||
if (suite > 1) {
|
||||
puts("error: only cypher suits 0 and 1 are supported");
|
||||
return -1;
|
||||
}
|
||||
_suite = suite;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int initiator_cmd(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
_print_initiator_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "set")) {
|
||||
return _set_cmd(argc - 1, &argv[1]);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "handshake")) {
|
||||
return _handshake_cmd(argc - 1, &argv[1]);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "oscore")) {
|
||||
if (_ctx.state == EDHOC_FINALIZED) {
|
||||
uint8_t secret[16];
|
||||
uint8_t salt[8];
|
||||
edhoc_oscore_exporter(&_ctx, secret, sizeof(secret), salt, sizeof(salt));
|
||||
}
|
||||
else {
|
||||
puts("error: perform edhoc handshake first");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int initiator_cli_init(void)
|
||||
{
|
||||
/* default to static-static (method 3) since we are using RPK keys */
|
||||
_method = EDHOC_AUTH_STATIC_STATIC;
|
||||
_suite = EDHOC_CIPHER_SUITE_0;
|
||||
if (edhoc_setup(&_ctx, &_conf, EDHOC_IS_INITIATOR, &_auth_key, &_cred_id,
|
||||
&_rpk, &_sha_i)) {
|
||||
puts("[initiator]: error during setup");
|
||||
return -1;
|
||||
}
|
||||
/* use fixed values only for testing purposes */
|
||||
puts("[initiator]: load ephemeral key: ONLY FOR TESTING");
|
||||
if (edhoc_load_ephkey(&_ctx, init_cbor_eph_key, sizeof(init_cbor_eph_key)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
puts("[initiator]: preset cid: ONLY FOR TESTING");
|
||||
if (edhoc_session_preset_cidi(&_ctx, init_cid, sizeof(init_cid)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_INITIATOR */
|
103
tests/pkg_edhoc_c/main.c
Normal file
103
tests/pkg_edhoc_c/main.c
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief EDHOC handhshake over COAP using EDHOC-C
|
||||
*
|
||||
* @author Timothy Claeys <timothy.claeys@inria.fr>
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "net/nanocoap_sock.h"
|
||||
#include "shell.h"
|
||||
#include "thread.h"
|
||||
|
||||
#include "edhoc/edhoc.h"
|
||||
#include "edhoc_keys.h"
|
||||
|
||||
#define MAIN_QUEUE_SIZE (4)
|
||||
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
|
||||
|
||||
#if IS_ACTIVE(CONFIG_RESPONDER)
|
||||
static char _nanocoap_server_stack[THREAD_STACKSIZE_MAIN];
|
||||
#define NANOCOAP_SERVER_QUEUE_SIZE (4)
|
||||
static msg_t _nanocoap_server_msg_queue[NANOCOAP_SERVER_QUEUE_SIZE];
|
||||
#define NANOCOAP_BUF_SIZE (512U)
|
||||
extern int responder_cli_init(void);
|
||||
extern int responder_cmd(int argc, char **argv);
|
||||
#endif
|
||||
|
||||
#if IS_ACTIVE(CONFIG_INITIATOR)
|
||||
extern int initiator_cmd(int argc, char **argv);
|
||||
extern int initiator_cli_init(void);
|
||||
#endif
|
||||
|
||||
static const shell_command_t shell_commands[] = {
|
||||
|
||||
#if IS_ACTIVE(CONFIG_INITIATOR)
|
||||
{ "init", "EDHOC Initiator cli", initiator_cmd },
|
||||
#endif
|
||||
#if IS_ACTIVE(CONFIG_RESPONDER)
|
||||
{ "resp", "EDHOC Responder cli", responder_cmd },
|
||||
#endif
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
#if IS_ACTIVE(CONFIG_RESPONDER)
|
||||
static void *_nanocoap_server_thread(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
/* nanocoap_server uses gnrc sock which uses gnrc which needs a msg queue */
|
||||
msg_init_queue(_nanocoap_server_msg_queue, NANOCOAP_SERVER_QUEUE_SIZE);
|
||||
|
||||
/* initialize nanocoap server instance */
|
||||
uint8_t buf[NANOCOAP_BUF_SIZE];
|
||||
sock_udp_ep_t local = { .port = COAP_PORT, .family = AF_INET6 };
|
||||
nanocoap_server(&local, buf, sizeof(buf));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
#if IS_ACTIVE(CONFIG_INITIATOR)
|
||||
if (initiator_cli_init()) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#if IS_ACTIVE(CONFIG_RESPONDER)
|
||||
if (responder_cli_init()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* start nanocoap server thread */
|
||||
thread_create(_nanocoap_server_stack, sizeof(_nanocoap_server_stack),
|
||||
THREAD_PRIORITY_MAIN - 1,
|
||||
THREAD_CREATE_STACKTEST,
|
||||
_nanocoap_server_thread, NULL, "nanocoap server");
|
||||
#endif
|
||||
|
||||
/* the shell contains commands that receive packets via GNRC and thus
|
||||
needs a msg queue */
|
||||
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
|
||||
|
||||
puts("Starting the shell");
|
||||
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||
|
||||
/* should be never reached */
|
||||
return 0;
|
||||
}
|
152
tests/pkg_edhoc_c/responder.c
Normal file
152
tests/pkg_edhoc_c/responder.c
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief EDHOC coap responder implementation
|
||||
*
|
||||
* @author Timothy Claeys <timothy.claeys@inria.fr>
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "net/ipv6.h"
|
||||
#include "net/nanocoap_sock.h"
|
||||
#include "shell.h"
|
||||
|
||||
#include "edhoc/edhoc.h"
|
||||
#include "edhoc_keys.h"
|
||||
|
||||
#if IS_USED(MODULE_WOLFSSL)
|
||||
#include "wolfssl/wolfcrypt/sha256.h"
|
||||
#elif IS_USED(MODULE_TINYCRYPT)
|
||||
#include "tinycrypt/sha256.h"
|
||||
#endif
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define COAP_BUF_SIZE (256U)
|
||||
|
||||
#if IS_ACTIVE(CONFIG_RESPONDER)
|
||||
|
||||
extern void print_bstr(const uint8_t *bstr, size_t bstr_len);
|
||||
extern int edhoc_setup(edhoc_ctx_t *ctx, edhoc_conf_t *conf, edhoc_role_t role,
|
||||
cose_key_t *auth_key, cred_id_t *cred_id, rpk_t *rpk,
|
||||
void *hash_ctx);
|
||||
extern void edhoc_oscore_exporter(edhoc_ctx_t *ctx, uint8_t *secret, size_t secret_len,
|
||||
uint8_t *salt, size_t salt_len);
|
||||
|
||||
static edhoc_ctx_t _ctx;
|
||||
static edhoc_conf_t _conf;
|
||||
static rpk_t _rpk;
|
||||
static cred_id_t _cred_id;
|
||||
static cose_key_t _auth_key;
|
||||
#if IS_USED(MODULE_WOLFSSL)
|
||||
static wc_Sha256 _sha_r;
|
||||
#elif IS_USED(MODULE_TINYCRYPT)
|
||||
struct tc_sha256_state_struct _sha_r;
|
||||
#endif
|
||||
|
||||
ssize_t _edhoc_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context)
|
||||
{
|
||||
(void)context;
|
||||
ssize_t msg_len = 0;
|
||||
|
||||
printf("[responder]: received an EDHOC message (len %d):\n", pkt->payload_len);
|
||||
print_bstr(pkt->payload, pkt->payload_len);
|
||||
|
||||
if (_ctx.state == EDHOC_FINALIZED || _ctx.state == EDHOC_FAILED) {
|
||||
_ctx.state = EDHOC_WAITING;
|
||||
}
|
||||
|
||||
if (_ctx.state == EDHOC_WAITING) {
|
||||
uint8_t msg[COAP_BUF_SIZE];
|
||||
if ((msg_len =
|
||||
edhoc_create_msg2(&_ctx, pkt->payload, pkt->payload_len, msg, sizeof(msg))) >= 0) {
|
||||
printf("[responder]: sending msg2 (%d bytes):\n", (int) msg_len);
|
||||
print_bstr(msg, msg_len);
|
||||
msg_len = coap_reply_simple(pkt, COAP_CODE_204, buf, len, COAP_FORMAT_OCTET, msg,
|
||||
msg_len);
|
||||
}
|
||||
else {
|
||||
puts("[responder]: failed to create msg2");
|
||||
coap_reply_simple(pkt, COAP_CODE_404, buf, len, COAP_FORMAT_TEXT, NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (_ctx.state == EDHOC_SENT_MESSAGE_2) {
|
||||
puts("[responder]: finalize exchange");
|
||||
edhoc_resp_finalize(&_ctx, pkt->payload, pkt->payload_len, false, NULL, 0);
|
||||
msg_len = coap_reply_simple(pkt, COAP_CODE_204, buf, len, COAP_FORMAT_OCTET, NULL, 0);
|
||||
}
|
||||
|
||||
if (_ctx.state == EDHOC_FINALIZED) {
|
||||
puts("[responder]: handshake successfully completed");
|
||||
}
|
||||
|
||||
return msg_len;
|
||||
}
|
||||
|
||||
/* must be sorted by path (ASCII order) */
|
||||
const coap_resource_t coap_resources[] = {
|
||||
COAP_WELL_KNOWN_CORE_DEFAULT_HANDLER,
|
||||
{ "/.well-known/edhoc", COAP_POST, _edhoc_handler, NULL },
|
||||
};
|
||||
|
||||
const unsigned coap_resources_numof = ARRAY_SIZE(coap_resources);
|
||||
|
||||
int responder_cmd(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
puts("Usage:");
|
||||
puts("\tresp oscore: derive OSCORE secret and salt");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "oscore")) {
|
||||
if (_ctx.state == EDHOC_FINALIZED) {
|
||||
uint8_t secret[16];
|
||||
uint8_t salt[8];
|
||||
edhoc_oscore_exporter(&_ctx, secret, sizeof(secret), salt, sizeof(salt));
|
||||
}
|
||||
else {
|
||||
puts("error: perform edhoc handshake first");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int responder_cli_init(void)
|
||||
{
|
||||
if (edhoc_setup(&_ctx, &_conf, EDHOC_IS_RESPONDER, &_auth_key, &_cred_id,
|
||||
&_rpk, &_sha_r)) {
|
||||
puts("[responder]: error during setup");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* use fixed values only for testing purposes */
|
||||
puts("[responder]: load ephemeral key: ONLY FOR TESTING");
|
||||
if (edhoc_load_ephkey(&_ctx, resp_cbor_eph_key, sizeof(resp_cbor_eph_key)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
puts("[responder]: preset cid: ONLY FOR TESTING");
|
||||
if (edhoc_session_preset_cidr(&_ctx, resp_cid, sizeof(resp_cid)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RESPONDER */
|
98
tests/pkg_edhoc_c/tests-with-config/01-run.py
Executable file
98
tests/pkg_edhoc_c/tests-with-config/01-run.py
Executable file
@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2021 Inria
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU Lesser
|
||||
# General Public License v2.1. See the file LICENSE in the top level
|
||||
# directory for more details.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from testrunner import run
|
||||
|
||||
# Default COAP port on which the edhoc responder is running
|
||||
COAP_PORT = int(os.getenv("COAP_PORT", "5683"))
|
||||
|
||||
LAKE_WG_EDHOC_TV_34900_MSG1 = \
|
||||
"0x0d 0x00 0x58 0x20 0x8d 0x3e 0xf5 0x6d\n" + \
|
||||
"0x1b 0x75 0x0a 0x43 0x51 0xd6 0x8a 0xc2\n" + \
|
||||
"0x50 0xa0 0xe8 0x83 0x79 0x0e 0xfc 0x80\n" + \
|
||||
"0xa5 0x38 0xa4 0x44 0xee 0x9e 0x2b 0x57\n" + \
|
||||
"0xe2 0x44 0x1a 0x7c 0x21"
|
||||
|
||||
LAKE_WG_EDHOC_TV_34900_MSG2 = \
|
||||
"0x58 0x20 0x52 0xfb 0xa0 0xbd 0xc8 0xd9\n" + \
|
||||
"0x53 0xdd 0x86 0xce 0x1a 0xb2 0xfd 0x7c\n" + \
|
||||
"0x05 0xa4 0x65 0x8c 0x7c 0x30 0xaf 0xdb\n" + \
|
||||
"0xfc 0x33 0x01 0x04 0x70 0x69 0x45 0x1b\n" + \
|
||||
"0xaf 0x35 0x37 0x4a 0xa3 0xf1 0xbd 0x5d\n" + \
|
||||
"0x02 0x8d 0x19 0xcf 0x3c 0x99"
|
||||
|
||||
LAKE_WG_EDHOC_TV_34900_MSG3 = \
|
||||
"0x37 0x52 0xd5 0x53 0x5f 0x31 0x47 0xe8\n" + \
|
||||
"0x5f 0x1c 0xfa 0xcd 0x9e 0x78 0xab 0xf9\n" + \
|
||||
"0xe0 0xa8 0x1b 0xbf"
|
||||
|
||||
LAKE_WG_EDHOC_TV_34900_TH4 = \
|
||||
"0x7c 0xcf 0xde 0xdc 0x2c 0x10 0xca 0x03\n" + \
|
||||
"0x56 0xe9 0x57 0xb9 0xf6 0xa5 0x92 0xe0\n" + \
|
||||
"0xfa 0x74 0xdb 0x2a 0xb5 0x4f 0x59 0x24\n" + \
|
||||
"0x40 0x96 0xf9 0xa2 0xac 0x56 0xd2 0x07"
|
||||
|
||||
LAKE_WG_EDHOC_TV_34900_OSCORE_SECRET = \
|
||||
"0x5b 0xb2 0xae 0xe2 0x5b 0x16 0x0e 0x7c\n" + \
|
||||
"0x6d 0x26 0x12 0xb0 0xa6 0x01 0x09 0x16"
|
||||
|
||||
LAKE_WG_EDHOC_TV_34900_OSCORE_SALT = \
|
||||
"0x8e 0x44 0x92 0x10 0xe0 0x3b 0xc2 0x9d"
|
||||
|
||||
|
||||
def get_ipv6_addr(child):
|
||||
child.expect_exact('>')
|
||||
child.sendline('ifconfig')
|
||||
# Get device local address
|
||||
child.expect(
|
||||
r"inet6\s+addr:\s+(?P<lladdr>[0-9a-fA-F:]+:[A-Fa-f:0-9]+)"
|
||||
" scope: link VAL"
|
||||
)
|
||||
|
||||
return child.match.group("lladdr").lower()
|
||||
|
||||
|
||||
def testfunc(child):
|
||||
child.sendline("init handshake {} {}".format(
|
||||
get_ipv6_addr(child), COAP_PORT))
|
||||
child.expect_exact("[initiator]: sending msg1 (37 bytes):")
|
||||
for line in LAKE_WG_EDHOC_TV_34900_MSG1.split('\n'):
|
||||
child.expect_exact(line)
|
||||
child.expect_exact("[responder]: received an EDHOC message (len 37):")
|
||||
child.expect_exact("[responder]: sending msg2 (46 bytes):")
|
||||
for line in LAKE_WG_EDHOC_TV_34900_MSG2.split('\n'):
|
||||
child.expect_exact(line)
|
||||
child.expect_exact("[initiator]: received a message (46 bytes):")
|
||||
child.expect_exact("[initiator]: sending msg3 (20 bytes)")
|
||||
for line in LAKE_WG_EDHOC_TV_34900_MSG3.split('\n'):
|
||||
child.expect_exact(line)
|
||||
child.expect_exact("[responder]: finalize exchange")
|
||||
child.expect_exact("[responder]: handshake successfully completed")
|
||||
child.expect_exact("[initiator]: handshake successfully completed")
|
||||
child.expect_exact("[initiator]: Transcript hash 4 (32 bytes):")
|
||||
for line in LAKE_WG_EDHOC_TV_34900_TH4.split('\n'):
|
||||
child.expect_exact(line)
|
||||
child.sendline("init oscore")
|
||||
child.expect_exact("OSCORE secret:")
|
||||
for line in LAKE_WG_EDHOC_TV_34900_OSCORE_SECRET.split('\n'):
|
||||
child.expect_exact(line)
|
||||
child.expect_exact("OSCORE salt:")
|
||||
child.expect_exact(LAKE_WG_EDHOC_TV_34900_OSCORE_SALT)
|
||||
child.sendline("resp oscore")
|
||||
child.expect_exact("OSCORE secret:")
|
||||
for line in LAKE_WG_EDHOC_TV_34900_OSCORE_SECRET.split('\n'):
|
||||
child.expect_exact(line)
|
||||
child.expect_exact("OSCORE salt:")
|
||||
child.expect_exact(LAKE_WG_EDHOC_TV_34900_OSCORE_SALT)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(run(testfunc))
|
Loading…
Reference in New Issue
Block a user