Skip to content

Commits on Source 10

_build
setup.data
setup.log
*.native
*~
Release 1.13:
- Add the Chacha20 stream cipher.
- Add the AES-CMAC (a.k.a. AES-OMAC1) message authentication code.
- Pseudo-random number generator: replace the old AES-CBC-Fibonacci generator
with a faster, simpler generator based on Chacha20.
- Add an alternate pseudo-random number generator based on AES in CTR mode.
- Documentation: warn about known cryptographic weaknesses in Triple DES,
Blowfish, and ARCfour.
- Documentation: warn about problems with variable-length messages in
MACs based on block ciphers in CBC mode.
Release 1.12:
- Fix x86-32 compilation error and improve detection of AES-NI for x86
processors (Jeremie Dimino, Etienne Millon)
(Closes: #1646)
- AES-NI: align key_schedule on a 16 byte boundary (Etienne Millon)
(Closes: #1709)
- Add original Keccak submission to SHA-3 (Yoichi Hirai)
Release 1.11:
- Adapt to "safe string" mode (OCaml 4.02 and later required).
The API should remain backward-compatible for clients compiled
......
This diff is collapsed.
# The Cryptokit library
## Overview
The Cryptokit library for OCaml provides a variety of cryptographic primitives that can be used to implement cryptographic protocols in security-sensitive applications. The primitives provided include:
* Symmetric-key ciphers: AES, Chacha20, DES, Triple-DES, Blowfish, ARCfour, in ECB, CBC, CFB, OFB and counter modes.
* Public-key cryptography: RSA encryption and signature, Diffie-Hellman key agreement.
* Hash functions and MACs: SHA-3, SHA-1, SHA-2, RIPEMD-160, MD5, and MACs based on AES and DES.
* Random number generation.
* Encodings and compression: base 64, hexadecimal, Zlib compression.
Additional ciphers and hashes can easily be used in conjunction with the library. In particular, basic mechanisms such as chaining modes, output buffering, and padding are provided by generic classes that can easily be composed with user-provided ciphers. More generally, the library promotes a "Lego"-like style of constructing and composing transformations over character streams.
This library is distributed under the conditions of the GNU Library General Public license version 2, with the special OCaml exception on linking described in file LICENSE.
## Requirements
* OCaml 4.02 or more recent.
* The findlib/ocamlfind tool.
* The Zarith library, version 1.4 or more recent.
* The Zlib C library, version 1.1.3 or up is recommended. If it is not installed on your system (look for libz.a or libz.so), get it from http://www.gzip.org/, or indicate in the Makefile that you do not have it. If you are running Linux or BSD or MacOS, your distribution provides precompiled binaries for this library.
* If the operating system does not provide the `/dev/random` device for random number generation, consider installing the [EGD](http://egd.sourceforge.net/) entropy gathering daemon. Without `/dev/random` nor EGD, this library cannot generate cryptographically-strong random data nor RSA keys. The remainder of the library still works, though.
## Installation
```
./configure --enable-tests
make
make test
make install
```
## Documentation
See the extensive documentation comments in file src/cryptokit.mli.
Compilation options: `ocamlfind ocamlopt -package cryptokit`...
Linking options: `ocamlfind ocamlopt -linkpkg -package cryptokit`...
## Warnings and disclaimers
Disclaimer 1: the author is not an expert in cryptography. While reasonable care has been taken to select good, widely-used implementations of the ciphers and hashes, and follow recommended practices found in reputable applied cryptography textbooks, you are advised to review thoroughly the implementation of this module before using it in a security-critical application.
Disclaimer 2: some knowledge of cryptography is needed to use effectively this library. A recommended reading is the [Handbook of Applied Cryptography](http://www.cacr.math.uwaterloo.ca/hac/). Building secure applications out of cryptographic primitives also requires a general background in computer security.
Disclaimer 3: in some countries, the use, distribution, import and/or export of cryptographic applications is restricted by law. The precise restrictions may depend on the strenght of the cryptography used (e.g. key size), but also on its purpose (e.g. confidentiality vs. authentication). It is up to the users of this library to comply with regulations applicable in their country.
## Design notes and references
The library is organized around the concept of "transforms". A transform is an object that accepts strings, sub-strings, characters and bytes as input, transforms them, and buffers the output. While it is possible to enter all input, then fetch the output, lower memory requirements can be achieved by purging the output periodically during data input.
The AES implementation is the public-domain optimized reference implementation by Daemen, Rijmen and Barreto. On x86 processors that support the AES-NI extensions, hardware implementation is used instead.
The Chacha20 implementation is due to D.J.Bernstein, https://cr.yp.to/streamciphers/timings/estreambench/submissions/salsa20/chacha8/regs/chacha.c . It is in the public domain.
The DES implementation is based on Outerbridge's popular "d3des" implementation. This is not the fastest DES implementation available, but one of the cleanest. Outerbridge's code is marked as public domain.
The Blowfish implementation is that of Paul Kocher with some performance improvements. It is under the LGPL. It passes the test vectors listed at http://www.schneier.com/code/vectors.txt
ARCfour (``alleged RC4'') is implemented from scratch, based on the algorithm described in Schneier's _Applied Cryptography_
SHA-1 is also implemented from scratch, based on the algorithm described in the _Handbook of Applied Cryptography_. It passes the FIPS test vectors.
SHA-2 is implemented from scratch based on FIPS publication 180-2. It passes the FIPS test vectors.
SHA-3 is based on the "readable" implementation of Keccak written by Markku-Juhani O. Saarinen <mjos@iki.fi>.
RIPEMD-160 is based on the reference implementation by A.Bosselaers. It passes the test vectors listed at http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
MD5 uses the public-domain implementation by Colin Plumb that is also used in the OCaml runtime system for module Digest.
RSA encryption and decryption was implemented from scratch, using the Zarith OCaml library for arbitrary-precision arithmetic, which itself uses GMP. Modular exponentiation is the constant-time implementation provided by GMP. The Chinese remainder theorem is exploited when possible, though. Like all ciphers in this library, the RSA implementation is *not* protected against timing attacks.
RSA key generation uses GMP's `nextprime` function for probabilistic primality testing.
The hardware RNG uses the RDRAND instruction of recent x86 processors, if supported. It is not available on other platforms.
The seeded PRNG is just the Chacha20 stream cipher encrypting the all-zeroes message. The seed is used as the Chacha20 key. An alternate seeded PRNG is provided, based on AES encryption of a 128-bit counter. Both PRNGs pass the Dieharder statistical tests. Still, better use the system RNG or the hardware RNG if high-quality random numbers are needed.
## Performance
If you configure with the options `--enable-tests --enable-bench`, then do `make test`, a simple benchmark is performed and shows the speed of various operations from this library.
(* OASIS_START *)
(* DO NOT EDIT (digest: 54340abf9f934bc8c8a02312afd5aa74) *)
(* DO NOT EDIT (digest: 38dc311195a3981d90ae188e25b31bc8) *)
cryptokit - Cryptographic primitives
====================================
......@@ -8,7 +8,7 @@ This library provides a variety of cryptographic primitives that can be used
to implement cryptographic protocols in security-sensitive applications. The
primitives provided include:
- Symmetric-key ciphers: AES, DES, Triple-DES, ARCfour,
- Symmetric-key ciphers: AES, Chacha20, Blowfish, DES, Triple-DES, ARCfour,
in ECB, CBC, CFB, OFB and counter modes.
- Public-key cryptography: RSA encryption, Diffie-Hellman key agreement. -
Hash functions and MACs: SHA-1, SHA-2, SHA-3, RIPEMD160, MD5,
......
OASISFormat: 0.3
Name: cryptokit
Version: 1.11
Version: 1.13
Authors: Xavier Leroy
License: LGPL-2 with OCaml linking exception
BuildTools: ocamlbuild, ocamldoc
......@@ -12,7 +12,7 @@ Description:
to implement cryptographic protocols in security-sensitive applications. The
primitives provided include:
.
- Symmetric-key ciphers: AES, DES, Triple-DES, ARCfour,
- Symmetric-key ciphers: AES, Chacha20, Blowfish, DES, Triple-DES, ARCfour,
in ECB, CBC, CFB, OFB and counter modes.
- Public-key cryptography: RSA encryption, Diffie-Hellman key agreement.
- Hash functions and MACs: SHA-1, SHA-2, SHA-3, RIPEMD160, MD5,
......@@ -32,7 +32,7 @@ Flag zlib
Default$: !os_type(Win32)
Flag hardwaresupport
Description: Enable hardware support for AES (needs GCC or Clang)
Description: Enable hardware support for AES and GCM (needs GCC or Clang)
Default$: (architecture(amd64) || architecture(i386)) && !os_type(Win32)
Library cryptokit
......@@ -70,7 +70,10 @@ Library cryptokit
stubs-zlib.c,
keccak.h,
keccak.c,
stubs-sha3.c
stubs-sha3.c,
chacha20.h,
chacha20.c,
stubs-chacha20.c
BuildDepends: unix, zarith
if flag(zlib)
CCOpt: -DHAVE_ZLIB
......@@ -93,6 +96,14 @@ Executable test
Build$: flag(tests)
Install: false
Executable prngtest
Path: test
MainIs: prngtest.ml
CompiledObject: native
BuildDepends: cryptokit
Build$: flag(tests)
Install: false
Test main
Command: $test
TestTools: test
......@@ -123,11 +134,11 @@ Document "api-cryptokit"
XOCamlbuildLibraries: cryptokit
SourceRepository head
Type: svn
Location: http://scm.ocamlcore.org/svnroot/cryptokit/trunk
Browser: https://forge.ocamlcore.org/scm/browser.php?group_id=133
Type: git
Location: https://github.com/xavierleroy/cryptokit
Browser: https://github.com/xavierleroy/cryptokit
SourceRepository this
Type: svn
Location: http://scm.ocamlcore.org/svnroot/tags/release111
Browser: https://forge.ocamlcore.org/scm/browser.php?group_id=133
Type: git
Location: https://github.com/xavierleroy/cryptokit/releases/tag/release113
Browser: https://github.com/xavierleroy/cryptokit/releases/tag/release113
# OASIS_START
# DO NOT EDIT (digest: 0942acdef56237583b50126ab62c0ec8)
# DO NOT EDIT (digest: 62ba61e1d8ad56a1e96795f7c6fb78e2)
# Ignore VCS directories, you can use the same kind of rule outside
# OASIS_START/STOP if you want to exclude directories that contains
# useless stuff for the build process
......@@ -40,6 +40,8 @@ true: annot, bin_annot
"src/stubs-zlib.c": oasis_library_cryptokit_ccopt
"src/keccak.c": oasis_library_cryptokit_ccopt
"src/stubs-sha3.c": oasis_library_cryptokit_ccopt
"src/chacha20.c": oasis_library_cryptokit_ccopt
"src/stubs-chacha20.c": oasis_library_cryptokit_ccopt
<src/cryptokit.{cma,cmxa}>: oasis_library_cryptokit_cclib
"src/libcryptokit_stubs.lib": oasis_library_cryptokit_cclib
"src/dllcryptokit_stubs.dll": oasis_library_cryptokit_cclib
......@@ -94,10 +96,18 @@ true: annot, bin_annot
"src/keccak.c": pkg_zarith
"src/stubs-sha3.c": pkg_unix
"src/stubs-sha3.c": pkg_zarith
"src/chacha20.c": pkg_unix
"src/chacha20.c": pkg_zarith
"src/stubs-chacha20.c": pkg_unix
"src/stubs-chacha20.c": pkg_zarith
# Executable test
"test/test.native": pkg_unix
"test/test.native": pkg_zarith
"test/test.native": use_cryptokit
# Executable prngtest
"test/prngtest.native": pkg_unix
"test/prngtest.native": pkg_zarith
"test/prngtest.native": use_cryptokit
# Executable speedtest
"test/speedtest.native": pkg_unix
"test/speedtest.native": pkg_zarith
......
ci = require("ci")
oasis = require("oasis")
dist = require("dist")
ci.init()
oasis.init()
ci.prependenv("PATH", "/usr/opt/godi/bin")
ci.prependenv("PATH", "/usr/opt/godi/sbin")
ci.putenv("OUNIT_OUTPUT_HTML_DIR", dist.make_filename("ounit-log.html"))
ci.putenv("OUNIT_OUTPUT_JUNIT_FILE", dist.make_filename("junit.xml"))
ci.putenv("OUNIT_OUTPUT_FILE", dist.make_filename("ounit-log.txt"))
oasis.std_process("--enable-tests")
cryptokit (1.13-1) UNRELEASED; urgency=medium
* New upstream release
* Update Vcs-*
* Remove Samuel from Uploaders
* Bump debhelper compat level to 12
* Bump Standards-Version to 4.4.0
-- Stéphane Glondu <glondu@debian.org> Sat, 03 Aug 2019 10:15:54 +0200
cryptokit (1.11-1) unstable; urgency=medium
* New upstream release
......
......@@ -4,18 +4,17 @@ Priority: optional
Maintainer: Debian OCaml Maintainers <debian-ocaml-maint@lists.debian.org>
Uploaders:
Ralf Treinen <treinen@debian.org>,
Samuel Mimram <smimram@debian.org>,
Stéphane Glondu <glondu@debian.org>,
Mehdi Dogguy <mehdi@debian.org>
Build-Depends:
ocaml-findlib (>= 1.4),
ocaml-nox (>= 4),
debhelper (>= 10),
debhelper (>= 12),
zlib1g-dev,
ocamlbuild,
libzarith-ocaml-dev,
dh-ocaml (>= 0.9)
Standards-Version: 4.0.0
Standards-Version: 4.4.0
Homepage: https://github.com/xavierleroy/cryptokit
Vcs-Git: https://salsa.debian.org/ocaml-team/cryptokit.git
Vcs-Browser: https://salsa.debian.org/ocaml-team/cryptokit
......
......@@ -30,6 +30,6 @@ override_dh_auto_install:
override_dh_auto_clean:
ocaml setup.ml -distclean
.PHONY: override_dh_install
override_dh_install:
dh_install --fail-missing -X.so.owner
.PHONY: override_dh_missing
override_dh_missing:
dh_missing --fail-missing -X.so.owner
abort-on-upstream-changes
unapply-patches
(* OASIS_START *)
(* DO NOT EDIT (digest: 24b175474dc2908a1391cac648439f5e) *)
(* DO NOT EDIT (digest: 7ab3acc49c3c9131310ec300b2562fe8) *)
module OASISGettext = struct
(* # 22 "src/oasis/OASISGettext.ml" *)
let ns_ str =
str
let s_ str =
str
let f_ (str: ('a, 'b, 'c, 'd) format4) =
str
let ns_ str = str
let s_ str = str
let f_ (str: ('a, 'b, 'c, 'd) format4) = str
let fn_ fmt1 fmt2 n =
......@@ -23,10 +16,7 @@ module OASISGettext = struct
fmt2^^""
let init =
[]
let init = []
end
module OASISString = struct
......@@ -115,10 +105,7 @@ module OASISString = struct
ok := false;
incr str_idx
done;
if !what_idx = String.length what then
true
else
false
!what_idx = String.length what
let strip_starts_with ~what str =
......@@ -141,10 +128,7 @@ module OASISString = struct
ok := false;
decr str_idx
done;
if !what_idx = -1 then
true
else
false
!what_idx = -1
let strip_ends_with ~what str =
......@@ -189,19 +173,181 @@ module OASISString = struct
end
module OASISExpr = struct
(* # 22 "src/oasis/OASISExpr.ml" *)
module OASISUtils = struct
(* # 22 "src/oasis/OASISUtils.ml" *)
open OASISGettext
module MapExt =
struct
module type S =
sig
include Map.S
val add_list: 'a t -> (key * 'a) list -> 'a t
val of_list: (key * 'a) list -> 'a t
val to_list: 'a t -> (key * 'a) list
end
module Make (Ord: Map.OrderedType) =
struct
include Map.Make(Ord)
open OASISGettext
let rec add_list t =
function
| (k, v) :: tl -> add_list (add k v t) tl
| [] -> t
let of_list lst = add_list empty lst
type test = string
let to_list t = fold (fun k v acc -> (k, v) :: acc) t []
end
end
module MapString = MapExt.Make(String)
module SetExt =
struct
module type S =
sig
include Set.S
val add_list: t -> elt list -> t
val of_list: elt list -> t
val to_list: t -> elt list
end
module Make (Ord: Set.OrderedType) =
struct
include Set.Make(Ord)
let rec add_list t =
function
| e :: tl -> add_list (add e t) tl
| [] -> t
let of_list lst = add_list empty lst
let to_list = elements
end
end
module SetString = SetExt.Make(String)
let compare_csl s1 s2 =
String.compare (OASISString.lowercase_ascii s1) (OASISString.lowercase_ascii s2)
module HashStringCsl =
Hashtbl.Make
(struct
type t = string
let equal s1 s2 = (compare_csl s1 s2) = 0
let hash s = Hashtbl.hash (OASISString.lowercase_ascii s)
end)
module SetStringCsl =
SetExt.Make
(struct
type t = string
let compare = compare_csl
end)
let varname_of_string ?(hyphen='_') s =
if String.length s = 0 then
begin
invalid_arg "varname_of_string"
end
else
begin
let buf =
OASISString.replace_chars
(fun c ->
if ('a' <= c && c <= 'z')
||
('A' <= c && c <= 'Z')
||
('0' <= c && c <= '9') then
c
else
hyphen)
s;
in
let buf =
(* Start with a _ if digit *)
if '0' <= s.[0] && s.[0] <= '9' then
"_"^buf
else
buf
in
OASISString.lowercase_ascii buf
end
let varname_concat ?(hyphen='_') p s =
let what = String.make 1 hyphen in
let p =
try
OASISString.strip_ends_with ~what p
with Not_found ->
p
in
let s =
try
OASISString.strip_starts_with ~what s
with Not_found ->
s
in
p^what^s
let is_varname str =
str = varname_of_string str
let failwithf fmt = Printf.ksprintf failwith fmt
let rec file_location ?pos1 ?pos2 ?lexbuf () =
match pos1, pos2, lexbuf with
| Some p, None, _ | None, Some p, _ ->
file_location ~pos1:p ~pos2:p ?lexbuf ()
| Some p1, Some p2, _ ->
let open Lexing in
let fn, lineno = p1.pos_fname, p1.pos_lnum in
let c1 = p1.pos_cnum - p1.pos_bol in
let c2 = c1 + (p2.pos_cnum - p1.pos_cnum) in
Printf.sprintf (f_ "file %S, line %d, characters %d-%d") fn lineno c1 c2
| _, _, Some lexbuf ->
file_location
~pos1:(Lexing.lexeme_start_p lexbuf)
~pos2:(Lexing.lexeme_end_p lexbuf)
()
| None, None, None ->
s_ "<position undefined>"
let failwithpf ?pos1 ?pos2 ?lexbuf fmt =
let loc = file_location ?pos1 ?pos2 ?lexbuf () in
Printf.ksprintf (fun s -> failwith (Printf.sprintf "%s: %s" loc s)) fmt
end
module OASISExpr = struct
(* # 22 "src/oasis/OASISExpr.ml" *)
open OASISGettext
open OASISUtils
type test = string
type flag = string
......@@ -214,7 +360,6 @@ module OASISExpr = struct
| ETest of test * string
type 'a choices = (t * 'a) list
......@@ -289,7 +434,7 @@ module OASISExpr = struct
end
# 292 "myocamlbuild.ml"
# 437 "myocamlbuild.ml"
module BaseEnvLight = struct
(* # 22 "src/base/BaseEnvLight.ml" *)
......@@ -300,24 +445,12 @@ module BaseEnvLight = struct
type t = string MapString.t
let default_filename =
Filename.concat
(Sys.getcwd ())
"setup.data"
let default_filename = Filename.concat (Sys.getcwd ()) "setup.data"
let load ?(allow_empty=false) ?(filename=default_filename) () =
if Sys.file_exists filename then
begin
let chn =
open_in_bin filename
in
let st =
Stream.of_channel chn
in
let line =
ref 1
in
let load ?(allow_empty=false) ?(filename=default_filename) ?stream () =
let line = ref 1 in
let lexer st =
let st_line =
Stream.from
(fun _ ->
......@@ -327,47 +460,40 @@ module BaseEnvLight = struct
| c -> Some c
with Stream.Failure -> None)
in
let lexer =
Genlex.make_lexer ["="] st_line
in
let rec read_file mp =
match Stream.npeek 3 lexer with
let rec read_file lxr mp =
match Stream.npeek 3 lxr with
| [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] ->
Stream.junk lexer;
Stream.junk lexer;
Stream.junk lexer;
read_file (MapString.add nm value mp)
| [] ->
mp
Stream.junk lxr; Stream.junk lxr; Stream.junk lxr;
read_file lxr (MapString.add nm value mp)
| [] -> mp
| _ ->
failwith
(Printf.sprintf
"Malformed data file '%s' line %d"
filename !line)
in
let mp =
read_file MapString.empty
(Printf.sprintf "Malformed data file '%s' line %d" filename !line)
in
close_in chn;
mp
end
else if allow_empty then
begin
match stream with
| Some st -> read_file (lexer st) MapString.empty
| None ->
if Sys.file_exists filename then begin
let chn = open_in_bin filename in
let st = Stream.of_channel chn in
try
let mp = read_file (lexer st) MapString.empty in
close_in chn; mp
with e ->
close_in chn; raise e
end else if allow_empty then begin
MapString.empty
end
else
begin
end else begin
failwith
(Printf.sprintf
"Unable to load environment, the file '%s' doesn't exist."
filename)
end
let rec var_expand str env =
let buff =
Buffer.create ((String.length str) * 2)
in
let buff = Buffer.create ((String.length str) * 2) in
Buffer.add_substitute
buff
(fun var ->
......@@ -383,49 +509,39 @@ module BaseEnvLight = struct
Buffer.contents buff
let var_get name env =
var_expand (MapString.find name env) env
let var_choose lst env =
OASISExpr.choose
(fun nm -> var_get nm env)
lst
let var_get name env = var_expand (MapString.find name env) env
let var_choose lst env = OASISExpr.choose (fun nm -> var_get nm env) lst
end
# 397 "myocamlbuild.ml"
# 517 "myocamlbuild.ml"
module MyOCamlbuildFindlib = struct
(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *)
(** OCamlbuild extension, copied from
* http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild
* https://ocaml.org/learn/tutorials/ocamlbuild/Using_ocamlfind_with_ocamlbuild.html
* by N. Pouillard and others
*
* Updated on 2009/02/28
* Updated on 2016-06-02
*
* Modified by Sylvain Le Gall
*)
open Ocamlbuild_plugin
type conf =
{ no_automatic_syntax: bool;
}
(* these functions are not really officially exported *)
let run_and_read =
Ocamlbuild_pack.My_unix.run_and_read
type conf = {no_automatic_syntax: bool}
let run_and_read = Ocamlbuild_pack.My_unix.run_and_read
let blank_sep_strings =
Ocamlbuild_pack.Lexers.blank_sep_strings
let blank_sep_strings = Ocamlbuild_pack.Lexers.blank_sep_strings
let exec_from_conf exec =
let exec =
let env_filename = Pathname.basename BaseEnvLight.default_filename in
let env = BaseEnvLight.load ~filename:env_filename ~allow_empty:true () in
let env = BaseEnvLight.load ~allow_empty:true () in
try
BaseEnvLight.var_get exec env
with Not_found ->
......@@ -447,6 +563,7 @@ module MyOCamlbuildFindlib = struct
in
fix_win32 exec
let split s ch =
let buf = Buffer.create 13 in
let x = ref [] in
......@@ -516,11 +633,13 @@ module MyOCamlbuildFindlib = struct
| After_rules ->
(* Avoid warnings for unused tag *)
flag ["tests"] N;
(* When one link an OCaml library/binary/package, one should use
* -linkpkg *)
flag ["ocaml"; "link"; "program"] & A"-linkpkg";
if not (conf.no_automatic_syntax) then begin
(* For each ocamlfind package one inject the -package option when
* compiling, computing dependencies, generating documentation and
* linking. *)
......@@ -533,8 +652,9 @@ module MyOCamlbuildFindlib = struct
(* Heuristic to identify syntax extensions: whether they end in
".syntax"; some might not.
*)
if Filename.check_suffix pkg "syntax" ||
List.mem pkg well_known_syntax then
if not (conf.no_automatic_syntax) &&
(Filename.check_suffix pkg "syntax" ||
List.mem pkg well_known_syntax) then
(syn_args @ base_args, syn_args)
else
(base_args, [])
......@@ -552,7 +672,6 @@ module MyOCamlbuildFindlib = struct
flag ["ocaml"; "infer_interface"; "package("^pkg^")"] & S pargs;
end
(find_packages ());
end;
(* Like -package but for extensions syntax. Morover -syntax is useless
* when linking. *)
......@@ -576,10 +695,12 @@ module MyOCamlbuildFindlib = struct
flag ["ocaml"; "pkg_threads"; "doc"] (S[A "-I"; A "+threads"]);
flag ["ocaml"; "pkg_threads"; "link"] (S[A "-thread"]);
flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"]);
flag ["c"; "pkg_threads"; "compile"] (S[A "-thread"]);
flag ["ocaml"; "package(threads)"; "compile"] (S[A "-thread"]);
flag ["ocaml"; "package(threads)"; "doc"] (S[A "-I"; A "+threads"]);
flag ["ocaml"; "package(threads)"; "link"] (S[A "-thread"]);
flag ["ocaml"; "package(threads)"; "infer_interface"] (S[A "-thread"]);
flag ["c"; "package(threads)"; "compile"] (S[A "-thread"]);
| _ ->
()
......@@ -594,9 +715,6 @@ module MyOCamlbuildBase = struct
*)
open Ocamlbuild_plugin
module OC = Ocamlbuild_pack.Ocaml_compiler
......@@ -607,9 +725,6 @@ module MyOCamlbuildBase = struct
type tag = string
(* # 62 "src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
type t =
{
lib_ocaml: (name * dir list * string list) list;
......@@ -622,9 +737,10 @@ module MyOCamlbuildBase = struct
}
let env_filename =
Pathname.basename
BaseEnvLight.default_filename
(* # 110 "src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
let env_filename = Pathname.basename BaseEnvLight.default_filename
let dispatch_combine lst =
......@@ -643,12 +759,7 @@ module MyOCamlbuildBase = struct
let dispatch t e =
let env =
BaseEnvLight.load
~filename:env_filename
~allow_empty:true
()
in
let env = BaseEnvLight.load ~allow_empty:true () in
match e with
| Before_options ->
let no_trailing_dot s =
......@@ -712,6 +823,7 @@ module MyOCamlbuildBase = struct
flag ["link"; "library"; "ocaml"; "native"; tag_libstubs lib]
(S[A"-cclib"; A("-l"^(nm_libstubs lib))]);
if bool_of_string (BaseEnvLight.var_get "native_dynlink" env) then
flag ["link"; "program"; "ocaml"; "byte"; tag_libstubs lib]
(S[A"-dllib"; A("dll"^(nm_libstubs lib))]);
......@@ -763,7 +875,7 @@ module MyOCamlbuildBase = struct
end
# 766 "myocamlbuild.ml"
# 878 "myocamlbuild.ml"
open Ocamlbuild_plugin;;
let package_default =
{
......@@ -782,7 +894,8 @@ let package_default =
"src/sha1.h";
"src/sha256.h";
"src/sha512.h";
"src/keccak.h"
"src/keccak.h";
"src/chacha20.h"
])
];
flags =
......@@ -1089,6 +1202,6 @@ let conf = {MyOCamlbuildFindlib.no_automatic_syntax = false}
let dispatch_default = MyOCamlbuildBase.dispatch_default conf package_default;;
# 1093 "myocamlbuild.ml"
# 1206 "myocamlbuild.ml"
(* OASIS_STOP *)
Ocamlbuild_plugin.dispatch dispatch_default;;
This diff is collapsed.
arcfour.o: arcfour.c arcfour.h
blowfish.o: blowfish.c blowfish.h
d3des.o: d3des.c d3des.h
rijndael-alg-fst.o: rijndael-alg-fst.c rijndael-alg-fst.h
ripemd160.o: ripemd160.c ripemd160.h
sha1.o: sha1.c sha1.h
sha256.o: sha256.c sha256.h
stubs-aes.o: stubs-aes.c rijndael-alg-fst.h
stubs-arcfour.o: stubs-arcfour.c arcfour.h
stubs-blowfish.o: stubs-blowfish.c blowfish.h
stubs-des.o: stubs-des.c d3des.h
stubs-md5.o: stubs-md5.c
stubs-misc.o: stubs-misc.c
stubs-ripemd160.o: stubs-ripemd160.c ripemd160.h
stubs-rng.o: stubs-rng.c
stubs-sha1.o: stubs-sha1.c sha1.h
stubs-sha256.o: stubs-sha256.c sha256.h
stubs-zlib.o: stubs-zlib.c
cryptokit.cmi:
cryptokit.cmo: cryptokit.cmi
cryptokit.cmx: cryptokit.cmi
# OASIS_START
# DO NOT EDIT (digest: 50ed06596b6c30f4761d9ed7f75fb433)
version = "1.11"
# DO NOT EDIT (digest: 7cb4f4b2e0b5e77bb7a0ee261fd36f90)
version = "1.13"
description = "Cryptographic primitives"
requires = "unix zarith"
archive(byte) = "cryptokit.cma"
......
......@@ -18,16 +18,20 @@
#ifdef __AES__
#include <wmmintrin.h>
#include <cpuid.h>
#include <stdint.h>
int aesni_available = -1;
int aesni_check_available(void)
{
unsigned int ax, bx, cx, dx;
__asm__ __volatile__ ("cpuid"
: "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx)
: "a" (1));
return (aesni_available = (cx & 0x2000000) != 0);
unsigned int eax, ebx, ecx, edx;
if(__get_cpuid(1, &eax, &ebx, &ecx, &edx)) {
aesni_available = (ecx & 0x2000000) != 0;
} else {
aesni_available = 0;
}
return aesni_available;
}
static inline __m128i aesni_128_assist(__m128i t1, __m128i t2)
......@@ -213,11 +217,19 @@ static int aesni_key_expansion(const unsigned char * userkey,
}
}
static void * align16(void * p)
{
uintptr_t n = (uintptr_t) p;
n = (n + 15) & -16;
return (void *) n;
}
int aesniKeySetupEnc(unsigned char * ckey,
const unsigned char * key,
int keylength)
{
__m128i key_schedule[15];
__m128i unaligned_key_schedule[15 + 1]; /* + 1 to leave space for alignment */
__m128i *key_schedule = align16(unaligned_key_schedule);
int nrounds, i;
nrounds = aesni_key_expansion(key, keylength, key_schedule);
......@@ -231,7 +243,8 @@ int aesniKeySetupDec(unsigned char * ckey,
const unsigned char * key,
int keylength)
{
__m128i key_schedule[15];
__m128i unaligned_key_schedule[15 + 1]; /* + 1 to leave space for alignment */
__m128i *key_schedule = align16(unaligned_key_schedule);
int nrounds, i;
nrounds = aesni_key_expansion(key, keylength, key_schedule);
......
/* Based on D. J. Bernstein's chacha-regs.c version 200801118,
https://cr.yp.to/streamciphers/timings/estreambench/submissions/salsa20/chacha8/regs/chacha.c
The initial code is in the public domain */
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <caml/config.h>
#include "chacha20.h"
static inline void U32TO8_LITTLE(uint8_t * dst, uint32_t val)
{
#ifdef ARCH_BIG_ENDIAN
dst[0] = val;
dst[1] = val >> 8;
dst[2] = val >> 16;
dst[3] = val >> 24;
#else
*((uint32_t *) dst) = val;
#endif
}
static inline uint32_t U8TO32_LITTLE(const uint8_t * src)
{
return (uint32_t) src[0]
+ ((uint32_t) src[1] << 8)
+ ((uint32_t) src[2] << 16)
+ ((uint32_t) src[3] << 24);
}
#define ROTATE(v,c) ((v) << (c) | (v) >> (32 - (c)))
#define XOR(v,w) ((v) ^ (w))
#define PLUS(v,w) ((v) + (w))
#define PLUSONE(v) ((v) + 1)
#define QUARTERROUND(a,b,c,d) \
a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
static void chacha20_block(chacha20_ctx * ctx)
{
uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
int i;
x0 = ctx->input[0];
x1 = ctx->input[1];
x2 = ctx->input[2];
x3 = ctx->input[3];
x4 = ctx->input[4];
x5 = ctx->input[5];
x6 = ctx->input[6];
x7 = ctx->input[7];
x8 = ctx->input[8];
x9 = ctx->input[9];
x10 = ctx->input[10];
x11 = ctx->input[11];
x12 = ctx->input[12];
x13 = ctx->input[13];
x14 = ctx->input[14];
x15 = ctx->input[15];
for (i = 10; i > 0; i --) {
QUARTERROUND( x0, x4, x8,x12)
QUARTERROUND( x1, x5, x9,x13)
QUARTERROUND( x2, x6,x10,x14)
QUARTERROUND( x3, x7,x11,x15)
QUARTERROUND( x0, x5,x10,x15)
QUARTERROUND( x1, x6,x11,x12)
QUARTERROUND( x2, x7, x8,x13)
QUARTERROUND( x3, x4, x9,x14)
}
x0 = PLUS(x0,ctx->input[0]);
x1 = PLUS(x1,ctx->input[1]);
x2 = PLUS(x2,ctx->input[2]);
x3 = PLUS(x3,ctx->input[3]);
x4 = PLUS(x4,ctx->input[4]);
x5 = PLUS(x5,ctx->input[5]);
x6 = PLUS(x6,ctx->input[6]);
x7 = PLUS(x7,ctx->input[7]);
x8 = PLUS(x8,ctx->input[8]);
x9 = PLUS(x9,ctx->input[9]);
x10 = PLUS(x10,ctx->input[10]);
x11 = PLUS(x11,ctx->input[11]);
x12 = PLUS(x12,ctx->input[12]);
x13 = PLUS(x13,ctx->input[13]);
x14 = PLUS(x14,ctx->input[14]);
x15 = PLUS(x15,ctx->input[15]);
U32TO8_LITTLE(ctx->output + 0,x0);
U32TO8_LITTLE(ctx->output + 4,x1);
U32TO8_LITTLE(ctx->output + 8,x2);
U32TO8_LITTLE(ctx->output + 12,x3);
U32TO8_LITTLE(ctx->output + 16,x4);
U32TO8_LITTLE(ctx->output + 20,x5);
U32TO8_LITTLE(ctx->output + 24,x6);
U32TO8_LITTLE(ctx->output + 28,x7);
U32TO8_LITTLE(ctx->output + 32,x8);
U32TO8_LITTLE(ctx->output + 36,x9);
U32TO8_LITTLE(ctx->output + 40,x10);
U32TO8_LITTLE(ctx->output + 44,x11);
U32TO8_LITTLE(ctx->output + 48,x12);
U32TO8_LITTLE(ctx->output + 52,x13);
U32TO8_LITTLE(ctx->output + 56,x14);
U32TO8_LITTLE(ctx->output + 60,x15);
/* Increment the 64-bit counter and, on overflow, the 64-bit nonce */
/* (Incrementing the nonce is not standard but a reasonable default.) */
if (++ ctx->input[12] == 0)
if (++ ctx->input[13] == 0)
if (++ ctx->input[14] == 0)
++ ctx->input[15];
}
void chacha20_transform(chacha20_ctx * ctx,
const uint8_t * in, uint8_t * out, size_t len)
{
int n = ctx->next;
for (/*nothing*/; len > 0; len--) {
if (n >= 64) { chacha20_block(ctx); n = 0; }
*out++ = *in++ ^ ctx->output[n++];
}
ctx->next = n;
}
void chacha20_extract(chacha20_ctx * ctx,
uint8_t * out, size_t len)
{
int n = ctx->next;
for (/*nothing*/; len > 0; len--) {
if (n >= 64) { chacha20_block(ctx); n = 0; }
*out++ = ctx->output[n++];
}
ctx->next = n;
}
void chacha20_init(chacha20_ctx * ctx,
const uint8_t * key, size_t key_length,
const uint8_t iv[8],
uint64_t counter)
{
const uint8_t *constants =
(uint8_t *) (key_length == 32 ? "expand 32-byte k" : "expand 16-byte k");
assert (key_length == 16 || key_length == 32);
ctx->input[0] = U8TO32_LITTLE(constants + 0);
ctx->input[1] = U8TO32_LITTLE(constants + 4);
ctx->input[2] = U8TO32_LITTLE(constants + 8);
ctx->input[3] = U8TO32_LITTLE(constants + 12);
ctx->input[4] = U8TO32_LITTLE(key + 0);
ctx->input[5] = U8TO32_LITTLE(key + 4);
ctx->input[6] = U8TO32_LITTLE(key + 8);
ctx->input[7] = U8TO32_LITTLE(key + 12);
if (key_length == 32) key += 16;
ctx->input[8] = U8TO32_LITTLE(key + 0);
ctx->input[9] = U8TO32_LITTLE(key + 4);
ctx->input[10] = U8TO32_LITTLE(key + 8);
ctx->input[11] = U8TO32_LITTLE(key + 12);
ctx->input[12] = (uint32_t) counter;
ctx->input[13] = (uint32_t) (counter >> 32);
ctx->input[14] = U8TO32_LITTLE(iv + 0);
ctx->input[15] = U8TO32_LITTLE(iv + 4);
ctx->next = 64;
}
/* Based on D. J. Bernstein's chacha-regs.c version 200801118,
https://cr.yp.to/streamciphers/timings/estreambench/submissions/salsa20/chacha8/regs/chacha.c
The initial code is in the public domain */
#include <stddef.h>
#include <stdint.h>
typedef struct {
uint32_t input[16]; /* The current state */
uint8_t output[64]; /* Output data for the current state */
int next; /* Index of next unused byte in output */
} chacha20_ctx;
void chacha20_init(chacha20_ctx * ctx,
const uint8_t * key, size_t key_length,
const uint8_t iv[8],
uint64_t ctr);
void chacha20_extract(chacha20_ctx * ctx,
uint8_t * out, size_t len);
void chacha20_transform(chacha20_ctx * ctx,
const uint8_t * in, uint8_t * out, size_t len);