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