mirror of
https://github.com/urbit/shrub.git
synced 2024-11-29 06:45:42 +03:00
commit
5666f99b16
@ -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; }
|
||||
|
7
nix/pkgs/libaes_siv/builder.sh
Normal file
7
nix/pkgs/libaes_siv/builder.sh
Normal file
@ -0,0 +1,7 @@
|
||||
source $stdenv/setup
|
||||
|
||||
cp -r $src ./src
|
||||
chmod -R u+w ./src
|
||||
cd ./src
|
||||
|
||||
PREFIX=$out make install
|
12
nix/pkgs/libaes_siv/cross.nix
Normal file
12
nix/pkgs/libaes_siv/cross.nix
Normal 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";
|
||||
}
|
9
nix/pkgs/libaes_siv/default.nix
Normal file
9
nix/pkgs/libaes_siv/default.nix
Normal file
@ -0,0 +1,9 @@
|
||||
{ pkgs }:
|
||||
|
||||
pkgs.stdenv.mkDerivation rec {
|
||||
name = "libaes_siv";
|
||||
builder = ./builder.sh;
|
||||
src = ../../../pkg/libaes_siv;
|
||||
|
||||
nativeBuildInputs = [ pkgs.openssl ];
|
||||
}
|
13
nix/pkgs/libaes_siv/release.sh
Normal file
13
nix/pkgs/libaes_siv/release.sh
Normal 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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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; };
|
||||
};
|
||||
|
202
pkg/libaes_siv/COPYING
Normal file
202
pkg/libaes_siv/COPYING
Normal 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
20
pkg/libaes_siv/Makefile
Normal 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
197
pkg/libaes_siv/README.md
Normal 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.
|
2
pkg/libaes_siv/README.urbit.md
Normal file
2
pkg/libaes_siv/README.urbit.md
Normal 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
594
pkg/libaes_siv/aes_siv.c
Normal 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
57
pkg/libaes_siv/aes_siv.h
Normal 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
19
pkg/libaes_siv/config.h
Normal 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
6
pkg/libaes_siv/shell.nix
Normal file
@ -0,0 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
with pkgs;
|
||||
stdenv.mkDerivation {
|
||||
name = "libaes_siv";
|
||||
buildInputs = [ cmake openssl ];
|
||||
}
|
2
pkg/urbit/configure
vendored
2
pkg/urbit/configure
vendored
@ -6,7 +6,7 @@ URBIT_VERSION="0.10.4"
|
||||
|
||||
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=" \
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
355
pkg/urbit/jets/e/aes_siv.c
Normal 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);
|
||||
}
|
||||
}
|
@ -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
|
||||
*/
|
||||
|
@ -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[] = {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user