blake2b-ref.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*
  2. BLAKE2 reference source code package - C implementations
  3. Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
  4. To the extent possible under law, the author(s) have dedicated all copyright
  5. and related and neighboring rights to this software to the public domain
  6. worldwide. This software is distributed without any warranty.
  7. You should have received a copy of the CC0 Public Domain Dedication along
  8. with
  9. this software. If not, see
  10. <http://creativecommons.org/publicdomain/zero/1.0/>.
  11. */
  12. #include <assert.h>
  13. #include <stddef.h>
  14. #include <stdint.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include "blake2.h"
  18. #include "core.h"
  19. #include "private/common.h"
  20. #include "runtime.h"
  21. #include "utils.h"
  22. static blake2b_compress_fn blake2b_compress = blake2b_compress_ref;
  23. static const uint64_t blake2b_IV[8] = {
  24. 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
  25. 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
  26. 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
  27. };
  28. /* LCOV_EXCL_START */
  29. static inline int
  30. blake2b_set_lastnode(blake2b_state *S)
  31. {
  32. S->f[1] = -1;
  33. return 0;
  34. }
  35. /* LCOV_EXCL_STOP */
  36. static inline int
  37. blake2b_is_lastblock(const blake2b_state *S)
  38. {
  39. return S->f[0] != 0;
  40. }
  41. static inline int
  42. blake2b_set_lastblock(blake2b_state *S)
  43. {
  44. if (S->last_node) {
  45. blake2b_set_lastnode(S);
  46. }
  47. S->f[0] = -1;
  48. return 0;
  49. }
  50. static inline int
  51. blake2b_increment_counter(blake2b_state *S, const uint64_t inc)
  52. {
  53. #ifdef HAVE_TI_MODE
  54. uint128_t t = ((uint128_t) S->t[1] << 64) | S->t[0];
  55. t += inc;
  56. S->t[0] = (uint64_t)(t >> 0);
  57. S->t[1] = (uint64_t)(t >> 64);
  58. #else
  59. S->t[0] += inc;
  60. S->t[1] += (S->t[0] < inc);
  61. #endif
  62. return 0;
  63. }
  64. /* Parameter-related functions */
  65. static inline int
  66. blake2b_param_set_salt(blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES])
  67. {
  68. memcpy(P->salt, salt, BLAKE2B_SALTBYTES);
  69. return 0;
  70. }
  71. static inline int
  72. blake2b_param_set_personal(blake2b_param *P,
  73. const uint8_t personal[BLAKE2B_PERSONALBYTES])
  74. {
  75. memcpy(P->personal, personal, BLAKE2B_PERSONALBYTES);
  76. return 0;
  77. }
  78. static inline int
  79. blake2b_init0(blake2b_state *S)
  80. {
  81. int i;
  82. for (i = 0; i < 8; i++) {
  83. S->h[i] = blake2b_IV[i];
  84. }
  85. /* zero everything between .t and .last_node */
  86. memset((void *) &S->t, 0,
  87. offsetof(blake2b_state, last_node) + sizeof(S->last_node)
  88. - offsetof(blake2b_state, t));
  89. return 0;
  90. }
  91. /* init xors IV with input parameter block */
  92. int
  93. blake2b_init_param(blake2b_state *S, const blake2b_param *P)
  94. {
  95. size_t i;
  96. const uint8_t *p;
  97. COMPILER_ASSERT(sizeof *P == 64);
  98. blake2b_init0(S);
  99. p = (const uint8_t *) (P);
  100. /* IV XOR ParamBlock */
  101. for (i = 0; i < 8; i++) {
  102. S->h[i] ^= LOAD64_LE(p + sizeof(S->h[i]) * i);
  103. }
  104. return 0;
  105. }
  106. int
  107. blake2b_init(blake2b_state *S, const uint8_t outlen)
  108. {
  109. blake2b_param P[1];
  110. if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) {
  111. sodium_misuse();
  112. }
  113. P->digest_length = outlen;
  114. P->key_length = 0;
  115. P->fanout = 1;
  116. P->depth = 1;
  117. STORE32_LE(P->leaf_length, 0);
  118. STORE64_LE(P->node_offset, 0);
  119. P->node_depth = 0;
  120. P->inner_length = 0;
  121. memset(P->reserved, 0, sizeof(P->reserved));
  122. memset(P->salt, 0, sizeof(P->salt));
  123. memset(P->personal, 0, sizeof(P->personal));
  124. return blake2b_init_param(S, P);
  125. }
  126. int
  127. blake2b_init_salt_personal(blake2b_state *S, const uint8_t outlen,
  128. const void *salt, const void *personal)
  129. {
  130. blake2b_param P[1];
  131. if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) {
  132. sodium_misuse();
  133. }
  134. P->digest_length = outlen;
  135. P->key_length = 0;
  136. P->fanout = 1;
  137. P->depth = 1;
  138. STORE32_LE(P->leaf_length, 0);
  139. STORE64_LE(P->node_offset, 0);
  140. P->node_depth = 0;
  141. P->inner_length = 0;
  142. memset(P->reserved, 0, sizeof(P->reserved));
  143. if (salt != NULL) {
  144. blake2b_param_set_salt(P, (const uint8_t *) salt);
  145. } else {
  146. memset(P->salt, 0, sizeof(P->salt));
  147. }
  148. if (personal != NULL) {
  149. blake2b_param_set_personal(P, (const uint8_t *) personal);
  150. } else {
  151. memset(P->personal, 0, sizeof(P->personal));
  152. }
  153. return blake2b_init_param(S, P);
  154. }
  155. int
  156. blake2b_init_key(blake2b_state *S, const uint8_t outlen, const void *key,
  157. const uint8_t keylen)
  158. {
  159. blake2b_param P[1];
  160. if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) {
  161. sodium_misuse();
  162. }
  163. if (!key || !keylen || keylen > BLAKE2B_KEYBYTES) {
  164. sodium_misuse(); /* does not return */
  165. }
  166. P->digest_length = outlen;
  167. P->key_length = keylen;
  168. P->fanout = 1;
  169. P->depth = 1;
  170. STORE32_LE(P->leaf_length, 0);
  171. STORE64_LE(P->node_offset, 0);
  172. P->node_depth = 0;
  173. P->inner_length = 0;
  174. memset(P->reserved, 0, sizeof(P->reserved));
  175. memset(P->salt, 0, sizeof(P->salt));
  176. memset(P->personal, 0, sizeof(P->personal));
  177. if (blake2b_init_param(S, P) < 0) {
  178. sodium_misuse();
  179. }
  180. {
  181. uint8_t block[BLAKE2B_BLOCKBYTES];
  182. memset(block, 0, BLAKE2B_BLOCKBYTES);
  183. memcpy(block, key, keylen); /* key and keylen cannot be 0 */
  184. blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
  185. sodium_memzero(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */
  186. }
  187. return 0;
  188. }
  189. int
  190. blake2b_init_key_salt_personal(blake2b_state *S, const uint8_t outlen,
  191. const void *key, const uint8_t keylen,
  192. const void *salt, const void *personal)
  193. {
  194. blake2b_param P[1];
  195. if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) {
  196. sodium_misuse();
  197. }
  198. if (!key || !keylen || keylen > BLAKE2B_KEYBYTES) {
  199. sodium_misuse(); /* does not return */
  200. }
  201. P->digest_length = outlen;
  202. P->key_length = keylen;
  203. P->fanout = 1;
  204. P->depth = 1;
  205. STORE32_LE(P->leaf_length, 0);
  206. STORE64_LE(P->node_offset, 0);
  207. P->node_depth = 0;
  208. P->inner_length = 0;
  209. memset(P->reserved, 0, sizeof(P->reserved));
  210. if (salt != NULL) {
  211. blake2b_param_set_salt(P, (const uint8_t *) salt);
  212. } else {
  213. memset(P->salt, 0, sizeof(P->salt));
  214. }
  215. if (personal != NULL) {
  216. blake2b_param_set_personal(P, (const uint8_t *) personal);
  217. } else {
  218. memset(P->personal, 0, sizeof(P->personal));
  219. }
  220. if (blake2b_init_param(S, P) < 0) {
  221. sodium_misuse();
  222. }
  223. {
  224. uint8_t block[BLAKE2B_BLOCKBYTES];
  225. memset(block, 0, BLAKE2B_BLOCKBYTES);
  226. memcpy(block, key, keylen); /* key and keylen cannot be 0 */
  227. blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
  228. sodium_memzero(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */
  229. }
  230. return 0;
  231. }
  232. /* inlen now in bytes */
  233. int
  234. blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen)
  235. {
  236. while (inlen > 0) {
  237. size_t left = S->buflen;
  238. size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
  239. if (inlen > fill) {
  240. memcpy(S->buf + left, in, fill); /* Fill buffer */
  241. S->buflen += fill;
  242. blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
  243. blake2b_compress(S, S->buf); /* Compress */
  244. memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES,
  245. BLAKE2B_BLOCKBYTES); /* Shift buffer left */
  246. S->buflen -= BLAKE2B_BLOCKBYTES;
  247. in += fill;
  248. inlen -= fill;
  249. } else /* inlen <= fill */
  250. {
  251. memcpy(S->buf + left, in, inlen);
  252. S->buflen += inlen; /* Be lazy, do not compress */
  253. in += inlen;
  254. inlen -= inlen;
  255. }
  256. }
  257. return 0;
  258. }
  259. int
  260. blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen)
  261. {
  262. unsigned char buffer[BLAKE2B_OUTBYTES];
  263. if (!outlen || outlen > BLAKE2B_OUTBYTES) {
  264. sodium_misuse();
  265. }
  266. if (blake2b_is_lastblock(S)) {
  267. return -1;
  268. }
  269. if (S->buflen > BLAKE2B_BLOCKBYTES) {
  270. blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
  271. blake2b_compress(S, S->buf);
  272. S->buflen -= BLAKE2B_BLOCKBYTES;
  273. assert(S->buflen <= BLAKE2B_BLOCKBYTES);
  274. memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen);
  275. }
  276. blake2b_increment_counter(S, S->buflen);
  277. blake2b_set_lastblock(S);
  278. memset(S->buf + S->buflen, 0,
  279. 2 * BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
  280. blake2b_compress(S, S->buf);
  281. COMPILER_ASSERT(sizeof buffer == 64U);
  282. STORE64_LE(buffer + 8 * 0, S->h[0]);
  283. STORE64_LE(buffer + 8 * 1, S->h[1]);
  284. STORE64_LE(buffer + 8 * 2, S->h[2]);
  285. STORE64_LE(buffer + 8 * 3, S->h[3]);
  286. STORE64_LE(buffer + 8 * 4, S->h[4]);
  287. STORE64_LE(buffer + 8 * 5, S->h[5]);
  288. STORE64_LE(buffer + 8 * 6, S->h[6]);
  289. STORE64_LE(buffer + 8 * 7, S->h[7]);
  290. memcpy(out, buffer, outlen); /* outlen <= BLAKE2B_OUTBYTES (64) */
  291. sodium_memzero(S->h, sizeof S->h);
  292. sodium_memzero(S->buf, sizeof S->buf);
  293. return 0;
  294. }
  295. /* inlen, at least, should be uint64_t. Others can be size_t. */
  296. int
  297. blake2b(uint8_t *out, const void *in, const void *key, const uint8_t outlen,
  298. const uint64_t inlen, uint8_t keylen)
  299. {
  300. CRYPTO_ALIGN(64) blake2b_state S[1];
  301. /* Verify parameters */
  302. if (NULL == in && inlen > 0) {
  303. sodium_misuse();
  304. }
  305. if (NULL == out) {
  306. sodium_misuse();
  307. }
  308. if (!outlen || outlen > BLAKE2B_OUTBYTES) {
  309. sodium_misuse();
  310. }
  311. if (NULL == key && keylen > 0) {
  312. sodium_misuse();
  313. }
  314. if (keylen > BLAKE2B_KEYBYTES) {
  315. sodium_misuse();
  316. }
  317. if (keylen > 0) {
  318. if (blake2b_init_key(S, outlen, key, keylen) < 0) {
  319. sodium_misuse();
  320. }
  321. } else {
  322. if (blake2b_init(S, outlen) < 0) {
  323. sodium_misuse();
  324. }
  325. }
  326. blake2b_update(S, (const uint8_t *) in, inlen);
  327. blake2b_final(S, out, outlen);
  328. return 0;
  329. }
  330. int
  331. blake2b_salt_personal(uint8_t *out, const void *in, const void *key,
  332. const uint8_t outlen, const uint64_t inlen,
  333. uint8_t keylen, const void *salt, const void *personal)
  334. {
  335. CRYPTO_ALIGN(64) blake2b_state S[1];
  336. /* Verify parameters */
  337. if (NULL == in && inlen > 0) {
  338. sodium_misuse();
  339. }
  340. if (NULL == out) {
  341. sodium_misuse();
  342. }
  343. if (!outlen || outlen > BLAKE2B_OUTBYTES) {
  344. sodium_misuse();
  345. }
  346. if (NULL == key && keylen > 0) {
  347. sodium_misuse();
  348. }
  349. if (keylen > BLAKE2B_KEYBYTES) {
  350. sodium_misuse();
  351. }
  352. if (keylen > 0) {
  353. if (blake2b_init_key_salt_personal(S, outlen, key, keylen, salt,
  354. personal) < 0) {
  355. sodium_misuse();
  356. }
  357. } else {
  358. if (blake2b_init_salt_personal(S, outlen, salt, personal) < 0) {
  359. sodium_misuse();
  360. }
  361. }
  362. blake2b_update(S, (const uint8_t *) in, inlen);
  363. blake2b_final(S, out, outlen);
  364. return 0;
  365. }
  366. int
  367. blake2b_pick_best_implementation(void)
  368. {
  369. /* LCOV_EXCL_START */
  370. #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_TMMINTRIN_H) && \
  371. defined(HAVE_SMMINTRIN_H)
  372. if (sodium_runtime_has_avx2()) {
  373. blake2b_compress = blake2b_compress_avx2;
  374. return 0;
  375. }
  376. #endif
  377. #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && \
  378. defined(HAVE_SMMINTRIN_H)
  379. if (sodium_runtime_has_sse41()) {
  380. blake2b_compress = blake2b_compress_sse41;
  381. return 0;
  382. }
  383. #endif
  384. #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H)
  385. if (sodium_runtime_has_ssse3()) {
  386. blake2b_compress = blake2b_compress_ssse3;
  387. return 0;
  388. }
  389. #endif
  390. blake2b_compress = blake2b_compress_ref;
  391. return 0;
  392. /* LCOV_EXCL_STOP */
  393. }