2021-07-26 15:16:43 -07:00
|
|
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│
|
|
|
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
|
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
|
|
│ Copyright The Mbed TLS Contributors │
|
|
|
|
│ │
|
|
|
|
│ Licensed under the Apache License, Version 2.0 (the "License"); │
|
|
|
|
│ you may not use this file except in compliance with the License. │
|
|
|
|
│ You may obtain a copy of the License at │
|
|
|
|
│ │
|
|
|
|
│ http://www.apache.org/licenses/LICENSE-2.0 │
|
|
|
|
│ │
|
|
|
|
│ Unless required by applicable law or agreed to in writing, software │
|
|
|
|
│ distributed under the License is distributed on an "AS IS" BASIS, │
|
|
|
|
│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
|
|
|
|
│ See the License for the specific language governing permissions and │
|
|
|
|
│ limitations under the License. │
|
|
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
Unbloat build config
- 10.5% reduction of o//depend dependency graph
- 8.8% reduction in latency of make command
- Fix issue with temporary file cleanup
There's a new -w option in compile.com that turns off the recent
Landlock output path workaround for "good commands" which do not
unlink() the output file like GNU tooling does.
Our new GNU Make unveil sandboxing appears to have zero overhead
in the grand scheme of things. Full builds are pretty fast since
the only thing that's actually slowed us down is probably libcxx
make -j16 MODE=rel
RL: took 85,732,063µs wall time
RL: ballooned to 323,612kb in size
RL: needed 828,560,521µs cpu (11% kernel)
RL: caused 39,080,670 page faults (99% memcpy)
RL: 350,073 context switches (72% consensual)
RL: performed 0 reads and 11,494,960 write i/o operations
pledge() and unveil() no longer consider ENOSYS to be an error.
These functions have also been added to Python's cosmo module.
This change also removes some WIN32 APIs and System Five magnums
which we're not using and it's doubtful anyone else would be too
2022-08-10 01:32:17 -07:00
|
|
|
#include "libc/str/str.h"
|
2021-07-26 15:16:43 -07:00
|
|
|
#include "third_party/mbedtls/ecdh_everest.h"
|
|
|
|
#include "third_party/mbedtls/everest.h"
|
|
|
|
#if defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
|
|
|
#define KEYSIZE 32
|
|
|
|
|
|
|
|
asm(".ident\t\"\\n\\n\
|
|
|
|
Mbed TLS (Apache 2.0)\\n\
|
|
|
|
Copyright ARM Limited\\n\
|
|
|
|
Copyright Mbed TLS Contributors\"");
|
|
|
|
asm(".include \"libc/disclaimer.inc\"");
|
|
|
|
/* clang-format off */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief This function sets up the ECDH context with the information
|
|
|
|
* given.
|
|
|
|
*
|
|
|
|
* This function should be called after mbedtls_ecdh_init() but
|
|
|
|
* before mbedtls_ecdh_make_params(). There is no need to call
|
|
|
|
* this function before mbedtls_ecdh_read_params().
|
|
|
|
*
|
|
|
|
* This is the first function used by a TLS server for
|
|
|
|
* ECDHE ciphersuites.
|
|
|
|
*
|
|
|
|
* \param ctx The ECDH context to set up.
|
|
|
|
* \param grp_id The group id of the group to set up the context for.
|
|
|
|
*
|
|
|
|
* \return \c 0 on success.
|
|
|
|
*/
|
|
|
|
int mbedtls_everest_setup(mbedtls_ecdh_context_everest *ctx, int grp_id)
|
|
|
|
{
|
|
|
|
if (grp_id != MBEDTLS_ECP_DP_CURVE25519)
|
|
|
|
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
|
|
|
mbedtls_platform_zeroize(ctx, sizeof(*ctx));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief This function frees a context.
|
|
|
|
*
|
|
|
|
* \param ctx The context to free.
|
|
|
|
*/
|
|
|
|
void mbedtls_everest_free(mbedtls_ecdh_context_everest *ctx)
|
|
|
|
{
|
|
|
|
if (!ctx) return;
|
|
|
|
mbedtls_platform_zeroize(ctx, sizeof(*ctx));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief This function generates a public key and a TLS
|
|
|
|
* ServerKeyExchange payload.
|
|
|
|
*
|
|
|
|
* This is the second function used by a TLS server for ECDHE
|
|
|
|
* ciphersuites. (It is called after mbedtls_ecdh_setup().)
|
|
|
|
*
|
|
|
|
* \note This function assumes that the ECP group (grp) of the
|
|
|
|
* \p ctx context has already been properly set,
|
|
|
|
* for example, using mbedtls_ecp_group_load().
|
|
|
|
*
|
|
|
|
* \see ecp.h
|
|
|
|
*
|
|
|
|
* \param ctx The ECDH context.
|
|
|
|
* \param olen The number of characters written.
|
|
|
|
* \param buf The destination buffer.
|
|
|
|
* \param blen The length of the destination buffer.
|
|
|
|
* \param f_rng The RNG function.
|
|
|
|
* \param p_rng The RNG context.
|
|
|
|
*
|
|
|
|
* \return \c 0 on success.
|
|
|
|
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
|
|
|
*/
|
|
|
|
int mbedtls_everest_make_params(mbedtls_ecdh_context_everest *ctx, size_t *olen,
|
|
|
|
unsigned char *buf, size_t blen,
|
|
|
|
int (*f_rng)(void *, unsigned char *, size_t),
|
|
|
|
void *p_rng)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
uint8_t base[KEYSIZE] = {9};
|
|
|
|
if ((ret = f_rng(p_rng, ctx->our_secret, KEYSIZE)) != 0) return ret;
|
|
|
|
*olen = KEYSIZE + 4;
|
|
|
|
if (blen < *olen) return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
|
|
|
|
*buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
|
|
|
|
*buf++ = MBEDTLS_ECP_TLS_CURVE25519 >> 8;
|
|
|
|
*buf++ = MBEDTLS_ECP_TLS_CURVE25519 & 0xFF;
|
|
|
|
*buf++ = KEYSIZE;
|
|
|
|
curve25519(buf, ctx->our_secret, base);
|
|
|
|
base[0] = 0;
|
2021-09-27 22:58:51 -07:00
|
|
|
if (!timingsafe_bcmp(buf, base, KEYSIZE))
|
2021-07-26 15:16:43 -07:00
|
|
|
return MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief This function parses and processes a TLS ServerKeyExhange
|
|
|
|
* payload.
|
|
|
|
*
|
|
|
|
* This is the first function used by a TLS client for ECDHE
|
|
|
|
* ciphersuites.
|
|
|
|
*
|
|
|
|
* \see ecp.h
|
|
|
|
*
|
|
|
|
* \param ctx The ECDH context.
|
|
|
|
* \param buf The pointer to the start of the input buffer.
|
|
|
|
* \param end The address for one Byte past the end of the buffer.
|
|
|
|
*
|
|
|
|
* \return \c 0 on success.
|
|
|
|
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
|
|
|
*/
|
|
|
|
int mbedtls_everest_read_params(mbedtls_ecdh_context_everest *ctx,
|
|
|
|
const unsigned char **buf,
|
|
|
|
const unsigned char *end)
|
|
|
|
{
|
|
|
|
if (end - *buf < KEYSIZE + 1) return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
|
|
|
if ((*(*buf)++ != KEYSIZE)) return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
|
|
|
memcpy(ctx->peer_point, *buf, KEYSIZE);
|
|
|
|
*buf += KEYSIZE;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief This function sets up an ECDH context from an EC key.
|
|
|
|
*
|
|
|
|
* It is used by clients and servers in place of the
|
|
|
|
* ServerKeyEchange for static ECDH, and imports ECDH
|
|
|
|
* parameters from the EC key information of a certificate.
|
|
|
|
*
|
|
|
|
* \see ecp.h
|
|
|
|
*
|
|
|
|
* \param ctx The ECDH context to set up.
|
|
|
|
* \param key The EC key to use.
|
|
|
|
* \param side Defines the source of the key: 1: Our key, or
|
|
|
|
* 0: The key of the peer.
|
|
|
|
*
|
|
|
|
* \return \c 0 on success.
|
|
|
|
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
|
|
|
*/
|
|
|
|
int mbedtls_everest_get_params(mbedtls_ecdh_context_everest *ctx,
|
|
|
|
const mbedtls_ecp_keypair *key,
|
|
|
|
mbedtls_everest_ecdh_side side)
|
|
|
|
{
|
|
|
|
size_t olen = 0;
|
|
|
|
mbedtls_everest_ecdh_side s;
|
|
|
|
switch (side)
|
|
|
|
{
|
|
|
|
case MBEDTLS_EVEREST_ECDH_THEIRS:
|
|
|
|
return mbedtls_ecp_point_write_binary(&key->grp, &key->Q,
|
|
|
|
MBEDTLS_ECP_PF_COMPRESSED, &olen,
|
|
|
|
ctx->peer_point, KEYSIZE);
|
|
|
|
case MBEDTLS_EVEREST_ECDH_OURS:
|
|
|
|
return mbedtls_mpi_write_binary_le(&key->d, ctx->our_secret, KEYSIZE);
|
|
|
|
default:
|
|
|
|
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief This function generates a public key and a TLS
|
|
|
|
* ClientKeyExchange payload.
|
|
|
|
*
|
|
|
|
* This is the second function used by a TLS client for ECDH(E)
|
|
|
|
* ciphersuites.
|
|
|
|
*
|
|
|
|
* \see ecp.h
|
|
|
|
*
|
|
|
|
* \param ctx The ECDH context.
|
|
|
|
* \param olen The number of Bytes written.
|
|
|
|
* \param buf The destination buffer.
|
|
|
|
* \param blen The size of the destination buffer.
|
|
|
|
* \param f_rng The RNG function.
|
|
|
|
* \param p_rng The RNG context.
|
|
|
|
*
|
|
|
|
* \return \c 0 on success.
|
|
|
|
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
|
|
|
*/
|
|
|
|
int mbedtls_everest_make_public(mbedtls_ecdh_context_everest *ctx, size_t *olen,
|
|
|
|
unsigned char *buf, size_t blen,
|
|
|
|
int (*f_rng)(void *, unsigned char *, size_t),
|
|
|
|
void *p_rng)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
unsigned char base[KEYSIZE] = {9};
|
|
|
|
if (!ctx) return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
|
|
|
if ((ret = f_rng(p_rng, ctx->our_secret, KEYSIZE))) return ret;
|
|
|
|
*olen = KEYSIZE + 1;
|
|
|
|
if (blen < *olen) return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
|
|
|
|
*buf++ = KEYSIZE;
|
|
|
|
curve25519(buf, ctx->our_secret, base);
|
|
|
|
base[0] = 0;
|
2021-09-27 22:58:51 -07:00
|
|
|
if (!timingsafe_bcmp(buf, base, KEYSIZE))
|
2021-07-26 15:16:43 -07:00
|
|
|
return MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief This function parses and processes a TLS ClientKeyExchange
|
|
|
|
* payload.
|
|
|
|
*
|
|
|
|
* This is the third function used by a TLS server for ECDH(E)
|
|
|
|
* ciphersuites. (It is called after mbedtls_ecdh_setup() and
|
|
|
|
* mbedtls_ecdh_make_params().)
|
|
|
|
*
|
|
|
|
* \see ecp.h
|
|
|
|
*
|
|
|
|
* \param ctx The ECDH context.
|
|
|
|
* \param buf The start of the input buffer.
|
|
|
|
* \param blen The length of the input buffer.
|
|
|
|
*
|
|
|
|
* \return \c 0 on success.
|
|
|
|
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
|
|
|
*/
|
|
|
|
int mbedtls_everest_read_public(mbedtls_ecdh_context_everest *ctx,
|
|
|
|
const unsigned char *buf, size_t blen)
|
|
|
|
{
|
|
|
|
if (blen < KEYSIZE + 1) return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
|
|
|
|
if ((*buf++ != KEYSIZE)) return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
|
|
|
memcpy(ctx->peer_point, buf, KEYSIZE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief This function derives and exports the shared secret.
|
|
|
|
*
|
|
|
|
* This is the last function used by both TLS client
|
|
|
|
* and servers.
|
|
|
|
*
|
|
|
|
* \note If \p f_rng is not NULL, it is used to implement
|
|
|
|
* countermeasures against side-channel attacks.
|
|
|
|
* For more information, see mbedtls_ecp_mul().
|
|
|
|
*
|
|
|
|
* \see ecp.h
|
|
|
|
*
|
|
|
|
* \param ctx The ECDH context.
|
|
|
|
* \param olen The number of Bytes written.
|
|
|
|
* \param buf The destination buffer.
|
|
|
|
* \param blen The length of the destination buffer.
|
|
|
|
* \param f_rng The RNG function.
|
|
|
|
* \param p_rng The RNG context.
|
|
|
|
*
|
|
|
|
* \return \c 0 on success.
|
|
|
|
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
|
|
|
*/
|
|
|
|
int mbedtls_everest_calc_secret(mbedtls_ecdh_context_everest *ctx, size_t *olen,
|
|
|
|
unsigned char *buf, size_t blen,
|
|
|
|
int (*f_rng)(void *, unsigned char *, size_t),
|
|
|
|
void *p_rng)
|
|
|
|
{
|
|
|
|
/* f_rng and p_rng are not used here because this implementation does not
|
|
|
|
need blinding since it has constant trace. (todo(jart): wut?) */
|
|
|
|
*olen = KEYSIZE;
|
|
|
|
if (blen < *olen) return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
|
|
|
|
curve25519(buf, ctx->our_secret, ctx->peer_point);
|
2021-09-27 22:58:51 -07:00
|
|
|
if (!timingsafe_bcmp(buf, ctx->our_secret, KEYSIZE)) goto wut;
|
2021-07-26 15:16:43 -07:00
|
|
|
/* Wipe the DH secret and don't let the peer chose a small subgroup point */
|
|
|
|
mbedtls_platform_zeroize(ctx->our_secret, KEYSIZE);
|
2021-09-27 22:58:51 -07:00
|
|
|
if (!timingsafe_bcmp(buf, ctx->our_secret, KEYSIZE)) goto wut;
|
2021-07-26 15:16:43 -07:00
|
|
|
return 0;
|
|
|
|
wut:
|
|
|
|
mbedtls_platform_zeroize(buf, KEYSIZE);
|
|
|
|
mbedtls_platform_zeroize(ctx->our_secret, KEYSIZE);
|
|
|
|
return MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|