quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

x25519.c (5937B)


      1 /*
      2  *  ECDH with curve-optimized implementation multiplexing
      3  *
      4  *  Copyright 2016-2018 INRIA and Microsoft Corporation
      5  *  SPDX-License-Identifier: Apache-2.0
      6  *
      7  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
      8  *  not use this file except in compliance with the License.
      9  *  You may obtain a copy of the License at
     10  *
     11  *  http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  *  Unless required by applicable law or agreed to in writing, software
     14  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     15  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  *  See the License for the specific language governing permissions and
     17  *  limitations under the License.
     18  *
     19  *  This file is part of Mbed TLS (https://tls.mbed.org)
     20  */
     21 
     22 #include "common.h"
     23 
     24 #if defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
     25 
     26 #include <mbedtls/ecdh.h>
     27 
     28 #if !(defined(__SIZEOF_INT128__) && (__SIZEOF_INT128__ == 16))
     29 #define KRML_VERIFIED_UINT128
     30 #endif
     31 
     32 #include <Hacl_Curve25519.h>
     33 #include <mbedtls/platform_util.h>
     34 
     35 #include "x25519.h"
     36 
     37 #include <string.h>
     38 
     39 /*
     40  * Initialize context
     41  */
     42 void mbedtls_x25519_init( mbedtls_x25519_context *ctx )
     43 {
     44     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x25519_context ) );
     45 }
     46 
     47 /*
     48  * Free context
     49  */
     50 void mbedtls_x25519_free( mbedtls_x25519_context *ctx )
     51 {
     52     if( ctx == NULL )
     53         return;
     54 
     55     mbedtls_platform_zeroize( ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES );
     56     mbedtls_platform_zeroize( ctx->peer_point, MBEDTLS_X25519_KEY_SIZE_BYTES );
     57 }
     58 
     59 int mbedtls_x25519_make_params( mbedtls_x25519_context *ctx, size_t *olen,
     60                         unsigned char *buf, size_t blen,
     61                         int( *f_rng )(void *, unsigned char *, size_t),
     62                         void *p_rng )
     63 {
     64     int ret = 0;
     65 
     66     uint8_t base[MBEDTLS_X25519_KEY_SIZE_BYTES] = {0};
     67 
     68     if( ( ret = f_rng( p_rng, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES ) ) != 0 )
     69         return ret;
     70 
     71     *olen = MBEDTLS_X25519_KEY_SIZE_BYTES + 4;
     72     if( blen < *olen )
     73         return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
     74 
     75     *buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
     76     *buf++ = MBEDTLS_ECP_TLS_CURVE25519 >> 8;
     77     *buf++ = MBEDTLS_ECP_TLS_CURVE25519 & 0xFF;
     78     *buf++ = MBEDTLS_X25519_KEY_SIZE_BYTES;
     79 
     80     base[0] = 9;
     81     Hacl_Curve25519_crypto_scalarmult( buf, ctx->our_secret, base );
     82 
     83     base[0] = 0;
     84     if( memcmp( buf, base, MBEDTLS_X25519_KEY_SIZE_BYTES) == 0 )
     85         return MBEDTLS_ERR_ECP_RANDOM_FAILED;
     86 
     87     return( 0 );
     88 }
     89 
     90 int mbedtls_x25519_read_params( mbedtls_x25519_context *ctx,
     91                         const unsigned char **buf, const unsigned char *end )
     92 {
     93     if( end - *buf < MBEDTLS_X25519_KEY_SIZE_BYTES + 1 )
     94         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
     95 
     96     if( ( *(*buf)++ != MBEDTLS_X25519_KEY_SIZE_BYTES ) )
     97         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
     98 
     99     memcpy( ctx->peer_point, *buf, MBEDTLS_X25519_KEY_SIZE_BYTES );
    100     *buf += MBEDTLS_X25519_KEY_SIZE_BYTES;
    101     return( 0 );
    102 }
    103 
    104 int mbedtls_x25519_get_params( mbedtls_x25519_context *ctx, const mbedtls_ecp_keypair *key,
    105                                mbedtls_x25519_ecdh_side side )
    106 {
    107     size_t olen = 0;
    108 
    109     switch( side ) {
    110     case MBEDTLS_X25519_ECDH_THEIRS:
    111         return mbedtls_ecp_point_write_binary( &key->grp, &key->Q, MBEDTLS_ECP_PF_COMPRESSED, &olen, ctx->peer_point, MBEDTLS_X25519_KEY_SIZE_BYTES );
    112     case MBEDTLS_X25519_ECDH_OURS:
    113         return mbedtls_mpi_write_binary_le( &key->d, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES );
    114     default:
    115         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
    116     }
    117 }
    118 
    119 int mbedtls_x25519_calc_secret( mbedtls_x25519_context *ctx, size_t *olen,
    120                         unsigned char *buf, size_t blen,
    121                         int( *f_rng )(void *, unsigned char *, size_t),
    122                         void *p_rng )
    123 {
    124     /* f_rng and p_rng are not used here because this implementation does not
    125        need blinding since it has constant trace. */
    126     (( void )f_rng);
    127     (( void )p_rng);
    128 
    129     *olen = MBEDTLS_X25519_KEY_SIZE_BYTES;
    130 
    131     if( blen < *olen )
    132         return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
    133 
    134     Hacl_Curve25519_crypto_scalarmult( buf, ctx->our_secret, ctx->peer_point);
    135 
    136     /* Wipe the DH secret and don't let the peer chose a small subgroup point */
    137     mbedtls_platform_zeroize( ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES );
    138 
    139     if( memcmp( buf, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES) == 0 )
    140         return MBEDTLS_ERR_ECP_RANDOM_FAILED;
    141 
    142     return( 0 );
    143 }
    144 
    145 int mbedtls_x25519_make_public( mbedtls_x25519_context *ctx, size_t *olen,
    146                         unsigned char *buf, size_t blen,
    147                         int( *f_rng )(void *, unsigned char *, size_t),
    148                         void *p_rng )
    149 {
    150     int ret = 0;
    151     unsigned char base[MBEDTLS_X25519_KEY_SIZE_BYTES] = { 0 };
    152 
    153     if( ctx == NULL )
    154         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
    155 
    156     if( ( ret = f_rng( p_rng, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES ) ) != 0 )
    157         return ret;
    158 
    159     *olen = MBEDTLS_X25519_KEY_SIZE_BYTES + 1;
    160     if( blen < *olen )
    161         return(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
    162     *buf++ = MBEDTLS_X25519_KEY_SIZE_BYTES;
    163 
    164     base[0] = 9;
    165     Hacl_Curve25519_crypto_scalarmult( buf, ctx->our_secret, base );
    166 
    167     base[0] = 0;
    168     if( memcmp( buf, base, MBEDTLS_X25519_KEY_SIZE_BYTES ) == 0 )
    169         return MBEDTLS_ERR_ECP_RANDOM_FAILED;
    170 
    171     return( ret );
    172 }
    173 
    174 int mbedtls_x25519_read_public( mbedtls_x25519_context *ctx,
    175                         const unsigned char *buf, size_t blen )
    176 {
    177     if( blen < MBEDTLS_X25519_KEY_SIZE_BYTES + 1 )
    178         return(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
    179     if( (*buf++ != MBEDTLS_X25519_KEY_SIZE_BYTES) )
    180         return(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
    181     memcpy( ctx->peer_point, buf, MBEDTLS_X25519_KEY_SIZE_BYTES );
    182     return( 0 );
    183 }
    184 
    185 
    186 #endif /* MBEDTLS_ECDH_C && MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED */