Merge branch 'master' into m/eyre-kill-channels

This commit is contained in:
Fang 2020-06-18 22:23:47 +02:00
commit b2600f553c
No known key found for this signature in database
GPG Key ID: EB035760C1BBA972
48 changed files with 1848 additions and 163 deletions

View File

@ -2,45 +2,53 @@ jobs:
include:
- os: linux
language: nix
nix: 2.1.3
env: STACK_YAML=pkg/hs/stack.yaml
nix: 2.3.6
before_install:
- git lfs pull
- sh/travis-install-stack
install:
- nix-env -iA cachix -f https://cachix.org/api/v1/install
- stack --no-terminal --install-ghc build urbit-king --only-dependencies
script:
- cachix use urbit2
- ./sh/cachix
- make build
- make release
- sh/release-king-linux64-dynamic
- sh/ci-tests
- os: linux
language: generic
env: STACK_YAML=pkg/hs/stack.yaml
cache:
directories:
- $HOME/.ghc
- $HOME/.cabal
- $HOME/.stack
- $TRAVIS_BUILD_DIR/.stack-work
before_install:
- sh/travis-install-stack
install:
- stack --no-terminal --install-ghc build urbit-king --only-dependencies
script:
- stack test
- sh/release-king-linux64-dynamic
- os: osx
language: generic
sudo: required
env: STACK_YAML=pkg/hs/stack.yaml
cache:
directories:
- $HOME/.ghc
- $HOME/.cabal
- $HOME/.stack
- $TRAVIS_BUILD_DIR/.stack-work
before_install:
- sh/travis-install-stack
install:
- stack --no-terminal --install-ghc build urbit-king --only-dependencies
script:
- stack test
- sh/release-king-darwin-dynamic
cache:
directories:
- $HOME/.ghc
- $HOME/.cabal
- $HOME/.stack
- $TRAVIS_BUILD_DIR/.stack-work
deploy:
- skip_cleanup: true
provider: gcs

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:801eb8574daff9f0ac88e2e40dab09d95bd8d667df953e971501a1f8db4fd039
size 10394205
oid sha256:f18a8670a53dc7fe0a3660c639a46e7c9d900ebd235d41e78ceb5af6807ff1ad
size 11350224

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9d131da321b891c126f62cc587c5e27c257695ff9ae15e502356159fba7f9bf3
size 1234415
oid sha256:ac18ec9cb1035466d9aef16371738ea80f2b1d13206afb44a8ba37e0a1db812b
size 1265214

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2c0c3e34876875722a8505d8e98843738460d6d8b3ab8872274a876f7859ae71
size 17336122
oid sha256:657e130a063598dc9e4800039f6dde1e7e4b7a3c56e57561a46a4f06641da48e
size 17337052

View File

@ -38,8 +38,9 @@ herb ./ship -p test -d ':- %renders /'
herb ./ship -d '~& %finish-test-renders ~'
# Run the test generator
herb ./ship -d '+test, =seed `@uvI`(shaz %reproducible)' |
tee test-generator-output
herb ./ship -d '+test, =seed `@uvI`(shaz %reproducible)' > test-generator-output
cat test-generator-output || true
herb ./ship -p hood -d '+hood/mass'

View File

@ -14,9 +14,13 @@ let
inherit (deps) ed25519;
};
libaes_siv = import ./libaes_siv {
inherit pkgs;
};
mkUrbit = { debug }:
import ./urbit {
inherit pkgs ent debug ge-additions;
inherit pkgs ent debug ge-additions libaes_siv;
inherit (deps) argon2 murmur3 uv ed25519 sni scrypt softfloat3;
inherit (deps) secp256k1 h2o ivory-header ca-header;
};
@ -26,4 +30,4 @@ let
in
{ inherit ent ge-additions arvo arvo-ropsten herb urbit urbit-debug; }
{ inherit ent ge-additions libaes_siv arvo arvo-ropsten herb urbit urbit-debug; }

View File

@ -0,0 +1,7 @@
source $stdenv/setup
cp -r $src ./src
chmod -R u+w ./src
cd ./src
PREFIX=$out make install

View File

@ -0,0 +1,12 @@
{ env_name, env, deps }:
env.make_derivation rec {
name = "libaes_siv";
builder = ./release.sh;
src = ../../../pkg/libaes_siv;
cross_inputs = [ env.openssl ];
CC = "${env.host}-gcc";
AR = "${env.host}-ar";
}

View File

@ -0,0 +1,9 @@
{ pkgs }:
pkgs.stdenv.mkDerivation rec {
name = "libaes_siv";
builder = ./builder.sh;
src = ../../../pkg/libaes_siv;
nativeBuildInputs = [ pkgs.openssl ];
}

View File

@ -0,0 +1,13 @@
source $setup
cp -r $src ./src
chmod -R u+w ./src
cd ./src
for dep in $cross_inputs; do
export CFLAGS="${CFLAGS-} -I$dep/include"
export LDFLAGS="${LDFLAGS-} -L$dep/lib"
done
PREFIX=$out make install

View File

@ -1,7 +1,7 @@
{
pkgs,
debug,
argon2, ed25519, ent, ge-additions, h2o, murmur3, scrypt, secp256k1, sni, softfloat3, uv, ivory-header, ca-header
argon2, ed25519, ent, ge-additions, libaes_siv, h2o, murmur3, scrypt, secp256k1, sni, softfloat3, uv, ivory-header, ca-header
}:
let
@ -21,7 +21,7 @@ let
[ curl gmp libsigsegv ncurses openssl zlib lmdb ];
vendor =
[ argon2 softfloat3 ed25519 ent ge-additions h2o scrypt uv murmur3 secp256k1 sni ivory-header ca-header ];
[ argon2 softfloat3 ed25519 ent ge-additions libaes_siv h2o scrypt uv murmur3 secp256k1 sni ivory-header ca-header ];
urbit = pkgs.stdenv.mkDerivation {
inherit name meta;

View File

@ -4,7 +4,8 @@
ent,
name ? "urbit",
debug ? false,
ge-additions
ge-additions,
libaes_siv
}:
let
@ -15,7 +16,7 @@ let
vendor =
with deps;
[ argon2 softfloat3 ed25519 ge-additions h2o scrypt uv murmur3 secp256k1 sni ivory-header ca-header ];
[ argon2 softfloat3 ed25519 ge-additions libaes_siv h2o scrypt uv murmur3 secp256k1 sni ivory-header ca-header ];
in

View File

@ -10,7 +10,7 @@ import ./default.nix {
inherit pkgs;
debug = false;
inherit (tlon)
ent ge-additions;
ent ge-additions libaes_siv;
inherit (deps)
argon2 ed25519 h2o murmur3 scrypt secp256k1 sni softfloat3 uv ivory-header ca-header;
}

View File

@ -19,12 +19,16 @@ let
ge-additions = env:
import ./pkgs/ge-additions/cross.nix env;
libaes_siv = env:
import ./pkgs/libaes_siv/cross.nix env;
urbit = { env, debug }:
import ./pkgs/urbit/release.nix env {
inherit debug;
name = if debug then "urbit-debug" else "urbit";
ent = ent env;
ge-additions = ge-additions env;
libaes_siv = libaes_siv env;
};
builds-for-platform = plat:
@ -33,6 +37,7 @@ let
inherit (plat.env) cmake_toolchain;
ent = ent plat;
ge-additions = ge-additions plat;
libaes_siv = libaes_siv plat;
urbit = urbit { env = plat; debug = false; };
urbit-debug = urbit { env = plat; debug = true; };
};

View File

@ -381,6 +381,7 @@
:* [%give %kick ~[[%mailbox path.act]] ~]
[%give %fact [/synced]~ %chat-hook-update !>([%initial synced])]
(pull-wire u.ship [%mailbox path.act])
(pull-wire u.ship [%store path.act])
(pull-backlog-subscriptions u.ship path.act)
==
==

View File

@ -1213,7 +1213,7 @@
::
=/ raw
~& [%hoon-compile `@p`(mug hun)]
(ride %noun hun)
(road |.((ride %noun hun)))
:: activate the new compiler gate, producing +ride
::
=/ cop .*(0 +.raw)
@ -1226,11 +1226,13 @@
::
:: hot: raw compiler formula
::
=> ?: =(nex hoon-version)
[hot=`*`raw .]
~& [%hoon-compile-upgrade nex]
=/ hot (slum cop [%noun hun])
.(cop .*(0 +.hot))
=^ hot=* cop
?: =(nex hoon-version)
[raw cop]
~& [%hoon-compile-upgrade nex]
%- road |.
=/ hot (slum cop [%noun hun])
[hot .*(0 +.hot)]
:: extract the hoon core from the outer gate (+ride)
::
=/ hoc .*(cop [%0 7])
@ -1241,7 +1243,7 @@
::
=/ rav
~& [%arvo-compile `@p`(mug hyp) `@p`(mug van)]
(slum cop [hyp van])
(road |.((slum cop [hyp van])))
:: activate arvo, and extract the arvo core from the outer gate
::
=/ voc .*(hoc [%7 +.rav %0 7])

View File

@ -12035,6 +12035,15 @@
?~ a !!
~_(i.a $(a t.a))
::
++ road
|* =(trap *)
^+ $:trap
=/ res (mule trap)
?- -.res
%& p.res
%| (mean leaf+"road: new" p.res)
==
::
++ slew :: get axis in vase
|= {axe/@ vax/vase} ^- (unit vase)
?. |- ^- ?

View File

