diff --git a/.github/workflows/build_freebsd.yml b/.github/workflows/build_freebsd.yml index 6d5a2a7fe..e2abc78f2 100644 --- a/.github/workflows/build_freebsd.yml +++ b/.github/workflows/build_freebsd.yml @@ -41,15 +41,17 @@ jobs: id: compile shell: bash env: - COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn -Werror" + LIBS: "-lm -lpthread -lX11 -lXi -lGL -lexecinfo" + SRCS: "src/*.c third_party/bearssl/src/*.c" + COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn -Werror -Ithird_party/bearssl/inc" PLAT32_FLAGS: "-fno-pie -fvisibility=hidden -fcf-protection=none -rdynamic -I freebsd32/include -L freebsd32/lib" PLAT64_FLAGS: "-fno-pie -fvisibility=hidden -fcf-protection=none -rdynamic -I freebsd64/include -L freebsd64/lib" + run: | LATEST_FLAG=-DCC_COMMIT_SHA=\"${GITHUB_SHA::9}\" - cd src - i386-freebsd11-clang *.c ${{ env.COMMON_FLAGS }} ${{ env.PLAT32_FLAGS }} $LATEST_FLAG -o cc-fbsd32-gl1 -lm -lpthread -lX11 -lXi -lGL -lexecinfo - x86_64-freebsd11-clang *.c ${{ env.COMMON_FLAGS }} ${{ env.PLAT64_FLAGS }} $LATEST_FLAG -o cc-fbsd64-gl1 -lm -lpthread -lX11 -lXi -lGL -lexecinfo + i386-freebsd11-clang ${{ env.SRCS }} ${{ env.COMMON_FLAGS }} ${{ env.PLAT32_FLAGS }} $LATEST_FLAG -o cc-fbsd32-gl1 ${{ env.LIBS }} + x86_64-freebsd11-clang ${{ env.SRCS }} ${{ env.COMMON_FLAGS }} ${{ env.PLAT64_FLAGS }} $LATEST_FLAG -o cc-fbsd64-gl1 ${{ env.LIBS }} # otherwise notify_failure doesn't work @@ -67,13 +69,13 @@ jobs: - uses: ./.github/actions/upload_build if: ${{ always() && steps.compile.outcome == 'success' }} with: - SOURCE_FILE: 'src/cc-fbsd32-gl1' + SOURCE_FILE: 'cc-fbsd32-gl1' DEST_NAME: 'ClassiCube-FreeBSD-32' - uses: ./.github/actions/upload_build if: ${{ always() && steps.compile.outcome == 'success' }} with: - SOURCE_FILE: 'src/cc-fbsd64-gl1' + SOURCE_FILE: 'cc-fbsd64-gl1' DEST_NAME: 'ClassiCube-FreeBSD-64' diff --git a/.github/workflows/build_haiku.yml b/.github/workflows/build_haiku.yml index 4c6629fe4..f23c5c6d8 100644 --- a/.github/workflows/build_haiku.yml +++ b/.github/workflows/build_haiku.yml @@ -23,11 +23,11 @@ jobs: - name: Compile haiku build id: compile env: - COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn -Werror" + LIBS: "-lm -lGL -lnetwork -lstdc++ -lbe -lgame -ltracker" + SRCS: "src/*.c src/Platform_BeOS.cpp src/Window_BeOS.cpp third_party/bearssl/src/*.c" + COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn -Werror -Ithird_party/bearssl/inc" run: | - cd src - x86_64-unknown-haiku-gcc *.c Platform_BeOS.cpp Window_BeOS.cpp -o ClassiCube-haiku ${{ env.COMMON_FLAGS }} -lm -lGL -lnetwork -lstdc++ -lbe -lgame -ltracker - + x86_64-unknown-haiku-gcc ${{ env.SRCS }} -o ClassiCube-haiku ${{ env.COMMON_FLAGS }} ${{ env.LIBS }} - uses: ./.github/actions/notify_failure if: ${{ always() && steps.compile.outcome == 'failure' }} @@ -39,7 +39,7 @@ jobs: - uses: ./.github/actions/upload_build if: ${{ always() && steps.compile.outcome == 'success' }} with: - SOURCE_FILE: 'src/ClassiCube-haiku' + SOURCE_FILE: 'ClassiCube-haiku' DEST_NAME: 'ClassiCube-haiku' diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml index e2e8e7e28..0fcc0d872 100644 --- a/.github/workflows/build_linux.yml +++ b/.github/workflows/build_linux.yml @@ -41,14 +41,15 @@ jobs: shell: bash id: compile env: - COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn -Werror" + LIBS: "-lX11 -lXi -lpthread -lGL -lm -ldl" + SRCS: "src/*.c third_party/bearssl/src/*.c" + COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn -Werror -Ithird_party/bearssl/inc" NIX32_FLAGS: "-no-pie -fno-pie -m32 -fvisibility=hidden -fcf-protection=none -rdynamic -L ../lib -Wl,--unresolved-symbols=ignore-in-shared-libs" run: | LATEST_FLAG=-DCC_COMMIT_SHA=\"${GITHUB_SHA::9}\" - cd src - gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.NIX32_FLAGS }} $LATEST_FLAG -o cc-nix32-gl1 -lX11 -lXi -lpthread -lGL -lm -ldl - gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.NIX32_FLAGS }} $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -o cc-nix32-gl2 -lX11 -lXi -lpthread -lGL -lm -ldl + gcc ${{ env.SRCS }} ${{ env.COMMON_FLAGS }} ${{ env.NIX32_FLAGS }} $LATEST_FLAG -o cc-nix32-gl1 ${{ env.LIBS }} + gcc ${{ env.SRCS }} ${{ env.COMMON_FLAGS }} ${{ env.NIX32_FLAGS }} $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -o cc-nix32-gl2 ${{ env.LIBS }} - uses: ./.github/actions/notify_failure @@ -61,13 +62,13 @@ jobs: - uses: ./.github/actions/upload_build if: ${{ always() && steps.compile.outcome == 'success' }} with: - SOURCE_FILE: 'src/cc-nix32-gl1' + SOURCE_FILE: 'cc-nix32-gl1' DEST_NAME: 'ClassiCube-Linux32-OpenGL' - uses: ./.github/actions/upload_build if: ${{ always() && steps.compile.outcome == 'success' }} with: - SOURCE_FILE: 'src/cc-nix32-gl2' + SOURCE_FILE: 'cc-nix32-gl2' DEST_NAME: 'ClassiCube-Linux32-ModernGL' @@ -103,16 +104,17 @@ jobs: - name: Compile 64 bit Linux builds shell: bash id: compile - env: - COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn -Werror" + env: + LIBS: "-lX11 -lXi -lpthread -lGL -lm -ldl" + SRCS: "src/*.c third_party/bearssl/src/*.c" + COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn -Werror -Ithird_party/bearssl/inc"" NIX64_FLAGS: "-no-pie -fno-pie -m64 -fvisibility=hidden -fcf-protection=none -rdynamic -L ../lib -Wl,--unresolved-symbols=ignore-in-shared-libs" run: | LATEST_FLAG=-DCC_COMMIT_SHA=\"${GITHUB_SHA::9}\" - - cd src - gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.NIX64_FLAGS }} $LATEST_FLAG -o cc-nix64-gl1 -lX11 -lXi -lpthread -lGL -lm -ldl - gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.NIX64_FLAGS }} $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -o cc-nix64-gl2 -lX11 -lXi -lpthread -lGL -lm -ldl - #gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.NIX64_FLAGS }} $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -DCC_WIN_BACKEND=CC_WIN_BACKEND_SDL2 -o cc-sdl64-gl2 -lSDL2 -lpthread -lGL -lm -ldl + + gcc ${{ env.SRCS }} ${{ env.COMMON_FLAGS }} ${{ env.NIX64_FLAGS }} $LATEST_FLAG -o cc-nix64-gl1 ${{ env.LIBS }} + gcc ${{ env.SRCS }} ${{ env.COMMON_FLAGS }} ${{ env.NIX64_FLAGS }} $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -o cc-nix64-gl2 ${{ env.LIBS }} + #gcc ${{ env.SRCS }} ${{ env.COMMON_FLAGS }} ${{ env.NIX64_FLAGS }} $LATEST_FLAG -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -DCC_WIN_BACKEND=CC_WIN_BACKEND_SDL2 -o cc-sdl64-gl2 -lSDL2 ${{ env.LIBS }} - uses: ./.github/actions/notify_failure @@ -125,19 +127,19 @@ jobs: - uses: ./.github/actions/upload_build if: ${{ always() && steps.compile.outcome == 'success' }} with: - SOURCE_FILE: 'src/cc-nix64-gl1' + SOURCE_FILE: 'cc-nix64-gl1' DEST_NAME: 'ClassiCube-Linux64-OpenGL' - uses: ./.github/actions/upload_build if: ${{ always() && steps.compile.outcome == 'success' }} with: - SOURCE_FILE: 'src/cc-nix64-gl2' + SOURCE_FILE: 'cc-nix64-gl2' DEST_NAME: 'ClassiCube-Linux64-ModernGL' - uses: ./.github/actions/upload_build if: ${{ always() && steps.compile.outcome == 'success' }} with: - SOURCE_FILE: 'src/cc-sdl64-gl2' + SOURCE_FILE: 'cc-sdl64-gl2' DEST_NAME: 'ClassiCube-Linux64-SDL2' diff --git a/.github/workflows/build_netbsd.yml b/.github/workflows/build_netbsd.yml index feea8dc6d..0d10066e6 100644 --- a/.github/workflows/build_netbsd.yml +++ b/.github/workflows/build_netbsd.yml @@ -35,14 +35,14 @@ jobs: id: compile shell: bash env: - COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn -Werror" + LIBS: "-lm -lpthread -lX11 -lXi -lGL -lexecinfo" + SRCS: "src/*.c third_party/bearssl/src/*.c" + COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn -Werror -Wl,-R/usr/X11R7/lib -Ithird_party/bearssl/inc" PLAT64_FLAGS: "-fno-pie -fvisibility=hidden -fcf-protection=none -rdynamic -I netbsd64/include -L netbsd64/lib -Wl,--unresolved-symbols=ignore-in-shared-libs" run: | LATEST_FLAG=-DCC_COMMIT_SHA=\"${GITHUB_SHA::9}\" - echo $LATEST_FLAG - - cd src - x86_64-unknown-netbsd-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.PLAT64_FLAGS }} $LATEST_FLAG -o cc-netbsd64-gl1 -lm -lpthread -lX11 -lXi -lGL -lexecinfo + + x86_64-unknown-netbsd-gcc ${{ env.SRCS }} ${{ env.COMMON_FLAGS }} ${{ env.PLAT64_FLAGS }} $LATEST_FLAG -o cc-netbsd64-gl1 ${{ env.LIBS }} - uses: ./.github/actions/notify_failure @@ -55,7 +55,7 @@ jobs: - uses: ./.github/actions/upload_build if: ${{ always() && steps.compile.outcome == 'success' }} with: - SOURCE_FILE: 'src/cc-netbsd64-gl1' + SOURCE_FILE: 'cc-netbsd64-gl1' DEST_NAME: 'ClassiCube-NetBSD-64' diff --git a/Makefile b/Makefile index 729294caa..3d31ae1da 100644 --- a/Makefile +++ b/Makefile @@ -73,11 +73,13 @@ endif ifeq ($(PLAT),linux) LIBS = -lX11 -lXi -lpthread -lGL -ldl BUILD_DIR = build/linux + BEARSSL = 1 endif ifeq ($(PLAT),sunos) LIBS = -lsocket -lX11 -lXi -lGL BUILD_DIR = build/solaris + BEARSSL = 1 endif ifeq ($(PLAT),hp-ux) @@ -85,6 +87,7 @@ ifeq ($(PLAT),hp-ux) LDFLAGS = LIBS = -lm -lX11 -lXi -lXext -L/opt/graphics/OpenGL/lib -lGL -lpthread BUILD_DIR = build/hpux + BEARSSL = 1 endif ifeq ($(PLAT),darwin) @@ -100,6 +103,7 @@ ifeq ($(PLAT),freebsd) LDFLAGS = -L /usr/local/lib -rdynamic LIBS = -lexecinfo -lGL -lX11 -lXi -lpthread BUILD_DIR = build/freebsd + BEARSSL = 1 endif ifeq ($(PLAT),openbsd) @@ -107,13 +111,15 @@ ifeq ($(PLAT),openbsd) LDFLAGS = -L /usr/X11R6/lib -L /usr/local/lib -rdynamic LIBS = -lexecinfo -lGL -lX11 -lXi -lpthread BUILD_DIR = build/openbsd + BEARSSL = 1 endif ifeq ($(PLAT),netbsd) CFLAGS += -I /usr/X11R7/include -I /usr/pkg/include - LDFLAGS = -L /usr/X11R7/lib -L /usr/pkg/lib -rdynamic + LDFLAGS = -L /usr/X11R7/lib -L /usr/pkg/lib -rdynamic -Wl,-R/usr/X11R7/lib LIBS = -lexecinfo -lGL -lX11 -lXi -lpthread BUILD_DIR = build/netbsd + BEARSSL = 1 endif ifeq ($(PLAT),dragonfly) @@ -121,6 +127,7 @@ ifeq ($(PLAT),dragonfly) LDFLAGS = -L /usr/local/lib -rdynamic LIBS = -lexecinfo -lGL -lX11 -lXi -lpthread BUILD_DIR = build/flybsd + BEARSSL = 1 endif ifeq ($(PLAT),haiku) @@ -130,6 +137,7 @@ ifeq ($(PLAT),haiku) LINK = $(CXX) LIBS = -lGL -lnetwork -lbe -lgame -ltracker BUILD_DIR = build/haiku + BEARSSL = 1 endif ifeq ($(PLAT),beos) @@ -145,12 +153,14 @@ endif ifeq ($(PLAT),serenityos) LIBS = -lgl -lSDL2 BUILD_DIR = build/serenity + BEARSSL = 1 endif ifeq ($(PLAT),irix) CC = gcc LIBS = -lGL -lX11 -lXi -lpthread -ldl BUILD_DIR = build/irix + BEARSSL = 1 endif ifeq ($(PLAT),dos) diff --git a/doc/portability.md b/doc/portability.md index 5254c3131..17125797d 100644 --- a/doc/portability.md +++ b/doc/portability.md @@ -2,6 +2,8 @@ Although most of the code is platform-independent, some per-platform functionali By default `Core.h` tries to automatically define appropriate backends for your system. Define ```CC_BUILD_MANUAL``` to disable this. +Note: Updating doesn't work properly in Windows 95 or Windows 98 + ## Before you start * IEEE floating-point support is required. (Can be emulated in software, but will affect performance) * The `int` data type must be 32-bits. @@ -12,39 +14,6 @@ By default `Core.h` tries to automatically define appropriate backends for your In summary, the codebase can theroetically be ported to any modern-ish hardware, but not stuff like a UNIVAC machine, the SuperFX chip on the SNES, or an 8-bit microcontroller. -## Supported platforms - -#### Tier 1 support -These platforms are regularly tested on and have executables automatically compiled for. - -|Platform|Testing|Support| -|--------|-------|-----| -|Windows x86/x64 | Mostly tested on 7+ | Should work in all Windows versions -|macOS x86/x64 | Mostly tested on 10.12 | Should work in all macOS versions since 10.3 -|Linux x86/x64 | Mostly tested on Linux Mint | Should work in most Linux distributions -|Web client | Mostly tested in Chrome | Should work in all browsers with WebGL (including IE) - -Note: Updating doesn't work properly in Windows 95 or Windows 98 - -#### Tier 2 support -The game has been compiled and run on these platforms before. It may or may not still compile for them. - -I don't really test these platforms at all, only when I suspect some changes to the code might impact them. - -|Platform|Machine|Notes| -|--------|-------|-----| -|macOS x86 | macOS 10.4 | -|FreeBSD x86 | FreeBSD | x64 should work too | -|NetBSD x86 | NetBSD | x64 should work too | -|OpenBSD x86 | OpenBSD | x64 should work too | -|Solaris x86 | OpenIndiana | x64 should work too | -|macOS PPC | macOS 10.3 | PPC64 completely untested | -|Linux PPC | Debian | Issues with colour channels incorrectly swapped? | -|Linux ARM | Raspberry pi | ARM64 should work too | -|Linux SPARC | Debian | Didn't really work due to lack of 24-bit colours | -|Linux Alpha | Debian | -|HaikuOS | Nightly | - ## Porting Listed below are the requirements for implementing each platform-dependent file.
@@ -116,3 +85,9 @@ Define: - ```DEFAULT_NET_BACKEND CC_NET_BACKEND_LIBCURL``` - use libcurl for HTTP Supporting connection reuse is highly recommended. (but not required) + +### SSL +SSL and TLS support, plus basic certificate validation + +Define: +- ```DEFAULT_SSL_BACKEND CC_SSL_BACKEND_BEARSSL``` - use BearSSL for SSL/TLS diff --git a/readme.md b/readme.md index 0193bf78b..7a9af1d66 100644 --- a/readme.md +++ b/readme.md @@ -144,8 +144,8 @@ Compiling with TCC: 1. Install X11, XInput2, and OpenGL development libraries if necessary.
For Ubuntu, these are the `libx11-dev`, `libxi-dev` and `libgl1-mesa-dev` packages 2. Run either: - * `make linux` or - * `cc -fno-math-errno src/*.c -o ClassiCube -rdynamic -lpthread -lX11 -lXi -lGL -ldl` + * `make linux` - produces a simple non-optimised executable, easier to debug + * `make linux RELEASE=1` - produces an optimised executable, harder to debug ##### Cross compiling for Windows (32 bit): 1. Install MinGW-w64 if necessary. (Ubuntu: `gcc-mingw-w64` package) @@ -163,8 +163,8 @@ Although the regular linux compiliation flags will work fine, to take full advan ## Compiling - macOS 1. Install a C compiler if necessary. The easiest way of obtaining one is by installing **Xcode**. 2. Run either: - * `make darwin` or - * `cc -fno-math-errno src/*.c src/*.m -o ClassiCube -framework Cocoa -framework OpenGL -framework IOKit -lobjc` + * `make darwin` - produces a simple non-optimised executable, easier to debug + * `make darwin RELEASE=1` - produces an optimised executable, harder to debug ##### Using Xcode GUI @@ -323,66 +323,66 @@ Run `make saturn`. You'll need [libyaul](https://github.com/yaul-org/libyaul) #### FreeBSD -1. Install `libxi`, `libexecinfo`, `curl` and `openal-soft` packages if needed +1. Install `gmake`, `libxi`, `libexecinfo`, `openssl` and `openal-soft` packages if needed 2. Run either: - * `make freebsd` or - * `cc src/*.c -o ClassiCube -I /usr/local/include -L /usr/local/lib -lm -lpthread -lX11 -lXi -lGL -lexecinfo` + * `gmake freebsd` - produces a simple non-optimised executable, easier to debug + * `gmake freebsd RELEASE=1` - produces an optimised executable, harder to debug #### OpenBSD -1. Install `libexecinfo`, `curl` and `openal` packages if needed +1. Install `gmake`, `libexecinfo`, `openssl` and `openal` packages if needed 2. Run either: - * `make openbsd` or - * `cc src/*.c -o ClassiCube -I /usr/X11R6/include -I /usr/local/include -L /usr/X11R6/lib -L /usr/local/lib -lm -lpthread -lX11 -lXi -lGL -lexecinfo` + * `gmake openbsd` - produces a simple non-optimised executable, easier to debug + * `gmake openbsd RELEASE=1` - produces an optimised executable, harder to debug #### NetBSD -1. Install `libexecinfo`, `curl` and `openal-soft` packages if needed +1. Install `gmake`, `libexecinfo`, `openssl` and `openal-soft` packages if needed 2. Run either: - * `make netbsd` or - * `cc src/*.c -o ClassiCube -I /usr/X11R7/include -I /usr/pkg/include -L /usr/X11R7/lib -L /usr/pkg/lib -lpthread -lX11 -lXi -lGL -lexecinfo` + * `gmake netbsd` - produces a simple non-optimised executable, easier to debug + * `gmake netbsd RELEASE=1` - produces an optimised executable, harder to debug #### DragonflyBSD -1. Install `libxi`, `libexecinfo`, `curl` and `openal-soft` packages if needed +1. Install `gmake`, `libxi`, `libexecinfo`, `openssl` and `openal-soft` packages if needed 2. Run either: - * `make dragonfly` or - * `cc src/*.c -o ClassiCube -I /usr/local/include -L /usr/local/lib -lm -lpthread -lX11 -lXi -lGL -lexecinfo` + * `gmake dragonfly` - produces a simple non-optimised executable, easier to debug + * `gmake dragonfly RELEASE=1` - produces an optimised executable, harder to debug #### Solaris 1. Install required packages if needed 2. Run either: - * `make sunos` or - * `gcc -fno-math-errno src/*.c -o ClassiCube -lsocket -lX11 -lXi -lGL` + * `make sunos` - produces a simple non-optimised executable, easier to debug + * `make sunos RELEASE=1` - produces an optimised executable, harder to debug #### Haiku 1. Install `gcc`, `haiku_devel`, `openal_devel` packages if needed 2. Run either: - * `make haiku` or - * `cc -fno-math-errno src/*.c src/*.cpp -o ClassiCube -lGL -lnetwork -lstdc++ -lbe -lgame -ltracker` + * `make haiku` - produces a simple non-optimised executable, easier to debug + * `make haiku RELEASE=1` - produces an optimised executable, harder to debug #### BeOS 1. Install a C compiler 2. Run either: - * `make beos` or - * `cc -fno-math-errno src/*.c src/*.cpp -o ClassiCube -lGL -lbe -lgame -ltracker` + * `make beos` - produces a simple non-optimised executable, easier to debug + * `make beos RELEASE=1` - produces an optimised executable, harder to debug #### IRIX 1. Install required packages if needed 2. Run either: - * `make irix` or - * gcc -fno-math-errno src/*.c -o ClassiCube -lGL -lX11 -lXi -lpthread -ldl` + * `make irix` - produces a simple non-optimised executable, easier to debug + * `make irix RELEASE=1` - produces an optimised executable, harder to debug #### SerenityOS 1. Install SDL2 port if needed 2. Run either: - * `make serenityos` or - * `cc src/*.c -o ClassiCube -lgl -lSDL2` + * `make serenityos` - produces a simple non-optimised executable, easier to debug + * `make serenityos RELEASE=1` - produces an optimised executable, harder to debug #### Classic Mac OS diff --git a/src/Certs.c b/src/Certs.c new file mode 100644 index 000000000..0b8539609 --- /dev/null +++ b/src/Certs.c @@ -0,0 +1,192 @@ +#include "Certs.h" + +#if CC_CTX_BACKEND == CC_CRT_BACKEND_NONE +void CertsBackend_Init(void) { } + +void Certs_BeginChain(struct X509CertContext* ctx) { } + +void Certs_FreeChain( struct X509CertContext* ctx) { } + +int Certs_VerifyChain(struct X509CertContext* ctx) { return ERR_NOT_SUPPORTED; } + +void Certs_BeginCert( struct X509CertContext* ctx, int size) { } + +void Certs_AppendCert(struct X509CertContext* ctx, const void* data, int len) { } + +void Certs_FinishCert(struct X509CertContext* ctx) { } +#else +#include "Platform.h" +#include "String.h" +#include "Stream.h" + +void Certs_BeginCert( struct X509CertContext* ctx, int size) { + void* data; + ctx->cert = NULL; + + /* Should never happen, but never know */ + if (ctx->numCerts >= X509_MAX_CERTS) return; + + data = Mem_TryAllocCleared(1, size); + if (!data) return; + + ctx->cert = &ctx->certs[ctx->numCerts++]; + ctx->cert->data = data; + ctx->cert->offset = 0; +} + +void Certs_AppendCert(struct X509CertContext* ctx, const void* data, int len) { + if (!ctx->cert) return; + + Mem_Copy((char*)ctx->cert->data + ctx->cert->offset, data, len); + ctx->cert->offset += len; +} + +void Certs_FinishCert(struct X509CertContext* ctx) { +} + +void Certs_BeginChain(struct X509CertContext* ctx) { + ctx->cert = NULL; + ctx->numCerts = 0; +} + +void Certs_FreeChain( struct X509CertContext* ctx) { + int i; + for (i = 0; i < ctx->numCerts; i++) + { + Mem_Free(ctx->certs[i].data); + } + ctx->numCerts = 0; +} + +#if CC_CRT_BACKEND == CC_CRT_BACKEND_OPENSSL +#include "Errors.h" +#include "Funcs.h" +/* === BEGIN OPENSSL HEADERS === */ +typedef struct X509_ X509; +typedef struct X509_STORE_ X509_STORE; +typedef struct X509_STORE_CTX_ X509_STORE_CTX; +typedef struct OPENSSL_STACK_ OPENSSL_STACK; +typedef void (*OPENSSL_PopFunc)(void* data); + +static OPENSSL_STACK* (*_OPENSSL_sk_new_null)(void); +int (*_OPENSSL_sk_push)(OPENSSL_STACK* st, const void* data); +void (*_OPENSSL_sk_pop_free)(OPENSSL_STACK* st, OPENSSL_PopFunc func); + +static X509* (*_d2i_X509)(X509** px, const unsigned char** in, int len); + +static X509* (*_X509_new)(void); +static void (*_X509_free)(X509* a); + +static X509_STORE* (*_X509_STORE_new)(void); +static int (*_X509_STORE_set_default_paths)(X509_STORE* ctx); + +static int (*_X509_verify_cert)(X509_STORE_CTX* ctx); +static const char* (*_X509_verify_cert_error_string)(long n); + +static X509_STORE_CTX* (*_X509_STORE_CTX_new)(void); +static void (*_X509_STORE_CTX_free)(X509_STORE_CTX* ctx); + +static int (*_X509_STORE_CTX_get_error)(X509_STORE_CTX* ctx); +static int (*_X509_STORE_CTX_init)(X509_STORE_CTX* ctx, X509_STORE* store, + X509* x509, OPENSSL_STACK* chain); +/* === END OPENSSL HEADERS === */ + +#if defined CC_BUILD_WIN +static const cc_string cryptoLib = String_FromConst("libcrypto.dll"); +#elif defined CC_BUILD_HAIKU +static const cc_string cryptoLib = String_FromConst("libcrypto.so.3"); +static const cc_string cryptoAlt = String_FromConst("libcrypto.so"); +#else +static const cc_string cryptoLib = String_FromConst("libcrypto.so"); +static const cc_string cryptoAlt = String_FromConst("libcrypto.so.3"); +#endif + +static X509_STORE* store; +static cc_bool ossl_loaded; + +void CertsBackend_Init(void) { + static const struct DynamicLibSym funcs[] = { + DynamicLib_ReqSym(OPENSSL_sk_new_null), + DynamicLib_ReqSym(OPENSSL_sk_push), + DynamicLib_ReqSym(OPENSSL_sk_pop_free), + DynamicLib_ReqSym(d2i_X509), + DynamicLib_ReqSym(X509_new), + DynamicLib_ReqSym(X509_free), + DynamicLib_ReqSym(X509_STORE_new), + DynamicLib_ReqSym(X509_STORE_set_default_paths), + DynamicLib_ReqSym(X509_STORE_CTX_new), + DynamicLib_ReqSym(X509_STORE_CTX_free), + DynamicLib_ReqSym(X509_STORE_CTX_get_error), + DynamicLib_ReqSym(X509_STORE_CTX_init), + DynamicLib_ReqSym(X509_verify_cert), + DynamicLib_ReqSym(X509_verify_cert_error_string), + }; + void* lib; + + ossl_loaded = DynamicLib_LoadAll(&cryptoLib, funcs, Array_Elems(funcs), &lib); + if (!lib) { + ossl_loaded = DynamicLib_LoadAll(&cryptoAlt, funcs, Array_Elems(funcs), &lib); + } +} + +static X509* ToOpenSSLCert(struct X509Cert* cert) { + const unsigned char* data = cert->data; + return _d2i_X509(NULL, &data, cert->offset); +} + +int Certs_VerifyChain(struct X509CertContext* chain) { + OPENSSL_STACK* inter; + X509_STORE_CTX* ctx; + int i, status, ret; + X509* cur; + X509* cert; + if (!ossl_loaded) return ERR_NOT_SUPPORTED; + + /* Delay creating X509 store until necessary */ + if (!store) { + store = _X509_STORE_new(); + if (!store) return ERR_OUT_OF_MEMORY; + + _X509_STORE_set_default_paths(store); + } + + Platform_Log1("VERIFY CHAIN: %i", &chain->numCerts); + if (!chain->numCerts) return ERR_INVALID_ARGUMENT; + + /* End/Leaf certificate */ + cert = ToOpenSSLCert(&chain->certs[0]); + if (!cert) return ERR_OUT_OF_MEMORY; + + inter = _OPENSSL_sk_new_null(); + if (!inter) return ERR_OUT_OF_MEMORY; + + /* Intermediate certificates */ + for (i = 1; i < chain->numCerts; i++) + { + cur = ToOpenSSLCert(&chain->certs[i]); + if (cur) _OPENSSL_sk_push(inter, cur); + } + + ctx = _X509_STORE_CTX_new(); + _X509_STORE_CTX_init(ctx, store, cert, inter); + + status = _X509_verify_cert(ctx); + if (status == 1) { + Platform_LogConst("Certificate verified"); + ret = 0; + } else { + int err = _X509_STORE_CTX_get_error(ctx); + Platform_LogConst(_X509_verify_cert_error_string(err)); + ret = -1; + } + + _X509_STORE_CTX_free(ctx); + _OPENSSL_sk_pop_free(inter, (OPENSSL_PopFunc)_X509_free); + _X509_free(cert); + + return ret; +} +#endif + +#endif + diff --git a/src/Certs.h b/src/Certs.h new file mode 100644 index 000000000..327f15f83 --- /dev/null +++ b/src/Certs.h @@ -0,0 +1,34 @@ +#ifndef CC_CERT_H +#define CC_CERT_H +#include "Core.h" +CC_BEGIN_HEADER + +/* +Validates an X509 certificate chain for verifying a SSL/TLS connection. +Copyright 2014-2025 ClassiCube | Licensed under BSD-3 +*/ + +void CertsBackend_Init(void); + +#define X509_MAX_CERTS 10 +struct X509Cert { + void* data; + int offset; +}; + +struct X509CertContext { + struct X509Cert certs[X509_MAX_CERTS]; + struct X509Cert* cert; + int numCerts; +}; + +void Certs_BeginChain( struct X509CertContext* ctx); +void Certs_FreeChain( struct X509CertContext* ctx); +int Certs_VerifyChain(struct X509CertContext* ctx); + +void Certs_BeginCert( struct X509CertContext* ctx, int size); +void Certs_AppendCert(struct X509CertContext* ctx, const void* data, int len); +void Certs_FinishCert(struct X509CertContext* ctx); + +CC_END_HEADER +#endif diff --git a/src/Core.h b/src/Core.h index b4e6d6bdf..5b588ad95 100644 --- a/src/Core.h +++ b/src/Core.h @@ -153,6 +153,9 @@ typedef cc_uint8 cc_bool; #define CC_NET_BACKEND_BUILTIN 1 #define CC_NET_BACKEND_LIBCURL 2 +#define CC_CRT_BACKEND_NONE 1 +#define CC_CRT_BACKEND_OPENSSL 2 + #define CC_AUD_BACKEND_OPENAL 1 #define CC_AUD_BACKEND_WINMM 2 #define CC_AUD_BACKEND_OPENSLES 3 @@ -226,7 +229,9 @@ typedef cc_uint8 cc_bool; #elif defined __serenity__ #define CC_BUILD_SERENITY #define CC_BUILD_POSIX - #define DEFAULT_NET_BACKEND CC_NET_BACKEND_LIBCURL + #define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN + #define DEFAULT_SSL_BACKEND CC_SSL_BACKEND_BEARSSL + #define DEFAULT_CRT_BACKEND CC_CRT_BACKEND_OPENSSL #define DEFAULT_AUD_BACKEND CC_AUD_BACKEND_OPENAL #define DEFAULT_GFX_BACKEND CC_GFX_BACKEND_GL1 #define DEFAULT_WIN_BACKEND CC_WIN_BACKEND_SDL2 @@ -255,7 +260,9 @@ typedef cc_uint8 cc_bool; #define CC_BUILD_LINUX #define CC_BUILD_POSIX #define CC_BUILD_XINPUT2 - #define DEFAULT_NET_BACKEND CC_NET_BACKEND_LIBCURL + #define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN + #define DEFAULT_SSL_BACKEND CC_SSL_BACKEND_BEARSSL + #define DEFAULT_CRT_BACKEND CC_CRT_BACKEND_OPENSSL #define DEFAULT_AUD_BACKEND CC_AUD_BACKEND_OPENAL #define DEFAULT_WIN_BACKEND CC_WIN_BACKEND_X11 #if defined CC_BUILD_RPI @@ -297,7 +304,9 @@ typedef cc_uint8 cc_bool; #define CC_BUILD_SOLARIS #define CC_BUILD_POSIX #define CC_BUILD_XINPUT2 - #define DEFAULT_NET_BACKEND CC_NET_BACKEND_LIBCURL + #define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN + #define DEFAULT_SSL_BACKEND CC_SSL_BACKEND_BEARSSL + #define DEFAULT_CRT_BACKEND CC_CRT_BACKEND_OPENSSL #define DEFAULT_AUD_BACKEND CC_AUD_BACKEND_OPENAL #define DEFAULT_GFX_BACKEND CC_GFX_BACKEND_GL1 #define DEFAULT_WIN_BACKEND CC_WIN_BACKEND_X11 @@ -316,7 +325,9 @@ typedef cc_uint8 cc_bool; #define CC_BUILD_POSIX #define CC_BUILD_BSD #define CC_BUILD_XINPUT2 - #define DEFAULT_NET_BACKEND CC_NET_BACKEND_LIBCURL + #define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN + #define DEFAULT_SSL_BACKEND CC_SSL_BACKEND_BEARSSL + #define DEFAULT_CRT_BACKEND CC_CRT_BACKEND_OPENSSL #define DEFAULT_AUD_BACKEND CC_AUD_BACKEND_OPENAL #define DEFAULT_GFX_BACKEND CC_GFX_BACKEND_GL1 #define DEFAULT_WIN_BACKEND CC_WIN_BACKEND_X11 @@ -325,7 +336,9 @@ typedef cc_uint8 cc_bool; #define CC_BUILD_POSIX #define CC_BUILD_BSD #define CC_BUILD_XINPUT2 - #define DEFAULT_NET_BACKEND CC_NET_BACKEND_LIBCURL + #define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN + #define DEFAULT_SSL_BACKEND CC_SSL_BACKEND_BEARSSL + #define DEFAULT_CRT_BACKEND CC_CRT_BACKEND_OPENSSL #define DEFAULT_AUD_BACKEND CC_AUD_BACKEND_OPENAL #define DEFAULT_GFX_BACKEND CC_GFX_BACKEND_GL1 #define DEFAULT_WIN_BACKEND CC_WIN_BACKEND_X11 @@ -334,7 +347,9 @@ typedef cc_uint8 cc_bool; #define CC_BUILD_POSIX #define CC_BUILD_BSD #define CC_BUILD_XINPUT2 - #define DEFAULT_NET_BACKEND CC_NET_BACKEND_LIBCURL + #define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN + #define DEFAULT_SSL_BACKEND CC_SSL_BACKEND_BEARSSL + #define DEFAULT_CRT_BACKEND CC_CRT_BACKEND_OPENSSL #define DEFAULT_AUD_BACKEND CC_AUD_BACKEND_OPENAL #define DEFAULT_GFX_BACKEND CC_GFX_BACKEND_GL1 #define DEFAULT_WIN_BACKEND CC_WIN_BACKEND_X11 @@ -342,7 +357,9 @@ typedef cc_uint8 cc_bool; #define CC_BUILD_HAIKU #define CC_BUILD_POSIX #define CC_BACKTRACE_BUILTIN - #define DEFAULT_NET_BACKEND CC_NET_BACKEND_LIBCURL + #define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN + #define DEFAULT_SSL_BACKEND CC_SSL_BACKEND_BEARSSL + #define DEFAULT_CRT_BACKEND CC_CRT_BACKEND_OPENSSL #define DEFAULT_AUD_BACKEND CC_AUD_BACKEND_OPENAL #define DEFAULT_GFX_BACKEND CC_GFX_BACKEND_GL1 #define DEFAULT_WIN_BACKEND CC_WIN_BACKEND_BEOS @@ -359,7 +376,9 @@ typedef cc_uint8 cc_bool; #define CC_BUILD_IRIX #define CC_BUILD_POSIX #define CC_BIG_ENDIAN - #define DEFAULT_NET_BACKEND CC_NET_BACKEND_LIBCURL + #define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN + #define DEFAULT_SSL_BACKEND CC_SSL_BACKEND_BEARSSL + #define DEFAULT_CRT_BACKEND CC_CRT_BACKEND_OPENSSL #define DEFAULT_AUD_BACKEND CC_AUD_BACKEND_OPENAL #define DEFAULT_GFX_BACKEND CC_GFX_BACKEND_GL1 #define DEFAULT_WIN_BACKEND CC_WIN_BACKEND_X11 @@ -525,7 +544,9 @@ typedef cc_uint8 cc_bool; #define CC_BUILD_OS2 #define CC_BUILD_POSIX #define CC_BUILD_FREETYPE - #define DEFAULT_NET_BACKEND CC_NET_BACKEND_LIBCURL + #define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN + #define DEFAULT_SSL_BACKEND CC_SSL_BACKEND_BEARSSL + #define DEFAULT_CRT_BACKEND CC_CRT_BACKEND_OPENSSL #define DEFAULT_GFX_BACKEND CC_GFX_BACKEND_SOFTGPU #define DEFAULT_WIN_BACKEND CC_WIN_BACKEND_OS2 #elif defined PLAT_SATURN @@ -597,6 +618,9 @@ typedef cc_uint8 cc_bool; #if defined DEFAULT_SSL_BACKEND && !defined CC_SSL_BACKEND #define CC_SSL_BACKEND DEFAULT_SSL_BACKEND #endif +#if defined DEFAULT_CRT_BACKEND && !defined CC_CRT_BACKEND + #define CC_CRT_BACKEND DEFAULT_CRT_BACKEND +#endif #if defined DEFAULT_NET_BACKEND && !defined CC_NET_BACKEND #define CC_NET_BACKEND DEFAULT_NET_BACKEND #endif diff --git a/src/Logger.c b/src/Logger.c index e1d3a24d3..c1ffd251a 100644 --- a/src/Logger.c +++ b/src/Logger.c @@ -1249,7 +1249,7 @@ void Logger_FailToStart(const char* raw_msg) { #include static _Unwind_Reason_Code UnwindFrame(struct _Unwind_Context* ctx, void* arg) { - cc_uintptr addr = _Unwind_GetIP(ctx); + cc_uintptr addr = (cc_uintptr)_Unwind_GetIP(ctx); if (!addr) return _URC_END_OF_STACK; DumpFrame((cc_string*)arg, (void*)addr); diff --git a/src/SSL.c b/src/SSL.c index a296b1c70..ba323ff61 100644 --- a/src/SSL.c +++ b/src/SSL.c @@ -406,17 +406,53 @@ cc_result SSL_Free(void* ctx_) { } #elif CC_SSL_BACKEND == CC_SSL_BACKEND_BEARSSL #include "String.h" +#include "Certs.h" #include "bearssl.h" #include "../misc/certs/certs.h" + // https://github.com/unkaktus/bearssl/blob/master/samples/client_basic.c#L283 #define SSL_ERROR_SHIFT 0xB5510000 -static br_x509_class cert_verifier_vtable; +typedef struct SSLContext { + br_x509_minimal_context xc; + br_ssl_client_context sc; + struct X509CertContext x509; + unsigned char iobuf[BR_SSL_BUFSIZE_BIDI]; + br_sslio_context ioc; + cc_result readError, writeError; + cc_socket socket; +} SSLContext; static cc_bool _verifyCerts; -static unsigned cert_verifier_end_chain(const br_x509_class** ctx) { - unsigned r = br_x509_minimal_vtable.end_chain(ctx); +static void x509_start_cert(const br_x509_class** ctx, uint32_t length) { + struct SSLContext* ssl = (struct SSLContext*)ctx; + br_x509_minimal_vtable.start_cert(ctx, length); + Certs_BeginCert(&ssl->x509, length); +} + +static void x509_append(const br_x509_class** ctx, const unsigned char* buf, size_t len) { + struct SSLContext* ssl = (struct SSLContext*)ctx; + + br_x509_minimal_vtable.append(ctx, buf, len); + Certs_AppendCert(&ssl->x509, buf, len); +} + +static void x509_end_cert(const br_x509_class** ctx) { + struct SSLContext* ssl = (struct SSLContext*)ctx; + + br_x509_minimal_vtable.end_cert(ctx); + Certs_FinishCert(&ssl->x509); +} + +static void x509_start_chain(const br_x509_class** ctx, const char* server_name) { + struct SSLContext* ssl = (struct SSLContext*)ctx; + + br_x509_minimal_vtable.start_chain(ctx, server_name); + Certs_BeginChain(&ssl->x509); +} + +static unsigned x509_maybe_skip_verify(unsigned r) { /* User selected to not care about certificate authenticity */ if (r == BR_ERR_X509_NOT_TRUSTED && !_verifyCerts) return 0; @@ -434,20 +470,36 @@ static unsigned cert_verifier_end_chain(const br_x509_class** ctx) { return r; } -typedef struct SSLContext { - br_x509_minimal_context xc; - br_ssl_client_context sc; - unsigned char iobuf[BR_SSL_BUFSIZE_BIDI]; - br_sslio_context ioc; - cc_result readError, writeError; - cc_socket socket; -} SSLContext; +static unsigned x509_end_chain(const br_x509_class** ctx) { + struct SSLContext* ssl = (struct SSLContext*)ctx; + + unsigned r = br_x509_minimal_vtable.end_chain(ctx); + r = x509_maybe_skip_verify(r); + + /* Fallback to system specific certificate validation */ + if (r == BR_ERR_X509_NOT_TRUSTED && Certs_VerifyChain(&ssl->x509) == 0) r = 0; + + Certs_FreeChain(&ssl->x509); + return r; +} + +static const br_x509_pkey* x509_get_pkey(const br_x509_class*const* ctx, unsigned* usages) { + return br_x509_minimal_vtable.get_pkey(ctx, usages); +} + +static const br_x509_class cert_verifier_vtable = { + sizeof(br_x509_minimal_context), + x509_start_chain, + x509_start_cert, + x509_append, + x509_end_cert, + x509_end_chain, + x509_get_pkey +}; void SSLBackend_Init(cc_bool verifyCerts) { _verifyCerts = verifyCerts; - - cert_verifier_vtable = br_x509_minimal_vtable; - cert_verifier_vtable.end_chain = cert_verifier_end_chain; + CertsBackend_Init(); } cc_bool SSLBackend_DescribeError(cc_result res, cc_string* dst) { diff --git a/third_party/bearssl/inc/bearssl.h b/third_party/bearssl/inc/bearssl.h index 0679cdd4b..2ce6fe7c5 100644 --- a/third_party/bearssl/inc/bearssl.h +++ b/third_party/bearssl/inc/bearssl.h @@ -39,7 +39,6 @@ * | :-------------- | :------------------------------------------------ | * | bearssl_hash.h | Hash functions | * | bearssl_hmac.h | HMAC | - * | bearssl_kdf.h | Key Derivation Functions | * | bearssl_rand.h | Pseudorandom byte generators | * | bearssl_prf.h | PRF implementations (for SSL/TLS) | * | bearssl_block.h | Symmetric encryption | @@ -48,7 +47,6 @@ * | bearssl_ec.h | Elliptic curves support (including ECDSA) | * | bearssl_ssl.h | SSL/TLS engine interface | * | bearssl_x509.h | X.509 certificate decoding and validation | - * | bearssl_pem.h | Base64/PEM decoding support functions | * * Applications using BearSSL are supposed to simply include `bearssl.h` * as follows: @@ -130,7 +128,6 @@ #include "bearssl_hash.h" #include "bearssl_hmac.h" -#include "bearssl_kdf.h" #include "bearssl_rand.h" #include "bearssl_prf.h" #include "bearssl_block.h" @@ -139,49 +136,5 @@ #include "bearssl_ec.h" #include "bearssl_ssl.h" #include "bearssl_x509.h" -#include "bearssl_pem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \brief Type for a configuration option. - * - * A "configuration option" is a value that is selected when the BearSSL - * library itself is compiled. Most options are boolean; their value is - * then either 1 (option is enabled) or 0 (option is disabled). Some - * values have other integer values. Option names correspond to macro - * names. Some of the options can be explicitly set in the internal - * `"config.h"` file. - */ -typedef struct { - /** \brief Configurable option name. */ - const char *name; - /** \brief Configurable option value. */ - long value; -} br_config_option; - -/** \brief Get configuration report. - * - * This function returns compiled configuration options, each as a - * 'long' value. Names match internal macro names, in particular those - * that can be set in the `"config.h"` inner file. For boolean options, - * the numerical value is 1 if enabled, 0 if disabled. For maximum - * key sizes, values are expressed in bits. - * - * The returned array is terminated by an entry whose `name` is `NULL`. - * - * \return the configuration report. - */ -const br_config_option *br_get_config(void); - -/* ======================================================================= */ - -/** \brief Version feature: support for time callback. */ -#define BR_FEATURE_X509_TIME_CALLBACK 1 - -#ifdef __cplusplus -} -#endif #endif diff --git a/third_party/bearssl/inc/bearssl_block.h b/third_party/bearssl/inc/bearssl_block.h index 5ab4be449..c3e6d7a95 100644 --- a/third_party/bearssl/inc/bearssl_block.h +++ b/third_party/bearssl/inc/bearssl_block.h @@ -299,13 +299,6 @@ extern "C" { * | aes_ct | AES | 16 | 16, 24 and 32 | * | aes_ct64 | AES | 16 | 16, 24 and 32 | * | aes_x86ni | AES | 16 | 16, 24 and 32 | - * | des_ct | DES/3DES | 8 | 8, 16 and 24 | - * | des_tab | DES/3DES | 8 | 8, 16 and 24 | - * - * **Note:** DES/3DES nominally uses keys of 64, 128 and 192 bits (i.e. 8, - * 16 and 24 bytes), but some of the bits are ignored by the algorithm, so - * the _effective_ key lengths, from a security point of view, are 56, - * 112 and 168 bits, respectively. * * `aes_big` is a "classical" AES implementation, using tables. It * is fast but not constant-time, since it makes data-dependent array @@ -334,12 +327,6 @@ extern "C" { * `aes_x86ni` exists only on x86 architectures (32-bit and 64-bit). It * uses the AES-NI opcodes when available. * - * `des_tab` is a classic, table-based implementation of DES/3DES. It - * is not constant-time. - * - * `des_ct` is an constant-time implementation of DES/3DES. It is - * substantially slower than `des_tab`. - * * ## ChaCha20 and Poly1305 * * ChaCha20 is a stream cipher. Poly1305 is a MAC algorithm. They @@ -364,19 +351,9 @@ extern "C" { * construction, where the Poly1305 part is performed with mixed 32-bit * multiplications (operands are 32-bit, result is 64-bit). * - * `poly1305_ctmul32` implements ChaCha20+Poly1305 using pure 32-bit - * multiplications (32-bit operands, 32-bit result). It is slower than - * `poly1305_ctmul`, except on some specific architectures such as - * the ARM Cortex M0+. - * * `poly1305_ctmulq` implements ChaCha20+Poly1305 with mixed 64-bit * multiplications (operands are 64-bit, result is 128-bit) on 64-bit * platforms that support such operations. - * - * `poly1305_i15` implements ChaCha20+Poly1305 with the generic "i15" - * big integer implementation. It is meant mostly for testing purposes, - * although it can help with saving a few hundred bytes of code footprint - * on systems where code size is scarce. */ /** @@ -1908,215 +1885,6 @@ typedef union { br_aes_x86ni_ctrcbc_keys c_x86ni; } br_aes_gen_ctrcbc_keys; -/* - * Traditional, table-based implementation for DES/3DES. Since tables are - * used, cache-timing attacks are conceptually possible. - */ - -/** \brief DES/3DES block size (8 bytes). */ -#define br_des_tab_BLOCK_SIZE 8 - -/** - * \brief Context for DES subkeys (`des_tab` implementation, CBC encryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcenc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[96]; - unsigned num_rounds; -#endif -} br_des_tab_cbcenc_keys; - -/** - * \brief Context for DES subkeys (`des_tab` implementation, CBC decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcdec_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[96]; - unsigned num_rounds; -#endif -} br_des_tab_cbcdec_keys; - -/** - * \brief Class instance for DES CBC encryption (`des_tab` implementation). - */ -extern const br_block_cbcenc_class br_des_tab_cbcenc_vtable; - -/** - * \brief Class instance for DES CBC decryption (`des_tab` implementation). - */ -extern const br_block_cbcdec_class br_des_tab_cbcdec_vtable; - -/** - * \brief Context initialisation (key schedule) for DES CBC encryption - * (`des_tab` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_des_tab_cbcenc_init(br_des_tab_cbcenc_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for DES CBC decryption - * (`des_tab` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_des_tab_cbcdec_init(br_des_tab_cbcdec_keys *ctx, - const void *key, size_t len); - -/** - * \brief CBC encryption with DES (`des_tab` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be multiple of 8). - */ -void br_des_tab_cbcenc_run(const br_des_tab_cbcenc_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CBC decryption with DES (`des_tab` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be multiple of 8). - */ -void br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx, void *iv, - void *data, size_t len); - -/* - * Constant-time implementation for DES/3DES. It is substantially slower - * (by a factor of about 4x), but also immune to cache-timing attacks. - */ - -/** \brief DES/3DES block size (8 bytes). */ -#define br_des_ct_BLOCK_SIZE 8 - -/** - * \brief Context for DES subkeys (`des_ct` implementation, CBC encryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcenc_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[96]; - unsigned num_rounds; -#endif -} br_des_ct_cbcenc_keys; - -/** - * \brief Context for DES subkeys (`des_ct` implementation, CBC decryption). - * - * First field is a pointer to the vtable; it is set by the initialisation - * function. Other fields are not supposed to be accessed by user code. - */ -typedef struct { - /** \brief Pointer to vtable for this context. */ - const br_block_cbcdec_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - uint32_t skey[96]; - unsigned num_rounds; -#endif -} br_des_ct_cbcdec_keys; - -/** - * \brief Class instance for DES CBC encryption (`des_ct` implementation). - */ -extern const br_block_cbcenc_class br_des_ct_cbcenc_vtable; - -/** - * \brief Class instance for DES CBC decryption (`des_ct` implementation). - */ -extern const br_block_cbcdec_class br_des_ct_cbcdec_vtable; - -/** - * \brief Context initialisation (key schedule) for DES CBC encryption - * (`des_ct` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_des_ct_cbcenc_init(br_des_ct_cbcenc_keys *ctx, - const void *key, size_t len); - -/** - * \brief Context initialisation (key schedule) for DES CBC decryption - * (`des_ct` implementation). - * - * \param ctx context to initialise. - * \param key secret key. - * \param len secret key length (in bytes). - */ -void br_des_ct_cbcdec_init(br_des_ct_cbcdec_keys *ctx, - const void *key, size_t len); - -/** - * \brief CBC encryption with DES (`des_ct` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to encrypt (updated). - * \param len data length (in bytes, MUST be multiple of 8). - */ -void br_des_ct_cbcenc_run(const br_des_ct_cbcenc_keys *ctx, void *iv, - void *data, size_t len); - -/** - * \brief CBC decryption with DES (`des_ct` implementation). - * - * \param ctx context (already initialised). - * \param iv IV (updated). - * \param data data to decrypt (updated). - * \param len data length (in bytes, MUST be multiple of 8). - */ -void br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx, void *iv, - void *data, size_t len); - -/* - * These structures are large enough to accommodate subkeys for all - * DES/3DES implementations. - */ - -/** - * \brief Aggregate structure large enough to be used as context for - * subkeys (CBC encryption) for all DES implementations. - */ -typedef union { - const br_block_cbcenc_class *vtable; - br_des_tab_cbcenc_keys tab; - br_des_ct_cbcenc_keys ct; -} br_des_gen_cbcenc_keys; - -/** - * \brief Aggregate structure large enough to be used as context for - * subkeys (CBC decryption) for all DES implementations. - */ -typedef union { - const br_block_cbcdec_class *vtable; - br_des_tab_cbcdec_keys c_tab; - br_des_ct_cbcdec_keys c_ct; -} br_des_gen_cbcdec_keys; - /** * \brief Type for a ChaCha20 implementation. * @@ -2234,50 +2002,6 @@ void br_poly1305_ctmul_run(const void *key, const void *iv, void *data, size_t len, const void *aad, size_t aad_len, void *tag, br_chacha20_run ichacha, int encrypt); -/** - * \brief ChaCha20+Poly1305 AEAD implementation (pure 32-bit multiplications). - * - * \see br_poly1305_run - * - * \param key secret key (32 bytes). - * \param iv nonce (12 bytes). - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - * \param aad additional authenticated data. - * \param aad_len length of additional authenticated data (in bytes). - * \param tag output buffer for the authentication tag. - * \param ichacha implementation of ChaCha20. - * \param encrypt non-zero for encryption, zero for decryption. - */ -void br_poly1305_ctmul32_run(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt); - -/** - * \brief ChaCha20+Poly1305 AEAD implementation (i15). - * - * This implementation relies on the generic big integer code "i15" - * (which uses pure 32-bit multiplications). As such, it may save a - * little code footprint in a context where "i15" is already included - * (e.g. for elliptic curves or for RSA); however, it is also - * substantially slower than the ctmul and ctmul32 implementations. - * - * \see br_poly1305_run - * - * \param key secret key (32 bytes). - * \param iv nonce (12 bytes). - * \param data data to encrypt or decrypt. - * \param len data length (in bytes). - * \param aad additional authenticated data. - * \param aad_len length of additional authenticated data (in bytes). - * \param tag output buffer for the authentication tag. - * \param ichacha implementation of ChaCha20. - * \param encrypt non-zero for encryption, zero for decryption. - */ -void br_poly1305_i15_run(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt); - /** * \brief ChaCha20+Poly1305 AEAD implementation (ctmulq). * diff --git a/third_party/bearssl/inc/bearssl_ec.h b/third_party/bearssl/inc/bearssl_ec.h index acd3a2bf5..5410d7c13 100644 --- a/third_party/bearssl/inc/bearssl_ec.h +++ b/third_party/bearssl/inc/bearssl_ec.h @@ -423,25 +423,6 @@ typedef struct { */ extern const br_ec_impl br_ec_prime_i31; -/** - * \brief EC implementation "i15". - * - * This implementation internally uses generic code for modular integers, - * with a representation as sequences of 15-bit words. It supports secp256r1, - * secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521). - */ -extern const br_ec_impl br_ec_prime_i15; - -/** - * \brief EC implementation "m15" for P-256. - * - * This implementation uses specialised code for curve secp256r1 (also - * known as NIST P-256), with optional Karatsuba decomposition, and fast - * modular reduction thanks to the field modulus special format. Only - * 32-bit multiplications are used (with 32-bit results, not 64-bit). - */ -extern const br_ec_impl br_ec_p256_m15; - /** * \brief EC implementation "m31" for P-256. * @@ -487,20 +468,6 @@ extern const br_ec_impl br_ec_p256_m64; */ const br_ec_impl *br_ec_p256_m64_get(void); -/** - * \brief EC implementation "i15" (generic code) for Curve25519. - * - * This implementation uses the generic code for modular integers (with - * 15-bit words) to support Curve25519. Due to the specificities of the - * curve definition, the following applies: - * - * - `muladd()` is not implemented (the function returns 0 systematically). - * - `order()` returns 2^255-1, since the point multiplication algorithm - * accepts any 32-bit integer as input (it clears the top bit and low - * three bits systematically). - */ -extern const br_ec_impl br_ec_c25519_i15; - /** * \brief EC implementation "i31" (generic code) for Curve25519. * @@ -515,20 +482,6 @@ extern const br_ec_impl br_ec_c25519_i15; */ extern const br_ec_impl br_ec_c25519_i31; -/** - * \brief EC implementation "m15" (specialised code) for Curve25519. - * - * This implementation uses custom code relying on multiplication of - * integers up to 15 bits. Due to the specificities of the curve - * definition, the following applies: - * - * - `muladd()` is not implemented (the function returns 0 systematically). - * - `order()` returns 2^255-1, since the point multiplication algorithm - * accepts any 32-bit integer as input (it clears the top bit and low - * three bits systematically). - */ -extern const br_ec_impl br_ec_c25519_m15; - /** * \brief EC implementation "m31" (specialised code) for Curve25519. * @@ -591,17 +544,6 @@ extern const br_ec_impl br_ec_c25519_m64; */ const br_ec_impl *br_ec_c25519_m64_get(void); -/** - * \brief Aggregate EC implementation "m15". - * - * This implementation is a wrapper for: - * - * - `br_ec_c25519_m15` for Curve25519 - * - `br_ec_p256_m15` for NIST P-256 - * - `br_ec_prime_i15` for other curves (NIST P-384 and NIST-P512) - */ -extern const br_ec_impl br_ec_all_m15; - /** * \brief Aggregate EC implementation "m31". * @@ -777,72 +719,6 @@ uint32_t br_ecdsa_i31_vrfy_raw(const br_ec_impl *impl, const void *hash, size_t hash_len, const br_ec_public_key *pk, const void *sig, size_t sig_len); -/** - * \brief ECDSA signature generator, "i15" implementation, "asn1" format. - * - * \see br_ecdsa_sign() - * - * \param impl EC implementation to use. - * \param hf hash function used to process the data. - * \param hash_value signed data (hashed). - * \param sk EC private key. - * \param sig destination buffer. - * \return the signature length (in bytes), or 0 on error. - */ -size_t br_ecdsa_i15_sign_asn1(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig); - -/** - * \brief ECDSA signature generator, "i15" implementation, "raw" format. - * - * \see br_ecdsa_sign() - * - * \param impl EC implementation to use. - * \param hf hash function used to process the data. - * \param hash_value signed data (hashed). - * \param sk EC private key. - * \param sig destination buffer. - * \return the signature length (in bytes), or 0 on error. - */ -size_t br_ecdsa_i15_sign_raw(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig); - -/** - * \brief ECDSA signature verifier, "i15" implementation, "asn1" format. - * - * \see br_ecdsa_vrfy() - * - * \param impl EC implementation to use. - * \param hash signed data (hashed). - * \param hash_len hash value length (in bytes). - * \param pk EC public key. - * \param sig signature. - * \param sig_len signature length (in bytes). - * \return 1 on success, 0 on error. - */ -uint32_t br_ecdsa_i15_vrfy_asn1(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, const void *sig, size_t sig_len); - -/** - * \brief ECDSA signature verifier, "i15" implementation, "raw" format. - * - * \see br_ecdsa_vrfy() - * - * \param impl EC implementation to use. - * \param hash signed data (hashed). - * \param hash_len hash value length (in bytes). - * \param pk EC public key. - * \param sig signature. - * \param sig_len signature length (in bytes). - * \return 1 on success, 0 on error. - */ -uint32_t br_ecdsa_i15_vrfy_raw(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, const void *sig, size_t sig_len); - /** * \brief Get "default" ECDSA implementation (signer, asn1 format). * diff --git a/third_party/bearssl/inc/bearssl_hash.h b/third_party/bearssl/inc/bearssl_hash.h index 554683d91..00c1e1d07 100644 --- a/third_party/bearssl/inc/bearssl_hash.h +++ b/third_party/bearssl/inc/bearssl_hash.h @@ -1256,22 +1256,6 @@ typedef void (*br_ghash)(void *y, const void *h, const void *data, size_t len); */ void br_ghash_ctmul(void *y, const void *h, const void *data, size_t len); -/** - * \brief GHASH implementation using multiplications (strict 32-bit). - * - * This implementation uses multiplications of 32-bit values, with a - * 32-bit result. It is usually somewhat slower than `br_ghash_ctmul()`, - * but it is expected to be faster on architectures for which the - * 32-bit multiplication opcode does not yield the upper 32 bits of the - * product. It is constant-time (if multiplications are constant-time). - * - * \param y the array to update. - * \param h the GHASH key. - * \param data the input data (may be `NULL` if `len` is zero). - * \param len the input data length (in bytes). - */ -void br_ghash_ctmul32(void *y, const void *h, const void *data, size_t len); - /** * \brief GHASH implementation using multiplications (64-bit). * diff --git a/third_party/bearssl/inc/bearssl_kdf.h b/third_party/bearssl/inc/bearssl_kdf.h deleted file mode 100644 index 955b84367..000000000 --- a/third_party/bearssl/inc/bearssl_kdf.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_KDF_H__ -#define BR_BEARSSL_KDF_H__ - -#include -#include - -#include "bearssl_hash.h" -#include "bearssl_hmac.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_kdf.h - * - * # Key Derivation Functions - * - * KDF are functions that takes a variable length input, and provide a - * variable length output, meant to be used to derive subkeys from a - * master key. - * - * ## HKDF - * - * HKDF is a KDF defined by [RFC 5869](https://tools.ietf.org/html/rfc5869). - * It is based on HMAC, itself using an underlying hash function. Any - * hash function can be used, as long as it is compatible with the rules - * for the HMAC implementation (i.e. output size is 64 bytes or less, hash - * internal state size is 64 bytes or less, and the internal block length is - * a power of 2 between 16 and 256 bytes). HKDF has two phases: - * - * - HKDF-Extract: the input data in ingested, along with a "salt" value. - * - * - HKDF-Expand: the output is produced, from the result of processing - * the input and salt, and using an extra non-secret parameter called - * "info". - * - * The "salt" and "info" strings are non-secret and can be empty. Their role - * is normally to bind the input and output, respectively, to conventional - * identifiers that qualifu them within the used protocol or application. - * - * The implementation defined in this file uses the following functions: - * - * - `br_hkdf_init()`: initialize an HKDF context, with a hash function, - * and the salt. This starts the HKDF-Extract process. - * - * - `br_hkdf_inject()`: inject more input bytes. This function may be - * called repeatedly if the input data is provided by chunks. - * - * - `br_hkdf_flip()`: end the HKDF-Extract process, and start the - * HKDF-Expand process. - * - * - `br_hkdf_produce()`: get the next bytes of output. This function - * may be called several times to obtain the full output by chunks. - * For correct HKDF processing, the same "info" string must be - * provided for each call. - * - * Note that the HKDF total output size (the number of bytes that - * HKDF-Expand is willing to produce) is limited: if the hash output size - * is _n_ bytes, then the maximum output size is _255*n_. - * - * ## SHAKE - * - * SHAKE is defined in - * [FIPS 202](https://csrc.nist.gov/publications/detail/fips/202/final) - * under two versions: SHAKE128 and SHAKE256, offering an alleged - * "security level" of 128 and 256 bits, respectively (SHAKE128 is - * about 20 to 25% faster than SHAKE256). SHAKE internally relies on - * the Keccak family of sponge functions, not on any externally provided - * hash function. Contrary to HKDF, SHAKE does not have a concept of - * either a "salt" or an "info" string. The API consists in four - * functions: - * - * - `br_shake_init()`: initialize a SHAKE context for a given - * security level. - * - * - `br_shake_inject()`: inject more input bytes. This function may be - * called repeatedly if the input data is provided by chunks. - * - * - `br_shake_flip()`: end the data injection process, and start the - * data production process. - * - * - `br_shake_produce()`: get the next bytes of output. This function - * may be called several times to obtain the full output by chunks. - */ - -/** - * \brief HKDF context. - * - * The HKDF context is initialized with a hash function implementation - * and a salt value. Contents are opaque (callers should not access them - * directly). The caller is responsible for allocating the context where - * appropriate. Context initialisation and usage incurs no dynamic - * allocation, so there is no release function. - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - union { - br_hmac_context hmac_ctx; - br_hmac_key_context prk_ctx; - } u; - unsigned char buf[64]; - size_t ptr; - size_t dig_len; - unsigned chunk_num; -#endif -} br_hkdf_context; - -/** - * \brief HKDF context initialization. - * - * The underlying hash function and salt value are provided. Arbitrary - * salt lengths can be used. - * - * HKDF makes a difference between a salt of length zero, and an - * absent salt (the latter being equivalent to a salt consisting of - * bytes of value zero, of the same length as the hash function output). - * If `salt_len` is zero, then this function assumes that the salt is - * present but of length zero. To specify an _absent_ salt, use - * `BR_HKDF_NO_SALT` as `salt` parameter (`salt_len` is then ignored). - * - * \param hc HKDF context to initialise. - * \param digest_vtable pointer to the hash function implementation vtable. - * \param salt HKDF-Extract salt. - * \param salt_len HKDF-Extract salt length (in bytes). - */ -void br_hkdf_init(br_hkdf_context *hc, const br_hash_class *digest_vtable, - const void *salt, size_t salt_len); - -/** - * \brief The special "absent salt" value for HKDF. - */ -#define BR_HKDF_NO_SALT (&br_hkdf_no_salt) - -#ifndef BR_DOXYGEN_IGNORE -extern const unsigned char br_hkdf_no_salt; -#endif - -/** - * \brief HKDF input injection (HKDF-Extract). - * - * This function injects some more input bytes ("key material") into - * HKDF. This function may be called several times, after `br_hkdf_init()` - * but before `br_hkdf_flip()`. - * - * \param hc HKDF context. - * \param ikm extra input bytes. - * \param ikm_len number of extra input bytes. - */ -void br_hkdf_inject(br_hkdf_context *hc, const void *ikm, size_t ikm_len); - -/** - * \brief HKDF switch to the HKDF-Expand phase. - * - * This call terminates the HKDF-Extract process (input injection), and - * starts the HKDF-Expand process (output production). - * - * \param hc HKDF context. - */ -void br_hkdf_flip(br_hkdf_context *hc); - -/** - * \brief HKDF output production (HKDF-Expand). - * - * Produce more output bytes from the current state. This function may be - * called several times, but only after `br_hkdf_flip()`. - * - * Returned value is the number of actually produced bytes. The total - * output length is limited to 255 times the output length of the - * underlying hash function. - * - * \param hc HKDF context. - * \param info application specific information string. - * \param info_len application specific information string length (in bytes). - * \param out destination buffer for the HKDF output. - * \param out_len the length of the requested output (in bytes). - * \return the produced output length (in bytes). - */ -size_t br_hkdf_produce(br_hkdf_context *hc, - const void *info, size_t info_len, void *out, size_t out_len); - -/** - * \brief SHAKE context. - * - * The HKDF context is initialized with a "security level". The internal - * notion is called "capacity"; the capacity is twice the security level - * (for instance, SHAKE128 has capacity 256). - * - * The caller is responsible for allocating the context where - * appropriate. Context initialisation and usage incurs no dynamic - * allocation, so there is no release function. - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - unsigned char dbuf[200]; - size_t dptr; - size_t rate; - uint64_t A[25]; -#endif -} br_shake_context; - -/** - * \brief SHAKE context initialization. - * - * The context is initialized for the provided "security level". - * Internally, this sets the "capacity" to twice the security level; - * thus, for SHAKE128, the `security_level` parameter should be 128, - * which corresponds to a 256-bit capacity. - * - * Allowed security levels are all multiples of 32, from 32 to 768, - * inclusive. Larger security levels imply lower performance; levels - * beyond 256 bits don't make much sense. Standard levels are 128 - * and 256 bits (for SHAKE128 and SHAKE256, respectively). - * - * \param sc SHAKE context to initialise. - * \param security_level security level (in bits). - */ -void br_shake_init(br_shake_context *sc, int security_level); - -/** - * \brief SHAKE input injection. - * - * This function injects some more input bytes ("key material") into - * SHAKE. This function may be called several times, after `br_shake_init()` - * but before `br_shake_flip()`. - * - * \param sc SHAKE context. - * \param data extra input bytes. - * \param len number of extra input bytes. - */ -void br_shake_inject(br_shake_context *sc, const void *data, size_t len); - -/** - * \brief SHAKE switch to production phase. - * - * This call terminates the input injection process, and starts the - * output production process. - * - * \param sc SHAKE context. - */ -void br_shake_flip(br_shake_context *hc); - -/** - * \brief SHAKE output production. - * - * Produce more output bytes from the current state. This function may be - * called several times, but only after `br_shake_flip()`. - * - * There is no practical limit to the number of bytes that may be produced. - * - * \param sc SHAKE context. - * \param out destination buffer for the SHAKE output. - * \param len the length of the requested output (in bytes). - */ -void br_shake_produce(br_shake_context *sc, void *out, size_t len); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/third_party/bearssl/inc/bearssl_pem.h b/third_party/bearssl/inc/bearssl_pem.h deleted file mode 100644 index 8dba58272..000000000 --- a/third_party/bearssl/inc/bearssl_pem.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef BR_BEARSSL_PEM_H__ -#define BR_BEARSSL_PEM_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file bearssl_pem.h - * - * # PEM Support - * - * PEM is a traditional encoding layer use to store binary objects (in - * particular X.509 certificates, and private keys) in text files. While - * the acronym comes from an old, defunct standard ("Privacy Enhanced - * Mail"), the format has been reused, with some variations, by many - * systems, and is a _de facto_ standard, even though it is not, actually, - * specified in all clarity anywhere. - * - * ## Format Details - * - * BearSSL contains a generic, streamed PEM decoder, which handles the - * following format: - * - * - The input source (a sequence of bytes) is assumed to be the - * encoding of a text file in an ASCII-compatible charset. This - * includes ISO-8859-1, Windows-1252, and UTF-8 encodings. Each - * line ends on a newline character (U+000A LINE FEED). The - * U+000D CARRIAGE RETURN characters are ignored, so the code - * accepts both Windows-style and Unix-style line endings. - * - * - Each object begins with a banner that occurs at the start of - * a line; the first banner characters are "`-----BEGIN `" (five - * dashes, the word "BEGIN", and a space). The banner matching is - * not case-sensitive. - * - * - The _object name_ consists in the characters that follow the - * banner start sequence, up to the end of the line, but without - * trailing dashes (in "normal" PEM, there are five trailing - * dashes, but this implementation is not picky about these dashes). - * The BearSSL decoder normalises the name characters to uppercase - * (for ASCII letters only) and accepts names up to 127 characters. - * - * - The object ends with a banner that again occurs at the start of - * a line, and starts with "`-----END `" (again case-insensitive). - * - * - Between that start and end banner, only Base64 data shall occur. - * Base64 converts each sequence of three bytes into four - * characters; the four characters are ASCII letters, digits, "`+`" - * or "`-`" signs, and one or two "`=`" signs may occur in the last - * quartet. Whitespace is ignored (whitespace is any ASCII character - * of code 32 or less, so control characters are whitespace) and - * lines may have arbitrary length; the only restriction is that the - * four characters of a quartet must appear on the same line (no - * line break inside a quartet). - * - * - A single file may contain more than one PEM object. Bytes that - * occur between objects are ignored. - * - * - * ## PEM Decoder API - * - * The PEM decoder offers a state-machine API. The caller allocates a - * decoder context, then injects source bytes. Source bytes are pushed - * with `br_pem_decoder_push()`. The decoder stops accepting bytes when - * it reaches an "event", which is either the start of an object, the - * end of an object, or a decoding error within an object. - * - * The `br_pem_decoder_event()` function is used to obtain the current - * event; it also clears it, thus allowing the decoder to accept more - * bytes. When a object start event is raised, the decoder context - * offers the found object name (normalised to ASCII uppercase). - * - * When an object is reached, the caller must set an appropriate callback - * function, which will receive (by chunks) the decoded object data. - * - * Since the decoder context makes no dynamic allocation, it requires - * no explicit deallocation. - */ - -/** - * \brief PEM decoder context. - * - * Contents are opaque (they should not be accessed directly). - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - /* CPU for the T0 virtual machine. */ - struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; - } cpu; - uint32_t dp_stack[32]; - uint32_t rp_stack[32]; - int err; - - const unsigned char *hbuf; - size_t hlen; - - void (*dest)(void *dest_ctx, const void *src, size_t len); - void *dest_ctx; - - unsigned char event; - char name[128]; - unsigned char buf[255]; - size_t ptr; -#endif -} br_pem_decoder_context; - -/** - * \brief Initialise a PEM decoder structure. - * - * \param ctx decoder context to initialise. - */ -void br_pem_decoder_init(br_pem_decoder_context *ctx); - -/** - * \brief Push some bytes into the decoder. - * - * Returned value is the number of bytes actually consumed; this may be - * less than the number of provided bytes if an event is raised. When an - * event is raised, it must be read (with `br_pem_decoder_event()`); - * until the event is read, this function will return 0. - * - * \param ctx decoder context. - * \param data new data bytes. - * \param len number of new data bytes. - * \return the number of bytes actually received (may be less than `len`). - */ -size_t br_pem_decoder_push(br_pem_decoder_context *ctx, - const void *data, size_t len); - -/** - * \brief Set the receiver for decoded data. - * - * When an object is entered, the provided function (with opaque context - * pointer) will be called repeatedly with successive chunks of decoded - * data for that object. If `dest` is set to 0, then decoded data is - * simply ignored. The receiver can be set at any time, but, in practice, - * it should be called immediately after receiving a "start of object" - * event. - * - * \param ctx decoder context. - * \param dest callback for receiving decoded data. - * \param dest_ctx opaque context pointer for the `dest` callback. - */ -static inline void -br_pem_decoder_setdest(br_pem_decoder_context *ctx, - void (*dest)(void *dest_ctx, const void *src, size_t len), - void *dest_ctx) -{ - ctx->dest = dest; - ctx->dest_ctx = dest_ctx; -} - -/** - * \brief Get the last event. - * - * If an event was raised, then this function returns the event value, and - * also clears it, thereby allowing the decoder to proceed. If no event - * was raised since the last call to `br_pem_decoder_event()`, then this - * function returns 0. - * - * \param ctx decoder context. - * \return the raised event, or 0. - */ -int br_pem_decoder_event(br_pem_decoder_context *ctx); - -/** - * \brief Event: start of object. - * - * This event is raised when the start of a new object has been detected. - * The object name (normalised to uppercase) can be accessed with - * `br_pem_decoder_name()`. - */ -#define BR_PEM_BEGIN_OBJ 1 - -/** - * \brief Event: end of object. - * - * This event is raised when the end of the current object is reached - * (normally, i.e. with no decoding error). - */ -#define BR_PEM_END_OBJ 2 - -/** - * \brief Event: decoding error. - * - * This event is raised when decoding fails within an object. - * This formally closes the current object and brings the decoder back - * to the "out of any object" state. The offending line in the source - * is consumed. - */ -#define BR_PEM_ERROR 3 - -/** - * \brief Get the name of the encountered object. - * - * The encountered object name is defined only when the "start of object" - * event is raised. That name is normalised to uppercase (for ASCII letters - * only) and does not include trailing dashes. - * - * \param ctx decoder context. - * \return the current object name. - */ -static inline const char * -br_pem_decoder_name(br_pem_decoder_context *ctx) -{ - return ctx->name; -} - -/** - * \brief Encode an object in PEM. - * - * This function encodes the provided binary object (`data`, of length `len` - * bytes) into PEM. The `banner` text will be included in the header and - * footer (e.g. use `"CERTIFICATE"` to get a `"BEGIN CERTIFICATE"` header). - * - * The length (in characters) of the PEM output is returned; that length - * does NOT include the terminating zero, that this function nevertheless - * adds. If using the returned value for allocation purposes, the allocated - * buffer size MUST be at least one byte larger than the returned size. - * - * If `dest` is `NULL`, then the encoding does not happen; however, the - * length of the encoded object is still computed and returned. - * - * The `data` pointer may be `NULL` only if `len` is zero (when encoding - * an object of length zero, which is not very useful), or when `dest` - * is `NULL` (in that case, source data bytes are ignored). - * - * Some `flags` can be specified to alter the encoding behaviour: - * - * - If `BR_PEM_LINE64` is set, then line-breaking will occur after - * every 64 characters of output, instead of the default of 76. - * - * - If `BR_PEM_CRLF` is set, then end-of-line sequence will use - * CR+LF instead of a single LF. - * - * The `data` and `dest` buffers may overlap, in which case the source - * binary data is destroyed in the process. Note that the PEM-encoded output - * is always larger than the source binary. - * - * \param dest the destination buffer (or `NULL`). - * \param data the source buffer (can be `NULL` in some cases). - * \param len the source length (in bytes). - * \param banner the PEM banner expression. - * \param flags the behavioural flags. - * \return the PEM object length (in characters), EXCLUDING the final zero. - */ -size_t br_pem_encode(void *dest, const void *data, size_t len, - const char *banner, unsigned flags); - -/** - * \brief PEM encoding flag: split lines at 64 characters. - */ -#define BR_PEM_LINE64 0x0001 - -/** - * \brief PEM encoding flag: use CR+LF line endings. - */ -#define BR_PEM_CRLF 0x0002 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/third_party/bearssl/inc/bearssl_ssl.h b/third_party/bearssl/inc/bearssl_ssl.h index e91df4755..cba7378b5 100644 --- a/third_party/bearssl/inc/bearssl_ssl.h +++ b/third_party/bearssl/inc/bearssl_ssl.h @@ -448,7 +448,6 @@ typedef struct { union { const br_block_cbcdec_class *vtable; br_aes_gen_cbcdec_keys aes; - br_des_gen_cbcdec_keys des; } bc; br_hmac_key_context mac; size_t mac_len; @@ -477,7 +476,6 @@ typedef struct { union { const br_block_cbcenc_class *vtable; br_aes_gen_cbcenc_keys aes; - br_des_gen_cbcenc_keys des; } bc; br_hmac_key_context mac; size_t mac_len; @@ -1099,8 +1097,6 @@ typedef struct { const br_block_cbcdec_class *iaes_cbcdec; const br_block_ctr_class *iaes_ctr; const br_block_ctrcbc_class *iaes_ctrcbc; - const br_block_cbcenc_class *ides_cbcenc; - const br_block_cbcdec_class *ides_cbcdec; br_ghash ighash; br_chacha20_run ichacha; br_poly1305_run ipoly; @@ -1482,34 +1478,6 @@ br_ssl_engine_set_aes_ctr(br_ssl_engine_context *cc, */ void br_ssl_engine_set_default_aes_gcm(br_ssl_engine_context *cc); -/** - * \brief Set the DES/CBC implementations. - * - * \param cc SSL engine context. - * \param impl_enc DES/CBC encryption implementation (or `NULL`). - * \param impl_dec DES/CBC decryption implementation (or `NULL`). - */ -static inline void -br_ssl_engine_set_des_cbc(br_ssl_engine_context *cc, - const br_block_cbcenc_class *impl_enc, - const br_block_cbcdec_class *impl_dec) -{ - cc->ides_cbcenc = impl_enc; - cc->ides_cbcdec = impl_dec; -} - -/** - * \brief Set the "default" DES/CBC implementations. - * - * This function configures in the engine the DES implementations that - * should provide best runtime performance on the local system, while - * still being safe (in particular, constant-time). It also sets the - * handlers for CBC records. - * - * \param cc SSL engine context. - */ -void br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc); - /** * \brief Set the GHASH implementation (used in GCM mode). * @@ -2234,41 +2202,6 @@ void br_ssl_engine_close(br_ssl_engine_context *cc); */ int br_ssl_engine_renegotiate(br_ssl_engine_context *cc); -/** - * \brief Export key material from a connected SSL engine (RFC 5705). - * - * This calls compute a secret key of arbitrary length from the master - * secret of a connected SSL engine. If the provided context is not - * currently in "application data" state (initial handshake is not - * finished, another handshake is ongoing, or the connection failed or - * was closed), then this function returns 0. Otherwise, a secret key of - * length `len` bytes is computed and written in the buffer pointed to - * by `dst`, and 1 is returned. - * - * The computed key follows the specification described in RFC 5705. - * That RFC includes two key computations, with and without a "context - * value". If `context` is `NULL`, then the variant without context is - * used; otherwise, the `context_len` bytes located at the address - * pointed to by `context` are used in the computation. Note that it - * is possible to have a "with context" key with a context length of - * zero bytes, by setting `context` to a non-`NULL` value but - * `context_len` to 0. - * - * When context bytes are used, the context length MUST NOT exceed - * 65535 bytes. - * - * \param cc SSL engine context. - * \param dst destination buffer for exported key. - * \param len exported key length (in bytes). - * \param label disambiguation label. - * \param context context value (or `NULL`). - * \param context_len context length (in bytes). - * \return 1 on success, 0 on error. - */ -int br_ssl_key_export(br_ssl_engine_context *cc, - void *dst, size_t len, const char *label, - const void *context, size_t context_len); - /* * Pre-declaration for the SSL client context. */ @@ -2926,994 +2859,6 @@ void br_ssl_client_set_single_ec(br_ssl_client_context *cc, unsigned cert_issuer_key_type, const br_ec_impl *iec, br_ecdsa_sign iecdsa); -/** - * \brief Type for a "translated cipher suite", as an array of two - * 16-bit integers. - * - * The first element is the cipher suite identifier (as used on the wire). - * The second element is the concatenation of four 4-bit elements which - * characterise the cipher suite contents. In most to least significant - * order, these 4-bit elements are: - * - * - Bits 12 to 15: key exchange + server key type - * - * | val | symbolic constant | suite type | details | - * | :-- | :----------------------- | :---------- | :----------------------------------------------- | - * | 0 | `BR_SSLKEYX_RSA` | RSA | RSA key exchange, key is RSA (encryption) | - * | 1 | `BR_SSLKEYX_ECDHE_RSA` | ECDHE_RSA | ECDHE key exchange, key is RSA (signature) | - * | 2 | `BR_SSLKEYX_ECDHE_ECDSA` | ECDHE_ECDSA | ECDHE key exchange, key is EC (signature) | - * | 3 | `BR_SSLKEYX_ECDH_RSA` | ECDH_RSA | Key is EC (key exchange), cert signed with RSA | - * | 4 | `BR_SSLKEYX_ECDH_ECDSA` | ECDH_ECDSA | Key is EC (key exchange), cert signed with ECDSA | - * - * - Bits 8 to 11: symmetric encryption algorithm - * - * | val | symbolic constant | symmetric encryption | key strength (bits) | - * | :-- | :--------------------- | :------------------- | :------------------ | - * | 0 | `BR_SSLENC_3DES_CBC` | 3DES/CBC | 168 | - * | 1 | `BR_SSLENC_AES128_CBC` | AES-128/CBC | 128 | - * | 2 | `BR_SSLENC_AES256_CBC` | AES-256/CBC | 256 | - * | 3 | `BR_SSLENC_AES128_GCM` | AES-128/GCM | 128 | - * | 4 | `BR_SSLENC_AES256_GCM` | AES-256/GCM | 256 | - * | 5 | `BR_SSLENC_CHACHA20` | ChaCha20/Poly1305 | 256 | - * - * - Bits 4 to 7: MAC algorithm - * - * | val | symbolic constant | MAC type | details | - * | :-- | :----------------- | :----------- | :------------------------------------ | - * | 0 | `BR_SSLMAC_AEAD` | AEAD | No dedicated MAC (encryption is AEAD) | - * | 2 | `BR_SSLMAC_SHA1` | HMAC/SHA-1 | Value matches `br_sha1_ID` | - * | 4 | `BR_SSLMAC_SHA256` | HMAC/SHA-256 | Value matches `br_sha256_ID` | - * | 5 | `BR_SSLMAC_SHA384` | HMAC/SHA-384 | Value matches `br_sha384_ID` | - * - * - Bits 0 to 3: hash function for PRF when used with TLS-1.2 - * - * | val | symbolic constant | hash function | details | - * | :-- | :----------------- | :------------ | :----------------------------------- | - * | 4 | `BR_SSLPRF_SHA256` | SHA-256 | Value matches `br_sha256_ID` | - * | 5 | `BR_SSLPRF_SHA384` | SHA-384 | Value matches `br_sha384_ID` | - * - * For instance, cipher suite `TLS_RSA_WITH_AES_128_GCM_SHA256` has - * standard identifier 0x009C, and is translated to 0x0304, for, in - * that order: RSA key exchange (0), AES-128/GCM (3), AEAD integrity (0), - * SHA-256 in the TLS PRF (4). - */ -typedef uint16_t br_suite_translated[2]; - -#ifndef BR_DOXYGEN_IGNORE -/* - * Constants are already documented in the br_suite_translated type. - */ - -#define BR_SSLKEYX_RSA 0 -#define BR_SSLKEYX_ECDHE_RSA 1 -#define BR_SSLKEYX_ECDHE_ECDSA 2 -#define BR_SSLKEYX_ECDH_RSA 3 -#define BR_SSLKEYX_ECDH_ECDSA 4 - -#define BR_SSLENC_3DES_CBC 0 -#define BR_SSLENC_AES128_CBC 1 -#define BR_SSLENC_AES256_CBC 2 -#define BR_SSLENC_AES128_GCM 3 -#define BR_SSLENC_AES256_GCM 4 -#define BR_SSLENC_CHACHA20 5 - -#define BR_SSLMAC_AEAD 0 -#define BR_SSLMAC_SHA1 br_sha1_ID -#define BR_SSLMAC_SHA256 br_sha256_ID -#define BR_SSLMAC_SHA384 br_sha384_ID - -#define BR_SSLPRF_SHA256 br_sha256_ID -#define BR_SSLPRF_SHA384 br_sha384_ID - -#endif - -/* - * Pre-declaration for the SSL server context. - */ -typedef struct br_ssl_server_context_ br_ssl_server_context; - -/** - * \brief Type for the server policy choices, taken after analysis of - * the client message (ClientHello). - */ -typedef struct { - /** - * \brief Cipher suite to use with that client. - */ - uint16_t cipher_suite; - - /** - * \brief Hash function or algorithm for signing the ServerKeyExchange. - * - * This parameter is ignored for `TLS_RSA_*` and `TLS_ECDH_*` - * cipher suites; it is used only for `TLS_ECDHE_*` suites, in - * which the server _signs_ the ephemeral EC Diffie-Hellman - * parameters sent to the client. - * - * This identifier must be one of the following values: - * - * - `0xFF00 + id`, where `id` is a hash function identifier - * (0 for MD5+SHA-1, or 2 to 6 for one of the SHA functions); - * - * - a full 16-bit identifier, lower than `0xFF00`. - * - * If the first option is used, then the SSL engine will - * compute the hash of the data that is to be signed, with the - * designated hash function. The `do_sign()` method will be - * invoked with that hash value provided in the the `data` - * buffer. - * - * If the second option is used, then the SSL engine will NOT - * compute a hash on the data; instead, it will provide the - * to-be-signed data itself in `data`, i.e. the concatenation of - * the client random, server random, and encoded ECDH - * parameters. Furthermore, with TLS-1.2 and later, the 16-bit - * identifier will be used "as is" in the protocol, in the - * SignatureAndHashAlgorithm; for instance, `0x0401` stands for - * RSA PKCS#1 v1.5 signature (the `01`) with SHA-256 as hash - * function (the `04`). - * - * Take care that with TLS 1.0 and 1.1, the hash function is - * constrainted by the protocol: RSA signature must use - * MD5+SHA-1 (so use `0xFF00`), while ECDSA must use SHA-1 - * (`0xFF02`). Since TLS 1.0 and 1.1 don't include a - * SignatureAndHashAlgorithm field in their ServerKeyExchange - * messages, any value below `0xFF00` will be usable to send the - * raw ServerKeyExchange data to the `do_sign()` callback, but - * that callback must still follow the protocol requirements - * when generating the signature. - */ - unsigned algo_id; - - /** - * \brief Certificate chain to send to the client. - * - * This is an array of `br_x509_certificate` objects, each - * normally containing a DER-encoded certificate. The server - * code does not try to decode these elements. - */ - const br_x509_certificate *chain; - - /** - * \brief Certificate chain length (number of certificates). - */ - size_t chain_len; - -} br_ssl_server_choices; - -/** - * \brief Class type for a policy handler (server side). - * - * A policy handler selects the policy parameters for a connection - * (cipher suite and other algorithms, and certificate chain to send to - * the client); it also performs the server-side computations involving - * its permanent private key. - * - * The SSL server engine will invoke first `choose()`, once the - * ClientHello message has been received, then either `do_keyx()` - * `do_sign()`, depending on the cipher suite. - */ -typedef struct br_ssl_server_policy_class_ br_ssl_server_policy_class; -struct br_ssl_server_policy_class_ { - /** - * \brief Context size (in bytes). - */ - size_t context_size; - - /** - * \brief Select algorithms and certificates for this connection. - * - * This callback function shall fill the provided `choices` - * structure with the policy choices for this connection. This - * entails selecting the cipher suite, hash function for signing - * the ServerKeyExchange (applicable only to ECDHE cipher suites), - * and certificate chain to send. - * - * The callback receives a pointer to the server context that - * contains the relevant data. In particular, the functions - * `br_ssl_server_get_client_suites()`, - * `br_ssl_server_get_client_hashes()` and - * `br_ssl_server_get_client_curves()` can be used to obtain - * the cipher suites, hash functions and elliptic curves - * supported by both the client and server, respectively. The - * `br_ssl_engine_get_version()` and `br_ssl_engine_get_server_name()` - * functions yield the protocol version and requested server name - * (SNI), respectively. - * - * This function may modify its context structure (`pctx`) in - * arbitrary ways to keep track of its own choices. - * - * This function shall return 1 if appropriate policy choices - * could be made, or 0 if this connection cannot be pursued. - * - * \param pctx policy context. - * \param cc SSL server context. - * \param choices destination structure for the policy choices. - * \return 1 on success, 0 on error. - */ - int (*choose)(const br_ssl_server_policy_class **pctx, - const br_ssl_server_context *cc, - br_ssl_server_choices *choices); - - /** - * \brief Perform key exchange (server part). - * - * This callback is invoked to perform the server-side cryptographic - * operation for a key exchange that is not ECDHE. This callback - * uses the private key. - * - * **For RSA key exchange**, the provided `data` (of length `*len` - * bytes) shall be decrypted with the server's private key, and - * the 48-byte premaster secret copied back to the first 48 bytes - * of `data`. - * - * - The caller makes sure that `*len` is at least 59 bytes. - * - * - This callback MUST check that the provided length matches - * that of the key modulus; it shall report an error otherwise. - * - * - If the length matches that of the RSA key modulus, then - * processing MUST be constant-time, even if decryption fails, - * or the padding is incorrect, or the plaintext message length - * is not exactly 48 bytes. - * - * - This callback needs not check the two first bytes of the - * obtained pre-master secret (the caller will do that). - * - * - If an error is reported (0), then what the callback put - * in the first 48 bytes of `data` is unimportant (the caller - * will use random bytes instead). - * - * **For ECDH key exchange**, the provided `data` (of length `*len` - * bytes) is the elliptic curve point from the client. The - * callback shall multiply it with its private key, and store - * the resulting X coordinate in `data`, starting at offset 0, - * and set `*len` to the length of the X coordinate. - * - * - If the input array does not have the proper length for - * an encoded curve point, then an error (0) shall be reported. - * - * - If the input array has the proper length, then processing - * MUST be constant-time, even if the data is not a valid - * encoded point. - * - * - This callback MUST check that the input point is valid. - * - * Returned value is 1 on success, 0 on error. - * - * \param pctx policy context. - * \param data key exchange data from the client. - * \param len key exchange data length (in bytes). - * \return 1 on success, 0 on error. - */ - uint32_t (*do_keyx)(const br_ssl_server_policy_class **pctx, - unsigned char *data, size_t *len); - - /** - * \brief Perform a signature (for a ServerKeyExchange message). - * - * This callback function is invoked for ECDHE cipher suites. On - * input, the hash value or message to sign is in `data`, of - * size `hv_len`; the involved hash function or algorithm is - * identified by `algo_id`. The signature shall be computed and - * written back into `data`; the total size of that buffer is - * `len` bytes. - * - * This callback shall verify that the signature length does not - * exceed `len` bytes, and abstain from writing the signature if - * it does not fit. - * - * The `algo_id` value matches that which was written in the - * `choices` structures by the `choose()` callback. This will be - * one of the following: - * - * - `0xFF00 + id` for a hash function identifier `id`. In - * that case, the `data` buffer contains a hash value - * already computed over the data that is to be signed, - * of length `hv_len`. The `id` may be 0 to designate the - * special MD5+SHA-1 concatenation (old-style RSA signing). - * - * - Another value, lower than `0xFF00`. The `data` buffer - * then contains the raw, non-hashed data to be signed - * (concatenation of the client and server randoms and - * ECDH parameters). The callback is responsible to apply - * any relevant hashing as part of the signing process. - * - * Returned value is the signature length (in bytes), or 0 on error. - * - * \param pctx policy context. - * \param algo_id hash function / algorithm identifier. - * \param data input/output buffer (message/hash, then signature). - * \param hv_len hash value or message length (in bytes). - * \param len total buffer length (in bytes). - * \return signature length (in bytes) on success, or 0 on error. - */ - size_t (*do_sign)(const br_ssl_server_policy_class **pctx, - unsigned algo_id, - unsigned char *data, size_t hv_len, size_t len); -}; - -/** - * \brief A single-chain RSA policy handler. - * - * This policy context uses a single certificate chain, and a RSA - * private key. The context can be restricted to only signatures or - * only key exchange. - * - * Apart from the first field (vtable pointer), its contents are - * opaque and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - const br_ssl_server_policy_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - const br_x509_certificate *chain; - size_t chain_len; - const br_rsa_private_key *sk; - unsigned allowed_usages; - br_rsa_private irsacore; - br_rsa_pkcs1_sign irsasign; -#endif -} br_ssl_server_policy_rsa_context; - -/** - * \brief A single-chain EC policy handler. - * - * This policy context uses a single certificate chain, and an EC - * private key. The context can be restricted to only signatures or - * only key exchange. - * - * Due to how TLS is defined, this context must be made aware whether - * the server certificate was itself signed with RSA or ECDSA. The code - * does not try to decode the certificate to obtain that information. - * - * Apart from the first field (vtable pointer), its contents are - * opaque and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - const br_ssl_server_policy_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - const br_x509_certificate *chain; - size_t chain_len; - const br_ec_private_key *sk; - unsigned allowed_usages; - unsigned cert_issuer_key_type; - const br_multihash_context *mhash; - const br_ec_impl *iec; - br_ecdsa_sign iecdsa; -#endif -} br_ssl_server_policy_ec_context; - -/** - * \brief Class type for a session parameter cache. - * - * Session parameters are saved in the cache with `save()`, and - * retrieved with `load()`. The cache implementation can apply any - * storage and eviction strategy that it sees fit. The SSL server - * context that performs the request is provided, so that its - * functionalities may be used by the implementation (e.g. hash - * functions or random number generation). - */ -typedef struct br_ssl_session_cache_class_ br_ssl_session_cache_class; -struct br_ssl_session_cache_class_ { - /** - * \brief Context size (in bytes). - */ - size_t context_size; - - /** - * \brief Record a session. - * - * This callback should record the provided session parameters. - * The `params` structure is transient, so its contents shall - * be copied into the cache. The session ID has been randomly - * generated and always has length exactly 32 bytes. - * - * \param ctx session cache context. - * \param server_ctx SSL server context. - * \param params session parameters to save. - */ - void (*save)(const br_ssl_session_cache_class **ctx, - br_ssl_server_context *server_ctx, - const br_ssl_session_parameters *params); - - /** - * \brief Lookup a session in the cache. - * - * The session ID to lookup is in `params` and always has length - * exactly 32 bytes. If the session parameters are found in the - * cache, then the parameters shall be copied into the `params` - * structure. Returned value is 1 on successful lookup, 0 - * otherwise. - * - * \param ctx session cache context. - * \param server_ctx SSL server context. - * \param params destination for session parameters. - * \return 1 if found, 0 otherwise. - */ - int (*load)(const br_ssl_session_cache_class **ctx, - br_ssl_server_context *server_ctx, - br_ssl_session_parameters *params); -}; - -/** - * \brief Context for a basic cache system. - * - * The system stores session parameters in a buffer provided at - * initialisation time. Each entry uses exactly 100 bytes, and - * buffer sizes up to 4294967295 bytes are supported. - * - * Entries are evicted with a LRU (Least Recently Used) policy. A - * search tree is maintained to keep lookups fast even with large - * caches. - * - * Apart from the first field (vtable pointer), the structure - * contents are opaque and shall not be accessed directly. - */ -typedef struct { - /** \brief Pointer to vtable. */ - const br_ssl_session_cache_class *vtable; -#ifndef BR_DOXYGEN_IGNORE - unsigned char *store; - size_t store_len, store_ptr; - unsigned char index_key[32]; - const br_hash_class *hash; - int init_done; - uint32_t head, tail, root; -#endif -} br_ssl_session_cache_lru; - -/** - * \brief Initialise a LRU session cache with the provided storage space. - * - * The provided storage space must remain valid as long as the cache - * is used. Arbitrary lengths are supported, up to 4294967295 bytes; - * each entry uses up exactly 100 bytes. - * - * \param cc session cache context. - * \param store storage space for cached entries. - * \param store_len storage space length (in bytes). - */ -void br_ssl_session_cache_lru_init(br_ssl_session_cache_lru *cc, - unsigned char *store, size_t store_len); - -/** - * \brief Forget an entry in an LRU session cache. - * - * The session cache context must have been initialised. The entry - * with the provided session ID (of exactly 32 bytes) is looked for - * in the cache; if located, it is disabled. - * - * \param cc session cache context. - * \param id session ID to forget. - */ -void br_ssl_session_cache_lru_forget( - br_ssl_session_cache_lru *cc, const unsigned char *id); - -/** - * \brief Context structure for a SSL server. - * - * The first field (called `eng`) is the SSL engine; all functions that - * work on a `br_ssl_engine_context` structure shall take as parameter - * a pointer to that field. The other structure fields are opaque and - * must not be accessed directly. - */ -struct br_ssl_server_context_ { - /** - * \brief The encapsulated engine context. - */ - br_ssl_engine_context eng; - -#ifndef BR_DOXYGEN_IGNORE - /* - * Maximum version from the client. - */ - uint16_t client_max_version; - - /* - * Session cache. - */ - const br_ssl_session_cache_class **cache_vtable; - - /* - * Translated cipher suites supported by the client. The list - * is trimmed to include only the cipher suites that the - * server also supports; they are in the same order as in the - * client message. - */ - br_suite_translated client_suites[BR_MAX_CIPHER_SUITES]; - unsigned char client_suites_num; - - /* - * Hash functions supported by the client, with ECDSA and RSA - * (bit mask). For hash function with id 'x', set bit index is - * x for RSA, x+8 for ECDSA. For newer algorithms, with ID - * 0x08**, bit 16+k is set for algorithm 0x0800+k. - */ - uint32_t hashes; - - /* - * Curves supported by the client (bit mask, for named curves). - */ - uint32_t curves; - - /* - * Context for chain handler. - */ - const br_ssl_server_policy_class **policy_vtable; - uint16_t sign_hash_id; - - /* - * For the core handlers, thus avoiding (in most cases) the - * need for an externally provided policy context. - */ - union { - const br_ssl_server_policy_class *vtable; - br_ssl_server_policy_rsa_context single_rsa; - br_ssl_server_policy_ec_context single_ec; - } chain_handler; - - /* - * Buffer for the ECDHE private key. - */ - unsigned char ecdhe_key[70]; - size_t ecdhe_key_len; - - /* - * Trust anchor names for client authentication. "ta_names" and - * "tas" cannot be both non-NULL. - */ - const br_x500_name *ta_names; - const br_x509_trust_anchor *tas; - size_t num_tas; - size_t cur_dn_index; - const unsigned char *cur_dn; - size_t cur_dn_len; - - /* - * Buffer for the hash value computed over all handshake messages - * prior to CertificateVerify, and identifier for the hash function. - */ - unsigned char hash_CV[64]; - size_t hash_CV_len; - int hash_CV_id; - - /* - * Server-specific implementations. - * (none for now) - */ -#endif -}; - -/* - * Each br_ssl_server_init_xxx() function sets the list of supported - * cipher suites and used implementations, as specified by the profile - * name 'xxx'. Defined profile names are: - * - * full_rsa all supported algorithm, server key type is RSA - * full_ec all supported algorithm, server key type is EC - * TODO: add other profiles - * - * Naming scheme for "minimal" profiles: min123 - * - * -- character 1: key exchange - * r = RSA - * e = ECDHE_RSA - * f = ECDHE_ECDSA - * u = ECDH_RSA - * v = ECDH_ECDSA - * -- character 2: version / PRF - * 0 = TLS 1.0 / 1.1 with MD5+SHA-1 - * 2 = TLS 1.2 with SHA-256 - * 3 = TLS 1.2 with SHA-384 - * -- character 3: encryption - * a = AES/CBC - * d = 3DES/CBC - * g = AES/GCM - * c = ChaCha20+Poly1305 - */ - -/** - * \brief SSL server profile: full_rsa. - * - * This function initialises the provided SSL server context with - * all supported algorithms and cipher suites that rely on a RSA - * key pair. - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk RSA private key. - */ -void br_ssl_server_init_full_rsa(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk); - -/** - * \brief SSL server profile: full_ec. - * - * This function initialises the provided SSL server context with - * all supported algorithms and cipher suites that rely on an EC - * key pair. - * - * The key type of the CA that issued the server's certificate must - * be provided, since it matters for ECDH cipher suites (ECDH_RSA - * suites require a RSA-powered CA). The key type is either - * `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len chain length (number of certificates). - * \param cert_issuer_key_type certificate issuer's key type. - * \param sk EC private key. - */ -void br_ssl_server_init_full_ec(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - unsigned cert_issuer_key_type, const br_ec_private_key *sk); - -/** - * \brief SSL server profile: minr2g. - * - * This profile uses only TLS_RSA_WITH_AES_128_GCM_SHA256. Server key is - * RSA, and RSA key exchange is used (not forward secure, but uses little - * CPU in the client). - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk RSA private key. - */ -void br_ssl_server_init_minr2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk); - -/** - * \brief SSL server profile: mine2g. - * - * This profile uses only TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256. Server key - * is RSA, and ECDHE key exchange is used. This suite provides forward - * security, with a higher CPU expense on the client, and a somewhat - * larger code footprint (compared to "minr2g"). - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk RSA private key. - */ -void br_ssl_server_init_mine2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk); - -/** - * \brief SSL server profile: minf2g. - * - * This profile uses only TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256. - * Server key is EC, and ECDHE key exchange is used. This suite provides - * forward security, with a higher CPU expense on the client and server - * (by a factor of about 3 to 4), and a somewhat larger code footprint - * (compared to "minu2g" and "minv2g"). - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk EC private key. - */ -void br_ssl_server_init_minf2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk); - -/** - * \brief SSL server profile: minu2g. - * - * This profile uses only TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256. - * Server key is EC, and ECDH key exchange is used; the issuing CA used - * a RSA key. - * - * The "minu2g" and "minv2g" profiles do not provide forward secrecy, - * but are the lightest on the server (for CPU usage), and are rather - * inexpensive on the client as well. - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk EC private key. - */ -void br_ssl_server_init_minu2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk); - -/** - * \brief SSL server profile: minv2g. - * - * This profile uses only TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256. - * Server key is EC, and ECDH key exchange is used; the issuing CA used - * an EC key. - * - * The "minu2g" and "minv2g" profiles do not provide forward secrecy, - * but are the lightest on the server (for CPU usage), and are rather - * inexpensive on the client as well. - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk EC private key. - */ -void br_ssl_server_init_minv2g(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk); - -/** - * \brief SSL server profile: mine2c. - * - * This profile uses only TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256. - * Server key is RSA, and ECDHE key exchange is used. This suite - * provides forward security. - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk RSA private key. - */ -void br_ssl_server_init_mine2c(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk); - -/** - * \brief SSL server profile: minf2c. - * - * This profile uses only TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256. - * Server key is EC, and ECDHE key exchange is used. This suite provides - * forward security. - * - * \param cc server context to initialise. - * \param chain server certificate chain. - * \param chain_len certificate chain length (number of certificate). - * \param sk EC private key. - */ -void br_ssl_server_init_minf2c(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk); - -/** - * \brief Get the supported client suites. - * - * This function shall be called only after the ClientHello has been - * processed, typically from the policy engine. The returned array - * contains the cipher suites that are supported by both the client - * and the server; these suites are in client preference order, unless - * the `BR_OPT_ENFORCE_SERVER_PREFERENCES` flag was set, in which case - * they are in server preference order. - * - * The suites are _translated_, which means that each suite is given - * as two 16-bit integers: the standard suite identifier, and its - * translated version, broken down into its individual components, - * as explained with the `br_suite_translated` type. - * - * The returned array is allocated in the context and will be rewritten - * by each handshake. - * - * \param cc server context. - * \param num receives the array size (number of suites). - * \return the translated common cipher suites, in preference order. - */ -static inline const br_suite_translated * -br_ssl_server_get_client_suites(const br_ssl_server_context *cc, size_t *num) -{ - *num = cc->client_suites_num; - return cc->client_suites; -} - -/** - * \brief Get the hash functions and signature algorithms supported by - * the client. - * - * This value is a bit field: - * - * - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`, - * then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1, - * or 2 to 6 for the SHA family). - * - * - If ECDSA is supported with hash function of ID `x`, then bit `8+x` - * is set. - * - * - Newer algorithms are symbolic 16-bit identifiers that do not - * represent signature algorithm and hash function separately. If - * the TLS-level identifier is `0x0800+x` for a `x` in the 0..15 - * range, then bit `16+x` is set. - * - * "New algorithms" are currently defined only in draft documents, so - * this support is subject to possible change. Right now (early 2017), - * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA - * on Curve448) to bit 24. If the identifiers on the wire change in - * future document, then the decoding mechanism in BearSSL will be - * amended to keep mapping ed25519 and ed448 on bits 23 and 24, - * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not - * guaranteed yet. - * - * \param cc server context. - * \return the client-supported hash functions and signature algorithms. - */ -static inline uint32_t -br_ssl_server_get_client_hashes(const br_ssl_server_context *cc) -{ - return cc->hashes; -} - -/** - * \brief Get the elliptic curves supported by the client. - * - * This is a bit field (bit x is set if curve of ID x is supported). - * - * \param cc server context. - * \return the client-supported elliptic curves. - */ -static inline uint32_t -br_ssl_server_get_client_curves(const br_ssl_server_context *cc) -{ - return cc->curves; -} - -/** - * \brief Clear the complete contents of a SSL server context. - * - * Everything is cleared, including the reference to the configured buffer, - * implementations, cipher suites and state. This is a preparatory step - * to assembling a custom profile. - * - * \param cc server context to clear. - */ -void br_ssl_server_zero(br_ssl_server_context *cc); - -/** - * \brief Set an externally provided policy context. - * - * The policy context's methods are invoked to decide the cipher suite - * and certificate chain, and to perform operations involving the server's - * private key. - * - * \param cc server context. - * \param pctx policy context (pointer to its vtable field). - */ -static inline void -br_ssl_server_set_policy(br_ssl_server_context *cc, - const br_ssl_server_policy_class **pctx) -{ - cc->policy_vtable = pctx; -} - -/** - * \brief Set the server certificate chain and key (single RSA case). - * - * This function uses a policy context included in the server context. - * It configures use of a single server certificate chain with a RSA - * private key. The `allowed_usages` is a combination of usages, namely - * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`; this enables or disables - * the corresponding cipher suites (i.e. `TLS_RSA_*` use the RSA key for - * key exchange, while `TLS_ECDHE_RSA_*` use the RSA key for signatures). - * - * \param cc server context. - * \param chain server certificate chain to send to the client. - * \param chain_len chain length (number of certificates). - * \param sk server private key (RSA). - * \param allowed_usages allowed private key usages. - * \param irsacore RSA core implementation. - * \param irsasign RSA signature implementation (PKCS#1 v1.5). - */ -void br_ssl_server_set_single_rsa(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk, unsigned allowed_usages, - br_rsa_private irsacore, br_rsa_pkcs1_sign irsasign); - -/** - * \brief Set the server certificate chain and key (single EC case). - * - * This function uses a policy context included in the server context. - * It configures use of a single server certificate chain with an EC - * private key. The `allowed_usages` is a combination of usages, namely - * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`; this enables or disables - * the corresponding cipher suites (i.e. `TLS_ECDH_*` use the EC key for - * key exchange, while `TLS_ECDHE_ECDSA_*` use the EC key for signatures). - * - * In order to support `TLS_ECDH_*` cipher suites (non-ephemeral ECDH), - * the algorithm type of the key used by the issuing CA to sign the - * server's certificate must be provided, as `cert_issuer_key_type` - * parameter (this value is either `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`). - * - * \param cc server context. - * \param chain server certificate chain to send. - * \param chain_len chain length (number of certificates). - * \param sk server private key (EC). - * \param allowed_usages allowed private key usages. - * \param cert_issuer_key_type issuing CA's key type. - * \param iec EC core implementation. - * \param iecdsa ECDSA signature implementation ("asn1" format). - */ -void br_ssl_server_set_single_ec(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk, unsigned allowed_usages, - unsigned cert_issuer_key_type, - const br_ec_impl *iec, br_ecdsa_sign iecdsa); - -/** - * \brief Activate client certificate authentication. - * - * The trust anchor encoded X.500 names (DN) to send to the client are - * provided. A client certificate will be requested and validated through - * the X.509 validator configured in the SSL engine. If `num` is 0, then - * client certificate authentication is disabled. - * - * If the client does not send a certificate, or on validation failure, - * the handshake aborts. Unauthenticated clients can be tolerated by - * setting the `BR_OPT_TOLERATE_NO_CLIENT_AUTH` flag. - * - * The provided array is linked in, not copied, so that pointer must - * remain valid as long as anchor names may be used. - * - * \param cc server context. - * \param ta_names encoded trust anchor names. - * \param num number of encoded trust anchor names. - */ -static inline void -br_ssl_server_set_trust_anchor_names(br_ssl_server_context *cc, - const br_x500_name *ta_names, size_t num) -{ - cc->ta_names = ta_names; - cc->tas = NULL; - cc->num_tas = num; -} - -/** - * \brief Activate client certificate authentication. - * - * This is a variant for `br_ssl_server_set_trust_anchor_names()`: the - * trust anchor names are provided not as an array of stand-alone names - * (`br_x500_name` structures), but as an array of trust anchors - * (`br_x509_trust_anchor` structures). The server engine itself will - * only use the `dn` field of each trust anchor. This is meant to allow - * defining a single array of trust anchors, to be used here and in the - * X.509 validation engine itself. - * - * The provided array is linked in, not copied, so that pointer must - * remain valid as long as anchor names may be used. - * - * \param cc server context. - * \param tas trust anchors (only names are used). - * \param num number of trust anchors. - */ -static inline void -br_ssl_server_set_trust_anchor_names_alt(br_ssl_server_context *cc, - const br_x509_trust_anchor *tas, size_t num) -{ - cc->ta_names = NULL; - cc->tas = tas; - cc->num_tas = num; -} - -/** - * \brief Configure the cache for session parameters. - * - * The cache context is provided as a pointer to its first field (vtable - * pointer). - * - * \param cc server context. - * \param vtable session cache context. - */ -static inline void -br_ssl_server_set_cache(br_ssl_server_context *cc, - const br_ssl_session_cache_class **vtable) -{ - cc->cache_vtable = vtable; -} - -/** - * \brief Prepare or reset a server context for handling an incoming client. - * - * \param cc server context. - * \return 1 on success, 0 on error. - */ -int br_ssl_server_reset(br_ssl_server_context *cc); - /* ===================================================================== */ /* diff --git a/third_party/bearssl/inc/bearssl_x509.h b/third_party/bearssl/inc/bearssl_x509.h index 7668e1de5..4791d9cce 100644 --- a/third_party/bearssl/inc/bearssl_x509.h +++ b/third_party/bearssl/inc/bearssl_x509.h @@ -989,186 +989,6 @@ br_x509_minimal_set_name_elements(br_x509_minimal_context *ctx, ctx->num_name_elts = num_elts; } -/** - * \brief X.509 decoder context. - * - * This structure is _not_ for X.509 validation, but for extracting - * names and public keys from encoded certificates. Intended usage is - * to use (self-signed) certificates as trust anchors. - * - * Contents are opaque and shall not be accessed directly. - */ -typedef struct { - -#ifndef BR_DOXYGEN_IGNORE - /* Structure for returning the public key. */ - br_x509_pkey pkey; - - /* CPU for the T0 virtual machine. */ - struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; - } cpu; - uint32_t dp_stack[32]; - uint32_t rp_stack[32]; - int err; - - /* The pad serves as destination for various operations. */ - unsigned char pad[256]; - - /* Flag set when decoding succeeds. */ - unsigned char decoded; - - /* Validity dates. */ - uint32_t notbefore_days, notbefore_seconds; - uint32_t notafter_days, notafter_seconds; - - /* The "CA" flag. This is set to true if the certificate contains - a Basic Constraints extension that asserts CA status. */ - unsigned char isCA; - - /* DN processing: the subject DN is extracted and pushed to the - provided callback. */ - unsigned char copy_dn; - void *append_dn_ctx; - void (*append_dn)(void *ctx, const void *buf, size_t len); - - /* Certificate data chunk. */ - const unsigned char *hbuf; - size_t hlen; - - /* Buffer for decoded public key. */ - unsigned char pkey_data[BR_X509_BUFSIZE_KEY]; - - /* Type of key and hash function used in the certificate signature. */ - unsigned char signer_key_type; - unsigned char signer_hash_id; -#endif - -} br_x509_decoder_context; - -/** - * \brief Initialise an X.509 decoder context for processing a new - * certificate. - * - * The `append_dn()` callback (with opaque context `append_dn_ctx`) - * will be invoked to receive, chunk by chunk, the certificate's - * subject DN. If `append_dn` is `0` then the subject DN will be - * ignored. - * - * \param ctx X.509 decoder context to initialise. - * \param append_dn DN receiver callback (or `0`). - * \param append_dn_ctx context for the DN receiver callback. - */ -void br_x509_decoder_init(br_x509_decoder_context *ctx, - void (*append_dn)(void *ctx, const void *buf, size_t len), - void *append_dn_ctx); - -/** - * \brief Push some certificate bytes into a decoder context. - * - * If `len` is non-zero, then that many bytes are pushed, from address - * `data`, into the provided decoder context. - * - * \param ctx X.509 decoder context. - * \param data certificate data chunk. - * \param len certificate data chunk length (in bytes). - */ -void br_x509_decoder_push(br_x509_decoder_context *ctx, - const void *data, size_t len); - -/** - * \brief Obtain the decoded public key. - * - * Returned value is a pointer to a structure internal to the decoder - * context; releasing or reusing the decoder context invalidates that - * structure. - * - * If decoding was not finished, or failed, then `NULL` is returned. - * - * \param ctx X.509 decoder context. - * \return the public key, or `NULL` on unfinished/error. - */ -static inline br_x509_pkey * -br_x509_decoder_get_pkey(br_x509_decoder_context *ctx) -{ - if (ctx->decoded && ctx->err == 0) { - return &ctx->pkey; - } else { - return NULL; - } -} - -/** - * \brief Get decoder error status. - * - * If no error was reported yet but the certificate decoding is not - * finished, then the error code is `BR_ERR_X509_TRUNCATED`. If decoding - * was successful, then 0 is returned. - * - * \param ctx X.509 decoder context. - * \return 0 on successful decoding, or a non-zero error code. - */ -static inline int -br_x509_decoder_last_error(br_x509_decoder_context *ctx) -{ - if (ctx->err != 0) { - return ctx->err; - } - if (!ctx->decoded) { - return BR_ERR_X509_TRUNCATED; - } - return 0; -} - -/** - * \brief Get the "isCA" flag from an X.509 decoder context. - * - * This flag is set if the decoded certificate claims to be a CA through - * a Basic Constraints extension. This flag should not be read before - * decoding completed successfully. - * - * \param ctx X.509 decoder context. - * \return the "isCA" flag. - */ -static inline int -br_x509_decoder_isCA(br_x509_decoder_context *ctx) -{ - return ctx->isCA; -} - -/** - * \brief Get the issuing CA key type (type of algorithm used to sign the - * decoded certificate). - * - * This is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. The value 0 is returned - * if the signature type was not recognised. - * - * \param ctx X.509 decoder context. - * \return the issuing CA key type. - */ -static inline int -br_x509_decoder_get_signer_key_type(br_x509_decoder_context *ctx) -{ - return ctx->signer_key_type; -} - -/** - * \brief Get the identifier for the hash function used to sign the decoded - * certificate. - * - * This is 0 if the hash function was not recognised. - * - * \param ctx X.509 decoder context. - * \return the signature hash function identifier. - */ -static inline int -br_x509_decoder_get_signer_hash_id(br_x509_decoder_context *ctx) -{ - return ctx->signer_hash_id; -} - /** * \brief Type for an X.509 certificate (DER-encoded). */ @@ -1179,294 +999,6 @@ typedef struct { size_t data_len; } br_x509_certificate; -/** - * \brief Private key decoder context. - * - * The private key decoder recognises RSA and EC private keys, either in - * their raw, DER-encoded format, or wrapped in an unencrypted PKCS#8 - * archive (again DER-encoded). - * - * Structure contents are opaque and shall not be accessed directly. - */ -typedef struct { -#ifndef BR_DOXYGEN_IGNORE - /* Structure for returning the private key. */ - union { - br_rsa_private_key rsa; - br_ec_private_key ec; - } key; - - /* CPU for the T0 virtual machine. */ - struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; - } cpu; - uint32_t dp_stack[32]; - uint32_t rp_stack[32]; - int err; - - /* Private key data chunk. */ - const unsigned char *hbuf; - size_t hlen; - - /* The pad serves as destination for various operations. */ - unsigned char pad[256]; - - /* Decoded key type; 0 until decoding is complete. */ - unsigned char key_type; - - /* Buffer for the private key elements. It shall be large enough - to accommodate all elements for a RSA-4096 private key (roughly - five 2048-bit integers, possibly a bit more). */ - unsigned char key_data[3 * BR_X509_BUFSIZE_SIG]; -#endif -} br_skey_decoder_context; - -/** - * \brief Initialise a private key decoder context. - * - * \param ctx key decoder context to initialise. - */ -void br_skey_decoder_init(br_skey_decoder_context *ctx); - -/** - * \brief Push some data bytes into a private key decoder context. - * - * If `len` is non-zero, then that many data bytes, starting at address - * `data`, are pushed into the decoder. - * - * \param ctx key decoder context. - * \param data private key data chunk. - * \param len private key data chunk length (in bytes). - */ -void br_skey_decoder_push(br_skey_decoder_context *ctx, - const void *data, size_t len); - -/** - * \brief Get the decoding status for a private key. - * - * Decoding status is 0 on success, or a non-zero error code. If the - * decoding is unfinished when this function is called, then the - * status code `BR_ERR_X509_TRUNCATED` is returned. - * - * \param ctx key decoder context. - * \return 0 on successful decoding, or a non-zero error code. - */ -static inline int -br_skey_decoder_last_error(const br_skey_decoder_context *ctx) -{ - if (ctx->err != 0) { - return ctx->err; - } - if (ctx->key_type == 0) { - return BR_ERR_X509_TRUNCATED; - } - return 0; -} - -/** - * \brief Get the decoded private key type. - * - * Private key type is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. If decoding is - * not finished or failed, then 0 is returned. - * - * \param ctx key decoder context. - * \return decoded private key type, or 0. - */ -static inline int -br_skey_decoder_key_type(const br_skey_decoder_context *ctx) -{ - if (ctx->err == 0) { - return ctx->key_type; - } else { - return 0; - } -} - -/** - * \brief Get the decoded RSA private key. - * - * This function returns `NULL` if the decoding failed, or is not - * finished, or the key is not RSA. The returned pointer references - * structures within the context that can become invalid if the context - * is reused or released. - * - * \param ctx key decoder context. - * \return decoded RSA private key, or `NULL`. - */ -static inline const br_rsa_private_key * -br_skey_decoder_get_rsa(const br_skey_decoder_context *ctx) -{ - if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_RSA) { - return &ctx->key.rsa; - } else { - return NULL; - } -} - -/** - * \brief Get the decoded EC private key. - * - * This function returns `NULL` if the decoding failed, or is not - * finished, or the key is not EC. The returned pointer references - * structures within the context that can become invalid if the context - * is reused or released. - * - * \param ctx key decoder context. - * \return decoded EC private key, or `NULL`. - */ -static inline const br_ec_private_key * -br_skey_decoder_get_ec(const br_skey_decoder_context *ctx) -{ - if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_EC) { - return &ctx->key.ec; - } else { - return NULL; - } -} - -/** - * \brief Encode an RSA private key (raw DER format). - * - * This function encodes the provided key into the "raw" format specified - * in PKCS#1 (RFC 8017, Appendix C, type `RSAPrivateKey`), with DER - * encoding rules. - * - * The key elements are: - * - * - `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`) - * - * - `pk`: the public key (`n` and `e`) - * - * - `d` (size: `dlen` bytes): the private exponent - * - * The public key elements, and the private exponent `d`, can be - * recomputed from the private key (see `br_rsa_compute_modulus()`, - * `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`). - * - * If `dest` is not `NULL`, then the encoded key is written at that - * address, and the encoded length (in bytes) is returned. If `dest` is - * `NULL`, then nothing is written, but the encoded length is still - * computed and returned. - * - * \param dest the destination buffer (or `NULL`). - * \param sk the RSA private key. - * \param pk the RSA public key. - * \param d the RSA private exponent. - * \param dlen the RSA private exponent length (in bytes). - * \return the encoded key length (in bytes). - */ -size_t br_encode_rsa_raw_der(void *dest, const br_rsa_private_key *sk, - const br_rsa_public_key *pk, const void *d, size_t dlen); - -/** - * \brief Encode an RSA private key (PKCS#8 DER format). - * - * This function encodes the provided key into the PKCS#8 format - * (RFC 5958, type `OneAsymmetricKey`). It wraps around the "raw DER" - * format for the RSA key, as implemented by `br_encode_rsa_raw_der()`. - * - * The key elements are: - * - * - `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`) - * - * - `pk`: the public key (`n` and `e`) - * - * - `d` (size: `dlen` bytes): the private exponent - * - * The public key elements, and the private exponent `d`, can be - * recomputed from the private key (see `br_rsa_compute_modulus()`, - * `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`). - * - * If `dest` is not `NULL`, then the encoded key is written at that - * address, and the encoded length (in bytes) is returned. If `dest` is - * `NULL`, then nothing is written, but the encoded length is still - * computed and returned. - * - * \param dest the destination buffer (or `NULL`). - * \param sk the RSA private key. - * \param pk the RSA public key. - * \param d the RSA private exponent. - * \param dlen the RSA private exponent length (in bytes). - * \return the encoded key length (in bytes). - */ -size_t br_encode_rsa_pkcs8_der(void *dest, const br_rsa_private_key *sk, - const br_rsa_public_key *pk, const void *d, size_t dlen); - -/** - * \brief Encode an EC private key (raw DER format). - * - * This function encodes the provided key into the "raw" format specified - * in RFC 5915 (type `ECPrivateKey`), with DER encoding rules. - * - * The private key is provided in `sk`, the public key being `pk`. If - * `pk` is `NULL`, then the encoded key will not include the public key - * in its `publicKey` field (which is nominally optional). - * - * If `dest` is not `NULL`, then the encoded key is written at that - * address, and the encoded length (in bytes) is returned. If `dest` is - * `NULL`, then nothing is written, but the encoded length is still - * computed and returned. - * - * If the key cannot be encoded (e.g. because there is no known OBJECT - * IDENTIFIER for the used curve), then 0 is returned. - * - * \param dest the destination buffer (or `NULL`). - * \param sk the EC private key. - * \param pk the EC public key (or `NULL`). - * \return the encoded key length (in bytes), or 0. - */ -size_t br_encode_ec_raw_der(void *dest, - const br_ec_private_key *sk, const br_ec_public_key *pk); - -/** - * \brief Encode an EC private key (PKCS#8 DER format). - * - * This function encodes the provided key into the PKCS#8 format - * (RFC 5958, type `OneAsymmetricKey`). The curve is identified - * by an OID provided as parameters to the `privateKeyAlgorithm` - * field. The private key value (contents of the `privateKey` field) - * contains the DER encoding of the `ECPrivateKey` type defined in - * RFC 5915, without the `parameters` field (since they would be - * redundant with the information in `privateKeyAlgorithm`). - * - * The private key is provided in `sk`, the public key being `pk`. If - * `pk` is not `NULL`, then the encoded public key is included in the - * `publicKey` field of the private key value (but not in the `publicKey` - * field of the PKCS#8 `OneAsymmetricKey` wrapper). - * - * If `dest` is not `NULL`, then the encoded key is written at that - * address, and the encoded length (in bytes) is returned. If `dest` is - * `NULL`, then nothing is written, but the encoded length is still - * computed and returned. - * - * If the key cannot be encoded (e.g. because there is no known OBJECT - * IDENTIFIER for the used curve), then 0 is returned. - * - * \param dest the destination buffer (or `NULL`). - * \param sk the EC private key. - * \param pk the EC public key (or `NULL`). - * \return the encoded key length (in bytes), or 0. - */ -size_t br_encode_ec_pkcs8_der(void *dest, - const br_ec_private_key *sk, const br_ec_public_key *pk); - -/** - * \brief PEM banner for RSA private key (raw). - */ -#define BR_ENCODE_PEM_RSA_RAW "RSA PRIVATE KEY" - -/** - * \brief PEM banner for EC private key (raw). - */ -#define BR_ENCODE_PEM_EC_RAW "EC PRIVATE KEY" - -/** - * \brief PEM banner for an RSA or EC private key in PKCS#8 format. - */ -#define BR_ENCODE_PEM_PKCS8 "PRIVATE KEY" - #ifdef __cplusplus } #endif diff --git a/third_party/bearssl/src/config.h b/third_party/bearssl/src/config.h index d5d27705d..ff6fabc40 100644 --- a/third_party/bearssl/src/config.h +++ b/third_party/bearssl/src/config.h @@ -55,16 +55,6 @@ #define BR_64 1 */ -/* - * When BR_LOMUL is enabled, then multiplications of 32-bit values whose - * result are truncated to the low 32 bits are assumed to be - * substantially more efficient than 32-bit multiplications that yield - * 64-bit results. This is typically the case on low-end ARM Cortex M - * systems (M0, M0+, M1, and arguably M3 and M4 as well). - * -#define BR_LOMUL 1 - */ - /* * When BR_SLOW_MUL is enabled, multiplications are assumed to be * substantially slow with regards to other integer operations, thus diff --git a/third_party/bearssl/src/des_ct.c b/third_party/bearssl/src/des_ct.c deleted file mode 100644 index 581c0ab29..000000000 --- a/third_party/bearssl/src/des_ct.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * During key schedule, we need to apply bit extraction PC-2 then permute - * things into our bitslice representation. PC-2 extracts 48 bits out - * of two 28-bit words (kl and kr), and we store these bits into two - * 32-bit words sk0 and sk1. - * - * -- bit 16+x of sk0 comes from bit QL0[x] of kl - * -- bit x of sk0 comes from bit QR0[x] of kr - * -- bit 16+x of sk1 comes from bit QL1[x] of kl - * -- bit x of sk1 comes from bit QR1[x] of kr - */ - -static const unsigned char QL0[] = { - 17, 4, 27, 23, 13, 22, 7, 18, - 16, 24, 2, 20, 1, 8, 15, 26 -}; - -static const unsigned char QR0[] = { - 25, 19, 9, 1, 5, 11, 23, 8, - 17, 0, 22, 3, 6, 20, 27, 24 -}; - -static const unsigned char QL1[] = { - 28, 28, 14, 11, 28, 28, 25, 0, - 28, 28, 5, 9, 28, 28, 12, 21 -}; - -static const unsigned char QR1[] = { - 28, 28, 15, 4, 28, 28, 26, 16, - 28, 28, 12, 7, 28, 28, 10, 14 -}; - -/* - * 32-bit rotation. The C compiler is supposed to recognize it as a - * rotation and use the local architecture rotation opcode (if available). - */ -static inline uint32_t -rotl(uint32_t x, int n) -{ - return (x << n) | (x >> (32 - n)); -} - -/* - * Compute key schedule for 8 key bytes (produces 32 subkey words). - */ -static void -keysched_unit(uint32_t *skey, const void *key) -{ - int i; - - br_des_keysched_unit(skey, key); - - /* - * Apply PC-2 + bitslicing. - */ - for (i = 0; i < 16; i ++) { - uint32_t kl, kr, sk0, sk1; - int j; - - kl = skey[(i << 1) + 0]; - kr = skey[(i << 1) + 1]; - sk0 = 0; - sk1 = 0; - for (j = 0; j < 16; j ++) { - sk0 <<= 1; - sk1 <<= 1; - sk0 |= ((kl >> QL0[j]) & (uint32_t)1) << 16; - sk0 |= (kr >> QR0[j]) & (uint32_t)1; - sk1 |= ((kl >> QL1[j]) & (uint32_t)1) << 16; - sk1 |= (kr >> QR1[j]) & (uint32_t)1; - } - - skey[(i << 1) + 0] = sk0; - skey[(i << 1) + 1] = sk1; - } - -#if 0 - /* - * Speed-optimized version for PC-2 + bitslicing. - * (Unused. Kept for reference only.) - */ - sk0 = kl & (uint32_t)0x00100000; - sk0 |= (kl & (uint32_t)0x08008000) << 2; - sk0 |= (kl & (uint32_t)0x00400000) << 4; - sk0 |= (kl & (uint32_t)0x00800000) << 5; - sk0 |= (kl & (uint32_t)0x00040000) << 6; - sk0 |= (kl & (uint32_t)0x00010000) << 7; - sk0 |= (kl & (uint32_t)0x00000100) << 10; - sk0 |= (kl & (uint32_t)0x00022000) << 14; - sk0 |= (kl & (uint32_t)0x00000082) << 18; - sk0 |= (kl & (uint32_t)0x00000004) << 19; - sk0 |= (kl & (uint32_t)0x04000000) >> 10; - sk0 |= (kl & (uint32_t)0x00000010) << 26; - sk0 |= (kl & (uint32_t)0x01000000) >> 2; - - sk0 |= kr & (uint32_t)0x00000100; - sk0 |= (kr & (uint32_t)0x00000008) << 1; - sk0 |= (kr & (uint32_t)0x00000200) << 4; - sk0 |= rotl(kr & (uint32_t)0x08000021, 6); - sk0 |= (kr & (uint32_t)0x01000000) >> 24; - sk0 |= (kr & (uint32_t)0x00000002) << 11; - sk0 |= (kr & (uint32_t)0x00100000) >> 18; - sk0 |= (kr & (uint32_t)0x00400000) >> 17; - sk0 |= (kr & (uint32_t)0x00800000) >> 14; - sk0 |= (kr & (uint32_t)0x02020000) >> 10; - sk0 |= (kr & (uint32_t)0x00080000) >> 5; - sk0 |= (kr & (uint32_t)0x00000040) >> 3; - sk0 |= (kr & (uint32_t)0x00000800) >> 1; - - sk1 = kl & (uint32_t)0x02000000; - sk1 |= (kl & (uint32_t)0x00001000) << 5; - sk1 |= (kl & (uint32_t)0x00000200) << 11; - sk1 |= (kl & (uint32_t)0x00004000) << 15; - sk1 |= (kl & (uint32_t)0x00000020) << 16; - sk1 |= (kl & (uint32_t)0x00000800) << 17; - sk1 |= (kl & (uint32_t)0x00000001) << 24; - sk1 |= (kl & (uint32_t)0x00200000) >> 5; - - sk1 |= (kr & (uint32_t)0x00000010) << 8; - sk1 |= (kr & (uint32_t)0x04000000) >> 17; - sk1 |= (kr & (uint32_t)0x00004000) >> 14; - sk1 |= (kr & (uint32_t)0x00000400) >> 9; - sk1 |= (kr & (uint32_t)0x00010000) >> 8; - sk1 |= (kr & (uint32_t)0x00001000) >> 7; - sk1 |= (kr & (uint32_t)0x00000080) >> 3; - sk1 |= (kr & (uint32_t)0x00008000) >> 2; -#endif -} - -/* see inner.h */ -unsigned -br_des_ct_keysched(uint32_t *skey, const void *key, size_t key_len) -{ - switch (key_len) { - case 8: - keysched_unit(skey, key); - return 1; - case 16: - keysched_unit(skey, key); - keysched_unit(skey + 32, (const unsigned char *)key + 8); - br_des_rev_skey(skey + 32); - memcpy(skey + 64, skey, 32 * sizeof *skey); - return 3; - default: - keysched_unit(skey, key); - keysched_unit(skey + 32, (const unsigned char *)key + 8); - br_des_rev_skey(skey + 32); - keysched_unit(skey + 64, (const unsigned char *)key + 16); - return 3; - } -} - -/* - * DES confusion function. This function performs expansion E (32 to - * 48 bits), XOR with subkey, S-boxes, and permutation P. - */ -static inline uint32_t -Fconf(uint32_t r0, const uint32_t *sk) -{ - /* - * Each 6->4 S-box is virtually turned into four 6->1 boxes; we - * thus end up with 32 boxes that we call "T-boxes" here. We will - * evaluate them with bitslice code. - * - * Each T-box is a circuit of multiplexers (sort of) and thus - * takes 70 inputs: the 6 actual T-box inputs, and 64 constants - * that describe the T-box output for all combinations of the - * 6 inputs. With this model, all T-boxes are identical (with - * distinct inputs) and thus can be executed in parallel with - * bitslice code. - * - * T-boxes are numbered from 0 to 31, in least-to-most - * significant order. Thus, S-box S1 corresponds to T-boxes 31, - * 30, 29 and 28, in that order. T-box 'n' is computed with the - * bits at rank 'n' in the 32-bit words. - * - * Words x0 to x5 contain the T-box inputs 0 to 5. - */ - uint32_t x0, x1, x2, x3, x4, x5, z0; - uint32_t y0, y1, y2, y3, y4, y5, y6, y7, y8, y9; - uint32_t y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; - uint32_t y20, y21, y22, y23, y24, y25, y26, y27, y28, y29; - uint32_t y30; - - /* - * Spread input bits over the 6 input words x*. - */ - x1 = r0 & (uint32_t)0x11111111; - x2 = (r0 >> 1) & (uint32_t)0x11111111; - x3 = (r0 >> 2) & (uint32_t)0x11111111; - x4 = (r0 >> 3) & (uint32_t)0x11111111; - x1 = (x1 << 4) - x1; - x2 = (x2 << 4) - x2; - x3 = (x3 << 4) - x3; - x4 = (x4 << 4) - x4; - x0 = (x4 << 4) | (x4 >> 28); - x5 = (x1 >> 4) | (x1 << 28); - - /* - * XOR with the subkey for this round. - */ - x0 ^= sk[0]; - x1 ^= sk[1]; - x2 ^= sk[2]; - x3 ^= sk[3]; - x4 ^= sk[4]; - x5 ^= sk[5]; - - /* - * The T-boxes are done in parallel, since they all use a - * "tree of multiplexer". We use "fake multiplexers": - * - * y = a ^ (x & b) - * - * computes y as either 'a' (if x == 0) or 'a ^ b' (if x == 1). - */ - y0 = (uint32_t)0xEFA72C4D ^ (x0 & (uint32_t)0xEC7AC69C); - y1 = (uint32_t)0xAEAAEDFF ^ (x0 & (uint32_t)0x500FB821); - y2 = (uint32_t)0x37396665 ^ (x0 & (uint32_t)0x40EFA809); - y3 = (uint32_t)0x68D7B833 ^ (x0 & (uint32_t)0xA5EC0B28); - y4 = (uint32_t)0xC9C755BB ^ (x0 & (uint32_t)0x252CF820); - y5 = (uint32_t)0x73FC3606 ^ (x0 & (uint32_t)0x40205801); - y6 = (uint32_t)0xA2A0A918 ^ (x0 & (uint32_t)0xE220F929); - y7 = (uint32_t)0x8222BD90 ^ (x0 & (uint32_t)0x44A3F9E1); - y8 = (uint32_t)0xD6B6AC77 ^ (x0 & (uint32_t)0x794F104A); - y9 = (uint32_t)0x3069300C ^ (x0 & (uint32_t)0x026F320B); - y10 = (uint32_t)0x6CE0D5CC ^ (x0 & (uint32_t)0x7640B01A); - y11 = (uint32_t)0x59A9A22D ^ (x0 & (uint32_t)0x238F1572); - y12 = (uint32_t)0xAC6D0BD4 ^ (x0 & (uint32_t)0x7A63C083); - y13 = (uint32_t)0x21C83200 ^ (x0 & (uint32_t)0x11CCA000); - y14 = (uint32_t)0xA0E62188 ^ (x0 & (uint32_t)0x202F69AA); - /* y15 = (uint32_t)0x00000000 ^ (x0 & (uint32_t)0x00000000); */ - y16 = (uint32_t)0xAF7D655A ^ (x0 & (uint32_t)0x51B33BE9); - y17 = (uint32_t)0xF0168AA3 ^ (x0 & (uint32_t)0x3B0FE8AE); - y18 = (uint32_t)0x90AA30C6 ^ (x0 & (uint32_t)0x90BF8816); - y19 = (uint32_t)0x5AB2750A ^ (x0 & (uint32_t)0x09E34F9B); - y20 = (uint32_t)0x5391BE65 ^ (x0 & (uint32_t)0x0103BE88); - y21 = (uint32_t)0x93372BAF ^ (x0 & (uint32_t)0x49AC8E25); - y22 = (uint32_t)0xF288210C ^ (x0 & (uint32_t)0x922C313D); - y23 = (uint32_t)0x920AF5C0 ^ (x0 & (uint32_t)0x70EF31B0); - y24 = (uint32_t)0x63D312C0 ^ (x0 & (uint32_t)0x6A707100); - y25 = (uint32_t)0x537B3006 ^ (x0 & (uint32_t)0xB97C9011); - y26 = (uint32_t)0xA2EFB0A5 ^ (x0 & (uint32_t)0xA320C959); - y27 = (uint32_t)0xBC8F96A5 ^ (x0 & (uint32_t)0x6EA0AB4A); - y28 = (uint32_t)0xFAD176A5 ^ (x0 & (uint32_t)0x6953DDF8); - y29 = (uint32_t)0x665A14A3 ^ (x0 & (uint32_t)0xF74F3E2B); - y30 = (uint32_t)0xF2EFF0CC ^ (x0 & (uint32_t)0xF0306CAD); - /* y31 = (uint32_t)0x00000000 ^ (x0 & (uint32_t)0x00000000); */ - - y0 = y0 ^ (x1 & y1); - y1 = y2 ^ (x1 & y3); - y2 = y4 ^ (x1 & y5); - y3 = y6 ^ (x1 & y7); - y4 = y8 ^ (x1 & y9); - y5 = y10 ^ (x1 & y11); - y6 = y12 ^ (x1 & y13); - y7 = y14; /* was: y14 ^ (x1 & y15) */ - y8 = y16 ^ (x1 & y17); - y9 = y18 ^ (x1 & y19); - y10 = y20 ^ (x1 & y21); - y11 = y22 ^ (x1 & y23); - y12 = y24 ^ (x1 & y25); - y13 = y26 ^ (x1 & y27); - y14 = y28 ^ (x1 & y29); - y15 = y30; /* was: y30 ^ (x1 & y31) */ - - y0 = y0 ^ (x2 & y1); - y1 = y2 ^ (x2 & y3); - y2 = y4 ^ (x2 & y5); - y3 = y6 ^ (x2 & y7); - y4 = y8 ^ (x2 & y9); - y5 = y10 ^ (x2 & y11); - y6 = y12 ^ (x2 & y13); - y7 = y14 ^ (x2 & y15); - - y0 = y0 ^ (x3 & y1); - y1 = y2 ^ (x3 & y3); - y2 = y4 ^ (x3 & y5); - y3 = y6 ^ (x3 & y7); - - y0 = y0 ^ (x4 & y1); - y1 = y2 ^ (x4 & y3); - - y0 = y0 ^ (x5 & y1); - - /* - * The P permutation: - * -- Each bit move is converted into a mask + left rotation. - * -- Rotations that use the same movement are coalesced together. - * -- Left and right shifts are used as alternatives to a rotation - * where appropriate (this will help architectures that do not have - * a rotation opcode). - */ - z0 = (y0 & (uint32_t)0x00000004) << 3; - z0 |= (y0 & (uint32_t)0x00004000) << 4; - z0 |= rotl(y0 & 0x12020120, 5); - z0 |= (y0 & (uint32_t)0x00100000) << 6; - z0 |= (y0 & (uint32_t)0x00008000) << 9; - z0 |= (y0 & (uint32_t)0x04000000) >> 22; - z0 |= (y0 & (uint32_t)0x00000001) << 11; - z0 |= rotl(y0 & 0x20000200, 12); - z0 |= (y0 & (uint32_t)0x00200000) >> 19; - z0 |= (y0 & (uint32_t)0x00000040) << 14; - z0 |= (y0 & (uint32_t)0x00010000) << 15; - z0 |= (y0 & (uint32_t)0x00000002) << 16; - z0 |= rotl(y0 & 0x40801800, 17); - z0 |= (y0 & (uint32_t)0x00080000) >> 13; - z0 |= (y0 & (uint32_t)0x00000010) << 21; - z0 |= (y0 & (uint32_t)0x01000000) >> 10; - z0 |= rotl(y0 & 0x88000008, 24); - z0 |= (y0 & (uint32_t)0x00000480) >> 7; - z0 |= (y0 & (uint32_t)0x00442000) >> 6; - return z0; -} - -/* - * Process one block through 16 successive rounds, omitting the swap - * in the final round. - */ -static void -process_block_unit(uint32_t *pl, uint32_t *pr, const uint32_t *sk_exp) -{ - int i; - uint32_t l, r; - - l = *pl; - r = *pr; - for (i = 0; i < 16; i ++) { - uint32_t t; - - t = l ^ Fconf(r, sk_exp); - l = r; - r = t; - sk_exp += 6; - } - *pl = r; - *pr = l; -} - -/* see inner.h */ -void -br_des_ct_process_block(unsigned num_rounds, - const uint32_t *sk_exp, void *block) -{ - unsigned char *buf; - uint32_t l, r; - - buf = block; - l = br_dec32be(buf); - r = br_dec32be(buf + 4); - br_des_do_IP(&l, &r); - while (num_rounds -- > 0) { - process_block_unit(&l, &r, sk_exp); - sk_exp += 96; - } - br_des_do_invIP(&l, &r); - br_enc32be(buf, l); - br_enc32be(buf + 4, r); -} - -/* see inner.h */ -void -br_des_ct_skey_expand(uint32_t *sk_exp, - unsigned num_rounds, const uint32_t *skey) -{ - num_rounds <<= 4; - while (num_rounds -- > 0) { - uint32_t v, w0, w1, w2, w3; - - v = *skey ++; - w0 = v & 0x11111111; - w1 = (v >> 1) & 0x11111111; - w2 = (v >> 2) & 0x11111111; - w3 = (v >> 3) & 0x11111111; - *sk_exp ++ = (w0 << 4) - w0; - *sk_exp ++ = (w1 << 4) - w1; - *sk_exp ++ = (w2 << 4) - w2; - *sk_exp ++ = (w3 << 4) - w3; - v = *skey ++; - w0 = v & 0x11111111; - w1 = (v >> 1) & 0x11111111; - *sk_exp ++ = (w0 << 4) - w0; - *sk_exp ++ = (w1 << 4) - w1; - } -} diff --git a/third_party/bearssl/src/des_ct_cbcdec.c b/third_party/bearssl/src/des_ct_cbcdec.c deleted file mode 100644 index d208a3d2a..000000000 --- a/third_party/bearssl/src/des_ct_cbcdec.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_des_ct_cbcdec_init(br_des_ct_cbcdec_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_des_ct_cbcdec_vtable; - ctx->num_rounds = br_des_ct_keysched(ctx->skey, key, len); - if (len == 8) { - br_des_rev_skey(ctx->skey); - } else { - int i; - - for (i = 0; i < 48; i += 2) { - uint32_t t; - - t = ctx->skey[i]; - ctx->skey[i] = ctx->skey[94 - i]; - ctx->skey[94 - i] = t; - t = ctx->skey[i + 1]; - ctx->skey[i + 1] = ctx->skey[95 - i]; - ctx->skey[95 - i] = t; - } - } -} - -/* see bearssl_block.h */ -void -br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - uint32_t sk_exp[288]; - - br_des_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - ivbuf = iv; - buf = data; - while (len > 0) { - unsigned char tmp[8]; - int i; - - memcpy(tmp, buf, 8); - br_des_ct_process_block(ctx->num_rounds, sk_exp, buf); - for (i = 0; i < 8; i ++) { - buf[i] ^= ivbuf[i]; - } - memcpy(ivbuf, tmp, 8); - buf += 8; - len -= 8; - } -} - -/* see bearssl_block.h */ -const br_block_cbcdec_class br_des_ct_cbcdec_vtable = { - sizeof(br_des_ct_cbcdec_keys), - 8, - 3, - (void (*)(const br_block_cbcdec_class **, const void *, size_t)) - &br_des_ct_cbcdec_init, - (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) - &br_des_ct_cbcdec_run -}; diff --git a/third_party/bearssl/src/des_ct_cbcenc.c b/third_party/bearssl/src/des_ct_cbcenc.c deleted file mode 100644 index 4b3610e07..000000000 --- a/third_party/bearssl/src/des_ct_cbcenc.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_des_ct_cbcenc_init(br_des_ct_cbcenc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_des_ct_cbcenc_vtable; - ctx->num_rounds = br_des_ct_keysched(ctx->skey, key, len); -} - -/* see bearssl_block.h */ -void -br_des_ct_cbcenc_run(const br_des_ct_cbcenc_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - uint32_t sk_exp[288]; - - br_des_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); - ivbuf = iv; - buf = data; - while (len > 0) { - int i; - - for (i = 0; i < 8; i ++) { - buf[i] ^= ivbuf[i]; - } - br_des_ct_process_block(ctx->num_rounds, sk_exp, buf); - memcpy(ivbuf, buf, 8); - buf += 8; - len -= 8; - } -} - -/* see bearssl_block.h */ -const br_block_cbcenc_class br_des_ct_cbcenc_vtable = { - sizeof(br_des_ct_cbcenc_keys), - 8, - 3, - (void (*)(const br_block_cbcenc_class **, const void *, size_t)) - &br_des_ct_cbcenc_init, - (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) - &br_des_ct_cbcenc_run -}; diff --git a/third_party/bearssl/src/des_support.c b/third_party/bearssl/src/des_support.c deleted file mode 100644 index 37f6db32d..000000000 --- a/third_party/bearssl/src/des_support.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_des_do_IP(uint32_t *xl, uint32_t *xr) -{ - /* - * Permutation algorithm is initially from Richard Outerbridge; - * implementation here is adapted from Crypto++ "des.cpp" file - * (which is in public domain). - */ - uint32_t l, r, t; - - l = *xl; - r = *xr; - t = ((l >> 4) ^ r) & (uint32_t)0x0F0F0F0F; - r ^= t; - l ^= t << 4; - t = ((l >> 16) ^ r) & (uint32_t)0x0000FFFF; - r ^= t; - l ^= t << 16; - t = ((r >> 2) ^ l) & (uint32_t)0x33333333; - l ^= t; - r ^= t << 2; - t = ((r >> 8) ^ l) & (uint32_t)0x00FF00FF; - l ^= t; - r ^= t << 8; - t = ((l >> 1) ^ r) & (uint32_t)0x55555555; - r ^= t; - l ^= t << 1; - *xl = l; - *xr = r; -} - -/* see inner.h */ -void -br_des_do_invIP(uint32_t *xl, uint32_t *xr) -{ - /* - * See br_des_do_IP(). - */ - uint32_t l, r, t; - - l = *xl; - r = *xr; - t = ((l >> 1) ^ r) & 0x55555555; - r ^= t; - l ^= t << 1; - t = ((r >> 8) ^ l) & 0x00FF00FF; - l ^= t; - r ^= t << 8; - t = ((r >> 2) ^ l) & 0x33333333; - l ^= t; - r ^= t << 2; - t = ((l >> 16) ^ r) & 0x0000FFFF; - r ^= t; - l ^= t << 16; - t = ((l >> 4) ^ r) & 0x0F0F0F0F; - r ^= t; - l ^= t << 4; - *xl = l; - *xr = r; -} - -/* see inner.h */ -void -br_des_keysched_unit(uint32_t *skey, const void *key) -{ - uint32_t xl, xr, kl, kr; - int i; - - xl = br_dec32be(key); - xr = br_dec32be((const unsigned char *)key + 4); - - /* - * Permutation PC-1 is quite similar to the IP permutation. - * Definition of IP (in FIPS 46-3 notations) is: - * 58 50 42 34 26 18 10 2 - * 60 52 44 36 28 20 12 4 - * 62 54 46 38 30 22 14 6 - * 64 56 48 40 32 24 16 8 - * 57 49 41 33 25 17 9 1 - * 59 51 43 35 27 19 11 3 - * 61 53 45 37 29 21 13 5 - * 63 55 47 39 31 23 15 7 - * - * Definition of PC-1 is: - * 57 49 41 33 25 17 9 1 - * 58 50 42 34 26 18 10 2 - * 59 51 43 35 27 19 11 3 - * 60 52 44 36 - * 63 55 47 39 31 23 15 7 - * 62 54 46 38 30 22 14 6 - * 61 53 45 37 29 21 13 5 - * 28 20 12 4 - */ - br_des_do_IP(&xl, &xr); - kl = ((xr & (uint32_t)0xFF000000) >> 4) - | ((xl & (uint32_t)0xFF000000) >> 12) - | ((xr & (uint32_t)0x00FF0000) >> 12) - | ((xl & (uint32_t)0x00FF0000) >> 20); - kr = ((xr & (uint32_t)0x000000FF) << 20) - | ((xl & (uint32_t)0x0000FF00) << 4) - | ((xr & (uint32_t)0x0000FF00) >> 4) - | ((xl & (uint32_t)0x000F0000) >> 16); - - /* - * For each round, rotate the two 28-bit words kl and kr. - * The extraction of the 48-bit subkey (PC-2) is not done yet. - */ - for (i = 0; i < 16; i ++) { - if ((1 << i) & 0x8103) { - kl = (kl << 1) | (kl >> 27); - kr = (kr << 1) | (kr >> 27); - } else { - kl = (kl << 2) | (kl >> 26); - kr = (kr << 2) | (kr >> 26); - } - kl &= (uint32_t)0x0FFFFFFF; - kr &= (uint32_t)0x0FFFFFFF; - skey[(i << 1) + 0] = kl; - skey[(i << 1) + 1] = kr; - } -} - -/* see inner.h */ -void -br_des_rev_skey(uint32_t *skey) -{ - int i; - - for (i = 0; i < 16; i += 2) { - uint32_t t; - - t = skey[i + 0]; - skey[i + 0] = skey[30 - i]; - skey[30 - i] = t; - t = skey[i + 1]; - skey[i + 1] = skey[31 - i]; - skey[31 - i] = t; - } -} diff --git a/third_party/bearssl/src/des_tab.c b/third_party/bearssl/src/des_tab.c deleted file mode 100644 index 3f8e4f9f2..000000000 --- a/third_party/bearssl/src/des_tab.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * PC2left[x] tells where bit x goes when applying PC-2. 'x' is a bit - * position in the left rotated key word. Both position are in normal - * order (rightmost bit is 0). - */ -static const unsigned char PC2left[] = { - 16, 3, 7, 24, 20, 11, 24, - 13, 2, 10, 24, 22, 5, 15, - 23, 1, 9, 21, 12, 24, 6, - 4, 14, 18, 8, 17, 0, 19 -}; - -/* - * Similar to PC2left[x], for the right rotated key word. - */ -static const unsigned char PC2right[] = { - 8, 18, 24, 6, 22, 15, 3, - 10, 12, 19, 5, 14, 11, 24, - 4, 23, 16, 9, 24, 20, 2, - 24, 7, 13, 0, 21, 17, 1 -}; - -/* - * S-boxes and PC-1 merged. - */ -static const uint32_t S1[] = { - 0x00808200, 0x00000000, 0x00008000, 0x00808202, - 0x00808002, 0x00008202, 0x00000002, 0x00008000, - 0x00000200, 0x00808200, 0x00808202, 0x00000200, - 0x00800202, 0x00808002, 0x00800000, 0x00000002, - 0x00000202, 0x00800200, 0x00800200, 0x00008200, - 0x00008200, 0x00808000, 0x00808000, 0x00800202, - 0x00008002, 0x00800002, 0x00800002, 0x00008002, - 0x00000000, 0x00000202, 0x00008202, 0x00800000, - 0x00008000, 0x00808202, 0x00000002, 0x00808000, - 0x00808200, 0x00800000, 0x00800000, 0x00000200, - 0x00808002, 0x00008000, 0x00008200, 0x00800002, - 0x00000200, 0x00000002, 0x00800202, 0x00008202, - 0x00808202, 0x00008002, 0x00808000, 0x00800202, - 0x00800002, 0x00000202, 0x00008202, 0x00808200, - 0x00000202, 0x00800200, 0x00800200, 0x00000000, - 0x00008002, 0x00008200, 0x00000000, 0x00808002 -}; - -static const uint32_t S2[] = { - 0x40084010, 0x40004000, 0x00004000, 0x00084010, - 0x00080000, 0x00000010, 0x40080010, 0x40004010, - 0x40000010, 0x40084010, 0x40084000, 0x40000000, - 0x40004000, 0x00080000, 0x00000010, 0x40080010, - 0x00084000, 0x00080010, 0x40004010, 0x00000000, - 0x40000000, 0x00004000, 0x00084010, 0x40080000, - 0x00080010, 0x40000010, 0x00000000, 0x00084000, - 0x00004010, 0x40084000, 0x40080000, 0x00004010, - 0x00000000, 0x00084010, 0x40080010, 0x00080000, - 0x40004010, 0x40080000, 0x40084000, 0x00004000, - 0x40080000, 0x40004000, 0x00000010, 0x40084010, - 0x00084010, 0x00000010, 0x00004000, 0x40000000, - 0x00004010, 0x40084000, 0x00080000, 0x40000010, - 0x00080010, 0x40004010, 0x40000010, 0x00080010, - 0x00084000, 0x00000000, 0x40004000, 0x00004010, - 0x40000000, 0x40080010, 0x40084010, 0x00084000 -}; - -static const uint32_t S3[] = { - 0x00000104, 0x04010100, 0x00000000, 0x04010004, - 0x04000100, 0x00000000, 0x00010104, 0x04000100, - 0x00010004, 0x04000004, 0x04000004, 0x00010000, - 0x04010104, 0x00010004, 0x04010000, 0x00000104, - 0x04000000, 0x00000004, 0x04010100, 0x00000100, - 0x00010100, 0x04010000, 0x04010004, 0x00010104, - 0x04000104, 0x00010100, 0x00010000, 0x04000104, - 0x00000004, 0x04010104, 0x00000100, 0x04000000, - 0x04010100, 0x04000000, 0x00010004, 0x00000104, - 0x00010000, 0x04010100, 0x04000100, 0x00000000, - 0x00000100, 0x00010004, 0x04010104, 0x04000100, - 0x04000004, 0x00000100, 0x00000000, 0x04010004, - 0x04000104, 0x00010000, 0x04000000, 0x04010104, - 0x00000004, 0x00010104, 0x00010100, 0x04000004, - 0x04010000, 0x04000104, 0x00000104, 0x04010000, - 0x00010104, 0x00000004, 0x04010004, 0x00010100 -}; - -static const uint32_t S4[] = { - 0x80401000, 0x80001040, 0x80001040, 0x00000040, - 0x00401040, 0x80400040, 0x80400000, 0x80001000, - 0x00000000, 0x00401000, 0x00401000, 0x80401040, - 0x80000040, 0x00000000, 0x00400040, 0x80400000, - 0x80000000, 0x00001000, 0x00400000, 0x80401000, - 0x00000040, 0x00400000, 0x80001000, 0x00001040, - 0x80400040, 0x80000000, 0x00001040, 0x00400040, - 0x00001000, 0x00401040, 0x80401040, 0x80000040, - 0x00400040, 0x80400000, 0x00401000, 0x80401040, - 0x80000040, 0x00000000, 0x00000000, 0x00401000, - 0x00001040, 0x00400040, 0x80400040, 0x80000000, - 0x80401000, 0x80001040, 0x80001040, 0x00000040, - 0x80401040, 0x80000040, 0x80000000, 0x00001000, - 0x80400000, 0x80001000, 0x00401040, 0x80400040, - 0x80001000, 0x00001040, 0x00400000, 0x80401000, - 0x00000040, 0x00400000, 0x00001000, 0x00401040 -}; - -static const uint32_t S5[] = { - 0x00000080, 0x01040080, 0x01040000, 0x21000080, - 0x00040000, 0x00000080, 0x20000000, 0x01040000, - 0x20040080, 0x00040000, 0x01000080, 0x20040080, - 0x21000080, 0x21040000, 0x00040080, 0x20000000, - 0x01000000, 0x20040000, 0x20040000, 0x00000000, - 0x20000080, 0x21040080, 0x21040080, 0x01000080, - 0x21040000, 0x20000080, 0x00000000, 0x21000000, - 0x01040080, 0x01000000, 0x21000000, 0x00040080, - 0x00040000, 0x21000080, 0x00000080, 0x01000000, - 0x20000000, 0x01040000, 0x21000080, 0x20040080, - 0x01000080, 0x20000000, 0x21040000, 0x01040080, - 0x20040080, 0x00000080, 0x01000000, 0x21040000, - 0x21040080, 0x00040080, 0x21000000, 0x21040080, - 0x01040000, 0x00000000, 0x20040000, 0x21000000, - 0x00040080, 0x01000080, 0x20000080, 0x00040000, - 0x00000000, 0x20040000, 0x01040080, 0x20000080 -}; - -static const uint32_t S6[] = { - 0x10000008, 0x10200000, 0x00002000, 0x10202008, - 0x10200000, 0x00000008, 0x10202008, 0x00200000, - 0x10002000, 0x00202008, 0x00200000, 0x10000008, - 0x00200008, 0x10002000, 0x10000000, 0x00002008, - 0x00000000, 0x00200008, 0x10002008, 0x00002000, - 0x00202000, 0x10002008, 0x00000008, 0x10200008, - 0x10200008, 0x00000000, 0x00202008, 0x10202000, - 0x00002008, 0x00202000, 0x10202000, 0x10000000, - 0x10002000, 0x00000008, 0x10200008, 0x00202000, - 0x10202008, 0x00200000, 0x00002008, 0x10000008, - 0x00200000, 0x10002000, 0x10000000, 0x00002008, - 0x10000008, 0x10202008, 0x00202000, 0x10200000, - 0x00202008, 0x10202000, 0x00000000, 0x10200008, - 0x00000008, 0x00002000, 0x10200000, 0x00202008, - 0x00002000, 0x00200008, 0x10002008, 0x00000000, - 0x10202000, 0x10000000, 0x00200008, 0x10002008 -}; - -static const uint32_t S7[] = { - 0x00100000, 0x02100001, 0x02000401, 0x00000000, - 0x00000400, 0x02000401, 0x00100401, 0x02100400, - 0x02100401, 0x00100000, 0x00000000, 0x02000001, - 0x00000001, 0x02000000, 0x02100001, 0x00000401, - 0x02000400, 0x00100401, 0x00100001, 0x02000400, - 0x02000001, 0x02100000, 0x02100400, 0x00100001, - 0x02100000, 0x00000400, 0x00000401, 0x02100401, - 0x00100400, 0x00000001, 0x02000000, 0x00100400, - 0x02000000, 0x00100400, 0x00100000, 0x02000401, - 0x02000401, 0x02100001, 0x02100001, 0x00000001, - 0x00100001, 0x02000000, 0x02000400, 0x00100000, - 0x02100400, 0x00000401, 0x00100401, 0x02100400, - 0x00000401, 0x02000001, 0x02100401, 0x02100000, - 0x00100400, 0x00000000, 0x00000001, 0x02100401, - 0x00000000, 0x00100401, 0x02100000, 0x00000400, - 0x02000001, 0x02000400, 0x00000400, 0x00100001 -}; - -static const uint32_t S8[] = { - 0x08000820, 0x00000800, 0x00020000, 0x08020820, - 0x08000000, 0x08000820, 0x00000020, 0x08000000, - 0x00020020, 0x08020000, 0x08020820, 0x00020800, - 0x08020800, 0x00020820, 0x00000800, 0x00000020, - 0x08020000, 0x08000020, 0x08000800, 0x00000820, - 0x00020800, 0x00020020, 0x08020020, 0x08020800, - 0x00000820, 0x00000000, 0x00000000, 0x08020020, - 0x08000020, 0x08000800, 0x00020820, 0x00020000, - 0x00020820, 0x00020000, 0x08020800, 0x00000800, - 0x00000020, 0x08020020, 0x00000800, 0x00020820, - 0x08000800, 0x00000020, 0x08000020, 0x08020000, - 0x08020020, 0x08000000, 0x00020000, 0x08000820, - 0x00000000, 0x08020820, 0x00020020, 0x08000020, - 0x08020000, 0x08000800, 0x08000820, 0x00000000, - 0x08020820, 0x00020800, 0x00020800, 0x00000820, - 0x00000820, 0x00020020, 0x08000000, 0x08020800 -}; - -static inline uint32_t -Fconf(uint32_t r0, uint32_t skl, uint32_t skr) -{ - uint32_t r1; - - r1 = (r0 << 16) | (r0 >> 16); - return - S1[((r1 >> 11) ^ (skl >> 18)) & 0x3F] - | S2[((r0 >> 23) ^ (skl >> 12)) & 0x3F] - | S3[((r0 >> 19) ^ (skl >> 6)) & 0x3F] - | S4[((r0 >> 15) ^ (skl )) & 0x3F] - | S5[((r0 >> 11) ^ (skr >> 18)) & 0x3F] - | S6[((r0 >> 7) ^ (skr >> 12)) & 0x3F] - | S7[((r0 >> 3) ^ (skr >> 6)) & 0x3F] - | S8[((r1 >> 15) ^ (skr )) & 0x3F]; -} - -static void -process_block_unit(uint32_t *pl, uint32_t *pr, const uint32_t *skey) -{ - int i; - uint32_t l, r; - - l = *pl; - r = *pr; - for (i = 0; i < 16; i ++) { - uint32_t t; - - t = l ^ Fconf(r, skey[(i << 1) + 0], skey[(i << 1) + 1]); - l = r; - r = t; - } - *pl = r; - *pr = l; -} - -/* see inner.h */ -void -br_des_tab_process_block(unsigned num_rounds, const uint32_t *skey, void *block) -{ - unsigned char *buf; - uint32_t l, r; - - buf = block; - l = br_dec32be(buf); - r = br_dec32be(buf + 4); - br_des_do_IP(&l, &r); - while (num_rounds -- > 0) { - process_block_unit(&l, &r, skey); - skey += 32; - } - br_des_do_invIP(&l, &r); - br_enc32be(buf, l); - br_enc32be(buf + 4, r); -} - -static void -keysched_unit(uint32_t *skey, const void *key) -{ - int i; - - br_des_keysched_unit(skey, key); - - /* - * Apply PC-2 to get the 48-bit subkeys. - */ - for (i = 0; i < 16; i ++) { - uint32_t xl, xr, ul, ur; - int j; - - xl = skey[(i << 1) + 0]; - xr = skey[(i << 1) + 1]; - ul = 0; - ur = 0; - for (j = 0; j < 28; j ++) { - ul |= (xl & 1) << PC2left[j]; - ur |= (xr & 1) << PC2right[j]; - xl >>= 1; - xr >>= 1; - } - skey[(i << 1) + 0] = ul; - skey[(i << 1) + 1] = ur; - } -} - -/* see inner.h */ -unsigned -br_des_tab_keysched(uint32_t *skey, const void *key, size_t key_len) -{ - switch (key_len) { - case 8: - keysched_unit(skey, key); - return 1; - case 16: - keysched_unit(skey, key); - keysched_unit(skey + 32, (const unsigned char *)key + 8); - br_des_rev_skey(skey + 32); - memcpy(skey + 64, skey, 32 * sizeof *skey); - return 3; - default: - keysched_unit(skey, key); - keysched_unit(skey + 32, (const unsigned char *)key + 8); - br_des_rev_skey(skey + 32); - keysched_unit(skey + 64, (const unsigned char *)key + 16); - return 3; - } -} diff --git a/third_party/bearssl/src/des_tab_cbcdec.c b/third_party/bearssl/src/des_tab_cbcdec.c deleted file mode 100644 index e7eabe9d0..000000000 --- a/third_party/bearssl/src/des_tab_cbcdec.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_des_tab_cbcdec_init(br_des_tab_cbcdec_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_des_tab_cbcdec_vtable; - ctx->num_rounds = br_des_tab_keysched(ctx->skey, key, len); - if (len == 8) { - br_des_rev_skey(ctx->skey); - } else { - int i; - - for (i = 0; i < 48; i += 2) { - uint32_t t; - - t = ctx->skey[i]; - ctx->skey[i] = ctx->skey[94 - i]; - ctx->skey[94 - i] = t; - t = ctx->skey[i + 1]; - ctx->skey[i + 1] = ctx->skey[95 - i]; - ctx->skey[95 - i] = t; - } - } -} - -/* see bearssl_block.h */ -void -br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - - ivbuf = iv; - buf = data; - while (len > 0) { - unsigned char tmp[8]; - int i; - - memcpy(tmp, buf, 8); - br_des_tab_process_block(ctx->num_rounds, ctx->skey, buf); - for (i = 0; i < 8; i ++) { - buf[i] ^= ivbuf[i]; - } - memcpy(ivbuf, tmp, 8); - buf += 8; - len -= 8; - } -} - -/* see bearssl_block.h */ -const br_block_cbcdec_class br_des_tab_cbcdec_vtable = { - sizeof(br_des_tab_cbcdec_keys), - 8, - 3, - (void (*)(const br_block_cbcdec_class **, const void *, size_t)) - &br_des_tab_cbcdec_init, - (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) - &br_des_tab_cbcdec_run -}; diff --git a/third_party/bearssl/src/des_tab_cbcenc.c b/third_party/bearssl/src/des_tab_cbcenc.c deleted file mode 100644 index 3a45ba3e5..000000000 --- a/third_party/bearssl/src/des_tab_cbcenc.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_block.h */ -void -br_des_tab_cbcenc_init(br_des_tab_cbcenc_keys *ctx, - const void *key, size_t len) -{ - ctx->vtable = &br_des_tab_cbcenc_vtable; - ctx->num_rounds = br_des_tab_keysched(ctx->skey, key, len); -} - -/* see bearssl_block.h */ -void -br_des_tab_cbcenc_run(const br_des_tab_cbcenc_keys *ctx, - void *iv, void *data, size_t len) -{ - unsigned char *buf, *ivbuf; - - ivbuf = iv; - buf = data; - while (len > 0) { - int i; - - for (i = 0; i < 8; i ++) { - buf[i] ^= ivbuf[i]; - } - br_des_tab_process_block(ctx->num_rounds, ctx->skey, buf); - memcpy(ivbuf, buf, 8); - buf += 8; - len -= 8; - } -} - -/* see bearssl_block.h */ -const br_block_cbcenc_class br_des_tab_cbcenc_vtable = { - sizeof(br_des_tab_cbcenc_keys), - 8, - 3, - (void (*)(const br_block_cbcenc_class **, const void *, size_t)) - &br_des_tab_cbcenc_init, - (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) - &br_des_tab_cbcenc_run -}; diff --git a/third_party/bearssl/src/ec_all_m15.c b/third_party/bearssl/src/ec_all_m15.c deleted file mode 100644 index bb550e185..000000000 --- a/third_party/bearssl/src/ec_all_m15.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m15.generator(curve, len); - case BR_EC_curve25519: - return br_ec_c25519_m15.generator(curve, len); - default: - return br_ec_prime_i15.generator(curve, len); - } -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m15.order(curve, len); - case BR_EC_curve25519: - return br_ec_c25519_m15.order(curve, len); - default: - return br_ec_prime_i15.order(curve, len); - } -} - -static size_t -api_xoff(int curve, size_t *len) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m15.xoff(curve, len); - case BR_EC_curve25519: - return br_ec_c25519_m15.xoff(curve, len); - default: - return br_ec_prime_i15.xoff(curve, len); - } -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *kb, size_t kblen, int curve) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m15.mul(G, Glen, kb, kblen, curve); - case BR_EC_curve25519: - return br_ec_c25519_m15.mul(G, Glen, kb, kblen, curve); - default: - return br_ec_prime_i15.mul(G, Glen, kb, kblen, curve); - } -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m15.mulgen(R, x, xlen, curve); - case BR_EC_curve25519: - return br_ec_c25519_m15.mulgen(R, x, xlen, curve); - default: - return br_ec_prime_i15.mulgen(R, x, xlen, curve); - } -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - switch (curve) { - case BR_EC_secp256r1: - return br_ec_p256_m15.muladd(A, B, len, - x, xlen, y, ylen, curve); - case BR_EC_curve25519: - return br_ec_c25519_m15.muladd(A, B, len, - x, xlen, y, ylen, curve); - default: - return br_ec_prime_i15.muladd(A, B, len, - x, xlen, y, ylen, curve); - } -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_all_m15 = { - (uint32_t)0x23800000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; diff --git a/third_party/bearssl/src/ec_c25519_i15.c b/third_party/bearssl/src/ec_c25519_i15.c deleted file mode 100644 index 8fadcf480..000000000 --- a/third_party/bearssl/src/ec_c25519_i15.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * Parameters for the field: - * - field modulus p = 2^255-19 - * - R^2 mod p (R = 2^(15k) for the smallest k such that R >= p) - */ - -static const uint16_t C255_P[] = { - 0x0110, - 0x7FED, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF -}; - -#define P0I 0x4A1B - -static const uint16_t C255_R2[] = { - 0x0110, - 0x0169, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000 -}; - -/* obsolete -#include -#include -static void -print_int_mont(const char *name, const uint16_t *x) -{ - uint16_t y[18]; - unsigned char tmp[32]; - size_t u; - - printf("%s = ", name); - memcpy(y, x, sizeof y); - br_i15_from_monty(y, C255_P, P0I); - br_i15_encode(tmp, sizeof tmp, y); - for (u = 0; u < sizeof tmp; u ++) { - printf("%02X", tmp[u]); - } - printf("\n"); -} -*/ - -static const uint16_t C255_A24[] = { - 0x0110, - 0x45D3, 0x0046, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000 -}; - -static const unsigned char GEN[] = { - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const unsigned char ORDER[] = { - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -}; - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return GEN; -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return ORDER; -} - -static size_t -api_xoff(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return 0; -} - -static void -cswap(uint16_t *a, uint16_t *b, uint32_t ctl) -{ - int i; - - ctl = -ctl; - for (i = 0; i < 18; i ++) { - uint32_t aw, bw, tw; - - aw = a[i]; - bw = b[i]; - tw = ctl & (aw ^ bw); - a[i] = aw ^ tw; - b[i] = bw ^ tw; - } -} - -static void -c255_add(uint16_t *d, const uint16_t *a, const uint16_t *b) -{ - uint32_t ctl; - uint16_t t[18]; - - memcpy(t, a, sizeof t); - ctl = br_i15_add(t, b, 1); - ctl |= NOT(br_i15_sub(t, C255_P, 0)); - br_i15_sub(t, C255_P, ctl); - memcpy(d, t, sizeof t); -} - -static void -c255_sub(uint16_t *d, const uint16_t *a, const uint16_t *b) -{ - uint16_t t[18]; - - memcpy(t, a, sizeof t); - br_i15_add(t, C255_P, br_i15_sub(t, b, 1)); - memcpy(d, t, sizeof t); -} - -static void -c255_mul(uint16_t *d, const uint16_t *a, const uint16_t *b) -{ - uint16_t t[18]; - - br_i15_montymul(t, a, b, C255_P, P0I); - memcpy(d, t, sizeof t); -} - -static void -byteswap(unsigned char *G) -{ - int i; - - for (i = 0; i < 16; i ++) { - unsigned char t; - - t = G[i]; - G[i] = G[31 - i]; - G[31 - i] = t; - } -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *kb, size_t kblen, int curve) -{ -#define ILEN (18 * sizeof(uint16_t)) - - /* - * The a[] and b[] arrays have an extra word to allow for - * decoding without using br_i15_decode_reduce(). - */ - uint16_t x1[18], x2[18], x3[18], z2[18], z3[18]; - uint16_t a[19], aa[18], b[19], bb[18]; - uint16_t c[18], d[18], e[18], da[18], cb[18]; - unsigned char k[32]; - uint32_t swap; - int i; - - (void)curve; - - /* - * Points are encoded over exactly 32 bytes. Multipliers must fit - * in 32 bytes as well. - * RFC 7748 mandates that the high bit of the last point byte must - * be ignored/cleared. - */ - if (Glen != 32 || kblen > 32) { - return 0; - } - G[31] &= 0x7F; - - /* - * Byteswap the point encoding, because it uses little-endian, and - * the generic decoding routine uses big-endian. - */ - byteswap(G); - - /* - * Decode the point ('u' coordinate). This should be reduced - * modulo p, but we prefer to avoid the dependency on - * br_i15_decode_reduce(). Instead, we use br_i15_decode_mod() - * with a synthetic modulus of value 2^255 (this must work - * since G was truncated to 255 bits), then use a conditional - * subtraction. We use br_i15_decode_mod() and not - * br_i15_decode(), because the ec_prime_i15 implementation uses - * the former but not the latter. - * br_i15_decode_reduce(a, G, 32, C255_P); - */ - br_i15_zero(b, 0x111); - b[18] = 1; - br_i15_decode_mod(a, G, 32, b); - a[0] = 0x110; - br_i15_sub(a, C255_P, NOT(br_i15_sub(a, C255_P, 0))); - - /* - * Initialise variables x1, x2, z2, x3 and z3. We set all of them - * into Montgomery representation. - */ - br_i15_montymul(x1, a, C255_R2, C255_P, P0I); - memcpy(x3, x1, ILEN); - br_i15_zero(z2, C255_P[0]); - memcpy(x2, z2, ILEN); - x2[1] = 19; - memcpy(z3, x2, ILEN); - - memset(k, 0, (sizeof k) - kblen); - memcpy(k + (sizeof k) - kblen, kb, kblen); - k[31] &= 0xF8; - k[0] &= 0x7F; - k[0] |= 0x40; - - /* obsolete - print_int_mont("x1", x1); - */ - - swap = 0; - for (i = 254; i >= 0; i --) { - uint32_t kt; - - kt = (k[31 - (i >> 3)] >> (i & 7)) & 1; - swap ^= kt; - cswap(x2, x3, swap); - cswap(z2, z3, swap); - swap = kt; - - /* obsolete - print_int_mont("x2", x2); - print_int_mont("z2", z2); - print_int_mont("x3", x3); - print_int_mont("z3", z3); - */ - - c255_add(a, x2, z2); - c255_mul(aa, a, a); - c255_sub(b, x2, z2); - c255_mul(bb, b, b); - c255_sub(e, aa, bb); - c255_add(c, x3, z3); - c255_sub(d, x3, z3); - c255_mul(da, d, a); - c255_mul(cb, c, b); - - /* obsolete - print_int_mont("a ", a); - print_int_mont("aa", aa); - print_int_mont("b ", b); - print_int_mont("bb", bb); - print_int_mont("e ", e); - print_int_mont("c ", c); - print_int_mont("d ", d); - print_int_mont("da", da); - print_int_mont("cb", cb); - */ - - c255_add(x3, da, cb); - c255_mul(x3, x3, x3); - c255_sub(z3, da, cb); - c255_mul(z3, z3, z3); - c255_mul(z3, z3, x1); - c255_mul(x2, aa, bb); - c255_mul(z2, C255_A24, e); - c255_add(z2, z2, aa); - c255_mul(z2, e, z2); - - /* obsolete - print_int_mont("x2", x2); - print_int_mont("z2", z2); - print_int_mont("x3", x3); - print_int_mont("z3", z3); - */ - } - cswap(x2, x3, swap); - cswap(z2, z3, swap); - - /* - * Inverse z2 with a modular exponentiation. This is a simple - * square-and-multiply algorithm; we mutualise most non-squarings - * since the exponent contains almost only ones. - */ - memcpy(a, z2, ILEN); - for (i = 0; i < 15; i ++) { - c255_mul(a, a, a); - c255_mul(a, a, z2); - } - memcpy(b, a, ILEN); - for (i = 0; i < 14; i ++) { - int j; - - for (j = 0; j < 16; j ++) { - c255_mul(b, b, b); - } - c255_mul(b, b, a); - } - for (i = 14; i >= 0; i --) { - c255_mul(b, b, b); - if ((0xFFEB >> i) & 1) { - c255_mul(b, z2, b); - } - } - c255_mul(b, x2, b); - - /* - * To avoid a dependency on br_i15_from_monty(), we use a - * Montgomery multiplication with 1. - * memcpy(x2, b, ILEN); - * br_i15_from_monty(x2, C255_P, P0I); - */ - br_i15_zero(a, C255_P[0]); - a[1] = 1; - br_i15_montymul(x2, a, b, C255_P, P0I); - - br_i15_encode(G, 32, x2); - byteswap(G); - return 1; - -#undef ILEN -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - /* - * We don't implement this method, since it is used for ECDSA - * only, and there is no ECDSA over Curve25519 (which instead - * uses EdDSA). - */ - (void)A; - (void)B; - (void)len; - (void)x; - (void)xlen; - (void)y; - (void)ylen; - (void)curve; - return 0; -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_c25519_i15 = { - (uint32_t)0x20000000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; diff --git a/third_party/bearssl/src/ec_c25519_m15.c b/third_party/bearssl/src/ec_c25519_m15.c deleted file mode 100644 index deff55b33..000000000 --- a/third_party/bearssl/src/ec_c25519_m15.c +++ /dev/null @@ -1,1478 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* obsolete -#include -#include -static void -print_int(const char *name, const uint32_t *x) -{ - size_t u; - unsigned char tmp[36]; - - printf("%s = ", name); - for (u = 0; u < 20; u ++) { - if (x[u] > 0x1FFF) { - printf("INVALID:"); - for (u = 0; u < 20; u ++) { - printf(" %04X", x[u]); - } - printf("\n"); - return; - } - } - memset(tmp, 0, sizeof tmp); - for (u = 0; u < 20; u ++) { - uint32_t w; - int j, k; - - w = x[u]; - j = 13 * (int)u; - k = j & 7; - if (k != 0) { - w <<= k; - j -= k; - } - k = j >> 3; - tmp[35 - k] |= (unsigned char)w; - tmp[34 - k] |= (unsigned char)(w >> 8); - tmp[33 - k] |= (unsigned char)(w >> 16); - tmp[32 - k] |= (unsigned char)(w >> 24); - } - for (u = 4; u < 36; u ++) { - printf("%02X", tmp[u]); - } - printf("\n"); -} -*/ - -/* - * If BR_NO_ARITH_SHIFT is undefined, or defined to 0, then we _assume_ - * that right-shifting a signed negative integer copies the sign bit - * (arithmetic right-shift). This is "implementation-defined behaviour", - * i.e. it is not undefined, but it may differ between compilers. Each - * compiler is supposed to document its behaviour in that respect. GCC - * explicitly defines that an arithmetic right shift is used. We expect - * all other compilers to do the same, because underlying CPU offer an - * arithmetic right shift opcode that could not be used otherwise. - */ -#if BR_NO_ARITH_SHIFT -#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ - | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) -#else -#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) -#endif - -/* - * Convert an integer from unsigned little-endian encoding to a sequence of - * 13-bit words in little-endian order. The final "partial" word is - * returned. - */ -static uint32_t -le8_to_le13(uint32_t *dst, const unsigned char *src, size_t len) -{ - uint32_t acc; - int acc_len; - - acc = 0; - acc_len = 0; - while (len -- > 0) { - acc |= (uint32_t)(*src ++) << acc_len; - acc_len += 8; - if (acc_len >= 13) { - *dst ++ = acc & 0x1FFF; - acc >>= 13; - acc_len -= 13; - } - } - return acc; -} - -/* - * Convert an integer (13-bit words, little-endian) to unsigned - * little-endian encoding. The total encoding length is provided; all - * the destination bytes will be filled. - */ -static void -le13_to_le8(unsigned char *dst, size_t len, const uint32_t *src) -{ - uint32_t acc; - int acc_len; - - acc = 0; - acc_len = 0; - while (len -- > 0) { - if (acc_len < 8) { - acc |= (*src ++) << acc_len; - acc_len += 13; - } - *dst ++ = (unsigned char)acc; - acc >>= 8; - acc_len -= 8; - } -} - -/* - * Normalise an array of words to a strict 13 bits per word. Returned - * value is the resulting carry. The source (w) and destination (d) - * arrays may be identical, but shall not overlap partially. - */ -static inline uint32_t -norm13(uint32_t *d, const uint32_t *w, size_t len) -{ - size_t u; - uint32_t cc; - - cc = 0; - for (u = 0; u < len; u ++) { - int32_t z; - - z = w[u] + cc; - d[u] = z & 0x1FFF; - cc = ARSH(z, 13); - } - return cc; -} - -/* - * mul20() multiplies two 260-bit integers together. Each word must fit - * on 13 bits; source operands use 20 words, destination operand - * receives 40 words. All overlaps allowed. - * - * square20() computes the square of a 260-bit integer. Each word must - * fit on 13 bits; source operand uses 20 words, destination operand - * receives 40 words. All overlaps allowed. - */ - -#if BR_SLOW_MUL15 - -static void -mul20(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - /* - * Two-level Karatsuba: turns a 20x20 multiplication into - * nine 5x5 multiplications. We use 13-bit words but do not - * propagate carries immediately, so words may expand: - * - * - First Karatsuba decomposition turns the 20x20 mul on - * 13-bit words into three 10x10 muls, two on 13-bit words - * and one on 14-bit words. - * - * - Second Karatsuba decomposition further splits these into: - * - * * four 5x5 muls on 13-bit words - * * four 5x5 muls on 14-bit words - * * one 5x5 mul on 15-bit words - * - * Highest word value is 8191, 16382 or 32764, for 13-bit, 14-bit - * or 15-bit words, respectively. - */ - uint32_t u[45], v[45], w[90]; - uint32_t cc; - int i; - -#define ZADD(dw, d_off, s1w, s1_off, s2w, s2_off) do { \ - (dw)[5 * (d_off) + 0] = (s1w)[5 * (s1_off) + 0] \ - + (s2w)[5 * (s2_off) + 0]; \ - (dw)[5 * (d_off) + 1] = (s1w)[5 * (s1_off) + 1] \ - + (s2w)[5 * (s2_off) + 1]; \ - (dw)[5 * (d_off) + 2] = (s1w)[5 * (s1_off) + 2] \ - + (s2w)[5 * (s2_off) + 2]; \ - (dw)[5 * (d_off) + 3] = (s1w)[5 * (s1_off) + 3] \ - + (s2w)[5 * (s2_off) + 3]; \ - (dw)[5 * (d_off) + 4] = (s1w)[5 * (s1_off) + 4] \ - + (s2w)[5 * (s2_off) + 4]; \ - } while (0) - -#define ZADDT(dw, d_off, sw, s_off) do { \ - (dw)[5 * (d_off) + 0] += (sw)[5 * (s_off) + 0]; \ - (dw)[5 * (d_off) + 1] += (sw)[5 * (s_off) + 1]; \ - (dw)[5 * (d_off) + 2] += (sw)[5 * (s_off) + 2]; \ - (dw)[5 * (d_off) + 3] += (sw)[5 * (s_off) + 3]; \ - (dw)[5 * (d_off) + 4] += (sw)[5 * (s_off) + 4]; \ - } while (0) - -#define ZSUB2F(dw, d_off, s1w, s1_off, s2w, s2_off) do { \ - (dw)[5 * (d_off) + 0] -= (s1w)[5 * (s1_off) + 0] \ - + (s2w)[5 * (s2_off) + 0]; \ - (dw)[5 * (d_off) + 1] -= (s1w)[5 * (s1_off) + 1] \ - + (s2w)[5 * (s2_off) + 1]; \ - (dw)[5 * (d_off) + 2] -= (s1w)[5 * (s1_off) + 2] \ - + (s2w)[5 * (s2_off) + 2]; \ - (dw)[5 * (d_off) + 3] -= (s1w)[5 * (s1_off) + 3] \ - + (s2w)[5 * (s2_off) + 3]; \ - (dw)[5 * (d_off) + 4] -= (s1w)[5 * (s1_off) + 4] \ - + (s2w)[5 * (s2_off) + 4]; \ - } while (0) - -#define CPR1(w, cprcc) do { \ - uint32_t cprz = (w) + cprcc; \ - (w) = cprz & 0x1FFF; \ - cprcc = cprz >> 13; \ - } while (0) - -#define CPR(dw, d_off) do { \ - uint32_t cprcc; \ - cprcc = 0; \ - CPR1((dw)[(d_off) + 0], cprcc); \ - CPR1((dw)[(d_off) + 1], cprcc); \ - CPR1((dw)[(d_off) + 2], cprcc); \ - CPR1((dw)[(d_off) + 3], cprcc); \ - CPR1((dw)[(d_off) + 4], cprcc); \ - CPR1((dw)[(d_off) + 5], cprcc); \ - CPR1((dw)[(d_off) + 6], cprcc); \ - CPR1((dw)[(d_off) + 7], cprcc); \ - CPR1((dw)[(d_off) + 8], cprcc); \ - (dw)[(d_off) + 9] = cprcc; \ - } while (0) - - memcpy(u, a, 20 * sizeof *a); - ZADD(u, 4, a, 0, a, 1); - ZADD(u, 5, a, 2, a, 3); - ZADD(u, 6, a, 0, a, 2); - ZADD(u, 7, a, 1, a, 3); - ZADD(u, 8, u, 6, u, 7); - - memcpy(v, b, 20 * sizeof *b); - ZADD(v, 4, b, 0, b, 1); - ZADD(v, 5, b, 2, b, 3); - ZADD(v, 6, b, 0, b, 2); - ZADD(v, 7, b, 1, b, 3); - ZADD(v, 8, v, 6, v, 7); - - /* - * Do the eight first 8x8 muls. Source words are at most 16382 - * each, so we can add product results together "as is" in 32-bit - * words. - */ - for (i = 0; i < 40; i += 5) { - w[(i << 1) + 0] = MUL15(u[i + 0], v[i + 0]); - w[(i << 1) + 1] = MUL15(u[i + 0], v[i + 1]) - + MUL15(u[i + 1], v[i + 0]); - w[(i << 1) + 2] = MUL15(u[i + 0], v[i + 2]) - + MUL15(u[i + 1], v[i + 1]) - + MUL15(u[i + 2], v[i + 0]); - w[(i << 1) + 3] = MUL15(u[i + 0], v[i + 3]) - + MUL15(u[i + 1], v[i + 2]) - + MUL15(u[i + 2], v[i + 1]) - + MUL15(u[i + 3], v[i + 0]); - w[(i << 1) + 4] = MUL15(u[i + 0], v[i + 4]) - + MUL15(u[i + 1], v[i + 3]) - + MUL15(u[i + 2], v[i + 2]) - + MUL15(u[i + 3], v[i + 1]) - + MUL15(u[i + 4], v[i + 0]); - w[(i << 1) + 5] = MUL15(u[i + 1], v[i + 4]) - + MUL15(u[i + 2], v[i + 3]) - + MUL15(u[i + 3], v[i + 2]) - + MUL15(u[i + 4], v[i + 1]); - w[(i << 1) + 6] = MUL15(u[i + 2], v[i + 4]) - + MUL15(u[i + 3], v[i + 3]) - + MUL15(u[i + 4], v[i + 2]); - w[(i << 1) + 7] = MUL15(u[i + 3], v[i + 4]) - + MUL15(u[i + 4], v[i + 3]); - w[(i << 1) + 8] = MUL15(u[i + 4], v[i + 4]); - w[(i << 1) + 9] = 0; - } - - /* - * For the 9th multiplication, source words are up to 32764, - * so we must do some carry propagation. If we add up to - * 4 products and the carry is no more than 524224, then the - * result fits in 32 bits, and the next carry will be no more - * than 524224 (because 4*(32764^2)+524224 < 8192*524225). - * - * We thus just skip one of the products in the middle word, - * then do a carry propagation (this reduces words to 13 bits - * each, except possibly the last, which may use up to 17 bits - * or so), then add the missing product. - */ - w[80 + 0] = MUL15(u[40 + 0], v[40 + 0]); - w[80 + 1] = MUL15(u[40 + 0], v[40 + 1]) - + MUL15(u[40 + 1], v[40 + 0]); - w[80 + 2] = MUL15(u[40 + 0], v[40 + 2]) - + MUL15(u[40 + 1], v[40 + 1]) - + MUL15(u[40 + 2], v[40 + 0]); - w[80 + 3] = MUL15(u[40 + 0], v[40 + 3]) - + MUL15(u[40 + 1], v[40 + 2]) - + MUL15(u[40 + 2], v[40 + 1]) - + MUL15(u[40 + 3], v[40 + 0]); - w[80 + 4] = MUL15(u[40 + 0], v[40 + 4]) - + MUL15(u[40 + 1], v[40 + 3]) - + MUL15(u[40 + 2], v[40 + 2]) - + MUL15(u[40 + 3], v[40 + 1]); - /* + MUL15(u[40 + 4], v[40 + 0]) */ - w[80 + 5] = MUL15(u[40 + 1], v[40 + 4]) - + MUL15(u[40 + 2], v[40 + 3]) - + MUL15(u[40 + 3], v[40 + 2]) - + MUL15(u[40 + 4], v[40 + 1]); - w[80 + 6] = MUL15(u[40 + 2], v[40 + 4]) - + MUL15(u[40 + 3], v[40 + 3]) - + MUL15(u[40 + 4], v[40 + 2]); - w[80 + 7] = MUL15(u[40 + 3], v[40 + 4]) - + MUL15(u[40 + 4], v[40 + 3]); - w[80 + 8] = MUL15(u[40 + 4], v[40 + 4]); - - CPR(w, 80); - - w[80 + 4] += MUL15(u[40 + 4], v[40 + 0]); - - /* - * The products on 14-bit words in slots 6 and 7 yield values - * up to 5*(16382^2) each, and we need to subtract two such - * values from the higher word. We need the subtraction to fit - * in a _signed_ 32-bit integer, i.e. 31 bits + a sign bit. - * However, 10*(16382^2) does not fit. So we must perform a - * bit of reduction here. - */ - CPR(w, 60); - CPR(w, 70); - - /* - * Recompose results. - */ - - /* 0..1*0..1 into 0..3 */ - ZSUB2F(w, 8, w, 0, w, 2); - ZSUB2F(w, 9, w, 1, w, 3); - ZADDT(w, 1, w, 8); - ZADDT(w, 2, w, 9); - - /* 2..3*2..3 into 4..7 */ - ZSUB2F(w, 10, w, 4, w, 6); - ZSUB2F(w, 11, w, 5, w, 7); - ZADDT(w, 5, w, 10); - ZADDT(w, 6, w, 11); - - /* (0..1+2..3)*(0..1+2..3) into 12..15 */ - ZSUB2F(w, 16, w, 12, w, 14); - ZSUB2F(w, 17, w, 13, w, 15); - ZADDT(w, 13, w, 16); - ZADDT(w, 14, w, 17); - - /* first-level recomposition */ - ZSUB2F(w, 12, w, 0, w, 4); - ZSUB2F(w, 13, w, 1, w, 5); - ZSUB2F(w, 14, w, 2, w, 6); - ZSUB2F(w, 15, w, 3, w, 7); - ZADDT(w, 2, w, 12); - ZADDT(w, 3, w, 13); - ZADDT(w, 4, w, 14); - ZADDT(w, 5, w, 15); - - /* - * Perform carry propagation to bring all words down to 13 bits. - */ - cc = norm13(d, w, 40); - d[39] += (cc << 13); - -#undef ZADD -#undef ZADDT -#undef ZSUB2F -#undef CPR1 -#undef CPR -} - -static inline void -square20(uint32_t *d, const uint32_t *a) -{ - mul20(d, a, a); -} - -#else - -static void -mul20(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t t[39]; - - t[ 0] = MUL15(a[ 0], b[ 0]); - t[ 1] = MUL15(a[ 0], b[ 1]) - + MUL15(a[ 1], b[ 0]); - t[ 2] = MUL15(a[ 0], b[ 2]) - + MUL15(a[ 1], b[ 1]) - + MUL15(a[ 2], b[ 0]); - t[ 3] = MUL15(a[ 0], b[ 3]) - + MUL15(a[ 1], b[ 2]) - + MUL15(a[ 2], b[ 1]) - + MUL15(a[ 3], b[ 0]); - t[ 4] = MUL15(a[ 0], b[ 4]) - + MUL15(a[ 1], b[ 3]) - + MUL15(a[ 2], b[ 2]) - + MUL15(a[ 3], b[ 1]) - + MUL15(a[ 4], b[ 0]); - t[ 5] = MUL15(a[ 0], b[ 5]) - + MUL15(a[ 1], b[ 4]) - + MUL15(a[ 2], b[ 3]) - + MUL15(a[ 3], b[ 2]) - + MUL15(a[ 4], b[ 1]) - + MUL15(a[ 5], b[ 0]); - t[ 6] = MUL15(a[ 0], b[ 6]) - + MUL15(a[ 1], b[ 5]) - + MUL15(a[ 2], b[ 4]) - + MUL15(a[ 3], b[ 3]) - + MUL15(a[ 4], b[ 2]) - + MUL15(a[ 5], b[ 1]) - + MUL15(a[ 6], b[ 0]); - t[ 7] = MUL15(a[ 0], b[ 7]) - + MUL15(a[ 1], b[ 6]) - + MUL15(a[ 2], b[ 5]) - + MUL15(a[ 3], b[ 4]) - + MUL15(a[ 4], b[ 3]) - + MUL15(a[ 5], b[ 2]) - + MUL15(a[ 6], b[ 1]) - + MUL15(a[ 7], b[ 0]); - t[ 8] = MUL15(a[ 0], b[ 8]) - + MUL15(a[ 1], b[ 7]) - + MUL15(a[ 2], b[ 6]) - + MUL15(a[ 3], b[ 5]) - + MUL15(a[ 4], b[ 4]) - + MUL15(a[ 5], b[ 3]) - + MUL15(a[ 6], b[ 2]) - + MUL15(a[ 7], b[ 1]) - + MUL15(a[ 8], b[ 0]); - t[ 9] = MUL15(a[ 0], b[ 9]) - + MUL15(a[ 1], b[ 8]) - + MUL15(a[ 2], b[ 7]) - + MUL15(a[ 3], b[ 6]) - + MUL15(a[ 4], b[ 5]) - + MUL15(a[ 5], b[ 4]) - + MUL15(a[ 6], b[ 3]) - + MUL15(a[ 7], b[ 2]) - + MUL15(a[ 8], b[ 1]) - + MUL15(a[ 9], b[ 0]); - t[10] = MUL15(a[ 0], b[10]) - + MUL15(a[ 1], b[ 9]) - + MUL15(a[ 2], b[ 8]) - + MUL15(a[ 3], b[ 7]) - + MUL15(a[ 4], b[ 6]) - + MUL15(a[ 5], b[ 5]) - + MUL15(a[ 6], b[ 4]) - + MUL15(a[ 7], b[ 3]) - + MUL15(a[ 8], b[ 2]) - + MUL15(a[ 9], b[ 1]) - + MUL15(a[10], b[ 0]); - t[11] = MUL15(a[ 0], b[11]) - + MUL15(a[ 1], b[10]) - + MUL15(a[ 2], b[ 9]) - + MUL15(a[ 3], b[ 8]) - + MUL15(a[ 4], b[ 7]) - + MUL15(a[ 5], b[ 6]) - + MUL15(a[ 6], b[ 5]) - + MUL15(a[ 7], b[ 4]) - + MUL15(a[ 8], b[ 3]) - + MUL15(a[ 9], b[ 2]) - + MUL15(a[10], b[ 1]) - + MUL15(a[11], b[ 0]); - t[12] = MUL15(a[ 0], b[12]) - + MUL15(a[ 1], b[11]) - + MUL15(a[ 2], b[10]) - + MUL15(a[ 3], b[ 9]) - + MUL15(a[ 4], b[ 8]) - + MUL15(a[ 5], b[ 7]) - + MUL15(a[ 6], b[ 6]) - + MUL15(a[ 7], b[ 5]) - + MUL15(a[ 8], b[ 4]) - + MUL15(a[ 9], b[ 3]) - + MUL15(a[10], b[ 2]) - + MUL15(a[11], b[ 1]) - + MUL15(a[12], b[ 0]); - t[13] = MUL15(a[ 0], b[13]) - + MUL15(a[ 1], b[12]) - + MUL15(a[ 2], b[11]) - + MUL15(a[ 3], b[10]) - + MUL15(a[ 4], b[ 9]) - + MUL15(a[ 5], b[ 8]) - + MUL15(a[ 6], b[ 7]) - + MUL15(a[ 7], b[ 6]) - + MUL15(a[ 8], b[ 5]) - + MUL15(a[ 9], b[ 4]) - + MUL15(a[10], b[ 3]) - + MUL15(a[11], b[ 2]) - + MUL15(a[12], b[ 1]) - + MUL15(a[13], b[ 0]); - t[14] = MUL15(a[ 0], b[14]) - + MUL15(a[ 1], b[13]) - + MUL15(a[ 2], b[12]) - + MUL15(a[ 3], b[11]) - + MUL15(a[ 4], b[10]) - + MUL15(a[ 5], b[ 9]) - + MUL15(a[ 6], b[ 8]) - + MUL15(a[ 7], b[ 7]) - + MUL15(a[ 8], b[ 6]) - + MUL15(a[ 9], b[ 5]) - + MUL15(a[10], b[ 4]) - + MUL15(a[11], b[ 3]) - + MUL15(a[12], b[ 2]) - + MUL15(a[13], b[ 1]) - + MUL15(a[14], b[ 0]); - t[15] = MUL15(a[ 0], b[15]) - + MUL15(a[ 1], b[14]) - + MUL15(a[ 2], b[13]) - + MUL15(a[ 3], b[12]) - + MUL15(a[ 4], b[11]) - + MUL15(a[ 5], b[10]) - + MUL15(a[ 6], b[ 9]) - + MUL15(a[ 7], b[ 8]) - + MUL15(a[ 8], b[ 7]) - + MUL15(a[ 9], b[ 6]) - + MUL15(a[10], b[ 5]) - + MUL15(a[11], b[ 4]) - + MUL15(a[12], b[ 3]) - + MUL15(a[13], b[ 2]) - + MUL15(a[14], b[ 1]) - + MUL15(a[15], b[ 0]); - t[16] = MUL15(a[ 0], b[16]) - + MUL15(a[ 1], b[15]) - + MUL15(a[ 2], b[14]) - + MUL15(a[ 3], b[13]) - + MUL15(a[ 4], b[12]) - + MUL15(a[ 5], b[11]) - + MUL15(a[ 6], b[10]) - + MUL15(a[ 7], b[ 9]) - + MUL15(a[ 8], b[ 8]) - + MUL15(a[ 9], b[ 7]) - + MUL15(a[10], b[ 6]) - + MUL15(a[11], b[ 5]) - + MUL15(a[12], b[ 4]) - + MUL15(a[13], b[ 3]) - + MUL15(a[14], b[ 2]) - + MUL15(a[15], b[ 1]) - + MUL15(a[16], b[ 0]); - t[17] = MUL15(a[ 0], b[17]) - + MUL15(a[ 1], b[16]) - + MUL15(a[ 2], b[15]) - + MUL15(a[ 3], b[14]) - + MUL15(a[ 4], b[13]) - + MUL15(a[ 5], b[12]) - + MUL15(a[ 6], b[11]) - + MUL15(a[ 7], b[10]) - + MUL15(a[ 8], b[ 9]) - + MUL15(a[ 9], b[ 8]) - + MUL15(a[10], b[ 7]) - + MUL15(a[11], b[ 6]) - + MUL15(a[12], b[ 5]) - + MUL15(a[13], b[ 4]) - + MUL15(a[14], b[ 3]) - + MUL15(a[15], b[ 2]) - + MUL15(a[16], b[ 1]) - + MUL15(a[17], b[ 0]); - t[18] = MUL15(a[ 0], b[18]) - + MUL15(a[ 1], b[17]) - + MUL15(a[ 2], b[16]) - + MUL15(a[ 3], b[15]) - + MUL15(a[ 4], b[14]) - + MUL15(a[ 5], b[13]) - + MUL15(a[ 6], b[12]) - + MUL15(a[ 7], b[11]) - + MUL15(a[ 8], b[10]) - + MUL15(a[ 9], b[ 9]) - + MUL15(a[10], b[ 8]) - + MUL15(a[11], b[ 7]) - + MUL15(a[12], b[ 6]) - + MUL15(a[13], b[ 5]) - + MUL15(a[14], b[ 4]) - + MUL15(a[15], b[ 3]) - + MUL15(a[16], b[ 2]) - + MUL15(a[17], b[ 1]) - + MUL15(a[18], b[ 0]); - t[19] = MUL15(a[ 0], b[19]) - + MUL15(a[ 1], b[18]) - + MUL15(a[ 2], b[17]) - + MUL15(a[ 3], b[16]) - + MUL15(a[ 4], b[15]) - + MUL15(a[ 5], b[14]) - + MUL15(a[ 6], b[13]) - + MUL15(a[ 7], b[12]) - + MUL15(a[ 8], b[11]) - + MUL15(a[ 9], b[10]) - + MUL15(a[10], b[ 9]) - + MUL15(a[11], b[ 8]) - + MUL15(a[12], b[ 7]) - + MUL15(a[13], b[ 6]) - + MUL15(a[14], b[ 5]) - + MUL15(a[15], b[ 4]) - + MUL15(a[16], b[ 3]) - + MUL15(a[17], b[ 2]) - + MUL15(a[18], b[ 1]) - + MUL15(a[19], b[ 0]); - t[20] = MUL15(a[ 1], b[19]) - + MUL15(a[ 2], b[18]) - + MUL15(a[ 3], b[17]) - + MUL15(a[ 4], b[16]) - + MUL15(a[ 5], b[15]) - + MUL15(a[ 6], b[14]) - + MUL15(a[ 7], b[13]) - + MUL15(a[ 8], b[12]) - + MUL15(a[ 9], b[11]) - + MUL15(a[10], b[10]) - + MUL15(a[11], b[ 9]) - + MUL15(a[12], b[ 8]) - + MUL15(a[13], b[ 7]) - + MUL15(a[14], b[ 6]) - + MUL15(a[15], b[ 5]) - + MUL15(a[16], b[ 4]) - + MUL15(a[17], b[ 3]) - + MUL15(a[18], b[ 2]) - + MUL15(a[19], b[ 1]); - t[21] = MUL15(a[ 2], b[19]) - + MUL15(a[ 3], b[18]) - + MUL15(a[ 4], b[17]) - + MUL15(a[ 5], b[16]) - + MUL15(a[ 6], b[15]) - + MUL15(a[ 7], b[14]) - + MUL15(a[ 8], b[13]) - + MUL15(a[ 9], b[12]) - + MUL15(a[10], b[11]) - + MUL15(a[11], b[10]) - + MUL15(a[12], b[ 9]) - + MUL15(a[13], b[ 8]) - + MUL15(a[14], b[ 7]) - + MUL15(a[15], b[ 6]) - + MUL15(a[16], b[ 5]) - + MUL15(a[17], b[ 4]) - + MUL15(a[18], b[ 3]) - + MUL15(a[19], b[ 2]); - t[22] = MUL15(a[ 3], b[19]) - + MUL15(a[ 4], b[18]) - + MUL15(a[ 5], b[17]) - + MUL15(a[ 6], b[16]) - + MUL15(a[ 7], b[15]) - + MUL15(a[ 8], b[14]) - + MUL15(a[ 9], b[13]) - + MUL15(a[10], b[12]) - + MUL15(a[11], b[11]) - + MUL15(a[12], b[10]) - + MUL15(a[13], b[ 9]) - + MUL15(a[14], b[ 8]) - + MUL15(a[15], b[ 7]) - + MUL15(a[16], b[ 6]) - + MUL15(a[17], b[ 5]) - + MUL15(a[18], b[ 4]) - + MUL15(a[19], b[ 3]); - t[23] = MUL15(a[ 4], b[19]) - + MUL15(a[ 5], b[18]) - + MUL15(a[ 6], b[17]) - + MUL15(a[ 7], b[16]) - + MUL15(a[ 8], b[15]) - + MUL15(a[ 9], b[14]) - + MUL15(a[10], b[13]) - + MUL15(a[11], b[12]) - + MUL15(a[12], b[11]) - + MUL15(a[13], b[10]) - + MUL15(a[14], b[ 9]) - + MUL15(a[15], b[ 8]) - + MUL15(a[16], b[ 7]) - + MUL15(a[17], b[ 6]) - + MUL15(a[18], b[ 5]) - + MUL15(a[19], b[ 4]); - t[24] = MUL15(a[ 5], b[19]) - + MUL15(a[ 6], b[18]) - + MUL15(a[ 7], b[17]) - + MUL15(a[ 8], b[16]) - + MUL15(a[ 9], b[15]) - + MUL15(a[10], b[14]) - + MUL15(a[11], b[13]) - + MUL15(a[12], b[12]) - + MUL15(a[13], b[11]) - + MUL15(a[14], b[10]) - + MUL15(a[15], b[ 9]) - + MUL15(a[16], b[ 8]) - + MUL15(a[17], b[ 7]) - + MUL15(a[18], b[ 6]) - + MUL15(a[19], b[ 5]); - t[25] = MUL15(a[ 6], b[19]) - + MUL15(a[ 7], b[18]) - + MUL15(a[ 8], b[17]) - + MUL15(a[ 9], b[16]) - + MUL15(a[10], b[15]) - + MUL15(a[11], b[14]) - + MUL15(a[12], b[13]) - + MUL15(a[13], b[12]) - + MUL15(a[14], b[11]) - + MUL15(a[15], b[10]) - + MUL15(a[16], b[ 9]) - + MUL15(a[17], b[ 8]) - + MUL15(a[18], b[ 7]) - + MUL15(a[19], b[ 6]); - t[26] = MUL15(a[ 7], b[19]) - + MUL15(a[ 8], b[18]) - + MUL15(a[ 9], b[17]) - + MUL15(a[10], b[16]) - + MUL15(a[11], b[15]) - + MUL15(a[12], b[14]) - + MUL15(a[13], b[13]) - + MUL15(a[14], b[12]) - + MUL15(a[15], b[11]) - + MUL15(a[16], b[10]) - + MUL15(a[17], b[ 9]) - + MUL15(a[18], b[ 8]) - + MUL15(a[19], b[ 7]); - t[27] = MUL15(a[ 8], b[19]) - + MUL15(a[ 9], b[18]) - + MUL15(a[10], b[17]) - + MUL15(a[11], b[16]) - + MUL15(a[12], b[15]) - + MUL15(a[13], b[14]) - + MUL15(a[14], b[13]) - + MUL15(a[15], b[12]) - + MUL15(a[16], b[11]) - + MUL15(a[17], b[10]) - + MUL15(a[18], b[ 9]) - + MUL15(a[19], b[ 8]); - t[28] = MUL15(a[ 9], b[19]) - + MUL15(a[10], b[18]) - + MUL15(a[11], b[17]) - + MUL15(a[12], b[16]) - + MUL15(a[13], b[15]) - + MUL15(a[14], b[14]) - + MUL15(a[15], b[13]) - + MUL15(a[16], b[12]) - + MUL15(a[17], b[11]) - + MUL15(a[18], b[10]) - + MUL15(a[19], b[ 9]); - t[29] = MUL15(a[10], b[19]) - + MUL15(a[11], b[18]) - + MUL15(a[12], b[17]) - + MUL15(a[13], b[16]) - + MUL15(a[14], b[15]) - + MUL15(a[15], b[14]) - + MUL15(a[16], b[13]) - + MUL15(a[17], b[12]) - + MUL15(a[18], b[11]) - + MUL15(a[19], b[10]); - t[30] = MUL15(a[11], b[19]) - + MUL15(a[12], b[18]) - + MUL15(a[13], b[17]) - + MUL15(a[14], b[16]) - + MUL15(a[15], b[15]) - + MUL15(a[16], b[14]) - + MUL15(a[17], b[13]) - + MUL15(a[18], b[12]) - + MUL15(a[19], b[11]); - t[31] = MUL15(a[12], b[19]) - + MUL15(a[13], b[18]) - + MUL15(a[14], b[17]) - + MUL15(a[15], b[16]) - + MUL15(a[16], b[15]) - + MUL15(a[17], b[14]) - + MUL15(a[18], b[13]) - + MUL15(a[19], b[12]); - t[32] = MUL15(a[13], b[19]) - + MUL15(a[14], b[18]) - + MUL15(a[15], b[17]) - + MUL15(a[16], b[16]) - + MUL15(a[17], b[15]) - + MUL15(a[18], b[14]) - + MUL15(a[19], b[13]); - t[33] = MUL15(a[14], b[19]) - + MUL15(a[15], b[18]) - + MUL15(a[16], b[17]) - + MUL15(a[17], b[16]) - + MUL15(a[18], b[15]) - + MUL15(a[19], b[14]); - t[34] = MUL15(a[15], b[19]) - + MUL15(a[16], b[18]) - + MUL15(a[17], b[17]) - + MUL15(a[18], b[16]) - + MUL15(a[19], b[15]); - t[35] = MUL15(a[16], b[19]) - + MUL15(a[17], b[18]) - + MUL15(a[18], b[17]) - + MUL15(a[19], b[16]); - t[36] = MUL15(a[17], b[19]) - + MUL15(a[18], b[18]) - + MUL15(a[19], b[17]); - t[37] = MUL15(a[18], b[19]) - + MUL15(a[19], b[18]); - t[38] = MUL15(a[19], b[19]); - - d[39] = norm13(d, t, 39); -} - -static void -square20(uint32_t *d, const uint32_t *a) -{ - uint32_t t[39]; - - t[ 0] = MUL15(a[ 0], a[ 0]); - t[ 1] = ((MUL15(a[ 0], a[ 1])) << 1); - t[ 2] = MUL15(a[ 1], a[ 1]) - + ((MUL15(a[ 0], a[ 2])) << 1); - t[ 3] = ((MUL15(a[ 0], a[ 3]) - + MUL15(a[ 1], a[ 2])) << 1); - t[ 4] = MUL15(a[ 2], a[ 2]) - + ((MUL15(a[ 0], a[ 4]) - + MUL15(a[ 1], a[ 3])) << 1); - t[ 5] = ((MUL15(a[ 0], a[ 5]) - + MUL15(a[ 1], a[ 4]) - + MUL15(a[ 2], a[ 3])) << 1); - t[ 6] = MUL15(a[ 3], a[ 3]) - + ((MUL15(a[ 0], a[ 6]) - + MUL15(a[ 1], a[ 5]) - + MUL15(a[ 2], a[ 4])) << 1); - t[ 7] = ((MUL15(a[ 0], a[ 7]) - + MUL15(a[ 1], a[ 6]) - + MUL15(a[ 2], a[ 5]) - + MUL15(a[ 3], a[ 4])) << 1); - t[ 8] = MUL15(a[ 4], a[ 4]) - + ((MUL15(a[ 0], a[ 8]) - + MUL15(a[ 1], a[ 7]) - + MUL15(a[ 2], a[ 6]) - + MUL15(a[ 3], a[ 5])) << 1); - t[ 9] = ((MUL15(a[ 0], a[ 9]) - + MUL15(a[ 1], a[ 8]) - + MUL15(a[ 2], a[ 7]) - + MUL15(a[ 3], a[ 6]) - + MUL15(a[ 4], a[ 5])) << 1); - t[10] = MUL15(a[ 5], a[ 5]) - + ((MUL15(a[ 0], a[10]) - + MUL15(a[ 1], a[ 9]) - + MUL15(a[ 2], a[ 8]) - + MUL15(a[ 3], a[ 7]) - + MUL15(a[ 4], a[ 6])) << 1); - t[11] = ((MUL15(a[ 0], a[11]) - + MUL15(a[ 1], a[10]) - + MUL15(a[ 2], a[ 9]) - + MUL15(a[ 3], a[ 8]) - + MUL15(a[ 4], a[ 7]) - + MUL15(a[ 5], a[ 6])) << 1); - t[12] = MUL15(a[ 6], a[ 6]) - + ((MUL15(a[ 0], a[12]) - + MUL15(a[ 1], a[11]) - + MUL15(a[ 2], a[10]) - + MUL15(a[ 3], a[ 9]) - + MUL15(a[ 4], a[ 8]) - + MUL15(a[ 5], a[ 7])) << 1); - t[13] = ((MUL15(a[ 0], a[13]) - + MUL15(a[ 1], a[12]) - + MUL15(a[ 2], a[11]) - + MUL15(a[ 3], a[10]) - + MUL15(a[ 4], a[ 9]) - + MUL15(a[ 5], a[ 8]) - + MUL15(a[ 6], a[ 7])) << 1); - t[14] = MUL15(a[ 7], a[ 7]) - + ((MUL15(a[ 0], a[14]) - + MUL15(a[ 1], a[13]) - + MUL15(a[ 2], a[12]) - + MUL15(a[ 3], a[11]) - + MUL15(a[ 4], a[10]) - + MUL15(a[ 5], a[ 9]) - + MUL15(a[ 6], a[ 8])) << 1); - t[15] = ((MUL15(a[ 0], a[15]) - + MUL15(a[ 1], a[14]) - + MUL15(a[ 2], a[13]) - + MUL15(a[ 3], a[12]) - + MUL15(a[ 4], a[11]) - + MUL15(a[ 5], a[10]) - + MUL15(a[ 6], a[ 9]) - + MUL15(a[ 7], a[ 8])) << 1); - t[16] = MUL15(a[ 8], a[ 8]) - + ((MUL15(a[ 0], a[16]) - + MUL15(a[ 1], a[15]) - + MUL15(a[ 2], a[14]) - + MUL15(a[ 3], a[13]) - + MUL15(a[ 4], a[12]) - + MUL15(a[ 5], a[11]) - + MUL15(a[ 6], a[10]) - + MUL15(a[ 7], a[ 9])) << 1); - t[17] = ((MUL15(a[ 0], a[17]) - + MUL15(a[ 1], a[16]) - + MUL15(a[ 2], a[15]) - + MUL15(a[ 3], a[14]) - + MUL15(a[ 4], a[13]) - + MUL15(a[ 5], a[12]) - + MUL15(a[ 6], a[11]) - + MUL15(a[ 7], a[10]) - + MUL15(a[ 8], a[ 9])) << 1); - t[18] = MUL15(a[ 9], a[ 9]) - + ((MUL15(a[ 0], a[18]) - + MUL15(a[ 1], a[17]) - + MUL15(a[ 2], a[16]) - + MUL15(a[ 3], a[15]) - + MUL15(a[ 4], a[14]) - + MUL15(a[ 5], a[13]) - + MUL15(a[ 6], a[12]) - + MUL15(a[ 7], a[11]) - + MUL15(a[ 8], a[10])) << 1); - t[19] = ((MUL15(a[ 0], a[19]) - + MUL15(a[ 1], a[18]) - + MUL15(a[ 2], a[17]) - + MUL15(a[ 3], a[16]) - + MUL15(a[ 4], a[15]) - + MUL15(a[ 5], a[14]) - + MUL15(a[ 6], a[13]) - + MUL15(a[ 7], a[12]) - + MUL15(a[ 8], a[11]) - + MUL15(a[ 9], a[10])) << 1); - t[20] = MUL15(a[10], a[10]) - + ((MUL15(a[ 1], a[19]) - + MUL15(a[ 2], a[18]) - + MUL15(a[ 3], a[17]) - + MUL15(a[ 4], a[16]) - + MUL15(a[ 5], a[15]) - + MUL15(a[ 6], a[14]) - + MUL15(a[ 7], a[13]) - + MUL15(a[ 8], a[12]) - + MUL15(a[ 9], a[11])) << 1); - t[21] = ((MUL15(a[ 2], a[19]) - + MUL15(a[ 3], a[18]) - + MUL15(a[ 4], a[17]) - + MUL15(a[ 5], a[16]) - + MUL15(a[ 6], a[15]) - + MUL15(a[ 7], a[14]) - + MUL15(a[ 8], a[13]) - + MUL15(a[ 9], a[12]) - + MUL15(a[10], a[11])) << 1); - t[22] = MUL15(a[11], a[11]) - + ((MUL15(a[ 3], a[19]) - + MUL15(a[ 4], a[18]) - + MUL15(a[ 5], a[17]) - + MUL15(a[ 6], a[16]) - + MUL15(a[ 7], a[15]) - + MUL15(a[ 8], a[14]) - + MUL15(a[ 9], a[13]) - + MUL15(a[10], a[12])) << 1); - t[23] = ((MUL15(a[ 4], a[19]) - + MUL15(a[ 5], a[18]) - + MUL15(a[ 6], a[17]) - + MUL15(a[ 7], a[16]) - + MUL15(a[ 8], a[15]) - + MUL15(a[ 9], a[14]) - + MUL15(a[10], a[13]) - + MUL15(a[11], a[12])) << 1); - t[24] = MUL15(a[12], a[12]) - + ((MUL15(a[ 5], a[19]) - + MUL15(a[ 6], a[18]) - + MUL15(a[ 7], a[17]) - + MUL15(a[ 8], a[16]) - + MUL15(a[ 9], a[15]) - + MUL15(a[10], a[14]) - + MUL15(a[11], a[13])) << 1); - t[25] = ((MUL15(a[ 6], a[19]) - + MUL15(a[ 7], a[18]) - + MUL15(a[ 8], a[17]) - + MUL15(a[ 9], a[16]) - + MUL15(a[10], a[15]) - + MUL15(a[11], a[14]) - + MUL15(a[12], a[13])) << 1); - t[26] = MUL15(a[13], a[13]) - + ((MUL15(a[ 7], a[19]) - + MUL15(a[ 8], a[18]) - + MUL15(a[ 9], a[17]) - + MUL15(a[10], a[16]) - + MUL15(a[11], a[15]) - + MUL15(a[12], a[14])) << 1); - t[27] = ((MUL15(a[ 8], a[19]) - + MUL15(a[ 9], a[18]) - + MUL15(a[10], a[17]) - + MUL15(a[11], a[16]) - + MUL15(a[12], a[15]) - + MUL15(a[13], a[14])) << 1); - t[28] = MUL15(a[14], a[14]) - + ((MUL15(a[ 9], a[19]) - + MUL15(a[10], a[18]) - + MUL15(a[11], a[17]) - + MUL15(a[12], a[16]) - + MUL15(a[13], a[15])) << 1); - t[29] = ((MUL15(a[10], a[19]) - + MUL15(a[11], a[18]) - + MUL15(a[12], a[17]) - + MUL15(a[13], a[16]) - + MUL15(a[14], a[15])) << 1); - t[30] = MUL15(a[15], a[15]) - + ((MUL15(a[11], a[19]) - + MUL15(a[12], a[18]) - + MUL15(a[13], a[17]) - + MUL15(a[14], a[16])) << 1); - t[31] = ((MUL15(a[12], a[19]) - + MUL15(a[13], a[18]) - + MUL15(a[14], a[17]) - + MUL15(a[15], a[16])) << 1); - t[32] = MUL15(a[16], a[16]) - + ((MUL15(a[13], a[19]) - + MUL15(a[14], a[18]) - + MUL15(a[15], a[17])) << 1); - t[33] = ((MUL15(a[14], a[19]) - + MUL15(a[15], a[18]) - + MUL15(a[16], a[17])) << 1); - t[34] = MUL15(a[17], a[17]) - + ((MUL15(a[15], a[19]) - + MUL15(a[16], a[18])) << 1); - t[35] = ((MUL15(a[16], a[19]) - + MUL15(a[17], a[18])) << 1); - t[36] = MUL15(a[18], a[18]) - + ((MUL15(a[17], a[19])) << 1); - t[37] = ((MUL15(a[18], a[19])) << 1); - t[38] = MUL15(a[19], a[19]); - - d[39] = norm13(d, t, 39); -} - -#endif - -/* - * Perform a "final reduction" in field F255 (field for Curve25519) - * The source value must be less than twice the modulus. If the value - * is not lower than the modulus, then the modulus is subtracted and - * this function returns 1; otherwise, it leaves it untouched and it - * returns 0. - */ -static uint32_t -reduce_final_f255(uint32_t *d) -{ - uint32_t t[20]; - uint32_t cc; - int i; - - memcpy(t, d, sizeof t); - cc = 19; - for (i = 0; i < 20; i ++) { - uint32_t w; - - w = t[i] + cc; - cc = w >> 13; - t[i] = w & 0x1FFF; - } - cc = t[19] >> 8; - t[19] &= 0xFF; - CCOPY(cc, d, t, sizeof t); - return cc; -} - -static void -f255_mulgen(uint32_t *d, const uint32_t *a, const uint32_t *b, int square) -{ - uint32_t t[40], cc, w; - - /* - * Compute raw multiplication. All result words fit in 13 bits - * each; upper word (t[39]) must fit on 5 bits, since the product - * of two 256-bit integers must fit on 512 bits. - */ - if (square) { - square20(t, a); - } else { - mul20(t, a, b); - } - - /* - * Modular reduction: each high word is added where necessary. - * Since the modulus is 2^255-19 and word 20 corresponds to - * offset 20*13 = 260, word 20+k must be added to word k with - * a factor of 19*2^5 = 608. The extra bits in word 19 are also - * added that way. - */ - cc = MUL15(t[19] >> 8, 19); - t[19] &= 0xFF; - -#define MM1(x) do { \ - w = t[x] + cc + MUL15(t[(x) + 20], 608); \ - t[x] = w & 0x1FFF; \ - cc = w >> 13; \ - } while (0) - - MM1( 0); - MM1( 1); - MM1( 2); - MM1( 3); - MM1( 4); - MM1( 5); - MM1( 6); - MM1( 7); - MM1( 8); - MM1( 9); - MM1(10); - MM1(11); - MM1(12); - MM1(13); - MM1(14); - MM1(15); - MM1(16); - MM1(17); - MM1(18); - MM1(19); - -#undef MM1 - - cc = MUL15(w >> 8, 19); - t[19] &= 0xFF; - -#define MM2(x) do { \ - w = t[x] + cc; \ - d[x] = w & 0x1FFF; \ - cc = w >> 13; \ - } while (0) - - MM2( 0); - MM2( 1); - MM2( 2); - MM2( 3); - MM2( 4); - MM2( 5); - MM2( 6); - MM2( 7); - MM2( 8); - MM2( 9); - MM2(10); - MM2(11); - MM2(12); - MM2(13); - MM2(14); - MM2(15); - MM2(16); - MM2(17); - MM2(18); - MM2(19); - -#undef MM2 -} - -/* - * Perform a multiplication of two integers modulo 2^255-19. - * Operands are arrays of 20 words, each containing 13 bits of data, in - * little-endian order. Input value may be up to 2^256-1; on output, value - * fits on 256 bits and is lower than twice the modulus. - * - * f255_mul() is the general multiplication, f255_square() is specialised - * for squarings. - */ -#define f255_mul(d, a, b) f255_mulgen(d, a, b, 0) -#define f255_square(d, a) f255_mulgen(d, a, a, 1) - -/* - * Add two values in F255. Partial reduction is performed (down to less - * than twice the modulus). - */ -static void -f255_add(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - int i; - uint32_t cc, w; - - cc = 0; - for (i = 0; i < 20; i ++) { - w = a[i] + b[i] + cc; - d[i] = w & 0x1FFF; - cc = w >> 13; - } - cc = MUL15(w >> 8, 19); - d[19] &= 0xFF; - for (i = 0; i < 20; i ++) { - w = d[i] + cc; - d[i] = w & 0x1FFF; - cc = w >> 13; - } -} - -/* - * Subtract one value from another in F255. Partial reduction is - * performed (down to less than twice the modulus). - */ -static void -f255_sub(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - /* - * We actually compute a - b + 2*p, so that the final value is - * necessarily positive. - */ - int i; - uint32_t cc, w; - - cc = (uint32_t)-38; - for (i = 0; i < 20; i ++) { - w = a[i] - b[i] + cc; - d[i] = w & 0x1FFF; - cc = ARSH(w, 13); - } - cc = MUL15((w + 0x200) >> 8, 19); - d[19] &= 0xFF; - for (i = 0; i < 20; i ++) { - w = d[i] + cc; - d[i] = w & 0x1FFF; - cc = w >> 13; - } -} - -/* - * Multiply an integer by the 'A24' constant (121665). Partial reduction - * is performed (down to less than twice the modulus). - */ -static void -f255_mul_a24(uint32_t *d, const uint32_t *a) -{ - int i; - uint32_t cc, w; - - cc = 0; - for (i = 0; i < 20; i ++) { - w = MUL15(a[i], 121665) + cc; - d[i] = w & 0x1FFF; - cc = w >> 13; - } - cc = MUL15(w >> 8, 19); - d[19] &= 0xFF; - for (i = 0; i < 20; i ++) { - w = d[i] + cc; - d[i] = w & 0x1FFF; - cc = w >> 13; - } -} - -static const unsigned char GEN[] = { - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const unsigned char ORDER[] = { - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -}; - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return GEN; -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return ORDER; -} - -static size_t -api_xoff(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return 0; -} - -static void -cswap(uint32_t *a, uint32_t *b, uint32_t ctl) -{ - int i; - - ctl = -ctl; - for (i = 0; i < 20; i ++) { - uint32_t aw, bw, tw; - - aw = a[i]; - bw = b[i]; - tw = ctl & (aw ^ bw); - a[i] = aw ^ tw; - b[i] = bw ^ tw; - } -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *kb, size_t kblen, int curve) -{ - uint32_t x1[20], x2[20], x3[20], z2[20], z3[20]; - uint32_t a[20], aa[20], b[20], bb[20]; - uint32_t c[20], d[20], e[20], da[20], cb[20]; - unsigned char k[32]; - uint32_t swap; - int i; - - (void)curve; - - /* - * Points are encoded over exactly 32 bytes. Multipliers must fit - * in 32 bytes as well. - * RFC 7748 mandates that the high bit of the last point byte must - * be ignored/cleared. - */ - if (Glen != 32 || kblen > 32) { - return 0; - } - G[31] &= 0x7F; - - /* - * Initialise variables x1, x2, z2, x3 and z3. We set all of them - * into Montgomery representation. - */ - x1[19] = le8_to_le13(x1, G, 32); - memcpy(x3, x1, sizeof x1); - memset(z2, 0, sizeof z2); - memset(x2, 0, sizeof x2); - x2[0] = 1; - memset(z3, 0, sizeof z3); - z3[0] = 1; - - memset(k, 0, (sizeof k) - kblen); - memcpy(k + (sizeof k) - kblen, kb, kblen); - k[31] &= 0xF8; - k[0] &= 0x7F; - k[0] |= 0x40; - - /* obsolete - print_int("x1", x1); - */ - - swap = 0; - for (i = 254; i >= 0; i --) { - uint32_t kt; - - kt = (k[31 - (i >> 3)] >> (i & 7)) & 1; - swap ^= kt; - cswap(x2, x3, swap); - cswap(z2, z3, swap); - swap = kt; - - /* obsolete - print_int("x2", x2); - print_int("z2", z2); - print_int("x3", x3); - print_int("z3", z3); - */ - - f255_add(a, x2, z2); - f255_square(aa, a); - f255_sub(b, x2, z2); - f255_square(bb, b); - f255_sub(e, aa, bb); - f255_add(c, x3, z3); - f255_sub(d, x3, z3); - f255_mul(da, d, a); - f255_mul(cb, c, b); - - /* obsolete - print_int("a ", a); - print_int("aa", aa); - print_int("b ", b); - print_int("bb", bb); - print_int("e ", e); - print_int("c ", c); - print_int("d ", d); - print_int("da", da); - print_int("cb", cb); - */ - - f255_add(x3, da, cb); - f255_square(x3, x3); - f255_sub(z3, da, cb); - f255_square(z3, z3); - f255_mul(z3, z3, x1); - f255_mul(x2, aa, bb); - f255_mul_a24(z2, e); - f255_add(z2, z2, aa); - f255_mul(z2, e, z2); - - /* obsolete - print_int("x2", x2); - print_int("z2", z2); - print_int("x3", x3); - print_int("z3", z3); - */ - } - cswap(x2, x3, swap); - cswap(z2, z3, swap); - - /* - * Inverse z2 with a modular exponentiation. This is a simple - * square-and-multiply algorithm; we mutualise most non-squarings - * since the exponent contains almost only ones. - */ - memcpy(a, z2, sizeof z2); - for (i = 0; i < 15; i ++) { - f255_square(a, a); - f255_mul(a, a, z2); - } - memcpy(b, a, sizeof a); - for (i = 0; i < 14; i ++) { - int j; - - for (j = 0; j < 16; j ++) { - f255_square(b, b); - } - f255_mul(b, b, a); - } - for (i = 14; i >= 0; i --) { - f255_square(b, b); - if ((0xFFEB >> i) & 1) { - f255_mul(b, z2, b); - } - } - f255_mul(x2, x2, b); - reduce_final_f255(x2); - le13_to_le8(G, 32, x2); - return 1; -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - /* - * We don't implement this method, since it is used for ECDSA - * only, and there is no ECDSA over Curve25519 (which instead - * uses EdDSA). - */ - (void)A; - (void)B; - (void)len; - (void)x; - (void)xlen; - (void)y; - (void)ylen; - (void)curve; - return 0; -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_c25519_m15 = { - (uint32_t)0x20000000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; diff --git a/third_party/bearssl/src/ec_default.c b/third_party/bearssl/src/ec_default.c index 7bb6e0c7f..24cc234a3 100644 --- a/third_party/bearssl/src/ec_default.c +++ b/third_party/bearssl/src/ec_default.c @@ -28,9 +28,5 @@ const br_ec_impl * br_ec_get_default(void) { -#if BR_LOMUL - return &br_ec_all_m15; -#else return &br_ec_all_m31; -#endif } diff --git a/third_party/bearssl/src/ec_p256_m15.c b/third_party/bearssl/src/ec_p256_m15.c deleted file mode 100644 index 05800d87f..000000000 --- a/third_party/bearssl/src/ec_p256_m15.c +++ /dev/null @@ -1,2124 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * If BR_NO_ARITH_SHIFT is undefined, or defined to 0, then we _assume_ - * that right-shifting a signed negative integer copies the sign bit - * (arithmetic right-shift). This is "implementation-defined behaviour", - * i.e. it is not undefined, but it may differ between compilers. Each - * compiler is supposed to document its behaviour in that respect. GCC - * explicitly defines that an arithmetic right shift is used. We expect - * all other compilers to do the same, because underlying CPU offer an - * arithmetic right shift opcode that could not be used otherwise. - */ -#if BR_NO_ARITH_SHIFT -#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ - | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) -#else -#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) -#endif - -/* - * Convert an integer from unsigned big-endian encoding to a sequence of - * 13-bit words in little-endian order. The final "partial" word is - * returned. - */ -static uint32_t -be8_to_le13(uint32_t *dst, const unsigned char *src, size_t len) -{ - uint32_t acc; - int acc_len; - - acc = 0; - acc_len = 0; - while (len -- > 0) { - acc |= (uint32_t)src[len] << acc_len; - acc_len += 8; - if (acc_len >= 13) { - *dst ++ = acc & 0x1FFF; - acc >>= 13; - acc_len -= 13; - } - } - return acc; -} - -/* - * Convert an integer (13-bit words, little-endian) to unsigned - * big-endian encoding. The total encoding length is provided; all - * the destination bytes will be filled. - */ -static void -le13_to_be8(unsigned char *dst, size_t len, const uint32_t *src) -{ - uint32_t acc; - int acc_len; - - acc = 0; - acc_len = 0; - while (len -- > 0) { - if (acc_len < 8) { - acc |= (*src ++) << acc_len; - acc_len += 13; - } - dst[len] = (unsigned char)acc; - acc >>= 8; - acc_len -= 8; - } -} - -/* - * Normalise an array of words to a strict 13 bits per word. Returned - * value is the resulting carry. The source (w) and destination (d) - * arrays may be identical, but shall not overlap partially. - */ -static inline uint32_t -norm13(uint32_t *d, const uint32_t *w, size_t len) -{ - size_t u; - uint32_t cc; - - cc = 0; - for (u = 0; u < len; u ++) { - int32_t z; - - z = w[u] + cc; - d[u] = z & 0x1FFF; - cc = ARSH(z, 13); - } - return cc; -} - -/* - * mul20() multiplies two 260-bit integers together. Each word must fit - * on 13 bits; source operands use 20 words, destination operand - * receives 40 words. All overlaps allowed. - * - * square20() computes the square of a 260-bit integer. Each word must - * fit on 13 bits; source operand uses 20 words, destination operand - * receives 40 words. All overlaps allowed. - */ - -#if BR_SLOW_MUL15 - -static void -mul20(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - /* - * Two-level Karatsuba: turns a 20x20 multiplication into - * nine 5x5 multiplications. We use 13-bit words but do not - * propagate carries immediately, so words may expand: - * - * - First Karatsuba decomposition turns the 20x20 mul on - * 13-bit words into three 10x10 muls, two on 13-bit words - * and one on 14-bit words. - * - * - Second Karatsuba decomposition further splits these into: - * - * * four 5x5 muls on 13-bit words - * * four 5x5 muls on 14-bit words - * * one 5x5 mul on 15-bit words - * - * Highest word value is 8191, 16382 or 32764, for 13-bit, 14-bit - * or 15-bit words, respectively. - */ - uint32_t u[45], v[45], w[90]; - uint32_t cc; - int i; - -#define ZADD(dw, d_off, s1w, s1_off, s2w, s2_off) do { \ - (dw)[5 * (d_off) + 0] = (s1w)[5 * (s1_off) + 0] \ - + (s2w)[5 * (s2_off) + 0]; \ - (dw)[5 * (d_off) + 1] = (s1w)[5 * (s1_off) + 1] \ - + (s2w)[5 * (s2_off) + 1]; \ - (dw)[5 * (d_off) + 2] = (s1w)[5 * (s1_off) + 2] \ - + (s2w)[5 * (s2_off) + 2]; \ - (dw)[5 * (d_off) + 3] = (s1w)[5 * (s1_off) + 3] \ - + (s2w)[5 * (s2_off) + 3]; \ - (dw)[5 * (d_off) + 4] = (s1w)[5 * (s1_off) + 4] \ - + (s2w)[5 * (s2_off) + 4]; \ - } while (0) - -#define ZADDT(dw, d_off, sw, s_off) do { \ - (dw)[5 * (d_off) + 0] += (sw)[5 * (s_off) + 0]; \ - (dw)[5 * (d_off) + 1] += (sw)[5 * (s_off) + 1]; \ - (dw)[5 * (d_off) + 2] += (sw)[5 * (s_off) + 2]; \ - (dw)[5 * (d_off) + 3] += (sw)[5 * (s_off) + 3]; \ - (dw)[5 * (d_off) + 4] += (sw)[5 * (s_off) + 4]; \ - } while (0) - -#define ZSUB2F(dw, d_off, s1w, s1_off, s2w, s2_off) do { \ - (dw)[5 * (d_off) + 0] -= (s1w)[5 * (s1_off) + 0] \ - + (s2w)[5 * (s2_off) + 0]; \ - (dw)[5 * (d_off) + 1] -= (s1w)[5 * (s1_off) + 1] \ - + (s2w)[5 * (s2_off) + 1]; \ - (dw)[5 * (d_off) + 2] -= (s1w)[5 * (s1_off) + 2] \ - + (s2w)[5 * (s2_off) + 2]; \ - (dw)[5 * (d_off) + 3] -= (s1w)[5 * (s1_off) + 3] \ - + (s2w)[5 * (s2_off) + 3]; \ - (dw)[5 * (d_off) + 4] -= (s1w)[5 * (s1_off) + 4] \ - + (s2w)[5 * (s2_off) + 4]; \ - } while (0) - -#define CPR1(w, cprcc) do { \ - uint32_t cprz = (w) + cprcc; \ - (w) = cprz & 0x1FFF; \ - cprcc = cprz >> 13; \ - } while (0) - -#define CPR(dw, d_off) do { \ - uint32_t cprcc; \ - cprcc = 0; \ - CPR1((dw)[(d_off) + 0], cprcc); \ - CPR1((dw)[(d_off) + 1], cprcc); \ - CPR1((dw)[(d_off) + 2], cprcc); \ - CPR1((dw)[(d_off) + 3], cprcc); \ - CPR1((dw)[(d_off) + 4], cprcc); \ - CPR1((dw)[(d_off) + 5], cprcc); \ - CPR1((dw)[(d_off) + 6], cprcc); \ - CPR1((dw)[(d_off) + 7], cprcc); \ - CPR1((dw)[(d_off) + 8], cprcc); \ - (dw)[(d_off) + 9] = cprcc; \ - } while (0) - - memcpy(u, a, 20 * sizeof *a); - ZADD(u, 4, a, 0, a, 1); - ZADD(u, 5, a, 2, a, 3); - ZADD(u, 6, a, 0, a, 2); - ZADD(u, 7, a, 1, a, 3); - ZADD(u, 8, u, 6, u, 7); - - memcpy(v, b, 20 * sizeof *b); - ZADD(v, 4, b, 0, b, 1); - ZADD(v, 5, b, 2, b, 3); - ZADD(v, 6, b, 0, b, 2); - ZADD(v, 7, b, 1, b, 3); - ZADD(v, 8, v, 6, v, 7); - - /* - * Do the eight first 8x8 muls. Source words are at most 16382 - * each, so we can add product results together "as is" in 32-bit - * words. - */ - for (i = 0; i < 40; i += 5) { - w[(i << 1) + 0] = MUL15(u[i + 0], v[i + 0]); - w[(i << 1) + 1] = MUL15(u[i + 0], v[i + 1]) - + MUL15(u[i + 1], v[i + 0]); - w[(i << 1) + 2] = MUL15(u[i + 0], v[i + 2]) - + MUL15(u[i + 1], v[i + 1]) - + MUL15(u[i + 2], v[i + 0]); - w[(i << 1) + 3] = MUL15(u[i + 0], v[i + 3]) - + MUL15(u[i + 1], v[i + 2]) - + MUL15(u[i + 2], v[i + 1]) - + MUL15(u[i + 3], v[i + 0]); - w[(i << 1) + 4] = MUL15(u[i + 0], v[i + 4]) - + MUL15(u[i + 1], v[i + 3]) - + MUL15(u[i + 2], v[i + 2]) - + MUL15(u[i + 3], v[i + 1]) - + MUL15(u[i + 4], v[i + 0]); - w[(i << 1) + 5] = MUL15(u[i + 1], v[i + 4]) - + MUL15(u[i + 2], v[i + 3]) - + MUL15(u[i + 3], v[i + 2]) - + MUL15(u[i + 4], v[i + 1]); - w[(i << 1) + 6] = MUL15(u[i + 2], v[i + 4]) - + MUL15(u[i + 3], v[i + 3]) - + MUL15(u[i + 4], v[i + 2]); - w[(i << 1) + 7] = MUL15(u[i + 3], v[i + 4]) - + MUL15(u[i + 4], v[i + 3]); - w[(i << 1) + 8] = MUL15(u[i + 4], v[i + 4]); - w[(i << 1) + 9] = 0; - } - - /* - * For the 9th multiplication, source words are up to 32764, - * so we must do some carry propagation. If we add up to - * 4 products and the carry is no more than 524224, then the - * result fits in 32 bits, and the next carry will be no more - * than 524224 (because 4*(32764^2)+524224 < 8192*524225). - * - * We thus just skip one of the products in the middle word, - * then do a carry propagation (this reduces words to 13 bits - * each, except possibly the last, which may use up to 17 bits - * or so), then add the missing product. - */ - w[80 + 0] = MUL15(u[40 + 0], v[40 + 0]); - w[80 + 1] = MUL15(u[40 + 0], v[40 + 1]) - + MUL15(u[40 + 1], v[40 + 0]); - w[80 + 2] = MUL15(u[40 + 0], v[40 + 2]) - + MUL15(u[40 + 1], v[40 + 1]) - + MUL15(u[40 + 2], v[40 + 0]); - w[80 + 3] = MUL15(u[40 + 0], v[40 + 3]) - + MUL15(u[40 + 1], v[40 + 2]) - + MUL15(u[40 + 2], v[40 + 1]) - + MUL15(u[40 + 3], v[40 + 0]); - w[80 + 4] = MUL15(u[40 + 0], v[40 + 4]) - + MUL15(u[40 + 1], v[40 + 3]) - + MUL15(u[40 + 2], v[40 + 2]) - + MUL15(u[40 + 3], v[40 + 1]); - /* + MUL15(u[40 + 4], v[40 + 0]) */ - w[80 + 5] = MUL15(u[40 + 1], v[40 + 4]) - + MUL15(u[40 + 2], v[40 + 3]) - + MUL15(u[40 + 3], v[40 + 2]) - + MUL15(u[40 + 4], v[40 + 1]); - w[80 + 6] = MUL15(u[40 + 2], v[40 + 4]) - + MUL15(u[40 + 3], v[40 + 3]) - + MUL15(u[40 + 4], v[40 + 2]); - w[80 + 7] = MUL15(u[40 + 3], v[40 + 4]) - + MUL15(u[40 + 4], v[40 + 3]); - w[80 + 8] = MUL15(u[40 + 4], v[40 + 4]); - - CPR(w, 80); - - w[80 + 4] += MUL15(u[40 + 4], v[40 + 0]); - - /* - * The products on 14-bit words in slots 6 and 7 yield values - * up to 5*(16382^2) each, and we need to subtract two such - * values from the higher word. We need the subtraction to fit - * in a _signed_ 32-bit integer, i.e. 31 bits + a sign bit. - * However, 10*(16382^2) does not fit. So we must perform a - * bit of reduction here. - */ - CPR(w, 60); - CPR(w, 70); - - /* - * Recompose results. - */ - - /* 0..1*0..1 into 0..3 */ - ZSUB2F(w, 8, w, 0, w, 2); - ZSUB2F(w, 9, w, 1, w, 3); - ZADDT(w, 1, w, 8); - ZADDT(w, 2, w, 9); - - /* 2..3*2..3 into 4..7 */ - ZSUB2F(w, 10, w, 4, w, 6); - ZSUB2F(w, 11, w, 5, w, 7); - ZADDT(w, 5, w, 10); - ZADDT(w, 6, w, 11); - - /* (0..1+2..3)*(0..1+2..3) into 12..15 */ - ZSUB2F(w, 16, w, 12, w, 14); - ZSUB2F(w, 17, w, 13, w, 15); - ZADDT(w, 13, w, 16); - ZADDT(w, 14, w, 17); - - /* first-level recomposition */ - ZSUB2F(w, 12, w, 0, w, 4); - ZSUB2F(w, 13, w, 1, w, 5); - ZSUB2F(w, 14, w, 2, w, 6); - ZSUB2F(w, 15, w, 3, w, 7); - ZADDT(w, 2, w, 12); - ZADDT(w, 3, w, 13); - ZADDT(w, 4, w, 14); - ZADDT(w, 5, w, 15); - - /* - * Perform carry propagation to bring all words down to 13 bits. - */ - cc = norm13(d, w, 40); - d[39] += (cc << 13); - -#undef ZADD -#undef ZADDT -#undef ZSUB2F -#undef CPR1 -#undef CPR -} - -static inline void -square20(uint32_t *d, const uint32_t *a) -{ - mul20(d, a, a); -} - -#else - -static void -mul20(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t t[39]; - - t[ 0] = MUL15(a[ 0], b[ 0]); - t[ 1] = MUL15(a[ 0], b[ 1]) - + MUL15(a[ 1], b[ 0]); - t[ 2] = MUL15(a[ 0], b[ 2]) - + MUL15(a[ 1], b[ 1]) - + MUL15(a[ 2], b[ 0]); - t[ 3] = MUL15(a[ 0], b[ 3]) - + MUL15(a[ 1], b[ 2]) - + MUL15(a[ 2], b[ 1]) - + MUL15(a[ 3], b[ 0]); - t[ 4] = MUL15(a[ 0], b[ 4]) - + MUL15(a[ 1], b[ 3]) - + MUL15(a[ 2], b[ 2]) - + MUL15(a[ 3], b[ 1]) - + MUL15(a[ 4], b[ 0]); - t[ 5] = MUL15(a[ 0], b[ 5]) - + MUL15(a[ 1], b[ 4]) - + MUL15(a[ 2], b[ 3]) - + MUL15(a[ 3], b[ 2]) - + MUL15(a[ 4], b[ 1]) - + MUL15(a[ 5], b[ 0]); - t[ 6] = MUL15(a[ 0], b[ 6]) - + MUL15(a[ 1], b[ 5]) - + MUL15(a[ 2], b[ 4]) - + MUL15(a[ 3], b[ 3]) - + MUL15(a[ 4], b[ 2]) - + MUL15(a[ 5], b[ 1]) - + MUL15(a[ 6], b[ 0]); - t[ 7] = MUL15(a[ 0], b[ 7]) - + MUL15(a[ 1], b[ 6]) - + MUL15(a[ 2], b[ 5]) - + MUL15(a[ 3], b[ 4]) - + MUL15(a[ 4], b[ 3]) - + MUL15(a[ 5], b[ 2]) - + MUL15(a[ 6], b[ 1]) - + MUL15(a[ 7], b[ 0]); - t[ 8] = MUL15(a[ 0], b[ 8]) - + MUL15(a[ 1], b[ 7]) - + MUL15(a[ 2], b[ 6]) - + MUL15(a[ 3], b[ 5]) - + MUL15(a[ 4], b[ 4]) - + MUL15(a[ 5], b[ 3]) - + MUL15(a[ 6], b[ 2]) - + MUL15(a[ 7], b[ 1]) - + MUL15(a[ 8], b[ 0]); - t[ 9] = MUL15(a[ 0], b[ 9]) - + MUL15(a[ 1], b[ 8]) - + MUL15(a[ 2], b[ 7]) - + MUL15(a[ 3], b[ 6]) - + MUL15(a[ 4], b[ 5]) - + MUL15(a[ 5], b[ 4]) - + MUL15(a[ 6], b[ 3]) - + MUL15(a[ 7], b[ 2]) - + MUL15(a[ 8], b[ 1]) - + MUL15(a[ 9], b[ 0]); - t[10] = MUL15(a[ 0], b[10]) - + MUL15(a[ 1], b[ 9]) - + MUL15(a[ 2], b[ 8]) - + MUL15(a[ 3], b[ 7]) - + MUL15(a[ 4], b[ 6]) - + MUL15(a[ 5], b[ 5]) - + MUL15(a[ 6], b[ 4]) - + MUL15(a[ 7], b[ 3]) - + MUL15(a[ 8], b[ 2]) - + MUL15(a[ 9], b[ 1]) - + MUL15(a[10], b[ 0]); - t[11] = MUL15(a[ 0], b[11]) - + MUL15(a[ 1], b[10]) - + MUL15(a[ 2], b[ 9]) - + MUL15(a[ 3], b[ 8]) - + MUL15(a[ 4], b[ 7]) - + MUL15(a[ 5], b[ 6]) - + MUL15(a[ 6], b[ 5]) - + MUL15(a[ 7], b[ 4]) - + MUL15(a[ 8], b[ 3]) - + MUL15(a[ 9], b[ 2]) - + MUL15(a[10], b[ 1]) - + MUL15(a[11], b[ 0]); - t[12] = MUL15(a[ 0], b[12]) - + MUL15(a[ 1], b[11]) - + MUL15(a[ 2], b[10]) - + MUL15(a[ 3], b[ 9]) - + MUL15(a[ 4], b[ 8]) - + MUL15(a[ 5], b[ 7]) - + MUL15(a[ 6], b[ 6]) - + MUL15(a[ 7], b[ 5]) - + MUL15(a[ 8], b[ 4]) - + MUL15(a[ 9], b[ 3]) - + MUL15(a[10], b[ 2]) - + MUL15(a[11], b[ 1]) - + MUL15(a[12], b[ 0]); - t[13] = MUL15(a[ 0], b[13]) - + MUL15(a[ 1], b[12]) - + MUL15(a[ 2], b[11]) - + MUL15(a[ 3], b[10]) - + MUL15(a[ 4], b[ 9]) - + MUL15(a[ 5], b[ 8]) - + MUL15(a[ 6], b[ 7]) - + MUL15(a[ 7], b[ 6]) - + MUL15(a[ 8], b[ 5]) - + MUL15(a[ 9], b[ 4]) - + MUL15(a[10], b[ 3]) - + MUL15(a[11], b[ 2]) - + MUL15(a[12], b[ 1]) - + MUL15(a[13], b[ 0]); - t[14] = MUL15(a[ 0], b[14]) - + MUL15(a[ 1], b[13]) - + MUL15(a[ 2], b[12]) - + MUL15(a[ 3], b[11]) - + MUL15(a[ 4], b[10]) - + MUL15(a[ 5], b[ 9]) - + MUL15(a[ 6], b[ 8]) - + MUL15(a[ 7], b[ 7]) - + MUL15(a[ 8], b[ 6]) - + MUL15(a[ 9], b[ 5]) - + MUL15(a[10], b[ 4]) - + MUL15(a[11], b[ 3]) - + MUL15(a[12], b[ 2]) - + MUL15(a[13], b[ 1]) - + MUL15(a[14], b[ 0]); - t[15] = MUL15(a[ 0], b[15]) - + MUL15(a[ 1], b[14]) - + MUL15(a[ 2], b[13]) - + MUL15(a[ 3], b[12]) - + MUL15(a[ 4], b[11]) - + MUL15(a[ 5], b[10]) - + MUL15(a[ 6], b[ 9]) - + MUL15(a[ 7], b[ 8]) - + MUL15(a[ 8], b[ 7]) - + MUL15(a[ 9], b[ 6]) - + MUL15(a[10], b[ 5]) - + MUL15(a[11], b[ 4]) - + MUL15(a[12], b[ 3]) - + MUL15(a[13], b[ 2]) - + MUL15(a[14], b[ 1]) - + MUL15(a[15], b[ 0]); - t[16] = MUL15(a[ 0], b[16]) - + MUL15(a[ 1], b[15]) - + MUL15(a[ 2], b[14]) - + MUL15(a[ 3], b[13]) - + MUL15(a[ 4], b[12]) - + MUL15(a[ 5], b[11]) - + MUL15(a[ 6], b[10]) - + MUL15(a[ 7], b[ 9]) - + MUL15(a[ 8], b[ 8]) - + MUL15(a[ 9], b[ 7]) - + MUL15(a[10], b[ 6]) - + MUL15(a[11], b[ 5]) - + MUL15(a[12], b[ 4]) - + MUL15(a[13], b[ 3]) - + MUL15(a[14], b[ 2]) - + MUL15(a[15], b[ 1]) - + MUL15(a[16], b[ 0]); - t[17] = MUL15(a[ 0], b[17]) - + MUL15(a[ 1], b[16]) - + MUL15(a[ 2], b[15]) - + MUL15(a[ 3], b[14]) - + MUL15(a[ 4], b[13]) - + MUL15(a[ 5], b[12]) - + MUL15(a[ 6], b[11]) - + MUL15(a[ 7], b[10]) - + MUL15(a[ 8], b[ 9]) - + MUL15(a[ 9], b[ 8]) - + MUL15(a[10], b[ 7]) - + MUL15(a[11], b[ 6]) - + MUL15(a[12], b[ 5]) - + MUL15(a[13], b[ 4]) - + MUL15(a[14], b[ 3]) - + MUL15(a[15], b[ 2]) - + MUL15(a[16], b[ 1]) - + MUL15(a[17], b[ 0]); - t[18] = MUL15(a[ 0], b[18]) - + MUL15(a[ 1], b[17]) - + MUL15(a[ 2], b[16]) - + MUL15(a[ 3], b[15]) - + MUL15(a[ 4], b[14]) - + MUL15(a[ 5], b[13]) - + MUL15(a[ 6], b[12]) - + MUL15(a[ 7], b[11]) - + MUL15(a[ 8], b[10]) - + MUL15(a[ 9], b[ 9]) - + MUL15(a[10], b[ 8]) - + MUL15(a[11], b[ 7]) - + MUL15(a[12], b[ 6]) - + MUL15(a[13], b[ 5]) - + MUL15(a[14], b[ 4]) - + MUL15(a[15], b[ 3]) - + MUL15(a[16], b[ 2]) - + MUL15(a[17], b[ 1]) - + MUL15(a[18], b[ 0]); - t[19] = MUL15(a[ 0], b[19]) - + MUL15(a[ 1], b[18]) - + MUL15(a[ 2], b[17]) - + MUL15(a[ 3], b[16]) - + MUL15(a[ 4], b[15]) - + MUL15(a[ 5], b[14]) - + MUL15(a[ 6], b[13]) - + MUL15(a[ 7], b[12]) - + MUL15(a[ 8], b[11]) - + MUL15(a[ 9], b[10]) - + MUL15(a[10], b[ 9]) - + MUL15(a[11], b[ 8]) - + MUL15(a[12], b[ 7]) - + MUL15(a[13], b[ 6]) - + MUL15(a[14], b[ 5]) - + MUL15(a[15], b[ 4]) - + MUL15(a[16], b[ 3]) - + MUL15(a[17], b[ 2]) - + MUL15(a[18], b[ 1]) - + MUL15(a[19], b[ 0]); - t[20] = MUL15(a[ 1], b[19]) - + MUL15(a[ 2], b[18]) - + MUL15(a[ 3], b[17]) - + MUL15(a[ 4], b[16]) - + MUL15(a[ 5], b[15]) - + MUL15(a[ 6], b[14]) - + MUL15(a[ 7], b[13]) - + MUL15(a[ 8], b[12]) - + MUL15(a[ 9], b[11]) - + MUL15(a[10], b[10]) - + MUL15(a[11], b[ 9]) - + MUL15(a[12], b[ 8]) - + MUL15(a[13], b[ 7]) - + MUL15(a[14], b[ 6]) - + MUL15(a[15], b[ 5]) - + MUL15(a[16], b[ 4]) - + MUL15(a[17], b[ 3]) - + MUL15(a[18], b[ 2]) - + MUL15(a[19], b[ 1]); - t[21] = MUL15(a[ 2], b[19]) - + MUL15(a[ 3], b[18]) - + MUL15(a[ 4], b[17]) - + MUL15(a[ 5], b[16]) - + MUL15(a[ 6], b[15]) - + MUL15(a[ 7], b[14]) - + MUL15(a[ 8], b[13]) - + MUL15(a[ 9], b[12]) - + MUL15(a[10], b[11]) - + MUL15(a[11], b[10]) - + MUL15(a[12], b[ 9]) - + MUL15(a[13], b[ 8]) - + MUL15(a[14], b[ 7]) - + MUL15(a[15], b[ 6]) - + MUL15(a[16], b[ 5]) - + MUL15(a[17], b[ 4]) - + MUL15(a[18], b[ 3]) - + MUL15(a[19], b[ 2]); - t[22] = MUL15(a[ 3], b[19]) - + MUL15(a[ 4], b[18]) - + MUL15(a[ 5], b[17]) - + MUL15(a[ 6], b[16]) - + MUL15(a[ 7], b[15]) - + MUL15(a[ 8], b[14]) - + MUL15(a[ 9], b[13]) - + MUL15(a[10], b[12]) - + MUL15(a[11], b[11]) - + MUL15(a[12], b[10]) - + MUL15(a[13], b[ 9]) - + MUL15(a[14], b[ 8]) - + MUL15(a[15], b[ 7]) - + MUL15(a[16], b[ 6]) - + MUL15(a[17], b[ 5]) - + MUL15(a[18], b[ 4]) - + MUL15(a[19], b[ 3]); - t[23] = MUL15(a[ 4], b[19]) - + MUL15(a[ 5], b[18]) - + MUL15(a[ 6], b[17]) - + MUL15(a[ 7], b[16]) - + MUL15(a[ 8], b[15]) - + MUL15(a[ 9], b[14]) - + MUL15(a[10], b[13]) - + MUL15(a[11], b[12]) - + MUL15(a[12], b[11]) - + MUL15(a[13], b[10]) - + MUL15(a[14], b[ 9]) - + MUL15(a[15], b[ 8]) - + MUL15(a[16], b[ 7]) - + MUL15(a[17], b[ 6]) - + MUL15(a[18], b[ 5]) - + MUL15(a[19], b[ 4]); - t[24] = MUL15(a[ 5], b[19]) - + MUL15(a[ 6], b[18]) - + MUL15(a[ 7], b[17]) - + MUL15(a[ 8], b[16]) - + MUL15(a[ 9], b[15]) - + MUL15(a[10], b[14]) - + MUL15(a[11], b[13]) - + MUL15(a[12], b[12]) - + MUL15(a[13], b[11]) - + MUL15(a[14], b[10]) - + MUL15(a[15], b[ 9]) - + MUL15(a[16], b[ 8]) - + MUL15(a[17], b[ 7]) - + MUL15(a[18], b[ 6]) - + MUL15(a[19], b[ 5]); - t[25] = MUL15(a[ 6], b[19]) - + MUL15(a[ 7], b[18]) - + MUL15(a[ 8], b[17]) - + MUL15(a[ 9], b[16]) - + MUL15(a[10], b[15]) - + MUL15(a[11], b[14]) - + MUL15(a[12], b[13]) - + MUL15(a[13], b[12]) - + MUL15(a[14], b[11]) - + MUL15(a[15], b[10]) - + MUL15(a[16], b[ 9]) - + MUL15(a[17], b[ 8]) - + MUL15(a[18], b[ 7]) - + MUL15(a[19], b[ 6]); - t[26] = MUL15(a[ 7], b[19]) - + MUL15(a[ 8], b[18]) - + MUL15(a[ 9], b[17]) - + MUL15(a[10], b[16]) - + MUL15(a[11], b[15]) - + MUL15(a[12], b[14]) - + MUL15(a[13], b[13]) - + MUL15(a[14], b[12]) - + MUL15(a[15], b[11]) - + MUL15(a[16], b[10]) - + MUL15(a[17], b[ 9]) - + MUL15(a[18], b[ 8]) - + MUL15(a[19], b[ 7]); - t[27] = MUL15(a[ 8], b[19]) - + MUL15(a[ 9], b[18]) - + MUL15(a[10], b[17]) - + MUL15(a[11], b[16]) - + MUL15(a[12], b[15]) - + MUL15(a[13], b[14]) - + MUL15(a[14], b[13]) - + MUL15(a[15], b[12]) - + MUL15(a[16], b[11]) - + MUL15(a[17], b[10]) - + MUL15(a[18], b[ 9]) - + MUL15(a[19], b[ 8]); - t[28] = MUL15(a[ 9], b[19]) - + MUL15(a[10], b[18]) - + MUL15(a[11], b[17]) - + MUL15(a[12], b[16]) - + MUL15(a[13], b[15]) - + MUL15(a[14], b[14]) - + MUL15(a[15], b[13]) - + MUL15(a[16], b[12]) - + MUL15(a[17], b[11]) - + MUL15(a[18], b[10]) - + MUL15(a[19], b[ 9]); - t[29] = MUL15(a[10], b[19]) - + MUL15(a[11], b[18]) - + MUL15(a[12], b[17]) - + MUL15(a[13], b[16]) - + MUL15(a[14], b[15]) - + MUL15(a[15], b[14]) - + MUL15(a[16], b[13]) - + MUL15(a[17], b[12]) - + MUL15(a[18], b[11]) - + MUL15(a[19], b[10]); - t[30] = MUL15(a[11], b[19]) - + MUL15(a[12], b[18]) - + MUL15(a[13], b[17]) - + MUL15(a[14], b[16]) - + MUL15(a[15], b[15]) - + MUL15(a[16], b[14]) - + MUL15(a[17], b[13]) - + MUL15(a[18], b[12]) - + MUL15(a[19], b[11]); - t[31] = MUL15(a[12], b[19]) - + MUL15(a[13], b[18]) - + MUL15(a[14], b[17]) - + MUL15(a[15], b[16]) - + MUL15(a[16], b[15]) - + MUL15(a[17], b[14]) - + MUL15(a[18], b[13]) - + MUL15(a[19], b[12]); - t[32] = MUL15(a[13], b[19]) - + MUL15(a[14], b[18]) - + MUL15(a[15], b[17]) - + MUL15(a[16], b[16]) - + MUL15(a[17], b[15]) - + MUL15(a[18], b[14]) - + MUL15(a[19], b[13]); - t[33] = MUL15(a[14], b[19]) - + MUL15(a[15], b[18]) - + MUL15(a[16], b[17]) - + MUL15(a[17], b[16]) - + MUL15(a[18], b[15]) - + MUL15(a[19], b[14]); - t[34] = MUL15(a[15], b[19]) - + MUL15(a[16], b[18]) - + MUL15(a[17], b[17]) - + MUL15(a[18], b[16]) - + MUL15(a[19], b[15]); - t[35] = MUL15(a[16], b[19]) - + MUL15(a[17], b[18]) - + MUL15(a[18], b[17]) - + MUL15(a[19], b[16]); - t[36] = MUL15(a[17], b[19]) - + MUL15(a[18], b[18]) - + MUL15(a[19], b[17]); - t[37] = MUL15(a[18], b[19]) - + MUL15(a[19], b[18]); - t[38] = MUL15(a[19], b[19]); - d[39] = norm13(d, t, 39); -} - -static void -square20(uint32_t *d, const uint32_t *a) -{ - uint32_t t[39]; - - t[ 0] = MUL15(a[ 0], a[ 0]); - t[ 1] = ((MUL15(a[ 0], a[ 1])) << 1); - t[ 2] = MUL15(a[ 1], a[ 1]) - + ((MUL15(a[ 0], a[ 2])) << 1); - t[ 3] = ((MUL15(a[ 0], a[ 3]) - + MUL15(a[ 1], a[ 2])) << 1); - t[ 4] = MUL15(a[ 2], a[ 2]) - + ((MUL15(a[ 0], a[ 4]) - + MUL15(a[ 1], a[ 3])) << 1); - t[ 5] = ((MUL15(a[ 0], a[ 5]) - + MUL15(a[ 1], a[ 4]) - + MUL15(a[ 2], a[ 3])) << 1); - t[ 6] = MUL15(a[ 3], a[ 3]) - + ((MUL15(a[ 0], a[ 6]) - + MUL15(a[ 1], a[ 5]) - + MUL15(a[ 2], a[ 4])) << 1); - t[ 7] = ((MUL15(a[ 0], a[ 7]) - + MUL15(a[ 1], a[ 6]) - + MUL15(a[ 2], a[ 5]) - + MUL15(a[ 3], a[ 4])) << 1); - t[ 8] = MUL15(a[ 4], a[ 4]) - + ((MUL15(a[ 0], a[ 8]) - + MUL15(a[ 1], a[ 7]) - + MUL15(a[ 2], a[ 6]) - + MUL15(a[ 3], a[ 5])) << 1); - t[ 9] = ((MUL15(a[ 0], a[ 9]) - + MUL15(a[ 1], a[ 8]) - + MUL15(a[ 2], a[ 7]) - + MUL15(a[ 3], a[ 6]) - + MUL15(a[ 4], a[ 5])) << 1); - t[10] = MUL15(a[ 5], a[ 5]) - + ((MUL15(a[ 0], a[10]) - + MUL15(a[ 1], a[ 9]) - + MUL15(a[ 2], a[ 8]) - + MUL15(a[ 3], a[ 7]) - + MUL15(a[ 4], a[ 6])) << 1); - t[11] = ((MUL15(a[ 0], a[11]) - + MUL15(a[ 1], a[10]) - + MUL15(a[ 2], a[ 9]) - + MUL15(a[ 3], a[ 8]) - + MUL15(a[ 4], a[ 7]) - + MUL15(a[ 5], a[ 6])) << 1); - t[12] = MUL15(a[ 6], a[ 6]) - + ((MUL15(a[ 0], a[12]) - + MUL15(a[ 1], a[11]) - + MUL15(a[ 2], a[10]) - + MUL15(a[ 3], a[ 9]) - + MUL15(a[ 4], a[ 8]) - + MUL15(a[ 5], a[ 7])) << 1); - t[13] = ((MUL15(a[ 0], a[13]) - + MUL15(a[ 1], a[12]) - + MUL15(a[ 2], a[11]) - + MUL15(a[ 3], a[10]) - + MUL15(a[ 4], a[ 9]) - + MUL15(a[ 5], a[ 8]) - + MUL15(a[ 6], a[ 7])) << 1); - t[14] = MUL15(a[ 7], a[ 7]) - + ((MUL15(a[ 0], a[14]) - + MUL15(a[ 1], a[13]) - + MUL15(a[ 2], a[12]) - + MUL15(a[ 3], a[11]) - + MUL15(a[ 4], a[10]) - + MUL15(a[ 5], a[ 9]) - + MUL15(a[ 6], a[ 8])) << 1); - t[15] = ((MUL15(a[ 0], a[15]) - + MUL15(a[ 1], a[14]) - + MUL15(a[ 2], a[13]) - + MUL15(a[ 3], a[12]) - + MUL15(a[ 4], a[11]) - + MUL15(a[ 5], a[10]) - + MUL15(a[ 6], a[ 9]) - + MUL15(a[ 7], a[ 8])) << 1); - t[16] = MUL15(a[ 8], a[ 8]) - + ((MUL15(a[ 0], a[16]) - + MUL15(a[ 1], a[15]) - + MUL15(a[ 2], a[14]) - + MUL15(a[ 3], a[13]) - + MUL15(a[ 4], a[12]) - + MUL15(a[ 5], a[11]) - + MUL15(a[ 6], a[10]) - + MUL15(a[ 7], a[ 9])) << 1); - t[17] = ((MUL15(a[ 0], a[17]) - + MUL15(a[ 1], a[16]) - + MUL15(a[ 2], a[15]) - + MUL15(a[ 3], a[14]) - + MUL15(a[ 4], a[13]) - + MUL15(a[ 5], a[12]) - + MUL15(a[ 6], a[11]) - + MUL15(a[ 7], a[10]) - + MUL15(a[ 8], a[ 9])) << 1); - t[18] = MUL15(a[ 9], a[ 9]) - + ((MUL15(a[ 0], a[18]) - + MUL15(a[ 1], a[17]) - + MUL15(a[ 2], a[16]) - + MUL15(a[ 3], a[15]) - + MUL15(a[ 4], a[14]) - + MUL15(a[ 5], a[13]) - + MUL15(a[ 6], a[12]) - + MUL15(a[ 7], a[11]) - + MUL15(a[ 8], a[10])) << 1); - t[19] = ((MUL15(a[ 0], a[19]) - + MUL15(a[ 1], a[18]) - + MUL15(a[ 2], a[17]) - + MUL15(a[ 3], a[16]) - + MUL15(a[ 4], a[15]) - + MUL15(a[ 5], a[14]) - + MUL15(a[ 6], a[13]) - + MUL15(a[ 7], a[12]) - + MUL15(a[ 8], a[11]) - + MUL15(a[ 9], a[10])) << 1); - t[20] = MUL15(a[10], a[10]) - + ((MUL15(a[ 1], a[19]) - + MUL15(a[ 2], a[18]) - + MUL15(a[ 3], a[17]) - + MUL15(a[ 4], a[16]) - + MUL15(a[ 5], a[15]) - + MUL15(a[ 6], a[14]) - + MUL15(a[ 7], a[13]) - + MUL15(a[ 8], a[12]) - + MUL15(a[ 9], a[11])) << 1); - t[21] = ((MUL15(a[ 2], a[19]) - + MUL15(a[ 3], a[18]) - + MUL15(a[ 4], a[17]) - + MUL15(a[ 5], a[16]) - + MUL15(a[ 6], a[15]) - + MUL15(a[ 7], a[14]) - + MUL15(a[ 8], a[13]) - + MUL15(a[ 9], a[12]) - + MUL15(a[10], a[11])) << 1); - t[22] = MUL15(a[11], a[11]) - + ((MUL15(a[ 3], a[19]) - + MUL15(a[ 4], a[18]) - + MUL15(a[ 5], a[17]) - + MUL15(a[ 6], a[16]) - + MUL15(a[ 7], a[15]) - + MUL15(a[ 8], a[14]) - + MUL15(a[ 9], a[13]) - + MUL15(a[10], a[12])) << 1); - t[23] = ((MUL15(a[ 4], a[19]) - + MUL15(a[ 5], a[18]) - + MUL15(a[ 6], a[17]) - + MUL15(a[ 7], a[16]) - + MUL15(a[ 8], a[15]) - + MUL15(a[ 9], a[14]) - + MUL15(a[10], a[13]) - + MUL15(a[11], a[12])) << 1); - t[24] = MUL15(a[12], a[12]) - + ((MUL15(a[ 5], a[19]) - + MUL15(a[ 6], a[18]) - + MUL15(a[ 7], a[17]) - + MUL15(a[ 8], a[16]) - + MUL15(a[ 9], a[15]) - + MUL15(a[10], a[14]) - + MUL15(a[11], a[13])) << 1); - t[25] = ((MUL15(a[ 6], a[19]) - + MUL15(a[ 7], a[18]) - + MUL15(a[ 8], a[17]) - + MUL15(a[ 9], a[16]) - + MUL15(a[10], a[15]) - + MUL15(a[11], a[14]) - + MUL15(a[12], a[13])) << 1); - t[26] = MUL15(a[13], a[13]) - + ((MUL15(a[ 7], a[19]) - + MUL15(a[ 8], a[18]) - + MUL15(a[ 9], a[17]) - + MUL15(a[10], a[16]) - + MUL15(a[11], a[15]) - + MUL15(a[12], a[14])) << 1); - t[27] = ((MUL15(a[ 8], a[19]) - + MUL15(a[ 9], a[18]) - + MUL15(a[10], a[17]) - + MUL15(a[11], a[16]) - + MUL15(a[12], a[15]) - + MUL15(a[13], a[14])) << 1); - t[28] = MUL15(a[14], a[14]) - + ((MUL15(a[ 9], a[19]) - + MUL15(a[10], a[18]) - + MUL15(a[11], a[17]) - + MUL15(a[12], a[16]) - + MUL15(a[13], a[15])) << 1); - t[29] = ((MUL15(a[10], a[19]) - + MUL15(a[11], a[18]) - + MUL15(a[12], a[17]) - + MUL15(a[13], a[16]) - + MUL15(a[14], a[15])) << 1); - t[30] = MUL15(a[15], a[15]) - + ((MUL15(a[11], a[19]) - + MUL15(a[12], a[18]) - + MUL15(a[13], a[17]) - + MUL15(a[14], a[16])) << 1); - t[31] = ((MUL15(a[12], a[19]) - + MUL15(a[13], a[18]) - + MUL15(a[14], a[17]) - + MUL15(a[15], a[16])) << 1); - t[32] = MUL15(a[16], a[16]) - + ((MUL15(a[13], a[19]) - + MUL15(a[14], a[18]) - + MUL15(a[15], a[17])) << 1); - t[33] = ((MUL15(a[14], a[19]) - + MUL15(a[15], a[18]) - + MUL15(a[16], a[17])) << 1); - t[34] = MUL15(a[17], a[17]) - + ((MUL15(a[15], a[19]) - + MUL15(a[16], a[18])) << 1); - t[35] = ((MUL15(a[16], a[19]) - + MUL15(a[17], a[18])) << 1); - t[36] = MUL15(a[18], a[18]) - + ((MUL15(a[17], a[19])) << 1); - t[37] = ((MUL15(a[18], a[19])) << 1); - t[38] = MUL15(a[19], a[19]); - d[39] = norm13(d, t, 39); -} - -#endif - -/* - * Modulus for field F256 (field for point coordinates in curve P-256). - */ -static const uint32_t F256[] = { - 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x001F, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0400, 0x0000, - 0x0000, 0x1FF8, 0x1FFF, 0x01FF -}; - -/* - * The 'b' curve equation coefficient for P-256. - */ -static const uint32_t P256_B[] = { - 0x004B, 0x1E93, 0x0F89, 0x1C78, 0x03BC, 0x187B, 0x114E, 0x1619, - 0x1D06, 0x0328, 0x01AF, 0x0D31, 0x1557, 0x15DE, 0x1ECF, 0x127C, - 0x0A3A, 0x0EC5, 0x118D, 0x00B5 -}; - -/* - * Perform a "short reduction" in field F256 (field for curve P-256). - * The source value should be less than 262 bits; on output, it will - * be at most 257 bits, and less than twice the modulus. - */ -static void -reduce_f256(uint32_t *d) -{ - uint32_t x; - - x = d[19] >> 9; - d[19] &= 0x01FF; - d[17] += x << 3; - d[14] -= x << 10; - d[7] -= x << 5; - d[0] += x; - norm13(d, d, 20); -} - -/* - * Perform a "final reduction" in field F256 (field for curve P-256). - * The source value must be less than twice the modulus. If the value - * is not lower than the modulus, then the modulus is subtracted and - * this function returns 1; otherwise, it leaves it untouched and it - * returns 0. - */ -static uint32_t -reduce_final_f256(uint32_t *d) -{ - uint32_t t[20]; - uint32_t cc; - int i; - - memcpy(t, d, sizeof t); - cc = 0; - for (i = 0; i < 20; i ++) { - uint32_t w; - - w = t[i] - F256[i] - cc; - cc = w >> 31; - t[i] = w & 0x1FFF; - } - cc ^= 1; - CCOPY(cc, d, t, sizeof t); - return cc; -} - -/* - * Perform a multiplication of two integers modulo - * 2^256-2^224+2^192+2^96-1 (for NIST curve P-256). Operands are arrays - * of 20 words, each containing 13 bits of data, in little-endian order. - * On input, upper word may be up to 13 bits (hence value up to 2^260-1); - * on output, value fits on 257 bits and is lower than twice the modulus. - */ -static void -mul_f256(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - uint32_t t[40], cc; - int i; - - /* - * Compute raw multiplication. All result words fit in 13 bits - * each. - */ - mul20(t, a, b); - - /* - * Modular reduction: each high word in added/subtracted where - * necessary. - * - * The modulus is: - * p = 2^256 - 2^224 + 2^192 + 2^96 - 1 - * Therefore: - * 2^256 = 2^224 - 2^192 - 2^96 + 1 mod p - * - * For a word x at bit offset n (n >= 256), we have: - * x*2^n = x*2^(n-32) - x*2^(n-64) - * - x*2^(n - 160) + x*2^(n-256) mod p - * - * Thus, we can nullify the high word if we reinject it at some - * proper emplacements. - */ - for (i = 39; i >= 20; i --) { - uint32_t x; - - x = t[i]; - t[i - 2] += ARSH(x, 6); - t[i - 3] += (x << 7) & 0x1FFF; - t[i - 4] -= ARSH(x, 12); - t[i - 5] -= (x << 1) & 0x1FFF; - t[i - 12] -= ARSH(x, 4); - t[i - 13] -= (x << 9) & 0x1FFF; - t[i - 19] += ARSH(x, 9); - t[i - 20] += (x << 4) & 0x1FFF; - } - - /* - * Propagate carries. This is a signed propagation, and the - * result may be negative. The loop above may enlarge values, - * but not two much: worst case is the chain involving t[i - 3], - * in which a value may be added to itself up to 7 times. Since - * starting values are 13-bit each, all words fit on 20 bits - * (21 to account for the sign bit). - */ - cc = norm13(t, t, 20); - - /* - * Perform modular reduction again for the bits beyond 256 (the carry - * and the bits 256..259). Since the largest shift below is by 10 - * bits, and the values fit on 21 bits, values fit in 32-bit words, - * thereby allowing injecting full word values. - */ - cc = (cc << 4) | (t[19] >> 9); - t[19] &= 0x01FF; - t[17] += cc << 3; - t[14] -= cc << 10; - t[7] -= cc << 5; - t[0] += cc; - - /* - * If the carry is negative, then after carry propagation, we may - * end up with a value which is negative, and we don't want that. - * Thus, in that case, we add the modulus. Note that the subtraction - * result, when the carry is negative, is always smaller than the - * modulus, so the extra addition will not make the value exceed - * twice the modulus. - */ - cc >>= 31; - t[0] -= cc; - t[7] += cc << 5; - t[14] += cc << 10; - t[17] -= cc << 3; - t[19] += cc << 9; - - norm13(d, t, 20); -} - -/* - * Square an integer modulo 2^256-2^224+2^192+2^96-1 (for NIST curve - * P-256). Operand is an array of 20 words, each containing 13 bits of - * data, in little-endian order. On input, upper word may be up to 13 - * bits (hence value up to 2^260-1); on output, value fits on 257 bits - * and is lower than twice the modulus. - */ -static void -square_f256(uint32_t *d, const uint32_t *a) -{ - uint32_t t[40], cc; - int i; - - /* - * Compute raw square. All result words fit in 13 bits each. - */ - square20(t, a); - - /* - * Modular reduction: each high word in added/subtracted where - * necessary. - * - * The modulus is: - * p = 2^256 - 2^224 + 2^192 + 2^96 - 1 - * Therefore: - * 2^256 = 2^224 - 2^192 - 2^96 + 1 mod p - * - * For a word x at bit offset n (n >= 256), we have: - * x*2^n = x*2^(n-32) - x*2^(n-64) - * - x*2^(n - 160) + x*2^(n-256) mod p - * - * Thus, we can nullify the high word if we reinject it at some - * proper emplacements. - */ - for (i = 39; i >= 20; i --) { - uint32_t x; - - x = t[i]; - t[i - 2] += ARSH(x, 6); - t[i - 3] += (x << 7) & 0x1FFF; - t[i - 4] -= ARSH(x, 12); - t[i - 5] -= (x << 1) & 0x1FFF; - t[i - 12] -= ARSH(x, 4); - t[i - 13] -= (x << 9) & 0x1FFF; - t[i - 19] += ARSH(x, 9); - t[i - 20] += (x << 4) & 0x1FFF; - } - - /* - * Propagate carries. This is a signed propagation, and the - * result may be negative. The loop above may enlarge values, - * but not two much: worst case is the chain involving t[i - 3], - * in which a value may be added to itself up to 7 times. Since - * starting values are 13-bit each, all words fit on 20 bits - * (21 to account for the sign bit). - */ - cc = norm13(t, t, 20); - - /* - * Perform modular reduction again for the bits beyond 256 (the carry - * and the bits 256..259). Since the largest shift below is by 10 - * bits, and the values fit on 21 bits, values fit in 32-bit words, - * thereby allowing injecting full word values. - */ - cc = (cc << 4) | (t[19] >> 9); - t[19] &= 0x01FF; - t[17] += cc << 3; - t[14] -= cc << 10; - t[7] -= cc << 5; - t[0] += cc; - - /* - * If the carry is negative, then after carry propagation, we may - * end up with a value which is negative, and we don't want that. - * Thus, in that case, we add the modulus. Note that the subtraction - * result, when the carry is negative, is always smaller than the - * modulus, so the extra addition will not make the value exceed - * twice the modulus. - */ - cc >>= 31; - t[0] -= cc; - t[7] += cc << 5; - t[14] += cc << 10; - t[17] -= cc << 3; - t[19] += cc << 9; - - norm13(d, t, 20); -} - -/* - * Jacobian coordinates for a point in P-256: affine coordinates (X,Y) - * are such that: - * X = x / z^2 - * Y = y / z^3 - * For the point at infinity, z = 0. - * Each point thus admits many possible representations. - * - * Coordinates are represented in arrays of 32-bit integers, each holding - * 13 bits of data. Values may also be slightly greater than the modulus, - * but they will always be lower than twice the modulus. - */ -typedef struct { - uint32_t x[20]; - uint32_t y[20]; - uint32_t z[20]; -} p256_jacobian; - -/* - * Convert a point to affine coordinates: - * - If the point is the point at infinity, then all three coordinates - * are set to 0. - * - Otherwise, the 'z' coordinate is set to 1, and the 'x' and 'y' - * coordinates are the 'X' and 'Y' affine coordinates. - * The coordinates are guaranteed to be lower than the modulus. - */ -static void -p256_to_affine(p256_jacobian *P) -{ - uint32_t t1[20], t2[20]; - int i; - - /* - * Invert z with a modular exponentiation: the modulus is - * p = 2^256 - 2^224 + 2^192 + 2^96 - 1, and the exponent is - * p-2. Exponent bit pattern (from high to low) is: - * - 32 bits of value 1 - * - 31 bits of value 0 - * - 1 bit of value 1 - * - 96 bits of value 0 - * - 94 bits of value 1 - * - 1 bit of value 0 - * - 1 bit of value 1 - * Thus, we precompute z^(2^31-1) to speed things up. - * - * If z = 0 (point at infinity) then the modular exponentiation - * will yield 0, which leads to the expected result (all three - * coordinates set to 0). - */ - - /* - * A simple square-and-multiply for z^(2^31-1). We could save about - * two dozen multiplications here with an addition chain, but - * this would require a bit more code, and extra stack buffers. - */ - memcpy(t1, P->z, sizeof P->z); - for (i = 0; i < 30; i ++) { - square_f256(t1, t1); - mul_f256(t1, t1, P->z); - } - - /* - * Square-and-multiply. Apart from the squarings, we have a few - * multiplications to set bits to 1; we multiply by the original z - * for setting 1 bit, and by t1 for setting 31 bits. - */ - memcpy(t2, P->z, sizeof P->z); - for (i = 1; i < 256; i ++) { - square_f256(t2, t2); - switch (i) { - case 31: - case 190: - case 221: - case 252: - mul_f256(t2, t2, t1); - break; - case 63: - case 253: - case 255: - mul_f256(t2, t2, P->z); - break; - } - } - - /* - * Now that we have 1/z, multiply x by 1/z^2 and y by 1/z^3. - */ - mul_f256(t1, t2, t2); - mul_f256(P->x, t1, P->x); - mul_f256(t1, t1, t2); - mul_f256(P->y, t1, P->y); - reduce_final_f256(P->x); - reduce_final_f256(P->y); - - /* - * Multiply z by 1/z. If z = 0, then this will yield 0, otherwise - * this will set z to 1. - */ - mul_f256(P->z, P->z, t2); - reduce_final_f256(P->z); -} - -/* - * Double a point in P-256. This function works for all valid points, - * including the point at infinity. - */ -static void -p256_double(p256_jacobian *Q) -{ - /* - * Doubling formulas are: - * - * s = 4*x*y^2 - * m = 3*(x + z^2)*(x - z^2) - * x' = m^2 - 2*s - * y' = m*(s - x') - 8*y^4 - * z' = 2*y*z - * - * These formulas work for all points, including points of order 2 - * and points at infinity: - * - If y = 0 then z' = 0. But there is no such point in P-256 - * anyway. - * - If z = 0 then z' = 0. - */ - uint32_t t1[20], t2[20], t3[20], t4[20]; - int i; - - /* - * Compute z^2 in t1. - */ - square_f256(t1, Q->z); - - /* - * Compute x-z^2 in t2 and x+z^2 in t1. - */ - for (i = 0; i < 20; i ++) { - t2[i] = (F256[i] << 1) + Q->x[i] - t1[i]; - t1[i] += Q->x[i]; - } - norm13(t1, t1, 20); - norm13(t2, t2, 20); - - /* - * Compute 3*(x+z^2)*(x-z^2) in t1. - */ - mul_f256(t3, t1, t2); - for (i = 0; i < 20; i ++) { - t1[i] = MUL15(3, t3[i]); - } - norm13(t1, t1, 20); - - /* - * Compute 4*x*y^2 (in t2) and 2*y^2 (in t3). - */ - square_f256(t3, Q->y); - for (i = 0; i < 20; i ++) { - t3[i] <<= 1; - } - norm13(t3, t3, 20); - mul_f256(t2, Q->x, t3); - for (i = 0; i < 20; i ++) { - t2[i] <<= 1; - } - norm13(t2, t2, 20); - reduce_f256(t2); - - /* - * Compute x' = m^2 - 2*s. - */ - square_f256(Q->x, t1); - for (i = 0; i < 20; i ++) { - Q->x[i] += (F256[i] << 2) - (t2[i] << 1); - } - norm13(Q->x, Q->x, 20); - reduce_f256(Q->x); - - /* - * Compute z' = 2*y*z. - */ - mul_f256(t4, Q->y, Q->z); - for (i = 0; i < 20; i ++) { - Q->z[i] = t4[i] << 1; - } - norm13(Q->z, Q->z, 20); - reduce_f256(Q->z); - - /* - * Compute y' = m*(s - x') - 8*y^4. Note that we already have - * 2*y^2 in t3. - */ - for (i = 0; i < 20; i ++) { - t2[i] += (F256[i] << 1) - Q->x[i]; - } - norm13(t2, t2, 20); - mul_f256(Q->y, t1, t2); - square_f256(t4, t3); - for (i = 0; i < 20; i ++) { - Q->y[i] += (F256[i] << 2) - (t4[i] << 1); - } - norm13(Q->y, Q->y, 20); - reduce_f256(Q->y); -} - -/* - * Add point P2 to point P1. - * - * This function computes the wrong result in the following cases: - * - * - If P1 == 0 but P2 != 0 - * - If P1 != 0 but P2 == 0 - * - If P1 == P2 - * - * In all three cases, P1 is set to the point at infinity. - * - * Returned value is 0 if one of the following occurs: - * - * - P1 and P2 have the same Y coordinate - * - P1 == 0 and P2 == 0 - * - The Y coordinate of one of the points is 0 and the other point is - * the point at infinity. - * - * The third case cannot actually happen with valid points, since a point - * with Y == 0 is a point of order 2, and there is no point of order 2 on - * curve P-256. - * - * Therefore, assuming that P1 != 0 and P2 != 0 on input, then the caller - * can apply the following: - * - * - If the result is not the point at infinity, then it is correct. - * - Otherwise, if the returned value is 1, then this is a case of - * P1+P2 == 0, so the result is indeed the point at infinity. - * - Otherwise, P1 == P2, so a "double" operation should have been - * performed. - */ -static uint32_t -p256_add(p256_jacobian *P1, const p256_jacobian *P2) -{ - /* - * Addtions formulas are: - * - * u1 = x1 * z2^2 - * u2 = x2 * z1^2 - * s1 = y1 * z2^3 - * s2 = y2 * z1^3 - * h = u2 - u1 - * r = s2 - s1 - * x3 = r^2 - h^3 - 2 * u1 * h^2 - * y3 = r * (u1 * h^2 - x3) - s1 * h^3 - * z3 = h * z1 * z2 - */ - uint32_t t1[20], t2[20], t3[20], t4[20], t5[20], t6[20], t7[20]; - uint32_t ret; - int i; - - /* - * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3). - */ - square_f256(t3, P2->z); - mul_f256(t1, P1->x, t3); - mul_f256(t4, P2->z, t3); - mul_f256(t3, P1->y, t4); - - /* - * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). - */ - square_f256(t4, P1->z); - mul_f256(t2, P2->x, t4); - mul_f256(t5, P1->z, t4); - mul_f256(t4, P2->y, t5); - - /* - * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). - * We need to test whether r is zero, so we will do some extra - * reduce. - */ - for (i = 0; i < 20; i ++) { - t2[i] += (F256[i] << 1) - t1[i]; - t4[i] += (F256[i] << 1) - t3[i]; - } - norm13(t2, t2, 20); - norm13(t4, t4, 20); - reduce_f256(t4); - reduce_final_f256(t4); - ret = 0; - for (i = 0; i < 20; i ++) { - ret |= t4[i]; - } - ret = (ret | -ret) >> 31; - - /* - * Compute u1*h^2 (in t6) and h^3 (in t5); - */ - square_f256(t7, t2); - mul_f256(t6, t1, t7); - mul_f256(t5, t7, t2); - - /* - * Compute x3 = r^2 - h^3 - 2*u1*h^2. - */ - square_f256(P1->x, t4); - for (i = 0; i < 20; i ++) { - P1->x[i] += (F256[i] << 3) - t5[i] - (t6[i] << 1); - } - norm13(P1->x, P1->x, 20); - reduce_f256(P1->x); - - /* - * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. - */ - for (i = 0; i < 20; i ++) { - t6[i] += (F256[i] << 1) - P1->x[i]; - } - norm13(t6, t6, 20); - mul_f256(P1->y, t4, t6); - mul_f256(t1, t5, t3); - for (i = 0; i < 20; i ++) { - P1->y[i] += (F256[i] << 1) - t1[i]; - } - norm13(P1->y, P1->y, 20); - reduce_f256(P1->y); - - /* - * Compute z3 = h*z1*z2. - */ - mul_f256(t1, P1->z, P2->z); - mul_f256(P1->z, t1, t2); - - return ret; -} - -/* - * Add point P2 to point P1. This is a specialised function for the - * case when P2 is a non-zero point in affine coordinate. - * - * This function computes the wrong result in the following cases: - * - * - If P1 == 0 - * - If P1 == P2 - * - * In both cases, P1 is set to the point at infinity. - * - * Returned value is 0 if one of the following occurs: - * - * - P1 and P2 have the same Y coordinate - * - The Y coordinate of P2 is 0 and P1 is the point at infinity. - * - * The second case cannot actually happen with valid points, since a point - * with Y == 0 is a point of order 2, and there is no point of order 2 on - * curve P-256. - * - * Therefore, assuming that P1 != 0 on input, then the caller - * can apply the following: - * - * - If the result is not the point at infinity, then it is correct. - * - Otherwise, if the returned value is 1, then this is a case of - * P1+P2 == 0, so the result is indeed the point at infinity. - * - Otherwise, P1 == P2, so a "double" operation should have been - * performed. - */ -static uint32_t -p256_add_mixed(p256_jacobian *P1, const p256_jacobian *P2) -{ - /* - * Addtions formulas are: - * - * u1 = x1 - * u2 = x2 * z1^2 - * s1 = y1 - * s2 = y2 * z1^3 - * h = u2 - u1 - * r = s2 - s1 - * x3 = r^2 - h^3 - 2 * u1 * h^2 - * y3 = r * (u1 * h^2 - x3) - s1 * h^3 - * z3 = h * z1 - */ - uint32_t t1[20], t2[20], t3[20], t4[20], t5[20], t6[20], t7[20]; - uint32_t ret; - int i; - - /* - * Compute u1 = x1 (in t1) and s1 = y1 (in t3). - */ - memcpy(t1, P1->x, sizeof t1); - memcpy(t3, P1->y, sizeof t3); - - /* - * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). - */ - square_f256(t4, P1->z); - mul_f256(t2, P2->x, t4); - mul_f256(t5, P1->z, t4); - mul_f256(t4, P2->y, t5); - - /* - * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). - * We need to test whether r is zero, so we will do some extra - * reduce. - */ - for (i = 0; i < 20; i ++) { - t2[i] += (F256[i] << 1) - t1[i]; - t4[i] += (F256[i] << 1) - t3[i]; - } - norm13(t2, t2, 20); - norm13(t4, t4, 20); - reduce_f256(t4); - reduce_final_f256(t4); - ret = 0; - for (i = 0; i < 20; i ++) { - ret |= t4[i]; - } - ret = (ret | -ret) >> 31; - - /* - * Compute u1*h^2 (in t6) and h^3 (in t5); - */ - square_f256(t7, t2); - mul_f256(t6, t1, t7); - mul_f256(t5, t7, t2); - - /* - * Compute x3 = r^2 - h^3 - 2*u1*h^2. - */ - square_f256(P1->x, t4); - for (i = 0; i < 20; i ++) { - P1->x[i] += (F256[i] << 3) - t5[i] - (t6[i] << 1); - } - norm13(P1->x, P1->x, 20); - reduce_f256(P1->x); - - /* - * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. - */ - for (i = 0; i < 20; i ++) { - t6[i] += (F256[i] << 1) - P1->x[i]; - } - norm13(t6, t6, 20); - mul_f256(P1->y, t4, t6); - mul_f256(t1, t5, t3); - for (i = 0; i < 20; i ++) { - P1->y[i] += (F256[i] << 1) - t1[i]; - } - norm13(P1->y, P1->y, 20); - reduce_f256(P1->y); - - /* - * Compute z3 = h*z1*z2. - */ - mul_f256(P1->z, P1->z, t2); - - return ret; -} - -/* - * Decode a P-256 point. This function does not support the point at - * infinity. Returned value is 0 if the point is invalid, 1 otherwise. - */ -static uint32_t -p256_decode(p256_jacobian *P, const void *src, size_t len) -{ - const unsigned char *buf; - uint32_t tx[20], ty[20], t1[20], t2[20]; - uint32_t bad; - int i; - - if (len != 65) { - return 0; - } - buf = src; - - /* - * First byte must be 0x04 (uncompressed format). We could support - * "hybrid format" (first byte is 0x06 or 0x07, and encodes the - * least significant bit of the Y coordinate), but it is explicitly - * forbidden by RFC 5480 (section 2.2). - */ - bad = NEQ(buf[0], 0x04); - - /* - * Decode the coordinates, and check that they are both lower - * than the modulus. - */ - tx[19] = be8_to_le13(tx, buf + 1, 32); - ty[19] = be8_to_le13(ty, buf + 33, 32); - bad |= reduce_final_f256(tx); - bad |= reduce_final_f256(ty); - - /* - * Check curve equation. - */ - square_f256(t1, tx); - mul_f256(t1, tx, t1); - square_f256(t2, ty); - for (i = 0; i < 20; i ++) { - t1[i] += (F256[i] << 3) - MUL15(3, tx[i]) + P256_B[i] - t2[i]; - } - norm13(t1, t1, 20); - reduce_f256(t1); - reduce_final_f256(t1); - for (i = 0; i < 20; i ++) { - bad |= t1[i]; - } - - /* - * Copy coordinates to the point structure. - */ - memcpy(P->x, tx, sizeof tx); - memcpy(P->y, ty, sizeof ty); - memset(P->z, 0, sizeof P->z); - P->z[0] = 1; - return EQ(bad, 0); -} - -/* - * Encode a point into a buffer. This function assumes that the point is - * valid, in affine coordinates, and not the point at infinity. - */ -static void -p256_encode(void *dst, const p256_jacobian *P) -{ - unsigned char *buf; - - buf = dst; - buf[0] = 0x04; - le13_to_be8(buf + 1, 32, P->x); - le13_to_be8(buf + 33, 32, P->y); -} - -/* - * Multiply a curve point by an integer. The integer is assumed to be - * lower than the curve order, and the base point must not be the point - * at infinity. - */ -static void -p256_mul(p256_jacobian *P, const unsigned char *x, size_t xlen) -{ - /* - * qz is a flag that is initially 1, and remains equal to 1 - * as long as the point is the point at infinity. - * - * We use a 2-bit window to handle multiplier bits by pairs. - * The precomputed window really is the points P2 and P3. - */ - uint32_t qz; - p256_jacobian P2, P3, Q, T, U; - - /* - * Compute window values. - */ - P2 = *P; - p256_double(&P2); - P3 = *P; - p256_add(&P3, &P2); - - /* - * We start with Q = 0. We process multiplier bits 2 by 2. - */ - memset(&Q, 0, sizeof Q); - qz = 1; - while (xlen -- > 0) { - int k; - - for (k = 6; k >= 0; k -= 2) { - uint32_t bits; - uint32_t bnz; - - p256_double(&Q); - p256_double(&Q); - T = *P; - U = Q; - bits = (*x >> k) & (uint32_t)3; - bnz = NEQ(bits, 0); - CCOPY(EQ(bits, 2), &T, &P2, sizeof T); - CCOPY(EQ(bits, 3), &T, &P3, sizeof T); - p256_add(&U, &T); - CCOPY(bnz & qz, &Q, &T, sizeof Q); - CCOPY(bnz & ~qz, &Q, &U, sizeof Q); - qz &= ~bnz; - } - x ++; - } - *P = Q; -} - -/* - * Precomputed window: k*G points, where G is the curve generator, and k - * is an integer from 1 to 15 (inclusive). The X and Y coordinates of - * the point are encoded as 20 words of 13 bits each (little-endian - * order); 13-bit words are then grouped 2-by-2 into 32-bit words - * (little-endian order within each word). - */ -static const uint32_t Gwin[15][20] = { - - { 0x04C60296, 0x02721176, 0x19D00F4A, 0x102517AC, - 0x13B8037D, 0x0748103C, 0x1E730E56, 0x08481FE2, - 0x0F97012C, 0x00D605F4, 0x1DFA11F5, 0x0C801A0D, - 0x0F670CBB, 0x0AED0CC5, 0x115E0E33, 0x181F0785, - 0x13F514A7, 0x0FF30E3B, 0x17171E1A, 0x009F18D0 }, - - { 0x1B341978, 0x16911F11, 0x0D9A1A60, 0x1C4E1FC8, - 0x1E040969, 0x096A06B0, 0x091C0030, 0x09EF1A29, - 0x18C40D03, 0x00F91C9E, 0x13C313D1, 0x096F0748, - 0x011419E0, 0x1CC713A6, 0x1DD31DAD, 0x1EE80C36, - 0x1ECD0C69, 0x1A0800A4, 0x08861B8E, 0x000E1DD5 }, - - { 0x173F1D6C, 0x02CC06F1, 0x14C21FB4, 0x043D1EB6, - 0x0F3606B7, 0x1A971C59, 0x1BF71951, 0x01481323, - 0x068D0633, 0x00BD12F9, 0x13EA1032, 0x136209E8, - 0x1C1E19A7, 0x06C7013E, 0x06C10AB0, 0x14C908BB, - 0x05830CE1, 0x1FEF18DD, 0x00620998, 0x010E0D19 }, - - { 0x18180852, 0x0604111A, 0x0B771509, 0x1B6F0156, - 0x00181FE2, 0x1DCC0AF4, 0x16EF0659, 0x11F70E80, - 0x11A912D0, 0x01C414D2, 0x027618C6, 0x05840FC6, - 0x100215C4, 0x187E0C3B, 0x12771C96, 0x150C0B5D, - 0x0FF705FD, 0x07981C67, 0x1AD20C63, 0x01C11C55 }, - - { 0x1E8113ED, 0x0A940370, 0x12920215, 0x1FA31D6F, - 0x1F7C0C82, 0x10CD03F7, 0x02640560, 0x081A0B5E, - 0x1BD21151, 0x00A21642, 0x0D0B0DA4, 0x0176113F, - 0x04440D1D, 0x001A1360, 0x1068012F, 0x1F141E49, - 0x10DF136B, 0x0E4F162B, 0x0D44104A, 0x01C1105F }, - - { 0x011411A9, 0x01551A4F, 0x0ADA0C6B, 0x01BD0EC8, - 0x18120C74, 0x112F1778, 0x099202CB, 0x0C05124B, - 0x195316A4, 0x01600685, 0x1E3B1FE2, 0x189014E3, - 0x0B5E1FD7, 0x0E0311F8, 0x08E000F7, 0x174E00DE, - 0x160702DF, 0x1B5A15BF, 0x03A11237, 0x01D01704 }, - - { 0x0C3D12A3, 0x0C501C0C, 0x17AD1300, 0x1715003F, - 0x03F719F8, 0x18031ED8, 0x1D980667, 0x0F681896, - 0x1B7D00BF, 0x011C14CE, 0x0FA000B4, 0x1C3501B0, - 0x0D901C55, 0x06790C10, 0x029E0736, 0x0DEB0400, - 0x034F183A, 0x030619B4, 0x0DEF0033, 0x00E71AC7 }, - - { 0x1B7D1393, 0x1B3B1076, 0x0BED1B4D, 0x13011F3A, - 0x0E0E1238, 0x156A132B, 0x013A02D3, 0x160A0D01, - 0x1CED1EE9, 0x00C5165D, 0x184C157E, 0x08141A83, - 0x153C0DA5, 0x1ED70F9D, 0x05170D51, 0x02CF13B8, - 0x18AE1771, 0x1B04113F, 0x05EC11E9, 0x015A16B3 }, - - { 0x04A41EE0, 0x1D1412E4, 0x1C591D79, 0x118511B7, - 0x14F00ACB, 0x1AE31E1C, 0x049C0D51, 0x016E061E, - 0x1DB71EDF, 0x01D41A35, 0x0E8208FA, 0x14441293, - 0x011F1E85, 0x1D54137A, 0x026B114F, 0x151D0832, - 0x00A50964, 0x1F9C1E1C, 0x064B12C9, 0x005409D1 }, - - { 0x062B123F, 0x0C0D0501, 0x183704C3, 0x08E31120, - 0x0A2E0A6C, 0x14440FED, 0x090A0D1E, 0x13271964, - 0x0B590A3A, 0x019D1D9B, 0x05780773, 0x09770A91, - 0x0F770CA3, 0x053F19D4, 0x02C80DED, 0x1A761304, - 0x091E0DD9, 0x15D201B8, 0x151109AA, 0x010F0198 }, - - { 0x05E101D1, 0x072314DD, 0x045F1433, 0x1A041541, - 0x10B3142E, 0x01840736, 0x1C1B19DB, 0x098B0418, - 0x1DBC083B, 0x007D1444, 0x01511740, 0x11DD1F3A, - 0x04ED0E2F, 0x1B4B1A62, 0x10480D04, 0x09E911A2, - 0x04211AFA, 0x19140893, 0x04D60CC4, 0x01210648 }, - - { 0x112703C4, 0x018B1BA1, 0x164C1D50, 0x05160BE0, - 0x0BCC1830, 0x01CB1554, 0x13291732, 0x1B2B1918, - 0x0DED0817, 0x00E80775, 0x0A2401D3, 0x0BFE08B3, - 0x0E531199, 0x058616E9, 0x04770B91, 0x110F0C55, - 0x19C11554, 0x0BFB1159, 0x03541C38, 0x000E1C2D }, - - { 0x10390C01, 0x02BB0751, 0x0AC5098E, 0x096C17AB, - 0x03C90E28, 0x10BD18BF, 0x002E1F2D, 0x092B0986, - 0x1BD700AC, 0x002E1F20, 0x1E3D1FD8, 0x077718BB, - 0x06F919C4, 0x187407ED, 0x11370E14, 0x081E139C, - 0x00481ADB, 0x14AB0289, 0x066A0EBE, 0x00C70ED6 }, - - { 0x0694120B, 0x124E1CC9, 0x0E2F0570, 0x17CF081A, - 0x078906AC, 0x066D17CF, 0x1B3207F4, 0x0C5705E9, - 0x10001C38, 0x00A919DE, 0x06851375, 0x0F900BD8, - 0x080401BA, 0x0EEE0D42, 0x1B8B11EA, 0x0B4519F0, - 0x090F18C0, 0x062E1508, 0x0DD909F4, 0x01EB067C }, - - { 0x0CDC1D5F, 0x0D1818F9, 0x07781636, 0x125B18E8, - 0x0D7003AF, 0x13110099, 0x1D9B1899, 0x175C1EB7, - 0x0E34171A, 0x01E01153, 0x081A0F36, 0x0B391783, - 0x1D1F147E, 0x19CE16D7, 0x11511B21, 0x1F2C10F9, - 0x12CA0E51, 0x05A31D39, 0x171A192E, 0x016B0E4F } -}; - -/* - * Lookup one of the Gwin[] values, by index. This is constant-time. - */ -static void -lookup_Gwin(p256_jacobian *T, uint32_t idx) -{ - uint32_t xy[20]; - uint32_t k; - size_t u; - - memset(xy, 0, sizeof xy); - for (k = 0; k < 15; k ++) { - uint32_t m; - - m = -EQ(idx, k + 1); - for (u = 0; u < 20; u ++) { - xy[u] |= m & Gwin[k][u]; - } - } - for (u = 0; u < 10; u ++) { - T->x[(u << 1) + 0] = xy[u] & 0xFFFF; - T->x[(u << 1) + 1] = xy[u] >> 16; - T->y[(u << 1) + 0] = xy[u + 10] & 0xFFFF; - T->y[(u << 1) + 1] = xy[u + 10] >> 16; - } - memset(T->z, 0, sizeof T->z); - T->z[0] = 1; -} - -/* - * Multiply the generator by an integer. The integer is assumed non-zero - * and lower than the curve order. - */ -static void -p256_mulgen(p256_jacobian *P, const unsigned char *x, size_t xlen) -{ - /* - * qz is a flag that is initially 1, and remains equal to 1 - * as long as the point is the point at infinity. - * - * We use a 4-bit window to handle multiplier bits by groups - * of 4. The precomputed window is constant static data, with - * points in affine coordinates; we use a constant-time lookup. - */ - p256_jacobian Q; - uint32_t qz; - - memset(&Q, 0, sizeof Q); - qz = 1; - while (xlen -- > 0) { - int k; - unsigned bx; - - bx = *x ++; - for (k = 0; k < 2; k ++) { - uint32_t bits; - uint32_t bnz; - p256_jacobian T, U; - - p256_double(&Q); - p256_double(&Q); - p256_double(&Q); - p256_double(&Q); - bits = (bx >> 4) & 0x0F; - bnz = NEQ(bits, 0); - lookup_Gwin(&T, bits); - U = Q; - p256_add_mixed(&U, &T); - CCOPY(bnz & qz, &Q, &T, sizeof Q); - CCOPY(bnz & ~qz, &Q, &U, sizeof Q); - qz &= ~bnz; - bx <<= 4; - } - } - *P = Q; -} - -static const unsigned char P256_G[] = { - 0x04, 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, - 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, - 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, - 0x98, 0xC2, 0x96, 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, - 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, 0x2B, - 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, - 0x68, 0x37, 0xBF, 0x51, 0xF5 -}; - -static const unsigned char P256_N[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, - 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, - 0x25, 0x51 -}; - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - (void)curve; - *len = sizeof P256_G; - return P256_G; -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - (void)curve; - *len = sizeof P256_N; - return P256_N; -} - -static size_t -api_xoff(int curve, size_t *len) -{ - (void)curve; - *len = 32; - return 1; -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *x, size_t xlen, int curve) -{ - uint32_t r; - p256_jacobian P; - - (void)curve; - if (Glen != 65) { - return 0; - } - r = p256_decode(&P, G, Glen); - p256_mul(&P, x, xlen); - p256_to_affine(&P); - p256_encode(G, &P); - return r; -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - p256_jacobian P; - - (void)curve; - p256_mulgen(&P, x, xlen); - p256_to_affine(&P); - p256_encode(R, &P); - return 65; -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - p256_jacobian P, Q; - uint32_t r, t, z; - int i; - - (void)curve; - if (len != 65) { - return 0; - } - r = p256_decode(&P, A, len); - p256_mul(&P, x, xlen); - if (B == NULL) { - p256_mulgen(&Q, y, ylen); - } else { - r &= p256_decode(&Q, B, len); - p256_mul(&Q, y, ylen); - } - - /* - * The final addition may fail in case both points are equal. - */ - t = p256_add(&P, &Q); - reduce_final_f256(P.z); - z = 0; - for (i = 0; i < 20; i ++) { - z |= P.z[i]; - } - z = EQ(z, 0); - p256_double(&Q); - - /* - * If z is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we - * have the following: - * - * z = 0, t = 0 return P (normal addition) - * z = 0, t = 1 return P (normal addition) - * z = 1, t = 0 return Q (a 'double' case) - * z = 1, t = 1 report an error (P+Q = 0) - */ - CCOPY(z & ~t, &P, &Q, sizeof Q); - p256_to_affine(&P); - p256_encode(A, &P); - r &= ~(z & t); - return r; -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_p256_m15 = { - (uint32_t)0x00800000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; diff --git a/third_party/bearssl/src/ec_prime_i15.c b/third_party/bearssl/src/ec_prime_i15.c deleted file mode 100644 index f86dbe6ff..000000000 --- a/third_party/bearssl/src/ec_prime_i15.c +++ /dev/null @@ -1,824 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * Parameters for supported curves: - * - field modulus p - * - R^2 mod p (R = 2^(15k) for the smallest k such that R >= p) - * - b*R mod p (b is the second curve equation parameter) - */ - -static const uint16_t P256_P[] = { - 0x0111, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x003F, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x4000, 0x7FFF, - 0x7FFF, 0x0001 -}; - -static const uint16_t P256_R2[] = { - 0x0111, - 0x0000, 0x6000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FFC, 0x7FFF, - 0x7FBF, 0x7FFF, 0x7FBF, 0x7FFF, 0x7FFF, 0x7FFF, 0x77FF, 0x7FFF, - 0x4FFF, 0x0000 -}; - -static const uint16_t P256_B[] = { - 0x0111, - 0x770C, 0x5EEF, 0x29C4, 0x3EC4, 0x6273, 0x0486, 0x4543, 0x3993, - 0x3C01, 0x6B56, 0x212E, 0x57EE, 0x4882, 0x204B, 0x7483, 0x3C16, - 0x0187, 0x0000 -}; - -static const uint16_t P384_P[] = { - 0x0199, - 0x7FFF, 0x7FFF, 0x0003, 0x0000, 0x0000, 0x0000, 0x7FC0, 0x7FFF, - 0x7EFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x01FF -}; - -static const uint16_t P384_R2[] = { - 0x0199, - 0x1000, 0x0000, 0x0000, 0x7FFF, 0x7FFF, 0x0001, 0x0000, 0x0010, - 0x0000, 0x0000, 0x0000, 0x7F00, 0x7FFF, 0x01FF, 0x0000, 0x1000, - 0x0000, 0x2000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000 -}; - -static const uint16_t P384_B[] = { - 0x0199, - 0x7333, 0x2096, 0x70D1, 0x2310, 0x3020, 0x6197, 0x1464, 0x35BB, - 0x70CA, 0x0117, 0x1920, 0x4136, 0x5FC8, 0x5713, 0x4938, 0x7DD2, - 0x4DD2, 0x4A71, 0x0220, 0x683E, 0x2C87, 0x4DB1, 0x7BFF, 0x6C09, - 0x0452, 0x0084 -}; - -static const uint16_t P521_P[] = { - 0x022B, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0x7FFF, 0x7FFF, 0x07FF -}; - -static const uint16_t P521_R2[] = { - 0x022B, - 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000 -}; - -static const uint16_t P521_B[] = { - 0x022B, - 0x7002, 0x6A07, 0x751A, 0x228F, 0x71EF, 0x5869, 0x20F4, 0x1EFC, - 0x7357, 0x37E0, 0x4EEC, 0x605E, 0x1652, 0x26F6, 0x31FA, 0x4A8F, - 0x6193, 0x3C2A, 0x3C42, 0x48C7, 0x3489, 0x6771, 0x4C57, 0x5CCD, - 0x2725, 0x545B, 0x503B, 0x5B42, 0x21A0, 0x2534, 0x687E, 0x70E4, - 0x1618, 0x27D7, 0x0465 -}; - -typedef struct { - const uint16_t *p; - const uint16_t *b; - const uint16_t *R2; - uint16_t p0i; - size_t point_len; -} curve_params; - -static inline const curve_params * -id_to_curve(int curve) -{ - static const curve_params pp[] = { - { P256_P, P256_B, P256_R2, 0x0001, 65 }, - { P384_P, P384_B, P384_R2, 0x0001, 97 }, - { P521_P, P521_B, P521_R2, 0x0001, 133 } - }; - - return &pp[curve - BR_EC_secp256r1]; -} - -#define I15_LEN ((BR_MAX_EC_SIZE + 29) / 15) - -/* - * Type for a point in Jacobian coordinates: - * -- three values, x, y and z, in Montgomery representation - * -- affine coordinates are X = x / z^2 and Y = y / z^3 - * -- for the point at infinity, z = 0 - */ -typedef struct { - uint16_t c[3][I15_LEN]; -} jacobian; - -/* - * We use a custom interpreter that uses a dozen registers, and - * only six operations: - * MSET(d, a) copy a into d - * MADD(d, a) d = d+a (modular) - * MSUB(d, a) d = d-a (modular) - * MMUL(d, a, b) d = a*b (Montgomery multiplication) - * MINV(d, a, b) invert d modulo p; a and b are used as scratch registers - * MTZ(d) clear return value if d = 0 - * Destination of MMUL (d) must be distinct from operands (a and b). - * There is no such constraint for MSUB and MADD. - * - * Registers include the operand coordinates, and temporaries. - */ -#define MSET(d, a) (0x0000 + ((d) << 8) + ((a) << 4)) -#define MADD(d, a) (0x1000 + ((d) << 8) + ((a) << 4)) -#define MSUB(d, a) (0x2000 + ((d) << 8) + ((a) << 4)) -#define MMUL(d, a, b) (0x3000 + ((d) << 8) + ((a) << 4) + (b)) -#define MINV(d, a, b) (0x4000 + ((d) << 8) + ((a) << 4) + (b)) -#define MTZ(d) (0x5000 + ((d) << 8)) -#define ENDCODE 0 - -/* - * Registers for the input operands. - */ -#define P1x 0 -#define P1y 1 -#define P1z 2 -#define P2x 3 -#define P2y 4 -#define P2z 5 - -/* - * Alternate names for the first input operand. - */ -#define Px 0 -#define Py 1 -#define Pz 2 - -/* - * Temporaries. - */ -#define t1 6 -#define t2 7 -#define t3 8 -#define t4 9 -#define t5 10 -#define t6 11 -#define t7 12 - -/* - * Extra scratch registers available when there is no second operand (e.g. - * for "double" and "affine"). - */ -#define t8 3 -#define t9 4 -#define t10 5 - -/* - * Doubling formulas are: - * - * s = 4*x*y^2 - * m = 3*(x + z^2)*(x - z^2) - * x' = m^2 - 2*s - * y' = m*(s - x') - 8*y^4 - * z' = 2*y*z - * - * If y = 0 (P has order 2) then this yields infinity (z' = 0), as it - * should. This case should not happen anyway, because our curves have - * prime order, and thus do not contain any point of order 2. - * - * If P is infinity (z = 0), then again the formulas yield infinity, - * which is correct. Thus, this code works for all points. - * - * Cost: 8 multiplications - */ -static const uint16_t code_double[] = { - /* - * Compute z^2 (in t1). - */ - MMUL(t1, Pz, Pz), - - /* - * Compute x-z^2 (in t2) and then x+z^2 (in t1). - */ - MSET(t2, Px), - MSUB(t2, t1), - MADD(t1, Px), - - /* - * Compute m = 3*(x+z^2)*(x-z^2) (in t1). - */ - MMUL(t3, t1, t2), - MSET(t1, t3), - MADD(t1, t3), - MADD(t1, t3), - - /* - * Compute s = 4*x*y^2 (in t2) and 2*y^2 (in t3). - */ - MMUL(t3, Py, Py), - MADD(t3, t3), - MMUL(t2, Px, t3), - MADD(t2, t2), - - /* - * Compute x' = m^2 - 2*s. - */ - MMUL(Px, t1, t1), - MSUB(Px, t2), - MSUB(Px, t2), - - /* - * Compute z' = 2*y*z. - */ - MMUL(t4, Py, Pz), - MSET(Pz, t4), - MADD(Pz, t4), - - /* - * Compute y' = m*(s - x') - 8*y^4. Note that we already have - * 2*y^2 in t3. - */ - MSUB(t2, Px), - MMUL(Py, t1, t2), - MMUL(t4, t3, t3), - MSUB(Py, t4), - MSUB(Py, t4), - - ENDCODE -}; - -/* - * Addtions formulas are: - * - * u1 = x1 * z2^2 - * u2 = x2 * z1^2 - * s1 = y1 * z2^3 - * s2 = y2 * z1^3 - * h = u2 - u1 - * r = s2 - s1 - * x3 = r^2 - h^3 - 2 * u1 * h^2 - * y3 = r * (u1 * h^2 - x3) - s1 * h^3 - * z3 = h * z1 * z2 - * - * If both P1 and P2 are infinity, then z1 == 0 and z2 == 0, implying that - * z3 == 0, so the result is correct. - * If either of P1 or P2 is infinity, but not both, then z3 == 0, which is - * not correct. - * h == 0 only if u1 == u2; this happens in two cases: - * -- if s1 == s2 then P1 and/or P2 is infinity, or P1 == P2 - * -- if s1 != s2 then P1 + P2 == infinity (but neither P1 or P2 is infinity) - * - * Thus, the following situations are not handled correctly: - * -- P1 = 0 and P2 != 0 - * -- P1 != 0 and P2 = 0 - * -- P1 = P2 - * All other cases are properly computed. However, even in "incorrect" - * situations, the three coordinates still are properly formed field - * elements. - * - * The returned flag is cleared if r == 0. This happens in the following - * cases: - * -- Both points are on the same horizontal line (same Y coordinate). - * -- Both points are infinity. - * -- One point is infinity and the other is on line Y = 0. - * The third case cannot happen with our curves (there is no valid point - * on line Y = 0 since that would be a point of order 2). If the two - * source points are non-infinity, then remains only the case where the - * two points are on the same horizontal line. - * - * This allows us to detect the "P1 == P2" case, assuming that P1 != 0 and - * P2 != 0: - * -- If the returned value is not the point at infinity, then it was properly - * computed. - * -- Otherwise, if the returned flag is 1, then P1+P2 = 0, and the result - * is indeed the point at infinity. - * -- Otherwise (result is infinity, flag is 0), then P1 = P2 and we should - * use the 'double' code. - * - * Cost: 16 multiplications - */ -static const uint16_t code_add[] = { - /* - * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3). - */ - MMUL(t3, P2z, P2z), - MMUL(t1, P1x, t3), - MMUL(t4, P2z, t3), - MMUL(t3, P1y, t4), - - /* - * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). - */ - MMUL(t4, P1z, P1z), - MMUL(t2, P2x, t4), - MMUL(t5, P1z, t4), - MMUL(t4, P2y, t5), - - /* - * Compute h = u2 - u1 (in t2) and r = s2 - s1 (in t4). - */ - MSUB(t2, t1), - MSUB(t4, t3), - - /* - * Report cases where r = 0 through the returned flag. - */ - MTZ(t4), - - /* - * Compute u1*h^2 (in t6) and h^3 (in t5). - */ - MMUL(t7, t2, t2), - MMUL(t6, t1, t7), - MMUL(t5, t7, t2), - - /* - * Compute x3 = r^2 - h^3 - 2*u1*h^2. - * t1 and t7 can be used as scratch registers. - */ - MMUL(P1x, t4, t4), - MSUB(P1x, t5), - MSUB(P1x, t6), - MSUB(P1x, t6), - - /* - * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. - */ - MSUB(t6, P1x), - MMUL(P1y, t4, t6), - MMUL(t1, t5, t3), - MSUB(P1y, t1), - - /* - * Compute z3 = h*z1*z2. - */ - MMUL(t1, P1z, P2z), - MMUL(P1z, t1, t2), - - ENDCODE -}; - -/* - * Check that the point is on the curve. This code snippet assumes the - * following conventions: - * -- Coordinates x and y have been freshly decoded in P1 (but not - * converted to Montgomery coordinates yet). - * -- P2x, P2y and P2z are set to, respectively, R^2, b*R and 1. - */ -static const uint16_t code_check[] = { - - /* Convert x and y to Montgomery representation. */ - MMUL(t1, P1x, P2x), - MMUL(t2, P1y, P2x), - MSET(P1x, t1), - MSET(P1y, t2), - - /* Compute x^3 in t1. */ - MMUL(t2, P1x, P1x), - MMUL(t1, P1x, t2), - - /* Subtract 3*x from t1. */ - MSUB(t1, P1x), - MSUB(t1, P1x), - MSUB(t1, P1x), - - /* Add b. */ - MADD(t1, P2y), - - /* Compute y^2 in t2. */ - MMUL(t2, P1y, P1y), - - /* Compare y^2 with x^3 - 3*x + b; they must match. */ - MSUB(t1, t2), - MTZ(t1), - - /* Set z to 1 (in Montgomery representation). */ - MMUL(P1z, P2x, P2z), - - ENDCODE -}; - -/* - * Conversion back to affine coordinates. This code snippet assumes that - * the z coordinate of P2 is set to 1 (not in Montgomery representation). - */ -static const uint16_t code_affine[] = { - - /* Save z*R in t1. */ - MSET(t1, P1z), - - /* Compute z^3 in t2. */ - MMUL(t2, P1z, P1z), - MMUL(t3, P1z, t2), - MMUL(t2, t3, P2z), - - /* Invert to (1/z^3) in t2. */ - MINV(t2, t3, t4), - - /* Compute y. */ - MSET(t3, P1y), - MMUL(P1y, t2, t3), - - /* Compute (1/z^2) in t3. */ - MMUL(t3, t2, t1), - - /* Compute x. */ - MSET(t2, P1x), - MMUL(P1x, t2, t3), - - ENDCODE -}; - -static uint32_t -run_code(jacobian *P1, const jacobian *P2, - const curve_params *cc, const uint16_t *code) -{ - uint32_t r; - uint16_t t[13][I15_LEN]; - size_t u; - - r = 1; - - /* - * Copy the two operands in the dedicated registers. - */ - memcpy(t[P1x], P1->c, 3 * I15_LEN * sizeof(uint16_t)); - memcpy(t[P2x], P2->c, 3 * I15_LEN * sizeof(uint16_t)); - - /* - * Run formulas. - */ - for (u = 0;; u ++) { - unsigned op, d, a, b; - - op = code[u]; - if (op == 0) { - break; - } - d = (op >> 8) & 0x0F; - a = (op >> 4) & 0x0F; - b = op & 0x0F; - op >>= 12; - switch (op) { - uint32_t ctl; - size_t plen; - unsigned char tp[(BR_MAX_EC_SIZE + 7) >> 3]; - - case 0: - memcpy(t[d], t[a], I15_LEN * sizeof(uint16_t)); - break; - case 1: - ctl = br_i15_add(t[d], t[a], 1); - ctl |= NOT(br_i15_sub(t[d], cc->p, 0)); - br_i15_sub(t[d], cc->p, ctl); - break; - case 2: - br_i15_add(t[d], cc->p, br_i15_sub(t[d], t[a], 1)); - break; - case 3: - br_i15_montymul(t[d], t[a], t[b], cc->p, cc->p0i); - break; - case 4: - plen = (cc->p[0] - (cc->p[0] >> 4) + 7) >> 3; - br_i15_encode(tp, plen, cc->p); - tp[plen - 1] -= 2; - br_i15_modpow(t[d], tp, plen, - cc->p, cc->p0i, t[a], t[b]); - break; - default: - r &= ~br_i15_iszero(t[d]); - break; - } - } - - /* - * Copy back result. - */ - memcpy(P1->c, t[P1x], 3 * I15_LEN * sizeof(uint16_t)); - return r; -} - -static void -set_one(uint16_t *x, const uint16_t *p) -{ - size_t plen; - - plen = (p[0] + 31) >> 4; - memset(x, 0, plen * sizeof *x); - x[0] = p[0]; - x[1] = 0x0001; -} - -static void -point_zero(jacobian *P, const curve_params *cc) -{ - memset(P, 0, sizeof *P); - P->c[0][0] = P->c[1][0] = P->c[2][0] = cc->p[0]; -} - -static inline void -point_double(jacobian *P, const curve_params *cc) -{ - run_code(P, P, cc, code_double); -} - -static inline uint32_t -point_add(jacobian *P1, const jacobian *P2, const curve_params *cc) -{ - return run_code(P1, P2, cc, code_add); -} - -static void -point_mul(jacobian *P, const unsigned char *x, size_t xlen, - const curve_params *cc) -{ - /* - * We do a simple double-and-add ladder with a 2-bit window - * to make only one add every two doublings. We thus first - * precompute 2P and 3P in some local buffers. - * - * We always perform two doublings and one addition; the - * addition is with P, 2P and 3P and is done in a temporary - * array. - * - * The addition code cannot handle cases where one of the - * operands is infinity, which is the case at the start of the - * ladder. We therefore need to maintain a flag that controls - * this situation. - */ - uint32_t qz; - jacobian P2, P3, Q, T, U; - - memcpy(&P2, P, sizeof P2); - point_double(&P2, cc); - memcpy(&P3, P, sizeof P3); - point_add(&P3, &P2, cc); - - point_zero(&Q, cc); - qz = 1; - while (xlen -- > 0) { - int k; - - for (k = 6; k >= 0; k -= 2) { - uint32_t bits; - uint32_t bnz; - - point_double(&Q, cc); - point_double(&Q, cc); - memcpy(&T, P, sizeof T); - memcpy(&U, &Q, sizeof U); - bits = (*x >> k) & (uint32_t)3; - bnz = NEQ(bits, 0); - CCOPY(EQ(bits, 2), &T, &P2, sizeof T); - CCOPY(EQ(bits, 3), &T, &P3, sizeof T); - point_add(&U, &T, cc); - CCOPY(bnz & qz, &Q, &T, sizeof Q); - CCOPY(bnz & ~qz, &Q, &U, sizeof Q); - qz &= ~bnz; - } - x ++; - } - memcpy(P, &Q, sizeof Q); -} - -/* - * Decode point into Jacobian coordinates. This function does not support - * the point at infinity. If the point is invalid then this returns 0, but - * the coordinates are still set to properly formed field elements. - */ -static uint32_t -point_decode(jacobian *P, const void *src, size_t len, const curve_params *cc) -{ - /* - * Points must use uncompressed format: - * -- first byte is 0x04; - * -- coordinates X and Y use unsigned big-endian, with the same - * length as the field modulus. - * - * We don't support hybrid format (uncompressed, but first byte - * has value 0x06 or 0x07, depending on the least significant bit - * of Y) because it is rather useless, and explicitly forbidden - * by PKIX (RFC 5480, section 2.2). - * - * We don't support compressed format either, because it is not - * much used in practice (there are or were patent-related - * concerns about point compression, which explains the lack of - * generalised support). Also, point compression support would - * need a bit more code. - */ - const unsigned char *buf; - size_t plen, zlen; - uint32_t r; - jacobian Q; - - buf = src; - point_zero(P, cc); - plen = (cc->p[0] - (cc->p[0] >> 4) + 7) >> 3; - if (len != 1 + (plen << 1)) { - return 0; - } - r = br_i15_decode_mod(P->c[0], buf + 1, plen, cc->p); - r &= br_i15_decode_mod(P->c[1], buf + 1 + plen, plen, cc->p); - - /* - * Check first byte. - */ - r &= EQ(buf[0], 0x04); - /* obsolete - r &= EQ(buf[0], 0x04) | (EQ(buf[0] & 0xFE, 0x06) - & ~(uint32_t)(buf[0] ^ buf[plen << 1])); - */ - - /* - * Convert coordinates and check that the point is valid. - */ - zlen = ((cc->p[0] + 31) >> 4) * sizeof(uint16_t); - memcpy(Q.c[0], cc->R2, zlen); - memcpy(Q.c[1], cc->b, zlen); - set_one(Q.c[2], cc->p); - r &= ~run_code(P, &Q, cc, code_check); - return r; -} - -/* - * Encode a point. This method assumes that the point is correct and is - * not the point at infinity. Encoded size is always 1+2*plen, where - * plen is the field modulus length, in bytes. - */ -static void -point_encode(void *dst, const jacobian *P, const curve_params *cc) -{ - unsigned char *buf; - size_t plen; - jacobian Q, T; - - buf = dst; - plen = (cc->p[0] - (cc->p[0] >> 4) + 7) >> 3; - buf[0] = 0x04; - memcpy(&Q, P, sizeof *P); - set_one(T.c[2], cc->p); - run_code(&Q, &T, cc, code_affine); - br_i15_encode(buf + 1, plen, Q.c[0]); - br_i15_encode(buf + 1 + plen, plen, Q.c[1]); -} - -static const br_ec_curve_def * -id_to_curve_def(int curve) -{ - switch (curve) { - case BR_EC_secp256r1: - return &br_secp256r1; - case BR_EC_secp384r1: - return &br_secp384r1; - case BR_EC_secp521r1: - return &br_secp521r1; - } - return NULL; -} - -static const unsigned char * -api_generator(int curve, size_t *len) -{ - const br_ec_curve_def *cd; - - cd = id_to_curve_def(curve); - *len = cd->generator_len; - return cd->generator; -} - -static const unsigned char * -api_order(int curve, size_t *len) -{ - const br_ec_curve_def *cd; - - cd = id_to_curve_def(curve); - *len = cd->order_len; - return cd->order; -} - -static size_t -api_xoff(int curve, size_t *len) -{ - api_generator(curve, len); - *len >>= 1; - return 1; -} - -static uint32_t -api_mul(unsigned char *G, size_t Glen, - const unsigned char *x, size_t xlen, int curve) -{ - uint32_t r; - const curve_params *cc; - jacobian P; - - cc = id_to_curve(curve); - if (Glen != cc->point_len) { - return 0; - } - r = point_decode(&P, G, Glen, cc); - point_mul(&P, x, xlen, cc); - point_encode(G, &P, cc); - return r; -} - -static size_t -api_mulgen(unsigned char *R, - const unsigned char *x, size_t xlen, int curve) -{ - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; -} - -static uint32_t -api_muladd(unsigned char *A, const unsigned char *B, size_t len, - const unsigned char *x, size_t xlen, - const unsigned char *y, size_t ylen, int curve) -{ - uint32_t r, t, z; - const curve_params *cc; - jacobian P, Q; - - /* - * TODO: see about merging the two ladders. Right now, we do - * two independent point multiplications, which is a bit - * wasteful of CPU resources (but yields short code). - */ - - cc = id_to_curve(curve); - if (len != cc->point_len) { - return 0; - } - r = point_decode(&P, A, len, cc); - if (B == NULL) { - size_t Glen; - - B = api_generator(curve, &Glen); - } - r &= point_decode(&Q, B, len, cc); - point_mul(&P, x, xlen, cc); - point_mul(&Q, y, ylen, cc); - - /* - * We want to compute P+Q. Since the base points A and B are distinct - * from infinity, and the multipliers are non-zero and lower than the - * curve order, then we know that P and Q are non-infinity. This - * leaves two special situations to test for: - * -- If P = Q then we must use point_double(). - * -- If P+Q = 0 then we must report an error. - */ - t = point_add(&P, &Q, cc); - point_double(&Q, cc); - z = br_i15_iszero(P.c[2]); - - /* - * If z is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we - * have the following: - * - * z = 0, t = 0 return P (normal addition) - * z = 0, t = 1 return P (normal addition) - * z = 1, t = 0 return Q (a 'double' case) - * z = 1, t = 1 report an error (P+Q = 0) - */ - CCOPY(z & ~t, &P, &Q, sizeof Q); - point_encode(A, &P, cc); - r &= ~(z & t); - - return r; -} - -/* see bearssl_ec.h */ -const br_ec_impl br_ec_prime_i15 = { - (uint32_t)0x03800000, - &api_generator, - &api_order, - &api_xoff, - &api_mul, - &api_mulgen, - &api_muladd -}; diff --git a/third_party/bearssl/src/ecdsa_default_sign_asn1.c b/third_party/bearssl/src/ecdsa_default_sign_asn1.c index afbf8acbd..36a11a773 100644 --- a/third_party/bearssl/src/ecdsa_default_sign_asn1.c +++ b/third_party/bearssl/src/ecdsa_default_sign_asn1.c @@ -28,9 +28,5 @@ br_ecdsa_sign br_ecdsa_sign_asn1_get_default(void) { -#if BR_LOMUL - return &br_ecdsa_i15_sign_asn1; -#else return &br_ecdsa_i31_sign_asn1; -#endif } diff --git a/third_party/bearssl/src/ecdsa_default_sign_raw.c b/third_party/bearssl/src/ecdsa_default_sign_raw.c index 287c97044..dc0071983 100644 --- a/third_party/bearssl/src/ecdsa_default_sign_raw.c +++ b/third_party/bearssl/src/ecdsa_default_sign_raw.c @@ -28,9 +28,5 @@ br_ecdsa_sign br_ecdsa_sign_raw_get_default(void) { -#if BR_LOMUL - return &br_ecdsa_i15_sign_raw; -#else return &br_ecdsa_i31_sign_raw; -#endif } diff --git a/third_party/bearssl/src/ecdsa_default_vrfy_asn1.c b/third_party/bearssl/src/ecdsa_default_vrfy_asn1.c index fe0996e8e..b009c4598 100644 --- a/third_party/bearssl/src/ecdsa_default_vrfy_asn1.c +++ b/third_party/bearssl/src/ecdsa_default_vrfy_asn1.c @@ -28,9 +28,5 @@ br_ecdsa_vrfy br_ecdsa_vrfy_asn1_get_default(void) { -#if BR_LOMUL - return &br_ecdsa_i15_vrfy_asn1; -#else return &br_ecdsa_i31_vrfy_asn1; -#endif } diff --git a/third_party/bearssl/src/ecdsa_default_vrfy_raw.c b/third_party/bearssl/src/ecdsa_default_vrfy_raw.c index e564a1052..8e1971bcf 100644 --- a/third_party/bearssl/src/ecdsa_default_vrfy_raw.c +++ b/third_party/bearssl/src/ecdsa_default_vrfy_raw.c @@ -28,9 +28,5 @@ br_ecdsa_vrfy br_ecdsa_vrfy_raw_get_default(void) { -#if BR_LOMUL - return &br_ecdsa_i15_vrfy_raw; -#else return &br_ecdsa_i31_vrfy_raw; -#endif } diff --git a/third_party/bearssl/src/ecdsa_i15_bits.c b/third_party/bearssl/src/ecdsa_i15_bits.c deleted file mode 100644 index 402d14a66..000000000 --- a/third_party/bearssl/src/ecdsa_i15_bits.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_ecdsa_i15_bits2int(uint16_t *x, - const void *src, size_t len, uint32_t ebitlen) -{ - uint32_t bitlen, hbitlen; - int sc; - - bitlen = ebitlen - (ebitlen >> 4); - hbitlen = (uint32_t)len << 3; - if (hbitlen > bitlen) { - len = (bitlen + 7) >> 3; - sc = (int)((hbitlen - bitlen) & 7); - } else { - sc = 0; - } - br_i15_zero(x, ebitlen); - br_i15_decode(x, src, len); - br_i15_rshift(x, sc); - x[0] = ebitlen; -} diff --git a/third_party/bearssl/src/ecdsa_i15_sign_asn1.c b/third_party/bearssl/src/ecdsa_i15_sign_asn1.c deleted file mode 100644 index ab4a283cf..000000000 --- a/third_party/bearssl/src/ecdsa_i15_sign_asn1.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -#define ORDER_LEN ((BR_MAX_EC_SIZE + 7) >> 3) - -/* see bearssl_ec.h */ -size_t -br_ecdsa_i15_sign_asn1(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig) -{ - unsigned char rsig[(ORDER_LEN << 1) + 12]; - size_t sig_len; - - sig_len = br_ecdsa_i15_sign_raw(impl, hf, hash_value, sk, rsig); - if (sig_len == 0) { - return 0; - } - sig_len = br_ecdsa_raw_to_asn1(rsig, sig_len); - memcpy(sig, rsig, sig_len); - return sig_len; -} diff --git a/third_party/bearssl/src/ecdsa_i15_sign_raw.c b/third_party/bearssl/src/ecdsa_i15_sign_raw.c deleted file mode 100644 index 39b2e1d7e..000000000 --- a/third_party/bearssl/src/ecdsa_i15_sign_raw.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -#define I15_LEN ((BR_MAX_EC_SIZE + 29) / 15) -#define POINT_LEN (1 + (((BR_MAX_EC_SIZE + 7) >> 3) << 1)) -#define ORDER_LEN ((BR_MAX_EC_SIZE + 7) >> 3) - -/* see bearssl_ec.h */ -size_t -br_ecdsa_i15_sign_raw(const br_ec_impl *impl, - const br_hash_class *hf, const void *hash_value, - const br_ec_private_key *sk, void *sig) -{ - /* - * IMPORTANT: this code is fit only for curves with a prime - * order. This is needed so that modular reduction of the X - * coordinate of a point can be done with a simple subtraction. - * We also rely on the last byte of the curve order to be distinct - * from 0 and 1. - */ - const br_ec_curve_def *cd; - uint16_t n[I15_LEN], r[I15_LEN], s[I15_LEN], x[I15_LEN]; - uint16_t m[I15_LEN], k[I15_LEN], t1[I15_LEN], t2[I15_LEN]; - unsigned char tt[ORDER_LEN << 1]; - unsigned char eU[POINT_LEN]; - size_t hash_len, nlen, ulen; - uint16_t n0i; - uint32_t ctl; - br_hmac_drbg_context drbg; - - /* - * If the curve is not supported, then exit with an error. - */ - if (((impl->supported_curves >> sk->curve) & 1) == 0) { - return 0; - } - - /* - * Get the curve parameters (generator and order). - */ - switch (sk->curve) { - case BR_EC_secp256r1: - cd = &br_secp256r1; - break; - case BR_EC_secp384r1: - cd = &br_secp384r1; - break; - case BR_EC_secp521r1: - cd = &br_secp521r1; - break; - default: - return 0; - } - - /* - * Get modulus. - */ - nlen = cd->order_len; - br_i15_decode(n, cd->order, nlen); - n0i = br_i15_ninv15(n[1]); - - /* - * Get private key as an i15 integer. This also checks that the - * private key is well-defined (not zero, and less than the - * curve order). - */ - if (!br_i15_decode_mod(x, sk->x, sk->xlen, n)) { - return 0; - } - if (br_i15_iszero(x)) { - return 0; - } - - /* - * Get hash length. - */ - hash_len = (hf->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; - - /* - * Truncate and reduce the hash value modulo the curve order. - */ - br_ecdsa_i15_bits2int(m, hash_value, hash_len, n[0]); - br_i15_sub(m, n, br_i15_sub(m, n, 0) ^ 1); - - /* - * RFC 6979 generation of the "k" value. - * - * The process uses HMAC_DRBG (with the hash function used to - * process the message that is to be signed). The seed is the - * concatenation of the encodings of the private key and - * the hash value (after truncation and modular reduction). - */ - br_i15_encode(tt, nlen, x); - br_i15_encode(tt + nlen, nlen, m); - br_hmac_drbg_init(&drbg, hf, tt, nlen << 1); - for (;;) { - br_hmac_drbg_generate(&drbg, tt, nlen); - br_ecdsa_i15_bits2int(k, tt, nlen, n[0]); - if (br_i15_iszero(k)) { - continue; - } - if (br_i15_sub(k, n, 0)) { - break; - } - } - - /* - * Compute k*G and extract the X coordinate, then reduce it - * modulo the curve order. Since we support only curves with - * prime order, that reduction is only a matter of computing - * a subtraction. - */ - br_i15_encode(tt, nlen, k); - ulen = impl->mulgen(eU, tt, nlen, sk->curve); - br_i15_zero(r, n[0]); - br_i15_decode(r, &eU[1], ulen >> 1); - r[0] = n[0]; - br_i15_sub(r, n, br_i15_sub(r, n, 0) ^ 1); - - /* - * Compute 1/k in double-Montgomery representation. We do so by - * first converting _from_ Montgomery representation (twice), - * then using a modular exponentiation. - */ - br_i15_from_monty(k, n, n0i); - br_i15_from_monty(k, n, n0i); - memcpy(tt, cd->order, nlen); - tt[nlen - 1] -= 2; - br_i15_modpow(k, tt, nlen, n, n0i, t1, t2); - - /* - * Compute s = (m+xr)/k (mod n). - * The k[] array contains R^2/k (double-Montgomery representation); - * we thus can use direct Montgomery multiplications and conversions - * from Montgomery, avoiding any call to br_i15_to_monty() (which - * is slower). - */ - br_i15_from_monty(m, n, n0i); - br_i15_montymul(t1, x, r, n, n0i); - ctl = br_i15_add(t1, m, 1); - ctl |= br_i15_sub(t1, n, 0) ^ 1; - br_i15_sub(t1, n, ctl); - br_i15_montymul(s, t1, k, n, n0i); - - /* - * Encode r and s in the signature. - */ - br_i15_encode(sig, nlen, r); - br_i15_encode((unsigned char *)sig + nlen, nlen, s); - return nlen << 1; -} diff --git a/third_party/bearssl/src/ecdsa_i15_vrfy_asn1.c b/third_party/bearssl/src/ecdsa_i15_vrfy_asn1.c deleted file mode 100644 index f4bef997c..000000000 --- a/third_party/bearssl/src/ecdsa_i15_vrfy_asn1.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -#define FIELD_LEN ((BR_MAX_EC_SIZE + 7) >> 3) - -/* see bearssl_ec.h */ -uint32_t -br_ecdsa_i15_vrfy_asn1(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, - const void *sig, size_t sig_len) -{ - /* - * We use a double-sized buffer because a malformed ASN.1 signature - * may trigger a size expansion when converting to "raw" format. - */ - unsigned char rsig[(FIELD_LEN << 2) + 24]; - - if (sig_len > ((sizeof rsig) >> 1)) { - return 0; - } - memcpy(rsig, sig, sig_len); - sig_len = br_ecdsa_asn1_to_raw(rsig, sig_len); - return br_ecdsa_i15_vrfy_raw(impl, hash, hash_len, pk, rsig, sig_len); -} diff --git a/third_party/bearssl/src/ecdsa_i15_vrfy_raw.c b/third_party/bearssl/src/ecdsa_i15_vrfy_raw.c deleted file mode 100644 index 14dd5e468..000000000 --- a/third_party/bearssl/src/ecdsa_i15_vrfy_raw.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -#define I15_LEN ((BR_MAX_EC_SIZE + 29) / 15) -#define POINT_LEN (1 + (((BR_MAX_EC_SIZE + 7) >> 3) << 1)) - -/* see bearssl_ec.h */ -uint32_t -br_ecdsa_i15_vrfy_raw(const br_ec_impl *impl, - const void *hash, size_t hash_len, - const br_ec_public_key *pk, - const void *sig, size_t sig_len) -{ - /* - * IMPORTANT: this code is fit only for curves with a prime - * order. This is needed so that modular reduction of the X - * coordinate of a point can be done with a simple subtraction. - */ - const br_ec_curve_def *cd; - uint16_t n[I15_LEN], r[I15_LEN], s[I15_LEN], t1[I15_LEN], t2[I15_LEN]; - unsigned char tx[(BR_MAX_EC_SIZE + 7) >> 3]; - unsigned char ty[(BR_MAX_EC_SIZE + 7) >> 3]; - unsigned char eU[POINT_LEN]; - size_t nlen, rlen, ulen; - uint16_t n0i; - uint32_t res; - - /* - * If the curve is not supported, then report an error. - */ - if (((impl->supported_curves >> pk->curve) & 1) == 0) { - return 0; - } - - /* - * Get the curve parameters (generator and order). - */ - switch (pk->curve) { - case BR_EC_secp256r1: - cd = &br_secp256r1; - break; - case BR_EC_secp384r1: - cd = &br_secp384r1; - break; - case BR_EC_secp521r1: - cd = &br_secp521r1; - break; - default: - return 0; - } - - /* - * Signature length must be even. - */ - if (sig_len & 1) { - return 0; - } - rlen = sig_len >> 1; - - /* - * Public key point must have the proper size for this curve. - */ - if (pk->qlen != cd->generator_len) { - return 0; - } - - /* - * Get modulus; then decode the r and s values. They must be - * lower than the modulus, and s must not be null. - */ - nlen = cd->order_len; - br_i15_decode(n, cd->order, nlen); - n0i = br_i15_ninv15(n[1]); - if (!br_i15_decode_mod(r, sig, rlen, n)) { - return 0; - } - if (!br_i15_decode_mod(s, (const unsigned char *)sig + rlen, rlen, n)) { - return 0; - } - if (br_i15_iszero(s)) { - return 0; - } - - /* - * Invert s. We do that with a modular exponentiation; we use - * the fact that for all the curves we support, the least - * significant byte is not 0 or 1, so we can subtract 2 without - * any carry to process. - * We also want 1/s in Montgomery representation, which can be - * done by converting _from_ Montgomery representation before - * the inversion (because (1/s)*R = 1/(s/R)). - */ - br_i15_from_monty(s, n, n0i); - memcpy(tx, cd->order, nlen); - tx[nlen - 1] -= 2; - br_i15_modpow(s, tx, nlen, n, n0i, t1, t2); - - /* - * Truncate the hash to the modulus length (in bits) and reduce - * it modulo the curve order. The modular reduction can be done - * with a subtraction since the truncation already reduced the - * value to the modulus bit length. - */ - br_ecdsa_i15_bits2int(t1, hash, hash_len, n[0]); - br_i15_sub(t1, n, br_i15_sub(t1, n, 0) ^ 1); - - /* - * Multiply the (truncated, reduced) hash value with 1/s, result in - * t2, encoded in ty. - */ - br_i15_montymul(t2, t1, s, n, n0i); - br_i15_encode(ty, nlen, t2); - - /* - * Multiply r with 1/s, result in t1, encoded in tx. - */ - br_i15_montymul(t1, r, s, n, n0i); - br_i15_encode(tx, nlen, t1); - - /* - * Compute the point x*Q + y*G. - */ - ulen = cd->generator_len; - memcpy(eU, pk->q, ulen); - res = impl->muladd(eU, NULL, ulen, - tx, nlen, ty, nlen, cd->curve); - - /* - * Get the X coordinate, reduce modulo the curve order, and - * compare with the 'r' value. - * - * The modular reduction can be done with subtractions because - * we work with curves of prime order, so the curve order is - * close to the field order (Hasse's theorem). - */ - br_i15_zero(t1, n[0]); - br_i15_decode(t1, &eU[1], ulen >> 1); - t1[0] = n[0]; - br_i15_sub(t1, n, br_i15_sub(t1, n, 0) ^ 1); - res &= ~br_i15_sub(t1, r, 1); - res &= br_i15_iszero(t1); - return res; -} diff --git a/third_party/bearssl/src/encode_ec_pk8der.c b/third_party/bearssl/src/encode_ec_pk8der.c deleted file mode 100644 index 53717ce3d..000000000 --- a/third_party/bearssl/src/encode_ec_pk8der.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_x509.h */ -size_t -br_encode_ec_pkcs8_der(void *dest, - const br_ec_private_key *sk, const br_ec_public_key *pk) -{ - /* - * ASN.1 format: - * - * OneAsymmetricKey ::= SEQUENCE { - * version Version, - * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - * privateKey PrivateKey, - * attributes [0] Attributes OPTIONAL, - * ..., - * [[2: publicKey [1] PublicKey OPTIONAL ]], - * ... - * } - * - * We don't include attributes or public key (the public key - * is included in the private key value instead). The - * 'version' field is an INTEGER that we will set to 0 - * (meaning 'v1', compatible with previous versions of PKCS#8). - * The 'privateKeyAlgorithm' structure is an AlgorithmIdentifier - * whose OID should be id-ecPublicKey, with, as parameters, the - * curve OID. The 'privateKey' is an OCTET STRING, whose value - * is the "raw DER" encoding of the key pair. - */ - - /* - * OID id-ecPublicKey (1.2.840.10045.2.1), DER-encoded (with - * the tag). - */ - static const unsigned char OID_ECPUBKEY[] = { - 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01 - }; - - size_t len_version, len_privateKeyAlgorithm, len_privateKeyValue; - size_t len_privateKey, len_seq; - const unsigned char *oid; - - oid = br_get_curve_OID(sk->curve); - if (oid == NULL) { - return 0; - } - len_version = 3; - len_privateKeyAlgorithm = 2 + sizeof OID_ECPUBKEY + 2 + oid[0]; - len_privateKeyValue = br_encode_ec_raw_der_inner(NULL, sk, pk, 0); - len_privateKey = 1 + len_of_len(len_privateKeyValue) - + len_privateKeyValue; - len_seq = len_version + len_privateKeyAlgorithm + len_privateKey; - - if (dest == NULL) { - return 1 + len_of_len(len_seq) + len_seq; - } else { - unsigned char *buf; - size_t lenlen; - - buf = dest; - *buf ++ = 0x30; /* SEQUENCE tag */ - lenlen = br_asn1_encode_length(buf, len_seq); - buf += lenlen; - - /* version */ - *buf ++ = 0x02; - *buf ++ = 0x01; - *buf ++ = 0x00; - - /* privateKeyAlgorithm */ - *buf ++ = 0x30; - *buf ++ = (sizeof OID_ECPUBKEY) + 2 + oid[0]; - memcpy(buf, OID_ECPUBKEY, sizeof OID_ECPUBKEY); - buf += sizeof OID_ECPUBKEY; - *buf ++ = 0x06; - memcpy(buf, oid, 1 + oid[0]); - buf += 1 + oid[0]; - - /* privateKey */ - *buf ++ = 0x04; - buf += br_asn1_encode_length(buf, len_privateKeyValue); - br_encode_ec_raw_der_inner(buf, sk, pk, 0); - - return 1 + lenlen + len_seq; - } -} diff --git a/third_party/bearssl/src/encode_ec_rawder.c b/third_party/bearssl/src/encode_ec_rawder.c deleted file mode 100644 index 5985909ad..000000000 --- a/third_party/bearssl/src/encode_ec_rawder.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -const unsigned char * -br_get_curve_OID(int curve) -{ - static const unsigned char OID_secp256r1[] = { - 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 - }; - static const unsigned char OID_secp384r1[] = { - 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 - }; - static const unsigned char OID_secp521r1[] = { - 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23 - }; - - switch (curve) { - case BR_EC_secp256r1: return OID_secp256r1; - case BR_EC_secp384r1: return OID_secp384r1; - case BR_EC_secp521r1: return OID_secp521r1; - default: - return NULL; - } -} - -/* see inner.h */ -size_t -br_encode_ec_raw_der_inner(void *dest, - const br_ec_private_key *sk, const br_ec_public_key *pk, - int include_curve_oid) -{ - /* - * ASN.1 format: - * - * ECPrivateKey ::= SEQUENCE { - * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - * privateKey OCTET STRING, - * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, - * publicKey [1] BIT STRING OPTIONAL - * } - * - * The tages '[0]' and '[1]' are explicit. The 'ECParameters' - * is a CHOICE; in our case, it will always be an OBJECT IDENTIFIER - * that identifies the curve. - * - * The value of the 'privateKey' field is the raw unsigned big-endian - * encoding of the private key (integer modulo the curve subgroup - * order); there is no INTEGER tag, and the leading bit may be 1. - * Also, leading bytes of value 0x00 are _not_ removed. - * - * The 'publicKey' contents are the raw encoded public key point, - * normally uncompressed (leading byte of value 0x04, followed - * by the unsigned big-endian encodings of the X and Y coordinates, - * padded to the full field length if necessary). - */ - - size_t len_version, len_privateKey, len_parameters, len_publicKey; - size_t len_publicKey_bits, len_seq; - const unsigned char *oid; - - if (include_curve_oid) { - oid = br_get_curve_OID(sk->curve); - if (oid == NULL) { - return 0; - } - } else { - oid = NULL; - } - len_version = 3; - len_privateKey = 1 + len_of_len(sk->xlen) + sk->xlen; - if (include_curve_oid) { - len_parameters = 4 + oid[0]; - } else { - len_parameters = 0; - } - if (pk == NULL) { - len_publicKey = 0; - len_publicKey_bits = 0; - } else { - len_publicKey_bits = 2 + len_of_len(pk->qlen) + pk->qlen; - len_publicKey = 1 + len_of_len(len_publicKey_bits) - + len_publicKey_bits; - } - len_seq = len_version + len_privateKey + len_parameters + len_publicKey; - if (dest == NULL) { - return 1 + len_of_len(len_seq) + len_seq; - } else { - unsigned char *buf; - size_t lenlen; - - buf = dest; - *buf ++ = 0x30; /* SEQUENCE tag */ - lenlen = br_asn1_encode_length(buf, len_seq); - buf += lenlen; - - /* version */ - *buf ++ = 0x02; - *buf ++ = 0x01; - *buf ++ = 0x01; - - /* privateKey */ - *buf ++ = 0x04; - buf += br_asn1_encode_length(buf, sk->xlen); - memcpy(buf, sk->x, sk->xlen); - buf += sk->xlen; - - /* parameters */ - if (include_curve_oid) { - *buf ++ = 0xA0; - *buf ++ = oid[0] + 2; - *buf ++ = 0x06; - memcpy(buf, oid, oid[0] + 1); - buf += oid[0] + 1; - } - - /* publicKey */ - if (pk != NULL) { - *buf ++ = 0xA1; - buf += br_asn1_encode_length(buf, len_publicKey_bits); - *buf ++ = 0x03; - buf += br_asn1_encode_length(buf, pk->qlen + 1); - *buf ++ = 0x00; - memcpy(buf, pk->q, pk->qlen); - /* buf += pk->qlen; */ - } - - return 1 + lenlen + len_seq; - } -} - -/* see bearssl_x509.h */ -size_t -br_encode_ec_raw_der(void *dest, - const br_ec_private_key *sk, const br_ec_public_key *pk) -{ - return br_encode_ec_raw_der_inner(dest, sk, pk, 1); -} diff --git a/third_party/bearssl/src/encode_rsa_pk8der.c b/third_party/bearssl/src/encode_rsa_pk8der.c deleted file mode 100644 index c053503d3..000000000 --- a/third_party/bearssl/src/encode_rsa_pk8der.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_x509.h */ -size_t -br_encode_rsa_pkcs8_der(void *dest, const br_rsa_private_key *sk, - const br_rsa_public_key *pk, const void *d, size_t dlen) -{ - /* - * ASN.1 format: - * - * OneAsymmetricKey ::= SEQUENCE { - * version Version, - * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - * privateKey PrivateKey, - * attributes [0] Attributes OPTIONAL, - * ..., - * [[2: publicKey [1] PublicKey OPTIONAL ]], - * ... - * } - * - * We don't include attributes or public key. The 'version' field - * is an INTEGER that we will set to 0 (meaning 'v1', compatible - * with previous versions of PKCS#8). The 'privateKeyAlgorithm' - * structure is an AlgorithmIdentifier whose OID should be - * rsaEncryption, with NULL parameters. The 'privateKey' is an - * OCTET STRING, whose value is the "raw DER" encoding of the - * key pair. - * - * Since the private key value comes last, this function really - * adds a header, which is mostly fixed (only some lengths have - * to be modified. - */ - - /* - * Concatenation of: - * - DER encoding of an INTEGER of value 0 (the 'version' field) - * - DER encoding of a PrivateKeyAlgorithmIdentifier that uses - * the rsaEncryption OID, and NULL parameters - * - An OCTET STRING tag - */ - static const unsigned char PK8_HEAD[] = { - 0x02, 0x01, 0x00, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, - 0x04 - }; - - size_t len_raw, len_seq; - - len_raw = br_encode_rsa_raw_der(NULL, sk, pk, d, dlen); - len_seq = (sizeof PK8_HEAD) + len_of_len(len_raw) + len_raw; - if (dest == NULL) { - return 1 + len_of_len(len_seq) + len_seq; - } else { - unsigned char *buf; - size_t lenlen; - - buf = dest; - *buf ++ = 0x30; /* SEQUENCE tag */ - lenlen = br_asn1_encode_length(buf, len_seq); - buf += lenlen; - - /* version, privateKeyAlgorithm, privateKey tag */ - memcpy(buf, PK8_HEAD, sizeof PK8_HEAD); - buf += sizeof PK8_HEAD; - - /* privateKey */ - buf += br_asn1_encode_length(buf, len_raw); - br_encode_rsa_raw_der(buf, sk, pk, d, dlen); - - return 1 + lenlen + len_seq; - } -} diff --git a/third_party/bearssl/src/encode_rsa_rawder.c b/third_party/bearssl/src/encode_rsa_rawder.c deleted file mode 100644 index 1a8052b03..000000000 --- a/third_party/bearssl/src/encode_rsa_rawder.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_x509.h */ -size_t -br_encode_rsa_raw_der(void *dest, const br_rsa_private_key *sk, - const br_rsa_public_key *pk, const void *d, size_t dlen) -{ - /* - * ASN.1 format: - * - * RSAPrivateKey ::= SEQUENCE { - * version Version, - * modulus INTEGER, -- n - * publicExponent INTEGER, -- e - * privateExponent INTEGER, -- d - * prime1 INTEGER, -- p - * prime2 INTEGER, -- q - * exponent1 INTEGER, -- d mod (p-1) - * exponent2 INTEGER, -- d mod (q-1) - * coefficient INTEGER, -- (inverse of q) mod p - * otherPrimeInfos OtherPrimeInfos OPTIONAL - * } - * - * The 'version' field is an INTEGER of value 0 (meaning: there - * are exactly two prime factors), and 'otherPrimeInfos' will - * be absent (because there are exactly two prime factors). - */ - - br_asn1_uint num[9]; - size_t u, slen; - - /* - * For all INTEGER values, get the pointer and length for the - * data bytes. - */ - num[0] = br_asn1_uint_prepare(NULL, 0); - num[1] = br_asn1_uint_prepare(pk->n, pk->nlen); - num[2] = br_asn1_uint_prepare(pk->e, pk->elen); - num[3] = br_asn1_uint_prepare(d, dlen); - num[4] = br_asn1_uint_prepare(sk->p, sk->plen); - num[5] = br_asn1_uint_prepare(sk->q, sk->qlen); - num[6] = br_asn1_uint_prepare(sk->dp, sk->dplen); - num[7] = br_asn1_uint_prepare(sk->dq, sk->dqlen); - num[8] = br_asn1_uint_prepare(sk->iq, sk->iqlen); - - /* - * Get the length of the SEQUENCE contents. - */ - slen = 0; - for (u = 0; u < 9; u ++) { - uint32_t ilen; - - ilen = num[u].asn1len; - slen += 1 + len_of_len(ilen) + ilen; - } - - if (dest == NULL) { - return 1 + len_of_len(slen) + slen; - } else { - unsigned char *buf; - size_t lenlen; - - buf = dest; - *buf ++ = 0x30; /* SEQUENCE tag */ - lenlen = br_asn1_encode_length(buf, slen); - buf += lenlen; - for (u = 0; u < 9; u ++) { - buf += br_asn1_encode_uint(buf, num[u]); - } - return 1 + lenlen + slen; - } -} diff --git a/third_party/bearssl/src/ghash_ctmul32.c b/third_party/bearssl/src/ghash_ctmul32.c deleted file mode 100644 index c66af4655..000000000 --- a/third_party/bearssl/src/ghash_ctmul32.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * This implementation uses 32-bit multiplications, and only the low - * 32 bits for each multiplication result. This is meant primarily for - * the ARM Cortex M0 and M0+, whose multiplication opcode does not yield - * the upper 32 bits; but it might also be useful on architectures where - * access to the upper 32 bits requires use of specific registers that - * create contention (e.g. on i386, "mul" necessarily outputs the result - * in edx:eax, while "imul" can use any registers but is limited to the - * low 32 bits). - * - * The implementation trick that is used here is bit-reversing (bit 0 - * is swapped with bit 31, bit 1 with bit 30, and so on). In GF(2)[X], - * for all values x and y, we have: - * rev32(x) * rev32(y) = rev64(x * y) - * In other words, if we bit-reverse (over 32 bits) the operands, then we - * bit-reverse (over 64 bits) the result. - */ - -/* - * Multiplication in GF(2)[X], truncated to its low 32 bits. - */ -static inline uint32_t -bmul32(uint32_t x, uint32_t y) -{ - uint32_t x0, x1, x2, x3; - uint32_t y0, y1, y2, y3; - uint32_t z0, z1, z2, z3; - - x0 = x & (uint32_t)0x11111111; - x1 = x & (uint32_t)0x22222222; - x2 = x & (uint32_t)0x44444444; - x3 = x & (uint32_t)0x88888888; - y0 = y & (uint32_t)0x11111111; - y1 = y & (uint32_t)0x22222222; - y2 = y & (uint32_t)0x44444444; - y3 = y & (uint32_t)0x88888888; - z0 = (x0 * y0) ^ (x1 * y3) ^ (x2 * y2) ^ (x3 * y1); - z1 = (x0 * y1) ^ (x1 * y0) ^ (x2 * y3) ^ (x3 * y2); - z2 = (x0 * y2) ^ (x1 * y1) ^ (x2 * y0) ^ (x3 * y3); - z3 = (x0 * y3) ^ (x1 * y2) ^ (x2 * y1) ^ (x3 * y0); - z0 &= (uint32_t)0x11111111; - z1 &= (uint32_t)0x22222222; - z2 &= (uint32_t)0x44444444; - z3 &= (uint32_t)0x88888888; - return z0 | z1 | z2 | z3; -} - -/* - * Bit-reverse a 32-bit word. - */ -static uint32_t -rev32(uint32_t x) -{ -#define RMS(m, s) do { \ - x = ((x & (uint32_t)(m)) << (s)) \ - | ((x >> (s)) & (uint32_t)(m)); \ - } while (0) - - RMS(0x55555555, 1); - RMS(0x33333333, 2); - RMS(0x0F0F0F0F, 4); - RMS(0x00FF00FF, 8); - return (x << 16) | (x >> 16); - -#undef RMS -} - -/* see bearssl_hash.h */ -void -br_ghash_ctmul32(void *y, const void *h, const void *data, size_t len) -{ - /* - * This implementation is similar to br_ghash_ctmul() except - * that we have to do the multiplication twice, with the - * "normal" and "bit reversed" operands. Hence we end up with - * eighteen 32-bit multiplications instead of nine. - */ - - const unsigned char *buf, *hb; - unsigned char *yb; - uint32_t yw[4]; - uint32_t hw[4], hwr[4]; - - buf = data; - yb = y; - hb = h; - yw[3] = br_dec32be(yb); - yw[2] = br_dec32be(yb + 4); - yw[1] = br_dec32be(yb + 8); - yw[0] = br_dec32be(yb + 12); - hw[3] = br_dec32be(hb); - hw[2] = br_dec32be(hb + 4); - hw[1] = br_dec32be(hb + 8); - hw[0] = br_dec32be(hb + 12); - hwr[3] = rev32(hw[3]); - hwr[2] = rev32(hw[2]); - hwr[1] = rev32(hw[1]); - hwr[0] = rev32(hw[0]); - while (len > 0) { - const unsigned char *src; - unsigned char tmp[16]; - int i; - uint32_t a[18], b[18], c[18]; - uint32_t d0, d1, d2, d3, d4, d5, d6, d7; - uint32_t zw[8]; - - if (len >= 16) { - src = buf; - buf += 16; - len -= 16; - } else { - memcpy(tmp, buf, len); - memset(tmp + len, 0, (sizeof tmp) - len); - src = tmp; - len = 0; - } - yw[3] ^= br_dec32be(src); - yw[2] ^= br_dec32be(src + 4); - yw[1] ^= br_dec32be(src + 8); - yw[0] ^= br_dec32be(src + 12); - - /* - * We are using Karatsuba: the 128x128 multiplication is - * reduced to three 64x64 multiplications, hence nine - * 32x32 multiplications. With the bit-reversal trick, - * we have to perform 18 32x32 multiplications. - */ - - /* - * y[0,1]*h[0,1] -> 0,1,4 - * y[2,3]*h[2,3] -> 2,3,5 - * (y[0,1]+y[2,3])*(h[0,1]+h[2,3]) -> 6,7,8 - */ - - a[0] = yw[0]; - a[1] = yw[1]; - a[2] = yw[2]; - a[3] = yw[3]; - a[4] = a[0] ^ a[1]; - a[5] = a[2] ^ a[3]; - a[6] = a[0] ^ a[2]; - a[7] = a[1] ^ a[3]; - a[8] = a[6] ^ a[7]; - - a[ 9] = rev32(yw[0]); - a[10] = rev32(yw[1]); - a[11] = rev32(yw[2]); - a[12] = rev32(yw[3]); - a[13] = a[ 9] ^ a[10]; - a[14] = a[11] ^ a[12]; - a[15] = a[ 9] ^ a[11]; - a[16] = a[10] ^ a[12]; - a[17] = a[15] ^ a[16]; - - b[0] = hw[0]; - b[1] = hw[1]; - b[2] = hw[2]; - b[3] = hw[3]; - b[4] = b[0] ^ b[1]; - b[5] = b[2] ^ b[3]; - b[6] = b[0] ^ b[2]; - b[7] = b[1] ^ b[3]; - b[8] = b[6] ^ b[7]; - - b[ 9] = hwr[0]; - b[10] = hwr[1]; - b[11] = hwr[2]; - b[12] = hwr[3]; - b[13] = b[ 9] ^ b[10]; - b[14] = b[11] ^ b[12]; - b[15] = b[ 9] ^ b[11]; - b[16] = b[10] ^ b[12]; - b[17] = b[15] ^ b[16]; - - for (i = 0; i < 18; i ++) { - c[i] = bmul32(a[i], b[i]); - } - - c[4] ^= c[0] ^ c[1]; - c[5] ^= c[2] ^ c[3]; - c[8] ^= c[6] ^ c[7]; - - c[13] ^= c[ 9] ^ c[10]; - c[14] ^= c[11] ^ c[12]; - c[17] ^= c[15] ^ c[16]; - - /* - * y[0,1]*h[0,1] -> 0,9^4,1^13,10 - * y[2,3]*h[2,3] -> 2,11^5,3^14,12 - * (y[0,1]+y[2,3])*(h[0,1]+h[2,3]) -> 6,15^8,7^17,16 - */ - d0 = c[0]; - d1 = c[4] ^ (rev32(c[9]) >> 1); - d2 = c[1] ^ c[0] ^ c[2] ^ c[6] ^ (rev32(c[13]) >> 1); - d3 = c[4] ^ c[5] ^ c[8] - ^ (rev32(c[10] ^ c[9] ^ c[11] ^ c[15]) >> 1); - d4 = c[2] ^ c[1] ^ c[3] ^ c[7] - ^ (rev32(c[13] ^ c[14] ^ c[17]) >> 1); - d5 = c[5] ^ (rev32(c[11] ^ c[10] ^ c[12] ^ c[16]) >> 1); - d6 = c[3] ^ (rev32(c[14]) >> 1); - d7 = rev32(c[12]) >> 1; - - zw[0] = d0 << 1; - zw[1] = (d1 << 1) | (d0 >> 31); - zw[2] = (d2 << 1) | (d1 >> 31); - zw[3] = (d3 << 1) | (d2 >> 31); - zw[4] = (d4 << 1) | (d3 >> 31); - zw[5] = (d5 << 1) | (d4 >> 31); - zw[6] = (d6 << 1) | (d5 >> 31); - zw[7] = (d7 << 1) | (d6 >> 31); - - for (i = 0; i < 4; i ++) { - uint32_t lw; - - lw = zw[i]; - zw[i + 4] ^= lw ^ (lw >> 1) ^ (lw >> 2) ^ (lw >> 7); - zw[i + 3] ^= (lw << 31) ^ (lw << 30) ^ (lw << 25); - } - memcpy(yw, zw + 4, sizeof yw); - } - br_enc32be(yb, yw[3]); - br_enc32be(yb + 4, yw[2]); - br_enc32be(yb + 8, yw[1]); - br_enc32be(yb + 12, yw[0]); -} diff --git a/third_party/bearssl/src/hkdf.c b/third_party/bearssl/src/hkdf.c deleted file mode 100644 index 6a36851b7..000000000 --- a/third_party/bearssl/src/hkdf.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -const unsigned char br_hkdf_no_salt = 0; - -/* see bearssl_kdf.h */ -void -br_hkdf_init(br_hkdf_context *hc, const br_hash_class *digest_vtable, - const void *salt, size_t salt_len) -{ - br_hmac_key_context kc; - unsigned char tmp[64]; - - if (salt == BR_HKDF_NO_SALT) { - salt = tmp; - salt_len = br_digest_size(digest_vtable); - memset(tmp, 0, salt_len); - } - br_hmac_key_init(&kc, digest_vtable, salt, salt_len); - br_hmac_init(&hc->u.hmac_ctx, &kc, 0); - hc->dig_len = br_hmac_size(&hc->u.hmac_ctx); -} - -/* see bearssl_kdf.h */ -void -br_hkdf_inject(br_hkdf_context *hc, const void *ikm, size_t ikm_len) -{ - br_hmac_update(&hc->u.hmac_ctx, ikm, ikm_len); -} - -/* see bearssl_kdf.h */ -void -br_hkdf_flip(br_hkdf_context *hc) -{ - unsigned char tmp[64]; - - br_hmac_out(&hc->u.hmac_ctx, tmp); - br_hmac_key_init(&hc->u.prk_ctx, - br_hmac_get_digest(&hc->u.hmac_ctx), tmp, hc->dig_len); - hc->ptr = hc->dig_len; - hc->chunk_num = 0; -} - -/* see bearssl_kdf.h */ -size_t -br_hkdf_produce(br_hkdf_context *hc, - const void *info, size_t info_len, void *out, size_t out_len) -{ - size_t tlen; - - tlen = 0; - while (out_len > 0) { - size_t clen; - - if (hc->ptr == hc->dig_len) { - br_hmac_context hmac_ctx; - unsigned char x; - - hc->chunk_num ++; - if (hc->chunk_num == 256) { - return tlen; - } - x = hc->chunk_num; - br_hmac_init(&hmac_ctx, &hc->u.prk_ctx, 0); - if (x != 1) { - br_hmac_update(&hmac_ctx, hc->buf, hc->dig_len); - } - br_hmac_update(&hmac_ctx, info, info_len); - br_hmac_update(&hmac_ctx, &x, 1); - br_hmac_out(&hmac_ctx, hc->buf); - hc->ptr = 0; - } - clen = hc->dig_len - hc->ptr; - if (clen > out_len) { - clen = out_len; - } - memcpy(out, hc->buf + hc->ptr, clen); - out = (unsigned char *)out + clen; - out_len -= clen; - hc->ptr += clen; - tlen += clen; - } - return tlen; -} diff --git a/third_party/bearssl/src/i15_add.c b/third_party/bearssl/src/i15_add.c deleted file mode 100644 index 97e29b825..000000000 --- a/third_party/bearssl/src/i15_add.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i15_add(uint16_t *a, const uint16_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; - - cc = 0; - m = (a[0] + 31) >> 4; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; - - aw = a[u]; - bw = b[u]; - naw = aw + bw + cc; - cc = naw >> 15; - a[u] = MUX(ctl, naw & 0x7FFF, aw); - } - return cc; -} diff --git a/third_party/bearssl/src/i15_bitlen.c b/third_party/bearssl/src/i15_bitlen.c deleted file mode 100644 index ad7446718..000000000 --- a/third_party/bearssl/src/i15_bitlen.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i15_bit_length(uint16_t *x, size_t xlen) -{ - uint32_t tw, twk; - - tw = 0; - twk = 0; - while (xlen -- > 0) { - uint32_t w, c; - - c = EQ(tw, 0); - w = x[xlen]; - tw = MUX(c, w, tw); - twk = MUX(c, (uint32_t)xlen, twk); - } - return (twk << 4) + BIT_LENGTH(tw); -} diff --git a/third_party/bearssl/src/i15_decmod.c b/third_party/bearssl/src/i15_decmod.c deleted file mode 100644 index 6076c57b5..000000000 --- a/third_party/bearssl/src/i15_decmod.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i15_decode_mod(uint16_t *x, const void *src, size_t len, const uint16_t *m) -{ - /* - * Two-pass algorithm: in the first pass, we determine whether the - * value fits; in the second pass, we do the actual write. - * - * During the first pass, 'r' contains the comparison result so - * far: - * 0x00000000 value is equal to the modulus - * 0x00000001 value is greater than the modulus - * 0xFFFFFFFF value is lower than the modulus - * - * Since we iterate starting with the least significant bytes (at - * the end of src[]), each new comparison overrides the previous - * except when the comparison yields 0 (equal). - * - * During the second pass, 'r' is either 0xFFFFFFFF (value fits) - * or 0x00000000 (value does not fit). - * - * We must iterate over all bytes of the source, _and_ possibly - * some extra virtual bytes (with value 0) so as to cover the - * complete modulus as well. We also add 4 such extra bytes beyond - * the modulus length because it then guarantees that no accumulated - * partial word remains to be processed. - */ - const unsigned char *buf; - size_t mlen, tlen; - int pass; - uint32_t r; - - buf = src; - mlen = (m[0] + 15) >> 4; - tlen = (mlen << 1); - if (tlen < len) { - tlen = len; - } - tlen += 4; - r = 0; - for (pass = 0; pass < 2; pass ++) { - size_t u, v; - uint32_t acc; - int acc_len; - - v = 1; - acc = 0; - acc_len = 0; - for (u = 0; u < tlen; u ++) { - uint32_t b; - - if (u < len) { - b = buf[len - 1 - u]; - } else { - b = 0; - } - acc |= (b << acc_len); - acc_len += 8; - if (acc_len >= 15) { - uint32_t xw; - - xw = acc & (uint32_t)0x7FFF; - acc_len -= 15; - acc = b >> (8 - acc_len); - if (v <= mlen) { - if (pass) { - x[v] = r & xw; - } else { - uint32_t cc; - - cc = (uint32_t)CMP(xw, m[v]); - r = MUX(EQ(cc, 0), r, cc); - } - } else { - if (!pass) { - r = MUX(EQ(xw, 0), r, 1); - } - } - v ++; - } - } - - /* - * When we reach this point at the end of the first pass: - * r is either 0, 1 or -1; we want to set r to 0 if it - * is equal to 0 or 1, and leave it to -1 otherwise. - * - * When we reach this point at the end of the second pass: - * r is either 0 or -1; we want to leave that value - * untouched. This is a subcase of the previous. - */ - r >>= 1; - r |= (r << 1); - } - - x[0] = m[0]; - return r & (uint32_t)1; -} diff --git a/third_party/bearssl/src/i15_decode.c b/third_party/bearssl/src/i15_decode.c deleted file mode 100644 index fc2c0be0d..000000000 --- a/third_party/bearssl/src/i15_decode.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i15_decode(uint16_t *x, const void *src, size_t len) -{ - const unsigned char *buf; - size_t v; - uint32_t acc; - int acc_len; - - buf = src; - v = 1; - acc = 0; - acc_len = 0; - while (len -- > 0) { - uint32_t b; - - b = buf[len]; - acc |= (b << acc_len); - acc_len += 8; - if (acc_len >= 15) { - x[v ++] = acc & 0x7FFF; - acc_len -= 15; - acc >>= 15; - } - } - if (acc_len != 0) { - x[v ++] = acc; - } - x[0] = br_i15_bit_length(x + 1, v - 1); -} diff --git a/third_party/bearssl/src/i15_decred.c b/third_party/bearssl/src/i15_decred.c deleted file mode 100644 index 81e7dd1bd..000000000 --- a/third_party/bearssl/src/i15_decred.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i15_decode_reduce(uint16_t *x, - const void *src, size_t len, const uint16_t *m) -{ - uint32_t m_ebitlen, m_rbitlen; - size_t mblen, k; - const unsigned char *buf; - uint32_t acc; - int acc_len; - - /* - * Get the encoded bit length. - */ - m_ebitlen = m[0]; - - /* - * Special case for an invalid (null) modulus. - */ - if (m_ebitlen == 0) { - x[0] = 0; - return; - } - - /* - * Clear the destination. - */ - br_i15_zero(x, m_ebitlen); - - /* - * First decode directly as many bytes as possible. This requires - * computing the actual bit length. - */ - m_rbitlen = m_ebitlen >> 4; - m_rbitlen = (m_ebitlen & 15) + (m_rbitlen << 4) - m_rbitlen; - mblen = (m_rbitlen + 7) >> 3; - k = mblen - 1; - if (k >= len) { - br_i15_decode(x, src, len); - x[0] = m_ebitlen; - return; - } - buf = src; - br_i15_decode(x, buf, k); - x[0] = m_ebitlen; - - /* - * Input remaining bytes, using 15-bit words. - */ - acc = 0; - acc_len = 0; - while (k < len) { - uint32_t v; - - v = buf[k ++]; - acc = (acc << 8) | v; - acc_len += 8; - if (acc_len >= 15) { - br_i15_muladd_small(x, acc >> (acc_len - 15), m); - acc_len -= 15; - acc &= ~((uint32_t)-1 << acc_len); - } - } - - /* - * We may have some bits accumulated. We then perform a shift to - * be able to inject these bits as a full 15-bit word. - */ - if (acc_len != 0) { - acc = (acc | (x[1] << acc_len)) & 0x7FFF; - br_i15_rshift(x, 15 - acc_len); - br_i15_muladd_small(x, acc, m); - } -} diff --git a/third_party/bearssl/src/i15_encode.c b/third_party/bearssl/src/i15_encode.c deleted file mode 100644 index 50668f47b..000000000 --- a/third_party/bearssl/src/i15_encode.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i15_encode(void *dst, size_t len, const uint16_t *x) -{ - unsigned char *buf; - size_t u, xlen; - uint32_t acc; - int acc_len; - - xlen = (x[0] + 15) >> 4; - if (xlen == 0) { - memset(dst, 0, len); - return; - } - u = 1; - acc = 0; - acc_len = 0; - buf = dst; - while (len -- > 0) { - if (acc_len < 8) { - if (u <= xlen) { - acc += (uint32_t)x[u ++] << acc_len; - } - acc_len += 15; - } - buf[len] = (unsigned char)acc; - acc >>= 8; - acc_len -= 8; - } -} diff --git a/third_party/bearssl/src/i15_fmont.c b/third_party/bearssl/src/i15_fmont.c deleted file mode 100644 index 3450b7237..000000000 --- a/third_party/bearssl/src/i15_fmont.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i15_from_monty(uint16_t *x, const uint16_t *m, uint16_t m0i) -{ - size_t len, u, v; - - len = (m[0] + 15) >> 4; - for (u = 0; u < len; u ++) { - uint32_t f, cc; - - f = MUL15(x[1], m0i) & 0x7FFF; - cc = 0; - for (v = 0; v < len; v ++) { - uint32_t z; - - z = (uint32_t)x[v + 1] + MUL15(f, m[v + 1]) + cc; - cc = z >> 15; - if (v != 0) { - x[v] = z & 0x7FFF; - } - } - x[len] = cc; - } - - /* - * We may have to do an extra subtraction, but only if the - * value in x[] is indeed greater than or equal to that of m[], - * which is why we must do two calls (first call computes the - * carry, second call performs the subtraction only if the carry - * is 0). - */ - br_i15_sub(x, m, NOT(br_i15_sub(x, m, 0))); -} diff --git a/third_party/bearssl/src/i15_iszero.c b/third_party/bearssl/src/i15_iszero.c deleted file mode 100644 index d4b6f10b2..000000000 --- a/third_party/bearssl/src/i15_iszero.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i15_iszero(const uint16_t *x) -{ - uint32_t z; - size_t u; - - z = 0; - for (u = (x[0] + 15) >> 4; u > 0; u --) { - z |= x[u]; - } - return ~(z | -z) >> 31; -} diff --git a/third_party/bearssl/src/i15_moddiv.c b/third_party/bearssl/src/i15_moddiv.c deleted file mode 100644 index 45af756d3..000000000 --- a/third_party/bearssl/src/i15_moddiv.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * In this file, we handle big integers with a custom format, i.e. - * without the usual one-word header. Value is split into 15-bit words, - * each stored in a 16-bit slot (top bit is zero) in little-endian - * order. The length (in words) is provided explicitly. In some cases, - * the value can be negative (using two's complement representation). In - * some cases, the top word is allowed to have a 16th bit. - */ - -/* - * Negate big integer conditionally. The value consists of 'len' words, - * with 15 bits in each word (the top bit of each word should be 0, - * except possibly for the last word). If 'ctl' is 1, the negation is - * computed; otherwise, if 'ctl' is 0, then the value is unchanged. - */ -static void -cond_negate(uint16_t *a, size_t len, uint32_t ctl) -{ - size_t k; - uint32_t cc, xm; - - cc = ctl; - xm = 0x7FFF & -ctl; - for (k = 0; k < len; k ++) { - uint32_t aw; - - aw = a[k]; - aw = (aw ^ xm) + cc; - a[k] = aw & 0x7FFF; - cc = (aw >> 15) & 1; - } -} - -/* - * Finish modular reduction. Rules on input parameters: - * - * if neg = 1, then -m <= a < 0 - * if neg = 0, then 0 <= a < 2*m - * - * If neg = 0, then the top word of a[] may use 16 bits. - * - * Also, modulus m must be odd. - */ -static void -finish_mod(uint16_t *a, size_t len, const uint16_t *m, uint32_t neg) -{ - size_t k; - uint32_t cc, xm, ym; - - /* - * First pass: compare a (assumed nonnegative) with m. - */ - cc = 0; - for (k = 0; k < len; k ++) { - uint32_t aw, mw; - - aw = a[k]; - mw = m[k]; - cc = (aw - mw - cc) >> 31; - } - - /* - * At this point: - * if neg = 1, then we must add m (regardless of cc) - * if neg = 0 and cc = 0, then we must subtract m - * if neg = 0 and cc = 1, then we must do nothing - */ - xm = 0x7FFF & -neg; - ym = -(neg | (1 - cc)); - cc = neg; - for (k = 0; k < len; k ++) { - uint32_t aw, mw; - - aw = a[k]; - mw = (m[k] ^ xm) & ym; - aw = aw - mw - cc; - a[k] = aw & 0x7FFF; - cc = aw >> 31; - } -} - -/* - * Compute: - * a <- (a*pa+b*pb)/(2^15) - * b <- (a*qa+b*qb)/(2^15) - * The division is assumed to be exact (i.e. the low word is dropped). - * If the final a is negative, then it is negated. Similarly for b. - * Returned value is the combination of two bits: - * bit 0: 1 if a had to be negated, 0 otherwise - * bit 1: 1 if b had to be negated, 0 otherwise - * - * Factors pa, pb, qa and qb must be at most 2^15 in absolute value. - * Source integers a and b must be nonnegative; top word is not allowed - * to contain an extra 16th bit. - */ -static uint32_t -co_reduce(uint16_t *a, uint16_t *b, size_t len, - int32_t pa, int32_t pb, int32_t qa, int32_t qb) -{ - size_t k; - int32_t cca, ccb; - uint32_t nega, negb; - - cca = 0; - ccb = 0; - for (k = 0; k < len; k ++) { - uint32_t wa, wb, za, zb; - uint16_t tta, ttb; - - /* - * Since: - * |pa| <= 2^15 - * |pb| <= 2^15 - * 0 <= wa <= 2^15 - 1 - * 0 <= wb <= 2^15 - 1 - * |cca| <= 2^16 - 1 - * Then: - * |za| <= (2^15-1)*(2^16) + (2^16-1) = 2^31 - 1 - * - * Thus, the new value of cca is such that |cca| <= 2^16 - 1. - * The same applies to ccb. - */ - wa = a[k]; - wb = b[k]; - za = wa * (uint32_t)pa + wb * (uint32_t)pb + (uint32_t)cca; - zb = wa * (uint32_t)qa + wb * (uint32_t)qb + (uint32_t)ccb; - if (k > 0) { - a[k - 1] = za & 0x7FFF; - b[k - 1] = zb & 0x7FFF; - } - tta = za >> 15; - ttb = zb >> 15; - cca = *(int16_t *)&tta; - ccb = *(int16_t *)&ttb; - } - a[len - 1] = (uint16_t)cca; - b[len - 1] = (uint16_t)ccb; - nega = (uint32_t)cca >> 31; - negb = (uint32_t)ccb >> 31; - cond_negate(a, len, nega); - cond_negate(b, len, negb); - return nega | (negb << 1); -} - -/* - * Compute: - * a <- (a*pa+b*pb)/(2^15) mod m - * b <- (a*qa+b*qb)/(2^15) mod m - * - * m0i is equal to -1/m[0] mod 2^15. - * - * Factors pa, pb, qa and qb must be at most 2^15 in absolute value. - * Source integers a and b must be nonnegative; top word is not allowed - * to contain an extra 16th bit. - */ -static void -co_reduce_mod(uint16_t *a, uint16_t *b, size_t len, - int32_t pa, int32_t pb, int32_t qa, int32_t qb, - const uint16_t *m, uint16_t m0i) -{ - size_t k; - int32_t cca, ccb, fa, fb; - - cca = 0; - ccb = 0; - fa = ((a[0] * (uint32_t)pa + b[0] * (uint32_t)pb) * m0i) & 0x7FFF; - fb = ((a[0] * (uint32_t)qa + b[0] * (uint32_t)qb) * m0i) & 0x7FFF; - for (k = 0; k < len; k ++) { - uint32_t wa, wb, za, zb; - uint32_t tta, ttb; - - /* - * In this loop, carries 'cca' and 'ccb' always fit on - * 17 bits (in absolute value). - */ - wa = a[k]; - wb = b[k]; - za = wa * (uint32_t)pa + wb * (uint32_t)pb - + m[k] * (uint32_t)fa + (uint32_t)cca; - zb = wa * (uint32_t)qa + wb * (uint32_t)qb - + m[k] * (uint32_t)fb + (uint32_t)ccb; - if (k > 0) { - a[k - 1] = za & 0x7FFF; - b[k - 1] = zb & 0x7FFF; - } - - /* - * The XOR-and-sub construction below does an arithmetic - * right shift in a portable way (technically, right-shifting - * a negative signed value is implementation-defined in C). - */ -#define M ((uint32_t)1 << 16) - tta = za >> 15; - ttb = zb >> 15; - tta = (tta ^ M) - M; - ttb = (ttb ^ M) - M; - cca = *(int32_t *)&tta; - ccb = *(int32_t *)&ttb; -#undef M - } - a[len - 1] = (uint32_t)cca; - b[len - 1] = (uint32_t)ccb; - - /* - * At this point: - * -m <= a < 2*m - * -m <= b < 2*m - * (this is a case of Montgomery reduction) - * The top word of 'a' and 'b' may have a 16-th bit set. - * We may have to add or subtract the modulus. - */ - finish_mod(a, len, m, (uint32_t)cca >> 31); - finish_mod(b, len, m, (uint32_t)ccb >> 31); -} - -/* see inner.h */ -uint32_t -br_i15_moddiv(uint16_t *x, const uint16_t *y, const uint16_t *m, uint16_t m0i, - uint16_t *t) -{ - /* - * Algorithm is an extended binary GCD. We maintain four values - * a, b, u and v, with the following invariants: - * - * a * x = y * u mod m - * b * x = y * v mod m - * - * Starting values are: - * - * a = y - * b = m - * u = x - * v = 0 - * - * The formal definition of the algorithm is a sequence of steps: - * - * - If a is even, then a <- a/2 and u <- u/2 mod m. - * - Otherwise, if b is even, then b <- b/2 and v <- v/2 mod m. - * - Otherwise, if a > b, then a <- (a-b)/2 and u <- (u-v)/2 mod m. - * - Otherwise, b <- (b-a)/2 and v <- (v-u)/2 mod m. - * - * Algorithm stops when a = b. At that point, they both are equal - * to GCD(y,m); the modular division succeeds if that value is 1. - * The result of the modular division is then u (or v: both are - * equal at that point). - * - * Each step makes either a or b shrink by at least one bit; hence, - * if m has bit length k bits, then 2k-2 steps are sufficient. - * - * - * Though complexity is quadratic in the size of m, the bit-by-bit - * processing is not very efficient. We can speed up processing by - * remarking that the decisions are taken based only on observation - * of the top and low bits of a and b. - * - * In the loop below, at each iteration, we use the two top words - * of a and b, and the low words of a and b, to compute reduction - * parameters pa, pb, qa and qb such that the new values for a - * and b are: - * - * a' = (a*pa + b*pb) / (2^15) - * b' = (a*qa + b*qb) / (2^15) - * - * the division being exact. - * - * Since the choices are based on the top words, they may be slightly - * off, requiring an optional correction: if a' < 0, then we replace - * pa with -pa, and pb with -pb. The total length of a and b is - * thus reduced by at least 14 bits at each iteration. - * - * The stopping conditions are still the same, though: when a - * and b become equal, they must be both odd (since m is odd, - * the GCD cannot be even), therefore the next operation is a - * subtraction, and one of the values becomes 0. At that point, - * nothing else happens, i.e. one value is stuck at 0, and the - * other one is the GCD. - */ - size_t len, k; - uint16_t *a, *b, *u, *v; - uint32_t num, r; - - len = (m[0] + 15) >> 4; - a = t; - b = a + len; - u = x + 1; - v = b + len; - memcpy(a, y + 1, len * sizeof *y); - memcpy(b, m + 1, len * sizeof *m); - memset(v, 0, len * sizeof *v); - - /* - * Loop below ensures that a and b are reduced by some bits each, - * for a total of at least 14 bits. - */ - for (num = ((m[0] - (m[0] >> 4)) << 1) + 14; num >= 14; num -= 14) { - size_t j; - uint32_t c0, c1; - uint32_t a0, a1, b0, b1; - uint32_t a_hi, b_hi, a_lo, b_lo; - int32_t pa, pb, qa, qb; - int i; - - /* - * Extract top words of a and b. If j is the highest - * index >= 1 such that a[j] != 0 or b[j] != 0, then we want - * (a[j] << 15) + a[j - 1], and (b[j] << 15) + b[j - 1]. - * If a and b are down to one word each, then we use a[0] - * and b[0]. - */ - c0 = (uint32_t)-1; - c1 = (uint32_t)-1; - a0 = 0; - a1 = 0; - b0 = 0; - b1 = 0; - j = len; - while (j -- > 0) { - uint32_t aw, bw; - - aw = a[j]; - bw = b[j]; - a0 ^= (a0 ^ aw) & c0; - a1 ^= (a1 ^ aw) & c1; - b0 ^= (b0 ^ bw) & c0; - b1 ^= (b1 ^ bw) & c1; - c1 = c0; - c0 &= (((aw | bw) + 0xFFFF) >> 16) - (uint32_t)1; - } - - /* - * If c1 = 0, then we grabbed two words for a and b. - * If c1 != 0 but c0 = 0, then we grabbed one word. It - * is not possible that c1 != 0 and c0 != 0, because that - * would mean that both integers are zero. - */ - a1 |= a0 & c1; - a0 &= ~c1; - b1 |= b0 & c1; - b0 &= ~c1; - a_hi = (a0 << 15) + a1; - b_hi = (b0 << 15) + b1; - a_lo = a[0]; - b_lo = b[0]; - - /* - * Compute reduction factors: - * - * a' = a*pa + b*pb - * b' = a*qa + b*qb - * - * such that a' and b' are both multiple of 2^15, but are - * only marginally larger than a and b. - */ - pa = 1; - pb = 0; - qa = 0; - qb = 1; - for (i = 0; i < 15; i ++) { - /* - * At each iteration: - * - * a <- (a-b)/2 if: a is odd, b is odd, a_hi > b_hi - * b <- (b-a)/2 if: a is odd, b is odd, a_hi <= b_hi - * a <- a/2 if: a is even - * b <- b/2 if: a is odd, b is even - * - * We multiply a_lo and b_lo by 2 at each - * iteration, thus a division by 2 really is a - * non-multiplication by 2. - */ - uint32_t r, oa, ob, cAB, cBA, cA; - - /* - * cAB = 1 if b must be subtracted from a - * cBA = 1 if a must be subtracted from b - * cA = 1 if a is divided by 2, 0 otherwise - * - * Rules: - * - * cAB and cBA cannot be both 1. - * if a is not divided by 2, b is. - */ - r = GT(a_hi, b_hi); - oa = (a_lo >> i) & 1; - ob = (b_lo >> i) & 1; - cAB = oa & ob & r; - cBA = oa & ob & NOT(r); - cA = cAB | NOT(oa); - - /* - * Conditional subtractions. - */ - a_lo -= b_lo & -cAB; - a_hi -= b_hi & -cAB; - pa -= qa & -(int32_t)cAB; - pb -= qb & -(int32_t)cAB; - b_lo -= a_lo & -cBA; - b_hi -= a_hi & -cBA; - qa -= pa & -(int32_t)cBA; - qb -= pb & -(int32_t)cBA; - - /* - * Shifting. - */ - a_lo += a_lo & (cA - 1); - pa += pa & ((int32_t)cA - 1); - pb += pb & ((int32_t)cA - 1); - a_hi ^= (a_hi ^ (a_hi >> 1)) & -cA; - b_lo += b_lo & -cA; - qa += qa & -(int32_t)cA; - qb += qb & -(int32_t)cA; - b_hi ^= (b_hi ^ (b_hi >> 1)) & (cA - 1); - } - - /* - * Replace a and b with new values a' and b'. - */ - r = co_reduce(a, b, len, pa, pb, qa, qb); - pa -= pa * ((r & 1) << 1); - pb -= pb * ((r & 1) << 1); - qa -= qa * (r & 2); - qb -= qb * (r & 2); - co_reduce_mod(u, v, len, pa, pb, qa, qb, m + 1, m0i); - } - - /* - * Now one of the arrays should be 0, and the other contains - * the GCD. If a is 0, then u is 0 as well, and v contains - * the division result. - * Result is correct if and only if GCD is 1. - */ - r = (a[0] | b[0]) ^ 1; - u[0] |= v[0]; - for (k = 1; k < len; k ++) { - r |= a[k] | b[k]; - u[k] |= v[k]; - } - return EQ0(r); -} diff --git a/third_party/bearssl/src/i15_modpow.c b/third_party/bearssl/src/i15_modpow.c deleted file mode 100644 index 9bf304e50..000000000 --- a/third_party/bearssl/src/i15_modpow.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i15_modpow(uint16_t *x, - const unsigned char *e, size_t elen, - const uint16_t *m, uint16_t m0i, uint16_t *t1, uint16_t *t2) -{ - size_t mlen; - unsigned k; - - mlen = ((m[0] + 31) >> 4) * sizeof m[0]; - memcpy(t1, x, mlen); - br_i15_to_monty(t1, m); - br_i15_zero(x, m[0]); - x[1] = 1; - for (k = 0; k < ((unsigned)elen << 3); k ++) { - uint32_t ctl; - - ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1; - br_i15_montymul(t2, x, t1, m, m0i); - CCOPY(ctl, x, t2, mlen); - br_i15_montymul(t2, t1, t1, m, m0i); - memcpy(t1, t2, mlen); - } -} diff --git a/third_party/bearssl/src/i15_modpow2.c b/third_party/bearssl/src/i15_modpow2.c deleted file mode 100644 index 4b3211864..000000000 --- a/third_party/bearssl/src/i15_modpow2.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i15_modpow_opt(uint16_t *x, - const unsigned char *e, size_t elen, - const uint16_t *m, uint16_t m0i, uint16_t *tmp, size_t twlen) -{ - size_t mlen, mwlen; - uint16_t *t1, *t2, *base; - size_t u, v; - uint32_t acc; - int acc_len, win_len; - - /* - * Get modulus size. - */ - mwlen = (m[0] + 31) >> 4; - mlen = mwlen * sizeof m[0]; - mwlen += (mwlen & 1); - t1 = tmp; - t2 = tmp + mwlen; - - /* - * Compute possible window size, with a maximum of 5 bits. - * When the window has size 1 bit, we use a specific code - * that requires only two temporaries. Otherwise, for a - * window of k bits, we need 2^k+1 temporaries. - */ - if (twlen < (mwlen << 1)) { - return 0; - } - for (win_len = 5; win_len > 1; win_len --) { - if ((((uint32_t)1 << win_len) + 1) * mwlen <= twlen) { - break; - } - } - - /* - * Everything is done in Montgomery representation. - */ - br_i15_to_monty(x, m); - - /* - * Compute window contents. If the window has size one bit only, - * then t2 is set to x; otherwise, t2[0] is left untouched, and - * t2[k] is set to x^k (for k >= 1). - */ - if (win_len == 1) { - memcpy(t2, x, mlen); - } else { - memcpy(t2 + mwlen, x, mlen); - base = t2 + mwlen; - for (u = 2; u < ((unsigned)1 << win_len); u ++) { - br_i15_montymul(base + mwlen, base, x, m, m0i); - base += mwlen; - } - } - - /* - * We need to set x to 1, in Montgomery representation. This can - * be done efficiently by setting the high word to 1, then doing - * one word-sized shift. - */ - br_i15_zero(x, m[0]); - x[(m[0] + 15) >> 4] = 1; - br_i15_muladd_small(x, 0, m); - - /* - * We process bits from most to least significant. At each - * loop iteration, we have acc_len bits in acc. - */ - acc = 0; - acc_len = 0; - while (acc_len > 0 || elen > 0) { - int i, k; - uint32_t bits; - - /* - * Get the next bits. - */ - k = win_len; - if (acc_len < win_len) { - if (elen > 0) { - acc = (acc << 8) | *e ++; - elen --; - acc_len += 8; - } else { - k = acc_len; - } - } - bits = (acc >> (acc_len - k)) & (((uint32_t)1 << k) - 1); - acc_len -= k; - - /* - * We could get exactly k bits. Compute k squarings. - */ - for (i = 0; i < k; i ++) { - br_i15_montymul(t1, x, x, m, m0i); - memcpy(x, t1, mlen); - } - - /* - * Window lookup: we want to set t2 to the window - * lookup value, assuming the bits are non-zero. If - * the window length is 1 bit only, then t2 is - * already set; otherwise, we do a constant-time lookup. - */ - if (win_len > 1) { - br_i15_zero(t2, m[0]); - base = t2 + mwlen; - for (u = 1; u < ((uint32_t)1 << k); u ++) { - uint32_t mask; - - mask = -EQ(u, bits); - for (v = 1; v < mwlen; v ++) { - t2[v] |= mask & base[v]; - } - base += mwlen; - } - } - - /* - * Multiply with the looked-up value. We keep the - * product only if the exponent bits are not all-zero. - */ - br_i15_montymul(t1, x, t2, m, m0i); - CCOPY(NEQ(bits, 0), x, t1, mlen); - } - - /* - * Convert back from Montgomery representation, and exit. - */ - br_i15_from_monty(x, m, m0i); - return 1; -} diff --git a/third_party/bearssl/src/i15_montmul.c b/third_party/bearssl/src/i15_montmul.c deleted file mode 100644 index e98bc32c4..000000000 --- a/third_party/bearssl/src/i15_montmul.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i15_montymul(uint16_t *d, const uint16_t *x, const uint16_t *y, - const uint16_t *m, uint16_t m0i) -{ - size_t len, len4, u, v; - uint32_t dh; - - len = (m[0] + 15) >> 4; - len4 = len & ~(size_t)3; - br_i15_zero(d, m[0]); - dh = 0; - for (u = 0; u < len; u ++) { - uint32_t f, xu, r, zh; - - xu = x[u + 1]; - f = MUL15((d[1] + MUL15(x[u + 1], y[1])) & 0x7FFF, m0i) - & 0x7FFF; -#if BR_ARMEL_CORTEXM_GCC - if (len4 != 0) { - uint16_t *limit; - - limit = d + len4; - asm volatile ( -"\n\ - @ carry: r=r2 \n\ - @ multipliers: xu=r3 f=r4 \n\ - @ base registers: d+v=r5 y+v=r6 m+v=r7 \n\ - @ r8 contains 0x7FFF \n\ - @ r9 contains d+len4 \n\ - ldr r0, %[limit] \n\ - ldr r3, %[xu] \n\ - mov r9, r0 \n\ - ldr r4, %[f] \n\ - eor r2, r2 \n\ - ldr r5, %[d] \n\ - sub r1, r2, #1 \n\ - ldr r6, %[y] \n\ - lsr r1, r1, #17 \n\ - ldr r7, %[m] \n\ - mov r8, r1 \n\ -loop%=: \n\ - ldrh r0, [r6, #2] \n\ - ldrh r1, [r7, #2] \n\ - mul r0, r3 \n\ - mul r1, r4 \n\ - add r2, r0, r2 \n\ - ldrh r0, [r5, #2] \n\ - add r2, r1, r2 \n\ - mov r1, r8 \n\ - add r2, r0, r2 \n\ - and r1, r2 \n\ - lsr r2, r2, #15 \n\ - strh r1, [r5, #0] \n\ - \n\ - ldrh r0, [r6, #4] \n\ - ldrh r1, [r7, #4] \n\ - mul r0, r3 \n\ - mul r1, r4 \n\ - add r2, r0, r2 \n\ - ldrh r0, [r5, #4] \n\ - add r2, r1, r2 \n\ - mov r1, r8 \n\ - add r2, r0, r2 \n\ - and r1, r2 \n\ - lsr r2, r2, #15 \n\ - strh r1, [r5, #2] \n\ - \n\ - ldrh r0, [r6, #6] \n\ - ldrh r1, [r7, #6] \n\ - mul r0, r3 \n\ - mul r1, r4 \n\ - add r2, r0, r2 \n\ - ldrh r0, [r5, #6] \n\ - add r2, r1, r2 \n\ - mov r1, r8 \n\ - add r2, r0, r2 \n\ - and r1, r2 \n\ - lsr r2, r2, #15 \n\ - strh r1, [r5, #4] \n\ - \n\ - ldrh r0, [r6, #8] \n\ - ldrh r1, [r7, #8] \n\ - mul r0, r3 \n\ - mul r1, r4 \n\ - add r2, r0, r2 \n\ - ldrh r0, [r5, #8] \n\ - add r2, r1, r2 \n\ - mov r1, r8 \n\ - add r2, r0, r2 \n\ - and r1, r2 \n\ - lsr r2, r2, #15 \n\ - strh r1, [r5, #6] \n\ - \n\ - add r5, r5, #8 \n\ - add r6, r6, #8 \n\ - add r7, r7, #8 \n\ - cmp r5, r9 \n\ - bne loop%= \n\ - \n\ - str r2, %[carry] \n\ -" -: [carry] "=m" (r) -: [xu] "m" (xu), [f] "m" (f), [d] "m" (d), [y] "m" (y), - [m] "m" (m), [limit] "m" (limit) -: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); - } else { - r = 0; - } - v = len4; -#else - r = 0; - for (v = 0; v < len4; v += 4) { - uint32_t z; - - z = d[v + 1] + MUL15(xu, y[v + 1]) - + MUL15(f, m[v + 1]) + r; - r = z >> 15; - d[v + 0] = z & 0x7FFF; - z = d[v + 2] + MUL15(xu, y[v + 2]) - + MUL15(f, m[v + 2]) + r; - r = z >> 15; - d[v + 1] = z & 0x7FFF; - z = d[v + 3] + MUL15(xu, y[v + 3]) - + MUL15(f, m[v + 3]) + r; - r = z >> 15; - d[v + 2] = z & 0x7FFF; - z = d[v + 4] + MUL15(xu, y[v + 4]) - + MUL15(f, m[v + 4]) + r; - r = z >> 15; - d[v + 3] = z & 0x7FFF; - } -#endif - for (; v < len; v ++) { - uint32_t z; - - z = d[v + 1] + MUL15(xu, y[v + 1]) - + MUL15(f, m[v + 1]) + r; - r = z >> 15; - d[v + 0] = z & 0x7FFF; - } - - zh = dh + r; - d[len] = zh & 0x7FFF; - dh = zh >> 15; - } - - /* - * Restore the bit length (it was overwritten in the loop above). - */ - d[0] = m[0]; - - /* - * d[] may be greater than m[], but it is still lower than twice - * the modulus. - */ - br_i15_sub(d, m, NEQ(dh, 0) | NOT(br_i15_sub(d, m, 0))); -} diff --git a/third_party/bearssl/src/i15_mulacc.c b/third_party/bearssl/src/i15_mulacc.c deleted file mode 100644 index 7a073ac67..000000000 --- a/third_party/bearssl/src/i15_mulacc.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i15_mulacc(uint16_t *d, const uint16_t *a, const uint16_t *b) -{ - size_t alen, blen, u; - unsigned dl, dh; - - alen = (a[0] + 15) >> 4; - blen = (b[0] + 15) >> 4; - - /* - * Announced bit length of d[] will be the sum of the announced - * bit lengths of a[] and b[]; but the lengths are encoded. - */ - dl = (a[0] & 15) + (b[0] & 15); - dh = (a[0] >> 4) + (b[0] >> 4); - d[0] = (dh << 4) + dl + (~(uint32_t)(dl - 15) >> 31); - - for (u = 0; u < blen; u ++) { - uint32_t f; - size_t v; - uint32_t cc; - - f = b[1 + u]; - cc = 0; - for (v = 0; v < alen; v ++) { - uint32_t z; - - z = (uint32_t)d[1 + u + v] + MUL15(f, a[1 + v]) + cc; - cc = z >> 15; - d[1 + u + v] = z & 0x7FFF; - } - d[1 + u + alen] = cc; - } -} diff --git a/third_party/bearssl/src/i15_muladd.c b/third_party/bearssl/src/i15_muladd.c deleted file mode 100644 index c4b72168e..000000000 --- a/third_party/bearssl/src/i15_muladd.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * Constant-time division. The divisor must not be larger than 16 bits, - * and the quotient must fit on 17 bits. - */ -static uint32_t -divrem16(uint32_t x, uint32_t d, uint32_t *r) -{ - int i; - uint32_t q; - - q = 0; - d <<= 16; - for (i = 16; i >= 0; i --) { - uint32_t ctl; - - ctl = LE(d, x); - q |= ctl << i; - x -= (-ctl) & d; - d >>= 1; - } - if (r != NULL) { - *r = x; - } - return q; -} - -/* see inner.h */ -void -br_i15_muladd_small(uint16_t *x, uint16_t z, const uint16_t *m) -{ - /* - * Constant-time: we accept to leak the exact bit length of the - * modulus m. - */ - unsigned m_bitlen, mblr; - size_t u, mlen; - uint32_t hi, a0, a, b, q; - uint32_t cc, tb, over, under; - - /* - * Simple case: the modulus fits on one word. - */ - m_bitlen = m[0]; - if (m_bitlen == 0) { - return; - } - if (m_bitlen <= 15) { - uint32_t rem; - - divrem16(((uint32_t)x[1] << 15) | z, m[1], &rem); - x[1] = rem; - return; - } - mlen = (m_bitlen + 15) >> 4; - mblr = m_bitlen & 15; - - /* - * Principle: we estimate the quotient (x*2^15+z)/m by - * doing a 30/15 division with the high words. - * - * Let: - * w = 2^15 - * a = (w*a0 + a1) * w^N + a2 - * b = b0 * w^N + b2 - * such that: - * 0 <= a0 < w - * 0 <= a1 < w - * 0 <= a2 < w^N - * w/2 <= b0 < w - * 0 <= b2 < w^N - * a < w*b - * I.e. the two top words of a are a0:a1, the top word of b is - * b0, we ensured that b0 is "full" (high bit set), and a is - * such that the quotient q = a/b fits on one word (0 <= q < w). - * - * If a = b*q + r (with 0 <= r < q), then we can estimate q by - * using a division on the top words: - * a0*w + a1 = b0*u + v (with 0 <= v < b0) - * Then the following holds: - * 0 <= u <= w - * u-2 <= q <= u - */ - hi = x[mlen]; - if (mblr == 0) { - a0 = x[mlen]; - memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); - x[1] = z; - a = (a0 << 15) + x[mlen]; - b = m[mlen]; - } else { - a0 = (x[mlen] << (15 - mblr)) | (x[mlen - 1] >> mblr); - memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); - x[1] = z; - a = (a0 << 15) | (((x[mlen] << (15 - mblr)) - | (x[mlen - 1] >> mblr)) & 0x7FFF); - b = (m[mlen] << (15 - mblr)) | (m[mlen - 1] >> mblr); - } - q = divrem16(a, b, NULL); - - /* - * We computed an estimate for q, but the real one may be q, - * q-1 or q-2; moreover, the division may have returned a value - * 8000 or even 8001 if the two high words were identical, and - * we want to avoid values beyond 7FFF. We thus adjust q so - * that the "true" multiplier will be q+1, q or q-1, and q is - * in the 0000..7FFF range. - */ - q = MUX(EQ(b, a0), 0x7FFF, q - 1 + ((q - 1) >> 31)); - - /* - * We subtract q*m from x (x has an extra high word of value 'hi'). - * Since q may be off by 1 (in either direction), we may have to - * add or subtract m afterwards. - * - * The 'tb' flag will be true (1) at the end of the loop if the - * result is greater than or equal to the modulus (not counting - * 'hi' or the carry). - */ - cc = 0; - tb = 1; - for (u = 1; u <= mlen; u ++) { - uint32_t mw, zl, xw, nxw; - - mw = m[u]; - zl = MUL15(mw, q) + cc; - cc = zl >> 15; - zl &= 0x7FFF; - xw = x[u]; - nxw = xw - zl; - cc += nxw >> 31; - nxw &= 0x7FFF; - x[u] = nxw; - tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw)); - } - - /* - * If we underestimated q, then either cc < hi (one extra bit - * beyond the top array word), or cc == hi and tb is true (no - * extra bit, but the result is not lower than the modulus). - * - * If we overestimated q, then cc > hi. - */ - over = GT(cc, hi); - under = ~over & (tb | LT(cc, hi)); - br_i15_add(x, m, over); - br_i15_sub(x, m, under); -} diff --git a/third_party/bearssl/src/i15_ninv15.c b/third_party/bearssl/src/i15_ninv15.c deleted file mode 100644 index de3a3ba89..000000000 --- a/third_party/bearssl/src/i15_ninv15.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint16_t -br_i15_ninv15(uint16_t x) -{ - uint32_t y; - - y = 2 - x; - y = MUL15(y, 2 - MUL15(x, y)); - y = MUL15(y, 2 - MUL15(x, y)); - y = MUL15(y, 2 - MUL15(x, y)); - return MUX(x & 1, -y, 0) & 0x7FFF; -} diff --git a/third_party/bearssl/src/i15_reduce.c b/third_party/bearssl/src/i15_reduce.c deleted file mode 100644 index 0931b1049..000000000 --- a/third_party/bearssl/src/i15_reduce.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i15_reduce(uint16_t *x, const uint16_t *a, const uint16_t *m) -{ - uint32_t m_bitlen, a_bitlen; - size_t mlen, alen, u; - - m_bitlen = m[0]; - mlen = (m_bitlen + 15) >> 4; - - x[0] = m_bitlen; - if (m_bitlen == 0) { - return; - } - - /* - * If the source is shorter, then simply copy all words from a[] - * and zero out the upper words. - */ - a_bitlen = a[0]; - alen = (a_bitlen + 15) >> 4; - if (a_bitlen < m_bitlen) { - memcpy(x + 1, a + 1, alen * sizeof *a); - for (u = alen; u < mlen; u ++) { - x[u + 1] = 0; - } - return; - } - - /* - * The source length is at least equal to that of the modulus. - * We must thus copy N-1 words, and input the remaining words - * one by one. - */ - memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a); - x[mlen] = 0; - for (u = 1 + alen - mlen; u > 0; u --) { - br_i15_muladd_small(x, a[u], m); - } -} diff --git a/third_party/bearssl/src/i15_rshift.c b/third_party/bearssl/src/i15_rshift.c deleted file mode 100644 index f9991ab6f..000000000 --- a/third_party/bearssl/src/i15_rshift.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i15_rshift(uint16_t *x, int count) -{ - size_t u, len; - unsigned r; - - len = (x[0] + 15) >> 4; - if (len == 0) { - return; - } - r = x[1] >> count; - for (u = 2; u <= len; u ++) { - unsigned w; - - w = x[u]; - x[u - 1] = ((w << (15 - count)) | r) & 0x7FFF; - r = w >> count; - } - x[len] = r; -} diff --git a/third_party/bearssl/src/i15_sub.c b/third_party/bearssl/src/i15_sub.c deleted file mode 100644 index 1983c4dcf..000000000 --- a/third_party/bearssl/src/i15_sub.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i15_sub(uint16_t *a, const uint16_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; - - cc = 0; - m = (a[0] + 31) >> 4; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; - - aw = a[u]; - bw = b[u]; - naw = aw - bw - cc; - cc = naw >> 31; - a[u] = MUX(ctl, naw & 0x7FFF, aw); - } - return cc; -} diff --git a/third_party/bearssl/src/i15_tmont.c b/third_party/bearssl/src/i15_tmont.c deleted file mode 100644 index d5c4b8b7a..000000000 --- a/third_party/bearssl/src/i15_tmont.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i15_to_monty(uint16_t *x, const uint16_t *m) -{ - unsigned k; - - for (k = (m[0] + 15) >> 4; k > 0; k --) { - br_i15_muladd_small(x, 0, m); - } -} diff --git a/third_party/bearssl/src/i32_add.c b/third_party/bearssl/src/i32_add.c deleted file mode 100644 index 620baffd7..000000000 --- a/third_party/bearssl/src/i32_add.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i32_add(uint32_t *a, const uint32_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; - - cc = 0; - m = (a[0] + 63) >> 5; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; - - aw = a[u]; - bw = b[u]; - naw = aw + bw + cc; - - /* - * Carry is 1 if naw < aw. Carry is also 1 if naw == aw - * AND the carry was already 1. - */ - cc = (cc & EQ(naw, aw)) | LT(naw, aw); - a[u] = MUX(ctl, naw, aw); - } - return cc; -} diff --git a/third_party/bearssl/src/i32_bitlen.c b/third_party/bearssl/src/i32_bitlen.c deleted file mode 100644 index 40ce9fa0b..000000000 --- a/third_party/bearssl/src/i32_bitlen.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i32_bit_length(uint32_t *x, size_t xlen) -{ - uint32_t tw, twk; - - tw = 0; - twk = 0; - while (xlen -- > 0) { - uint32_t w, c; - - c = EQ(tw, 0); - w = x[xlen]; - tw = MUX(c, w, tw); - twk = MUX(c, (uint32_t)xlen, twk); - } - return (twk << 5) + BIT_LENGTH(tw); -} diff --git a/third_party/bearssl/src/i32_decmod.c b/third_party/bearssl/src/i32_decmod.c deleted file mode 100644 index a859af122..000000000 --- a/third_party/bearssl/src/i32_decmod.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i32_decode_mod(uint32_t *x, const void *src, size_t len, const uint32_t *m) -{ - const unsigned char *buf; - uint32_t r; - size_t u, v, mlen; - - buf = src; - - /* - * First pass: determine whether the value fits. The 'r' value - * will contain the comparison result, as 0x00000000 (value is - * equal to the modulus), 0x00000001 (value is greater than the - * modulus), or 0xFFFFFFFF (value is lower than the modulus). - */ - mlen = (m[0] + 7) >> 3; - r = 0; - for (u = (mlen > len) ? mlen : len; u > 0; u --) { - uint32_t mb, xb; - - v = u - 1; - if (v >= mlen) { - mb = 0; - } else { - mb = (m[1 + (v >> 2)] >> ((v & 3) << 3)) & 0xFF; - } - if (v >= len) { - xb = 0; - } else { - xb = buf[len - u]; - } - r = MUX(EQ(r, 0), (uint32_t)CMP(xb, mb), r); - } - - /* - * Only r == 0xFFFFFFFF is acceptable. We want to set r to 0xFF if - * the value fits, 0x00 otherwise. - */ - r >>= 24; - br_i32_zero(x, m[0]); - u = (mlen > len) ? len : mlen; - while (u > 0) { - uint32_t xb; - - xb = buf[len - u] & r; - u --; - x[1 + (u >> 2)] |= xb << ((u & 3) << 3); - } - return r >> 7; -} diff --git a/third_party/bearssl/src/i32_decode.c b/third_party/bearssl/src/i32_decode.c deleted file mode 100644 index f28903846..000000000 --- a/third_party/bearssl/src/i32_decode.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i32_decode(uint32_t *x, const void *src, size_t len) -{ - const unsigned char *buf; - size_t u, v; - - buf = src; - u = len; - v = 1; - for (;;) { - if (u < 4) { - uint32_t w; - - if (u < 2) { - if (u == 0) { - break; - } else { - w = buf[0]; - } - } else { - if (u == 2) { - w = br_dec16be(buf); - } else { - w = ((uint32_t)buf[0] << 16) - | br_dec16be(buf + 1); - } - } - x[v ++] = w; - break; - } else { - u -= 4; - x[v ++] = br_dec32be(buf + u); - } - } - x[0] = br_i32_bit_length(x + 1, v - 1); -} diff --git a/third_party/bearssl/src/i32_decred.c b/third_party/bearssl/src/i32_decred.c deleted file mode 100644 index dc476db0d..000000000 --- a/third_party/bearssl/src/i32_decred.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i32_decode_reduce(uint32_t *x, - const void *src, size_t len, const uint32_t *m) -{ - uint32_t m_bitlen; - size_t mblen, k, q; - const unsigned char *buf; - - m_bitlen = m[0]; - - /* - * Special case for an invalid modulus. - */ - if (m_bitlen == 0) { - x[0] = 0; - return; - } - - /* - * Clear the destination. - */ - br_i32_zero(x, m_bitlen); - - /* - * First decode directly as many bytes as possible without - * reduction, taking care to leave a number of bytes which - * is a multiple of 4. - */ - mblen = (m_bitlen + 7) >> 3; - k = mblen - 1; - - /* - * Up to k bytes can be safely decoded. - */ - if (k >= len) { - br_i32_decode(x, src, len); - x[0] = m_bitlen; - return; - } - - /* - * We want to first inject some bytes with direct decoding, - * then extra bytes by whole 32-bit words. First compute - * the size that should be injected that way. - */ - buf = src; - q = (len - k + 3) & ~(size_t)3; - - /* - * It may happen that this is more than what we already have - * (by at most 3 bytes). Such a case may happen only with - * a very short modulus. In that case, we must process the first - * bytes "manually". - */ - if (q > len) { - int i; - uint32_t w; - - w = 0; - for (i = 0; i < 4; i ++) { - w <<= 8; - if (q <= len) { - w |= buf[len - q]; - } - q --; - } - br_i32_muladd_small(x, w, m); - } else { - br_i32_decode(x, buf, len - q); - x[0] = m_bitlen; - } - - /* - * At that point, we have exactly q bytes to inject, and q is - * a multiple of 4. - */ - for (k = len - q; k < len; k += 4) { - br_i32_muladd_small(x, br_dec32be(buf + k), m); - } -} diff --git a/third_party/bearssl/src/i32_encode.c b/third_party/bearssl/src/i32_encode.c deleted file mode 100644 index 303652f96..000000000 --- a/third_party/bearssl/src/i32_encode.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i32_encode(void *dst, size_t len, const uint32_t *x) -{ - unsigned char *buf; - size_t k; - - buf = dst; - - /* - * Compute the announced size of x in bytes; extra bytes are - * filled with zeros. - */ - k = (x[0] + 7) >> 3; - while (len > k) { - *buf ++ = 0; - len --; - } - - /* - * Now we use k as index within x[]. That index starts at 1; - * we initialize it to the topmost complete word, and process - * any remaining incomplete word. - */ - k = (len + 3) >> 2; - switch (len & 3) { - case 3: - *buf ++ = x[k] >> 16; - /* fall through */ - case 2: - *buf ++ = x[k] >> 8; - /* fall through */ - case 1: - *buf ++ = x[k]; - k --; - } - - /* - * Encode all complete words. - */ - while (k > 0) { - br_enc32be(buf, x[k]); - k --; - buf += 4; - } -} diff --git a/third_party/bearssl/src/i32_fmont.c b/third_party/bearssl/src/i32_fmont.c deleted file mode 100644 index dc1c93440..000000000 --- a/third_party/bearssl/src/i32_fmont.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i32_from_monty(uint32_t *x, const uint32_t *m, uint32_t m0i) -{ - size_t len, u, v; - - len = (m[0] + 31) >> 5; - for (u = 0; u < len; u ++) { - uint32_t f; - uint64_t cc; - - f = x[1] * m0i; - cc = 0; - for (v = 0; v < len; v ++) { - uint64_t z; - - z = (uint64_t)x[v + 1] + MUL(f, m[v + 1]) + cc; - cc = z >> 32; - if (v != 0) { - x[v] = (uint32_t)z; - } - } - x[len] = (uint32_t)cc; - } - - /* - * We may have to do an extra subtraction, but only if the - * value in x[] is indeed greater than or equal to that of m[], - * which is why we must do two calls (first call computes the - * carry, second call performs the subtraction only if the carry - * is 0). - */ - br_i32_sub(x, m, NOT(br_i32_sub(x, m, 0))); -} diff --git a/third_party/bearssl/src/i32_iszero.c b/third_party/bearssl/src/i32_iszero.c deleted file mode 100644 index 659df7f24..000000000 --- a/third_party/bearssl/src/i32_iszero.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i32_iszero(const uint32_t *x) -{ - uint32_t z; - size_t u; - - z = 0; - for (u = (x[0] + 31) >> 5; u > 0; u --) { - z |= x[u]; - } - return ~(z | -z) >> 31; -} diff --git a/third_party/bearssl/src/i32_modpow.c b/third_party/bearssl/src/i32_modpow.c deleted file mode 100644 index 034aba06d..000000000 --- a/third_party/bearssl/src/i32_modpow.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i32_modpow(uint32_t *x, - const unsigned char *e, size_t elen, - const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2) -{ - size_t mlen; - uint32_t k; - - /* - * 'mlen' is the length of m[] expressed in bytes (including - * the "bit length" first field). - */ - mlen = ((m[0] + 63) >> 5) * sizeof m[0]; - - /* - * Throughout the algorithm: - * -- t1[] is in Montgomery representation; it contains x, x^2, - * x^4, x^8... - * -- The result is accumulated, in normal representation, in - * the x[] array. - * -- t2[] is used as destination buffer for each multiplication. - * - * Note that there is no need to call br_i32_from_monty(). - */ - memcpy(t1, x, mlen); - br_i32_to_monty(t1, m); - br_i32_zero(x, m[0]); - x[1] = 1; - for (k = 0; k < ((uint32_t)elen << 3); k ++) { - uint32_t ctl; - - ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1; - br_i32_montymul(t2, x, t1, m, m0i); - CCOPY(ctl, x, t2, mlen); - br_i32_montymul(t2, t1, t1, m, m0i); - memcpy(t1, t2, mlen); - } -} diff --git a/third_party/bearssl/src/i32_montmul.c b/third_party/bearssl/src/i32_montmul.c deleted file mode 100644 index 7edb376cd..000000000 --- a/third_party/bearssl/src/i32_montmul.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i32_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, - const uint32_t *m, uint32_t m0i) -{ - size_t len, u, v; - uint64_t dh; - - len = (m[0] + 31) >> 5; - br_i32_zero(d, m[0]); - dh = 0; - for (u = 0; u < len; u ++) { - uint32_t f, xu; - uint64_t r1, r2, zh; - - xu = x[u + 1]; - f = (d[1] + x[u + 1] * y[1]) * m0i; - r1 = 0; - r2 = 0; - for (v = 0; v < len; v ++) { - uint64_t z; - uint32_t t; - - z = (uint64_t)d[v + 1] + MUL(xu, y[v + 1]) + r1; - r1 = z >> 32; - t = (uint32_t)z; - z = (uint64_t)t + MUL(f, m[v + 1]) + r2; - r2 = z >> 32; - if (v != 0) { - d[v] = (uint32_t)z; - } - } - zh = dh + r1 + r2; - d[len] = (uint32_t)zh; - dh = zh >> 32; - } - - /* - * d[] may still be greater than m[] at that point; notably, the - * 'dh' word may be non-zero. - */ - br_i32_sub(d, m, NEQ(dh, 0) | NOT(br_i32_sub(d, m, 0))); -} diff --git a/third_party/bearssl/src/i32_mulacc.c b/third_party/bearssl/src/i32_mulacc.c deleted file mode 100644 index 55da38580..000000000 --- a/third_party/bearssl/src/i32_mulacc.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i32_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - size_t alen, blen, u; - - alen = (a[0] + 31) >> 5; - blen = (b[0] + 31) >> 5; - d[0] = a[0] + b[0]; - for (u = 0; u < blen; u ++) { - uint32_t f; - size_t v; -#if BR_64 - uint64_t cc; -#else - uint32_t cc; -#endif - - f = b[1 + u]; - cc = 0; - for (v = 0; v < alen; v ++) { - uint64_t z; - - z = (uint64_t)d[1 + u + v] + MUL(f, a[1 + v]) + cc; - cc = z >> 32; - d[1 + u + v] = (uint32_t)z; - } - d[1 + u + alen] = (uint32_t)cc; - } -} diff --git a/third_party/bearssl/src/i32_muladd.c b/third_party/bearssl/src/i32_muladd.c deleted file mode 100644 index dd526ad5e..000000000 --- a/third_party/bearssl/src/i32_muladd.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i32_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m) -{ - uint32_t m_bitlen; - size_t u, mlen; - uint32_t a0, a1, b0, hi, g, q, tb; - uint32_t chf, clow, under, over; - uint64_t cc; - - /* - * We can test on the modulus bit length since we accept to - * leak that length. - */ - m_bitlen = m[0]; - if (m_bitlen == 0) { - return; - } - if (m_bitlen <= 32) { - x[1] = br_rem(x[1], z, m[1]); - return; - } - mlen = (m_bitlen + 31) >> 5; - - /* - * Principle: we estimate the quotient (x*2^32+z)/m by - * doing a 64/32 division with the high words. - * - * Let: - * w = 2^32 - * a = (w*a0 + a1) * w^N + a2 - * b = b0 * w^N + b2 - * such that: - * 0 <= a0 < w - * 0 <= a1 < w - * 0 <= a2 < w^N - * w/2 <= b0 < w - * 0 <= b2 < w^N - * a < w*b - * I.e. the two top words of a are a0:a1, the top word of b is - * b0, we ensured that b0 is "full" (high bit set), and a is - * such that the quotient q = a/b fits on one word (0 <= q < w). - * - * If a = b*q + r (with 0 <= r < q), we can estimate q by - * doing an Euclidean division on the top words: - * a0*w+a1 = b0*u + v (with 0 <= v < w) - * Then the following holds: - * 0 <= u <= w - * u-2 <= q <= u - */ - a0 = br_i32_word(x, m_bitlen - 32); - hi = x[mlen]; - memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); - x[1] = z; - a1 = br_i32_word(x, m_bitlen - 32); - b0 = br_i32_word(m, m_bitlen - 32); - - /* - * We estimate a divisor q. If the quotient returned by br_div() - * is g: - * -- If a0 == b0 then g == 0; we want q = 0xFFFFFFFF. - * -- Otherwise: - * -- if g == 0 then we set q = 0; - * -- otherwise, we set q = g - 1. - * The properties described above then ensure that the true - * quotient is q-1, q or q+1. - */ - g = br_div(a0, a1, b0); - q = MUX(EQ(a0, b0), 0xFFFFFFFF, MUX(EQ(g, 0), 0, g - 1)); - - /* - * We subtract q*m from x (with the extra high word of value 'hi'). - * Since q may be off by 1 (in either direction), we may have to - * add or subtract m afterwards. - * - * The 'tb' flag will be true (1) at the end of the loop if the - * result is greater than or equal to the modulus (not counting - * 'hi' or the carry). - */ - cc = 0; - tb = 1; - for (u = 1; u <= mlen; u ++) { - uint32_t mw, zw, xw, nxw; - uint64_t zl; - - mw = m[u]; - zl = MUL(mw, q) + cc; - cc = (uint32_t)(zl >> 32); - zw = (uint32_t)zl; - xw = x[u]; - nxw = xw - zw; - cc += (uint64_t)GT(nxw, xw); - x[u] = nxw; - tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw)); - } - - /* - * If we underestimated q, then either cc < hi (one extra bit - * beyond the top array word), or cc == hi and tb is true (no - * extra bit, but the result is not lower than the modulus). In - * these cases we must subtract m once. - * - * Otherwise, we may have overestimated, which will show as - * cc > hi (thus a negative result). Correction is adding m once. - */ - chf = (uint32_t)(cc >> 32); - clow = (uint32_t)cc; - over = chf | GT(clow, hi); - under = ~over & (tb | (~chf & LT(clow, hi))); - br_i32_add(x, m, over); - br_i32_sub(x, m, under); -} diff --git a/third_party/bearssl/src/i32_ninv32.c b/third_party/bearssl/src/i32_ninv32.c deleted file mode 100644 index 656443413..000000000 --- a/third_party/bearssl/src/i32_ninv32.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i32_ninv32(uint32_t x) -{ - uint32_t y; - - y = 2 - x; - y *= 2 - y * x; - y *= 2 - y * x; - y *= 2 - y * x; - y *= 2 - y * x; - return MUX(x & 1, -y, 0); -} diff --git a/third_party/bearssl/src/i32_reduce.c b/third_party/bearssl/src/i32_reduce.c deleted file mode 100644 index 90fff092b..000000000 --- a/third_party/bearssl/src/i32_reduce.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i32_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m) -{ - uint32_t m_bitlen, a_bitlen; - size_t mlen, alen, u; - - m_bitlen = m[0]; - mlen = (m_bitlen + 31) >> 5; - - x[0] = m_bitlen; - if (m_bitlen == 0) { - return; - } - - /* - * If the source is shorter, then simply copy all words from a[] - * and zero out the upper words. - */ - a_bitlen = a[0]; - alen = (a_bitlen + 31) >> 5; - if (a_bitlen < m_bitlen) { - memcpy(x + 1, a + 1, alen * sizeof *a); - for (u = alen; u < mlen; u ++) { - x[u + 1] = 0; - } - return; - } - - /* - * The source length is at least equal to that of the modulus. - * We must thus copy N-1 words, and input the remaining words - * one by one. - */ - memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a); - x[mlen] = 0; - for (u = 1 + alen - mlen; u > 0; u --) { - br_i32_muladd_small(x, a[u], m); - } -} diff --git a/third_party/bearssl/src/i32_sub.c b/third_party/bearssl/src/i32_sub.c deleted file mode 100644 index 9c5002382..000000000 --- a/third_party/bearssl/src/i32_sub.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -uint32_t -br_i32_sub(uint32_t *a, const uint32_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; - - cc = 0; - m = (a[0] + 63) >> 5; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; - - aw = a[u]; - bw = b[u]; - naw = aw - bw - cc; - - /* - * Carry is 1 if naw > aw. Carry is 1 also if naw == aw - * AND the carry was already 1. - */ - cc = (cc & EQ(naw, aw)) | GT(naw, aw); - a[u] = MUX(ctl, naw, aw); - } - return cc; -} diff --git a/third_party/bearssl/src/i32_tmont.c b/third_party/bearssl/src/i32_tmont.c deleted file mode 100644 index 058cd8868..000000000 --- a/third_party/bearssl/src/i32_tmont.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see inner.h */ -void -br_i32_to_monty(uint32_t *x, const uint32_t *m) -{ - uint32_t k; - - for (k = (m[0] + 31) >> 5; k > 0; k --) { - br_i32_muladd_small(x, 0, m); - } -} diff --git a/third_party/bearssl/src/inner.h b/third_party/bearssl/src/inner.h index 719843e72..1ef9086e8 100644 --- a/third_party/bearssl/src/inner.h +++ b/third_party/bearssl/src/inner.h @@ -125,15 +125,6 @@ #endif #endif -/* - * Set BR_LOMUL on platforms where it makes sense. - */ -#ifndef BR_LOMUL -#if BR_ARMEL_CORTEXM_GCC -#define BR_LOMUL 1 -#endif -#endif - /* * Architecture detection. */ diff --git a/third_party/bearssl/src/poly1305_ctmul32.c b/third_party/bearssl/src/poly1305_ctmul32.c deleted file mode 100644 index 15d9635dd..000000000 --- a/third_party/bearssl/src/poly1305_ctmul32.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * Perform the inner processing of blocks for Poly1305. - */ -static void -poly1305_inner(uint32_t *a, const uint32_t *r, const void *data, size_t len) -{ - /* - * Implementation notes: we split the 130-bit values into ten - * 13-bit words. This gives us some space for carries and allows - * using only 32x32->32 multiplications, which are way faster than - * 32x32->64 multiplications on the ARM Cortex-M0/M0+, and also - * help in making constant-time code on the Cortex-M3. - * - * Since we compute modulo 2^130-5, the "upper words" become - * low words with a factor of 5; that is, x*2^130 = x*5 mod p. - * This has already been integrated in the r[] array, which - * is extended to the 0..18 range. - * - * In each loop iteration, a[] and r[] words are 13-bit each, - * except a[1] which may use 14 bits. - */ - const unsigned char *buf; - - buf = data; - while (len > 0) { - unsigned char tmp[16]; - uint32_t b[10]; - unsigned u, v; - uint32_t z, cc1, cc2; - - /* - * If there is a partial block, right-pad it with zeros. - */ - if (len < 16) { - memset(tmp, 0, sizeof tmp); - memcpy(tmp, buf, len); - buf = tmp; - len = 16; - } - - /* - * Decode next block and apply the "high bit"; that value - * is added to the accumulator. - */ - v = br_dec16le(buf); - a[0] += v & 0x01FFF; - v >>= 13; - v |= buf[2] << 3; - v |= buf[3] << 11; - a[1] += v & 0x01FFF; - v >>= 13; - v |= buf[4] << 6; - a[2] += v & 0x01FFF; - v >>= 13; - v |= buf[5] << 1; - v |= buf[6] << 9; - a[3] += v & 0x01FFF; - v >>= 13; - v |= buf[7] << 4; - v |= buf[8] << 12; - a[4] += v & 0x01FFF; - v >>= 13; - v |= buf[9] << 7; - a[5] += v & 0x01FFF; - v >>= 13; - v |= buf[10] << 2; - v |= buf[11] << 10; - a[6] += v & 0x01FFF; - v >>= 13; - v |= buf[12] << 5; - a[7] += v & 0x01FFF; - v = br_dec16le(buf + 13); - a[8] += v & 0x01FFF; - v >>= 13; - v |= buf[15] << 3; - a[9] += v | 0x00800; - - /* - * At that point, all a[] values fit on 14 bits, while - * all r[] values fit on 13 bits. Thus products fit on - * 27 bits, and we can accumulate up to 31 of them in - * a 32-bit word and still have some room for carries. - */ - - /* - * Now a[] contains words with values up to 14 bits each. - * We perform the multiplication with r[]. - * - * The extended words of r[] may be larger than 13 bits - * (they are 5 times a 13-bit word) so the full summation - * may yield values up to 46 times a 27-bit word, which - * does not fit on a 32-bit word. To avoid that issue, we - * must split the loop below in two, with a carry - * propagation operation in the middle. - */ - cc1 = 0; - for (u = 0; u < 10; u ++) { - uint32_t s; - - s = cc1 - + MUL15(a[0], r[u + 9 - 0]) - + MUL15(a[1], r[u + 9 - 1]) - + MUL15(a[2], r[u + 9 - 2]) - + MUL15(a[3], r[u + 9 - 3]) - + MUL15(a[4], r[u + 9 - 4]); - b[u] = s & 0x1FFF; - cc1 = s >> 13; - } - cc2 = 0; - for (u = 0; u < 10; u ++) { - uint32_t s; - - s = b[u] + cc2 - + MUL15(a[5], r[u + 9 - 5]) - + MUL15(a[6], r[u + 9 - 6]) - + MUL15(a[7], r[u + 9 - 7]) - + MUL15(a[8], r[u + 9 - 8]) - + MUL15(a[9], r[u + 9 - 9]); - b[u] = s & 0x1FFF; - cc2 = s >> 13; - } - memcpy(a, b, sizeof b); - - /* - * The two carries "loop back" with a factor of 5. We - * propagate them into a[0] and a[1]. - */ - z = cc1 + cc2; - z += (z << 2) + a[0]; - a[0] = z & 0x1FFF; - a[1] += z >> 13; - - buf += 16; - len -= 16; - } -} - -/* see bearssl_block.h */ -void -br_poly1305_ctmul32_run(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt) -{ - unsigned char pkey[32], foot[16]; - uint32_t z, r[19], acc[10], cc, ctl; - int i; - - /* - * Compute the MAC key. The 'r' value is the first 16 bytes of - * pkey[]. - */ - memset(pkey, 0, sizeof pkey); - ichacha(key, iv, 0, pkey, sizeof pkey); - - /* - * If encrypting, ChaCha20 must run first, followed by Poly1305. - * When decrypting, the operations are reversed. - */ - if (encrypt) { - ichacha(key, iv, 1, data, len); - } - - /* - * Run Poly1305. We must process the AAD, then ciphertext, then - * the footer (with the lengths). Note that the AAD and ciphertext - * are meant to be padded with zeros up to the next multiple of 16, - * and the length of the footer is 16 bytes as well. - */ - - /* - * Decode the 'r' value into 13-bit words, with the "clamping" - * operation applied. - */ - z = br_dec32le(pkey) & 0x03FFFFFF; - r[9] = z & 0x1FFF; - r[10] = z >> 13; - z = (br_dec32le(pkey + 3) >> 2) & 0x03FFFF03; - r[11] = z & 0x1FFF; - r[12] = z >> 13; - z = (br_dec32le(pkey + 6) >> 4) & 0x03FFC0FF; - r[13] = z & 0x1FFF; - r[14] = z >> 13; - z = (br_dec32le(pkey + 9) >> 6) & 0x03F03FFF; - r[15] = z & 0x1FFF; - r[16] = z >> 13; - z = (br_dec32le(pkey + 12) >> 8) & 0x000FFFFF; - r[17] = z & 0x1FFF; - r[18] = z >> 13; - - /* - * Extend r[] with the 5x factor pre-applied. - */ - for (i = 0; i < 9; i ++) { - r[i] = MUL15(5, r[i + 10]); - } - - /* - * Accumulator is 0. - */ - memset(acc, 0, sizeof acc); - - /* - * Process the additional authenticated data, ciphertext, and - * footer in due order. - */ - br_enc64le(foot, (uint64_t)aad_len); - br_enc64le(foot + 8, (uint64_t)len); - poly1305_inner(acc, r, aad, aad_len); - poly1305_inner(acc, r, data, len); - poly1305_inner(acc, r, foot, sizeof foot); - - /* - * Finalise modular reduction. This is done with carry propagation - * and applying the '2^130 = -5 mod p' rule. Note that the output - * of poly1035_inner() is already mostly reduced, since only - * acc[1] may be (very slightly) above 2^13. A single loop back - * to acc[1] will be enough to make the value fit in 130 bits. - */ - cc = 0; - for (i = 1; i < 10; i ++) { - z = acc[i] + cc; - acc[i] = z & 0x1FFF; - cc = z >> 13; - } - z = acc[0] + cc + (cc << 2); - acc[0] = z & 0x1FFF; - acc[1] += z >> 13; - - /* - * We may still have a value in the 2^130-5..2^130-1 range, in - * which case we must reduce it again. The code below selects, - * in constant-time, between 'acc' and 'acc-p', - */ - ctl = GT(acc[0], 0x1FFA); - for (i = 1; i < 10; i ++) { - ctl &= EQ(acc[i], 0x1FFF); - } - acc[0] = MUX(ctl, acc[0] - 0x1FFB, acc[0]); - for (i = 1; i < 10; i ++) { - acc[i] &= ~(-ctl); - } - - /* - * Convert back the accumulator to 32-bit words, and add the - * 's' value (second half of pkey[]). That addition is done - * modulo 2^128. - */ - z = acc[0] + (acc[1] << 13) + br_dec16le(pkey + 16); - br_enc16le((unsigned char *)tag, z & 0xFFFF); - z = (z >> 16) + (acc[2] << 10) + br_dec16le(pkey + 18); - br_enc16le((unsigned char *)tag + 2, z & 0xFFFF); - z = (z >> 16) + (acc[3] << 7) + br_dec16le(pkey + 20); - br_enc16le((unsigned char *)tag + 4, z & 0xFFFF); - z = (z >> 16) + (acc[4] << 4) + br_dec16le(pkey + 22); - br_enc16le((unsigned char *)tag + 6, z & 0xFFFF); - z = (z >> 16) + (acc[5] << 1) + (acc[6] << 14) + br_dec16le(pkey + 24); - br_enc16le((unsigned char *)tag + 8, z & 0xFFFF); - z = (z >> 16) + (acc[7] << 11) + br_dec16le(pkey + 26); - br_enc16le((unsigned char *)tag + 10, z & 0xFFFF); - z = (z >> 16) + (acc[8] << 8) + br_dec16le(pkey + 28); - br_enc16le((unsigned char *)tag + 12, z & 0xFFFF); - z = (z >> 16) + (acc[9] << 5) + br_dec16le(pkey + 30); - br_enc16le((unsigned char *)tag + 14, z & 0xFFFF); - - /* - * If decrypting, then ChaCha20 runs _after_ Poly1305. - */ - if (!encrypt) { - ichacha(key, iv, 1, data, len); - } -} diff --git a/third_party/bearssl/src/poly1305_i15.c b/third_party/bearssl/src/poly1305_i15.c deleted file mode 100644 index 6f8921219..000000000 --- a/third_party/bearssl/src/poly1305_i15.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * This is a "reference" implementation of Poly1305 that uses the - * generic "i15" code for big integers. It is slow, but it handles all - * big-integer operations with generic code, thereby avoiding most - * tricky situations with carry propagation and modular reduction. - */ - -/* - * Modulus: 2^130-5. - */ -static const uint16_t P1305[] = { - 0x008A, - 0x7FFB, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x03FF -}; - -/* - * -p mod 2^15. - */ -#define P0I 0x4CCD - -/* - * R^2 mod p, for conversion to Montgomery representation (R = 2^135, - * since we use 9 words of 15 bits each, and 15*9 = 135). - */ -static const uint16_t R2[] = { - 0x008A, - 0x6400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -}; - -/* - * Perform the inner processing of blocks for Poly1305. The "r" array - * is in Montgomery representation, while the "a" array is not. - */ -static void -poly1305_inner(uint16_t *a, const uint16_t *r, const void *data, size_t len) -{ - const unsigned char *buf; - - buf = data; - while (len > 0) { - unsigned char tmp[16], rev[16]; - uint16_t b[10]; - uint32_t ctl; - int i; - - /* - * If there is a partial block, right-pad it with zeros. - */ - if (len < 16) { - memset(tmp, 0, sizeof tmp); - memcpy(tmp, buf, len); - buf = tmp; - len = 16; - } - - /* - * Decode next block and apply the "high bit". Since - * decoding is little-endian, we must byte-swap the buffer. - */ - for (i = 0; i < 16; i ++) { - rev[i] = buf[15 - i]; - } - br_i15_decode_mod(b, rev, sizeof rev, P1305); - b[9] |= 0x0100; - - /* - * Add the accumulator to the decoded block (modular - * addition). - */ - ctl = br_i15_add(b, a, 1); - ctl |= NOT(br_i15_sub(b, P1305, 0)); - br_i15_sub(b, P1305, ctl); - - /* - * Multiply by r, result is the new accumulator value. - */ - br_i15_montymul(a, b, r, P1305, P0I); - - buf += 16; - len -= 16; - } -} - -/* - * Byteswap a 16-byte value. - */ -static void -byteswap16(unsigned char *buf) -{ - int i; - - for (i = 0; i < 8; i ++) { - unsigned x; - - x = buf[i]; - buf[i] = buf[15 - i]; - buf[15 - i] = x; - } -} - -/* see bearssl_block.h */ -void -br_poly1305_i15_run(const void *key, const void *iv, - void *data, size_t len, const void *aad, size_t aad_len, - void *tag, br_chacha20_run ichacha, int encrypt) -{ - unsigned char pkey[32], foot[16]; - uint16_t t[10], r[10], acc[10]; - - /* - * Compute the MAC key. The 'r' value is the first 16 bytes of - * pkey[]. - */ - memset(pkey, 0, sizeof pkey); - ichacha(key, iv, 0, pkey, sizeof pkey); - - /* - * If encrypting, ChaCha20 must run first, followed by Poly1305. - * When decrypting, the operations are reversed. - */ - if (encrypt) { - ichacha(key, iv, 1, data, len); - } - - /* - * Run Poly1305. We must process the AAD, then ciphertext, then - * the footer (with the lengths). Note that the AAD and ciphertext - * are meant to be padded with zeros up to the next multiple of 16, - * and the length of the footer is 16 bytes as well. - */ - - /* - * Apply the "clamping" operation on the encoded 'r' value. - */ - pkey[ 3] &= 0x0F; - pkey[ 7] &= 0x0F; - pkey[11] &= 0x0F; - pkey[15] &= 0x0F; - pkey[ 4] &= 0xFC; - pkey[ 8] &= 0xFC; - pkey[12] &= 0xFC; - - /* - * Decode the clamped 'r' value. Decoding should use little-endian - * so we must byteswap the value first. - */ - byteswap16(pkey); - br_i15_decode_mod(t, pkey, 16, P1305); - - /* - * Convert 'r' to Montgomery representation. - */ - br_i15_montymul(r, t, R2, P1305, P0I); - - /* - * Accumulator is 0. - */ - br_i15_zero(acc, 0x8A); - - /* - * Process the additional authenticated data, ciphertext, and - * footer in due order. - */ - br_enc64le(foot, (uint64_t)aad_len); - br_enc64le(foot + 8, (uint64_t)len); - poly1305_inner(acc, r, aad, aad_len); - poly1305_inner(acc, r, data, len); - poly1305_inner(acc, r, foot, sizeof foot); - - /* - * Decode the value 's'. Again, a byteswap is needed. - */ - byteswap16(pkey + 16); - br_i15_decode_mod(t, pkey + 16, 16, P1305); - - /* - * Add the value 's' to the accumulator. That addition is done - * modulo 2^128, so we just ignore the carry. - */ - br_i15_add(acc, t, 1); - - /* - * Encode the result (128 low bits) to the tag. Encoding should - * be little-endian. - */ - br_i15_encode(tag, 16, acc); - byteswap16(tag); - - /* - * If decrypting, then ChaCha20 runs _after_ Poly1305. - */ - if (!encrypt) { - ichacha(key, iv, 1, data, len); - } -} diff --git a/third_party/bearssl/src/rsa_default_keygen.c b/third_party/bearssl/src/rsa_default_keygen.c index f2e83c8da..aba3af472 100644 --- a/third_party/bearssl/src/rsa_default_keygen.c +++ b/third_party/bearssl/src/rsa_default_keygen.c @@ -30,8 +30,6 @@ br_rsa_keygen_get_default(void) { #if BR_INT128 || BR_UMUL128 return &br_rsa_i62_keygen; -#elif BR_LOMUL - return &br_rsa_i15_keygen; #else return &br_rsa_i31_keygen; #endif diff --git a/third_party/bearssl/src/rsa_default_modulus.c b/third_party/bearssl/src/rsa_default_modulus.c index 57d4be56c..42200bb19 100644 --- a/third_party/bearssl/src/rsa_default_modulus.c +++ b/third_party/bearssl/src/rsa_default_modulus.c @@ -28,9 +28,5 @@ br_rsa_compute_modulus br_rsa_compute_modulus_get_default(void) { -#if BR_LOMUL - return &br_rsa_i15_compute_modulus; -#else return &br_rsa_i31_compute_modulus; -#endif } diff --git a/third_party/bearssl/src/rsa_default_oaep_decrypt.c b/third_party/bearssl/src/rsa_default_oaep_decrypt.c index 7345d64ec..70d60a999 100644 --- a/third_party/bearssl/src/rsa_default_oaep_decrypt.c +++ b/third_party/bearssl/src/rsa_default_oaep_decrypt.c @@ -30,8 +30,6 @@ br_rsa_oaep_decrypt_get_default(void) { #if BR_INT128 || BR_UMUL128 return &br_rsa_i62_oaep_decrypt; -#elif BR_LOMUL - return &br_rsa_i15_oaep_decrypt; #else return &br_rsa_i31_oaep_decrypt; #endif diff --git a/third_party/bearssl/src/rsa_default_oaep_encrypt.c b/third_party/bearssl/src/rsa_default_oaep_encrypt.c index ae33fcc6c..a30ad3928 100644 --- a/third_party/bearssl/src/rsa_default_oaep_encrypt.c +++ b/third_party/bearssl/src/rsa_default_oaep_encrypt.c @@ -30,8 +30,6 @@ br_rsa_oaep_encrypt_get_default(void) { #if BR_INT128 || BR_UMUL128 return &br_rsa_i62_oaep_encrypt; -#elif BR_LOMUL - return &br_rsa_i15_oaep_encrypt; #else return &br_rsa_i31_oaep_encrypt; #endif diff --git a/third_party/bearssl/src/rsa_default_pkcs1_sign.c b/third_party/bearssl/src/rsa_default_pkcs1_sign.c index e926704f5..d7d340e65 100644 --- a/third_party/bearssl/src/rsa_default_pkcs1_sign.c +++ b/third_party/bearssl/src/rsa_default_pkcs1_sign.c @@ -30,8 +30,6 @@ br_rsa_pkcs1_sign_get_default(void) { #if BR_INT128 || BR_UMUL128 return &br_rsa_i62_pkcs1_sign; -#elif BR_LOMUL - return &br_rsa_i15_pkcs1_sign; #else return &br_rsa_i31_pkcs1_sign; #endif diff --git a/third_party/bearssl/src/rsa_default_pkcs1_vrfy.c b/third_party/bearssl/src/rsa_default_pkcs1_vrfy.c index b3dbeb7bf..4385f9fef 100644 --- a/third_party/bearssl/src/rsa_default_pkcs1_vrfy.c +++ b/third_party/bearssl/src/rsa_default_pkcs1_vrfy.c @@ -30,8 +30,6 @@ br_rsa_pkcs1_vrfy_get_default(void) { #if BR_INT128 || BR_UMUL128 return &br_rsa_i62_pkcs1_vrfy; -#elif BR_LOMUL - return &br_rsa_i15_pkcs1_vrfy; #else return &br_rsa_i31_pkcs1_vrfy; #endif diff --git a/third_party/bearssl/src/rsa_default_priv.c b/third_party/bearssl/src/rsa_default_priv.c index bb0b2c008..6aa9014c3 100644 --- a/third_party/bearssl/src/rsa_default_priv.c +++ b/third_party/bearssl/src/rsa_default_priv.c @@ -30,8 +30,6 @@ br_rsa_private_get_default(void) { #if BR_INT128 || BR_UMUL128 return &br_rsa_i62_private; -#elif BR_LOMUL - return &br_rsa_i15_private; #else return &br_rsa_i31_private; #endif diff --git a/third_party/bearssl/src/rsa_default_privexp.c b/third_party/bearssl/src/rsa_default_privexp.c index cda45559b..a437bbecc 100644 --- a/third_party/bearssl/src/rsa_default_privexp.c +++ b/third_party/bearssl/src/rsa_default_privexp.c @@ -28,9 +28,5 @@ br_rsa_compute_privexp br_rsa_compute_privexp_get_default(void) { -#if BR_LOMUL - return &br_rsa_i15_compute_privexp; -#else return &br_rsa_i31_compute_privexp; -#endif } diff --git a/third_party/bearssl/src/rsa_default_pss_sign.c b/third_party/bearssl/src/rsa_default_pss_sign.c index ce4f3e075..641193208 100644 --- a/third_party/bearssl/src/rsa_default_pss_sign.c +++ b/third_party/bearssl/src/rsa_default_pss_sign.c @@ -30,8 +30,6 @@ br_rsa_pss_sign_get_default(void) { #if BR_INT128 || BR_UMUL128 return &br_rsa_i62_pss_sign; -#elif BR_LOMUL - return &br_rsa_i15_pss_sign; #else return &br_rsa_i31_pss_sign; #endif diff --git a/third_party/bearssl/src/rsa_default_pss_vrfy.c b/third_party/bearssl/src/rsa_default_pss_vrfy.c index e3a9ad9fc..2ce0cdf5f 100644 --- a/third_party/bearssl/src/rsa_default_pss_vrfy.c +++ b/third_party/bearssl/src/rsa_default_pss_vrfy.c @@ -30,8 +30,6 @@ br_rsa_pss_vrfy_get_default(void) { #if BR_INT128 || BR_UMUL128 return &br_rsa_i62_pss_vrfy; -#elif BR_LOMUL - return &br_rsa_i15_pss_vrfy; #else return &br_rsa_i31_pss_vrfy; #endif diff --git a/third_party/bearssl/src/rsa_default_pub.c b/third_party/bearssl/src/rsa_default_pub.c index a1f03ef38..6063d591c 100644 --- a/third_party/bearssl/src/rsa_default_pub.c +++ b/third_party/bearssl/src/rsa_default_pub.c @@ -30,8 +30,6 @@ br_rsa_public_get_default(void) { #if BR_INT128 || BR_UMUL128 return &br_rsa_i62_public; -#elif BR_LOMUL - return &br_rsa_i15_public; #else return &br_rsa_i31_public; #endif diff --git a/third_party/bearssl/src/rsa_default_pubexp.c b/third_party/bearssl/src/rsa_default_pubexp.c index 47bc00058..1be88c1f3 100644 --- a/third_party/bearssl/src/rsa_default_pubexp.c +++ b/third_party/bearssl/src/rsa_default_pubexp.c @@ -28,9 +28,5 @@ br_rsa_compute_pubexp br_rsa_compute_pubexp_get_default(void) { -#if BR_LOMUL - return &br_rsa_i15_compute_pubexp; -#else return &br_rsa_i31_compute_pubexp; -#endif } diff --git a/third_party/bearssl/src/rsa_i15_keygen.c b/third_party/bearssl/src/rsa_i15_keygen.c deleted file mode 100644 index e8da41984..000000000 --- a/third_party/bearssl/src/rsa_i15_keygen.c +++ /dev/null @@ -1,583 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * Make a random integer of the provided size. The size is encoded. - * The header word is untouched. - */ -static void -mkrand(const br_prng_class **rng, uint16_t *x, uint32_t esize) -{ - size_t u, len; - unsigned m; - - len = (esize + 15) >> 4; - (*rng)->generate(rng, x + 1, len * sizeof(uint16_t)); - for (u = 1; u < len; u ++) { - x[u] &= 0x7FFF; - } - m = esize & 15; - if (m == 0) { - x[len] &= 0x7FFF; - } else { - x[len] &= 0x7FFF >> (15 - m); - } -} - -/* - * This is the big-endian unsigned representation of the product of - * all small primes from 13 to 1481. - */ -static const unsigned char SMALL_PRIMES[] = { - 0x2E, 0xAB, 0x92, 0xD1, 0x8B, 0x12, 0x47, 0x31, 0x54, 0x0A, - 0x99, 0x5D, 0x25, 0x5E, 0xE2, 0x14, 0x96, 0x29, 0x1E, 0xB7, - 0x78, 0x70, 0xCC, 0x1F, 0xA5, 0xAB, 0x8D, 0x72, 0x11, 0x37, - 0xFB, 0xD8, 0x1E, 0x3F, 0x5B, 0x34, 0x30, 0x17, 0x8B, 0xE5, - 0x26, 0x28, 0x23, 0xA1, 0x8A, 0xA4, 0x29, 0xEA, 0xFD, 0x9E, - 0x39, 0x60, 0x8A, 0xF3, 0xB5, 0xA6, 0xEB, 0x3F, 0x02, 0xB6, - 0x16, 0xC3, 0x96, 0x9D, 0x38, 0xB0, 0x7D, 0x82, 0x87, 0x0C, - 0xF7, 0xBE, 0x24, 0xE5, 0x5F, 0x41, 0x04, 0x79, 0x76, 0x40, - 0xE7, 0x00, 0x22, 0x7E, 0xB5, 0x85, 0x7F, 0x8D, 0x01, 0x50, - 0xE9, 0xD3, 0x29, 0x42, 0x08, 0xB3, 0x51, 0x40, 0x7B, 0xD7, - 0x8D, 0xCC, 0x10, 0x01, 0x64, 0x59, 0x28, 0xB6, 0x53, 0xF3, - 0x50, 0x4E, 0xB1, 0xF2, 0x58, 0xCD, 0x6E, 0xF5, 0x56, 0x3E, - 0x66, 0x2F, 0xD7, 0x07, 0x7F, 0x52, 0x4C, 0x13, 0x24, 0xDC, - 0x8E, 0x8D, 0xCC, 0xED, 0x77, 0xC4, 0x21, 0xD2, 0xFD, 0x08, - 0xEA, 0xD7, 0xC0, 0x5C, 0x13, 0x82, 0x81, 0x31, 0x2F, 0x2B, - 0x08, 0xE4, 0x80, 0x04, 0x7A, 0x0C, 0x8A, 0x3C, 0xDC, 0x22, - 0xE4, 0x5A, 0x7A, 0xB0, 0x12, 0x5E, 0x4A, 0x76, 0x94, 0x77, - 0xC2, 0x0E, 0x92, 0xBA, 0x8A, 0xA0, 0x1F, 0x14, 0x51, 0x1E, - 0x66, 0x6C, 0x38, 0x03, 0x6C, 0xC7, 0x4A, 0x4B, 0x70, 0x80, - 0xAF, 0xCA, 0x84, 0x51, 0xD8, 0xD2, 0x26, 0x49, 0xF5, 0xA8, - 0x5E, 0x35, 0x4B, 0xAC, 0xCE, 0x29, 0x92, 0x33, 0xB7, 0xA2, - 0x69, 0x7D, 0x0C, 0xE0, 0x9C, 0xDB, 0x04, 0xD6, 0xB4, 0xBC, - 0x39, 0xD7, 0x7F, 0x9E, 0x9D, 0x78, 0x38, 0x7F, 0x51, 0x54, - 0x50, 0x8B, 0x9E, 0x9C, 0x03, 0x6C, 0xF5, 0x9D, 0x2C, 0x74, - 0x57, 0xF0, 0x27, 0x2A, 0xC3, 0x47, 0xCA, 0xB9, 0xD7, 0x5C, - 0xFF, 0xC2, 0xAC, 0x65, 0x4E, 0xBD -}; - -/* - * We need temporary values for at least 7 integers of the same size - * as a factor (including header word); more space helps with performance - * (in modular exponentiations), but we much prefer to remain under - * 2 kilobytes in total, to save stack space. The macro TEMPS below - * exceeds 1024 (which is a count in 16-bit words) when BR_MAX_RSA_SIZE - * is greater than 4350 (default value is 4096, so the 2-kB limit is - * maintained unless BR_MAX_RSA_SIZE was modified). - */ -#define MAX(x, y) ((x) > (y) ? (x) : (y)) -#define TEMPS MAX(1024, 7 * ((((BR_MAX_RSA_SIZE + 1) >> 1) + 29) / 15)) - -/* - * Perform trial division on a candidate prime. This computes - * y = SMALL_PRIMES mod x, then tries to compute y/y mod x. The - * br_i15_moddiv() function will report an error if y is not invertible - * modulo x. Returned value is 1 on success (none of the small primes - * divides x), 0 on error (a non-trivial GCD is obtained). - * - * This function assumes that x is odd. - */ -static uint32_t -trial_divisions(const uint16_t *x, uint16_t *t) -{ - uint16_t *y; - uint16_t x0i; - - y = t; - t += 1 + ((x[0] + 15) >> 4); - x0i = br_i15_ninv15(x[1]); - br_i15_decode_reduce(y, SMALL_PRIMES, sizeof SMALL_PRIMES, x); - return br_i15_moddiv(y, y, x, x0i, t); -} - -/* - * Perform n rounds of Miller-Rabin on the candidate prime x. This - * function assumes that x = 3 mod 4. - * - * Returned value is 1 on success (all rounds completed successfully), - * 0 otherwise. - */ -static uint32_t -miller_rabin(const br_prng_class **rng, const uint16_t *x, int n, - uint16_t *t, size_t tlen) -{ - /* - * Since x = 3 mod 4, the Miller-Rabin test is simple: - * - get a random base a (such that 1 < a < x-1) - * - compute z = a^((x-1)/2) mod x - * - if z != 1 and z != x-1, the number x is composite - * - * We generate bases 'a' randomly with a size which is - * one bit less than x, which ensures that a < x-1. It - * is not useful to verify that a > 1 because the probability - * that we get a value a equal to 0 or 1 is much smaller - * than the probability of our Miller-Rabin tests not to - * detect a composite, which is already quite smaller than the - * probability of the hardware misbehaving and return a - * composite integer because of some glitch (e.g. bad RAM - * or ill-timed cosmic ray). - */ - unsigned char *xm1d2; - size_t xlen, xm1d2_len, xm1d2_len_u16, u; - uint32_t asize; - unsigned cc; - uint16_t x0i; - - /* - * Compute (x-1)/2 (encoded). - */ - xm1d2 = (unsigned char *)t; - xm1d2_len = ((x[0] - (x[0] >> 4)) + 7) >> 3; - br_i15_encode(xm1d2, xm1d2_len, x); - cc = 0; - for (u = 0; u < xm1d2_len; u ++) { - unsigned w; - - w = xm1d2[u]; - xm1d2[u] = (unsigned char)((w >> 1) | cc); - cc = w << 7; - } - - /* - * We used some words of the provided buffer for (x-1)/2. - */ - xm1d2_len_u16 = (xm1d2_len + 1) >> 1; - t += xm1d2_len_u16; - tlen -= xm1d2_len_u16; - - xlen = (x[0] + 15) >> 4; - asize = x[0] - 1 - EQ0(x[0] & 15); - x0i = br_i15_ninv15(x[1]); - while (n -- > 0) { - uint16_t *a; - uint32_t eq1, eqm1; - - /* - * Generate a random base. We don't need the base to be - * really uniform modulo x, so we just get a random - * number which is one bit shorter than x. - */ - a = t; - a[0] = x[0]; - a[xlen] = 0; - mkrand(rng, a, asize); - - /* - * Compute a^((x-1)/2) mod x. We assume here that the - * function will not fail (the temporary array is large - * enough). - */ - br_i15_modpow_opt(a, xm1d2, xm1d2_len, - x, x0i, t + 1 + xlen, tlen - 1 - xlen); - - /* - * We must obtain either 1 or x-1. Note that x is odd, - * hence x-1 differs from x only in its low word (no - * carry). - */ - eq1 = a[1] ^ 1; - eqm1 = a[1] ^ (x[1] - 1); - for (u = 2; u <= xlen; u ++) { - eq1 |= a[u]; - eqm1 |= a[u] ^ x[u]; - } - - if ((EQ0(eq1) | EQ0(eqm1)) == 0) { - return 0; - } - } - return 1; -} - -/* - * Create a random prime of the provided size. 'size' is the _encoded_ - * bit length. The two top bits and the two bottom bits are set to 1. - */ -static void -mkprime(const br_prng_class **rng, uint16_t *x, uint32_t esize, - uint32_t pubexp, uint16_t *t, size_t tlen) -{ - size_t len; - - x[0] = esize; - len = (esize + 15) >> 4; - for (;;) { - size_t u; - uint32_t m3, m5, m7, m11; - int rounds; - - /* - * Generate random bits. We force the two top bits and the - * two bottom bits to 1. - */ - mkrand(rng, x, esize); - if ((esize & 15) == 0) { - x[len] |= 0x6000; - } else if ((esize & 15) == 1) { - x[len] |= 0x0001; - x[len - 1] |= 0x4000; - } else { - x[len] |= 0x0003 << ((esize & 15) - 2); - } - x[1] |= 0x0003; - - /* - * Trial division with low primes (3, 5, 7 and 11). We - * use the following properties: - * - * 2^2 = 1 mod 3 - * 2^4 = 1 mod 5 - * 2^3 = 1 mod 7 - * 2^10 = 1 mod 11 - */ - m3 = 0; - m5 = 0; - m7 = 0; - m11 = 0; - for (u = 0; u < len; u ++) { - uint32_t w; - - w = x[1 + u]; - m3 += w << (u & 1); - m3 = (m3 & 0xFF) + (m3 >> 8); - m5 += w << ((4 - u) & 3); - m5 = (m5 & 0xFF) + (m5 >> 8); - m7 += w; - m7 = (m7 & 0x1FF) + (m7 >> 9); - m11 += w << (5 & -(u & 1)); - m11 = (m11 & 0x3FF) + (m11 >> 10); - } - - /* - * Maximum values of m* at this point: - * m3: 511 - * m5: 2310 - * m7: 510 - * m11: 2047 - * We use the same properties to make further reductions. - */ - - m3 = (m3 & 0x0F) + (m3 >> 4); /* max: 46 */ - m3 = (m3 & 0x0F) + (m3 >> 4); /* max: 16 */ - m3 = ((m3 * 43) >> 5) & 3; - - m5 = (m5 & 0xFF) + (m5 >> 8); /* max: 263 */ - m5 = (m5 & 0x0F) + (m5 >> 4); /* max: 30 */ - m5 = (m5 & 0x0F) + (m5 >> 4); /* max: 15 */ - m5 -= 10 & -GT(m5, 9); - m5 -= 5 & -GT(m5, 4); - - m7 = (m7 & 0x3F) + (m7 >> 6); /* max: 69 */ - m7 = (m7 & 7) + (m7 >> 3); /* max: 14 */ - m7 = ((m7 * 147) >> 7) & 7; - - /* - * 2^5 = 32 = -1 mod 11. - */ - m11 = (m11 & 0x1F) + 66 - (m11 >> 5); /* max: 97 */ - m11 -= 88 & -GT(m11, 87); - m11 -= 44 & -GT(m11, 43); - m11 -= 22 & -GT(m11, 21); - m11 -= 11 & -GT(m11, 10); - - /* - * If any of these modulo is 0, then the candidate is - * not prime. Also, if pubexp is 3, 5, 7 or 11, and the - * corresponding modulus is 1, then the candidate must - * be rejected, because we need e to be invertible - * modulo p-1. We can use simple comparisons here - * because they won't leak information on a candidate - * that we keep, only on one that we reject (and is thus - * not secret). - */ - if (m3 == 0 || m5 == 0 || m7 == 0 || m11 == 0) { - continue; - } - if ((pubexp == 3 && m3 == 1) - || (pubexp == 5 && m5 == 1) - || (pubexp == 7 && m7 == 1) - || (pubexp == 11 && m11 == 1)) - { - continue; - } - - /* - * More trial divisions. - */ - if (!trial_divisions(x, t)) { - continue; - } - - /* - * Miller-Rabin algorithm. Since we selected a random - * integer, not a maliciously crafted integer, we can use - * relatively few rounds to lower the risk of a false - * positive (i.e. declaring prime a non-prime) under - * 2^(-80). It is not useful to lower the probability much - * below that, since that would be substantially below - * the probability of the hardware misbehaving. Sufficient - * numbers of rounds are extracted from the Handbook of - * Applied Cryptography, note 4.49 (page 149). - * - * Since we work on the encoded size (esize), we need to - * compare with encoded thresholds. - */ - if (esize < 320) { - rounds = 12; - } else if (esize < 480) { - rounds = 9; - } else if (esize < 693) { - rounds = 6; - } else if (esize < 906) { - rounds = 4; - } else if (esize < 1386) { - rounds = 3; - } else { - rounds = 2; - } - - if (miller_rabin(rng, x, rounds, t, tlen)) { - return; - } - } -} - -/* - * Let p be a prime (p > 2^33, p = 3 mod 4). Let m = (p-1)/2, provided - * as parameter (with announced bit length equal to that of p). This - * function computes d = 1/e mod p-1 (for an odd integer e). Returned - * value is 1 on success, 0 on error (an error is reported if e is not - * invertible modulo p-1). - * - * The temporary buffer (t) must have room for at least 4 integers of - * the size of p. - */ -static uint32_t -invert_pubexp(uint16_t *d, const uint16_t *m, uint32_t e, uint16_t *t) -{ - uint16_t *f; - uint32_t r; - - f = t; - t += 1 + ((m[0] + 15) >> 4); - - /* - * Compute d = 1/e mod m. Since p = 3 mod 4, m is odd. - */ - br_i15_zero(d, m[0]); - d[1] = 1; - br_i15_zero(f, m[0]); - f[1] = e & 0x7FFF; - f[2] = (e >> 15) & 0x7FFF; - f[3] = e >> 30; - r = br_i15_moddiv(d, f, m, br_i15_ninv15(m[1]), t); - - /* - * We really want d = 1/e mod p-1, with p = 2m. By the CRT, - * the result is either the d we got, or d + m. - * - * Let's write e*d = 1 + k*m, for some integer k. Integers e - * and m are odd. If d is odd, then e*d is odd, which implies - * that k must be even; in that case, e*d = 1 + (k/2)*2m, and - * thus d is already fine. Conversely, if d is even, then k - * is odd, and we must add m to d in order to get the correct - * result. - */ - br_i15_add(d, m, (uint32_t)(1 - (d[1] & 1))); - - return r; -} - -/* - * Swap two buffers in RAM. They must be disjoint. - */ -static void -bufswap(void *b1, void *b2, size_t len) -{ - size_t u; - unsigned char *buf1, *buf2; - - buf1 = b1; - buf2 = b2; - for (u = 0; u < len; u ++) { - unsigned w; - - w = buf1[u]; - buf1[u] = buf2[u]; - buf2[u] = w; - } -} - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_keygen(const br_prng_class **rng, - br_rsa_private_key *sk, void *kbuf_priv, - br_rsa_public_key *pk, void *kbuf_pub, - unsigned size, uint32_t pubexp) -{ - uint32_t esize_p, esize_q; - size_t plen, qlen, tlen; - uint16_t *p, *q, *t; - uint16_t tmp[TEMPS]; - uint32_t r; - - if (size < BR_MIN_RSA_SIZE || size > BR_MAX_RSA_SIZE) { - return 0; - } - if (pubexp == 0) { - pubexp = 3; - } else if (pubexp == 1 || (pubexp & 1) == 0) { - return 0; - } - - esize_p = (size + 1) >> 1; - esize_q = size - esize_p; - sk->n_bitlen = size; - sk->p = kbuf_priv; - sk->plen = (esize_p + 7) >> 3; - sk->q = sk->p + sk->plen; - sk->qlen = (esize_q + 7) >> 3; - sk->dp = sk->q + sk->qlen; - sk->dplen = sk->plen; - sk->dq = sk->dp + sk->dplen; - sk->dqlen = sk->qlen; - sk->iq = sk->dq + sk->dqlen; - sk->iqlen = sk->plen; - - if (pk != NULL) { - pk->n = kbuf_pub; - pk->nlen = (size + 7) >> 3; - pk->e = pk->n + pk->nlen; - pk->elen = 4; - br_enc32be(pk->e, pubexp); - while (*pk->e == 0) { - pk->e ++; - pk->elen --; - } - } - - /* - * We now switch to encoded sizes. - * - * floor((x * 17477) / (2^18)) is equal to floor(x/15) for all - * integers x from 0 to 23833. - */ - esize_p += MUL15(esize_p, 17477) >> 18; - esize_q += MUL15(esize_q, 17477) >> 18; - plen = (esize_p + 15) >> 4; - qlen = (esize_q + 15) >> 4; - p = tmp; - q = p + 1 + plen; - t = q + 1 + qlen; - tlen = ((sizeof tmp) / sizeof(uint16_t)) - (2 + plen + qlen); - - /* - * When looking for primes p and q, we temporarily divide - * candidates by 2, in order to compute the inverse of the - * public exponent. - */ - - for (;;) { - mkprime(rng, p, esize_p, pubexp, t, tlen); - br_i15_rshift(p, 1); - if (invert_pubexp(t, p, pubexp, t + 1 + plen)) { - br_i15_add(p, p, 1); - p[1] |= 1; - br_i15_encode(sk->p, sk->plen, p); - br_i15_encode(sk->dp, sk->dplen, t); - break; - } - } - - for (;;) { - mkprime(rng, q, esize_q, pubexp, t, tlen); - br_i15_rshift(q, 1); - if (invert_pubexp(t, q, pubexp, t + 1 + qlen)) { - br_i15_add(q, q, 1); - q[1] |= 1; - br_i15_encode(sk->q, sk->qlen, q); - br_i15_encode(sk->dq, sk->dqlen, t); - break; - } - } - - /* - * If p and q have the same size, then it is possible that q > p - * (when the target modulus size is odd, we generate p with a - * greater bit length than q). If q > p, we want to swap p and q - * (and also dp and dq) for two reasons: - * - The final step below (inversion of q modulo p) is easier if - * p > q. - * - While BearSSL's RSA code is perfectly happy with RSA keys such - * that p < q, some other implementations have restrictions and - * require p > q. - * - * Note that we can do a simple non-constant-time swap here, - * because the only information we leak here is that we insist on - * returning p and q such that p > q, which is not a secret. - */ - if (esize_p == esize_q && br_i15_sub(p, q, 0) == 1) { - bufswap(p, q, (1 + plen) * sizeof *p); - bufswap(sk->p, sk->q, sk->plen); - bufswap(sk->dp, sk->dq, sk->dplen); - } - - /* - * We have produced p, q, dp and dq. We can now compute iq = 1/d mod p. - * - * We ensured that p >= q, so this is just a matter of updating the - * header word for q (and possibly adding an extra word). - * - * Theoretically, the call below may fail, in case we were - * extraordinarily unlucky, and p = q. Another failure case is if - * Miller-Rabin failed us _twice_, and p and q are non-prime and - * have a factor is common. We report the error mostly because it - * is cheap and we can, but in practice this never happens (or, at - * least, it happens way less often than hardware glitches). - */ - q[0] = p[0]; - if (plen > qlen) { - q[plen] = 0; - t ++; - tlen --; - } - br_i15_zero(t, p[0]); - t[1] = 1; - r = br_i15_moddiv(t, q, p, br_i15_ninv15(p[1]), t + 1 + plen); - br_i15_encode(sk->iq, sk->iqlen, t); - - /* - * Compute the public modulus too, if required. - */ - if (pk != NULL) { - br_i15_zero(t, p[0]); - br_i15_mulacc(t, p, q); - br_i15_encode(pk->n, pk->nlen, t); - } - - return r; -} diff --git a/third_party/bearssl/src/rsa_i15_modulus.c b/third_party/bearssl/src/rsa_i15_modulus.c deleted file mode 100644 index 16458c3e5..000000000 --- a/third_party/bearssl/src/rsa_i15_modulus.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -size_t -br_rsa_i15_compute_modulus(void *n, const br_rsa_private_key *sk) -{ - uint16_t tmp[4 * (((BR_MAX_RSA_SIZE / 2) + 14) / 15) + 5]; - uint16_t *t, *p, *q; - const unsigned char *pbuf, *qbuf; - size_t nlen, plen, qlen, tlen; - - /* - * Compute actual byte and lengths for p and q. - */ - pbuf = sk->p; - plen = sk->plen; - while (plen > 0 && *pbuf == 0) { - pbuf ++; - plen --; - } - qbuf = sk->q; - qlen = sk->qlen; - while (qlen > 0 && *qbuf == 0) { - qbuf ++; - qlen --; - } - - t = tmp; - tlen = (sizeof tmp) / (sizeof tmp[0]); - - /* - * Decode p. - */ - if ((15 * tlen) < (plen << 3) + 15) { - return 0; - } - br_i15_decode(t, pbuf, plen); - p = t; - plen = (p[0] + 31) >> 4; - t += plen; - tlen -= plen; - - /* - * Decode q. - */ - if ((15 * tlen) < (qlen << 3) + 15) { - return 0; - } - br_i15_decode(t, qbuf, qlen); - q = t; - qlen = (q[0] + 31) >> 4; - t += qlen; - tlen -= qlen; - - /* - * Computation can proceed only if we have enough room for the - * modulus. - */ - if (tlen < (plen + qlen + 1)) { - return 0; - } - - /* - * Private key already contains the modulus bit length, from which - * we can infer the output length. Even if n is NULL, we still had - * to decode p and q to make sure that the product can be computed. - */ - nlen = (sk->n_bitlen + 7) >> 3; - if (n != NULL) { - br_i15_zero(t, p[0]); - br_i15_mulacc(t, p, q); - br_i15_encode(n, nlen, t); - } - return nlen; -} diff --git a/third_party/bearssl/src/rsa_i15_oaep_decrypt.c b/third_party/bearssl/src/rsa_i15_oaep_decrypt.c deleted file mode 100644 index 927eecd85..000000000 --- a/third_party/bearssl/src/rsa_i15_oaep_decrypt.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_oaep_decrypt(const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_private_key *sk, void *data, size_t *len) -{ - uint32_t r; - - if (*len != ((sk->n_bitlen + 7) >> 3)) { - return 0; - } - r = br_rsa_i15_private(data, sk); - r &= br_rsa_oaep_unpad(dig, label, label_len, data, len); - return r; -} diff --git a/third_party/bearssl/src/rsa_i15_oaep_encrypt.c b/third_party/bearssl/src/rsa_i15_oaep_encrypt.c deleted file mode 100644 index b9a6cfa48..000000000 --- a/third_party/bearssl/src/rsa_i15_oaep_encrypt.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -size_t -br_rsa_i15_oaep_encrypt( - const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_public_key *pk, - void *dst, size_t dst_max_len, - const void *src, size_t src_len) -{ - size_t dlen; - - dlen = br_rsa_oaep_pad(rnd, dig, label, label_len, - pk, dst, dst_max_len, src, src_len); - if (dlen == 0) { - return 0; - } - return dlen & -(size_t)br_rsa_i15_public(dst, dlen, pk); -} diff --git a/third_party/bearssl/src/rsa_i15_pkcs1_sign.c b/third_party/bearssl/src/rsa_i15_pkcs1_sign.c deleted file mode 100644 index f519423d3..000000000 --- a/third_party/bearssl/src/rsa_i15_pkcs1_sign.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_pkcs1_sign(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - const br_rsa_private_key *sk, unsigned char *x) -{ - if (!br_rsa_pkcs1_sig_pad(hash_oid, hash, hash_len, sk->n_bitlen, x)) { - return 0; - } - return br_rsa_i15_private(x, sk); -} diff --git a/third_party/bearssl/src/rsa_i15_pkcs1_vrfy.c b/third_party/bearssl/src/rsa_i15_pkcs1_vrfy.c deleted file mode 100644 index 2c3518496..000000000 --- a/third_party/bearssl/src/rsa_i15_pkcs1_vrfy.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_pkcs1_vrfy(const unsigned char *x, size_t xlen, - const unsigned char *hash_oid, size_t hash_len, - const br_rsa_public_key *pk, unsigned char *hash_out) -{ - unsigned char sig[BR_MAX_RSA_SIZE >> 3]; - - if (xlen > (sizeof sig)) { - return 0; - } - memcpy(sig, x, xlen); - if (!br_rsa_i15_public(sig, xlen, pk)) { - return 0; - } - return br_rsa_pkcs1_sig_unpad(sig, xlen, hash_oid, hash_len, hash_out); -} diff --git a/third_party/bearssl/src/rsa_i15_priv.c b/third_party/bearssl/src/rsa_i15_priv.c deleted file mode 100644 index 177cc3a66..000000000 --- a/third_party/bearssl/src/rsa_i15_priv.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -#define U (2 + ((BR_MAX_RSA_FACTOR + 14) / 15)) -#define TLEN (8 * U) - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_private(unsigned char *x, const br_rsa_private_key *sk) -{ - const unsigned char *p, *q; - size_t plen, qlen; - size_t fwlen; - uint16_t p0i, q0i; - size_t xlen, u; - uint16_t tmp[1 + TLEN]; - long z; - uint16_t *mp, *mq, *s1, *s2, *t1, *t2, *t3; - uint32_t r; - - /* - * Compute the actual lengths of p and q, in bytes. - * These lengths are not considered secret (we cannot really hide - * them anyway in constant-time code). - */ - p = sk->p; - plen = sk->plen; - while (plen > 0 && *p == 0) { - p ++; - plen --; - } - q = sk->q; - qlen = sk->qlen; - while (qlen > 0 && *q == 0) { - q ++; - qlen --; - } - - /* - * Compute the maximum factor length, in words. - */ - z = (long)(plen > qlen ? plen : qlen) << 3; - fwlen = 1; - while (z > 0) { - z -= 15; - fwlen ++; - } - /* - * Round up the word length to an even number. - */ - fwlen += (fwlen & 1); - - /* - * We need to fit at least 6 values in the stack buffer. - */ - if (6 * fwlen > TLEN) { - return 0; - } - - /* - * Compute signature length (in bytes). - */ - xlen = (sk->n_bitlen + 7) >> 3; - - /* - * Ensure 32-bit alignment for value words. - */ - mq = tmp; - if (((uintptr_t)mq & 2) == 0) { - mq ++; - } - - /* - * Decode q. - */ - br_i15_decode(mq, q, qlen); - - /* - * Decode p. - */ - t1 = mq + fwlen; - br_i15_decode(t1, p, plen); - - /* - * Compute the modulus (product of the two factors), to compare - * it with the source value. We use br_i15_mulacc(), since it's - * already used later on. - */ - t2 = mq + 2 * fwlen; - br_i15_zero(t2, mq[0]); - br_i15_mulacc(t2, mq, t1); - - /* - * We encode the modulus into bytes, to perform the comparison - * with bytes. We know that the product length, in bytes, is - * exactly xlen. - * The comparison actually computes the carry when subtracting - * the modulus from the source value; that carry must be 1 for - * a value in the correct range. We keep it in r, which is our - * accumulator for the error code. - */ - t3 = mq + 4 * fwlen; - br_i15_encode(t3, xlen, t2); - u = xlen; - r = 0; - while (u > 0) { - uint32_t wn, wx; - - u --; - wn = ((unsigned char *)t3)[u]; - wx = x[u]; - r = ((wx - (wn + r)) >> 8) & 1; - } - - /* - * Move the decoded p to another temporary buffer. - */ - mp = mq + 2 * fwlen; - memmove(mp, t1, fwlen * sizeof *t1); - - /* - * Compute s2 = x^dq mod q. - */ - q0i = br_i15_ninv15(mq[1]); - s2 = mq + fwlen; - br_i15_decode_reduce(s2, x, xlen, mq); - r &= br_i15_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i, - mq + 3 * fwlen, TLEN - 3 * fwlen); - - /* - * Compute s1 = x^dq mod q. - */ - p0i = br_i15_ninv15(mp[1]); - s1 = mq + 3 * fwlen; - br_i15_decode_reduce(s1, x, xlen, mp); - r &= br_i15_modpow_opt(s1, sk->dp, sk->dplen, mp, p0i, - mq + 4 * fwlen, TLEN - 4 * fwlen); - - /* - * Compute: - * h = (s1 - s2)*(1/q) mod p - * s1 is an integer modulo p, but s2 is modulo q. PKCS#1 is - * unclear about whether p may be lower than q (some existing, - * widely deployed implementations of RSA don't tolerate p < q), - * but we want to support that occurrence, so we need to use the - * reduction function. - * - * Since we use br_i15_decode_reduce() for iq (purportedly, the - * inverse of q modulo p), we also tolerate improperly large - * values for this parameter. - */ - t1 = mq + 4 * fwlen; - t2 = mq + 5 * fwlen; - br_i15_reduce(t2, s2, mp); - br_i15_add(s1, mp, br_i15_sub(s1, t2, 1)); - br_i15_to_monty(s1, mp); - br_i15_decode_reduce(t1, sk->iq, sk->iqlen, mp); - br_i15_montymul(t2, s1, t1, mp, p0i); - - /* - * h is now in t2. We compute the final result: - * s = s2 + q*h - * All these operations are non-modular. - * - * We need mq, s2 and t2. We use the t3 buffer as destination. - * The buffers mp, s1 and t1 are no longer needed, so we can - * reuse them for t3. Moreover, the first step of the computation - * is to copy s2 into t3, after which s2 is not needed. Right - * now, mq is in slot 0, s2 is in slot 1, and t2 in slot 5. - * Therefore, we have ample room for t3 by simply using s2. - */ - t3 = s2; - br_i15_mulacc(t3, mq, t2); - - /* - * Encode the result. Since we already checked the value of xlen, - * we can just use it right away. - */ - br_i15_encode(x, xlen, t3); - - /* - * The only error conditions remaining at that point are invalid - * values for p and q (even integers). - */ - return p0i & q0i & r; -} diff --git a/third_party/bearssl/src/rsa_i15_privexp.c b/third_party/bearssl/src/rsa_i15_privexp.c deleted file mode 100644 index 57d6918e7..000000000 --- a/third_party/bearssl/src/rsa_i15_privexp.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -size_t -br_rsa_i15_compute_privexp(void *d, - const br_rsa_private_key *sk, uint32_t e) -{ - /* - * We want to invert e modulo phi = (p-1)(q-1). This first - * requires computing phi, which is easy since we have the factors - * p and q in the private key structure. - * - * Since p = 3 mod 4 and q = 3 mod 4, phi/4 is an odd integer. - * We could invert e modulo phi/4 then patch the result to - * modulo phi, but this would involve assembling three modulus-wide - * values (phi/4, 1 and e) and calling moddiv, that requires - * three more temporaries, for a total of six big integers, or - * slightly more than 3 kB of stack space for RSA-4096. This - * exceeds our stack requirements. - * - * Instead, we first use one step of the extended GCD: - * - * - We compute phi = k*e + r (Euclidean division of phi by e). - * If public exponent e is correct, then r != 0 (e must be - * invertible modulo phi). We also have k != 0 since we - * enforce non-ridiculously-small factors. - * - * - We find small u, v such that u*e - v*r = 1 (using a - * binary GCD; we can arrange for u < r and v < e, i.e. all - * values fit on 32 bits). - * - * - Solution is: d = u + v*k - * This last computation is exact: since u < r and v < e, - * the above implies d < r + e*((phi-r)/e) = phi - */ - - uint16_t tmp[4 * ((BR_MAX_RSA_FACTOR + 14) / 15) + 12]; - uint16_t *p, *q, *k, *m, *z, *phi; - const unsigned char *pbuf, *qbuf; - size_t plen, qlen, u, len, dlen; - uint32_t r, a, b, u0, v0, u1, v1, he, hr; - int i; - - /* - * Check that e is correct. - */ - if (e < 3 || (e & 1) == 0) { - return 0; - } - - /* - * Check lengths of p and q, and that they are both odd. - */ - pbuf = sk->p; - plen = sk->plen; - while (plen > 0 && *pbuf == 0) { - pbuf ++; - plen --; - } - if (plen < 5 || plen > (BR_MAX_RSA_FACTOR / 8) - || (pbuf[plen - 1] & 1) != 1) - { - return 0; - } - qbuf = sk->q; - qlen = sk->qlen; - while (qlen > 0 && *qbuf == 0) { - qbuf ++; - qlen --; - } - if (qlen < 5 || qlen > (BR_MAX_RSA_FACTOR / 8) - || (qbuf[qlen - 1] & 1) != 1) - { - return 0; - } - - /* - * Output length is that of the modulus. - */ - dlen = (sk->n_bitlen + 7) >> 3; - if (d == NULL) { - return dlen; - } - - p = tmp; - br_i15_decode(p, pbuf, plen); - plen = (p[0] + 15) >> 4; - q = p + 1 + plen; - br_i15_decode(q, qbuf, qlen); - qlen = (q[0] + 15) >> 4; - - /* - * Compute phi = (p-1)*(q-1), then move it over p-1 and q-1 (that - * we do not need anymore). The mulacc function sets the announced - * bit length of t to be the sum of the announced bit lengths of - * p-1 and q-1, which is usually exact but may overshoot by one 1 - * bit in some cases; we readjust it to its true length. - */ - p[1] --; - q[1] --; - phi = q + 1 + qlen; - br_i15_zero(phi, p[0]); - br_i15_mulacc(phi, p, q); - len = (phi[0] + 15) >> 4; - memmove(tmp, phi, (1 + len) * sizeof *phi); - phi = tmp; - phi[0] = br_i15_bit_length(phi + 1, len); - len = (phi[0] + 15) >> 4; - - /* - * Divide phi by public exponent e. The final remainder r must be - * non-zero (otherwise, the key is invalid). The quotient is k, - * which we write over phi, since we don't need phi after that. - */ - r = 0; - for (u = len; u >= 1; u --) { - /* - * Upon entry, r < e, and phi[u] < 2^15; hence, - * hi:lo < e*2^15. Thus, the produced word k[u] - * must be lower than 2^15, and the new remainder r - * is lower than e. - */ - uint32_t hi, lo; - - hi = r >> 17; - lo = (r << 15) + phi[u]; - phi[u] = br_divrem(hi, lo, e, &r); - } - if (r == 0) { - return 0; - } - k = phi; - - /* - * Compute u and v such that u*e - v*r = GCD(e,r). We use - * a binary GCD algorithm, with 6 extra integers a, b, - * u0, u1, v0 and v1. Initial values are: - * a = e u0 = 1 v0 = 0 - * b = r u1 = r v1 = e-1 - * The following invariants are maintained: - * a = u0*e - v0*r - * b = u1*e - v1*r - * 0 < a <= e - * 0 < b <= r - * 0 <= u0 <= r - * 0 <= v0 <= e - * 0 <= u1 <= r - * 0 <= v1 <= e - * - * At each iteration, we reduce either a or b by one bit, and - * adjust u0, u1, v0 and v1 to maintain the invariants: - * - if a is even, then a <- a/2 - * - otherwise, if b is even, then b <- b/2 - * - otherwise, if a > b, then a <- (a-b)/2 - * - otherwise, if b > a, then b <- (b-a)/2 - * Algorithm stops when a = b. At that point, the common value - * is the GCD of e and r; it must be 1 (otherwise, the private - * key or public exponent is not valid). The (u0,v0) or (u1,v1) - * pairs are the solution we are looking for. - * - * Since either a or b is reduced by at least 1 bit at each - * iteration, 62 iterations are enough to reach the end - * condition. - * - * To maintain the invariants, we must compute the same operations - * on the u* and v* values that we do on a and b: - * - When a is divided by 2, u0 and v0 must be divided by 2. - * - When b is divided by 2, u1 and v1 must be divided by 2. - * - When b is subtracted from a, u1 and v1 are subtracted from - * u0 and v0, respectively. - * - When a is subtracted from b, u0 and v0 are subtracted from - * u1 and v1, respectively. - * - * However, we want to keep the u* and v* values in their proper - * ranges. The following remarks apply: - * - * - When a is divided by 2, then a is even. Therefore: - * - * * If r is odd, then u0 and v0 must have the same parity; - * if they are both odd, then adding r to u0 and e to v0 - * makes them both even, and the division by 2 brings them - * back to the proper range. - * - * * If r is even, then u0 must be even; if v0 is odd, then - * adding r to u0 and e to v0 makes them both even, and the - * division by 2 brings them back to the proper range. - * - * Thus, all we need to do is to look at the parity of v0, - * and add (r,e) to (u0,v0) when v0 is odd. In order to avoid - * a 32-bit overflow, we can add ((r+1)/2,(e/2)+1) after the - * division (r+1 does not overflow since r < e; and (e/2)+1 - * is equal to (e+1)/2 since e is odd). - * - * - When we subtract b from a, three cases may occur: - * - * * u1 <= u0 and v1 <= v0: just do the subtractions - * - * * u1 > u0 and v1 > v0: compute: - * (u0, v0) <- (u0 + r - u1, v0 + e - v1) - * - * * u1 <= u0 and v1 > v0: compute: - * (u0, v0) <- (u0 + r - u1, v0 + e - v1) - * - * The fourth case (u1 > u0 and v1 <= v0) is not possible - * because it would contradict "b < a" (which is the reason - * why we subtract b from a). - * - * The tricky case is the third one: from the equations, it - * seems that u0 may go out of range. However, the invariants - * and ranges of other values imply that, in that case, the - * new u0 does not actually exceed the range. - * - * We can thus handle the subtraction by adding (r,e) based - * solely on the comparison between v0 and v1. - */ - a = e; - b = r; - u0 = 1; - v0 = 0; - u1 = r; - v1 = e - 1; - hr = (r + 1) >> 1; - he = (e >> 1) + 1; - for (i = 0; i < 62; i ++) { - uint32_t oa, ob, agtb, bgta; - uint32_t sab, sba, da, db; - uint32_t ctl; - - oa = a & 1; /* 1 if a is odd */ - ob = b & 1; /* 1 if b is odd */ - agtb = GT(a, b); /* 1 if a > b */ - bgta = GT(b, a); /* 1 if b > a */ - - sab = oa & ob & agtb; /* 1 if a <- a-b */ - sba = oa & ob & bgta; /* 1 if b <- b-a */ - - /* a <- a-b, u0 <- u0-u1, v0 <- v0-v1 */ - ctl = GT(v1, v0); - a -= b & -sab; - u0 -= (u1 - (r & -ctl)) & -sab; - v0 -= (v1 - (e & -ctl)) & -sab; - - /* b <- b-a, u1 <- u1-u0 mod r, v1 <- v1-v0 mod e */ - ctl = GT(v0, v1); - b -= a & -sba; - u1 -= (u0 - (r & -ctl)) & -sba; - v1 -= (v0 - (e & -ctl)) & -sba; - - da = NOT(oa) | sab; /* 1 if a <- a/2 */ - db = (oa & NOT(ob)) | sba; /* 1 if b <- b/2 */ - - /* a <- a/2, u0 <- u0/2, v0 <- v0/2 */ - ctl = v0 & 1; - a ^= (a ^ (a >> 1)) & -da; - u0 ^= (u0 ^ ((u0 >> 1) + (hr & -ctl))) & -da; - v0 ^= (v0 ^ ((v0 >> 1) + (he & -ctl))) & -da; - - /* b <- b/2, u1 <- u1/2 mod r, v1 <- v1/2 mod e */ - ctl = v1 & 1; - b ^= (b ^ (b >> 1)) & -db; - u1 ^= (u1 ^ ((u1 >> 1) + (hr & -ctl))) & -db; - v1 ^= (v1 ^ ((v1 >> 1) + (he & -ctl))) & -db; - } - - /* - * Check that the GCD is indeed 1. If not, then the key is invalid - * (and there's no harm in leaking that piece of information). - */ - if (a != 1) { - return 0; - } - - /* - * Now we have u0*e - v0*r = 1. Let's compute the result as: - * d = u0 + v0*k - * We still have k in the tmp[] array, and its announced bit - * length is that of phi. - */ - m = k + 1 + len; - m[0] = (2 << 4) + 2; /* bit length is 32 bits, encoded */ - m[1] = v0 & 0x7FFF; - m[2] = (v0 >> 15) & 0x7FFF; - m[3] = v0 >> 30; - z = m + 4; - br_i15_zero(z, k[0]); - z[1] = u0 & 0x7FFF; - z[2] = (u0 >> 15) & 0x7FFF; - z[3] = u0 >> 30; - br_i15_mulacc(z, k, m); - - /* - * Encode the result. - */ - br_i15_encode(d, dlen, z); - return dlen; -} diff --git a/third_party/bearssl/src/rsa_i15_pss_sign.c b/third_party/bearssl/src/rsa_i15_pss_sign.c deleted file mode 100644 index dd9385b0a..000000000 --- a/third_party/bearssl/src/rsa_i15_pss_sign.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_pss_sign(const br_prng_class **rng, - const br_hash_class *hf_data, const br_hash_class *hf_mgf1, - const unsigned char *hash, size_t salt_len, - const br_rsa_private_key *sk, unsigned char *x) -{ - if (!br_rsa_pss_sig_pad(rng, hf_data, hf_mgf1, hash, - salt_len, sk->n_bitlen, x)) - { - return 0; - } - return br_rsa_i15_private(x, sk); -} diff --git a/third_party/bearssl/src/rsa_i15_pss_vrfy.c b/third_party/bearssl/src/rsa_i15_pss_vrfy.c deleted file mode 100644 index 7d9f2cbc4..000000000 --- a/third_party/bearssl/src/rsa_i15_pss_vrfy.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_pss_vrfy(const unsigned char *x, size_t xlen, - const br_hash_class *hf_data, const br_hash_class *hf_mgf1, - const void *hash, size_t salt_len, const br_rsa_public_key *pk) -{ - unsigned char sig[BR_MAX_RSA_SIZE >> 3]; - - if (xlen > (sizeof sig)) { - return 0; - } - memcpy(sig, x, xlen); - if (!br_rsa_i15_public(sig, xlen, pk)) { - return 0; - } - return br_rsa_pss_sig_unpad(hf_data, hf_mgf1, - hash, salt_len, pk, sig); -} diff --git a/third_party/bearssl/src/rsa_i15_pub.c b/third_party/bearssl/src/rsa_i15_pub.c deleted file mode 100644 index 9eab5e842..000000000 --- a/third_party/bearssl/src/rsa_i15_pub.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * As a strict minimum, we need four buffers that can hold a - * modular integer. - */ -#define TLEN (4 * (2 + ((BR_MAX_RSA_SIZE + 14) / 15))) - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_public(unsigned char *x, size_t xlen, - const br_rsa_public_key *pk) -{ - const unsigned char *n; - size_t nlen; - uint16_t tmp[1 + TLEN]; - uint16_t *m, *a, *t; - size_t fwlen; - long z; - uint16_t m0i; - uint32_t r; - - /* - * Get the actual length of the modulus, and see if it fits within - * our stack buffer. We also check that the length of x[] is valid. - */ - n = pk->n; - nlen = pk->nlen; - while (nlen > 0 && *n == 0) { - n ++; - nlen --; - } - if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) { - return 0; - } - z = (long)nlen << 3; - fwlen = 1; - while (z > 0) { - z -= 15; - fwlen ++; - } - /* - * Round up length to an even number. - */ - fwlen += (fwlen & 1); - - /* - * The modulus gets decoded into m[]. - * The value to exponentiate goes into a[]. - * The temporaries for modular exponentiations are in t[]. - * - * We want the first value word of each integer to be aligned - * on a 32-bit boundary. - */ - m = tmp; - if (((uintptr_t)m & 2) == 0) { - m ++; - } - a = m + fwlen; - t = m + 2 * fwlen; - - /* - * Decode the modulus. - */ - br_i15_decode(m, n, nlen); - m0i = br_i15_ninv15(m[1]); - - /* - * Note: if m[] is even, then m0i == 0. Otherwise, m0i must be - * an odd integer. - */ - r = m0i & 1; - - /* - * Decode x[] into a[]; we also check that its value is proper. - */ - r &= br_i15_decode_mod(a, x, xlen, m); - - /* - * Compute the modular exponentiation. - */ - br_i15_modpow_opt(a, pk->e, pk->elen, m, m0i, t, TLEN - 2 * fwlen); - - /* - * Encode the result. - */ - br_i15_encode(x, xlen, a); - return r; -} diff --git a/third_party/bearssl/src/rsa_i15_pubexp.c b/third_party/bearssl/src/rsa_i15_pubexp.c deleted file mode 100644 index 803bff793..000000000 --- a/third_party/bearssl/src/rsa_i15_pubexp.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * Recompute public exponent, based on factor p and reduced private - * exponent dp. - */ -static uint32_t -get_pubexp(const unsigned char *pbuf, size_t plen, - const unsigned char *dpbuf, size_t dplen) -{ - /* - * dp is the inverse of e modulo p-1. If p = 3 mod 4, then - * p-1 = 2*((p-1)/2). Taken modulo 2, e is odd and has inverse 1; - * thus, dp must be odd. - * - * We compute the inverse of dp modulo (p-1)/2. This requires - * first reducing dp modulo (p-1)/2 (this can be done with a - * conditional subtract, no need to use the generic modular - * reduction function); then, we use moddiv. - */ - - uint16_t tmp[6 * ((BR_MAX_RSA_FACTOR + 29) / 15)]; - uint16_t *p, *dp, *x; - size_t len; - uint32_t e; - - /* - * Compute actual factor length (in bytes) and check that it fits - * under our size constraints. - */ - while (plen > 0 && *pbuf == 0) { - pbuf ++; - plen --; - } - if (plen == 0 || plen < 5 || plen > (BR_MAX_RSA_FACTOR / 8)) { - return 0; - } - - /* - * Compute actual reduced exponent length (in bytes) and check that - * it is not longer than p. - */ - while (dplen > 0 && *dpbuf == 0) { - dpbuf ++; - dplen --; - } - if (dplen > plen || dplen == 0 - || (dplen == plen && dpbuf[0] > pbuf[0])) - { - return 0; - } - - /* - * Verify that p = 3 mod 4 and that dp is odd. - */ - if ((pbuf[plen - 1] & 3) != 3 || (dpbuf[dplen - 1] & 1) != 1) { - return 0; - } - - /* - * Decode p and compute (p-1)/2. - */ - p = tmp; - br_i15_decode(p, pbuf, plen); - len = (p[0] + 31) >> 4; - br_i15_rshift(p, 1); - - /* - * Decode dp and make sure its announced bit length matches that of - * p (we already know that the size of dp, in bits, does not exceed - * the size of p, so we just have to copy the header word). - */ - dp = p + len; - memset(dp, 0, len * sizeof *dp); - br_i15_decode(dp, dpbuf, dplen); - dp[0] = p[0]; - - /* - * Subtract (p-1)/2 from dp if necessary. - */ - br_i15_sub(dp, p, NOT(br_i15_sub(dp, p, 0))); - - /* - * If another subtraction is needed, then this means that the - * value was invalid. We don't care to leak information about - * invalid keys. - */ - if (br_i15_sub(dp, p, 0) == 0) { - return 0; - } - - /* - * Invert dp modulo (p-1)/2. If the inversion fails, then the - * key value was invalid. - */ - x = dp + len; - br_i15_zero(x, p[0]); - x[1] = 1; - if (br_i15_moddiv(x, dp, p, br_i15_ninv15(p[1]), x + len) == 0) { - return 0; - } - - /* - * We now have an inverse. We must set it to zero (error) if its - * length is greater than 32 bits and/or if it is an even integer. - * Take care that the bit_length function returns an encoded - * bit length. - */ - e = (uint32_t)x[1] | ((uint32_t)x[2] << 15) | ((uint32_t)x[3] << 30); - e &= -LT(br_i15_bit_length(x + 1, len - 1), 35); - e &= -(e & 1); - return e; -} - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i15_compute_pubexp(const br_rsa_private_key *sk) -{ - /* - * Get the public exponent from both p and q. This is the right - * exponent if we get twice the same value. - */ - uint32_t ep, eq; - - ep = get_pubexp(sk->p, sk->plen, sk->dp, sk->dplen); - eq = get_pubexp(sk->q, sk->qlen, sk->dq, sk->dqlen); - return ep & -EQ(ep, eq); -} diff --git a/third_party/bearssl/src/rsa_i32_oaep_decrypt.c b/third_party/bearssl/src/rsa_i32_oaep_decrypt.c deleted file mode 100644 index ecfd92b10..000000000 --- a/third_party/bearssl/src/rsa_i32_oaep_decrypt.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i32_oaep_decrypt(const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_private_key *sk, void *data, size_t *len) -{ - uint32_t r; - - if (*len != ((sk->n_bitlen + 7) >> 3)) { - return 0; - } - r = br_rsa_i32_private(data, sk); - r &= br_rsa_oaep_unpad(dig, label, label_len, data, len); - return r; -} diff --git a/third_party/bearssl/src/rsa_i32_oaep_encrypt.c b/third_party/bearssl/src/rsa_i32_oaep_encrypt.c deleted file mode 100644 index dc17f3f2b..000000000 --- a/third_party/bearssl/src/rsa_i32_oaep_encrypt.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -size_t -br_rsa_i32_oaep_encrypt( - const br_prng_class **rnd, const br_hash_class *dig, - const void *label, size_t label_len, - const br_rsa_public_key *pk, - void *dst, size_t dst_max_len, - const void *src, size_t src_len) -{ - size_t dlen; - - dlen = br_rsa_oaep_pad(rnd, dig, label, label_len, - pk, dst, dst_max_len, src, src_len); - if (dlen == 0) { - return 0; - } - return dlen & -(size_t)br_rsa_i32_public(dst, dlen, pk); -} diff --git a/third_party/bearssl/src/rsa_i32_pkcs1_sign.c b/third_party/bearssl/src/rsa_i32_pkcs1_sign.c deleted file mode 100644 index 44b6e6d51..000000000 --- a/third_party/bearssl/src/rsa_i32_pkcs1_sign.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i32_pkcs1_sign(const unsigned char *hash_oid, - const unsigned char *hash, size_t hash_len, - const br_rsa_private_key *sk, unsigned char *x) -{ - if (!br_rsa_pkcs1_sig_pad(hash_oid, hash, hash_len, sk->n_bitlen, x)) { - return 0; - } - return br_rsa_i32_private(x, sk); -} diff --git a/third_party/bearssl/src/rsa_i32_pkcs1_vrfy.c b/third_party/bearssl/src/rsa_i32_pkcs1_vrfy.c deleted file mode 100644 index 6ee7a198f..000000000 --- a/third_party/bearssl/src/rsa_i32_pkcs1_vrfy.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i32_pkcs1_vrfy(const unsigned char *x, size_t xlen, - const unsigned char *hash_oid, size_t hash_len, - const br_rsa_public_key *pk, unsigned char *hash_out) -{ - unsigned char sig[BR_MAX_RSA_SIZE >> 3]; - - if (xlen > (sizeof sig)) { - return 0; - } - memcpy(sig, x, xlen); - if (!br_rsa_i32_public(sig, xlen, pk)) { - return 0; - } - return br_rsa_pkcs1_sig_unpad(sig, xlen, hash_oid, hash_len, hash_out); -} diff --git a/third_party/bearssl/src/rsa_i32_priv.c b/third_party/bearssl/src/rsa_i32_priv.c deleted file mode 100644 index 05c22ec39..000000000 --- a/third_party/bearssl/src/rsa_i32_priv.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -#define U (1 + (BR_MAX_RSA_FACTOR >> 5)) - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i32_private(unsigned char *x, const br_rsa_private_key *sk) -{ - const unsigned char *p, *q; - size_t plen, qlen; - uint32_t tmp[6 * U]; - uint32_t *mp, *mq, *s1, *s2, *t1, *t2, *t3; - uint32_t p0i, q0i; - size_t xlen, u; - uint32_t r; - - /* - * All our temporary buffers are from the tmp[] array. - * - * The mp, mq, s1, s2, t1 and t2 buffers are large enough to - * contain a RSA factor. The t3 buffer can contain a complete - * RSA modulus. t3 shares its storage space with s2, s1 and t1, - * in that order (this is important, see below). - */ - mq = tmp; - mp = tmp + U; - t2 = tmp + 2 * U; - s2 = tmp + 3 * U; - s1 = tmp + 4 * U; - t1 = tmp + 5 * U; - t3 = s2; - - /* - * Compute the actual lengths (in bytes) of p and q, and check - * that they fit within our stack buffers. - */ - p = sk->p; - plen = sk->plen; - while (plen > 0 && *p == 0) { - p ++; - plen --; - } - q = sk->q; - qlen = sk->qlen; - while (qlen > 0 && *q == 0) { - q ++; - qlen --; - } - if (plen > (BR_MAX_RSA_FACTOR >> 3) - || qlen > (BR_MAX_RSA_FACTOR >> 3)) - { - return 0; - } - - /* - * Decode p and q. - */ - br_i32_decode(mp, p, plen); - br_i32_decode(mq, q, qlen); - - /* - * Recompute modulus, to compare with the source value. - */ - br_i32_zero(t2, mp[0]); - br_i32_mulacc(t2, mp, mq); - xlen = (sk->n_bitlen + 7) >> 3; - br_i32_encode(t2 + 2 * U, xlen, t2); - u = xlen; - r = 0; - while (u > 0) { - uint32_t wn, wx; - - u --; - wn = ((unsigned char *)(t2 + 2 * U))[u]; - wx = x[u]; - r = ((wx - (wn + r)) >> 8) & 1; - } - - /* - * Compute s1 = x^dp mod p. - */ - p0i = br_i32_ninv32(mp[1]); - br_i32_decode_reduce(s1, x, xlen, mp); - br_i32_modpow(s1, sk->dp, sk->dplen, mp, p0i, t1, t2); - - /* - * Compute s2 = x^dq mod q. - */ - q0i = br_i32_ninv32(mq[1]); - br_i32_decode_reduce(s2, x, xlen, mq); - br_i32_modpow(s2, sk->dq, sk->dqlen, mq, q0i, t1, t2); - - /* - * Compute: - * h = (s1 - s2)*(1/q) mod p - * s1 is an integer modulo p, but s2 is modulo q. PKCS#1 is - * unclear about whether p may be lower than q (some existing, - * widely deployed implementations of RSA don't tolerate p < q), - * but we want to support that occurrence, so we need to use the - * reduction function. - * - * Since we use br_i32_decode_reduce() for iq (purportedly, the - * inverse of q modulo p), we also tolerate improperly large - * values for this parameter. - */ - br_i32_reduce(t2, s2, mp); - br_i32_add(s1, mp, br_i32_sub(s1, t2, 1)); - br_i32_to_monty(s1, mp); - br_i32_decode_reduce(t1, sk->iq, sk->iqlen, mp); - br_i32_montymul(t2, s1, t1, mp, p0i); - - /* - * h is now in t2. We compute the final result: - * s = s2 + q*h - * All these operations are non-modular. - * - * We need mq, s2 and t2. We use the t3 buffer as destination. - * The buffers mp, s1 and t1 are no longer needed. Moreover, - * the first step is to copy s2 into the destination buffer t3. - * We thus arranged for t3 to actually share space with s2, and - * to be followed by the space formerly used by s1 and t1. - */ - br_i32_mulacc(t3, mq, t2); - - /* - * Encode the result. Since we already checked the value of xlen, - * we can just use it right away. - */ - br_i32_encode(x, xlen, t3); - - /* - * The only error conditions remaining at that point are invalid - * values for p and q (even integers). - */ - return p0i & q0i & r; -} diff --git a/third_party/bearssl/src/rsa_i32_pss_sign.c b/third_party/bearssl/src/rsa_i32_pss_sign.c deleted file mode 100644 index 0f72f9274..000000000 --- a/third_party/bearssl/src/rsa_i32_pss_sign.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i32_pss_sign(const br_prng_class **rng, - const br_hash_class *hf_data, const br_hash_class *hf_mgf1, - const unsigned char *hash, size_t salt_len, - const br_rsa_private_key *sk, unsigned char *x) -{ - if (!br_rsa_pss_sig_pad(rng, hf_data, hf_mgf1, hash, - salt_len, sk->n_bitlen, x)) - { - return 0; - } - return br_rsa_i32_private(x, sk); -} diff --git a/third_party/bearssl/src/rsa_i32_pss_vrfy.c b/third_party/bearssl/src/rsa_i32_pss_vrfy.c deleted file mode 100644 index 2e70d2348..000000000 --- a/third_party/bearssl/src/rsa_i32_pss_vrfy.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i32_pss_vrfy(const unsigned char *x, size_t xlen, - const br_hash_class *hf_data, const br_hash_class *hf_mgf1, - const void *hash, size_t salt_len, const br_rsa_public_key *pk) -{ - unsigned char sig[BR_MAX_RSA_SIZE >> 3]; - - if (xlen > (sizeof sig)) { - return 0; - } - memcpy(sig, x, xlen); - if (!br_rsa_i32_public(sig, xlen, pk)) { - return 0; - } - return br_rsa_pss_sig_unpad(hf_data, hf_mgf1, - hash, salt_len, pk, sig); -} diff --git a/third_party/bearssl/src/rsa_i32_pub.c b/third_party/bearssl/src/rsa_i32_pub.c deleted file mode 100644 index 6e8d8e3eb..000000000 --- a/third_party/bearssl/src/rsa_i32_pub.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_rsa.h */ -uint32_t -br_rsa_i32_public(unsigned char *x, size_t xlen, - const br_rsa_public_key *pk) -{ - const unsigned char *n; - size_t nlen; - uint32_t m[1 + (BR_MAX_RSA_SIZE >> 5)]; - uint32_t a[1 + (BR_MAX_RSA_SIZE >> 5)]; - uint32_t t1[1 + (BR_MAX_RSA_SIZE >> 5)]; - uint32_t t2[1 + (BR_MAX_RSA_SIZE >> 5)]; - uint32_t m0i, r; - - /* - * Get the actual length of the modulus, and see if it fits within - * our stack buffer. We also check that the length of x[] is valid. - */ - n = pk->n; - nlen = pk->nlen; - while (nlen > 0 && *n == 0) { - n ++; - nlen --; - } - if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) { - return 0; - } - br_i32_decode(m, n, nlen); - m0i = br_i32_ninv32(m[1]); - - /* - * Note: if m[] is even, then m0i == 0. Otherwise, m0i must be - * an odd integer. - */ - r = m0i & 1; - - /* - * Decode x[] into a[]; we also check that its value is proper. - */ - r &= br_i32_decode_mod(a, x, xlen, m); - - /* - * Compute the modular exponentiation. - */ - br_i32_modpow(a, pk->e, pk->elen, m, m0i, t1, t2); - - /* - * Encode the result. - */ - br_i32_encode(x, xlen, a); - return r; -} diff --git a/third_party/bearssl/src/settings.c b/third_party/bearssl/src/settings.c deleted file mode 100644 index ccd8152ef..000000000 --- a/third_party/bearssl/src/settings.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -static const br_config_option config[] = { - { "BR_64", -#if BR_64 - 1 -#else - 0 -#endif - }, - { "BR_AES_X86NI", -#if BR_AES_X86NI - 1 -#else - 0 -#endif - }, - { "BR_amd64", -#if BR_amd64 - 1 -#else - 0 -#endif - }, - { "BR_ARMEL_CORTEXM_GCC", -#if BR_ARMEL_CORTEXM_GCC - 1 -#else - 0 -#endif - }, - { "BR_BE_UNALIGNED", -#if BR_BE_UNALIGNED - 1 -#else - 0 -#endif - }, - { "BR_CLANG", -#if BR_CLANG - 1 -#else - 0 -#endif - }, - { "BR_CLANG_3_7", -#if BR_CLANG_3_7 - 1 -#else - 0 -#endif - }, - { "BR_CLANG_3_8", -#if BR_CLANG_3_8 - 1 -#else - 0 -#endif - }, - { "BR_CT_MUL15", -#if BR_CT_MUL15 - 1 -#else - 0 -#endif - }, - { "BR_CT_MUL31", -#if BR_CT_MUL31 - 1 -#else - 0 -#endif - }, - { "BR_GCC", -#if BR_GCC - 1 -#else - 0 -#endif - }, - { "BR_GCC_4_4", -#if BR_GCC_4_4 - 1 -#else - 0 -#endif - }, - { "BR_GCC_4_5", -#if BR_GCC_4_5 - 1 -#else - 0 -#endif - }, - { "BR_GCC_4_6", -#if BR_GCC_4_6 - 1 -#else - 0 -#endif - }, - { "BR_GCC_4_7", -#if BR_GCC_4_7 - 1 -#else - 0 -#endif - }, - { "BR_GCC_4_8", -#if BR_GCC_4_8 - 1 -#else - 0 -#endif - }, - { "BR_GCC_4_9", -#if BR_GCC_4_9 - 1 -#else - 0 -#endif - }, - { "BR_GCC_5_0", -#if BR_GCC_5_0 - 1 -#else - 0 -#endif - }, - { "BR_i386", -#if BR_i386 - 1 -#else - 0 -#endif - }, - { "BR_INT128", -#if BR_INT128 - 1 -#else - 0 -#endif - }, - { "BR_LE_UNALIGNED", -#if BR_LE_UNALIGNED - 1 -#else - 0 -#endif - }, - { "BR_LOMUL", -#if BR_LOMUL - 1 -#else - 0 -#endif - }, - { "BR_MAX_EC_SIZE", BR_MAX_EC_SIZE }, - { "BR_MAX_RSA_SIZE", BR_MAX_RSA_SIZE }, - { "BR_MAX_RSA_FACTOR", BR_MAX_RSA_FACTOR }, - { "BR_MSC", -#if BR_MSC - 1 -#else - 0 -#endif - }, - { "BR_MSC_2005", -#if BR_MSC_2005 - 1 -#else - 0 -#endif - }, - { "BR_MSC_2008", -#if BR_MSC_2008 - 1 -#else - 0 -#endif - }, - { "BR_MSC_2010", -#if BR_MSC_2010 - 1 -#else - 0 -#endif - }, - { "BR_MSC_2012", -#if BR_MSC_2012 - 1 -#else - 0 -#endif - }, - { "BR_MSC_2013", -#if BR_MSC_2013 - 1 -#else - 0 -#endif - }, - { "BR_MSC_2015", -#if BR_MSC_2015 - 1 -#else - 0 -#endif - }, - { "BR_RDRAND", -#if BR_RDRAND - 1 -#else - 0 -#endif - }, - { "BR_SLOW_MUL", -#if BR_SLOW_MUL - 1 -#else - 0 -#endif - }, - { "BR_SLOW_MUL15", -#if BR_SLOW_MUL15 - 1 -#else - 0 -#endif - }, - { "BR_SSE2", -#if BR_SSE2 - 1 -#else - 0 -#endif - }, - { "BR_UMUL128", -#if BR_UMUL128 - 1 -#else - 0 -#endif - }, - { "BR_USE_UNIX_TIME", -#if BR_USE_UNIX_TIME - 1 -#else - 0 -#endif - }, - { "BR_USE_WIN32_RAND", -#if BR_USE_WIN32_RAND - 1 -#else - 0 -#endif - }, - { "BR_USE_WIN32_TIME", -#if BR_USE_WIN32_TIME - 1 -#else - 0 -#endif - }, - - { NULL, 0 } -}; - -/* see bearssl.h */ -const br_config_option * -br_get_config(void) -{ - return config; -} diff --git a/third_party/bearssl/src/shake.c b/third_party/bearssl/src/shake.c deleted file mode 100644 index 80d7176dc..000000000 --- a/third_party/bearssl/src/shake.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Copyright (c) 2018 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * Round constants. - */ -static const uint64_t RC[] = { - 0x0000000000000001, 0x0000000000008082, - 0x800000000000808A, 0x8000000080008000, - 0x000000000000808B, 0x0000000080000001, - 0x8000000080008081, 0x8000000000008009, - 0x000000000000008A, 0x0000000000000088, - 0x0000000080008009, 0x000000008000000A, - 0x000000008000808B, 0x800000000000008B, - 0x8000000000008089, 0x8000000000008003, - 0x8000000000008002, 0x8000000000000080, - 0x000000000000800A, 0x800000008000000A, - 0x8000000080008081, 0x8000000000008080, - 0x0000000080000001, 0x8000000080008008 -}; - -/* - * XOR a block of data into the provided state. This supports only - * blocks whose length is a multiple of 64 bits. - */ -static void -xor_block(uint64_t *A, const void *data, size_t rate) -{ - size_t u; - - for (u = 0; u < rate; u += 8) { - A[u >> 3] ^= br_dec64le((const unsigned char *)data + u); - } -} - -/* - * Process a block with the provided data. The data length must be a - * multiple of 8 (in bytes); normally, this is the "rate". - */ -static void -process_block(uint64_t *A) -{ - uint64_t t0, t1, t2, t3, t4; - uint64_t tt0, tt1, tt2, tt3; - uint64_t t, kt; - uint64_t c0, c1, c2, c3, c4, bnn; - int j; - - /* - * Compute the 24 rounds. This loop is partially unrolled (each - * iteration computes two rounds). - */ - for (j = 0; j < 24; j += 2) { - - tt0 = A[ 1] ^ A[ 6]; - tt1 = A[11] ^ A[16]; - tt0 ^= A[21] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >> 63); - tt2 = A[ 4] ^ A[ 9]; - tt3 = A[14] ^ A[19]; - tt0 ^= A[24]; - tt2 ^= tt3; - t0 = tt0 ^ tt2; - - tt0 = A[ 2] ^ A[ 7]; - tt1 = A[12] ^ A[17]; - tt0 ^= A[22] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >> 63); - tt2 = A[ 0] ^ A[ 5]; - tt3 = A[10] ^ A[15]; - tt0 ^= A[20]; - tt2 ^= tt3; - t1 = tt0 ^ tt2; - - tt0 = A[ 3] ^ A[ 8]; - tt1 = A[13] ^ A[18]; - tt0 ^= A[23] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >> 63); - tt2 = A[ 1] ^ A[ 6]; - tt3 = A[11] ^ A[16]; - tt0 ^= A[21]; - tt2 ^= tt3; - t2 = tt0 ^ tt2; - - tt0 = A[ 4] ^ A[ 9]; - tt1 = A[14] ^ A[19]; - tt0 ^= A[24] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >> 63); - tt2 = A[ 2] ^ A[ 7]; - tt3 = A[12] ^ A[17]; - tt0 ^= A[22]; - tt2 ^= tt3; - t3 = tt0 ^ tt2; - - tt0 = A[ 0] ^ A[ 5]; - tt1 = A[10] ^ A[15]; - tt0 ^= A[20] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >> 63); - tt2 = A[ 3] ^ A[ 8]; - tt3 = A[13] ^ A[18]; - tt0 ^= A[23]; - tt2 ^= tt3; - t4 = tt0 ^ tt2; - - A[ 0] = A[ 0] ^ t0; - A[ 5] = A[ 5] ^ t0; - A[10] = A[10] ^ t0; - A[15] = A[15] ^ t0; - A[20] = A[20] ^ t0; - A[ 1] = A[ 1] ^ t1; - A[ 6] = A[ 6] ^ t1; - A[11] = A[11] ^ t1; - A[16] = A[16] ^ t1; - A[21] = A[21] ^ t1; - A[ 2] = A[ 2] ^ t2; - A[ 7] = A[ 7] ^ t2; - A[12] = A[12] ^ t2; - A[17] = A[17] ^ t2; - A[22] = A[22] ^ t2; - A[ 3] = A[ 3] ^ t3; - A[ 8] = A[ 8] ^ t3; - A[13] = A[13] ^ t3; - A[18] = A[18] ^ t3; - A[23] = A[23] ^ t3; - A[ 4] = A[ 4] ^ t4; - A[ 9] = A[ 9] ^ t4; - A[14] = A[14] ^ t4; - A[19] = A[19] ^ t4; - A[24] = A[24] ^ t4; - A[ 5] = (A[ 5] << 36) | (A[ 5] >> (64 - 36)); - A[10] = (A[10] << 3) | (A[10] >> (64 - 3)); - A[15] = (A[15] << 41) | (A[15] >> (64 - 41)); - A[20] = (A[20] << 18) | (A[20] >> (64 - 18)); - A[ 1] = (A[ 1] << 1) | (A[ 1] >> (64 - 1)); - A[ 6] = (A[ 6] << 44) | (A[ 6] >> (64 - 44)); - A[11] = (A[11] << 10) | (A[11] >> (64 - 10)); - A[16] = (A[16] << 45) | (A[16] >> (64 - 45)); - A[21] = (A[21] << 2) | (A[21] >> (64 - 2)); - A[ 2] = (A[ 2] << 62) | (A[ 2] >> (64 - 62)); - A[ 7] = (A[ 7] << 6) | (A[ 7] >> (64 - 6)); - A[12] = (A[12] << 43) | (A[12] >> (64 - 43)); - A[17] = (A[17] << 15) | (A[17] >> (64 - 15)); - A[22] = (A[22] << 61) | (A[22] >> (64 - 61)); - A[ 3] = (A[ 3] << 28) | (A[ 3] >> (64 - 28)); - A[ 8] = (A[ 8] << 55) | (A[ 8] >> (64 - 55)); - A[13] = (A[13] << 25) | (A[13] >> (64 - 25)); - A[18] = (A[18] << 21) | (A[18] >> (64 - 21)); - A[23] = (A[23] << 56) | (A[23] >> (64 - 56)); - A[ 4] = (A[ 4] << 27) | (A[ 4] >> (64 - 27)); - A[ 9] = (A[ 9] << 20) | (A[ 9] >> (64 - 20)); - A[14] = (A[14] << 39) | (A[14] >> (64 - 39)); - A[19] = (A[19] << 8) | (A[19] >> (64 - 8)); - A[24] = (A[24] << 14) | (A[24] >> (64 - 14)); - bnn = ~A[12]; - kt = A[ 6] | A[12]; - c0 = A[ 0] ^ kt; - kt = bnn | A[18]; - c1 = A[ 6] ^ kt; - kt = A[18] & A[24]; - c2 = A[12] ^ kt; - kt = A[24] | A[ 0]; - c3 = A[18] ^ kt; - kt = A[ 0] & A[ 6]; - c4 = A[24] ^ kt; - A[ 0] = c0; - A[ 6] = c1; - A[12] = c2; - A[18] = c3; - A[24] = c4; - bnn = ~A[22]; - kt = A[ 9] | A[10]; - c0 = A[ 3] ^ kt; - kt = A[10] & A[16]; - c1 = A[ 9] ^ kt; - kt = A[16] | bnn; - c2 = A[10] ^ kt; - kt = A[22] | A[ 3]; - c3 = A[16] ^ kt; - kt = A[ 3] & A[ 9]; - c4 = A[22] ^ kt; - A[ 3] = c0; - A[ 9] = c1; - A[10] = c2; - A[16] = c3; - A[22] = c4; - bnn = ~A[19]; - kt = A[ 7] | A[13]; - c0 = A[ 1] ^ kt; - kt = A[13] & A[19]; - c1 = A[ 7] ^ kt; - kt = bnn & A[20]; - c2 = A[13] ^ kt; - kt = A[20] | A[ 1]; - c3 = bnn ^ kt; - kt = A[ 1] & A[ 7]; - c4 = A[20] ^ kt; - A[ 1] = c0; - A[ 7] = c1; - A[13] = c2; - A[19] = c3; - A[20] = c4; - bnn = ~A[17]; - kt = A[ 5] & A[11]; - c0 = A[ 4] ^ kt; - kt = A[11] | A[17]; - c1 = A[ 5] ^ kt; - kt = bnn | A[23]; - c2 = A[11] ^ kt; - kt = A[23] & A[ 4]; - c3 = bnn ^ kt; - kt = A[ 4] | A[ 5]; - c4 = A[23] ^ kt; - A[ 4] = c0; - A[ 5] = c1; - A[11] = c2; - A[17] = c3; - A[23] = c4; - bnn = ~A[ 8]; - kt = bnn & A[14]; - c0 = A[ 2] ^ kt; - kt = A[14] | A[15]; - c1 = bnn ^ kt; - kt = A[15] & A[21]; - c2 = A[14] ^ kt; - kt = A[21] | A[ 2]; - c3 = A[15] ^ kt; - kt = A[ 2] & A[ 8]; - c4 = A[21] ^ kt; - A[ 2] = c0; - A[ 8] = c1; - A[14] = c2; - A[15] = c3; - A[21] = c4; - A[ 0] = A[ 0] ^ RC[j + 0]; - - tt0 = A[ 6] ^ A[ 9]; - tt1 = A[ 7] ^ A[ 5]; - tt0 ^= A[ 8] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >> 63); - tt2 = A[24] ^ A[22]; - tt3 = A[20] ^ A[23]; - tt0 ^= A[21]; - tt2 ^= tt3; - t0 = tt0 ^ tt2; - - tt0 = A[12] ^ A[10]; - tt1 = A[13] ^ A[11]; - tt0 ^= A[14] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >> 63); - tt2 = A[ 0] ^ A[ 3]; - tt3 = A[ 1] ^ A[ 4]; - tt0 ^= A[ 2]; - tt2 ^= tt3; - t1 = tt0 ^ tt2; - - tt0 = A[18] ^ A[16]; - tt1 = A[19] ^ A[17]; - tt0 ^= A[15] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >> 63); - tt2 = A[ 6] ^ A[ 9]; - tt3 = A[ 7] ^ A[ 5]; - tt0 ^= A[ 8]; - tt2 ^= tt3; - t2 = tt0 ^ tt2; - - tt0 = A[24] ^ A[22]; - tt1 = A[20] ^ A[23]; - tt0 ^= A[21] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >> 63); - tt2 = A[12] ^ A[10]; - tt3 = A[13] ^ A[11]; - tt0 ^= A[14]; - tt2 ^= tt3; - t3 = tt0 ^ tt2; - - tt0 = A[ 0] ^ A[ 3]; - tt1 = A[ 1] ^ A[ 4]; - tt0 ^= A[ 2] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >> 63); - tt2 = A[18] ^ A[16]; - tt3 = A[19] ^ A[17]; - tt0 ^= A[15]; - tt2 ^= tt3; - t4 = tt0 ^ tt2; - - A[ 0] = A[ 0] ^ t0; - A[ 3] = A[ 3] ^ t0; - A[ 1] = A[ 1] ^ t0; - A[ 4] = A[ 4] ^ t0; - A[ 2] = A[ 2] ^ t0; - A[ 6] = A[ 6] ^ t1; - A[ 9] = A[ 9] ^ t1; - A[ 7] = A[ 7] ^ t1; - A[ 5] = A[ 5] ^ t1; - A[ 8] = A[ 8] ^ t1; - A[12] = A[12] ^ t2; - A[10] = A[10] ^ t2; - A[13] = A[13] ^ t2; - A[11] = A[11] ^ t2; - A[14] = A[14] ^ t2; - A[18] = A[18] ^ t3; - A[16] = A[16] ^ t3; - A[19] = A[19] ^ t3; - A[17] = A[17] ^ t3; - A[15] = A[15] ^ t3; - A[24] = A[24] ^ t4; - A[22] = A[22] ^ t4; - A[20] = A[20] ^ t4; - A[23] = A[23] ^ t4; - A[21] = A[21] ^ t4; - A[ 3] = (A[ 3] << 36) | (A[ 3] >> (64 - 36)); - A[ 1] = (A[ 1] << 3) | (A[ 1] >> (64 - 3)); - A[ 4] = (A[ 4] << 41) | (A[ 4] >> (64 - 41)); - A[ 2] = (A[ 2] << 18) | (A[ 2] >> (64 - 18)); - A[ 6] = (A[ 6] << 1) | (A[ 6] >> (64 - 1)); - A[ 9] = (A[ 9] << 44) | (A[ 9] >> (64 - 44)); - A[ 7] = (A[ 7] << 10) | (A[ 7] >> (64 - 10)); - A[ 5] = (A[ 5] << 45) | (A[ 5] >> (64 - 45)); - A[ 8] = (A[ 8] << 2) | (A[ 8] >> (64 - 2)); - A[12] = (A[12] << 62) | (A[12] >> (64 - 62)); - A[10] = (A[10] << 6) | (A[10] >> (64 - 6)); - A[13] = (A[13] << 43) | (A[13] >> (64 - 43)); - A[11] = (A[11] << 15) | (A[11] >> (64 - 15)); - A[14] = (A[14] << 61) | (A[14] >> (64 - 61)); - A[18] = (A[18] << 28) | (A[18] >> (64 - 28)); - A[16] = (A[16] << 55) | (A[16] >> (64 - 55)); - A[19] = (A[19] << 25) | (A[19] >> (64 - 25)); - A[17] = (A[17] << 21) | (A[17] >> (64 - 21)); - A[15] = (A[15] << 56) | (A[15] >> (64 - 56)); - A[24] = (A[24] << 27) | (A[24] >> (64 - 27)); - A[22] = (A[22] << 20) | (A[22] >> (64 - 20)); - A[20] = (A[20] << 39) | (A[20] >> (64 - 39)); - A[23] = (A[23] << 8) | (A[23] >> (64 - 8)); - A[21] = (A[21] << 14) | (A[21] >> (64 - 14)); - bnn = ~A[13]; - kt = A[ 9] | A[13]; - c0 = A[ 0] ^ kt; - kt = bnn | A[17]; - c1 = A[ 9] ^ kt; - kt = A[17] & A[21]; - c2 = A[13] ^ kt; - kt = A[21] | A[ 0]; - c3 = A[17] ^ kt; - kt = A[ 0] & A[ 9]; - c4 = A[21] ^ kt; - A[ 0] = c0; - A[ 9] = c1; - A[13] = c2; - A[17] = c3; - A[21] = c4; - bnn = ~A[14]; - kt = A[22] | A[ 1]; - c0 = A[18] ^ kt; - kt = A[ 1] & A[ 5]; - c1 = A[22] ^ kt; - kt = A[ 5] | bnn; - c2 = A[ 1] ^ kt; - kt = A[14] | A[18]; - c3 = A[ 5] ^ kt; - kt = A[18] & A[22]; - c4 = A[14] ^ kt; - A[18] = c0; - A[22] = c1; - A[ 1] = c2; - A[ 5] = c3; - A[14] = c4; - bnn = ~A[23]; - kt = A[10] | A[19]; - c0 = A[ 6] ^ kt; - kt = A[19] & A[23]; - c1 = A[10] ^ kt; - kt = bnn & A[ 2]; - c2 = A[19] ^ kt; - kt = A[ 2] | A[ 6]; - c3 = bnn ^ kt; - kt = A[ 6] & A[10]; - c4 = A[ 2] ^ kt; - A[ 6] = c0; - A[10] = c1; - A[19] = c2; - A[23] = c3; - A[ 2] = c4; - bnn = ~A[11]; - kt = A[ 3] & A[ 7]; - c0 = A[24] ^ kt; - kt = A[ 7] | A[11]; - c1 = A[ 3] ^ kt; - kt = bnn | A[15]; - c2 = A[ 7] ^ kt; - kt = A[15] & A[24]; - c3 = bnn ^ kt; - kt = A[24] | A[ 3]; - c4 = A[15] ^ kt; - A[24] = c0; - A[ 3] = c1; - A[ 7] = c2; - A[11] = c3; - A[15] = c4; - bnn = ~A[16]; - kt = bnn & A[20]; - c0 = A[12] ^ kt; - kt = A[20] | A[ 4]; - c1 = bnn ^ kt; - kt = A[ 4] & A[ 8]; - c2 = A[20] ^ kt; - kt = A[ 8] | A[12]; - c3 = A[ 4] ^ kt; - kt = A[12] & A[16]; - c4 = A[ 8] ^ kt; - A[12] = c0; - A[16] = c1; - A[20] = c2; - A[ 4] = c3; - A[ 8] = c4; - A[ 0] = A[ 0] ^ RC[j + 1]; - t = A[ 5]; - A[ 5] = A[18]; - A[18] = A[11]; - A[11] = A[10]; - A[10] = A[ 6]; - A[ 6] = A[22]; - A[22] = A[20]; - A[20] = A[12]; - A[12] = A[19]; - A[19] = A[15]; - A[15] = A[24]; - A[24] = A[ 8]; - A[ 8] = t; - t = A[ 1]; - A[ 1] = A[ 9]; - A[ 9] = A[14]; - A[14] = A[ 2]; - A[ 2] = A[13]; - A[13] = A[23]; - A[23] = A[ 4]; - A[ 4] = A[21]; - A[21] = A[16]; - A[16] = A[ 3]; - A[ 3] = A[17]; - A[17] = A[ 7]; - A[ 7] = t; - } -} - -/* see bearssl_kdf.h */ -void -br_shake_init(br_shake_context *sc, int security_level) -{ - sc->rate = 200 - (size_t)(security_level >> 2); - sc->dptr = 0; - memset(sc->A, 0, sizeof sc->A); - sc->A[ 1] = ~(uint64_t)0; - sc->A[ 2] = ~(uint64_t)0; - sc->A[ 8] = ~(uint64_t)0; - sc->A[12] = ~(uint64_t)0; - sc->A[17] = ~(uint64_t)0; - sc->A[20] = ~(uint64_t)0; -} - -/* see bearssl_kdf.h */ -void -br_shake_inject(br_shake_context *sc, const void *data, size_t len) -{ - const unsigned char *buf; - size_t rate, dptr; - - buf = data; - rate = sc->rate; - dptr = sc->dptr; - while (len > 0) { - size_t clen; - - clen = rate - dptr; - if (clen > len) { - clen = len; - } - memcpy(sc->dbuf + dptr, buf, clen); - dptr += clen; - buf += clen; - len -= clen; - if (dptr == rate) { - xor_block(sc->A, sc->dbuf, rate); - process_block(sc->A); - dptr = 0; - } - } - sc->dptr = dptr; -} - -/* see bearssl_kdf.h */ -void -br_shake_flip(br_shake_context *sc) -{ - /* - * We apply padding and pre-XOR the value into the state. We - * set dptr to the end of the buffer, so that first call to - * shake_extract() will process the block. - */ - if ((sc->dptr + 1) == sc->rate) { - sc->dbuf[sc->dptr ++] = 0x9F; - } else { - sc->dbuf[sc->dptr ++] = 0x1F; - memset(sc->dbuf + sc->dptr, 0x00, sc->rate - sc->dptr - 1); - sc->dbuf[sc->rate - 1] = 0x80; - sc->dptr = sc->rate; - } - xor_block(sc->A, sc->dbuf, sc->rate); -} - -/* see bearssl_kdf.h */ -void -br_shake_produce(br_shake_context *sc, void *out, size_t len) -{ - unsigned char *buf; - size_t dptr, rate; - - buf = out; - dptr = sc->dptr; - rate = sc->rate; - while (len > 0) { - size_t clen; - - if (dptr == rate) { - unsigned char *dbuf; - uint64_t *A; - - A = sc->A; - dbuf = sc->dbuf; - process_block(A); - br_enc64le(dbuf + 0, A[ 0]); - br_enc64le(dbuf + 8, ~A[ 1]); - br_enc64le(dbuf + 16, ~A[ 2]); - br_enc64le(dbuf + 24, A[ 3]); - br_enc64le(dbuf + 32, A[ 4]); - br_enc64le(dbuf + 40, A[ 5]); - br_enc64le(dbuf + 48, A[ 6]); - br_enc64le(dbuf + 56, A[ 7]); - br_enc64le(dbuf + 64, ~A[ 8]); - br_enc64le(dbuf + 72, A[ 9]); - br_enc64le(dbuf + 80, A[10]); - br_enc64le(dbuf + 88, A[11]); - br_enc64le(dbuf + 96, ~A[12]); - br_enc64le(dbuf + 104, A[13]); - br_enc64le(dbuf + 112, A[14]); - br_enc64le(dbuf + 120, A[15]); - br_enc64le(dbuf + 128, A[16]); - br_enc64le(dbuf + 136, ~A[17]); - br_enc64le(dbuf + 144, A[18]); - br_enc64le(dbuf + 152, A[19]); - br_enc64le(dbuf + 160, ~A[20]); - br_enc64le(dbuf + 168, A[21]); - br_enc64le(dbuf + 176, A[22]); - br_enc64le(dbuf + 184, A[23]); - br_enc64le(dbuf + 192, A[24]); - dptr = 0; - } - clen = rate - dptr; - if (clen > len) { - clen = len; - } - memcpy(buf, sc->dbuf + dptr, clen); - dptr += clen; - buf += clen; - len -= clen; - } - sc->dptr = dptr; -} diff --git a/third_party/bearssl/src/skey_decoder.c b/third_party/bearssl/src/skey_decoder.c deleted file mode 100644 index 9e285d74e..000000000 --- a/third_party/bearssl/src/skey_decoder.c +++ /dev/null @@ -1,650 +0,0 @@ -/* Automatically generated code; do not modify directly. */ - -#include -#include - -typedef struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; -} t0_context; - -static uint32_t -t0_parse7E_unsigned(const unsigned char **p) -{ - uint32_t x; - - x = 0; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - return x; - } - } -} - -static int32_t -t0_parse7E_signed(const unsigned char **p) -{ - int neg; - uint32_t x; - - neg = ((**p) >> 6) & 1; - x = (uint32_t)-neg; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - if (neg) { - return -(int32_t)~x - 1; - } else { - return (int32_t)x; - } - } - } -} - -#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) -#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) -#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) -#define T0_INT1(x) T0_FBYTE(x, 0) -#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) - -/* static const unsigned char t0_datablock[]; */ - - -void br_skey_decoder_init_main(void *t0ctx); - -void br_skey_decoder_run(void *t0ctx); - - - -#include "inner.h" - - - - - -#include "inner.h" - -#define CTX ((br_skey_decoder_context *)(void *)((unsigned char *)t0ctx - offsetof(br_skey_decoder_context, cpu))) -#define CONTEXT_NAME br_skey_decoder_context - -/* see bearssl_x509.h */ -void -br_skey_decoder_init(br_skey_decoder_context *ctx) -{ - memset(ctx, 0, sizeof *ctx); - ctx->cpu.dp = &ctx->dp_stack[0]; - ctx->cpu.rp = &ctx->rp_stack[0]; - br_skey_decoder_init_main(&ctx->cpu); - br_skey_decoder_run(&ctx->cpu); -} - -/* see bearssl_x509.h */ -void -br_skey_decoder_push(br_skey_decoder_context *ctx, - const void *data, size_t len) -{ - ctx->hbuf = data; - ctx->hlen = len; - br_skey_decoder_run(&ctx->cpu); -} - - - -static const unsigned char t0_datablock[] = { - 0x00, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x07, - 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x08, 0x2A, 0x86, 0x48, 0xCE, - 0x3D, 0x03, 0x01, 0x07, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x05, 0x2B, - 0x81, 0x04, 0x00, 0x23 -}; - -static const unsigned char t0_codeblock[] = { - 0x00, 0x01, 0x01, 0x07, 0x00, 0x00, 0x01, 0x01, 0x08, 0x00, 0x00, 0x13, - 0x13, 0x00, 0x00, 0x01, T0_INT1(BR_ERR_X509_BAD_TAG_CLASS), 0x00, 0x00, - 0x01, T0_INT1(BR_ERR_X509_BAD_TAG_VALUE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_EXTRA_ELEMENT), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_INDEFINITE_LENGTH), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_INNER_TRUNC), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_INVALID_VALUE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_NOT_CONSTRUCTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_NOT_PRIMITIVE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_OVERFLOW), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_UNEXPECTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_UNSUPPORTED), 0x00, 0x00, 0x01, - T0_INT1(BR_KEYTYPE_EC), 0x00, 0x00, 0x01, T0_INT1(BR_KEYTYPE_RSA), - 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, key_data)), 0x00, - 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, key_type)), 0x00, 0x00, - 0x33, 0x48, 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, pad)), - 0x00, 0x00, 0x01, 0x13, 0x00, 0x00, 0x01, 0x1C, 0x00, 0x00, 0x01, 0x22, - 0x00, 0x00, 0x05, 0x02, 0x2C, 0x16, 0x00, 0x00, 0x06, 0x02, 0x2D, 0x16, - 0x00, 0x00, 0x01, 0x10, 0x3D, 0x00, 0x00, 0x0D, 0x05, 0x02, 0x2F, 0x16, - 0x3A, 0x00, 0x00, 0x0D, 0x05, 0x02, 0x2F, 0x16, 0x3B, 0x00, 0x00, 0x06, - 0x02, 0x27, 0x16, 0x00, 0x01, 0x03, 0x00, 0x54, 0x57, 0x01, 0x02, 0x3E, - 0x55, 0x23, 0x06, 0x02, 0x30, 0x16, 0x57, 0x01, 0x04, 0x3E, 0x02, 0x00, - 0x41, 0x3F, 0x00, 0x02, 0x03, 0x00, 0x53, 0x14, 0x14, 0x03, 0x01, 0x48, - 0x0E, 0x06, 0x02, 0x30, 0x16, 0x33, 0x4C, 0x58, 0x01, 0x7F, 0x19, 0x0D, - 0x06, 0x04, 0x13, 0x13, 0x04, 0x29, 0x01, 0x20, 0x19, 0x0D, 0x06, 0x16, - 0x13, 0x3A, 0x53, 0x4D, 0x02, 0x00, 0x06, 0x09, 0x02, 0x00, 0x0C, 0x06, - 0x02, 0x2A, 0x16, 0x04, 0x02, 0x03, 0x00, 0x3F, 0x04, 0x0D, 0x01, 0x21, - 0x19, 0x0D, 0x06, 0x04, 0x13, 0x3A, 0x04, 0x03, 0x30, 0x16, 0x13, 0x5D, - 0x02, 0x00, 0x05, 0x02, 0x30, 0x16, 0x02, 0x00, 0x02, 0x01, 0x1D, 0x00, - 0x02, 0x53, 0x4B, 0x05, 0x02, 0x30, 0x16, 0x5B, 0x15, 0x06, 0x07, 0x5D, - 0x01, 0x7F, 0x03, 0x01, 0x04, 0x16, 0x46, 0x15, 0x06, 0x10, 0x01, 0x00, - 0x03, 0x01, 0x14, 0x06, 0x03, 0x4D, 0x04, 0x02, 0x01, 0x00, 0x03, 0x00, - 0x04, 0x02, 0x30, 0x16, 0x3F, 0x57, 0x01, 0x04, 0x3E, 0x53, 0x02, 0x01, - 0x06, 0x03, 0x43, 0x04, 0x03, 0x02, 0x00, 0x40, 0x3F, 0x5D, 0x02, 0x01, - 0x06, 0x03, 0x32, 0x04, 0x01, 0x31, 0x00, 0x00, 0x54, 0x57, 0x01, 0x02, - 0x3E, 0x55, 0x06, 0x02, 0x30, 0x16, 0x57, 0x01, 0x02, 0x3E, 0x44, 0x3F, - 0x00, 0x07, 0x35, 0x50, 0x14, 0x05, 0x02, 0x2F, 0x16, 0x23, 0x01, 0x03, - 0x0B, 0x33, 0x17, 0x47, 0x07, 0x03, 0x00, 0x4F, 0x4F, 0x35, 0x4E, 0x14, - 0x14, 0x03, 0x01, 0x03, 0x02, 0x51, 0x14, 0x03, 0x03, 0x02, 0x02, 0x07, - 0x14, 0x03, 0x02, 0x51, 0x14, 0x03, 0x04, 0x02, 0x02, 0x07, 0x14, 0x03, - 0x02, 0x51, 0x14, 0x03, 0x05, 0x02, 0x02, 0x07, 0x14, 0x03, 0x02, 0x51, - 0x03, 0x06, 0x02, 0x00, 0x02, 0x01, 0x02, 0x03, 0x02, 0x04, 0x02, 0x05, - 0x02, 0x06, 0x1E, 0x00, 0x00, 0x19, 0x19, 0x00, 0x00, 0x01, 0x0B, 0x00, - 0x00, 0x01, 0x00, 0x20, 0x14, 0x06, 0x08, 0x01, 0x01, 0x21, 0x20, 0x22, - 0x20, 0x04, 0x75, 0x13, 0x00, 0x00, 0x01, - T0_INT2(3 * BR_X509_BUFSIZE_SIG), 0x00, 0x01, 0x01, 0x87, 0xFF, 0xFF, - 0x7F, 0x54, 0x57, 0x01, 0x02, 0x3E, 0x55, 0x01, 0x01, 0x0E, 0x06, 0x02, - 0x30, 0x16, 0x57, 0x01, 0x02, 0x19, 0x0D, 0x06, 0x06, 0x13, 0x3B, 0x44, - 0x32, 0x04, 0x1C, 0x01, 0x04, 0x19, 0x0D, 0x06, 0x08, 0x13, 0x3B, 0x01, - 0x00, 0x41, 0x31, 0x04, 0x0E, 0x01, 0x10, 0x19, 0x0D, 0x06, 0x05, 0x13, - 0x3A, 0x42, 0x04, 0x03, 0x30, 0x16, 0x13, 0x03, 0x00, 0x3F, 0x02, 0x00, - 0x34, 0x1F, 0x5A, 0x27, 0x16, 0x00, 0x01, 0x45, 0x0A, 0x06, 0x02, 0x29, - 0x16, 0x14, 0x03, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x57, 0x01, 0x06, - 0x3E, 0x56, 0x00, 0x00, 0x20, 0x14, 0x06, 0x07, 0x1A, 0x14, 0x06, 0x01, - 0x12, 0x04, 0x76, 0x24, 0x00, 0x00, 0x4B, 0x05, 0x02, 0x30, 0x16, 0x37, - 0x15, 0x06, 0x04, 0x01, 0x17, 0x04, 0x12, 0x38, 0x15, 0x06, 0x04, 0x01, - 0x18, 0x04, 0x0A, 0x39, 0x15, 0x06, 0x04, 0x01, 0x19, 0x04, 0x02, 0x30, - 0x16, 0x00, 0x00, 0x1C, 0x57, 0x01, 0x02, 0x3E, 0x09, 0x50, 0x00, 0x00, - 0x35, 0x4E, 0x13, 0x00, 0x03, 0x14, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, - 0x53, 0x59, 0x14, 0x01, 0x81, 0x00, 0x0F, 0x06, 0x02, 0x2E, 0x16, 0x14, - 0x01, 0x00, 0x0D, 0x06, 0x0B, 0x13, 0x14, 0x05, 0x04, 0x13, 0x01, 0x00, - 0x00, 0x59, 0x04, 0x6F, 0x02, 0x01, 0x14, 0x05, 0x02, 0x2B, 0x16, 0x23, - 0x03, 0x01, 0x02, 0x02, 0x1F, 0x02, 0x02, 0x22, 0x03, 0x02, 0x14, 0x06, - 0x03, 0x59, 0x04, 0x68, 0x13, 0x02, 0x00, 0x02, 0x01, 0x08, 0x00, 0x00, - 0x14, 0x35, 0x1C, 0x08, 0x20, 0x1C, 0x07, 0x20, 0x4E, 0x00, 0x01, 0x59, - 0x14, 0x01, 0x81, 0x00, 0x0A, 0x06, 0x01, 0x00, 0x01, 0x81, 0x00, 0x08, - 0x14, 0x05, 0x02, 0x28, 0x16, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, - 0x00, 0x0E, 0x06, 0x19, 0x02, 0x00, 0x23, 0x03, 0x00, 0x14, 0x01, 0x83, - 0xFF, 0xFF, 0x7F, 0x0E, 0x06, 0x02, 0x29, 0x16, 0x01, 0x08, 0x0B, 0x20, - 0x59, 0x1C, 0x07, 0x04, 0x60, 0x00, 0x00, 0x52, 0x4A, 0x00, 0x00, 0x57, - 0x3C, 0x53, 0x00, 0x01, 0x53, 0x14, 0x05, 0x02, 0x2E, 0x16, 0x59, 0x14, - 0x01, 0x81, 0x00, 0x0F, 0x06, 0x02, 0x2E, 0x16, 0x03, 0x00, 0x14, 0x06, - 0x16, 0x59, 0x02, 0x00, 0x14, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x0F, 0x06, - 0x02, 0x2E, 0x16, 0x01, 0x08, 0x0B, 0x07, 0x03, 0x00, 0x04, 0x67, 0x13, - 0x02, 0x00, 0x00, 0x00, 0x53, 0x14, 0x01, 0x81, 0x7F, 0x0E, 0x06, 0x08, - 0x5C, 0x01, 0x00, 0x36, 0x1F, 0x01, 0x00, 0x00, 0x14, 0x36, 0x1F, 0x36, - 0x22, 0x4C, 0x01, 0x7F, 0x00, 0x01, 0x59, 0x03, 0x00, 0x02, 0x00, 0x01, - 0x05, 0x10, 0x01, 0x01, 0x11, 0x18, 0x02, 0x00, 0x01, 0x06, 0x10, 0x14, - 0x01, 0x01, 0x11, 0x06, 0x02, 0x25, 0x16, 0x01, 0x04, 0x0B, 0x02, 0x00, - 0x01, 0x1F, 0x11, 0x14, 0x01, 0x1F, 0x0D, 0x06, 0x02, 0x26, 0x16, 0x07, - 0x00, 0x00, 0x14, 0x05, 0x05, 0x01, 0x00, 0x01, 0x7F, 0x00, 0x57, 0x00, - 0x00, 0x14, 0x05, 0x02, 0x29, 0x16, 0x23, 0x5A, 0x00, 0x00, 0x1B, 0x14, - 0x01, 0x00, 0x0F, 0x06, 0x01, 0x00, 0x13, 0x12, 0x04, 0x74, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x5D, 0x13, 0x00, 0x00, 0x14, 0x06, 0x07, 0x5E, 0x14, - 0x06, 0x01, 0x12, 0x04, 0x76, 0x00, 0x00, 0x01, 0x00, 0x19, 0x1A, 0x09, - 0x24, 0x00 -}; - -static const uint16_t t0_caddr[] = { - 0, - 5, - 10, - 14, - 18, - 22, - 26, - 30, - 34, - 38, - 42, - 46, - 50, - 54, - 58, - 62, - 66, - 70, - 75, - 80, - 84, - 89, - 93, - 97, - 101, - 107, - 113, - 118, - 126, - 134, - 140, - 163, - 244, - 311, - 329, - 404, - 408, - 412, - 429, - 434, - 505, - 519, - 526, - 540, - 573, - 582, - 587, - 654, - 665, - 721, - 725, - 730, - 778, - 804, - 848, - 859, - 868, - 881, - 885, - 889, - 901 -}; - -#define T0_INTERPRETED 34 - -#define T0_ENTER(ip, rp, slot) do { \ - const unsigned char *t0_newip; \ - uint32_t t0_lnum; \ - t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ - t0_lnum = t0_parse7E_unsigned(&t0_newip); \ - (rp) += t0_lnum; \ - *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ - (ip) = t0_newip; \ - } while (0) - -#define T0_DEFENTRY(name, slot) \ -void \ -name(void *ctx) \ -{ \ - t0_context *t0ctx = ctx; \ - t0ctx->ip = &t0_codeblock[0]; \ - T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ -} - -T0_DEFENTRY(br_skey_decoder_init_main, 73) - -#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) - -void -br_skey_decoder_run(void *t0ctx) -{ - uint32_t *dp, *rp; - const unsigned char *ip; - -#define T0_LOCAL(x) (*(rp - 2 - (x))) -#define T0_POP() (*-- dp) -#define T0_POPi() (*(int32_t *)(-- dp)) -#define T0_PEEK(x) (*(dp - 1 - (x))) -#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) -#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) -#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) -#define T0_RPOP() (*-- rp) -#define T0_RPOPi() (*(int32_t *)(-- rp)) -#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) -#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) -#define T0_ROLL(x) do { \ - size_t t0len = (size_t)(x); \ - uint32_t t0tmp = *(dp - 1 - t0len); \ - memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_SWAP() do { \ - uint32_t t0tmp = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_ROT() do { \ - uint32_t t0tmp = *(dp - 3); \ - *(dp - 3) = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_NROT() do { \ - uint32_t t0tmp = *(dp - 1); \ - *(dp - 1) = *(dp - 2); \ - *(dp - 2) = *(dp - 3); \ - *(dp - 3) = t0tmp; \ -} while (0) -#define T0_PICK(x) do { \ - uint32_t t0depth = (x); \ - T0_PUSH(T0_PEEK(t0depth)); \ -} while (0) -#define T0_CO() do { \ - goto t0_exit; \ -} while (0) -#define T0_RET() goto t0_next - - dp = ((t0_context *)t0ctx)->dp; - rp = ((t0_context *)t0ctx)->rp; - ip = ((t0_context *)t0ctx)->ip; - goto t0_next; - for (;;) { - uint32_t t0x; - - t0_next: - t0x = T0_NEXT(&ip); - if (t0x < T0_INTERPRETED) { - switch (t0x) { - int32_t t0off; - - case 0: /* ret */ - t0x = T0_RPOP(); - rp -= (t0x >> 16); - t0x &= 0xFFFF; - if (t0x == 0) { - ip = NULL; - goto t0_exit; - } - ip = &t0_codeblock[t0x]; - break; - case 1: /* literal constant */ - T0_PUSHi(t0_parse7E_signed(&ip)); - break; - case 2: /* read local */ - T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); - break; - case 3: /* write local */ - T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); - break; - case 4: /* jump */ - t0off = t0_parse7E_signed(&ip); - ip += t0off; - break; - case 5: /* jump if */ - t0off = t0_parse7E_signed(&ip); - if (T0_POP()) { - ip += t0off; - } - break; - case 6: /* jump if not */ - t0off = t0_parse7E_signed(&ip); - if (!T0_POP()) { - ip += t0off; - } - break; - case 7: { - /* + */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a + b); - - } - break; - case 8: { - /* - */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a - b); - - } - break; - case 9: { - /* -rot */ - T0_NROT(); - } - break; - case 10: { - /* < */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a < b)); - - } - break; - case 11: { - /* << */ - - int c = (int)T0_POPi(); - uint32_t x = T0_POP(); - T0_PUSH(x << c); - - } - break; - case 12: { - /* <> */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a != b)); - - } - break; - case 13: { - /* = */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a == b)); - - } - break; - case 14: { - /* > */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a > b)); - - } - break; - case 15: { - /* >= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a >= b)); - - } - break; - case 16: { - /* >> */ - - int c = (int)T0_POPi(); - int32_t x = T0_POPi(); - T0_PUSHi(x >> c); - - } - break; - case 17: { - /* and */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a & b); - - } - break; - case 18: { - /* co */ - T0_CO(); - } - break; - case 19: { - /* drop */ - (void)T0_POP(); - } - break; - case 20: { - /* dup */ - T0_PUSH(T0_PEEK(0)); - } - break; - case 21: { - /* eqOID */ - - const unsigned char *a2 = &t0_datablock[T0_POP()]; - const unsigned char *a1 = &CTX->pad[0]; - size_t len = a1[0]; - int x; - if (len == a2[0]) { - x = -(memcmp(a1 + 1, a2 + 1, len) == 0); - } else { - x = 0; - } - T0_PUSH((uint32_t)x); - - } - break; - case 22: { - /* fail */ - - CTX->err = T0_POPi(); - T0_CO(); - - } - break; - case 23: { - /* get8 */ - - uint32_t addr = T0_POP(); - T0_PUSH(*((unsigned char *)CTX + addr)); - - } - break; - case 24: { - /* neg */ - - uint32_t a = T0_POP(); - T0_PUSH(-a); - - } - break; - case 25: { - /* over */ - T0_PUSH(T0_PEEK(1)); - } - break; - case 26: { - /* read-blob-inner */ - - uint32_t len = T0_POP(); - uint32_t addr = T0_POP(); - size_t clen = CTX->hlen; - if (clen > len) { - clen = (size_t)len; - } - if (addr != 0) { - memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); - } - CTX->hbuf += clen; - CTX->hlen -= clen; - T0_PUSH(addr + clen); - T0_PUSH(len - clen); - - } - break; - case 27: { - /* read8-low */ - - if (CTX->hlen == 0) { - T0_PUSHi(-1); - } else { - CTX->hlen --; - T0_PUSH(*CTX->hbuf ++); - } - - } - break; - case 28: { - /* rot */ - T0_ROT(); - } - break; - case 29: { - /* set-ec-key */ - - size_t xlen = T0_POP(); - uint32_t curve = T0_POP(); - CTX->key.ec.curve = curve; - CTX->key.ec.x = CTX->key_data; - CTX->key.ec.xlen = xlen; - - } - break; - case 30: { - /* set-rsa-key */ - - size_t iqlen = T0_POP(); - size_t dqlen = T0_POP(); - size_t dplen = T0_POP(); - size_t qlen = T0_POP(); - size_t plen = T0_POP(); - uint32_t n_bitlen = T0_POP(); - size_t off; - - CTX->key.rsa.n_bitlen = n_bitlen; - CTX->key.rsa.p = CTX->key_data; - CTX->key.rsa.plen = plen; - off = plen; - CTX->key.rsa.q = CTX->key_data + off; - CTX->key.rsa.qlen = qlen; - off += qlen; - CTX->key.rsa.dp = CTX->key_data + off; - CTX->key.rsa.dplen = dplen; - off += dplen; - CTX->key.rsa.dq = CTX->key_data + off; - CTX->key.rsa.dqlen = dqlen; - off += dqlen; - CTX->key.rsa.iq = CTX->key_data + off; - CTX->key.rsa.iqlen = iqlen; - - } - break; - case 31: { - /* set8 */ - - uint32_t addr = T0_POP(); - *((unsigned char *)CTX + addr) = (unsigned char)T0_POP(); - - } - break; - case 32: { - /* swap */ - T0_SWAP(); - } - break; - case 33: { - /* u>> */ - - int c = (int)T0_POPi(); - uint32_t x = T0_POP(); - T0_PUSH(x >> c); - - } - break; - } - - } else { - T0_ENTER(ip, rp, t0x); - } - } -t0_exit: - ((t0_context *)t0ctx)->dp = dp; - ((t0_context *)t0ctx)->rp = rp; - ((t0_context *)t0ctx)->ip = ip; -} diff --git a/third_party/bearssl/src/ssl_client_full.c b/third_party/bearssl/src/ssl_client_full.c index 981434990..9e754ad9c 100644 --- a/third_party/bearssl/src/ssl_client_full.c +++ b/third_party/bearssl/src/ssl_client_full.c @@ -36,7 +36,6 @@ br_ssl_client_init_full(br_ssl_client_context *cc, * Rationale for suite order, from most important to least * important rule: * - * -- Don't use 3DES if AES or ChaCha20 is available. * -- Try to have Forward Secrecy (ECDHE suite) if possible. * -- When not using Forward Secrecy, ECDH key exchange is * better than RSA key exchange (slightly more expensive on the @@ -89,12 +88,7 @@ br_ssl_client_init_full(br_ssl_client_context *cc, BR_TLS_RSA_WITH_AES_128_CBC_SHA256, BR_TLS_RSA_WITH_AES_256_CBC_SHA256, BR_TLS_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA + BR_TLS_RSA_WITH_AES_256_CBC_SHA }; /* @@ -174,6 +168,5 @@ br_ssl_client_init_full(br_ssl_client_context *cc, br_ssl_engine_set_default_aes_cbc(&cc->eng); br_ssl_engine_set_default_aes_ccm(&cc->eng); br_ssl_engine_set_default_aes_gcm(&cc->eng); - br_ssl_engine_set_default_des_cbc(&cc->eng); br_ssl_engine_set_default_chapol(&cc->eng); } diff --git a/third_party/bearssl/src/ssl_engine.c b/third_party/bearssl/src/ssl_engine.c index 4b895489d..61f8c0ef4 100644 --- a/third_party/bearssl/src/ssl_engine.c +++ b/third_party/bearssl/src/ssl_engine.c @@ -455,20 +455,6 @@ br_ssl_engine_init_rand(br_ssl_engine_context *cc) return 0; } - /* - * We always try OS/hardware seeding once. If it works, then - * we assume proper seeding. If not, then external entropy must - * have been injected; otherwise, we report an error. - */ - if (!cc->rng_os_rand_done) { - br_prng_seeder sd; - - sd = br_prng_seeder_system(NULL); - if (sd != 0 && sd(&cc->rng.vtable)) { - cc->rng_init_done = 2; - } - cc->rng_os_rand_done = 1; - } if (cc->rng_init_done < 2) { br_ssl_engine_fail(cc, BR_ERR_NO_RANDOM); return 0; diff --git a/third_party/bearssl/src/ssl_engine_default_aesgcm.c b/third_party/bearssl/src/ssl_engine_default_aesgcm.c index 996834287..8c8674816 100644 --- a/third_party/bearssl/src/ssl_engine_default_aesgcm.c +++ b/third_party/bearssl/src/ssl_engine_default_aesgcm.c @@ -61,9 +61,7 @@ br_ssl_engine_set_default_aes_gcm(br_ssl_engine_context *cc) return; } #endif -#if BR_LOMUL - br_ssl_engine_set_ghash(cc, &br_ghash_ctmul32); -#elif BR_64 +#if BR_64 br_ssl_engine_set_ghash(cc, &br_ghash_ctmul64); #else br_ssl_engine_set_ghash(cc, &br_ghash_ctmul); diff --git a/third_party/bearssl/src/ssl_engine_default_chapol.c b/third_party/bearssl/src/ssl_engine_default_chapol.c index 47a0c9847..7196b420e 100644 --- a/third_party/bearssl/src/ssl_engine_default_chapol.c +++ b/third_party/bearssl/src/ssl_engine_default_chapol.c @@ -54,11 +54,7 @@ br_ssl_engine_set_default_chapol(br_ssl_engine_context *cc) br_ssl_engine_set_poly1305(cc, bp); } else { #endif -#if BR_LOMUL - br_ssl_engine_set_poly1305(cc, &br_poly1305_ctmul32_run); -#else br_ssl_engine_set_poly1305(cc, &br_poly1305_ctmul_run); -#endif #if BR_INT128 || BR_UMUL128 } #endif diff --git a/third_party/bearssl/src/ssl_engine_default_descbc.c b/third_party/bearssl/src/ssl_engine_default_descbc.c deleted file mode 100644 index 0253cb2fc..000000000 --- a/third_party/bearssl/src/ssl_engine_default_descbc.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_ssl.h */ -void -br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc) -{ - br_ssl_engine_set_cbc(cc, - &br_sslrec_in_cbc_vtable, - &br_sslrec_out_cbc_vtable); - br_ssl_engine_set_des_cbc(cc, - &br_des_ct_cbcenc_vtable, - &br_des_ct_cbcdec_vtable); -} diff --git a/third_party/bearssl/src/ssl_engine_default_ec.c b/third_party/bearssl/src/ssl_engine_default_ec.c index 0213ae63e..bf1d71110 100644 --- a/third_party/bearssl/src/ssl_engine_default_ec.c +++ b/third_party/bearssl/src/ssl_engine_default_ec.c @@ -28,9 +28,5 @@ void br_ssl_engine_set_default_ec(br_ssl_engine_context *cc) { -#if BR_LOMUL - br_ssl_engine_set_ec(cc, &br_ec_all_m15); -#else br_ssl_engine_set_ec(cc, &br_ec_all_m31); -#endif } diff --git a/third_party/bearssl/src/ssl_engine_default_ecdsa.c b/third_party/bearssl/src/ssl_engine_default_ecdsa.c index 130400257..331594caa 100644 --- a/third_party/bearssl/src/ssl_engine_default_ecdsa.c +++ b/third_party/bearssl/src/ssl_engine_default_ecdsa.c @@ -28,11 +28,6 @@ void br_ssl_engine_set_default_ecdsa(br_ssl_engine_context *cc) { -#if BR_LOMUL - br_ssl_engine_set_ec(cc, &br_ec_all_m15); - br_ssl_engine_set_ecdsa(cc, &br_ecdsa_i15_vrfy_asn1); -#else br_ssl_engine_set_ec(cc, &br_ec_all_m31); br_ssl_engine_set_ecdsa(cc, &br_ecdsa_i31_vrfy_asn1); -#endif } diff --git a/third_party/bearssl/src/ssl_hs_client.c b/third_party/bearssl/src/ssl_hs_client.c index 579d8abb7..1a1cf4b31 100644 --- a/third_party/bearssl/src/ssl_hs_client.c +++ b/third_party/bearssl/src/ssl_hs_client.c @@ -1714,7 +1714,7 @@ br_ssl_hs_client_run(void *t0ctx) prf_id = T0_POP(); is_client = T0_POP(); br_ssl_engine_switch_cbc_in(ENG, is_client, prf_id, mac_id, - aes ? ENG->iaes_cbcdec : ENG->ides_cbcdec, cipher_key_len); + ENG->iaes_cbcdec, cipher_key_len); } break; @@ -1730,7 +1730,7 @@ br_ssl_hs_client_run(void *t0ctx) prf_id = T0_POP(); is_client = T0_POP(); br_ssl_engine_switch_cbc_out(ENG, is_client, prf_id, mac_id, - aes ? ENG->iaes_cbcenc : ENG->ides_cbcenc, cipher_key_len); + ENG->iaes_cbcenc, cipher_key_len); } break; diff --git a/third_party/bearssl/src/ssl_keyexport.c b/third_party/bearssl/src/ssl_keyexport.c deleted file mode 100644 index 58e6dc3cd..000000000 --- a/third_party/bearssl/src/ssl_keyexport.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * Supported cipher suites that use SHA-384 for the PRF when selected - * for TLS 1.2. All other cipher suites are deemed to use SHA-256. - */ -static const uint16_t suites_sha384[] = { - BR_TLS_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 -}; - -/* see bearssl_ssl.h */ -int -br_ssl_key_export(br_ssl_engine_context *cc, - void *dst, size_t len, const char *label, - const void *context, size_t context_len) -{ - br_tls_prf_seed_chunk chunks[4]; - br_tls_prf_impl iprf; - size_t num_chunks, u; - unsigned char tmp[2]; - int prf_id; - - if (cc->application_data != 1) { - return 0; - } - chunks[0].data = cc->client_random; - chunks[0].len = sizeof cc->client_random; - chunks[1].data = cc->server_random; - chunks[1].len = sizeof cc->server_random; - if (context != NULL) { - br_enc16be(tmp, (unsigned)context_len); - chunks[2].data = tmp; - chunks[2].len = 2; - chunks[3].data = context; - chunks[3].len = context_len; - num_chunks = 4; - } else { - num_chunks = 2; - } - prf_id = BR_SSLPRF_SHA256; - for (u = 0; u < (sizeof suites_sha384) / sizeof(uint16_t); u ++) { - if (suites_sha384[u] == cc->session.cipher_suite) { - prf_id = BR_SSLPRF_SHA384; - } - } - iprf = br_ssl_engine_get_PRF(cc, prf_id); - iprf(dst, len, - cc->session.master_secret, sizeof cc->session.master_secret, - label, num_chunks, chunks); - return 1; -} diff --git a/third_party/bearssl/src/ssl_lru.c b/third_party/bearssl/src/ssl_lru.c deleted file mode 100644 index 4c71011f0..000000000 --- a/third_party/bearssl/src/ssl_lru.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* - * Each entry consists in a fixed number of bytes. Entries are concatenated - * in the store block. "Addresses" are really offsets in the block, - * expressed over 32 bits (so the cache may have size at most 4 GB, which - * "ought to be enough for everyone"). The "null address" is 0xFFFFFFFF. - * Note that since the storage block alignment is in no way guaranteed, we - * perform only accesses that can handle unaligned data. - * - * Two concurrent data structures are maintained: - * - * -- Entries are organised in a doubly-linked list; saved entries are added - * at the head, and loaded entries are moved to the head. Eviction uses - * the list tail (this is the LRU algorithm). - * - * -- Entries are indexed with a binary tree: all left descendants of a - * node have a lower session ID (in lexicographic order), while all - * right descendants have a higher session ID. The tree is heuristically - * balanced. - * - * Entry format: - * - * session ID 32 bytes - * master secret 48 bytes - * protocol version 2 bytes (big endian) - * cipher suite 2 bytes (big endian) - * list prev 4 bytes (big endian) - * list next 4 bytes (big endian) - * tree left child 4 bytes (big endian) - * tree right child 4 bytes (big endian) - * - * If an entry has a protocol version set to 0, then it is "disabled": - * it was a session pushed to the cache at some point, but it has - * been explicitly removed. - * - * We need to keep the tree balanced because an attacker could make - * handshakes, selecting some specific sessions (by reusing them) to - * try to make us make an imbalanced tree that makes lookups expensive - * (a denial-of-service attack that would persist as long as the cache - * remains, i.e. even after the attacker made all his connections). - * To do that, we replace the session ID (or the start of the session ID) - * with a HMAC value computed over the replaced part; the hash function - * implementation and the key are obtained from the server context upon - * first save() call. - * - * Theoretically, an attacker could use the exact timing of the lookup - * to infer the current tree topology, and try to revive entries to make - * it as unbalanced as possible. However, since the session ID are - * chosen randomly by the server, and the attacker cannot see the - * indexing values and must thus rely on blind selection, it should be - * exponentially difficult for the attacker to maintain a large - * imbalance. - */ -#define SESSION_ID_LEN 32 -#define MASTER_SECRET_LEN 48 - -#define SESSION_ID_OFF 0 -#define MASTER_SECRET_OFF 32 -#define VERSION_OFF 80 -#define CIPHER_SUITE_OFF 82 -#define LIST_PREV_OFF 84 -#define LIST_NEXT_OFF 88 -#define TREE_LEFT_OFF 92 -#define TREE_RIGHT_OFF 96 - -#define LRU_ENTRY_LEN 100 - -#define ADDR_NULL ((uint32_t)-1) - -#define GETSET(name, off) \ -static inline uint32_t get_ ## name(br_ssl_session_cache_lru *cc, uint32_t x) \ -{ \ - return br_dec32be(cc->store + x + (off)); \ -} \ -static inline void set_ ## name(br_ssl_session_cache_lru *cc, \ - uint32_t x, uint32_t val) \ -{ \ - br_enc32be(cc->store + x + (off), val); \ -} - -GETSET(prev, LIST_PREV_OFF) -GETSET(next, LIST_NEXT_OFF) -GETSET(left, TREE_LEFT_OFF) -GETSET(right, TREE_RIGHT_OFF) - -/* - * Transform the session ID by replacing the first N bytes with a HMAC - * value computed over these bytes, using the random key K (the HMAC - * value is truncated if needed). HMAC will use the same hash function - * as the DRBG in the SSL server context, so with SHA-256, SHA-384, - * or SHA-1, depending on what is available. - * - * The risk of collision is considered too small to be a concern; and - * the impact of a collision is low (the handshake won't succeed). This - * risk is much lower than any transmission error, which would lead to - * the same consequences. - * - * Source and destination arrays msut be disjoint. - */ -static void -mask_id(br_ssl_session_cache_lru *cc, - const unsigned char *src, unsigned char *dst) -{ - br_hmac_key_context hkc; - br_hmac_context hc; - - memcpy(dst, src, SESSION_ID_LEN); - br_hmac_key_init(&hkc, cc->hash, cc->index_key, sizeof cc->index_key); - br_hmac_init(&hc, &hkc, SESSION_ID_LEN); - br_hmac_update(&hc, src, SESSION_ID_LEN); - br_hmac_out(&hc, dst); -} - -/* - * Find a node by ID. Returned value is the node address, or ADDR_NULL if - * the node is not found. - * - * If addr_link is not NULL, then '*addr_link' is set to the address of the - * last followed link. If the found node is the root, or if the tree is - * empty, then '*addr_link' is set to ADDR_NULL. - */ -static uint32_t -find_node(br_ssl_session_cache_lru *cc, const unsigned char *id, - uint32_t *addr_link) -{ - uint32_t x, y; - - x = cc->root; - y = ADDR_NULL; - while (x != ADDR_NULL) { - int r; - - r = memcmp(id, cc->store + x + SESSION_ID_OFF, SESSION_ID_LEN); - if (r < 0) { - y = x + TREE_LEFT_OFF; - x = get_left(cc, x); - } else if (r == 0) { - if (addr_link != NULL) { - *addr_link = y; - } - return x; - } else { - y = x + TREE_RIGHT_OFF; - x = get_right(cc, x); - } - } - if (addr_link != NULL) { - *addr_link = y; - } - return ADDR_NULL; -} - -/* - * For node x, find its replacement upon removal. - * - * -- If node x has no child, then this returns ADDR_NULL. - * -- Otherwise, if node x has a left child, then the replacement is the - * rightmost left-descendent. - * -- Otherwise, the replacement is the leftmost right-descendent. - * - * If a node is returned, then '*al' is set to the address of the field - * that points to that node. Otherwise (node x has no child), '*al' is - * set to ADDR_NULL. - * - * Note that the replacement node, when found, is always a descendent - * of node 'x', so it cannot be the tree root. Thus, '*al' can be set - * to ADDR_NULL only when no node is found and ADDR_NULL is returned. - */ -static uint32_t -find_replacement_node(br_ssl_session_cache_lru *cc, uint32_t x, uint32_t *al) -{ - uint32_t y1, y2; - - y1 = get_left(cc, x); - if (y1 != ADDR_NULL) { - y2 = x + TREE_LEFT_OFF; - for (;;) { - uint32_t z; - - z = get_right(cc, y1); - if (z == ADDR_NULL) { - *al = y2; - return y1; - } - y2 = y1 + TREE_RIGHT_OFF; - y1 = z; - } - } - y1 = get_right(cc, x); - if (y1 != ADDR_NULL) { - y2 = x + TREE_RIGHT_OFF; - for (;;) { - uint32_t z; - - z = get_left(cc, y1); - if (z == ADDR_NULL) { - *al = y2; - return y1; - } - y2 = y1 + TREE_LEFT_OFF; - y1 = z; - } - } - *al = ADDR_NULL; - return ADDR_NULL; -} - -/* - * Set the link at address 'alx' to point to node 'x'. If 'alx' is - * ADDR_NULL, then this sets the tree root to 'x'. - */ -static inline void -set_link(br_ssl_session_cache_lru *cc, uint32_t alx, uint32_t x) -{ - if (alx == ADDR_NULL) { - cc->root = x; - } else { - br_enc32be(cc->store + alx, x); - } -} - -/* - * Remove node 'x' from the tree. This function shall not be called if - * node 'x' is not part of the tree. - */ -static void -remove_node(br_ssl_session_cache_lru *cc, uint32_t x) -{ - uint32_t alx, y, aly; - - /* - * Removal algorithm: - * ------------------ - * - * - If we remove the root, then the tree becomes empty. - * - * - If the removed node has no child, then we can simply remove - * it, with nothing else to do. - * - * - Otherwise, the removed node must be replaced by either its - * rightmost left-descendent, or its leftmost right-descendent. - * The replacement node itself must be removed from its current - * place. By definition, that replacement node has either no - * child, or at most a single child that will replace it in the - * tree. - */ - - /* - * Find node back and its ancestor link. If the node was the - * root, then alx is set to ADDR_NULL. - */ - find_node(cc, cc->store + x + SESSION_ID_OFF, &alx); - - /* - * Find replacement node 'y', and 'aly' is set to the address of - * the link to that replacement node. If the removed node has no - * child, then both 'y' and 'aly' are set to ADDR_NULL. - */ - y = find_replacement_node(cc, x, &aly); - - if (y != ADDR_NULL) { - uint32_t z; - - /* - * The unlinked replacement node may have one child (but - * not two) that takes its place. - */ - z = get_left(cc, y); - if (z == ADDR_NULL) { - z = get_right(cc, y); - } - set_link(cc, aly, z); - - /* - * Link the replacement node in its new place, overwriting - * the current link to the node 'x' (which removes 'x'). - */ - set_link(cc, alx, y); - - /* - * The replacement node adopts the left and right children - * of the removed node. Note that this also works even if - * the replacement node was a direct descendent of the - * removed node, since we unlinked it previously. - */ - set_left(cc, y, get_left(cc, x)); - set_right(cc, y, get_right(cc, x)); - } else { - /* - * No replacement, we simply unlink the node 'x'. - */ - set_link(cc, alx, ADDR_NULL); - } -} - -static void -lru_save(const br_ssl_session_cache_class **ctx, - br_ssl_server_context *server_ctx, - const br_ssl_session_parameters *params) -{ - br_ssl_session_cache_lru *cc; - unsigned char id[SESSION_ID_LEN]; - uint32_t x, alx; - - cc = (br_ssl_session_cache_lru *)ctx; - - /* - * If the buffer is too small, we don't record anything. This - * test avoids problems in subsequent code. - */ - if (cc->store_len < LRU_ENTRY_LEN) { - return; - } - - /* - * Upon the first save in a session cache instance, we obtain - * a random key for our indexing. - */ - if (!cc->init_done) { - br_hmac_drbg_generate(&server_ctx->eng.rng, - cc->index_key, sizeof cc->index_key); - cc->hash = br_hmac_drbg_get_hash(&server_ctx->eng.rng); - cc->init_done = 1; - } - mask_id(cc, params->session_id, id); - - /* - * Look for the node in the tree. If the same ID is already used, - * then reject it. This is a collision event, which should be - * exceedingly rare. - * Note: we do NOT record the emplacement here, because the - * removal of an entry may change the tree topology. - */ - if (find_node(cc, id, NULL) != ADDR_NULL) { - return; - } - - /* - * Find some room for the new parameters. If the cache is not - * full yet, add it to the end of the area and bump the pointer up. - * Otherwise, evict the list tail entry. Note that we already - * filtered out the case of a ridiculously small buffer that - * cannot hold any entry at all; thus, if there is no room for an - * extra entry, then the cache cannot be empty. - */ - if (cc->store_ptr > (cc->store_len - LRU_ENTRY_LEN)) { - /* - * Evict tail. If the buffer has room for a single entry, - * then this may also be the head. - */ - x = cc->tail; - cc->tail = get_prev(cc, x); - if (cc->tail == ADDR_NULL) { - cc->head = ADDR_NULL; - } else { - set_next(cc, cc->tail, ADDR_NULL); - } - - /* - * Remove the node from the tree. - */ - remove_node(cc, x); - } else { - /* - * Allocate room for new node. - */ - x = cc->store_ptr; - cc->store_ptr += LRU_ENTRY_LEN; - } - - /* - * Find the emplacement for the new node, and link it. - */ - find_node(cc, id, &alx); - set_link(cc, alx, x); - set_left(cc, x, ADDR_NULL); - set_right(cc, x, ADDR_NULL); - - /* - * New entry becomes new list head. It may also become the list - * tail if the cache was empty at that point. - */ - if (cc->head == ADDR_NULL) { - cc->tail = x; - } else { - set_prev(cc, cc->head, x); - } - set_prev(cc, x, ADDR_NULL); - set_next(cc, x, cc->head); - cc->head = x; - - /* - * Fill data in the entry. - */ - memcpy(cc->store + x + SESSION_ID_OFF, id, SESSION_ID_LEN); - memcpy(cc->store + x + MASTER_SECRET_OFF, - params->master_secret, MASTER_SECRET_LEN); - br_enc16be(cc->store + x + VERSION_OFF, params->version); - br_enc16be(cc->store + x + CIPHER_SUITE_OFF, params->cipher_suite); -} - -static int -lru_load(const br_ssl_session_cache_class **ctx, - br_ssl_server_context *server_ctx, - br_ssl_session_parameters *params) -{ - br_ssl_session_cache_lru *cc; - unsigned char id[SESSION_ID_LEN]; - uint32_t x; - - (void)server_ctx; - cc = (br_ssl_session_cache_lru *)ctx; - if (!cc->init_done) { - return 0; - } - mask_id(cc, params->session_id, id); - x = find_node(cc, id, NULL); - if (x != ADDR_NULL) { - unsigned version; - - version = br_dec16be(cc->store + x + VERSION_OFF); - if (version == 0) { - /* - * Entry is disabled, we pretend we did not find it. - * Notably, we don't move it to the front of the - * LRU list. - */ - return 0; - } - params->version = version; - params->cipher_suite = br_dec16be( - cc->store + x + CIPHER_SUITE_OFF); - memcpy(params->master_secret, - cc->store + x + MASTER_SECRET_OFF, - MASTER_SECRET_LEN); - if (x != cc->head) { - /* - * Found node is not at list head, so move - * it to the head. - */ - uint32_t p, n; - - p = get_prev(cc, x); - n = get_next(cc, x); - set_next(cc, p, n); - if (n == ADDR_NULL) { - cc->tail = p; - } else { - set_prev(cc, n, p); - } - set_prev(cc, cc->head, x); - set_next(cc, x, cc->head); - set_prev(cc, x, ADDR_NULL); - cc->head = x; - } - return 1; - } - return 0; -} - -static const br_ssl_session_cache_class lru_class = { - sizeof(br_ssl_session_cache_lru), - &lru_save, - &lru_load -}; - -/* see inner.h */ -void -br_ssl_session_cache_lru_init(br_ssl_session_cache_lru *cc, - unsigned char *store, size_t store_len) -{ - cc->vtable = &lru_class; - cc->store = store; - cc->store_len = store_len; - cc->store_ptr = 0; - cc->init_done = 0; - cc->head = ADDR_NULL; - cc->tail = ADDR_NULL; - cc->root = ADDR_NULL; -} - -/* see bearssl_ssl.h */ -void br_ssl_session_cache_lru_forget( - br_ssl_session_cache_lru *cc, const unsigned char *id) -{ - unsigned char mid[SESSION_ID_LEN]; - uint32_t addr; - - /* - * If the cache is not initialised yet, then it is empty, and - * there is nothing to forget. - */ - if (!cc->init_done) { - return; - } - - /* - * Look for the node in the tree. If found, the entry is marked - * as "disabled"; it will be reused in due course, as it ages - * through the list. - * - * We do not go through the complex moves of actually releasing - * the entry right away because explicitly forgetting sessions - * should be a rare event, meant mostly for testing purposes, - * so this is not worth the extra code size. - */ - mask_id(cc, id, mid); - addr = find_node(cc, mid, NULL); - if (addr != ADDR_NULL) { - br_enc16be(cc->store + addr + VERSION_OFF, 0); - } -} diff --git a/third_party/bearssl/src/ssl_scert_single_ec.c b/third_party/bearssl/src/ssl_scert_single_ec.c deleted file mode 100644 index ce8d7539a..000000000 --- a/third_party/bearssl/src/ssl_scert_single_ec.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -static int -se_choose(const br_ssl_server_policy_class **pctx, - const br_ssl_server_context *cc, - br_ssl_server_choices *choices) -{ - br_ssl_server_policy_ec_context *pc; - const br_suite_translated *st; - size_t u, st_num; - unsigned hash_id; - - pc = (br_ssl_server_policy_ec_context *)pctx; - st = br_ssl_server_get_client_suites(cc, &st_num); - hash_id = br_ssl_choose_hash(br_ssl_server_get_client_hashes(cc) >> 8); - if (cc->eng.session.version < BR_TLS12) { - hash_id = br_sha1_ID; - } - choices->chain = pc->chain; - choices->chain_len = pc->chain_len; - for (u = 0; u < st_num; u ++) { - unsigned tt; - - tt = st[u][1]; - switch (tt >> 12) { - case BR_SSLKEYX_ECDH_RSA: - if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0 - && pc->cert_issuer_key_type == BR_KEYTYPE_RSA) - { - choices->cipher_suite = st[u][0]; - return 1; - } - break; - case BR_SSLKEYX_ECDH_ECDSA: - if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0 - && pc->cert_issuer_key_type == BR_KEYTYPE_EC) - { - choices->cipher_suite = st[u][0]; - return 1; - } - break; - case BR_SSLKEYX_ECDHE_ECDSA: - if ((pc->allowed_usages & BR_KEYTYPE_SIGN) != 0 - && hash_id != 0) - { - choices->cipher_suite = st[u][0]; - choices->algo_id = hash_id + 0xFF00; - return 1; - } - break; - } - } - return 0; -} - -static uint32_t -se_do_keyx(const br_ssl_server_policy_class **pctx, - unsigned char *data, size_t *len) -{ - br_ssl_server_policy_ec_context *pc; - uint32_t r; - size_t xoff, xlen; - - pc = (br_ssl_server_policy_ec_context *)pctx; - r = pc->iec->mul(data, *len, pc->sk->x, pc->sk->xlen, pc->sk->curve); - xoff = pc->iec->xoff(pc->sk->curve, &xlen); - memmove(data, data + xoff, xlen); - *len = xlen; - return r; -} - -static size_t -se_do_sign(const br_ssl_server_policy_class **pctx, - unsigned algo_id, unsigned char *data, size_t hv_len, size_t len) -{ - br_ssl_server_policy_ec_context *pc; - unsigned char hv[64]; - const br_hash_class *hc; - - algo_id &= 0xFF; - pc = (br_ssl_server_policy_ec_context *)pctx; - hc = br_multihash_getimpl(pc->mhash, algo_id); - if (hc == NULL) { - return 0; - } - memcpy(hv, data, hv_len); - if (len < 139) { - return 0; - } - return pc->iecdsa(pc->iec, hc, hv, pc->sk, data); -} - -static const br_ssl_server_policy_class se_policy_vtable = { - sizeof(br_ssl_server_policy_ec_context), - se_choose, - se_do_keyx, - se_do_sign -}; - -/* see bearssl_ssl.h */ -void -br_ssl_server_set_single_ec(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_ec_private_key *sk, unsigned allowed_usages, - unsigned cert_issuer_key_type, - const br_ec_impl *iec, br_ecdsa_sign iecdsa) -{ - cc->chain_handler.single_ec.vtable = &se_policy_vtable; - cc->chain_handler.single_ec.chain = chain; - cc->chain_handler.single_ec.chain_len = chain_len; - cc->chain_handler.single_ec.sk = sk; - cc->chain_handler.single_ec.allowed_usages = allowed_usages; - cc->chain_handler.single_ec.cert_issuer_key_type = cert_issuer_key_type; - cc->chain_handler.single_ec.mhash = &cc->eng.mhash; - cc->chain_handler.single_ec.iec = iec; - cc->chain_handler.single_ec.iecdsa = iecdsa; - cc->policy_vtable = &cc->chain_handler.single_ec.vtable; -} diff --git a/third_party/bearssl/src/ssl_scert_single_rsa.c b/third_party/bearssl/src/ssl_scert_single_rsa.c deleted file mode 100644 index b2c77679f..000000000 --- a/third_party/bearssl/src/ssl_scert_single_rsa.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -static int -sr_choose(const br_ssl_server_policy_class **pctx, - const br_ssl_server_context *cc, - br_ssl_server_choices *choices) -{ - br_ssl_server_policy_rsa_context *pc; - const br_suite_translated *st; - size_t u, st_num; - unsigned hash_id; - int fh; - - pc = (br_ssl_server_policy_rsa_context *)pctx; - st = br_ssl_server_get_client_suites(cc, &st_num); - if (cc->eng.session.version < BR_TLS12) { - hash_id = 0; - fh = 1; - } else { - hash_id = br_ssl_choose_hash( - br_ssl_server_get_client_hashes(cc)); - fh = (hash_id != 0); - } - choices->chain = pc->chain; - choices->chain_len = pc->chain_len; - for (u = 0; u < st_num; u ++) { - unsigned tt; - - tt = st[u][1]; - switch (tt >> 12) { - case BR_SSLKEYX_RSA: - if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0) { - choices->cipher_suite = st[u][0]; - return 1; - } - break; - case BR_SSLKEYX_ECDHE_RSA: - if ((pc->allowed_usages & BR_KEYTYPE_SIGN) != 0 && fh) { - choices->cipher_suite = st[u][0]; - choices->algo_id = hash_id + 0xFF00; - return 1; - } - break; - } - } - return 0; -} - -static uint32_t -sr_do_keyx(const br_ssl_server_policy_class **pctx, - unsigned char *data, size_t *len) -{ - br_ssl_server_policy_rsa_context *pc; - - pc = (br_ssl_server_policy_rsa_context *)pctx; - return br_rsa_ssl_decrypt(pc->irsacore, pc->sk, data, *len); -} - -/* - * OID for hash functions in RSA signatures. - */ -static const unsigned char HASH_OID_SHA1[] = { - 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A -}; - -static const unsigned char HASH_OID_SHA224[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 -}; - -static const unsigned char HASH_OID_SHA256[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 -}; - -static const unsigned char HASH_OID_SHA384[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 -}; - -static const unsigned char HASH_OID_SHA512[] = { - 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 -}; - -static const unsigned char *HASH_OID[] = { - HASH_OID_SHA1, - HASH_OID_SHA224, - HASH_OID_SHA256, - HASH_OID_SHA384, - HASH_OID_SHA512 -}; - -static size_t -sr_do_sign(const br_ssl_server_policy_class **pctx, - unsigned algo_id, unsigned char *data, size_t hv_len, size_t len) -{ - br_ssl_server_policy_rsa_context *pc; - unsigned char hv[64]; - size_t sig_len; - const unsigned char *hash_oid; - - pc = (br_ssl_server_policy_rsa_context *)pctx; - memcpy(hv, data, hv_len); - algo_id &= 0xFF; - if (algo_id == 0) { - hash_oid = NULL; - } else if (algo_id >= 2 && algo_id <= 6) { - hash_oid = HASH_OID[algo_id - 2]; - } else { - return 0; - } - sig_len = (pc->sk->n_bitlen + 7) >> 3; - if (len < sig_len) { - return 0; - } - return pc->irsasign(hash_oid, hv, hv_len, pc->sk, data) ? sig_len : 0; -} - -static const br_ssl_server_policy_class sr_policy_vtable = { - sizeof(br_ssl_server_policy_rsa_context), - sr_choose, - sr_do_keyx, - sr_do_sign -}; - -/* see bearssl_ssl.h */ -void -br_ssl_server_set_single_rsa(br_ssl_server_context *cc, - const br_x509_certificate *chain, size_t chain_len, - const br_rsa_private_key *sk, unsigned allowed_usages, - br_rsa_private irsacore, br_rsa_pkcs1_sign irsasign) -{ - cc->chain_handler.single_rsa.vtable = &sr_policy_vtable; - cc->chain_handler.single_rsa.chain = chain; - cc->chain_handler.single_rsa.chain_len = chain_len; - cc->chain_handler.single_rsa.sk = sk; - cc->chain_handler.single_rsa.allowed_usages = allowed_usages; - cc->chain_handler.single_rsa.irsacore = irsacore; - cc->chain_handler.single_rsa.irsasign = irsasign; - cc->policy_vtable = &cc->chain_handler.single_rsa.vtable; -} diff --git a/third_party/bearssl/src/sysrng.c b/third_party/bearssl/src/sysrng.c deleted file mode 100644 index 5a921145d..000000000 --- a/third_party/bearssl/src/sysrng.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (c) 2017 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#define BR_ENABLE_INTRINSICS 1 -#include "inner.h" - -#if BR_USE_GETENTROPY -#include -#endif - -#if BR_USE_URANDOM -#include -#include -#include -#include -#endif - -#if BR_USE_WIN32_RAND -#include -#include -#pragma comment(lib, "advapi32") -#endif - -/* - * Seeder that uses the RDRAND opcodes (on x86 CPU). - */ -#if BR_RDRAND -BR_TARGETS_X86_UP -BR_TARGET("rdrnd") -static int -seeder_rdrand(const br_prng_class **ctx) -{ - unsigned char tmp[32]; - size_t u; - - for (u = 0; u < sizeof tmp; u += sizeof(uint32_t)) { - int j; - uint32_t x; - - /* - * We use the 32-bit intrinsic so that code is compatible - * with both 32-bit and 64-bit architectures. - * - * Intel recommends trying at least 10 times in case of - * failure. - * - * AMD bug: there are reports that some AMD processors - * have a bug that makes them fail silently after a - * suspend/resume cycle, in which case RDRAND will report - * a success but always return 0xFFFFFFFF. - * see: https://bugzilla.kernel.org/show_bug.cgi?id=85911 - * - * As a mitigation, if the 32-bit value is 0 or -1, then - * it is considered a failure and tried again. This should - * reliably detect the buggy case, at least. This also - * implies that the selected seed values can never be - * 0x00000000 or 0xFFFFFFFF, which is not a problem since - * we are generating a seed for a PRNG, and we overdo it - * a bit (we generate 32 bytes of randomness, and 256 bits - * of entropy are really overkill). - */ - for (j = 0; j < 10; j ++) { - if (_rdrand32_step(&x) && x != 0 && x != (uint32_t)-1) { - goto next_word; - } - } - return 0; - next_word: - br_enc32le(tmp + u, x); - } - (*ctx)->update(ctx, tmp, sizeof tmp); - return 1; -} -BR_TARGETS_X86_DOWN - -static int -rdrand_supported(void) -{ - /* - * The RDRND support is bit 30 of ECX, as returned by CPUID. - */ - return br_cpuid(0, 0, 0x40000000, 0); -} -#endif - -/* - * Seeder that uses /dev/urandom (on Unix-like systems). - */ -#if BR_USE_URANDOM -static int -seeder_urandom(const br_prng_class **ctx) -{ - int f; - - f = open("/dev/urandom", O_RDONLY); - if (f >= 0) { - unsigned char tmp[32]; - size_t u; - - for (u = 0; u < sizeof tmp;) { - ssize_t len; - - len = read(f, tmp + u, (sizeof tmp) - u); - if (len < 0) { - if (errno == EINTR) { - continue; - } - break; - } - u += (size_t)len; - } - close(f); - if (u == sizeof tmp) { - (*ctx)->update(ctx, tmp, sizeof tmp); - return 1; - } - } - return 0; -} -#endif - -/* - * Seeder that uses getentropy() (backed by getrandom() on some systems, - * e.g. Linux). On failure, it will use the /dev/urandom seeder (if - * enabled). - */ -#if BR_USE_GETENTROPY -static int -seeder_getentropy(const br_prng_class **ctx) -{ - unsigned char tmp[32]; - - if (getentropy(tmp, sizeof tmp) == 0) { - (*ctx)->update(ctx, tmp, sizeof tmp); - return 1; - } -#if BR_USE_URANDOM - return seeder_urandom(ctx); -#else - return 0; -#endif -} -#endif - -/* - * Seeder that uses CryptGenRandom() (on Windows). - */ -#if BR_USE_WIN32_RAND -static int -seeder_win32(const br_prng_class **ctx) -{ - HCRYPTPROV hp; - - if (CryptAcquireContext(&hp, 0, 0, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - { - BYTE buf[32]; - BOOL r; - - r = CryptGenRandom(hp, sizeof buf, buf); - CryptReleaseContext(hp, 0); - if (r) { - (*ctx)->update(ctx, buf, sizeof buf); - return 1; - } - } - return 0; -} -#endif - -/* - * An aggregate seeder that uses RDRAND, and falls back to an OS-provided - * source if RDRAND fails. - */ -#if BR_RDRAND && (BR_USE_GETENTROPY || BR_USE_URANDOM || BR_USE_WIN32_RAND) -static int -seeder_rdrand_with_fallback(const br_prng_class **ctx) -{ - if (!seeder_rdrand(ctx)) { -#if BR_USE_GETENTROPY - return seeder_getentropy(ctx); -#elif BR_USE_URANDOM - return seeder_urandom(ctx); -#elif BR_USE_WIN32_RAND - return seeder_win32(ctx); -#else -#error "macro selection has gone wrong" -#endif - } - return 1; -} -#endif - -/* see bearssl_rand.h */ -br_prng_seeder -br_prng_seeder_system(const char **name) -{ -#if BR_RDRAND - if (rdrand_supported()) { - if (name != NULL) { - *name = "rdrand"; - } -#if BR_USE_GETENTROPY || BR_USE_URANDOM || BR_USE_WIN32_RAND - return &seeder_rdrand_with_fallback; -#else - return &seeder_rdrand; -#endif - } -#endif -#if BR_USE_GETENTROPY - if (name != NULL) { - *name = "getentropy"; - } - return &seeder_getentropy; -#elif BR_USE_URANDOM - if (name != NULL) { - *name = "urandom"; - } - return &seeder_urandom; -#elif BR_USE_WIN32_RAND - if (name != NULL) { - *name = "win32"; - } - return &seeder_win32; -#else - if (name != NULL) { - *name = "none"; - } - return 0; -#endif -} diff --git a/third_party/bearssl/src/x509_decoder.c b/third_party/bearssl/src/x509_decoder.c deleted file mode 100644 index 8dd970f13..000000000 --- a/third_party/bearssl/src/x509_decoder.c +++ /dev/null @@ -1,773 +0,0 @@ -/* Automatically generated code; do not modify directly. */ - -#include -#include - -typedef struct { - uint32_t *dp; - uint32_t *rp; - const unsigned char *ip; -} t0_context; - -static uint32_t -t0_parse7E_unsigned(const unsigned char **p) -{ - uint32_t x; - - x = 0; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - return x; - } - } -} - -static int32_t -t0_parse7E_signed(const unsigned char **p) -{ - int neg; - uint32_t x; - - neg = ((**p) >> 6) & 1; - x = (uint32_t)-neg; - for (;;) { - unsigned y; - - y = *(*p) ++; - x = (x << 7) | (uint32_t)(y & 0x7F); - if (y < 0x80) { - if (neg) { - return -(int32_t)~x - 1; - } else { - return (int32_t)x; - } - } - } -} - -#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) -#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) -#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) -#define T0_INT1(x) T0_FBYTE(x, 0) -#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) -#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) - -/* static const unsigned char t0_datablock[]; */ - - -void br_x509_decoder_init_main(void *t0ctx); - -void br_x509_decoder_run(void *t0ctx); - - - -#include "inner.h" - - - - - -#include "inner.h" - -#define CTX ((br_x509_decoder_context *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_decoder_context, cpu))) -#define CONTEXT_NAME br_x509_decoder_context - -/* see bearssl_x509.h */ -void -br_x509_decoder_init(br_x509_decoder_context *ctx, - void (*append_dn)(void *ctx, const void *buf, size_t len), - void *append_dn_ctx) -{ - memset(ctx, 0, sizeof *ctx); - /* obsolete - ctx->err = 0; - ctx->hbuf = NULL; - ctx->hlen = 0; - */ - ctx->append_dn = append_dn; - ctx->append_dn_ctx = append_dn_ctx; - ctx->cpu.dp = &ctx->dp_stack[0]; - ctx->cpu.rp = &ctx->rp_stack[0]; - br_x509_decoder_init_main(&ctx->cpu); - br_x509_decoder_run(&ctx->cpu); -} - -/* see bearssl_x509.h */ -void -br_x509_decoder_push(br_x509_decoder_context *ctx, - const void *data, size_t len) -{ - ctx->hbuf = data; - ctx->hlen = len; - br_x509_decoder_run(&ctx->cpu); -} - - - -static const unsigned char t0_datablock[] = { - 0x00, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x09, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E, 0x09, 0x2A, 0x86, 0x48, 0x86, - 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x01, 0x0C, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, - 0x0D, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x08, 0x2A, 0x86, - 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, - 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, - 0x04, 0x01, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01, 0x08, - 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x08, 0x2A, 0x86, 0x48, - 0xCE, 0x3D, 0x04, 0x03, 0x03, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, - 0x03, 0x04, 0x00, 0x1F, 0x03, 0xFC, 0x07, 0x7F, 0x0B, 0x5E, 0x0F, 0x1F, - 0x12, 0xFE, 0x16, 0xBF, 0x1A, 0x9F, 0x1E, 0x7E, 0x22, 0x3F, 0x26, 0x1E, - 0x29, 0xDF, 0x00, 0x1F, 0x03, 0xFD, 0x07, 0x9F, 0x0B, 0x7E, 0x0F, 0x3F, - 0x13, 0x1E, 0x16, 0xDF, 0x1A, 0xBF, 0x1E, 0x9E, 0x22, 0x5F, 0x26, 0x3E, - 0x29, 0xFF, 0x03, 0x55, 0x1D, 0x13 -}; - -static const unsigned char t0_codeblock[] = { - 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x01, - 0x01, 0x09, 0x00, 0x00, 0x01, 0x01, 0x0A, 0x00, 0x00, 0x1A, 0x1A, 0x00, - 0x00, 0x01, T0_INT1(BR_ERR_X509_BAD_BOOLEAN), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_BAD_TAG_CLASS), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_BAD_TAG_VALUE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_BAD_TIME), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_EXTRA_ELEMENT), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_INDEFINITE_LENGTH), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_INNER_TRUNC), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_NOT_CONSTRUCTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_NOT_PRIMITIVE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_OVERFLOW), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_PARTIAL_BYTE), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_UNEXPECTED), 0x00, 0x00, 0x01, - T0_INT1(BR_ERR_X509_UNSUPPORTED), 0x00, 0x00, 0x01, - T0_INT1(BR_KEYTYPE_EC), 0x00, 0x00, 0x01, T0_INT1(BR_KEYTYPE_RSA), - 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, copy_dn)), 0x00, 0x00, - 0x01, T0_INT2(offsetof(CONTEXT_NAME, decoded)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, isCA)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(br_x509_decoder_context, pkey_data)), 0x01, - T0_INT2(BR_X509_BUFSIZE_KEY), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, notafter_days)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, notafter_seconds)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, notbefore_days)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, notbefore_seconds)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, pad)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, signer_hash_id)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, signer_key_type)), 0x00, 0x00, 0x01, - 0x80, 0x45, 0x00, 0x00, 0x01, 0x80, 0x4E, 0x00, 0x00, 0x01, 0x80, 0x54, - 0x00, 0x00, 0x01, 0x81, 0x36, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0x1B, - 0x02, 0x01, 0x13, 0x26, 0x02, 0x00, 0x0F, 0x15, 0x00, 0x00, 0x05, 0x02, - 0x34, 0x1D, 0x00, 0x00, 0x06, 0x02, 0x35, 0x1D, 0x00, 0x00, 0x01, 0x10, - 0x4F, 0x00, 0x00, 0x11, 0x05, 0x02, 0x38, 0x1D, 0x4C, 0x00, 0x00, 0x11, - 0x05, 0x02, 0x38, 0x1D, 0x4D, 0x00, 0x00, 0x06, 0x02, 0x30, 0x1D, 0x00, - 0x00, 0x1B, 0x19, 0x01, 0x08, 0x0E, 0x26, 0x29, 0x19, 0x09, 0x00, 0x00, - 0x01, 0x30, 0x0A, 0x1B, 0x01, 0x00, 0x01, 0x09, 0x4B, 0x05, 0x02, 0x2F, - 0x1D, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x01, 0x80, 0x5A, 0x00, 0x00, - 0x01, 0x80, 0x62, 0x00, 0x00, 0x01, 0x80, 0x6B, 0x00, 0x00, 0x01, 0x80, - 0x74, 0x00, 0x00, 0x01, 0x80, 0x7D, 0x00, 0x00, 0x01, 0x3D, 0x00, 0x00, - 0x20, 0x11, 0x06, 0x04, 0x2B, 0x6B, 0x7A, 0x71, 0x00, 0x04, 0x01, 0x00, - 0x3D, 0x25, 0x01, 0x00, 0x3C, 0x25, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x6D, - 0x6D, 0x70, 0x1B, 0x01, 0x20, 0x11, 0x06, 0x11, 0x1A, 0x4C, 0x6B, 0x70, - 0x01, 0x02, 0x50, 0x6E, 0x01, 0x02, 0x12, 0x06, 0x02, 0x39, 0x1D, 0x51, - 0x70, 0x01, 0x02, 0x50, 0x6C, 0x6D, 0x7A, 0x6D, 0x7A, 0x6D, 0x65, 0x43, - 0x24, 0x42, 0x24, 0x65, 0x41, 0x24, 0x40, 0x24, 0x51, 0x01, 0x01, 0x3C, - 0x25, 0x6D, 0x7A, 0x01, 0x00, 0x3C, 0x25, 0x6D, 0x6D, 0x60, 0x05, 0x02, - 0x39, 0x1D, 0x74, 0x1C, 0x06, 0x1C, 0x7A, 0x61, 0x6D, 0x3F, 0x68, 0x03, - 0x00, 0x3F, 0x26, 0x02, 0x00, 0x09, 0x26, 0x02, 0x00, 0x0A, 0x68, 0x03, - 0x01, 0x51, 0x51, 0x02, 0x00, 0x02, 0x01, 0x18, 0x04, 0x1E, 0x5A, 0x1C, - 0x06, 0x18, 0x64, 0x03, 0x02, 0x51, 0x61, 0x1B, 0x03, 0x03, 0x1B, 0x3F, - 0x23, 0x0D, 0x06, 0x02, 0x33, 0x1D, 0x62, 0x02, 0x02, 0x02, 0x03, 0x17, - 0x04, 0x02, 0x39, 0x1D, 0x51, 0x01, 0x00, 0x3E, 0x25, 0x71, 0x01, 0x21, - 0x5B, 0x01, 0x22, 0x5B, 0x1B, 0x01, 0x23, 0x11, 0x06, 0x28, 0x1A, 0x4C, - 0x6B, 0x6D, 0x1B, 0x06, 0x1D, 0x6D, 0x60, 0x1A, 0x70, 0x1B, 0x01, 0x01, - 0x11, 0x06, 0x03, 0x63, 0x1A, 0x70, 0x01, 0x04, 0x50, 0x6B, 0x4A, 0x1C, - 0x06, 0x03, 0x5F, 0x04, 0x01, 0x7B, 0x51, 0x51, 0x04, 0x60, 0x51, 0x51, - 0x04, 0x08, 0x01, 0x7F, 0x11, 0x05, 0x02, 0x38, 0x1D, 0x1A, 0x51, 0x6D, - 0x60, 0x06, 0x80, 0x63, 0x75, 0x1C, 0x06, 0x06, 0x01, 0x02, 0x3B, 0x04, - 0x80, 0x57, 0x76, 0x1C, 0x06, 0x06, 0x01, 0x03, 0x3B, 0x04, 0x80, 0x4D, - 0x77, 0x1C, 0x06, 0x06, 0x01, 0x04, 0x3B, 0x04, 0x80, 0x43, 0x78, 0x1C, - 0x06, 0x05, 0x01, 0x05, 0x3B, 0x04, 0x3A, 0x79, 0x1C, 0x06, 0x05, 0x01, - 0x06, 0x3B, 0x04, 0x31, 0x55, 0x1C, 0x06, 0x05, 0x01, 0x02, 0x3A, 0x04, - 0x28, 0x56, 0x1C, 0x06, 0x05, 0x01, 0x03, 0x3A, 0x04, 0x1F, 0x57, 0x1C, - 0x06, 0x05, 0x01, 0x04, 0x3A, 0x04, 0x16, 0x58, 0x1C, 0x06, 0x05, 0x01, - 0x05, 0x3A, 0x04, 0x0D, 0x59, 0x1C, 0x06, 0x05, 0x01, 0x06, 0x3A, 0x04, - 0x04, 0x01, 0x00, 0x01, 0x00, 0x04, 0x04, 0x01, 0x00, 0x01, 0x00, 0x46, - 0x25, 0x45, 0x25, 0x7A, 0x61, 0x7A, 0x51, 0x1A, 0x01, 0x01, 0x3D, 0x25, - 0x73, 0x30, 0x1D, 0x00, 0x00, 0x01, 0x81, 0x06, 0x00, 0x01, 0x54, 0x0D, - 0x06, 0x02, 0x32, 0x1D, 0x1B, 0x03, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x00, - 0x6D, 0x71, 0x1B, 0x01, 0x01, 0x11, 0x06, 0x08, 0x63, 0x01, 0x01, 0x15, - 0x3E, 0x25, 0x04, 0x01, 0x2B, 0x7A, 0x00, 0x00, 0x70, 0x01, 0x06, 0x50, - 0x6F, 0x00, 0x00, 0x70, 0x01, 0x03, 0x50, 0x6B, 0x72, 0x06, 0x02, 0x37, - 0x1D, 0x00, 0x00, 0x26, 0x1B, 0x06, 0x07, 0x21, 0x1B, 0x06, 0x01, 0x16, - 0x04, 0x76, 0x2B, 0x00, 0x00, 0x01, 0x01, 0x50, 0x6A, 0x01, 0x01, 0x10, - 0x06, 0x02, 0x2C, 0x1D, 0x72, 0x27, 0x00, 0x00, 0x60, 0x05, 0x02, 0x39, - 0x1D, 0x47, 0x1C, 0x06, 0x04, 0x01, 0x17, 0x04, 0x12, 0x48, 0x1C, 0x06, - 0x04, 0x01, 0x18, 0x04, 0x0A, 0x49, 0x1C, 0x06, 0x04, 0x01, 0x19, 0x04, - 0x02, 0x39, 0x1D, 0x00, 0x04, 0x70, 0x1B, 0x01, 0x17, 0x01, 0x18, 0x4B, - 0x05, 0x02, 0x2F, 0x1D, 0x01, 0x18, 0x11, 0x03, 0x00, 0x4D, 0x6B, 0x66, - 0x02, 0x00, 0x06, 0x0C, 0x01, 0x80, 0x64, 0x08, 0x03, 0x01, 0x66, 0x02, - 0x01, 0x09, 0x04, 0x0E, 0x1B, 0x01, 0x32, 0x0D, 0x06, 0x04, 0x01, 0x80, - 0x64, 0x09, 0x01, 0x8E, 0x6C, 0x09, 0x03, 0x01, 0x02, 0x01, 0x01, 0x82, - 0x6D, 0x08, 0x02, 0x01, 0x01, 0x03, 0x09, 0x01, 0x04, 0x0C, 0x09, 0x02, - 0x01, 0x01, 0x80, 0x63, 0x09, 0x01, 0x80, 0x64, 0x0C, 0x0A, 0x02, 0x01, - 0x01, 0x83, 0x0F, 0x09, 0x01, 0x83, 0x10, 0x0C, 0x09, 0x03, 0x03, 0x01, - 0x01, 0x01, 0x0C, 0x67, 0x2A, 0x01, 0x01, 0x0E, 0x02, 0x01, 0x01, 0x04, - 0x07, 0x28, 0x02, 0x01, 0x01, 0x80, 0x64, 0x07, 0x27, 0x02, 0x01, 0x01, - 0x83, 0x10, 0x07, 0x28, 0x1F, 0x15, 0x06, 0x03, 0x01, 0x18, 0x09, 0x5D, - 0x09, 0x52, 0x1B, 0x01, 0x05, 0x14, 0x02, 0x03, 0x09, 0x03, 0x03, 0x01, - 0x1F, 0x15, 0x01, 0x01, 0x26, 0x67, 0x02, 0x03, 0x09, 0x2A, 0x03, 0x03, - 0x01, 0x00, 0x01, 0x17, 0x67, 0x01, 0x9C, 0x10, 0x08, 0x03, 0x02, 0x01, - 0x00, 0x01, 0x3B, 0x67, 0x01, 0x3C, 0x08, 0x02, 0x02, 0x09, 0x03, 0x02, - 0x01, 0x00, 0x01, 0x3C, 0x67, 0x02, 0x02, 0x09, 0x03, 0x02, 0x72, 0x1B, - 0x01, 0x2E, 0x11, 0x06, 0x0D, 0x1A, 0x72, 0x1B, 0x01, 0x30, 0x01, 0x39, - 0x4B, 0x06, 0x03, 0x1A, 0x04, 0x74, 0x01, 0x80, 0x5A, 0x10, 0x06, 0x02, - 0x2F, 0x1D, 0x51, 0x02, 0x03, 0x02, 0x02, 0x00, 0x01, 0x72, 0x53, 0x01, - 0x0A, 0x08, 0x03, 0x00, 0x72, 0x53, 0x02, 0x00, 0x09, 0x00, 0x02, 0x03, - 0x00, 0x03, 0x01, 0x66, 0x1B, 0x02, 0x01, 0x02, 0x00, 0x4B, 0x05, 0x02, - 0x2F, 0x1D, 0x00, 0x00, 0x23, 0x70, 0x01, 0x02, 0x50, 0x0B, 0x69, 0x00, - 0x03, 0x1B, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0x6B, 0x72, 0x1B, 0x01, - 0x81, 0x00, 0x13, 0x06, 0x02, 0x36, 0x1D, 0x1B, 0x01, 0x00, 0x11, 0x06, - 0x0B, 0x1A, 0x1B, 0x05, 0x04, 0x1A, 0x01, 0x00, 0x00, 0x72, 0x04, 0x6F, - 0x02, 0x01, 0x1B, 0x05, 0x02, 0x33, 0x1D, 0x2A, 0x03, 0x01, 0x02, 0x02, - 0x25, 0x02, 0x02, 0x29, 0x03, 0x02, 0x1B, 0x06, 0x03, 0x72, 0x04, 0x68, - 0x1A, 0x02, 0x00, 0x02, 0x01, 0x0A, 0x00, 0x01, 0x72, 0x1B, 0x01, 0x81, - 0x00, 0x0D, 0x06, 0x01, 0x00, 0x01, 0x81, 0x00, 0x0A, 0x1B, 0x05, 0x02, - 0x31, 0x1D, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x12, 0x06, - 0x19, 0x02, 0x00, 0x2A, 0x03, 0x00, 0x1B, 0x01, 0x83, 0xFF, 0xFF, 0x7F, - 0x12, 0x06, 0x02, 0x32, 0x1D, 0x01, 0x08, 0x0E, 0x26, 0x72, 0x23, 0x09, - 0x04, 0x60, 0x00, 0x00, 0x6A, 0x5E, 0x00, 0x00, 0x6B, 0x7A, 0x00, 0x00, - 0x70, 0x4E, 0x6B, 0x00, 0x01, 0x6B, 0x1B, 0x05, 0x02, 0x36, 0x1D, 0x72, - 0x1B, 0x01, 0x81, 0x00, 0x13, 0x06, 0x02, 0x36, 0x1D, 0x03, 0x00, 0x1B, - 0x06, 0x16, 0x72, 0x02, 0x00, 0x1B, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x13, - 0x06, 0x02, 0x36, 0x1D, 0x01, 0x08, 0x0E, 0x09, 0x03, 0x00, 0x04, 0x67, - 0x1A, 0x02, 0x00, 0x00, 0x00, 0x6B, 0x1B, 0x01, 0x81, 0x7F, 0x12, 0x06, - 0x08, 0x7A, 0x01, 0x00, 0x44, 0x25, 0x01, 0x00, 0x00, 0x1B, 0x44, 0x25, - 0x44, 0x29, 0x62, 0x01, 0x7F, 0x00, 0x01, 0x72, 0x03, 0x00, 0x02, 0x00, - 0x01, 0x05, 0x14, 0x01, 0x01, 0x15, 0x1E, 0x02, 0x00, 0x01, 0x06, 0x14, - 0x1B, 0x01, 0x01, 0x15, 0x06, 0x02, 0x2D, 0x1D, 0x01, 0x04, 0x0E, 0x02, - 0x00, 0x01, 0x1F, 0x15, 0x1B, 0x01, 0x1F, 0x11, 0x06, 0x02, 0x2E, 0x1D, - 0x09, 0x00, 0x00, 0x1B, 0x05, 0x05, 0x01, 0x00, 0x01, 0x7F, 0x00, 0x70, - 0x00, 0x00, 0x1B, 0x05, 0x02, 0x32, 0x1D, 0x2A, 0x73, 0x00, 0x00, 0x22, - 0x1B, 0x01, 0x00, 0x13, 0x06, 0x01, 0x00, 0x1A, 0x16, 0x04, 0x74, 0x00, - 0x01, 0x01, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x00, 0x01, 0x15, 0x00, 0x00, - 0x01, 0x1F, 0x00, 0x00, 0x01, 0x29, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, - 0x7B, 0x1A, 0x00, 0x00, 0x1B, 0x06, 0x07, 0x7C, 0x1B, 0x06, 0x01, 0x16, - 0x04, 0x76, 0x00, 0x00, 0x01, 0x00, 0x20, 0x21, 0x0B, 0x2B, 0x00 -}; - -static const uint16_t t0_caddr[] = { - 0, - 5, - 10, - 15, - 20, - 24, - 28, - 32, - 36, - 40, - 44, - 48, - 52, - 56, - 60, - 64, - 68, - 72, - 76, - 80, - 84, - 88, - 93, - 98, - 103, - 111, - 116, - 121, - 126, - 131, - 136, - 141, - 146, - 151, - 156, - 161, - 166, - 181, - 187, - 193, - 198, - 206, - 214, - 220, - 231, - 246, - 250, - 255, - 260, - 265, - 270, - 275, - 279, - 289, - 620, - 625, - 639, - 659, - 666, - 678, - 692, - 707, - 740, - 960, - 974, - 991, - 1000, - 1067, - 1123, - 1127, - 1131, - 1136, - 1184, - 1210, - 1254, - 1265, - 1274, - 1287, - 1291, - 1295, - 1299, - 1303, - 1307, - 1311, - 1315, - 1327 -}; - -#define T0_INTERPRETED 39 - -#define T0_ENTER(ip, rp, slot) do { \ - const unsigned char *t0_newip; \ - uint32_t t0_lnum; \ - t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ - t0_lnum = t0_parse7E_unsigned(&t0_newip); \ - (rp) += t0_lnum; \ - *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ - (ip) = t0_newip; \ - } while (0) - -#define T0_DEFENTRY(name, slot) \ -void \ -name(void *ctx) \ -{ \ - t0_context *t0ctx = ctx; \ - t0ctx->ip = &t0_codeblock[0]; \ - T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ -} - -T0_DEFENTRY(br_x509_decoder_init_main, 92) - -#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) - -void -br_x509_decoder_run(void *t0ctx) -{ - uint32_t *dp, *rp; - const unsigned char *ip; - -#define T0_LOCAL(x) (*(rp - 2 - (x))) -#define T0_POP() (*-- dp) -#define T0_POPi() (*(int32_t *)(-- dp)) -#define T0_PEEK(x) (*(dp - 1 - (x))) -#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) -#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) -#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) -#define T0_RPOP() (*-- rp) -#define T0_RPOPi() (*(int32_t *)(-- rp)) -#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) -#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) -#define T0_ROLL(x) do { \ - size_t t0len = (size_t)(x); \ - uint32_t t0tmp = *(dp - 1 - t0len); \ - memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_SWAP() do { \ - uint32_t t0tmp = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_ROT() do { \ - uint32_t t0tmp = *(dp - 3); \ - *(dp - 3) = *(dp - 2); \ - *(dp - 2) = *(dp - 1); \ - *(dp - 1) = t0tmp; \ -} while (0) -#define T0_NROT() do { \ - uint32_t t0tmp = *(dp - 1); \ - *(dp - 1) = *(dp - 2); \ - *(dp - 2) = *(dp - 3); \ - *(dp - 3) = t0tmp; \ -} while (0) -#define T0_PICK(x) do { \ - uint32_t t0depth = (x); \ - T0_PUSH(T0_PEEK(t0depth)); \ -} while (0) -#define T0_CO() do { \ - goto t0_exit; \ -} while (0) -#define T0_RET() goto t0_next - - dp = ((t0_context *)t0ctx)->dp; - rp = ((t0_context *)t0ctx)->rp; - ip = ((t0_context *)t0ctx)->ip; - goto t0_next; - for (;;) { - uint32_t t0x; - - t0_next: - t0x = T0_NEXT(&ip); - if (t0x < T0_INTERPRETED) { - switch (t0x) { - int32_t t0off; - - case 0: /* ret */ - t0x = T0_RPOP(); - rp -= (t0x >> 16); - t0x &= 0xFFFF; - if (t0x == 0) { - ip = NULL; - goto t0_exit; - } - ip = &t0_codeblock[t0x]; - break; - case 1: /* literal constant */ - T0_PUSHi(t0_parse7E_signed(&ip)); - break; - case 2: /* read local */ - T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); - break; - case 3: /* write local */ - T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); - break; - case 4: /* jump */ - t0off = t0_parse7E_signed(&ip); - ip += t0off; - break; - case 5: /* jump if */ - t0off = t0_parse7E_signed(&ip); - if (T0_POP()) { - ip += t0off; - } - break; - case 6: /* jump if not */ - t0off = t0_parse7E_signed(&ip); - if (!T0_POP()) { - ip += t0off; - } - break; - case 7: { - /* %25 */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSHi(a % b); - - } - break; - case 8: { - /* * */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a * b); - - } - break; - case 9: { - /* + */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a + b); - - } - break; - case 10: { - /* - */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a - b); - - } - break; - case 11: { - /* -rot */ - T0_NROT(); - } - break; - case 12: { - /* / */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSHi(a / b); - - } - break; - case 13: { - /* < */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a < b)); - - } - break; - case 14: { - /* << */ - - int c = (int)T0_POPi(); - uint32_t x = T0_POP(); - T0_PUSH(x << c); - - } - break; - case 15: { - /* <= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a <= b)); - - } - break; - case 16: { - /* <> */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a != b)); - - } - break; - case 17: { - /* = */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(-(uint32_t)(a == b)); - - } - break; - case 18: { - /* > */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a > b)); - - } - break; - case 19: { - /* >= */ - - int32_t b = T0_POPi(); - int32_t a = T0_POPi(); - T0_PUSH(-(uint32_t)(a >= b)); - - } - break; - case 20: { - /* >> */ - - int c = (int)T0_POPi(); - int32_t x = T0_POPi(); - T0_PUSHi(x >> c); - - } - break; - case 21: { - /* and */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a & b); - - } - break; - case 22: { - /* co */ - T0_CO(); - } - break; - case 23: { - /* copy-ec-pkey */ - - size_t qlen = T0_POP(); - uint32_t curve = T0_POP(); - CTX->pkey.key_type = BR_KEYTYPE_EC; - CTX->pkey.key.ec.curve = curve; - CTX->pkey.key.ec.q = CTX->pkey_data; - CTX->pkey.key.ec.qlen = qlen; - - } - break; - case 24: { - /* copy-rsa-pkey */ - - size_t elen = T0_POP(); - size_t nlen = T0_POP(); - CTX->pkey.key_type = BR_KEYTYPE_RSA; - CTX->pkey.key.rsa.n = CTX->pkey_data; - CTX->pkey.key.rsa.nlen = nlen; - CTX->pkey.key.rsa.e = CTX->pkey_data + nlen; - CTX->pkey.key.rsa.elen = elen; - - } - break; - case 25: { - /* data-get8 */ - - size_t addr = T0_POP(); - T0_PUSH(t0_datablock[addr]); - - } - break; - case 26: { - /* drop */ - (void)T0_POP(); - } - break; - case 27: { - /* dup */ - T0_PUSH(T0_PEEK(0)); - } - break; - case 28: { - /* eqOID */ - - const unsigned char *a2 = &t0_datablock[T0_POP()]; - const unsigned char *a1 = &CTX->pad[0]; - size_t len = a1[0]; - int x; - if (len == a2[0]) { - x = -(memcmp(a1 + 1, a2 + 1, len) == 0); - } else { - x = 0; - } - T0_PUSH((uint32_t)x); - - } - break; - case 29: { - /* fail */ - - CTX->err = T0_POPi(); - T0_CO(); - - } - break; - case 30: { - /* neg */ - - uint32_t a = T0_POP(); - T0_PUSH(-a); - - } - break; - case 31: { - /* or */ - - uint32_t b = T0_POP(); - uint32_t a = T0_POP(); - T0_PUSH(a | b); - - } - break; - case 32: { - /* over */ - T0_PUSH(T0_PEEK(1)); - } - break; - case 33: { - /* read-blob-inner */ - - uint32_t len = T0_POP(); - uint32_t addr = T0_POP(); - size_t clen = CTX->hlen; - if (clen > len) { - clen = (size_t)len; - } - if (addr != 0) { - memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); - } - if (CTX->copy_dn && CTX->append_dn) { - CTX->append_dn(CTX->append_dn_ctx, CTX->hbuf, clen); - } - CTX->hbuf += clen; - CTX->hlen -= clen; - T0_PUSH(addr + clen); - T0_PUSH(len - clen); - - } - break; - case 34: { - /* read8-low */ - - if (CTX->hlen == 0) { - T0_PUSHi(-1); - } else { - unsigned char x = *CTX->hbuf ++; - if (CTX->copy_dn && CTX->append_dn) { - CTX->append_dn(CTX->append_dn_ctx, &x, 1); - } - CTX->hlen --; - T0_PUSH(x); - } - - } - break; - case 35: { - /* rot */ - T0_ROT(); - } - break; - case 36: { - /* set32 */ - - uint32_t addr = T0_POP(); - *(uint32_t *)(void *)((unsigned char *)CTX + addr) = T0_POP(); - - } - break; - case 37: { - /* set8 */ - - uint32_t addr = T0_POP(); - *((unsigned char *)CTX + addr) = (unsigned char)T0_POP(); - - } - break; - case 38: { - /* swap */ - T0_SWAP(); - } - break; - } - - } else { - T0_ENTER(ip, rp, t0x); - } - } -t0_exit: - ((t0_context *)t0ctx)->dp = dp; - ((t0_context *)t0ctx)->rp = rp; - ((t0_context *)t0ctx)->ip = ip; -} diff --git a/third_party/bearssl/src/x509_knownkey.c b/third_party/bearssl/src/x509_knownkey.c deleted file mode 100644 index 7674f3fd0..000000000 --- a/third_party/bearssl/src/x509_knownkey.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2016 Thomas Pornin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "inner.h" - -/* see bearssl_x509.h */ -void -br_x509_knownkey_init_rsa(br_x509_knownkey_context *ctx, - const br_rsa_public_key *pk, unsigned usages) -{ - ctx->vtable = &br_x509_knownkey_vtable; - ctx->pkey.key_type = BR_KEYTYPE_RSA; - ctx->pkey.key.rsa = *pk; - ctx->usages = usages; -} - -/* see bearssl_x509.h */ -void -br_x509_knownkey_init_ec(br_x509_knownkey_context *ctx, - const br_ec_public_key *pk, unsigned usages) -{ - ctx->vtable = &br_x509_knownkey_vtable; - ctx->pkey.key_type = BR_KEYTYPE_EC; - ctx->pkey.key.ec = *pk; - ctx->usages = usages; -} - -static void -kk_start_chain(const br_x509_class **ctx, const char *server_name) -{ - (void)ctx; - (void)server_name; -} - -static void -kk_start_cert(const br_x509_class **ctx, uint32_t length) -{ - (void)ctx; - (void)length; -} - -static void -kk_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) -{ - (void)ctx; - (void)buf; - (void)len; -} - -static void -kk_end_cert(const br_x509_class **ctx) -{ - (void)ctx; -} - -static unsigned -kk_end_chain(const br_x509_class **ctx) -{ - (void)ctx; - return 0; -} - -static const br_x509_pkey * -kk_get_pkey(const br_x509_class *const *ctx, unsigned *usages) -{ - const br_x509_knownkey_context *xc; - - xc = (const br_x509_knownkey_context *)ctx; - if (usages != NULL) { - *usages = xc->usages; - } - return &xc->pkey; -} - -/* see bearssl_x509.h */ -const br_x509_class br_x509_knownkey_vtable = { - sizeof(br_x509_knownkey_context), - kk_start_chain, - kk_start_cert, - kk_append, - kk_end_cert, - kk_end_chain, - kk_get_pkey -};