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 14 static void 15 poly1305_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 58 static int 59 crypto_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 72 static int 73 crypto_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 83 static int 84 crypto_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 93 static int 94 crypto_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 102 static int 103 crypto_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 115 struct 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