@ -620,12 +620,14 @@
?~ t.t.t.wire
=/ full-wire sys+wire
=/ stand
%+ ~(gut by outstanding.agents.state) [full-wire hen]
:: default is do nothing; should only hit if cleared queue
:: in +load 3-to-4
::
(~(gut by outstanding.agents.state) [full-wire hen] ~)
::
:: default is to send both ack types; should only hit if
:: cleared queue in +load 3-to-4 or +load-4-to-5
::
=? stand ?=(~ stand)
(~(put to *(qeu remote-request)) %missing)
~| [full-wire=full-wire hen=hen stand=stand outs=outstanding.agents.state]
~| [full-wire=full-wire hen=hen stand=stand]
=^ rr stand ~(get to stand)
[rr (~(put by outstanding.agents.state) [full-wire hen] stand)]
:: non-null case of wire is old, remove on next breach after

View File

@ -3734,62 +3734,53 @@
:: :: ++s2va:aes:crypto
++ s2va :: AES-128 S2V
~/ %s2va
|= {key/@H ads/(list @)}
=+ res=(maca key `16 0x0)
%^ maca key ~
|- ^- @uxH
|= [key=@H ads=(list @)]
?~ ads (maca key `16 0x1)
=/ res (maca key `16 0x0)
%+ maca key
|- ^- [[~ @ud] @uxH]
?~ t.ads
?: (gte (xeb i.ads) 128)
(mix i.ads res)
%+ mix
(doub res)
(mpad (met 3 i.ads) i.ads)
=/ wyt (met 3 i.ads)
?: (gte wyt 16)
[`wyt (mix i.ads res)]
[`16 (mix (doub res) (mpad wyt i.ads))]
%= $
res %+ mix
(doub res)
(maca key ~ i.ads)
ads t.ads
res (mix (doub res) (maca key ~ i.ads))
==
:: :: ++s2vb:aes:crypto
++ s2vb :: AES-192 S2V
~/ %s2vb
|= {key/@I ads/(list @)}
=+ res=(macb key `16 0x0)
%^ macb key ~
|- ^- @uxH
|= [key=@I ads=(list @)]
?~ ads (macb key `16 0x1)
=/ res (macb key `16 0x0)
%+ macb key
|- ^- [[~ @ud] @uxH]
?~ t.ads
?: (gte (xeb i.ads) 128)
(mix i.ads res)
%+ mix
(doub res)
(mpad (met 3 i.ads) i.ads)
=/ wyt (met 3 i.ads)
?: (gte wyt 16)
[`wyt (mix i.ads res)]
[`16 (mix (doub res) (mpad wyt i.ads))]
%= $
res %+ mix
(doub res)
(macb key ~ i.ads)
ads t.ads
res (mix (doub res) (macb key ~ i.ads))
==
:: :: ++s2vc:aes:crypto
++ s2vc :: AES-256 S2V
~/ %s2vc
|= {key/@I ads/(list @)}
=+ res=(macc key `16 0x0)
%^ macc key ~
|- ^- @uxH
|= [key=@I ads=(list @)]
?~ ads (macc key `16 0x1)
=/ res (macc key `16 0x0)
%+ macc key
|- ^- [[~ @ud] @uxH]
?~ t.ads
?: (gte (xeb i.ads) 128)
(mix i.ads res)
%+ mix
(doub res)
(mpad (met 3 i.ads) i.ads)
=/ wyt (met 3 i.ads)
?: (gte wyt 16)
[`wyt (mix i.ads res)]
[`16 (mix (doub res) (mpad wyt i.ads))]
%= $
res %+ mix
(doub res)
(macc key ~ i.ads)
ads t.ads
res (mix (doub res) (macc key ~ i.ads))
==
:: :: ++siva:aes:crypto
++ siva :: AES-128 SIV

View File

@ -567,6 +567,18 @@
^- (list vector-siv)
:~
::
:: failed in the wild, see https://github.com/urbit/urbit/pull/3013
::
:^ 0xfdef.6253.d284.a940.1b5d.d1b7.fbcd.4489.
3071.bf93.ace9.37da.7c5d.77d2.1f3e.cda4.
83be.1c51.a88b.c9ba.8741.e1ee.935b.c0ef.
888a.feff.0249.bdb6.1344.0ff9.4e1b.fca5
ad=~
inp=0x97.0341.38e3.960e.87e1
:+ iv=0x249f.85e3.c9a8.29b6.3122.ec22.cde6.76df
len=9
cph=0xdc.bdcd.e4f1.4fd4.2d8d
::
:: from RFC 5297, with extended key
::
:^ 0xfffe.fdfc.fbfa.f9f8.f7f6.f5f4.f3f2.f1f0.

202
pkg/libaes_siv/COPYING Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

20
pkg/libaes_siv/Makefile Normal file
View File

@ -0,0 +1,20 @@
CC ?= cc
AR ?= ar
PREFIX ?= ./out
################################################################################
.PHONY: all test install clean
all: aes_siv.c aes_siv.h
$(CC) $(CFLAGS) -Wall -Wextra -Wstrict-prototypes -Wconversion -O3 -fomit-frame-pointer -funroll-loops -ftree-vectorize -DNDEBUG -c aes_siv.c
$(AR) rcs libaes_siv.a aes_siv.o
install: all
@mkdir -p $(PREFIX)/lib/
@mkdir -p $(PREFIX)/include/
cp libaes_siv.a $(PREFIX)/lib/
cp aes_siv.h $(PREFIX)/include/
clean:
rm -rf ./out

197
pkg/libaes_siv/README.md Normal file
View File

@ -0,0 +1,197 @@
# libaes_siv
This is an [RFC5297](https://tools.ietf.org/html/rfc5297)-compliant C
implementation of AES-SIV written by Daniel Franke on behalf of
[Akamai Technologies](https://www.akamai.com). It is published under
the [Apache License
(v2.0)](https://www.apache.org/licenses/LICENSE-2.0). It uses OpenSSL
for the underlying
[AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) and
[CMAC](https://en.wikipedia.org/wiki/One-key_MAC) implementations and
follows a similar interface style.
An AES_SIV implementation forked from libaes_siv has been [merged into
the OpenSSL master branch](https://github.com/openssl/openssl/pull/3540).
However, the two implementations are not API-compatible; see section
"OpenSSL API Comparison" below.
## Overview of SIV mode
Synthetic Initialization Vector (SIV) mode is a [block cipher mode of
operation](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation)
for [authenticated encryption with associated
data](https://en.wikipedia.org/wiki/Authenticated_encryption) designed
to be maximally resistant to accidental
[nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) reuse. If
two messages are accidentally encrypted using the same nonce and the
same associated data, the attacker learns nothing except whether or
not the plaintexts of the two messages are identical to each other.
SIV mode also permits the nonce to be intentionally omitted, resulting
in a [deterministic encryption
scheme](https://en.wikipedia.org/wiki/Deterministic_encryption).
Here are a couple common situations where AES-SIV may be an
appropriate choice of AEAD scheme:
1. You can't count on the system doing the encrypting to reliably
generate a unique nonce for every message. For example, the system
may be an embedded device with no good entropy source, or may be a
VM subject to be snapshotted and restored.
2. You want your encryption to be deterministic so that an
intermediating party such as a caching proxy, provided only with
ciphertext, can perform deduplication.
The drawback to SIV mode is that it requires two passes over its
input. This makes it potentially clumsy for use with large messages
since the entire message must be held in memory at one time. SIV mode
is also a bit slower than most widely-used block cipher modes (but
can still be quite fast — see performance numbers below).
Be aware that with *any* encryption scheme, including SIV, repeating
or omitting a nonce can still be [fatal to
security](https://xkcd.com/257) if your plaintexts have low entropy,
e.g., if each message consists only of a single bit.
Keys for SIV mode are twice the length of the keys for the underlying
block cipher. For example, keys for AES-128-SIV are 256 bits long,
and keys for AES-256-SIV are 512 bits long.
## Build instructions
Build dependencies:
* Any ISO C89 compiler (GCC or Clang recommended). No C99 language
features are required, however `<stdint.h>` must be available and
must define `uint64_t`. `char` must be 8 bits and arithmetic must be
two's complement.
* [CMake](https://cmake.org) >= 3.1
* [OpenSSL](https://openssl.org) >=1.0.1 (libcrypto only). A recent
release from the 1.0.2 branch or later is strongly recommended since
1.0.1 was EOL'ed at the end of 2016. Furthermore, OpenSSL versions prior
to 1.0.1n and 1.0.2b have known bugs which impact `libaes_siv` and
will cause failures in its test suite. LibreSSL is not supported.
* [Asciidoc](http://asciidoc.org) (only required for building man pages)
Running benchmarks requires a POSIX.1-2001 compliant OS, including
the `clock_gettime` system call.
To build and install on POSIX-like platforms:
```
cmake . &&
make &&
make test &&
sudo make install
```
NOTE: Out-of-source builds are allowed, but out-of-source manpage builds
require a2x's -D option, which may provoke an apparently bogus warning from a2x.
If you want to build on an OS X machine, install the Xcode development
environment and the command line tools, then use either the Homebrew package
manager or the MacPorts package manager to install cmake and OpenSSL.
Homebrew (https://brew.sh/):
```
brew install cmake openssl &&
cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/openssl . &&
make &&
make test &&
sudo make install
```
MacPorts (https://www.macports.org/):
```
sudo port install cmake openssl &&
cmake . &&
make &&
make test &&
sudo make install
```
To create a native Windows build, you will first need to build
OpenSSL. Install Visual Studio, CMake, ActiveState Perl, and NASM, and
ensure that `nasm.exe` is somewhere in your `%PATH%`. From a VS developer
command prompt, unpack the OpenSSL sources and run
```
perl Configure VC-WIN64A
nmake
```
Then to build `libaes_siv`, run
```
cmake -G "NMake Makefiles" -DOPENSSL_ROOT_DIR=\path\to\openssl .
nmake
nmake test
```
## Usage
See the manual pages for API documentation, and the test vectors
in `tests.c` for simple usage examples. You can also use the `demo` command
line program to encrypt and decrypt data.
## OpenSSL API Comparison
In December 2018, OpenSSL merged an AES-SIV implementation derived
from libaes_siv. As of February 2019 this implementation has not been
released yet; it will appear some time post-1.1.1. However, despite
the two implementations' common ancestry, they are not API-compatible.
The OpenSSL team had to make an ugly-but-necessary compromise in order
to shoehorn SIV mode into OpenSSL's EVP API, which is a streaming API
that was never designed to support SIV's two-pass operation. When used for
SIV operations, the EVP API is forced to return an error if you invoke
`EVP_(En|De)crypt_Update` more than once for the same message.
When designing libaes_siv, I rejected this behavior as an unacceptable
breakdown of the API contract and opted to dispense with the EVP
abstraction altogether rather than permit it to leak. libaes_siv's API
remains stylistically similar to EVP, but is nonetheless distinct and
avoids the above pitfall.
## Performance
On the author's Intel Core i7-6560U laptop, libaes_siv can process
approximately 796 MiB of plaintext or ciphertext or 963 MiB of
associated data per second using 256-bit keys
(i.e., AES-128). Encrypting a zero-byte message takes approximately
990ns. To obtain numbers for your own system, run `make bench &&
./bench`.
## Software assurance
libaes_siv's test suite includes all test vectors from RFC 5297 and
achieves 100% code coverage according to
[gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html). It produces
clean output from [Valgrind](https://valgrind.org) and from Clang's
[undefined behavior
sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html),
and is verified using [ctgrind](https://github.com/agl/ctgrind) to run
in constant time.
Nonetheless, libaes_siv should at present be considered beta-quality
code. It has not yet been tested on platforms other than x86-64 Linux
or benefited from any significant amount of user feedback, and
the codebase is in need of additional review by cryptographers and
expert C programmers.
## Bugs and pull requests
Use the GitHub issue tracker. For reporting sensitive security issues,
contact the author directly. (Note: I no longer use PGP. Please
request my Signal details if necessary).
## A note on version numbers
libaes_siv version numbers are of the form `<major>.<minor>.<patch>`
and follow a semantic versioning scheme. The major version number
will be incremented with any backward-incompatible ABI change. The
minor version number will be incremented if new functionality is
added without impacting ABI backward-compatibility. The patch
version number will be incremented for releases that make no
externally-visible changes.
As a result of this scheme, on ELF platforms, the .so version will
be the same as the release version.
Version numbers indicate nothing about code quality or maturity. No
code known or suspected to be less suitable for production use than
previous releases will ever be tagged with a version number.

View File

@ -0,0 +1,2 @@
Vendoring of git@github.com:dfoxfranke/libaes_siv.git.
Code from commit 509550e92a416172b9b8255e275f3a04d5fd4545

594
pkg/libaes_siv/aes_siv.c Normal file
View File

@ -0,0 +1,594 @@
/* Copyright (c) 2017-2019 Akamai Technologies, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#define _POSIX_C_SOURCE 200112L
#define _ISOC99_SOURCE 1
#include "config.h"
#include "aes_siv.h"
#include <assert.h>
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#ifdef ENABLE_DEBUG_OUTPUT
#include <stdio.h>
#endif
#ifdef _MSC_VER
/* For _byteswap_uint64 */
#include <stdlib.h>
#endif
#include <string.h>
#include <openssl/cmac.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#ifdef ENABLE_CTGRIND
#include <ctgrind.h>
#endif
#if CHAR_BIT != 8
#error "libaes_siv requires an 8-bit char type"
#endif
#if -1 != ~0
#error "libaes_siv requires a two's-complement architecture"
#endif
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901
#undef inline
#elif defined(__GNUC__) || defined(__clang__)
#define inline __inline__
#elif defined(_MSC_VER)
#define inline __inline
#else
#define inline
#endif
#if defined(__GNUC__) || defined(__clang__)
#define LIKELY(cond) __builtin_expect(cond, 1)
#define UNLIKELY(cond) __builtin_expect(cond, 0)
#else
#define LIKELY(cond) cond
#define UNLIKELY(cond) cond
#endif
#ifndef ENABLE_CTGRIND
static inline void ct_poison(const void *data, size_t len) {
(void)data;
(void)len;
}
static inline void ct_unpoison(const void *data, size_t len) {
(void)data;
(void)len;
}
#endif
static void debug(const char *label, const unsigned char *hex, size_t len) {
/* ENABLE_CTGRIND has to override ENABLE_DEBUG_OUTPUT since sensitive data
gets printed.
*/
#if defined(ENABLE_DEBUG_OUTPUT) && !defined(ENABLE_CTGRIND)
size_t i;
printf("%16s: ", label);
for (i = 0; i < len; i++) {
if (i > 0 && i % 16 == 0) {
printf("\n ");
}
printf("%.2x", (int)hex[i]);
if (i > 0 && i % 4 == 3) {
printf(" ");
}
}
printf("\n");
#else
(void)label;
(void)hex;
(void)len;
#endif
}
typedef union block_un {
uint64_t word[2];
unsigned char byte[16];
} block;
const union {
uint64_t word;
char byte[8];
} endian = {0x0102030405060708};
#define I_AM_BIG_ENDIAN (endian.byte[0] == 1 && \
endian.byte[1] == 2 && \
endian.byte[2] == 3 && \
endian.byte[3] == 4 && \
endian.byte[4] == 5 && \
endian.byte[5] == 6 && \
endian.byte[6] == 7 && \
endian.byte[7] == 8)
#define I_AM_LITTLE_ENDIAN (endian.byte[0] == 8 && \
endian.byte[1] == 7 && \
endian.byte[2] == 6 && \
endian.byte[3] == 5 && \
endian.byte[4] == 4 && \
endian.byte[5] == 3 && \
endian.byte[6] == 2 && \
endian.byte[7] == 1)
#if defined(__GNUC__) || defined(__clang__)
static inline uint64_t bswap64(uint64_t x) { return __builtin_bswap64(x); }
#elif defined(_MSC_VER)
static inline uint64_t bswap64(uint64_t x) { return _byteswap_uint64(x); }
#else
static inline uint32_t rotl(uint32_t x) { return (x << 8) | (x >> 24); }
static inline uint32_t rotr(uint32_t x) { return (x >> 8) | (x << 24); }
static inline uint64_t bswap64(uint64_t x) {
uint32_t high = (uint32_t)(x >> 32);
uint32_t low = (uint32_t)x;
high = (rotl(high) & 0x00ff00ff) | (rotr(high) & 0xff00ff00);
low = (rotl(low) & 0x00ff00ff) | (rotr(low) & 0xff00ff00);
return ((uint64_t)low) << 32 | (uint64_t)high;
}
#endif
static inline uint64_t getword(block const *block, size_t i) {
#ifndef ENABLE_DEBUG_WEIRD_ENDIAN
if (I_AM_BIG_ENDIAN) {
return block->word[i];
} else if (I_AM_LITTLE_ENDIAN) {
return bswap64(block->word[i]);
} else {
#endif
i <<= 3;
return ((uint64_t)block->byte[i + 7]) |
((uint64_t)block->byte[i + 6] << 8) |
((uint64_t)block->byte[i + 5] << 16) |
((uint64_t)block->byte[i + 4] << 24) |
((uint64_t)block->byte[i + 3] << 32) |
((uint64_t)block->byte[i + 2] << 40) |
((uint64_t)block->byte[i + 1] << 48) |
((uint64_t)block->byte[i] << 56);
#ifndef ENABLE_DEBUG_WEIRD_ENDIAN
}
#endif
}
static inline void putword(block *block, size_t i, uint64_t x) {
#ifndef ENABLE_DEBUG_WEIRD_ENDIAN
if (I_AM_BIG_ENDIAN) {
block->word[i] = x;
} else if (I_AM_LITTLE_ENDIAN) {
block->word[i] = bswap64(x);
} else {
#endif
i <<= 3;
block->byte[i] = (unsigned char)(x >> 56);
block->byte[i + 1] = (unsigned char)((x >> 48) & 0xff);
block->byte[i + 2] = (unsigned char)((x >> 40) & 0xff);
block->byte[i + 3] = (unsigned char)((x >> 32) & 0xff);
block->byte[i + 4] = (unsigned char)((x >> 24) & 0xff);
block->byte[i + 5] = (unsigned char)((x >> 16) & 0xff);
block->byte[i + 6] = (unsigned char)((x >> 8) & 0xff);
block->byte[i + 7] = (unsigned char)(x & 0xff);
#ifndef ENABLE_DEBUG_WEIRD_ENDIAN
}
#endif
}
static inline void xorblock(block *x, block const *y) {
x->word[0] ^= y->word[0];
x->word[1] ^= y->word[1];
}
/* Doubles `block`, which is 16 bytes representing an element
of GF(2**128) modulo the irreducible polynomial
x**128 + x**7 + x**2 + x + 1. */
static inline void dbl(block *block) {
uint64_t high = getword(block, 0);
uint64_t low = getword(block, 1);
uint64_t high_carry = high & (((uint64_t)1) << 63);
uint64_t low_carry = low & (((uint64_t)1) << 63);
/* Assumes two's-complement arithmetic */
int64_t low_mask = -((int64_t)(high_carry >> 63)) & 0x87;
uint64_t high_mask = low_carry >> 63;
high = (high << 1) | high_mask;
low = (low << 1) ^ (uint64_t)low_mask;
putword(block, 0, high);
putword(block, 1, low);
}
struct AES_SIV_CTX_st {
/* d stores intermediate results of S2V; it corresponds to D from the
pseudocode in section 2.4 of RFC 5297. */
block d;
EVP_CIPHER_CTX *cipher_ctx;
/* SIV_AES_Init() sets up cmac_ctx_init. cmac_ctx is a scratchpad used
by SIV_AES_AssociateData() and SIV_AES_(En|De)cryptFinal. */
CMAC_CTX *cmac_ctx_init, *cmac_ctx;
};
void AES_SIV_CTX_cleanup(AES_SIV_CTX *ctx) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
EVP_CIPHER_CTX_reset(ctx->cipher_ctx);
#else
EVP_CIPHER_CTX_cleanup(ctx->cipher_ctx);
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && OPENSSL_VERSION_NUMBER <= 0x10100060L
/* Workaround for an OpenSSL bug that causes a double free
if you call CMAC_CTX_cleanup() before CMAC_CTX_free().
https://github.com/openssl/openssl/pull/2798
*/
CMAC_CTX_free(ctx->cmac_ctx_init);
ctx->cmac_ctx_init = CMAC_CTX_new();
CMAC_CTX_free(ctx->cmac_ctx);
ctx->cmac_ctx = CMAC_CTX_new();
#else
CMAC_CTX_cleanup(ctx->cmac_ctx_init);
CMAC_CTX_cleanup(ctx->cmac_ctx);
#endif
OPENSSL_cleanse(&ctx->d, sizeof ctx->d);
}
void AES_SIV_CTX_free(AES_SIV_CTX *ctx) {
if (ctx) {
EVP_CIPHER_CTX_free(ctx->cipher_ctx);
/* Prior to OpenSSL 1.0.2b, CMAC_CTX_free() crashes on NULL */
if (LIKELY(ctx->cmac_ctx_init != NULL)) {
CMAC_CTX_free(ctx->cmac_ctx_init);
}
if (LIKELY(ctx->cmac_ctx != NULL)) {
CMAC_CTX_free(ctx->cmac_ctx);
}
OPENSSL_cleanse(&ctx->d, sizeof ctx->d);
OPENSSL_free(ctx);
}
}
AES_SIV_CTX *AES_SIV_CTX_new(void) {
AES_SIV_CTX *ctx = OPENSSL_malloc(sizeof(struct AES_SIV_CTX_st));
if (UNLIKELY(ctx == NULL)) {
return NULL;
}
ctx->cipher_ctx = EVP_CIPHER_CTX_new();
ctx->cmac_ctx_init = CMAC_CTX_new();
ctx->cmac_ctx = CMAC_CTX_new();
if (UNLIKELY(ctx->cipher_ctx == NULL ||
ctx->cmac_ctx_init == NULL ||
ctx->cmac_ctx == NULL)) {
AES_SIV_CTX_free(ctx);
return NULL;
}
return ctx;
}
int AES_SIV_CTX_copy(AES_SIV_CTX *dst, AES_SIV_CTX const *src) {
memcpy(&dst->d, &src->d, sizeof src->d);
if(UNLIKELY(EVP_CIPHER_CTX_copy(dst->cipher_ctx, src->cipher_ctx)
!= 1)) {
return 0;
}
if (UNLIKELY(CMAC_CTX_copy(dst->cmac_ctx_init, src->cmac_ctx_init)
!= 1)) {
return 0;
}
/* Not necessary to copy cmac_ctx since it's just temporary
* storage */
return 1;
}
int AES_SIV_Init(AES_SIV_CTX *ctx, unsigned char const *key, size_t key_len) {
static const unsigned char zero[] = {0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0};
size_t out_len;
int ret = 0;
ct_poison(key, key_len);
switch (key_len) {
case 32:
if (UNLIKELY(CMAC_Init(ctx->cmac_ctx_init, key, 16,
EVP_aes_128_cbc(), NULL) != 1)) {
goto done;
}
if (UNLIKELY(EVP_EncryptInit_ex(ctx->cipher_ctx,
EVP_aes_128_ctr(),
NULL, key + 16, NULL) != 1)) {
goto done;
}
break;
case 48:
if (UNLIKELY(CMAC_Init(ctx->cmac_ctx_init, key, 24,
EVP_aes_192_cbc(), NULL) != 1)) {
goto done;
}
if (UNLIKELY(EVP_EncryptInit_ex(ctx->cipher_ctx,
EVP_aes_192_ctr(),
NULL, key + 24, NULL) != 1)) {
goto done;
}
break;
case 64:
if (UNLIKELY(CMAC_Init(ctx->cmac_ctx_init, key, 32,
EVP_aes_256_cbc(), NULL) != 1)) {
goto done;
}
if (UNLIKELY(EVP_EncryptInit_ex(ctx->cipher_ctx,
EVP_aes_256_ctr(),
NULL, key + 32, NULL) != 1)) {
goto done;
}
break;
default:
goto done;
}
if (UNLIKELY(CMAC_CTX_copy(ctx->cmac_ctx, ctx->cmac_ctx_init) != 1)) {
goto done;
}
if (UNLIKELY(CMAC_Update(ctx->cmac_ctx, zero, sizeof zero) != 1)) {
goto done;
}
out_len = sizeof ctx->d;
if (UNLIKELY(CMAC_Final(ctx->cmac_ctx, ctx->d.byte, &out_len) != 1)) {
goto done;
}
debug("CMAC(zero)", ctx->d.byte, out_len);
ret = 1;
done:
ct_unpoison(key, key_len);
return ret;
}
int AES_SIV_AssociateData(AES_SIV_CTX *ctx, unsigned char const *data,
size_t len) {
block cmac_out;
size_t out_len = sizeof cmac_out;
int ret = 0;
ct_poison(data, len);
dbl(&ctx->d);
debug("double()", ctx->d.byte, 16);
if (UNLIKELY(CMAC_CTX_copy(ctx->cmac_ctx, ctx->cmac_ctx_init) != 1)) {
goto done;
}
if (UNLIKELY(CMAC_Update(ctx->cmac_ctx, data, len) != 1)) {
goto done;
}
if (UNLIKELY(CMAC_Final(ctx->cmac_ctx, cmac_out.byte, &out_len) != 1)) {
goto done;
}
assert(out_len == 16);
debug("CMAC(ad)", cmac_out.byte, 16);
xorblock(&ctx->d, &cmac_out);
debug("xor", ctx->d.byte, 16);
ret = 1;
done:
ct_unpoison(data, len);
return ret;
}
static inline int do_s2v_p(AES_SIV_CTX *ctx, block *out,
unsigned char const* in, size_t len) {
block t;
size_t out_len = sizeof out->byte;
if (UNLIKELY(CMAC_CTX_copy(ctx->cmac_ctx, ctx->cmac_ctx_init) != 1)) {
return 0;
}
if(len >= 16) {
if(UNLIKELY(CMAC_Update(ctx->cmac_ctx, in, len - 16) != 1)) {
return 0;
}
debug("xorend part 1", in, len - 16);
memcpy(&t, in + (len-16), 16);
xorblock(&t, &ctx->d);
debug("xorend part 2", t.byte, 16);
if(UNLIKELY(CMAC_Update(ctx->cmac_ctx, t.byte, 16) != 1)) {
return 0;
}
} else {
size_t i;
memcpy(&t, in, len);
t.byte[len] = 0x80;
for(i = len + 1; i < 16; i++) {
t.byte[i] = 0;
}
debug("pad", t.byte, 16);
dbl(&ctx->d);
xorblock(&t, &ctx->d);
debug("xor", t.byte, 16);
if(UNLIKELY(CMAC_Update(ctx->cmac_ctx, t.byte, 16) != 1)) {
return 0;
}
}
if(UNLIKELY(CMAC_Final(ctx->cmac_ctx, out->byte, &out_len) != 1)) {
return 0;
}
assert(out_len == 16);
debug("CMAC(final)", out->byte, 16);
return 1;
}
static inline int do_encrypt(EVP_CIPHER_CTX *ctx, unsigned char *out,
unsigned char const *in, size_t len, block *icv) {
#ifdef ENABLE_DEBUG_TINY_CHUNK_SIZE
const int chunk_size = 7;
#else
const int chunk_size = 1 << 30;
#endif
size_t len_remaining = len;
int out_len;
int ret;
if(UNLIKELY(EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, icv->byte)
!= 1)) {
return 0;
}
while(UNLIKELY(len_remaining > (size_t)chunk_size)) {
out_len = chunk_size;
if(UNLIKELY(EVP_EncryptUpdate(ctx, out, &out_len, in, out_len)
!= 1)) {
return 0;
}
assert(out_len == chunk_size);
out += out_len;
in += out_len;
len_remaining -= (size_t)out_len;
}
out_len = (int)len_remaining;
ret = EVP_EncryptUpdate(ctx, out, &out_len, in, out_len);
assert(!ret || out_len == (int)len_remaining);
return ret;
}
int AES_SIV_EncryptFinal(AES_SIV_CTX *ctx, unsigned char *v_out,
unsigned char *c_out, unsigned char const *plaintext,
size_t len) {
block q;
int ret = 0;
ct_poison(plaintext, len);
if(UNLIKELY(do_s2v_p(ctx, &q, plaintext, len) != 1)) {
goto done;
}
ct_unpoison(&q, sizeof q);
memcpy(v_out, &q, 16);
q.byte[8] &= 0x7f;
q.byte[12] &= 0x7f;
if(UNLIKELY(do_encrypt(ctx->cipher_ctx, c_out, plaintext, len, &q)
!= 1)) {
goto done;
}
ret = 1;
debug("ciphertext", c_out, len);
done:
ct_unpoison(plaintext, len);
ct_unpoison(c_out, len);
ct_unpoison(v_out, 16);
return ret;
}
int AES_SIV_DecryptFinal(AES_SIV_CTX *ctx, unsigned char *out,
unsigned char const *v, unsigned char const *c,
size_t len) {
block t, q;
size_t i;
uint64_t result;
int ret = 0;
ct_poison(c, len);
memcpy(&q, v, 16);
q.byte[8] &= 0x7f;
q.byte[12] &= 0x7f;
if(UNLIKELY(do_encrypt(ctx->cipher_ctx, out, c, len, &q) != 1)) {
goto done;
}
debug("plaintext", out, len);
if(UNLIKELY(do_s2v_p(ctx, &t, out, len) != 1)) {
goto done;
}
for (i = 0; i < 16; i++) {
t.byte[i] ^= v[i];
}
result = t.word[0] | t.word[1];
ct_unpoison(&result, sizeof result);
ret = !result;
if(ret) {
ct_unpoison(out, len);
} else {
OPENSSL_cleanse(out, len);
}
done:
ct_unpoison(c, len);
return ret;
}
int AES_SIV_Encrypt(AES_SIV_CTX *ctx, unsigned char *out, size_t *out_len,
unsigned char const *key, size_t key_len,
unsigned char const *nonce, size_t nonce_len,
unsigned char const *plaintext, size_t plaintext_len,
unsigned char const *ad, size_t ad_len) {
if (UNLIKELY(*out_len < plaintext_len + 16)) {
return 0;
}
*out_len = plaintext_len + 16;
if (UNLIKELY(AES_SIV_Init(ctx, key, key_len) != 1)) {
return 0;
}
if (UNLIKELY(AES_SIV_AssociateData(ctx, ad, ad_len) != 1)) {
return 0;
}
if (nonce != NULL &&
UNLIKELY(AES_SIV_AssociateData(ctx, nonce, nonce_len) != 1)) {
return 0;
}
if (UNLIKELY(AES_SIV_EncryptFinal(ctx, out, out + 16, plaintext,
plaintext_len) != 1)) {
return 0;
}
debug("IV || C", out, *out_len);
return 1;
}
int AES_SIV_Decrypt(AES_SIV_CTX *ctx, unsigned char *out, size_t *out_len,
unsigned char const *key, size_t key_len,
unsigned char const *nonce, size_t nonce_len,
unsigned char const *ciphertext, size_t ciphertext_len,
unsigned char const *ad, size_t ad_len) {
if (UNLIKELY(ciphertext_len < 16)) {
return 0;
}
if (UNLIKELY(*out_len < ciphertext_len - 16)) {
return 0;
}
*out_len = ciphertext_len - 16;
if (UNLIKELY(AES_SIV_Init(ctx, key, key_len) != 1)) {
return 0;
}
if (UNLIKELY(AES_SIV_AssociateData(ctx, ad, ad_len) != 1)) {
return 0;
}
if (nonce != NULL &&
UNLIKELY(AES_SIV_AssociateData(ctx, nonce, nonce_len) != 1)) {
return 0;
}
if (UNLIKELY(AES_SIV_DecryptFinal(ctx, out, ciphertext, ciphertext + 16,
ciphertext_len - 16) != 1)) {
return 0;
}
debug("plaintext", out, *out_len);
return 1;
}

57
pkg/libaes_siv/aes_siv.h Normal file
View File

@ -0,0 +1,57 @@
/* Copyright (c) 2017-2019 Akamai Technologies, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef AES_SIV_H_
#define AES_SIV_H_
#include <stddef.h>
#define LIBAES_SIV_VERSION_MAJOR 1
#define LIBAES_SIV_VERSION_MINOR 0
#define LIBAES_SIV_VERSION_PATCH 1
#define LIBAES_SIV_VERSION ((LIBAES_SIV_VERSION_MAJOR << 16) + \
(LIBAES_SIV_VERSION_MINOR << 8) + \
LIBAES_SIV_VERSION_PATCH)
#ifdef __cplusplus
extern "C" {
#endif
typedef struct AES_SIV_CTX_st AES_SIV_CTX;
AES_SIV_CTX *AES_SIV_CTX_new(void);
int AES_SIV_CTX_copy(AES_SIV_CTX *dst, AES_SIV_CTX const *src);
void AES_SIV_CTX_cleanup(AES_SIV_CTX *ctx);
void AES_SIV_CTX_free(AES_SIV_CTX *ctx);
int AES_SIV_Init(AES_SIV_CTX *ctx, unsigned char const *key, size_t key_len);
int AES_SIV_AssociateData(AES_SIV_CTX *ctx, unsigned char const *data,
size_t len);
int AES_SIV_EncryptFinal(AES_SIV_CTX *ctx, unsigned char *v_out,
unsigned char *c_out, unsigned char const *plaintext,
size_t len);
int AES_SIV_DecryptFinal(AES_SIV_CTX *ctx, unsigned char *out,
unsigned char const *v, unsigned char const *c,
size_t len);
int AES_SIV_Encrypt(AES_SIV_CTX *ctx, unsigned char *out, size_t *out_len,
unsigned char const *key, size_t key_len,
unsigned char const *nonce, size_t nonce_len,
unsigned char const *plaintext, size_t plaintext_len,
unsigned char const *ad, size_t ad_len);
int AES_SIV_Decrypt(AES_SIV_CTX *ctx, unsigned char *out, size_t *out_len,
unsigned char const *key, size_t key_len,
unsigned char const *nonce, size_t nonce_len,
unsigned char const *ciphertext, size_t ciphertext_len,
unsigned char const *ad, size_t ad_len);
#ifdef __cplusplus
}
#endif
#endif

19
pkg/libaes_siv/config.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef AES_SIV_CONFIG_H_
#define AES_SIV_CONFIG_H_
/* Enable ct_poison() and ct_unpoison() hooks for testing with
ctgrind. */
/* #undef ENABLE_CTGRIND */
/* Enable this to get test coverage for the portable versions of
putword() and getword() when you don't happen to have a PDP-11
in your test farm.
*/
/* #undef ENABLE_DEBUG_WEIRD_ENDIAN */
/* Enable this to get test coverage for the while loop in do_encrypt()
without having to have a multi-gigabyte test case that'll take
forever for Valgrind to crunch through
*/
/* #undef ENABLE_DEBUG_TINY_CHUNK_SIZE */
#endif

6
pkg/libaes_siv/shell.nix Normal file
View File

@ -0,0 +1,6 @@
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
stdenv.mkDerivation {
name = "libaes_siv";
buildInputs = [ cmake openssl ];
}

4
pkg/urbit/configure vendored
View File

@ -2,11 +2,11 @@
set -e
URBIT_VERSION="0.10.4"
URBIT_VERSION="0.10.5"
deps=" \
curl gmp sigsegv argon2 ed25519 ent h2o scrypt sni uv murmur3 secp256k1 \
softfloat3 ncurses ssl crypto z lmdb ge-additions \
softfloat3 ncurses ssl crypto z lmdb ge-additions aes_siv \
"
headers=" \

View File

@ -135,6 +135,13 @@
u3_noun u3wea_cbcc_en(u3_noun);
u3_noun u3wea_cbcc_de(u3_noun);
u3_noun u3wea_siva_en(u3_noun);
u3_noun u3wea_siva_de(u3_noun);
u3_noun u3wea_sivb_en(u3_noun);
u3_noun u3wea_sivb_de(u3_noun);
u3_noun u3wea_sivc_en(u3_noun);
u3_noun u3wea_sivc_de(u3_noun);
u3_noun u3wea_de(u3_noun);
u3_noun u3wea_en(u3_noun);

View File

@ -351,6 +351,15 @@
void*
u3a_malloc(size_t len_i);
/* u3a_malloc_ssl(): openssl-shaped malloc
*/
void*
u3a_malloc_ssl(size_t len_i
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
);
/* u3a_calloc(): aligned storage measured in bytes.
*/
void*
@ -366,6 +375,15 @@
void*
u3a_realloc2(void* lag_v, size_t old_i, size_t new_i);
/* u3a_realloc_ssl(): openssl-shaped realloc.
*/
void*
u3a_realloc_ssl(void* lag_v, size_t len_i
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
);
/* u3a_free(): free for aligned malloc.
*/
void
@ -376,6 +394,15 @@
void
u3a_free2(void* tox_v, size_t siz_i);
/* u3a_free_ssl(): openssl-shaped free.
*/
void
u3a_free_ssl(void* tox_v
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
);
/* Reference and arena control.
*/
/* u3a_gain(): gain a reference count in normal space.

View File

@ -6,26 +6,30 @@
**/
/* Conventional axes for gate call.
*/
# define u3x_pay 3 // payload
# define u3x_sam 6 // sample
# define u3x_sam_1 6
# define u3x_sam_2 12
# define u3x_sam_3 13
# define u3x_sam_4 24
# define u3x_sam_5 25
# define u3x_sam_6 26
# define u3x_sam_12 52
# define u3x_sam_13 53
# define u3x_sam_7 27
# define u3x_sam_14 54
# define u3x_sam_15 55
# define u3x_sam_30 110
# define u3x_sam_31 111
# define u3x_con 7 // context
# define u3x_con_2 14 // context
# define u3x_con_3 15 // context
# define u3x_con_sam 30 // sample in gate context
# define u3x_bat 2 // battery
# define u3x_pay 3 // payload
# define u3x_sam 6 // sample
# define u3x_sam_1 6
# define u3x_sam_2 12
# define u3x_sam_3 13
# define u3x_sam_4 24
# define u3x_sam_5 25
# define u3x_sam_6 26
# define u3x_sam_12 52
# define u3x_sam_13 53
# define u3x_sam_7 27
# define u3x_sam_14 54
# define u3x_sam_15 55
# define u3x_sam_30 110
# define u3x_sam_31 111
# define u3x_sam_62 222
# define u3x_sam_63 223
# define u3x_con 7 // context
# define u3x_con_2 14 // context
# define u3x_con_3 15 // context
# define u3x_con_sam 30 // sample in gate context
# define u3x_con_sam_2 60
# define u3x_con_sam_3 61
# define u3x_bat 2 // battery
/** Macros.

View File

@ -5,6 +5,8 @@
#include <openssl/aes.h>
#include "aes_siv.h"
/* functions
*/
u3_noun

355
pkg/urbit/jets/e/aes_siv.c Normal file
View File

@ -0,0 +1,355 @@
/* j/5/aes_ecb.c
**
*/
#include "all.h"
#include <openssl/aes.h>
#include "aes_siv.h"
/* functions
*/
static void u3r_bytes_reverse(c3_w a_w,
c3_w b_w,
c3_y* c_y, /* out */
u3_atom d) /* in */
{
u3r_bytes(a_w, b_w, c_y, d);
c3_w i_w;
for (i_w = 0; i_w < ((b_w - a_w) / 2) ; i_w++) {
c3_y lo = c_y[i_w];
c3_y hi = c_y[b_w - i_w - 1];
c_y[i_w] = hi;
c_y[b_w - i_w - 1] = lo;
}
return;
}
static u3_noun _siv_en(c3_y* key_y,
c3_w keysize,
u3_noun ads,
u3_atom txt)
{
AES_SIV_CTX* ctx = AES_SIV_CTX_new();
if ( 0 == ctx ) {
return u3_none;
}
if ( 0 == AES_SIV_Init(ctx, key_y, keysize) ) {
AES_SIV_CTX_free(ctx);
return u3_none;
}
while (u3_nul != ads) {
c3_w ad_w = u3r_met(3, u3h(ads));
c3_y* ad_y = u3a_malloc(ad_w);
u3r_bytes_reverse(0, ad_w, ad_y, u3h(ads));
c3_w ret = AES_SIV_AssociateData(ctx, ad_y, ad_w);
u3a_free(ad_y);
if ( 0 == ret ) {
AES_SIV_CTX_free(ctx);
return u3_none;
}
ads = u3t(ads);
}
c3_w txt_w = u3r_met(3, txt);
c3_y* txt_y = u3a_malloc(txt_w);
u3r_bytes_reverse(0, txt_w, txt_y, txt);
const c3_w iv_w = 16;
c3_y iv_y[iv_w];
c3_y* out_y = u3a_malloc(txt_w);
if ( 0 == AES_SIV_EncryptFinal(ctx, iv_y, out_y, txt_y, txt_w) ) {
u3a_free(out_y);
u3a_free(txt_y);
AES_SIV_CTX_free(ctx);
return u3_none;
}
u3a_free(txt_y);
AES_SIV_CTX_free(ctx);
// Read the first 16 bytes as the "iv"
u3_noun iv = u3i_bytes(16, iv_y);
u3_noun msg = u3i_bytes(txt_w, out_y);
// Reverse byte order for output
u3_noun rev_iv = u3kc_rev(3, iv_w, iv);
u3_noun rev_msg = u3kc_rev(3, txt_w, msg);
u3a_free(out_y);
return u3nt(rev_iv, u3i_words(1, &txt_w), rev_msg);
}
static u3_noun _siv_de(c3_y* key_y,
c3_w keysize,
u3_noun ads,
u3_atom iv,
u3_atom len,
u3_atom txt)
{
AES_SIV_CTX* ctx = AES_SIV_CTX_new();
if ( 0 == ctx ) {
return u3_none;
}
if ( 0 == AES_SIV_Init(ctx, key_y, keysize) ) {
AES_SIV_CTX_free(ctx);
return u3_none;
}
while (u3_nul != ads) {
c3_w ad_w = u3r_met(3, u3h(ads));
c3_y* ad_y = u3a_malloc(ad_w);
u3r_bytes_reverse(0, ad_w, ad_y, u3h(ads));
c3_w ret = AES_SIV_AssociateData(ctx, ad_y, ad_w);
u3a_free(ad_y);
if ( 0 == ret ) {
AES_SIV_CTX_free(ctx);
return u3_none;
}
ads = u3t(ads);
}
c3_w txt_w = u3r_word(0, len);
c3_y* txt_y = u3a_malloc(txt_w);
u3r_bytes_reverse(0, txt_w, txt_y, txt);
const c3_w iv_w = 16;
c3_y iv_y[iv_w];
u3r_bytes_reverse(0, 16, iv_y, iv);
c3_y* out_y = u3a_malloc(txt_w);
if ( 0 == AES_SIV_DecryptFinal(ctx, out_y, iv_y, txt_y, txt_w) ) {
u3a_free(out_y);
u3a_free(txt_y);
AES_SIV_CTX_free(ctx);
// Either decryption failed or signature bad or there was a memory
// error. Some of these are deterministic and some are not. return u3_none
// to fallback to the Nock implementation.
return u3_none;
}
u3a_free(txt_y);
AES_SIV_CTX_free(ctx);
// Read the first 16 bytes as the "iv"
u3_noun msg = u3i_bytes(txt_w, out_y);
// Reverse byte order for output
u3_noun rev_msg = u3kc_rev(3, txt_w, msg);
u3a_free(out_y);
return u3nc(0, rev_msg);
}
u3_noun
u3qea_siva_en(u3_atom key,
u3_noun ads,
u3_atom txt)
{
c3_y key_y[32];
if (u3r_met(3, key) > 32) {
return u3_none;
}
u3r_bytes_reverse(0, 32, key_y, key);
return _siv_en(key_y, 32, ads, txt);
}
u3_noun
u3wea_siva_en(u3_noun cor)
{
u3_noun key, ads, txt;
if ( c3n == u3r_mean(cor, u3x_sam, &txt,
u3x_con_sam_2, &key,
u3x_con_sam_3, &ads, 0) ||
c3n == u3ud(key) ||
c3n == u3ud(txt) ) {
return u3m_bail(c3__exit);
} else {
return u3qea_siva_en(key, ads, txt);
}
}
u3_noun
u3qea_siva_de(u3_atom key,
u3_noun ads,
u3_atom iv,
u3_atom len,
u3_atom txt)
{
c3_y key_y[32];
if (u3r_met(3, key) > 32) {
return u3_none;
}
u3r_bytes_reverse(0, 32, key_y, key);
return _siv_de(key_y, 32, ads, iv, len, txt);
}
u3_noun
u3wea_siva_de(u3_noun cor)
{
u3_noun key, ads, iv, len, txt;
if ( c3n == u3r_mean(cor,
u3x_sam_2, &iv,
u3x_sam_6, &len,
u3x_sam_7, &txt,
u3x_con_sam_2, &key,
u3x_con_sam_3, &ads, 0) ||
c3n == u3ud(key) ||
c3n == u3ud(txt) ) {
return u3m_bail(c3__exit);
} else {
return u3qea_siva_de(key, ads, iv, len, txt);
}
}
u3_noun
u3qea_sivb_en(u3_atom key,
u3_noun ads,
u3_atom txt)
{
c3_y key_y[48];
if (u3r_met(3, key) > 48) {
return u3_none;
}
u3r_bytes_reverse(0, 48, key_y, key);
return _siv_en(key_y, 48, ads, txt);
}
u3_noun
u3wea_sivb_en(u3_noun cor)
{
u3_noun key, ads, txt;
if ( c3n == u3r_mean(cor, u3x_sam, &txt,
u3x_con_sam_2, &key,
u3x_con_sam_3, &ads, 0) ||
c3n == u3ud(key) ||
c3n == u3ud(txt) ) {
return u3m_bail(c3__exit);
} else {
return u3qea_sivb_en(key, ads, txt);
}
}
u3_noun
u3qea_sivb_de(u3_atom key,
u3_noun ads,
u3_atom iv,
u3_atom len,
u3_atom txt)
{
c3_y key_y[48];
if (u3r_met(3, key) > 48) {
return u3_none;
}
u3r_bytes_reverse(0, 48, key_y, key);
return _siv_de(key_y, 48, ads, iv, len, txt);
}
u3_noun
u3wea_sivb_de(u3_noun cor)
{
u3_noun key, ads, iv, len, txt;
if ( c3n == u3r_mean(cor,
u3x_sam_2, &iv,
u3x_sam_6, &len,
u3x_sam_7, &txt,
u3x_con_sam_2, &key,
u3x_con_sam_3, &ads, 0) ||
c3n == u3ud(key) ||
c3n == u3ud(txt) ) {
return u3m_bail(c3__exit);
} else {
return u3qea_sivb_de(key, ads, iv, len, txt);
}
}
u3_noun
u3qea_sivc_en(u3_atom key,
u3_noun ads,
u3_atom txt)
{
c3_y key_y[64];
if (u3r_met(3, key) > 64) {
return u3_none;
}
u3r_bytes_reverse(0, 64, key_y, key);
return _siv_en(key_y, 64, ads, txt);
}
u3_noun
u3wea_sivc_en(u3_noun cor)
{
u3_noun key, ads, txt;
if ( c3n == u3r_mean(cor, u3x_sam, &txt,
u3x_con_sam_2, &key,
u3x_con_sam_3, &ads, 0) ||
c3n == u3ud(key) ||
c3n == u3ud(txt) ) {
return u3m_bail(c3__exit);
} else {
return u3qea_sivc_en(key, ads, txt);
}
}
u3_noun
u3qea_sivc_de(u3_atom key,
u3_noun ads,
u3_atom iv,
u3_atom len,
u3_atom txt)
{
c3_y key_y[64];
if (u3r_met(3, key) > 64) {
return u3_none;
}
u3r_bytes_reverse(0, 64, key_y, key);
return _siv_de(key_y, 64, ads, iv, len, txt);
}
u3_noun
u3wea_sivc_de(u3_noun cor)
{
u3_noun key, ads, iv, len, txt;
if ( c3n == u3r_mean(cor,
u3x_sam_2, &iv,
u3x_sam_6, &len,
u3x_sam_7, &txt,
u3x_con_sam_2, &key,
u3x_con_sam_3, &ads, 0) ||
c3n == u3ud(key) ||
c3n == u3ud(txt) ) {
return u3m_bail(c3__exit);
} else {
return u3qea_sivc_de(key, ads, iv, len, txt);
}
}

View File

@ -17,15 +17,7 @@
u3r_bytes(0, wid, (void*)dat_y, dat);
const EVP_MD* rip_u = EVP_ripemd160(); // ripem algorithm
static EVP_MD_CTX* con_u = NULL; // context
/* build library context object
we do this once (and only once)
*/
if (NULL == con_u) {
con_u = EVP_MD_CTX_create();
}
EVP_MD_CTX* con_u = EVP_MD_CTX_create();
/* perform signature
*/
@ -37,23 +29,28 @@
ret_w = EVP_DigestInit_ex(con_u, rip_u, NULL);
if ( 1 != ret_w ) {
u3a_free(dat_y);
EVP_MD_CTX_destroy(con_u);
u3l_log("\rripe jet: crypto library fail 1\n");
return u3m_bail(c3__exit);
return u3m_bail(c3__fail);
}
ret_w = EVP_DigestUpdate(con_u, (void*)dat_y, wid);
u3a_free(dat_y);
if (1 != ret_w) {
EVP_MD_CTX_destroy(con_u);
u3l_log("\rripe jet: crypto library fail 2\n");
return u3m_bail(c3__exit);
return u3m_bail(c3__fail);
}
ret_w = EVP_DigestFinal_ex(con_u, sib_y, &sil_w);
if ( 1 != ret_w ) {
EVP_MD_CTX_destroy(con_u);
u3l_log("\rripe jet: crypto library fail 3\n");
return u3m_bail(c3__exit);
return u3m_bail(c3__fail);
}
EVP_MD_CTX_destroy(con_u);
/* endian conversion;
turn into noun for return
*/

View File

@ -14,7 +14,13 @@
u3_atom w, x, y, z;
u3_atom p, q;
u3_atom m = u3qa_add(a, u3r_met(0, b));
u3_atom m;
{
c3_w bit_w = u3r_met(0, b);
u3_noun bit = u3i_words(1, &bit_w);
m = u3qa_add(a, bit);
u3z(bit);
}
// Compute c and d.
{

View File

@ -76,6 +76,30 @@ static c3_c* _141_hex_aes_cbcc_de_ha[] = {
"b9d521b4d5e1d9387b34bbf5ca38f4d52ba86952ea54490dad7e2670183c572b",
0
};
static u3j_harm _141_hex_aes_siva_en_a[] = {{".2", u3wea_siva_en}, {}};
static c3_c* _141_hex_aes_siva_en_ha[] = {
0
};
static u3j_harm _141_hex_aes_siva_de_a[] = {{".2", u3wea_siva_de}, {}};
static c3_c* _141_hex_aes_siva_de_ha[] = {
0
};
static u3j_harm _141_hex_aes_sivb_en_a[] = {{".2", u3wea_sivb_en}, {}};
static c3_c* _141_hex_aes_sivb_en_ha[] = {
0
};
static u3j_harm _141_hex_aes_sivb_de_a[] = {{".2", u3wea_sivb_de}, {}};
static c3_c* _141_hex_aes_sivb_de_ha[] = {
0
};
static u3j_harm _141_hex_aes_sivc_en_a[] = {{".2", u3wea_sivc_en}, {}};
static c3_c* _141_hex_aes_sivc_en_ha[] = {
0
};
static u3j_harm _141_hex_aes_sivc_de_a[] = {{".2", u3wea_sivc_de}, {}};
static c3_c* _141_hex_aes_sivc_de_ha[] = {
0
};
static u3j_core _141_hex_aes_ecba_d[] =
{ { "en", 7, _141_hex_aes_ecba_en_a, 0, _141_hex_aes_ecba_en_ha },
@ -137,6 +161,31 @@ static c3_c* _141_hex_aes_cbcc_ha[] = {
0
};
static u3j_core _141_hex_aes_siva_d[] =
{ { "en", 7, _141_hex_aes_siva_en_a, 0, _141_hex_aes_siva_en_ha },
{ "de", 7, _141_hex_aes_siva_de_a, 0, _141_hex_aes_siva_de_ha },
{}
};
static c3_c* _141_hex_aes_siva_ha[] = {
0
};
static u3j_core _141_hex_aes_sivb_d[] =
{ { "en", 7, _141_hex_aes_sivb_en_a, 0, _141_hex_aes_sivb_en_ha },
{ "de", 7, _141_hex_aes_sivb_de_a, 0, _141_hex_aes_sivb_de_ha },
{}
};
static c3_c* _141_hex_aes_sivb_ha[] = {
0
};
static u3j_core _141_hex_aes_sivc_d[] =
{ { "en", 7, _141_hex_aes_sivc_en_a, 0, _141_hex_aes_sivc_en_ha },
{ "de", 7, _141_hex_aes_sivc_de_a, 0, _141_hex_aes_sivc_de_ha },
{}
};
static c3_c* _141_hex_aes_sivc_ha[] = {
0
};
static u3j_core _141_hex_aes_d[] =
{ { "ecba", 7, 0, _141_hex_aes_ecba_d, _141_hex_aes_ecba_ha },
{ "ecbb", 7, 0, _141_hex_aes_ecbb_d, _141_hex_aes_ecbb_ha },
@ -144,6 +193,9 @@ static u3j_core _141_hex_aes_d[] =
{ "cbca", 7, 0, _141_hex_aes_cbca_d, _141_hex_aes_cbca_ha },
{ "cbcb", 7, 0, _141_hex_aes_cbcb_d, _141_hex_aes_cbcb_ha },
{ "cbcc", 7, 0, _141_hex_aes_cbcc_d, _141_hex_aes_cbcc_ha },
{ "siva", 7, 0, _141_hex_aes_siva_d, _141_hex_aes_siva_ha },
{ "sivb", 7, 0, _141_hex_aes_sivb_d, _141_hex_aes_sivb_ha },
{ "sivc", 7, 0, _141_hex_aes_sivc_d, _141_hex_aes_sivc_ha },
{}
};
static c3_c* _141_hex_aes_ha[] = {

View File

@ -700,6 +700,18 @@ u3a_malloc(size_t len_i)
return out_w;
}
/* u3a_malloc_ssl(): openssl-shaped malloc
*/
void*
u3a_malloc_ssl(size_t len_i
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
)
{
return u3a_malloc(len_i);
}
/* u3a_cellblock(): allocate a block of cells on the hat.
*/
static c3_o
@ -883,6 +895,18 @@ u3a_realloc2(void* lag_v, size_t old_i, size_t new_i)
return u3a_realloc(lag_v, new_i);
}
/* u3a_realloc_ssl(): openssl-shaped realloc.
*/
void*
u3a_realloc_ssl(void* lag_v, size_t len_i
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
)
{
return u3a_realloc(lag_v, len_i);
}
/* u3a_free(): free for aligned malloc.
*/
void
@ -907,6 +931,18 @@ u3a_free2(void* tox_v, size_t siz_i)
return u3a_free(tox_v);
}
/* u3a_free_ssl(): openssl-shaped free.
*/
void
u3a_free_ssl(void* tox_v
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
)
{
return u3a_free(tox_v);
}
/* _me_wash_north(): clean up mug slots after copy.
*/
static void _me_wash_north(u3_noun dog);

View File

@ -7,6 +7,7 @@
#include <ctype.h>
#include <sigsegv.h>
#include <curl/curl.h>
#include <openssl/crypto.h>
#include "all.h"
@ -1633,6 +1634,11 @@ u3m_boot(c3_c* dir_c)
*/
u3m_init();
/* In the worker, set the openssl memory allocation functions to always
** work on the loom.
*/
CRYPTO_set_mem_functions(u3a_malloc_ssl, u3a_realloc_ssl, u3a_free_ssl);
/* Activate the storage system.
*/
nuu_o = u3e_live(c3n, dir_c);
@ -1742,7 +1748,7 @@ u3m_rock_load(c3_c* dir_c, c3_d evt_d)
// XX u3m_file bails, but we'd prefer to return errors
//
u3_noun fil = u3m_file(nam_c);
u3a_print_memory(stderr, "rock: load", u3r_met(3, fil));
u3a_print_memory(stderr, "rock: load", u3r_met(5, fil));
u3_noun pro = u3m_soft(0, u3ke_cue, fil);

View File

@ -1092,10 +1092,14 @@ u3r_mp(mpz_t a_mp,
u3a_atom* b_u = u3a_to_ptr(b);
c3_w len_w = b_u->len_w;
// slight deficiency in the GMP API.
// avoid reallocation on import, if possible
//
c3_assert(!(len_w >> 27));
mpz_init2(a_mp, len_w << 5);
if ( (len_w >> 27) ) {
mpz_init(a_mp);
}
else {
mpz_init2(a_mp, len_w << 5);
}
mpz_import(a_mp, len_w, -1, sizeof(c3_w), 0, 0, b_u->buf_w);
}

View File

@ -364,23 +364,33 @@ _cttp_mcut_pork(c3_c* buf_c, c3_w len_w, u3_noun pok)
static c3_w
_cttp_mcut_quay(c3_c* buf_c, c3_w len_w, u3_noun quy)
{
if ( u3_nul == quy ) {
return len_w;
}
else {
u3_noun i_quy = u3h(quy);
u3_noun pi_quy = u3h(i_quy);
u3_noun qi_quy = u3t(i_quy);
u3_noun t_quy = u3t(quy);
u3_noun yuq = quy;
c3_o fir_o = c3y;
len_w = _cttp_mcut_char(buf_c, len_w, '&');
len_w = _cttp_mcut_cord(buf_c, len_w, u3k(pi_quy));
len_w = _cttp_mcut_char(buf_c, len_w, '=');
len_w = _cttp_mcut_cord(buf_c, len_w, u3k(qi_quy));
while ( u3_nul != quy ) {
if ( c3y == fir_o ) {
len_w = _cttp_mcut_char(buf_c, len_w, '?');
fir_o = c3n;
}
else {
len_w = _cttp_mcut_char(buf_c, len_w, '&');
}
len_w = _cttp_mcut_quay(buf_c, len_w, u3k(t_quy));
{
u3_noun i_quy, t_quy;
u3_noun pi_quy, qi_quy;
u3x_cell(quy, &i_quy, &t_quy);
u3x_cell(i_quy, &pi_quy, &qi_quy);
len_w = _cttp_mcut_cord(buf_c, len_w, u3k(pi_quy));
len_w = _cttp_mcut_char(buf_c, len_w, '=');
len_w = _cttp_mcut_cord(buf_c, len_w, u3k(qi_quy));
quy = t_quy;
}
}
u3z(quy);
u3z(yuq);
return len_w;
}
@ -396,7 +406,6 @@ _cttp_mcut_url(c3_c* buf_c, c3_w len_w, u3_noun pul)
len_w = _cttp_mcut_pork(buf_c, len_w, u3k(q_pul));
if ( u3_nul != r_pul ) {
len_w = _cttp_mcut_char(buf_c, len_w, '?');
len_w = _cttp_mcut_quay(buf_c, len_w, u3k(r_pul));
}
u3z(pul);

View File

@ -612,7 +612,14 @@ _boothack_key(u3_noun kef)
// +seed:able:jael: private key file
//
seed = u3ke_cue(u3k(u3t(des)));
u3_noun pro = u3m_soft(0, u3ke_cue, u3k(u3t(des)));
if ( u3_blip != u3h(pro) ) {
u3l_log("dawn: unable to cue private key\r\n");
exit(1);
}
seed = u3k(u3t(pro));
u3z(pro);
// local reference, not counted
//
ship = u3h(seed);

View File

@ -337,7 +337,7 @@ u3_dawn_vent(u3_noun seed)
//
c3_c* url_c = ( 0 != u3_Host.ops_u.eth_c ) ?
u3_Host.ops_u.eth_c :
"https://mainnet.infura.io/v3/196a7f37c7d54211b4a07904ec73ad87";
"http://eth-mainnet.urbit.org:8545";
// pin block number
//

View File

@ -96,7 +96,7 @@ c3_o _perform_put_on_database_raw(MDB_txn* transaction_u,
c3_w ret_w = mdb_put(transaction_u, database_u, &key_val, &value_val, flags);
if (ret_w != 0) {
u3l_log("lmdb: write failed: %s\n", mdb_strerror(ret_w));
fprintf(stderr, "lmdb: write failed: %s\n", mdb_strerror(ret_w));
return c3n;
}
@ -118,7 +118,7 @@ c3_o _perform_get_on_database_raw(MDB_txn* transaction_u,
c3_w ret_w = mdb_get(transaction_u, database_u, &key_val, value);
if (ret_w != 0) {
u3l_log("lmdb: read failed: %s\n", mdb_strerror(ret_w));
fprintf(stderr, "lmdb: read failed: %s\n", mdb_strerror(ret_w));
return c3n;
}
@ -277,7 +277,7 @@ static void _u3_lmdb_write_event_cb(uv_work_t* req) {
0, /* flags */
&transaction_u);
if (0 != ret_w) {
u3l_log("lmdb: txn_begin fail: %s\n", mdb_strerror(ret_w));
fprintf(stderr, "lmdb: txn_begin fail: %s\n", mdb_strerror(ret_w));
return;
}
@ -289,7 +289,7 @@ static void _u3_lmdb_write_event_cb(uv_work_t* req) {
flags_w,
&database_u);
if (0 != ret_w) {
u3l_log("lmdb: dbi_open fail: %s\n", mdb_strerror(ret_w));
fprintf(stderr, "lmdb: dbi_open fail: %s\n", mdb_strerror(ret_w));
return;
}
@ -307,7 +307,7 @@ static void _u3_lmdb_write_event_cb(uv_work_t* req) {
request->malloced_event_data_size[i]);
if (success == c3n) {
u3l_log("lmdb: failed to write event %" PRIu64 "\n", event_number);
fprintf(stderr, "lmdb: failed to write event %" PRIu64 "\n", event_number);
mdb_txn_abort(transaction_u);
data->success = c3n;
return;
@ -317,12 +317,12 @@ static void _u3_lmdb_write_event_cb(uv_work_t* req) {
ret_w = mdb_txn_commit(transaction_u);
if (0 != ret_w) {
if ( request->event_count == 1 ) {
u3l_log("lmdb: failed to commit event %" PRIu64 ": %s\n",
fprintf(stderr, "lmdb: failed to commit event %" PRIu64 ": %s\n",
request->first_event,
mdb_strerror(ret_w));
} else {
c3_d through = request->first_event + request->event_count - 1ULL;
u3l_log("lmdb: failed to commit events %" PRIu64 " through %" PRIu64
fprintf(stderr, "lmdb: failed to commit events %" PRIu64 " through %" PRIu64
": %s\n",
request->first_event,
through,

View File

@ -19,7 +19,7 @@ static u3_utty* _term_main();
static void _term_read_cb(uv_stream_t* tcp_u,
ssize_t siz_i,
const uv_buf_t* buf_u);
static c3_i _term_tcsetattr(int, int, const struct termios *);
static c3_i _term_tcsetattr(c3_i, c3_i, const struct termios*);
/* _write(): wraps write(), asserting length
*/
@ -292,13 +292,21 @@ u3_term_io_exit(void)
/* _term_tcsetattr(): tcsetattr w/retry on EINTR.
*/
static c3_i
_term_tcsetattr(int fildes, int optional_actions,
const struct termios *termios_p)
_term_tcsetattr(c3_i fil_i, c3_i act_i, const struct termios* tms_u)
{
c3_i ret_i = 0;
c3_w len_w = 0;
do {
ret_i = tcsetattr(fildes, optional_actions, termios_p);
} while (-1 == ret_i && errno == EINTR);
// abort pathological retry loop
//
if ( 100 == ++len_w ) {
fprintf(stderr, "term: tcsetattr loop\r\n");
return -1;
}
ret_i = tcsetattr(fil_i, act_i, tms_u);
} while ( (-1 == ret_i) && (EINTR == errno) );
return ret_i;
}

View File

@ -427,7 +427,7 @@ _worker_lame(u3_noun now, u3_noun ovo, u3_noun why, u3_noun tan)
{
u3_noun rep;
u3_noun wir, tag, cad;
c3_o pac_o = c3n;
c3_o rec_o = c3n;
c3_d evt_d = u3V.sen_d;
u3V.sen_d = u3V.dun_d;
@ -467,16 +467,16 @@ _worker_lame(u3_noun now, u3_noun ovo, u3_noun why, u3_noun tan)
u3nc(u3k(tag), u3k(cad))));
}
pac_o = _(c3__meme == why);
// reclaim memory on bail:meme?
//
rec_o = __(c3__meme == why);
_worker_send_replace(evt_d, u3nc(now, rep));
u3z(ovo); u3z(why); u3z(tan);
// XX review, always pack on meme?
//
if ( c3y == pac_o ) {
_worker_pack();
if ( c3y == rec_o ) {
u3m_reclaim();
}
}
@ -554,16 +554,13 @@ _worker_sure_feck(u3_noun ovo, u3_noun vir, c3_w pre_w)
if ( (pre_w > low_w) && !(pos_w > low_w) ) {
// XX set flag(s) in u3V so we don't repeat endlessly?
// XX pack here too?
//
pac_o = c3y;
rec_o = c3y;
pri = 1;
}
else if ( (pre_w > hig_w) && !(pos_w > hig_w) ) {
// XX we should probably jam/cue our entire state at this point
//
pac_o = c3y;
rec_o = c3y;
pri = 0;
}

View File

@ -2,10 +2,6 @@
set -ex
export STACK_YAML="`pwd`/pkg/hs/stack.yaml"
stack test urbit-king
if [ "$TRAVIS_PULL_REQUEST" = false ]
then

View File

@ -2,8 +2,6 @@
set -e
stack test urbit-king --fast
pkg=$(nix-build nix/ops -A test --no-out-link "$@")
hdr () {