upstream: https://github.com/mirage/mirage-crypto
1// from https://github.com/floodyberry/poly1305-donna.git
2
3#include "crypto.h"
4
5typedef struct poly1305_context {
6 size_t aligner;
7 unsigned char opaque[136];
8} poly1305_context;
9
10/* 64-bit Windows sets ARCH_64BIT but poly1305-donna-64 requires 128-bit integers
11 * that are not supported by the Microsoft compiler. Drop down to 32-bit for MSVC.
12 */
13#if defined(ARCH_64BIT) && !defined(_MSC_VER)
14#include "poly1305-donna-64.h"
15#else
16#include "poly1305-donna-32.h"
17#endif
18
19static void
20poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) {
21 poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
22 size_t i;
23
24 /* handle leftover */
25 if (st->leftover) {
26 size_t want = (poly1305_block_size - st->leftover);
27 if (want > bytes)
28 want = bytes;
29 for (i = 0; i < want; i++)
30 st->buffer[st->leftover + i] = m[i];
31 bytes -= want;
32 m += want;
33 st->leftover += want;
34 if (st->leftover < poly1305_block_size)
35 return;
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 size_t want = (bytes & ~(poly1305_block_size - 1));
43 poly1305_blocks(st, m, want);
44 m += want;
45 bytes -= want;
46 }
47
48 /* store leftover */
49 if (bytes) {
50 for (i = 0; i < bytes; i++)
51 st->buffer[st->leftover + i] = m[i];
52 st->leftover += bytes;
53 }
54}
55
56//stubs for OCaml
57CAMLprim value mc_poly1305_init (value ctx, value key) {
58 poly1305_init ((poly1305_context *) Bytes_val(ctx), _st_uint8(key));
59 return Val_unit;
60}
61
62CAMLprim value mc_poly1305_update (value ctx, value buf, value off, value len) {
63 poly1305_update ((poly1305_context *) Bytes_val(ctx), _st_uint8_off(buf, off), Int_val(len));
64 return Val_unit;
65}
66
67CAMLprim value mc_poly1305_finalize (value ctx, value mac, value off) {
68 poly1305_finish ((poly1305_context *) Bytes_val(ctx), _bp_uint8_off(mac, off));
69 return Val_unit;
70}
71
72CAMLprim value mc_poly1305_ctx_size (__unit ()) {
73 return Val_int(sizeof(poly1305_context));
74}
75
76CAMLprim value mc_poly1305_mac_size (__unit ()) {
77 return Val_int(16);
78}