blake2b-long.c 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include <limits.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "crypto_generichash_blake2b.h"
  6. #include "private/common.h"
  7. #include "utils.h"
  8. #include "blake2b-long.h"
  9. int
  10. blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen)
  11. {
  12. uint8_t *out = (uint8_t *) pout;
  13. crypto_generichash_blake2b_state blake_state;
  14. uint8_t outlen_bytes[4 /* sizeof(uint32_t) */] = { 0 };
  15. int ret = -1;
  16. if (outlen > UINT32_MAX) {
  17. goto fail; /* LCOV_EXCL_LINE */
  18. }
  19. /* Ensure little-endian byte order! */
  20. STORE32_LE(outlen_bytes, (uint32_t) outlen);
  21. #define TRY(statement) \
  22. do { \
  23. ret = statement; \
  24. if (ret < 0) { \
  25. goto fail; \
  26. } \
  27. } while ((void) 0, 0)
  28. if (outlen <= crypto_generichash_blake2b_BYTES_MAX) {
  29. TRY(crypto_generichash_blake2b_init(&blake_state, NULL, 0U, outlen));
  30. TRY(crypto_generichash_blake2b_update(&blake_state, outlen_bytes,
  31. sizeof(outlen_bytes)));
  32. TRY(crypto_generichash_blake2b_update(
  33. &blake_state, (const unsigned char *) in, inlen));
  34. TRY(crypto_generichash_blake2b_final(&blake_state, out, outlen));
  35. } else {
  36. uint32_t toproduce;
  37. uint8_t out_buffer[crypto_generichash_blake2b_BYTES_MAX];
  38. uint8_t in_buffer[crypto_generichash_blake2b_BYTES_MAX];
  39. TRY(crypto_generichash_blake2b_init(
  40. &blake_state, NULL, 0U, crypto_generichash_blake2b_BYTES_MAX));
  41. TRY(crypto_generichash_blake2b_update(&blake_state, outlen_bytes,
  42. sizeof(outlen_bytes)));
  43. TRY(crypto_generichash_blake2b_update(
  44. &blake_state, (const unsigned char *) in, inlen));
  45. TRY(crypto_generichash_blake2b_final(
  46. &blake_state, out_buffer, crypto_generichash_blake2b_BYTES_MAX));
  47. memcpy(out, out_buffer, crypto_generichash_blake2b_BYTES_MAX / 2);
  48. out += crypto_generichash_blake2b_BYTES_MAX / 2;
  49. toproduce =
  50. (uint32_t) outlen - crypto_generichash_blake2b_BYTES_MAX / 2;
  51. while (toproduce > crypto_generichash_blake2b_BYTES_MAX) {
  52. memcpy(in_buffer, out_buffer, crypto_generichash_blake2b_BYTES_MAX);
  53. TRY(crypto_generichash_blake2b(
  54. out_buffer, crypto_generichash_blake2b_BYTES_MAX, in_buffer,
  55. crypto_generichash_blake2b_BYTES_MAX, NULL, 0U));
  56. memcpy(out, out_buffer, crypto_generichash_blake2b_BYTES_MAX / 2);
  57. out += crypto_generichash_blake2b_BYTES_MAX / 2;
  58. toproduce -= crypto_generichash_blake2b_BYTES_MAX / 2;
  59. }
  60. memcpy(in_buffer, out_buffer, crypto_generichash_blake2b_BYTES_MAX);
  61. TRY(crypto_generichash_blake2b(out_buffer, toproduce, in_buffer,
  62. crypto_generichash_blake2b_BYTES_MAX,
  63. NULL, 0U));
  64. memcpy(out, out_buffer, toproduce);
  65. }
  66. fail:
  67. sodium_memzero(&blake_state, sizeof(blake_state));
  68. return ret;
  69. #undef TRY
  70. }