diff --git a/src/cipher_block.ml b/src/cipher_block.ml index 8127f98..b56ccc4 100644 --- a/src/cipher_block.ml +++ b/src/cipher_block.ml @@ -118,8 +118,7 @@ module Counter = struct let add8 cs i x = BE.(set_uint64 cs i (Int64.add x (get_uint64 cs i))) - (* FIXME: overflow: higher order bits. *) - let add16 cs i x = add8 cs (i + 8) x + let add16 cs i x = Native.add16be cs.buffer i x end diff --git a/src/native.ml b/src/native.ml index 2cc6791..b8d23cb 100644 --- a/src/native.ml +++ b/src/native.ml @@ -79,5 +79,6 @@ external xor_into : buffer -> off -> buffer -> off -> size -> unit = "caml_nc_xo external count8be : buffer -> off -> buffer -> off -> size -> unit = "caml_nc_count_8_be" [@@noalloc] external count16be : buffer -> off -> buffer -> off -> size -> unit = "caml_nc_count_16_be" [@@noalloc] +external add16be : buffer -> off -> int64 -> unit = "caml_nc_add_16_be" [@@noalloc] external blit : buffer -> off -> buffer -> off -> size -> unit = "caml_blit_bigstring_to_bigstring" [@@noalloc] diff --git a/src/native/misc.c b/src/native/misc.c index 2ea4031..7f667d1 100644 --- a/src/native/misc.c +++ b/src/native/misc.c @@ -48,6 +48,16 @@ static inline void nc_count_16_be (uint64_t *init, uint64_t *dst, size_t blocks) } } +static inline void nc_add_16_be (uint64_t *init, uint64_t n) { + uint64_t h = be64_to_cpu (init[0]); + uint64_t l = be64_to_cpu (init[1]); + uint64_t nl = l + n; /* let it wrap */ + + if (nl < l) + h++; + init[0] = cpu_to_be64 (h); + init[1] = cpu_to_be64 (nl); +} CAMLprim value caml_nc_xor_into (value b1, value off1, value b2, value off2, value n) { @@ -70,3 +80,9 @@ caml_nc_count_16_be (value init, value off1, value dst, value off2, value blocks Long_val (blocks) ); return Val_unit; } + +CAMLprim value +caml_nc_add_16_be (value init, value off, value n) { + nc_add_16_be ( (uint64_t *) _ba_uint8_off (init, off), Int64_val(n)); + return Val_unit; +}