blake2b.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. /*
  2. BLAKE2 reference source code package - reference 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 with
  8. this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
  9. */
  10. /* blake2b.c
  11. *
  12. * Copyright (C) 2006-2022 wolfSSL Inc.
  13. *
  14. * This file is part of wolfSSL.
  15. *
  16. * wolfSSL is free software; you can redistribute it and/or modify
  17. * it under the terms of the GNU General Public License as published by
  18. * the Free Software Foundation; either version 2 of the License, or
  19. * (at your option) any later version.
  20. *
  21. * wolfSSL is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU General Public License
  27. * along with this program; if not, write to the Free Software
  28. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  29. */
  30. #ifdef HAVE_CONFIG_H
  31. #include <config.h>
  32. #endif
  33. #include <wolfssl/wolfcrypt/settings.h>
  34. #ifdef HAVE_BLAKE2
  35. #include <wolfssl/wolfcrypt/blake2.h>
  36. #include <wolfssl/wolfcrypt/blake2-impl.h>
  37. #include <wolfssl/wolfcrypt/error-crypt.h>
  38. static const word64 blake2b_IV[8] =
  39. {
  40. 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
  41. 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
  42. 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
  43. 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
  44. };
  45. static const byte blake2b_sigma[12][16] =
  46. {
  47. { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
  48. { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
  49. { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
  50. { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
  51. { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
  52. { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
  53. { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
  54. { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
  55. { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
  56. { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
  57. { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
  58. { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
  59. };
  60. static WC_INLINE int blake2b_set_lastnode( blake2b_state *S )
  61. {
  62. S->f[1] = ~0ULL;
  63. return 0;
  64. }
  65. /* Some helper functions, not necessarily useful */
  66. static WC_INLINE int blake2b_set_lastblock( blake2b_state *S )
  67. {
  68. if( S->last_node ) blake2b_set_lastnode( S );
  69. S->f[0] = ~0ULL;
  70. return 0;
  71. }
  72. static WC_INLINE int blake2b_increment_counter( blake2b_state *S, const word64
  73. inc )
  74. {
  75. S->t[0] += inc;
  76. S->t[1] += ( S->t[0] < inc );
  77. return 0;
  78. }
  79. static WC_INLINE int blake2b_init0( blake2b_state *S )
  80. {
  81. int i;
  82. XMEMSET( S, 0, sizeof( blake2b_state ) );
  83. for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
  84. return 0;
  85. }
  86. /* init xors IV with input parameter block */
  87. int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
  88. {
  89. word32 i;
  90. byte *p ;
  91. blake2b_init0( S );
  92. p = ( byte * )( P );
  93. /* IV XOR ParamBlock */
  94. for( i = 0; i < 8; ++i )
  95. S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
  96. return 0;
  97. }
  98. int blake2b_init( blake2b_state *S, const byte outlen )
  99. {
  100. #ifdef WOLFSSL_BLAKE2B_INIT_EACH_FIELD
  101. blake2b_param P[1];
  102. #else
  103. volatile blake2b_param P[1];
  104. #endif
  105. if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return BAD_FUNC_ARG;
  106. #ifdef WOLFSSL_BLAKE2B_INIT_EACH_FIELD
  107. P->digest_length = outlen;
  108. P->key_length = 0;
  109. P->fanout = 1;
  110. P->depth = 1;
  111. store32( &P->leaf_length, 0 );
  112. store64( &P->node_offset, 0 );
  113. P->node_depth = 0;
  114. P->inner_length = 0;
  115. XMEMSET( P->reserved, 0, sizeof( P->reserved ) );
  116. XMEMSET( P->salt, 0, sizeof( P->salt ) );
  117. XMEMSET( P->personal, 0, sizeof( P->personal ) );
  118. #else
  119. XMEMSET( (blake2b_param *)P, 0, sizeof( *P ) );
  120. P->digest_length = outlen;
  121. P->fanout = 1;
  122. P->depth = 1;
  123. #endif
  124. return blake2b_init_param( S, (blake2b_param *)P );
  125. }
  126. int blake2b_init_key( blake2b_state *S, const byte outlen, const void *key,
  127. const byte keylen )
  128. {
  129. int ret = 0;
  130. #ifdef WOLFSSL_BLAKE2B_INIT_EACH_FIELD
  131. blake2b_param P[1];
  132. #else
  133. volatile blake2b_param P[1];
  134. #endif
  135. if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return BAD_FUNC_ARG;
  136. if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return BAD_FUNC_ARG;
  137. #ifdef WOLFSSL_BLAKE2B_INIT_EACH_FIELD
  138. P->digest_length = outlen;
  139. P->key_length = keylen;
  140. P->fanout = 1;
  141. P->depth = 1;
  142. store32( &P->leaf_length, 0 );
  143. store64( &P->node_offset, 0 );
  144. P->node_depth = 0;
  145. P->inner_length = 0;
  146. XMEMSET( P->reserved, 0, sizeof( P->reserved ) );
  147. XMEMSET( P->salt, 0, sizeof( P->salt ) );
  148. XMEMSET( P->personal, 0, sizeof( P->personal ) );
  149. #else
  150. XMEMSET( (blake2b_param *)P, 0, sizeof( *P ) );
  151. P->digest_length = outlen;
  152. P->key_length = keylen;
  153. P->fanout = 1;
  154. P->depth = 1;
  155. #endif
  156. ret = blake2b_init_param( S, (blake2b_param *)P );
  157. if ( ret < 0 ) return ret;
  158. {
  159. #ifdef WOLFSSL_SMALL_STACK
  160. byte* block;
  161. block = (byte*)XMALLOC(BLAKE2B_BLOCKBYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  162. if ( block == NULL ) return MEMORY_E;
  163. #else
  164. byte block[BLAKE2B_BLOCKBYTES];
  165. #endif
  166. XMEMSET( block, 0, BLAKE2B_BLOCKBYTES );
  167. XMEMCPY( block, key, keylen );
  168. ret = blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
  169. secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from */
  170. /* memory */
  171. #ifdef WOLFSSL_SMALL_STACK
  172. XFREE(block, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  173. #endif
  174. }
  175. return ret;
  176. }
  177. static WC_INLINE int blake2b_compress(
  178. blake2b_state *S,
  179. const byte block[BLAKE2B_BLOCKBYTES],
  180. word64* m,
  181. word64* v)
  182. {
  183. int i;
  184. for( i = 0; i < 16; ++i )
  185. m[i] = load64( block + i * sizeof( m[i] ) );
  186. for( i = 0; i < 8; ++i )
  187. v[i] = S->h[i];
  188. v[ 8] = blake2b_IV[0];
  189. v[ 9] = blake2b_IV[1];
  190. v[10] = blake2b_IV[2];
  191. v[11] = blake2b_IV[3];
  192. v[12] = S->t[0] ^ blake2b_IV[4];
  193. v[13] = S->t[1] ^ blake2b_IV[5];
  194. v[14] = S->f[0] ^ blake2b_IV[6];
  195. v[15] = S->f[1] ^ blake2b_IV[7];
  196. #define G(r,i,a,b,c,d) \
  197. do { \
  198. (a) = (a) + (b) + m[blake2b_sigma[r][2*(i)+0]]; \
  199. (d) = rotr64((d) ^ (a), 32); \
  200. (c) = (c) + (d); \
  201. (b) = rotr64((b) ^ (c), 24); \
  202. (a) = (a) + (b) + m[blake2b_sigma[r][2*(i)+1]]; \
  203. (d) = rotr64((d) ^ (a), 16); \
  204. (c) = (c) + (d); \
  205. (b) = rotr64((b) ^ (c), 63); \
  206. } while(0)
  207. #define ROUND(r) \
  208. do { \
  209. G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
  210. G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
  211. G(r,2,v[ 2],v[ 6],v[10],v[14]); \
  212. G(r,3,v[ 3],v[ 7],v[11],v[15]); \
  213. G(r,4,v[ 0],v[ 5],v[10],v[15]); \
  214. G(r,5,v[ 1],v[ 6],v[11],v[12]); \
  215. G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
  216. G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
  217. } while(0)
  218. ROUND( 0 );
  219. ROUND( 1 );
  220. ROUND( 2 );
  221. ROUND( 3 );
  222. ROUND( 4 );
  223. ROUND( 5 );
  224. ROUND( 6 );
  225. ROUND( 7 );
  226. ROUND( 8 );
  227. ROUND( 9 );
  228. ROUND( 10 );
  229. ROUND( 11 );
  230. for( i = 0; i < 8; ++i )
  231. S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
  232. #undef G
  233. #undef ROUND
  234. return 0;
  235. }
  236. /* inlen now in bytes */
  237. int blake2b_update( blake2b_state *S, const byte *in, word64 inlen )
  238. {
  239. int ret = 0;
  240. #ifdef WOLFSSL_SMALL_STACK
  241. word64* m;
  242. word64* v;
  243. m = (word64*)XMALLOC(sizeof(word64) * 32, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  244. if ( m == NULL ) return MEMORY_E;
  245. v = &m[16];
  246. #else
  247. word64 m[16];
  248. word64 v[16];
  249. #endif
  250. while( inlen > 0 )
  251. {
  252. word64 left = S->buflen;
  253. word64 fill = 2 * BLAKE2B_BLOCKBYTES - left;
  254. if( inlen > fill )
  255. {
  256. XMEMCPY( S->buf + left, in, (wolfssl_word)fill ); /* Fill buffer */
  257. S->buflen += fill;
  258. blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
  259. {
  260. ret = blake2b_compress( S, S->buf, m, v );
  261. if (ret < 0) break;
  262. }
  263. XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES );
  264. /* Shift buffer left */
  265. S->buflen -= BLAKE2B_BLOCKBYTES;
  266. in += fill;
  267. inlen -= fill;
  268. }
  269. else /* inlen <= fill */
  270. {
  271. XMEMCPY( S->buf + left, in, (wolfssl_word)inlen );
  272. S->buflen += inlen; /* Be lazy, do not compress */
  273. inlen = 0;
  274. }
  275. }
  276. #ifdef WOLFSSL_SMALL_STACK
  277. XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  278. #endif
  279. return ret;
  280. }
  281. /* Is this correct? */
  282. int blake2b_final( blake2b_state *S, byte *out, byte outlen )
  283. {
  284. int ret = 0;
  285. byte buffer[BLAKE2B_OUTBYTES];
  286. int i;
  287. #ifdef WOLFSSL_SMALL_STACK
  288. word64* m;
  289. word64* v;
  290. m = (word64*)XMALLOC(sizeof(word64) * 32, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  291. if ( m == NULL ) return MEMORY_E;
  292. v = &m[16];
  293. #else
  294. word64 m[16];
  295. word64 v[16];
  296. #endif
  297. if( S->buflen > BLAKE2B_BLOCKBYTES )
  298. {
  299. blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
  300. {
  301. ret = blake2b_compress( S, S->buf, m, v );
  302. if (ret < 0) goto out;
  303. }
  304. S->buflen -= BLAKE2B_BLOCKBYTES;
  305. XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, (wolfssl_word)S->buflen );
  306. }
  307. blake2b_increment_counter( S, S->buflen );
  308. blake2b_set_lastblock( S );
  309. XMEMSET( S->buf + S->buflen, 0, (wolfssl_word)(2 * BLAKE2B_BLOCKBYTES - S->buflen) );
  310. /* Padding */
  311. {
  312. ret = blake2b_compress( S, S->buf, m, v );
  313. if (ret < 0) goto out;
  314. }
  315. for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
  316. store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
  317. XMEMCPY( out, buffer, outlen );
  318. out:
  319. #ifdef WOLFSSL_SMALL_STACK
  320. XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  321. #endif
  322. return ret;
  323. }
  324. /* inlen, at least, should be word64. Others can be size_t. */
  325. int blake2b( byte *out, const void *in, const void *key, const byte outlen,
  326. const word64 inlen, byte keylen )
  327. {
  328. blake2b_state S[1];
  329. /* Verify parameters */
  330. if ( NULL == in ) return BAD_FUNC_ARG;
  331. if ( NULL == out ) return BAD_FUNC_ARG;
  332. if( NULL == key ) keylen = 0;
  333. if( keylen > 0 )
  334. {
  335. int ret = blake2b_init_key( S, outlen, key, keylen );
  336. if (ret < 0) return ret;
  337. }
  338. else
  339. {
  340. int ret = blake2b_init( S, outlen );
  341. if (ret < 0) return ret;
  342. }
  343. {
  344. int ret = blake2b_update( S, ( byte * )in, inlen );
  345. if (ret < 0) return ret;
  346. }
  347. return blake2b_final( S, out, outlen );
  348. }
  349. #if defined(BLAKE2B_SELFTEST)
  350. #include <string.h>
  351. #include "blake2-kat.h"
  352. int main( int argc, char **argv )
  353. {
  354. byte key[BLAKE2B_KEYBYTES];
  355. byte buf[KAT_LENGTH];
  356. for( word32 i = 0; i < BLAKE2B_KEYBYTES; ++i )
  357. key[i] = ( byte )i;
  358. for( word32 i = 0; i < KAT_LENGTH; ++i )
  359. buf[i] = ( byte )i;
  360. for( word32 i = 0; i < KAT_LENGTH; ++i )
  361. {
  362. byte hash[BLAKE2B_OUTBYTES];
  363. if ( blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 )
  364. {
  365. puts( "error" );
  366. return -1;
  367. }
  368. if( 0 != XMEMCMP( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
  369. {
  370. puts( "error" );
  371. return -1;
  372. }
  373. }
  374. puts( "ok" );
  375. return 0;
  376. }
  377. #endif
  378. /* wolfCrypt API */
  379. /* Init Blake2b digest, track size in case final doesn't want to "remember" */
  380. int wc_InitBlake2b(Blake2b* b2b, word32 digestSz)
  381. {
  382. if (b2b == NULL){
  383. return BAD_FUNC_ARG;
  384. }
  385. b2b->digestSz = digestSz;
  386. return blake2b_init(b2b->S, (byte)digestSz);
  387. }
  388. /* Init Blake2b digest with key, track size in case final doesn't want to "remember" */
  389. int wc_InitBlake2b_WithKey(Blake2b* b2b, word32 digestSz, const byte *key, word32 keylen)
  390. {
  391. if (b2b == NULL){
  392. return BAD_FUNC_ARG;
  393. }
  394. b2b->digestSz = digestSz;
  395. if (keylen >= 256)
  396. return BAD_FUNC_ARG;
  397. if (key)
  398. return blake2b_init_key(b2b->S, (byte)digestSz, key, (byte)keylen);
  399. else
  400. return blake2b_init(b2b->S, (byte)digestSz);
  401. }
  402. /* Blake2b Update */
  403. int wc_Blake2bUpdate(Blake2b* b2b, const byte* data, word32 sz)
  404. {
  405. return blake2b_update(b2b->S, data, sz);
  406. }
  407. /* Blake2b Final, if pass in zero size we use init digestSz */
  408. int wc_Blake2bFinal(Blake2b* b2b, byte* final, word32 requestSz)
  409. {
  410. word32 sz = requestSz ? requestSz : b2b->digestSz;
  411. return blake2b_final(b2b->S, final, (byte)sz);
  412. }
  413. /* end CTaoCrypt API */
  414. #endif /* HAVE_BLAKE2 */