w1_ds28el15_sha256.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. /*
  2. * 1-Wire SHA256 software implementation for the ds23el15 chip
  3. *
  4. * Copyright (C) 2013 maximintergrated
  5. *
  6. *
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. *
  12. */
  13. #include <linux/string.h>
  14. #include <linux/memory.h>
  15. #include "w1_ds28el15_sha256.h"
  16. #define SHA_256_INITIAL_LENGTH 8
  17. #define TRUE 1
  18. #define FALSE 0
  19. // SHA-256 Functions
  20. int compute_sha256(uchar* message, short length, ushort skipconst, ushort reverse, uchar* digest);
  21. int compute_mac256(uchar* message, short length, uchar* MAC);
  22. int verify_mac256(uchar* message, short length, uchar* compare_MAC);
  23. int calculate_nextsecret256(uchar* binding, uchar* partial, int page_num, uchar* manid);
  24. void set_secret(uchar *secret_data);
  25. void set_romid(uchar *romid_data);
  26. // Utility Functions
  27. ulong sha_ch(ulong x, ulong y, ulong z);
  28. ulong sha_maj(ulong x, ulong y, ulong z);
  29. ulong sha_rotr_32(ulong val, ushort r);
  30. ulong sha_shr_32(ulong val, ushort r);
  31. ulong sha_bigsigma256_0(ulong x);
  32. ulong sha_littlesigma256_0(ulong x);
  33. ulong sha_littlesigma256_1(ulong x);
  34. void sha_copy32(ulong* p1, ulong* p2, ushort length);
  35. void sha_copyWordsToBytes32(ulong* input, uchar* output, ushort numwords);
  36. void sha_writeResult(ushort reverse, uchar* outpointer);
  37. ulong sha_getW(int index);
  38. void sha_prepareSchedule(uchar* message);
  39. void sha256_hashblock(uchar* message, ushort lastblock);
  40. // hold secret for creating a
  41. static uchar secret[32];
  42. uchar rom_no[8];
  43. // SHA-256 globals values
  44. ulong SHA_256_Initial[] =
  45. {
  46. 0x6a09e667,
  47. 0xbb67ae85,
  48. 0x3c6ef372,
  49. 0xa54ff53a,
  50. 0x510e527f,
  51. 0x9b05688c,
  52. 0x1f83d9ab,
  53. 0x5be0cd19
  54. };
  55. ulong SHA_CONSTANTS[] =
  56. {
  57. 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  58. 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  59. 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  60. 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  61. 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  62. 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  63. 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  64. 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
  65. 0xca273ece, 0xd186b8c7, 0xeada7dd6, 0xf57d4f7f, 0x06f067aa, 0x0a637dc5, 0x113f9804, 0x1b710b35,
  66. 0x28db77f5, 0x32caab7b, 0x3c9ebe0a, 0x431d67c4, 0x4cc5d4be, 0x597f299c, 0x5fcb6fab, 0x6c44198c
  67. };
  68. uchar workbuffer[128];
  69. ulong a32, b32, c32, d32, e32, f32, g32, h32; // SHA working variables
  70. ulong W32[16]; // SHA message schedule
  71. ulong H32[8]; // last SHA result variables
  72. int reverse_endian=1;
  73. int sha_debug=0;
  74. //----------------------------------------------------------------------
  75. // Set the Secret to be used for calculating MAC's in the ComputeMAC
  76. // function.
  77. //
  78. void set_secret(uchar *secret_data)
  79. {
  80. int i;
  81. for (i = 0; i < 32; i++)
  82. secret[i] = secret_data[i];
  83. }
  84. //----------------------------------------------------------------------
  85. // Set the Secret to be used for calculating MAC's in the ComputeMAC
  86. // function.
  87. //
  88. void set_romid(uchar *romid_data)
  89. {
  90. int i;
  91. for (i = 0; i < 8; i++)
  92. rom_no[i] = romid_data[i];
  93. }
  94. //----------------------------------------------------------------------
  95. // Computes SHA-256 given the MT digest buffer after first inserting
  96. // the secret at the correct location in the array defined by all Maxim
  97. // devices. Since part of the input is secret it is called a Message
  98. // Autnentication Code (MAC).
  99. //
  100. // 'MT' - buffer containing the message digest
  101. // 'length' - Length of block to digest
  102. // 'MAC' - result MAC in byte order used by 1-Wire device
  103. //
  104. int compute_mac256(uchar* MT, short length, uchar* MAC)
  105. {
  106. int i,j;
  107. uchar tmp[4];
  108. // check for two block format
  109. if (length == 119)
  110. {
  111. // insert secret
  112. memcpy(&MT[64], &secret[0], 32);
  113. // change to little endian for A1 devices
  114. if (reverse_endian)
  115. {
  116. for (i = 0; i < 108; i+=4)
  117. {
  118. for (j = 0; j < 4; j++)
  119. tmp[3 - j] = MT[i + j];
  120. for (j = 0; j < 4; j++)
  121. MT[i + j] = tmp[j];
  122. }
  123. }
  124. compute_sha256(MT, 119, TRUE, TRUE, MAC);
  125. }
  126. // one block format
  127. else
  128. {
  129. // insert secret
  130. memcpy(&MT[0], &secret[0], 32);
  131. // change to little endian for A1 devices
  132. if (reverse_endian)
  133. {
  134. for (i = 0; i < 56; i+=4)
  135. {
  136. for (j = 0; j < 4; j++)
  137. tmp[3 - j] = MT[i + j];
  138. for (j = 0; j < 4; j++)
  139. MT[i + j] = tmp[j];
  140. }
  141. }
  142. compute_sha256(MT, 55, TRUE, TRUE, MAC);
  143. }
  144. return TRUE;
  145. }
  146. //----------------------------------------------------------------------
  147. // Computes SHA-256 given the MT digest buffer after first iserting
  148. // the secret at the correct location in the array defined by all Maxim
  149. // devices. Since part of the input is secret it is called a Message
  150. // Autnentication Code (MAC).
  151. //
  152. // 'MT' - buffer containing the message digest
  153. // 'length' - Length of block to digest
  154. // 'compare_MAC' - MAC in byte order used by 1-Wire device to compare
  155. // with calculate MAC.
  156. //
  157. int verify_mac256(uchar* MT, short length, uchar* compare_MAC)
  158. {
  159. uchar calc_mac[32];
  160. int i;
  161. // calculate the MAC
  162. compute_mac256(MT, length, calc_mac);
  163. // Compare calculated mac with one read from device
  164. for (i = 0; i < 32; i++)
  165. {
  166. if (compare_MAC[i] != calc_mac[i])
  167. return FALSE;
  168. }
  169. return TRUE;
  170. }
  171. //----------------------------------------------------------------------
  172. // Performs a Compute Next SHA-256 calculation given the provided 32-bytes
  173. // of binding data and 8 byte partial secret. The first 8 bytes of the
  174. // resulting MAC is set as the new secret.
  175. //
  176. // 'binding' - 32 byte buffer containing the binding data
  177. // 'partial' - 8 byte buffer with new partial secret
  178. // 'page_num' - page number that the compute is calculated on
  179. // 'manid' - manufacturer ID
  180. //
  181. // Globals used : secret used in calculation and set to new secret
  182. //
  183. // Returns: TRUE if compute successful
  184. // FALSE failed to do compute
  185. //
  186. int calculate_nextsecret256(uchar* binding, uchar* partial, int page_num, uchar* manid)
  187. {
  188. uchar MT[128];
  189. uchar MAC[64];
  190. // clear
  191. memset(MT,0,128);
  192. // insert page data
  193. memcpy(&MT[0],binding,32);
  194. // insert challenge
  195. memcpy(&MT[32],partial,32);
  196. // insert ROM number or FF
  197. memcpy(&MT[96],rom_no,8);
  198. MT[106] = page_num;
  199. MT[105] = manid[0];
  200. MT[104] = manid[1];
  201. compute_mac256(MT, 119, MAC);
  202. // set the new secret to the first 32 bytes of MAC
  203. set_secret(MAC);
  204. return TRUE;
  205. }
  206. //----------------------------------------------------------------------
  207. // SHA-256 support function
  208. //
  209. ulong sha_ch(ulong x, ulong y, ulong z)
  210. {
  211. return (x & y) ^ ((~x) & z);
  212. }
  213. //----------------------------------------------------------------------
  214. // SHA-256 support function
  215. //
  216. ulong sha_maj(ulong x, ulong y, ulong z)
  217. {
  218. ulong temp = x & y;
  219. temp ^= (x & z);
  220. temp ^= (y & z);
  221. return temp; //(x & y) ^ (x & z) ^ (y & z);
  222. }
  223. //----------------------------------------------------------------------
  224. // SHA-256 support function
  225. //
  226. ulong sha_rotr_32(ulong val, ushort r)
  227. {
  228. val = val & 0xFFFFFFFFL;
  229. return ((val >> r) | (val << (32 - r))) & 0xFFFFFFFFL;
  230. }
  231. //----------------------------------------------------------------------
  232. // SHA-256 support function
  233. //
  234. ulong sha_shr_32(ulong val, ushort r)
  235. {
  236. val = val & 0xFFFFFFFFL;
  237. return val >> r;
  238. }
  239. //----------------------------------------------------------------------
  240. // SHA-256 support function
  241. //
  242. ulong sha_bigsigma256_0(ulong x)
  243. {
  244. return sha_rotr_32(x,2) ^ sha_rotr_32(x,13) ^ sha_rotr_32(x,22);
  245. }
  246. //----------------------------------------------------------------------
  247. // SHA-256 support function
  248. //
  249. ulong sha_bigsigma256_1(ulong x)
  250. {
  251. return sha_rotr_32(x,6) ^ sha_rotr_32(x,11) ^ sha_rotr_32(x,25);
  252. }
  253. //----------------------------------------------------------------------
  254. // SHA-256 support function
  255. //
  256. ulong sha_littlesigma256_0(ulong x)
  257. {
  258. return sha_rotr_32(x,7) ^ sha_rotr_32(x,18) ^ sha_shr_32(x,3);
  259. }
  260. //----------------------------------------------------------------------
  261. // SHA-256 support function
  262. //
  263. ulong sha_littlesigma256_1(ulong x)
  264. {
  265. return sha_rotr_32(x,17) ^ sha_rotr_32(x,19) ^ sha_shr_32(x,10);
  266. }
  267. //----------------------------------------------------------------------
  268. // SHA-256 support function
  269. //
  270. void sha_copy32(ulong* p1, ulong* p2, ushort length)
  271. {
  272. while (length > 0)
  273. {
  274. *p2++ = *p1++;
  275. length--;
  276. }
  277. }
  278. //----------------------------------------------------------------------
  279. // SHA-256 support function
  280. //
  281. void sha_copyWordsToBytes32(ulong* input, uchar* output, ushort numwords)
  282. {
  283. ulong temp;
  284. ushort i;
  285. for (i=0;i<numwords;i++)
  286. {
  287. temp = *input++;
  288. *output++ = (uchar)(temp >> 24);
  289. *output++ = (uchar)(temp >> 16);
  290. *output++ = (uchar)(temp >> 8);
  291. *output++ = (uchar)(temp);
  292. }
  293. }
  294. //----------------------------------------------------------------------
  295. // SHA-256 support function
  296. //
  297. void sha_writeResult(ushort reverse, uchar* outpointer)
  298. {
  299. int i;
  300. uchar tmp;
  301. sha_copyWordsToBytes32(H32, outpointer, 8);
  302. if (reverse)
  303. {
  304. for (i = 0; i < 16; i++)
  305. {
  306. tmp = outpointer[i];
  307. outpointer[i] = outpointer[31-i];
  308. outpointer[31-i] = tmp;
  309. }
  310. }
  311. }
  312. //----------------------------------------------------------------------
  313. // SHA-256 support function
  314. //
  315. ulong sha_getW(int index)
  316. {
  317. ulong newW;
  318. if (index < 16)
  319. {
  320. return W32[index];
  321. }
  322. newW = sha_littlesigma256_1(W32[(index-2)&0x0f]) +
  323. W32[(index-7)&0x0f] +
  324. sha_littlesigma256_0(W32[(index-15)&0x0f]) +
  325. W32[(index-16)&0x0f];
  326. W32[index & 0x0f] = newW & 0xFFFFFFFFL; // just in case...
  327. return newW;
  328. }
  329. //----------------------------------------------------------------------
  330. // Prepair the block for hashing
  331. //
  332. void sha_prepareSchedule(uchar* message)
  333. {
  334. // we need to copy the initial message into the 16 W registers
  335. ushort i,j;
  336. ulong temp;
  337. for (i = 0; i < 16; i++)
  338. {
  339. temp = 0;
  340. for (j = 0; j < 4;j++)
  341. {
  342. temp = temp << 8;
  343. temp = temp | (*message & 0xff);
  344. message++;
  345. }
  346. W32[i] = temp;
  347. }
  348. }
  349. //----------------------------------------------------------------------
  350. // Hash a single block of data.
  351. //
  352. void sha256_hashblock(uchar* message, ushort lastblock)
  353. {
  354. ushort sha1counter = 0;
  355. ushort sha1functionselect = 0;
  356. ushort i;
  357. ulong nodeT1, nodeT2;
  358. ulong Wt, Kt;
  359. // chunk the original message into the working schedule
  360. sha_prepareSchedule(message);
  361. a32 = H32[0];
  362. b32 = H32[1];
  363. c32 = H32[2];
  364. d32 = H32[3];
  365. e32 = H32[4];
  366. f32 = H32[5];
  367. g32 = H32[6];
  368. h32 = H32[7];
  369. // rounds
  370. for (i = 0; i < 64; i++)
  371. {
  372. Wt = sha_getW(i);
  373. Kt = SHA_CONSTANTS[i];
  374. nodeT1 = (h32 + sha_bigsigma256_1(e32) + sha_ch(e32,f32,g32) + Kt + Wt); // & 0xFFFFFFFFL;
  375. nodeT2 = (sha_bigsigma256_0(a32) + sha_maj(a32,b32,c32)); // & 0xFFFFFFFFL;
  376. h32 = g32;
  377. g32 = f32;
  378. f32 = e32;
  379. e32 = d32 + nodeT1;
  380. d32 = c32;
  381. c32 = b32;
  382. b32 = a32;
  383. a32 = nodeT1 + nodeT2;
  384. sha1counter++;
  385. if (sha1counter==20)
  386. {
  387. sha1functionselect++;
  388. sha1counter = 0;
  389. }
  390. }
  391. if (!lastblock)
  392. {
  393. // now fix up our H array
  394. H32[0] += a32;
  395. H32[1] += b32;
  396. H32[2] += c32;
  397. H32[3] += d32;
  398. H32[4] += e32;
  399. H32[5] += f32;
  400. H32[6] += g32;
  401. H32[7] += h32;
  402. }
  403. else
  404. {
  405. // now fix up our H array
  406. H32[0] = a32;
  407. H32[1] = b32;
  408. H32[2] = c32;
  409. H32[3] = d32;
  410. H32[4] = e32;
  411. H32[5] = f32;
  412. H32[6] = g32;
  413. H32[7] = h32;
  414. }
  415. }
  416. //----------------------------------------------------------------------
  417. // Computes SHA-256 given the data block 'message' with no padding.
  418. // The result is returned in 'digest'.
  419. //
  420. // 'message' - buffer containing the message
  421. // 'skipconst' - skip adding constant on last block (skipconst=1)
  422. // 'reverse' - reverse order of digest (reverse=1, MSWord first, LSByte first)
  423. // 'digest' - result hash digest in byte order used by 1-Wire device
  424. //
  425. int compute_sha256(uchar* message, short length, ushort skipconst, ushort reverse, uchar* digest)
  426. {
  427. ushort bytes_per_block;
  428. ushort nonpaddedlength;
  429. ushort numblocks;
  430. ushort i,j;
  431. ulong bitlength;
  432. ushort markerwritten;
  433. ushort lastblock;
  434. ushort wordsize = 32;
  435. if (sha_debug)
  436. {
  437. printk(KERN_INFO "\nSHA-256 INPUT:\n");
  438. for (i = 0; i < length; i+=4)
  439. {
  440. for (j = 0; j < 4; j++)
  441. printk(KERN_INFO "%02X ",message[i+j]);
  442. printk(KERN_INFO "\n");
  443. }
  444. printk(KERN_INFO "\n");
  445. }
  446. // if wordsize is 32 bits, we need 512 bit blocks. else 1024 bit blocks.
  447. // that means 16 words are in one message.
  448. bytes_per_block = 16 * (wordsize / 8);
  449. // 1 byte for the '80' that follows the message, 8 or 16 bytes of length
  450. nonpaddedlength = length + 1 + (wordsize/4);
  451. numblocks = nonpaddedlength / bytes_per_block;
  452. if ((nonpaddedlength % bytes_per_block) != 0)
  453. {
  454. // then there is some remainder we need to pad
  455. numblocks++;
  456. }
  457. sha_copy32(SHA_256_Initial, H32, SHA_256_INITIAL_LENGTH);
  458. bitlength = 8 * length;
  459. markerwritten = 0;
  460. // 'length' is our number of bytes remaining.
  461. for (i = 0; i < numblocks; i++)
  462. {
  463. if (length > bytes_per_block)
  464. {
  465. memcpy(workbuffer, message, bytes_per_block);
  466. length -= bytes_per_block;
  467. }
  468. else if (length==bytes_per_block)
  469. {
  470. memcpy(workbuffer, message, length);
  471. length = 0;
  472. }
  473. else // length is less than number of bytes in a block
  474. {
  475. memcpy(workbuffer, message, length);
  476. // message is now used for temporary space
  477. message = workbuffer + length;
  478. if (markerwritten == 0)
  479. {
  480. *message++ = 0x80;
  481. length++;
  482. }
  483. while (length < bytes_per_block)
  484. {
  485. // this loop is inserting padding, in this case all zeroes
  486. *message++ = 0;
  487. length++;
  488. }
  489. length = 0;
  490. // signify that we have already written the 80h
  491. markerwritten = 1;
  492. }
  493. // on the last block, put the bit length at the very end
  494. lastblock = (i == (numblocks - 1));
  495. if (lastblock)
  496. {
  497. // point at the last byte in the block
  498. message = workbuffer + bytes_per_block - 1;
  499. for (j = 0; j < wordsize/4; j++)
  500. {
  501. *message-- = (uchar)bitlength;
  502. bitlength = bitlength >> 8;
  503. }
  504. }
  505. // SHA in software
  506. sha256_hashblock(workbuffer, (ushort)(lastblock && skipconst));
  507. message += bytes_per_block;
  508. }
  509. sha_writeResult(reverse, digest);
  510. if (sha_debug)
  511. {
  512. printk(KERN_INFO "\nSHA-256 Result:\n");
  513. for (i = 0; i < 32; i++)
  514. printk(KERN_INFO "%02X ",digest[i]);
  515. printk(KERN_INFO "\n");
  516. }
  517. return TRUE;
  518. }