I2C toy code
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

5 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. # i2c-stub toy
  2. 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.
  3. # Requirements
  4. The solution needs to be implemented in C and have following functionalities
  5. * Possibility to connect to I2C slave
  6. * Send encrypted data
  7. * Receive and decrypt data
  8. * Possibility to check connection status
  9. # The code
  10. The code itself is here. To compilie with ``gcc`` simply download and ``make``.
  11. ## Initialization
  12. In order to use the code (read/write data to I2C) I'm using ``i2c-stub`` linux
  13. 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.
  14. Following command will load the module, initialize slave device with an address 0x03, and read it's initial state:
  15. ```
  16. > modprobe i2c-dev
  17. > modprobe i2c-stub chip_addr=0x03
  18. > i2cdetect -l
  19. i2c-1 i2c i915 gmbus dpc I2C adapter
  20. i2c-2 i2c i915 gmbus dpd I2C adapter
  21. ...
  22. i2c-8 smbus SMBus stub driver SMBus adapter <-- this one
  23. ...
  24. > i2cdump -y 8 0x03
  25. No size specified (using byte-data access)
  26. 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
  27. 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  28. 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  29. 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  30. 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  31. 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  32. 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  33. 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  34. 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  35. 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  36. 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  37. a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  38. b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  39. c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  40. d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  41. e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  42. f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  43. ```
  44. 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``.
  45. ## Sending data
  46. Test program has ``-s`` option that needs to be used in order to send data. As an argument, device ID needs to be provided.
  47. ```
  48. > ./bin/main -s 8 && echo $?
  49. 0
  50. ```
  51. On a success program return 0. We can now verify if data has been stored in the i2c device with ``i2cdump``.
  52. ```
  53. 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
  54. 00: 1f f8 47 8e 7f 24 1d 2b 47 ca 64 be ce 0a 3f bd ??G??$?+G?d?????
  55. 10: 08 1c 05 87 b0 31 6c 85 46 94 6f c8 9e 49 dd b2 ?????1l?F?o??I??
  56. 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  57. 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  58. 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  59. 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  60. 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  61. 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  62. 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  63. 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  64. a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  65. b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  66. c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  67. d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  68. e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  69. f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  70. ```
  71. Before sending program uses Poly1305-ChaCha20 to encrypt and authenticate data.
  72. ## Receiving data
  73. Test program has ``-r`` option to indicate that user want's to receive data from I2C device. On exit program prints received data.
  74. ```
  75. [root@cryptoden final]# ./bin/main -r 8
  76. RECEIVED DATA:
  77. HELLO WORLD!!!
  78. ```
  79. As data is authenticated any change to data stored in the I2C will result
  80. in decryption error. In order to see this behaviour one can dump the I2C
  81. memory, change it, load to I2C and try to read again. Let's see this:
  82. ```
  83. > i2cdump -y 8 0x03 b > dump
  84. > cat dump
  85. [root@cryptoden ~]# cat dump
  86. 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
  87. 00: 1f f8 47 8e 7f 24 1d 2b 47 ca 64 be ce 0a 3f bd ??G??$?+G?d?????
  88. 10: 08 1c 05 87 b0 31 6c 85 46 94 6f c8 9e 49 dd b3 ?????1l?F?o??I??
  89. 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  90. 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  91. 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  92. 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  93. 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  94. 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  95. 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  96. 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  97. a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  98. b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  99. c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  100. d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  101. e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  102. f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  103. ## Here I modify 32-nd byte from b3 to b2 and load data to i2c-stub
  104. > i2c-stub-from-dump 0x03 dump
  105. 256 byte values written to 8-0003
  106. ## Trying to read
  107. > ./bin/main -r 8
  108. [i2c_recv() src/i2c.c:165] Error occured when decrypting
  109. [i2c_recv() src/i2c.c:172] ERROR: can't receive encrypted data
  110. [test_receive() src/main.c:88] Error occured when receiving data
  111. ```
  112. ## Testing
  113. Program has a ``-t`` option which can be used to test program and see
  114. that connection stays persistent after connecting to the device.
  115. ```
  116. > ./bin/main -t 8 && echo $?
  117. 0
  118. ```