poly1305_donna.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include "poly1305_donna.h"
  2. #include "crypto_verify_16.h"
  3. #include "private/common.h"
  4. #include "utils.h"
  5. #ifdef HAVE_TI_MODE
  6. #include "poly1305_donna64.h"
  7. #else
  8. #include "poly1305_donna32.h"
  9. #endif
  10. #include "../onetimeauth_poly1305.h"
  11. static void
  12. poly1305_update(poly1305_state_internal_t *st, const unsigned char *m,
  13. unsigned long long bytes)
  14. {
  15. unsigned long long i;
  16. /* handle leftover */
  17. if (st->leftover) {
  18. unsigned long long want = (poly1305_block_size - st->leftover);
  19. if (want > bytes) {
  20. want = bytes;
  21. }
  22. for (i = 0; i < want; i++) {
  23. st->buffer[st->leftover + i] = m[i];
  24. }
  25. bytes -= want;
  26. m += want;
  27. st->leftover += want;
  28. if (st->leftover < poly1305_block_size) {
  29. return;
  30. }
  31. poly1305_blocks(st, st->buffer, poly1305_block_size);
  32. st->leftover = 0;
  33. }
  34. /* process full blocks */
  35. if (bytes >= poly1305_block_size) {
  36. unsigned long long want = (bytes & ~(poly1305_block_size - 1));
  37. poly1305_blocks(st, m, want);
  38. m += want;
  39. bytes -= want;
  40. }
  41. /* store leftover */
  42. if (bytes) {
  43. for (i = 0; i < bytes; i++) {
  44. st->buffer[st->leftover + i] = m[i];
  45. }
  46. st->leftover += bytes;
  47. }
  48. }
  49. static int
  50. crypto_onetimeauth_poly1305_donna(unsigned char *out, const unsigned char *m,
  51. unsigned long long inlen,
  52. const unsigned char *key)
  53. {
  54. CRYPTO_ALIGN(64) poly1305_state_internal_t state;
  55. poly1305_init(&state, key);
  56. poly1305_update(&state, m, inlen);
  57. poly1305_finish(&state, out);
  58. return 0;
  59. }
  60. static int
  61. crypto_onetimeauth_poly1305_donna_init(crypto_onetimeauth_poly1305_state *state,
  62. const unsigned char *key)
  63. {
  64. COMPILER_ASSERT(sizeof(crypto_onetimeauth_poly1305_state) >=
  65. sizeof(poly1305_state_internal_t));
  66. poly1305_init((poly1305_state_internal_t *) (void *) state, key);
  67. return 0;
  68. }
  69. static int
  70. crypto_onetimeauth_poly1305_donna_update(
  71. crypto_onetimeauth_poly1305_state *state, const unsigned char *in,
  72. unsigned long long inlen)
  73. {
  74. poly1305_update((poly1305_state_internal_t *) (void *) state, in, inlen);
  75. return 0;
  76. }
  77. static int
  78. crypto_onetimeauth_poly1305_donna_final(
  79. crypto_onetimeauth_poly1305_state *state, unsigned char *out)
  80. {
  81. poly1305_finish((poly1305_state_internal_t *) (void *) state, out);
  82. return 0;
  83. }
  84. static int
  85. crypto_onetimeauth_poly1305_donna_verify(const unsigned char *h,
  86. const unsigned char *in,
  87. unsigned long long inlen,
  88. const unsigned char *k)
  89. {
  90. unsigned char correct[16];
  91. crypto_onetimeauth_poly1305_donna(correct, in, inlen, k);
  92. return crypto_verify_16(h, correct);
  93. }
  94. struct crypto_onetimeauth_poly1305_implementation
  95. crypto_onetimeauth_poly1305_donna_implementation = {
  96. SODIUM_C99(.onetimeauth =) crypto_onetimeauth_poly1305_donna,
  97. SODIUM_C99(.onetimeauth_verify =)
  98. crypto_onetimeauth_poly1305_donna_verify,
  99. SODIUM_C99(.onetimeauth_init =) crypto_onetimeauth_poly1305_donna_init,
  100. SODIUM_C99(.onetimeauth_update =)
  101. crypto_onetimeauth_poly1305_donna_update,
  102. SODIUM_C99(.onetimeauth_final =) crypto_onetimeauth_poly1305_donna_final
  103. };