Smart-Home am Beispiel der Präsenzerkennung im Raum Projektarbeit Lennart Heimbs, Johannes Krug, Sebastian Dohle und Kevin Holzschuh bei Prof. Oliver Hofmann SS2019
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MyCryptoGeneric.cpp 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*
  2. * The MySensors Arduino library handles the wireless radio link and protocol
  3. * between your home built sensors/actuators and HA controller of choice.
  4. * The sensors forms a self healing radio network with optional repeaters. Each
  5. * repeater and gateway builds a routing tables in EEPROM which keeps track of the
  6. * network topology allowing messages to be routed to nodes.
  7. *
  8. * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
  9. * Copyright (C) 2013-2018 Sensnology AB
  10. * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
  11. *
  12. * Documentation: http://www.mysensors.org
  13. * Support Forum: http://forum.mysensors.org
  14. *
  15. * This program is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU General Public License
  17. * version 2 as published by the Free Software Foundation.
  18. */
  19. #include "MyCryptoGeneric.h"
  20. const uint32_t SHA256K[] PROGMEM = {
  21. 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
  22. 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
  23. 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
  24. 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
  25. 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
  26. 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
  27. 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
  28. 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
  29. };
  30. const uint8_t SHA256InitState[] PROGMEM = {
  31. 0x67,0xe6,0x09,0x6a, // H0
  32. 0x85,0xae,0x67,0xbb, // H1
  33. 0x72,0xf3,0x6e,0x3c, // H2
  34. 0x3a,0xf5,0x4f,0xa5, // H3
  35. 0x7f,0x52,0x0e,0x51, // H4
  36. 0x8c,0x68,0x05,0x9b, // H5
  37. 0xab,0xd9,0x83,0x1f, // H6
  38. 0x19,0xcd,0xe0,0x5b // H7
  39. };
  40. _SHA256buffer_t SHA256buffer;
  41. uint8_t SHA256bufferOffset;
  42. _SHA256state_t SHA256state;
  43. uint32_t SHA256byteCount;
  44. uint8_t SHA256keyBuffer[BLOCK_LENGTH];
  45. void SHA256Init(void)
  46. {
  47. (void)memcpy_P((void *)&SHA256state.b, (const void *)&SHA256InitState, 32);
  48. SHA256byteCount = 0;
  49. SHA256bufferOffset = 0;
  50. }
  51. uint32_t SHA256ror32(const uint32_t number, const uint8_t bits)
  52. {
  53. return ((number << (32 - bits)) | (number >> bits));
  54. }
  55. void SHA256hashBlock(void)
  56. {
  57. uint32_t a, b, c, d, e, f, g, h, t1, t2;
  58. a = SHA256state.w[0];
  59. b = SHA256state.w[1];
  60. c = SHA256state.w[2];
  61. d = SHA256state.w[3];
  62. e = SHA256state.w[4];
  63. f = SHA256state.w[5];
  64. g = SHA256state.w[6];
  65. h = SHA256state.w[7];
  66. for (uint8_t i = 0; i < 64; i++) {
  67. if (i >= 16) {
  68. t1 = SHA256buffer.w[i & 15] + SHA256buffer.w[(i - 7) & 15];
  69. t2 = SHA256buffer.w[(i - 2) & 15];
  70. t1 += SHA256ror32(t2, 17) ^ SHA256ror32(t2, 19) ^ (t2 >> 10);
  71. t2 = SHA256buffer.w[(i - 15) & 15];
  72. t1 += SHA256ror32(t2, 7) ^ SHA256ror32(t2, 18) ^ (t2 >> 3);
  73. SHA256buffer.w[i & 15] = t1;
  74. }
  75. t1 = h;
  76. t1 += SHA256ror32(e, 6) ^ SHA256ror32(e, 11) ^ SHA256ror32(e, 25); // ∑1(e)
  77. t1 += g ^ (e & (g ^ f)); // Ch(e,f,g)
  78. t1 += pgm_read_dword(SHA256K + i); // Ki
  79. t1 += SHA256buffer.w[i & 15]; // Wi
  80. t2 = SHA256ror32(a, 2) ^ SHA256ror32(a, 13) ^ SHA256ror32(a, 22); // ∑0(a)
  81. t2 += ((b & c) | (a & (b | c))); // Maj(a,b,c)
  82. h = g;
  83. g = f;
  84. f = e;
  85. e = d + t1;
  86. d = c;
  87. c = b;
  88. b = a;
  89. a = t1 + t2;
  90. }
  91. SHA256state.w[0] += a;
  92. SHA256state.w[1] += b;
  93. SHA256state.w[2] += c;
  94. SHA256state.w[3] += d;
  95. SHA256state.w[4] += e;
  96. SHA256state.w[5] += f;
  97. SHA256state.w[6] += g;
  98. SHA256state.w[7] += h;
  99. }
  100. void SHA256addUncounted(const uint8_t data)
  101. {
  102. SHA256buffer.b[SHA256bufferOffset ^ 3] = data;
  103. SHA256bufferOffset++;
  104. if (SHA256bufferOffset == BLOCK_LENGTH) {
  105. SHA256hashBlock();
  106. SHA256bufferOffset = 0;
  107. }
  108. }
  109. void SHA256Add(const uint8_t data)
  110. {
  111. SHA256byteCount++;
  112. SHA256addUncounted(data);
  113. }
  114. void SHA256Add(const uint8_t *data, size_t dataLength)
  115. {
  116. while (dataLength--) {
  117. SHA256Add(*data++);
  118. }
  119. }
  120. void SHA256Result(uint8_t *dest)
  121. {
  122. // Pad to complete the last block
  123. SHA256addUncounted(0x80);
  124. while (SHA256bufferOffset != 56) {
  125. SHA256addUncounted(0x00);
  126. }
  127. // Append length in the last 8 bytes
  128. SHA256addUncounted(0); // We're only using 32 bit lengths
  129. SHA256addUncounted(0); // But SHA-1 supports 64 bit lengths
  130. SHA256addUncounted(0); // So zero pad the top bits
  131. SHA256addUncounted(SHA256byteCount >> 29); // Shifting to multiply by 8
  132. SHA256addUncounted(SHA256byteCount >> 21); // as SHA-1 supports bitstreams as well as
  133. SHA256addUncounted(SHA256byteCount >> 13); // byte.
  134. SHA256addUncounted(SHA256byteCount >> 5);
  135. SHA256addUncounted(SHA256byteCount << 3);
  136. // Swap byte order back
  137. for (uint8_t i = 0; i<8; i++) {
  138. uint32_t a, b;
  139. a = SHA256state.w[i];
  140. b = a << 24;
  141. b |= (a << 8) & 0x00ff0000;
  142. b |= (a >> 8) & 0x0000ff00;
  143. b |= a >> 24;
  144. SHA256state.w[i] = b;
  145. }
  146. (void)memcpy((void *)dest, (const void *)SHA256state.b, 32);
  147. // Return pointer to hash (20 characters)
  148. //return SHA256state.b;
  149. }
  150. void SHA256(uint8_t *dest, const uint8_t *data, size_t dataLength)
  151. {
  152. SHA256Init();
  153. SHA256Add(data, dataLength);
  154. SHA256Result(dest);
  155. }
  156. // SHA256HMAC
  157. void SHA256HMACInit(const uint8_t *key, size_t keyLength)
  158. {
  159. (void)memset((void *)&SHA256keyBuffer, 0x00, BLOCK_LENGTH);
  160. if (keyLength > BLOCK_LENGTH) {
  161. // Hash long keys
  162. SHA256Init();
  163. SHA256Add(key, keyLength);
  164. SHA256Result(SHA256keyBuffer);
  165. } else {
  166. // Block length keys are used as is
  167. (void)memcpy((void *)SHA256keyBuffer, (const void *)key, keyLength);
  168. }
  169. // Start inner hash
  170. SHA256Init();
  171. for (uint8_t i = 0; i < BLOCK_LENGTH; i++) {
  172. SHA256Add(SHA256keyBuffer[i] ^ HMAC_IPAD);
  173. }
  174. }
  175. void SHA256HMACAdd(const uint8_t data)
  176. {
  177. SHA256Add(data);
  178. }
  179. void SHA256HMACAdd(const uint8_t *data, size_t dataLength)
  180. {
  181. SHA256Add(data, dataLength);
  182. }
  183. void SHA256HMACResult(uint8_t *dest)
  184. {
  185. uint8_t innerHash[HASH_LENGTH];
  186. // Complete inner hash
  187. SHA256Result(innerHash);
  188. // Calculate outer hash
  189. SHA256Init();
  190. for (uint8_t i = 0; i < BLOCK_LENGTH; i++) {
  191. SHA256Add(SHA256keyBuffer[i] ^ HMAC_OPAD);
  192. }
  193. SHA256Add(innerHash, HASH_LENGTH);
  194. SHA256Result(dest);
  195. }
  196. void SHA256HMAC(uint8_t *dest, const uint8_t *key, size_t keyLength, const uint8_t *data,
  197. size_t dataLength)
  198. {
  199. SHA256HMACInit(key, keyLength);
  200. SHA256HMACAdd(data, dataLength);
  201. SHA256HMACResult(dest);
  202. }