auth.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /* https://github.com/floodyberry/poly1305-donna */
  2. #include "crypto_onetimeauth.h"
  3. #include <stddef.h>
  4. typedef struct poly1305_context {
  5. size_t aligner;
  6. unsigned char opaque[136];
  7. } poly1305_context;
  8. #if defined(POLY1305_8BIT)
  9. #include "poly1305-donna-8.h"
  10. #elif defined(POLY1305_16BIT)
  11. #include "poly1305-donna-16.h"
  12. #elif defined(POLY1305_32BIT)
  13. #include "poly1305-donna-32.h"
  14. #elif defined(POLY1305_64BIT)
  15. #include "poly1305-donna-64.h"
  16. #else
  17. /* auto detect between 32bit / 64bit */
  18. #define HAS_SIZEOF_INT128_64BIT (defined(__SIZEOF_INT128__) && defined(__LP64__))
  19. #define HAS_MSVC_64BIT (defined(_MSC_VER) && defined(_M_X64))
  20. #define HAS_GCC_4_4_64BIT (defined(__GNUC__) && defined(__LP64__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4))))
  21. #if (HAS_SIZEOF_INT128_64BIT || HAS_MSVC_64BIT || HAS_GCC_4_4_64BIT)
  22. #include "poly1305-donna-64.h"
  23. #else
  24. #include "poly1305-donna-32.h"
  25. #endif
  26. #endif
  27. static void
  28. poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) {
  29. poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
  30. size_t i;
  31. /* handle leftover */
  32. if (st->leftover) {
  33. size_t want = (poly1305_block_size - st->leftover);
  34. if (want > bytes)
  35. want = bytes;
  36. for (i = 0; i < want; i++)
  37. st->buffer[st->leftover + i] = m[i];
  38. bytes -= want;
  39. m += want;
  40. st->leftover += want;
  41. if (st->leftover < poly1305_block_size)
  42. return;
  43. poly1305_blocks(st, st->buffer, poly1305_block_size);
  44. st->leftover = 0;
  45. }
  46. /* process full blocks */
  47. if (bytes >= poly1305_block_size) {
  48. size_t want = (bytes & ~(poly1305_block_size - 1));
  49. poly1305_blocks(st, m, want);
  50. m += want;
  51. bytes -= want;
  52. }
  53. /* store leftover */
  54. if (bytes) {
  55. for (i = 0; i < bytes; i++)
  56. st->buffer[st->leftover + i] = m[i];
  57. st->leftover += bytes;
  58. }
  59. }
  60. int
  61. crypto_onetimeauth(unsigned char* out, const unsigned char *m, unsigned long long inlen, const unsigned char* key) {
  62. poly1305_context ctx;
  63. poly1305_init(&ctx, key);
  64. poly1305_update(&ctx, m, inlen);
  65. poly1305_finish(&ctx, out);
  66. return 0;
  67. }