Fixup workflow files

This commit is contained in:
UnknownShadow200 2025-06-28 15:11:14 +10:00
parent 8ce38175f5
commit 8b4c36a9ec
16 changed files with 37 additions and 3667 deletions

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -35,14 +35,14 @@ jobs:
id: compile
shell: bash
env:
COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn -Werror -Wl,-R/usr/X11R7/lib"
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'

View File

@ -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,6 +136,5 @@
#include "bearssl_ec.h"
#include "bearssl_ssl.h"
#include "bearssl_x509.h"
#include "bearssl_pem.h"
#endif

View File

@ -1,284 +0,0 @@
/*
* Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
*
* 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 <stddef.h>
#include <stdint.h>
#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

View File

@ -1,294 +0,0 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* 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 <stddef.h>
#include <stdint.h>
#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

View File

@ -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

View File

@ -1,110 +0,0 @@
/*
* Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
*
* 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;
}
}

View File

@ -1,161 +0,0 @@
/*
* Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
*
* 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);
}

View File

@ -1,97 +0,0 @@
/*
* Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
*
* 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;
}
}

View File

@ -1,96 +0,0 @@
/*
* Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
*
* 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;
}
}

View File

@ -1,107 +0,0 @@
/*
* Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
*
* 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;
}

View File

@ -1,590 +0,0 @@
/*
* Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
*
* 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;
}

View File

@ -1,650 +0,0 @@
/* Automatically generated code; do not modify directly. */
#include <stddef.h>
#include <stdint.h>
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;
}

View File

@ -1,773 +0,0 @@
/* Automatically generated code; do not modify directly. */
#include <stddef.h>
#include <stdint.h>
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;
}