123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899(*
* Copyright (c) 2016, Alfredo Beaumont, Sonia Meruelo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)externalxor_into:string->src_off:int->bytes->dst_off:int->len:int->unit="spoke_xor_into_generic"[@@noalloc]externalbytes_set_int32:bytes->int->int32->unit="%caml_bytes_set32"externallessequal:'a->'a->bool="%lessequal"letimin(a:int)b=let(<=)(x:int)y=lessequalxyinifa<=bthenaelseb[@@inline]letxor_intosrc~src_offdst~dst_off~len=iflen>imin(String.lengthsrc)(Bytes.lengthdst)thenFmt.invalid_arg"xor: buffers to small (need %d)"lenelsexor_intosrc~src_offdst~dst_off~lenletxorstr0str1=letlen=imin(String.lengthstr0)(String.lengthstr1)inletbuf=Bytes.of_string(String.substr10len)inxor_intostr0~src_off:0buf~dst_off:0~len;Bytes.unsafe_to_stringbuflet(//)xy=ify<1thenraiseDivision_by_zero;ifx>0then1+((x-1)/y)else0[@@inline](* XXX(dinosaure): implementation of PBKDF 2 from ocaml-pbkdf without the
* mirage-crypto dependency. ocaml-pbkdf is under the BSD-2-Clause license.
*
* Copyright (c) 2016, Alfredo Beaumont, Sonia Meruelo
* All rights reserved. *)letgenerate:typehash.hashDigestif.hash->password:string->salt:string->count:int->int32->string=funhash~password~salt~countlen->letmoduleHash=(valDigestif.module_ofhash)inifcount<=0thenFmt.invalid_arg"pbkdf2: count must be a positive integer";iflen<=0lthenFmt.invalid_arg"pbkdf2: derived key length must be a positive integer";lethash_len=Hash.digest_sizeinletderived_key_len=Int32.to_intleninletlen=derived_key_len//hash_leninletr=derived_key_len-((len-1)*hash_len)inletblockidx:string=letrecgouv=function|0->v|j->letu=Hash.hmac_string~key:passworduinletu=Hash.to_raw_stringuingou(xorvu)(predj)inlettrailer=letbuf=Bytes.make4'\000'inbytes_set_int32buf0(Int32.of_intidx);Bytes.unsafe_to_stringbufinletu=Hash.hmac_string~key:password(salt^trailer)inletu=Hash.to_raw_stringuingouu(predcount)inletrecgoblocks=function|0->blocks|n->go(blockn::blocks)(predn)inString.concat""(go[String.sub(blocklen)0r](predlen))