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.
 
 
 
 
 

627 lines
18 KiB

  1. /**
  2. * @cond internal
  3. * @file shake.c
  4. * @copyright
  5. * Uses public domain code by Mathias Panzenböck \n
  6. * Uses CC0 code by David Leon Gil, 2015 \n
  7. * Copyright (c) 2015 Cryptography Research, Inc. \n
  8. * Released under the MIT License. See LICENSE.txt for license information.
  9. * @author Mike Hamburg
  10. * @brief SHA-3-n and SHAKE-n instances.
  11. * @warning EXPERIMENTAL! The names, parameter orders etc are likely to change.
  12. */
  13. #define __STDC_WANT_LIB_EXT1__ 1 /* for memset_s */
  14. #define _BSD_SOURCE 1 /* for endian */
  15. #include <assert.h>
  16. #include <stdint.h>
  17. #include <string.h>
  18. /* to open and read from /dev/urandom */
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #include <fcntl.h>
  22. #include <unistd.h>
  23. /* Subset of Mathias Panzenböck's portable endian code, public domain */
  24. #if defined(__linux__) || defined(__CYGWIN__)
  25. # include <endian.h>
  26. #elif defined(__OpenBSD__)
  27. # include <sys/endian.h>
  28. #elif defined(__APPLE__)
  29. # include <libkern/OSByteOrder.h>
  30. # define htole64(x) OSSwapHostToLittleInt64(x)
  31. # define le64toh(x) OSSwapLittleToHostInt64(x)
  32. #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
  33. # include <sys/endian.h>
  34. # define le64toh(x) letoh64(x)
  35. #elif defined(_WIN16) || defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
  36. # include <winsock2.h>
  37. # include <sys/param.h>
  38. # if BYTE_ORDER == LITTLE_ENDIAN
  39. # define htole64(x) (x)
  40. # define le64toh(x) (x)
  41. # elif BYTE_ORDER == BIG_ENDIAN
  42. # define htole64(x) __builtin_bswap64(x)
  43. # define le64toh(x) __builtin_bswap64(x)
  44. # else
  45. # error byte order not supported
  46. # endif
  47. #else
  48. # error platform not supported
  49. #endif
  50. /* The internal, non-opaque definition of the sponge struct. */
  51. typedef union {
  52. uint64_t w[25]; uint8_t b[25*8];
  53. } kdomain_t[1];
  54. typedef struct kparams_s {
  55. uint8_t position, flags, rate, startRound, pad, ratePad, maxOut, client;
  56. } kparams_t[1];
  57. typedef struct keccak_sponge_s {
  58. kdomain_t state;
  59. kparams_t params;
  60. } keccak_sponge_s, keccak_sponge_t[1];
  61. #define INTERNAL_SPONGE_STRUCT 1
  62. #include <decaf/shake.h>
  63. #include <decaf/strobe.h>
  64. #include <decaf/spongerng.h>
  65. #define FLAG_ABSORBING 'A'
  66. #define FLAG_SQUEEZING 'Z'
  67. /** Constants. **/
  68. static const uint8_t pi[24] = {
  69. 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
  70. 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
  71. };
  72. #define RC_B(x,n) ((((x##ull)>>n)&1)<<((1<<n)-1))
  73. #define RC_X(x) (RC_B(x,0)|RC_B(x,1)|RC_B(x,2)|RC_B(x,3)|RC_B(x,4)|RC_B(x,5)|RC_B(x,6))
  74. static const uint64_t RC[24] = {
  75. RC_X(0x01), RC_X(0x1a), RC_X(0x5e), RC_X(0x70), RC_X(0x1f), RC_X(0x21),
  76. RC_X(0x79), RC_X(0x55), RC_X(0x0e), RC_X(0x0c), RC_X(0x35), RC_X(0x26),
  77. RC_X(0x3f), RC_X(0x4f), RC_X(0x5d), RC_X(0x53), RC_X(0x52), RC_X(0x48),
  78. RC_X(0x16), RC_X(0x66), RC_X(0x79), RC_X(0x58), RC_X(0x21), RC_X(0x74)
  79. };
  80. static inline uint64_t rol(uint64_t x, int s) {
  81. return (x << s) | (x >> (64 - s));
  82. }
  83. /* Helper macros to unroll the permutation. */
  84. #define REPEAT5(e) e e e e e
  85. #define FOR51(v, e) v = 0; REPEAT5(e; v += 1;)
  86. #ifndef SHAKE_NO_UNROLL_LOOPS
  87. # define FOR55(v, e) v = 0; REPEAT5(e; v += 5;)
  88. # define REPEAT24(e) e e e e e e e e e e e e e e e e e e e e e e e e
  89. #else
  90. # define FOR55(v, e) for (v=0; v<25; v+= 5) { e; }
  91. # define REPEAT24(e) {int _j=0; for (_j=0; _j<24; _j++) { e }}
  92. #endif
  93. /*** The Keccak-f[1600] permutation ***/
  94. static void
  95. __attribute__((noinline))
  96. keccakf(kdomain_t state, uint8_t startRound) {
  97. uint64_t* a = state->w;
  98. uint64_t b[5] = {0}, t, u;
  99. uint8_t x, y, i;
  100. for (i=0; i<25; i++) a[i] = le64toh(a[i]);
  101. for (i = startRound; i < 24; i++) {
  102. FOR51(x, b[x] = 0; )
  103. FOR55(y, FOR51(x, b[x] ^= a[x + y]; ))
  104. FOR55(y, FOR51(x,
  105. a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1);
  106. ))
  107. // Rho and pi
  108. t = a[1];
  109. x = y = 0;
  110. REPEAT24(u = a[pi[x]]; y += x+1; a[pi[x]] = rol(t, y % 64); t = u; x++; )
  111. // Chi
  112. FOR55(y,
  113. FOR51(x, b[x] = a[y + x];)
  114. FOR51(x, a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]);)
  115. )
  116. // Iota
  117. a[0] ^= RC[i];
  118. }
  119. for (i=0; i<25; i++) a[i] = htole64(a[i]);
  120. }
  121. static inline void dokeccak (keccak_sponge_t sponge) {
  122. keccakf(sponge->state, sponge->params->startRound);
  123. sponge->params->position = 0;
  124. }
  125. void sha3_update (
  126. struct keccak_sponge_s * __restrict__ sponge,
  127. const uint8_t *in,
  128. size_t len
  129. ) {
  130. if (!len) return;
  131. assert(sponge->params->position < sponge->params->rate);
  132. assert(sponge->params->rate < sizeof(sponge->state));
  133. assert(sponge->params->flags == FLAG_ABSORBING);
  134. while (len) {
  135. size_t cando = sponge->params->rate - sponge->params->position, i;
  136. uint8_t* state = &sponge->state->b[sponge->params->position];
  137. if (cando > len) {
  138. for (i = 0; i < len; i += 1) state[i] ^= in[i];
  139. sponge->params->position += len;
  140. return;
  141. } else {
  142. for (i = 0; i < cando; i += 1) state[i] ^= in[i];
  143. dokeccak(sponge);
  144. len -= cando;
  145. in += cando;
  146. }
  147. }
  148. }
  149. void sha3_output (
  150. keccak_sponge_t sponge,
  151. uint8_t * __restrict__ out,
  152. size_t len
  153. ) {
  154. assert(sponge->params->position < sponge->params->rate);
  155. assert(sponge->params->rate < sizeof(sponge->state));
  156. if (sponge->params->maxOut != 0xFF) {
  157. assert(sponge->params->maxOut >= len);
  158. sponge->params->maxOut -= len;
  159. }
  160. switch (sponge->params->flags) {
  161. case FLAG_SQUEEZING: break;
  162. case FLAG_ABSORBING:
  163. {
  164. uint8_t* state = sponge->state->b;
  165. state[sponge->params->position] ^= sponge->params->pad;
  166. state[sponge->params->rate - 1] ^= sponge->params->ratePad;
  167. dokeccak(sponge);
  168. break;
  169. }
  170. default:
  171. assert(0);
  172. }
  173. while (len) {
  174. size_t cando = sponge->params->rate - sponge->params->position;
  175. uint8_t* state = &sponge->state->b[sponge->params->position];
  176. if (cando > len) {
  177. memcpy(out, state, len);
  178. sponge->params->position += len;
  179. return;
  180. } else {
  181. memcpy(out, state, cando);
  182. dokeccak(sponge);
  183. len -= cando;
  184. out += cando;
  185. }
  186. }
  187. }
  188. void sponge_destroy (keccak_sponge_t sponge) { decaf_bzero(sponge, sizeof(keccak_sponge_t)); }
  189. void sponge_init (
  190. keccak_sponge_t sponge,
  191. const struct kparams_s *params
  192. ) {
  193. memset(sponge->state, 0, sizeof(sponge->state));
  194. sponge->params[0] = params[0];
  195. }
  196. void sponge_hash (
  197. const uint8_t *in,
  198. size_t inlen,
  199. uint8_t *out,
  200. size_t outlen,
  201. const struct kparams_s *params
  202. ) {
  203. keccak_sponge_t sponge;
  204. sponge_init(sponge, params);
  205. sha3_update(sponge, in, inlen);
  206. sha3_output(sponge, out, outlen);
  207. sponge_destroy(sponge);
  208. }
  209. #define DEFSHAKE(n) \
  210. const struct kparams_s SHAKE##n##_params_s = \
  211. { 0, FLAG_ABSORBING, 200-n/4, 0, 0x1f, 0x80, 0xFF, 0 };
  212. #define DEFSHA3(n) \
  213. const struct kparams_s SHA3_##n##_params_s = \
  214. { 0, FLAG_ABSORBING, 200-n/4, 0, 0x06, 0x80, n/8, 0 };
  215. size_t sponge_default_output_bytes (
  216. const keccak_sponge_t s
  217. ) {
  218. return (s->params->maxOut == 0xFF)
  219. ? (200-s->params->rate)
  220. : ((200-s->params->rate)/2);
  221. }
  222. DEFSHAKE(128)
  223. DEFSHAKE(256)
  224. DEFSHA3(224)
  225. DEFSHA3(256)
  226. DEFSHA3(384)
  227. DEFSHA3(512)
  228. /** Get entropy from a CPU, preferably in the form of RDRAND, but possibly instead from RDTSC. */
  229. static void get_cpu_entropy(uint8_t *entropy, size_t len) {
  230. # if (defined(__i386__) || defined(__x86_64__))
  231. static char tested = 0, have_rdrand = 0;
  232. if (!tested) {
  233. u_int32_t a,b,c,d;
  234. a=1; __asm__("cpuid" : "+a"(a), "=b"(b), "=c"(c), "=d"(d));
  235. have_rdrand = (c>>30)&1;
  236. tested = 1;
  237. }
  238. if (have_rdrand) {
  239. # if defined(__x86_64__)
  240. uint64_t out, a=0, *eo = (uint64_t *)entropy;
  241. # elif defined(__i386__)
  242. uint32_t out, a=0, *eo = (uint64_t *)entropy;
  243. #endif
  244. len /= sizeof(out);
  245. uint32_t tries;
  246. for (tries = 100+len; tries && len; len--, eo++) {
  247. for (a = 0; tries && !a; tries--) {
  248. __asm__ __volatile__ ("rdrand %0\n\tsetc %%al" : "=r"(out), "+a"(a) :: "cc" );
  249. }
  250. *eo ^= out;
  251. }
  252. } else if (len>=8) {
  253. uint64_t out;
  254. __asm__ __volatile__ ("rdtsc" : "=A"(out));
  255. *(uint64_t*) entropy ^= out;
  256. }
  257. #else
  258. (void) entropy;
  259. (void) len;
  260. #endif
  261. }
  262. static const char *SPONGERNG_NAME = "strobe::spongerng"; /* TODO: canonicalize name */
  263. void spongerng_next (
  264. keccak_prng_t prng,
  265. uint8_t * __restrict__ out,
  266. size_t len
  267. ) {
  268. keccak_sponge_s *sponge = prng->sponge;
  269. if (sponge->params->client) {
  270. /* nondet */
  271. uint8_t cpu_entropy[32];
  272. get_cpu_entropy(cpu_entropy, sizeof(cpu_entropy));
  273. strobe_transact((keccak_strobe_s*)sponge,NULL,cpu_entropy,sizeof(cpu_entropy),STROBE_CW_PRNG_CPU_SEED);
  274. }
  275. strobe_transact((keccak_strobe_s*)sponge,out,NULL,len,STROBE_CW_PRNG);
  276. }
  277. void spongerng_stir (
  278. keccak_prng_t sponge,
  279. const uint8_t * __restrict__ in,
  280. size_t len
  281. ) {
  282. strobe_transact((keccak_strobe_s*)sponge,NULL,in,len,STROBE_CW_PRNG_USER_SEED);
  283. }
  284. static const struct kparams_s spongerng_params = {
  285. 0, 0, 200-256/4, 0, 0x06, 0x80, 0xFF, 0
  286. };
  287. void spongerng_init_from_buffer (
  288. keccak_prng_t prng,
  289. const uint8_t * __restrict__ in,
  290. size_t len,
  291. int deterministic
  292. ) {
  293. keccak_sponge_s *sponge = prng->sponge;
  294. strobe_init((keccak_strobe_s*)sponge, &spongerng_params, SPONGERNG_NAME, !deterministic);
  295. spongerng_stir(prng, in, len);
  296. }
  297. decaf_error_t spongerng_init_from_file (
  298. keccak_prng_t prng,
  299. const char *file,
  300. size_t len,
  301. int deterministic
  302. ) {
  303. keccak_sponge_s *sponge = prng->sponge;
  304. strobe_init((keccak_strobe_s*)sponge, &spongerng_params, SPONGERNG_NAME, !deterministic);
  305. if (!len) return DECAF_FAILURE;
  306. int fd = open(file, O_RDONLY);
  307. if (fd < 0) return DECAF_FAILURE;
  308. uint8_t buffer[128];
  309. int first = 1;
  310. while (len) {
  311. ssize_t red = read(fd, buffer, (len > sizeof(buffer)) ? sizeof(buffer) : len);
  312. if (red <= 0) {
  313. close(fd);
  314. return DECAF_FAILURE;
  315. }
  316. strobe_transact((keccak_strobe_s*)sponge,NULL,buffer,red,
  317. first ? STROBE_CW_PRNG_USER_SEED : (STROBE_CW_PRNG_USER_SEED | STROBE_FLAG_MORE));
  318. len -= red;
  319. first = 0;
  320. };
  321. close(fd);
  322. return DECAF_SUCCESS;
  323. }
  324. decaf_error_t spongerng_init_from_dev_urandom (
  325. keccak_prng_t sponge
  326. ) {
  327. return spongerng_init_from_file(sponge, "/dev/urandom", 64, 0);
  328. }
  329. const struct kparams_s STROBE_128 = { 0, 0, 200-128/4, 0, 0, 0, 0, 0 };
  330. const struct kparams_s STROBE_256 = { 0, 0, 200-256/4, 0, 0, 0, 0, 0 };
  331. const struct kparams_s STROBE_KEYED_256 = { 0, 0, 200-256/4, 12, 0, 0, 0, 0 };
  332. const struct kparams_s STROBE_KEYED_128 = { 0, 0, 200-128/4, 12, 0, 0, 0, 0 };
  333. /* Strobe is different in that its rate is padded by one byte. */
  334. void strobe_init(
  335. keccak_strobe_t strobe,
  336. const struct kparams_s *params,
  337. const char *proto,
  338. uint8_t am_client
  339. ) {
  340. keccak_sponge_s *sponge = strobe->sponge;
  341. sponge_init(sponge,params);
  342. const char *a_string = "STROBE full v0.2";
  343. unsigned len = strlen(a_string);
  344. memcpy (
  345. &sponge->state->b[sizeof(sponge->state)-len],
  346. a_string,
  347. len
  348. );
  349. strobe_transact(strobe, NULL, (const unsigned char *)proto, strlen(proto), STROBE_CW_INIT);
  350. sponge->state->b[sponge->params->rate+1] = 1;
  351. sponge->params->client = !!am_client;
  352. }
  353. static const uint8_t EXCEEDED_RATE_PAD = 0x2;
  354. static __inline__ uint8_t CONTROL_WORD_PAD(int cw_size) {
  355. assert(cw_size >= 0 && cw_size <= 31);
  356. return 0xC0 | cw_size;
  357. }
  358. /* PERF vectorize */
  359. static void strobe_duplex (
  360. struct keccak_sponge_s *__restrict__ sponge,
  361. unsigned char *out,
  362. const unsigned char *in,
  363. size_t len,
  364. mode_t mode
  365. ) {
  366. unsigned int j, r = sponge->params->rate, p = sponge->params->position;
  367. uint8_t* __restrict__ state = &sponge->state->b[0];
  368. /* sanity */
  369. assert(r < sizeof(sponge->state) && r >= p);
  370. switch (mode) {
  371. case STROBE_MODE_PLAINTEXT:
  372. assert(in || len==0);
  373. break;
  374. case STROBE_MODE_ABSORB:
  375. case STROBE_MODE_ABSORB_R:
  376. assert((in||len==0) && !out);
  377. break;
  378. case STROBE_MODE_DUPLEX:
  379. case STROBE_MODE_DUPLEX_R:
  380. assert((in && out) || len==0);
  381. break;
  382. case STROBE_MODE_SQUEEZE:
  383. case STROBE_MODE_SQUEEZE_R:
  384. assert((out || len==0) && !in);
  385. break;
  386. case STROBE_MODE_FORGET:
  387. assert(!in && !out);
  388. break;
  389. default:
  390. assert(0);
  391. }
  392. while(1) {
  393. unsigned int cando = r - p;
  394. unsigned int last = (cando >= len);
  395. if (last) {
  396. cando = len;
  397. }
  398. switch (mode) {
  399. case STROBE_MODE_PLAINTEXT:
  400. for (j=0; j<cando; j++) state[p+j] ^= in[j];
  401. if (out) {
  402. memcpy(out, in, cando);
  403. out += cando;
  404. }
  405. in += cando;
  406. break;
  407. case STROBE_MODE_ABSORB:
  408. for (j=0; j<cando; j++) state[p+j] ^= in[j];
  409. in += cando;
  410. break;
  411. case STROBE_MODE_ABSORB_R:
  412. memcpy(state+p, in, cando);
  413. in += cando;
  414. break;
  415. case STROBE_MODE_SQUEEZE:
  416. memcpy(out, state+p, cando);
  417. out += cando;
  418. break;
  419. case STROBE_MODE_SQUEEZE_R:
  420. memcpy(out, state+p, cando);
  421. out += cando;
  422. memset(state+p, 0, cando);
  423. break;
  424. case STROBE_MODE_FORGET:
  425. memset(state+p, 0, cando);
  426. break;
  427. case STROBE_MODE_DUPLEX:
  428. for (j=0; j<cando; j++) {
  429. state[p+j] ^= in[j];
  430. out[j] = state[p+j];
  431. }
  432. in += cando;
  433. out += cando;
  434. break;
  435. case STROBE_MODE_DUPLEX_R:
  436. for (j=0; j<cando; j++) {
  437. unsigned char c = in[j];
  438. out[j] = c ^ state[p+j];
  439. state[p+j] = c;
  440. }
  441. in += cando;
  442. out += cando;
  443. break;
  444. default:
  445. assert(0);
  446. };
  447. if (last) {
  448. sponge->params->position = p+len;
  449. return;
  450. } else {
  451. state[r] ^= EXCEEDED_RATE_PAD;
  452. keccakf(sponge->state, sponge->params->startRound);
  453. len -= cando;
  454. p = 0;
  455. }
  456. }
  457. }
  458. static inline mode_t get_mode ( uint32_t cw_flags ) {
  459. return (mode_t)((cw_flags >> 29) & 7);
  460. }
  461. static const int STROBE_FORGET_BYTES = 32;
  462. static const uint8_t FLAG_NOPARSE = 1;
  463. void strobe_transact (
  464. keccak_strobe_t strobe,
  465. unsigned char *out,
  466. const unsigned char *in,
  467. size_t len,
  468. uint32_t cw_flags
  469. ) {
  470. keccak_sponge_s *sponge = strobe->sponge;
  471. if ( (cw_flags & STROBE_FLAG_NONDIR) == 0
  472. /* extraneous nots to change ints to bools :-/ */
  473. && !(cw_flags & STROBE_FLAG_RECV) != !(sponge->params->client) ) {
  474. cw_flags ^= STROBE_FLAG_CLIENT_SENT;
  475. }
  476. uint64_t my_len = len, len_cw = (cw_flags & STROBE_FLAG_LENGTH_64) ? 10 : 4;
  477. if (cw_flags & STROBE_FLAG_NO_LENGTH) {
  478. my_len = 0;
  479. } else if ((cw_flags & STROBE_FLAG_LENGTH_64)==0) {
  480. assert(my_len < 1<<16);
  481. }
  482. if (cw_flags & STROBE_FLAG_MORE) {
  483. assert(cw_flags & STROBE_FLAG_NO_LENGTH); /* FUTURE */
  484. } else {
  485. uint8_t cwb[10] = {
  486. cw_flags,
  487. cw_flags>>8,
  488. my_len,
  489. my_len>>8,
  490. my_len>>16,
  491. my_len>>24,
  492. my_len>>32,
  493. my_len>>40,
  494. my_len>>48,
  495. my_len>>56
  496. };
  497. strobe_duplex(sponge, NULL, cwb, len_cw, STROBE_MODE_ABSORB_R);
  498. if ((cw_flags & STROBE_FLAG_RUN_F) || (sponge->params->flags & FLAG_NOPARSE)) {
  499. sponge->state->b[sponge->params->position] ^= CONTROL_WORD_PAD(len_cw);
  500. dokeccak(sponge);
  501. }
  502. sponge->params->flags &= ~FLAG_NOPARSE;
  503. if (cw_flags & STROBE_FLAG_NO_LENGTH) {
  504. sponge->params->flags |= FLAG_NOPARSE;
  505. }
  506. }
  507. strobe_duplex(sponge, out, in, len, get_mode(cw_flags));
  508. if (cw_flags & STROBE_FLAG_FORGET) {
  509. uint32_t len = sponge->params->rate - sponge->params->position;
  510. if (len < STROBE_FORGET_BYTES + len_cw) len += sponge->params->rate;
  511. len -= len_cw; /* HACK */
  512. if (cw_flags & STROBE_FLAG_NO_LENGTH) len = 2*STROBE_FORGET_BYTES;
  513. assert(!(cw_flags & STROBE_FLAG_MORE));
  514. strobe_duplex(
  515. sponge, NULL, NULL, len,
  516. STROBE_MODE_FORGET
  517. );
  518. }
  519. }
  520. decaf_error_t strobe_verify_auth (
  521. keccak_strobe_t strobe,
  522. const unsigned char *in,
  523. uint16_t len
  524. ) {
  525. keccak_sponge_s *sponge = strobe->sponge;
  526. if (len > sponge->params->rate) return DECAF_FAILURE;
  527. strobe_transact(strobe, NULL, in, len, strobe_cw_recv(STROBE_CW_MAC));
  528. int32_t residue = 0;
  529. int i;
  530. for (i=0; i<len; i++) {
  531. residue |= sponge->state->b[i];
  532. }
  533. return decaf_succeed_if((residue-1)>>8);
  534. }
  535. void strobe_respec (
  536. keccak_strobe_t strobe,
  537. const struct kparams_s *params
  538. ) {
  539. keccak_sponge_s *sponge = strobe->sponge;
  540. uint8_t in[] = { params->rate, params->startRound };
  541. strobe_transact( strobe, NULL, in, sizeof(in), STROBE_CW_RESPEC_INFO );
  542. strobe_transact( strobe, NULL, NULL, 0, STROBE_CW_RESPEC );
  543. assert(sponge->params->position == 0);
  544. sponge->params->rate = params->rate;
  545. sponge->params->startRound = params->startRound;
  546. }
  547. /* FUTURE: Keyak instances, etc */