|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- # i2c-stub toy
-
- Recently I had a chance to play with ``i2c-stub``. The goal was to send and receive encrypted data to/from I2C connected device. I didn't want to play with real I2C device, so I needed to emulate it somehow, which is possible with ``i2c-stub`` on linux. Here below is description how it was done.
-
- # Requirements
-
- The solution needs to be implemented in C and have following functionalities
- * Possibility to connect to I2C slave
- * Send encrypted data
- * Receive and decrypt data
- * Possibility to check connection status
-
- # The code
-
- The code itself is here. To compilie with ``gcc`` simply download and ``make``.
-
- ## Initialization
-
- In order to use the code (read/write data to I2C) I'm using ``i2c-stub`` linux
- module and i2c-tools package (ArchLinux). ``i2c-stub`` creates a fake I2C adapter(Controller/Master) and emulates i2C hardware (using array to store data). We also will need ``i2c-dev`` module as a frontend.
-
- Following command will load the module, initialize slave device with an address 0x03, and read it's initial state:
-
- ```
- > modprobe i2c-dev
- > modprobe i2c-stub chip_addr=0x03
-
- > i2cdetect -l
- i2c-1 i2c i915 gmbus dpc I2C adapter
- i2c-2 i2c i915 gmbus dpd I2C adapter
- ...
- i2c-8 smbus SMBus stub driver SMBus adapter <-- this one
- ...
-
- > i2cdump -y 8 0x03
- No size specified (using byte-data access)
- 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
- 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
-
- ```
-
- We can see that module was loaded. ``i2cdetect`` as detected is as a character device ``/dev/i2c-8`` and ``i2c-dump`` shows memory state of slave device with an ID ``0x03``.
-
-
- ## Sending data
-
- Test program has ``-s`` option that needs to be used in order to send data. As an argument, device ID needs to be provided.
-
- ```
- > ./bin/main -s 8 && echo $?
- 0
- ```
-
- On a success program return 0. We can now verify if data has been stored in the i2c device with ``i2cdump``.
-
- ```
- 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
- 00: 1f f8 47 8e 7f 24 1d 2b 47 ca 64 be ce 0a 3f bd ??G??$?+G?d?????
- 10: 08 1c 05 87 b0 31 6c 85 46 94 6f c8 9e 49 dd b2 ?????1l?F?o??I??
- 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- ```
-
- Before sending program uses Poly1305-ChaCha20 to encrypt and authenticate data.
-
- ## Receiving data
-
- Test program has ``-r`` option to indicate that user want's to receive data from I2C device. On exit program prints received data.
-
- ```
- [root@cryptoden final]# ./bin/main -r 8
- RECEIVED DATA:
- HELLO WORLD!!!
- ```
-
- As data is authenticated any change to data stored in the I2C will result
- in decryption error. In order to see this behaviour one can dump the I2C
- memory, change it, load to I2C and try to read again. Let's see this:
-
- ```
- > i2cdump -y 8 0x03 b > dump
- > cat dump
- [root@cryptoden ~]# cat dump
- 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
- 00: 1f f8 47 8e 7f 24 1d 2b 47 ca 64 be ce 0a 3f bd ??G??$?+G?d?????
- 10: 08 1c 05 87 b0 31 6c 85 46 94 6f c8 9e 49 dd b3 ?????1l?F?o??I??
- 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
-
- ## Here I modify 32-nd byte from b3 to b2 and load data to i2c-stub
- > i2c-stub-from-dump 0x03 dump
- 256 byte values written to 8-0003
-
- ## Trying to read
- > ./bin/main -r 8
- [i2c_recv() src/i2c.c:165] Error occured when decrypting
- [i2c_recv() src/i2c.c:172] ERROR: can't receive encrypted data
- [test_receive() src/main.c:88] Error occured when receiving data
- ```
-
-
- ## Testing
- Program has a ``-t`` option which can be used to test program and see
- that connection stays persistent after connecting to the device.
-
- ```
- > ./bin/main -t 8 && echo $?
- 0
- ```
|