Source code

Revision control

Copy as Markdown

Other Tools

/*
* Copyright (c) 2017-2020 [Ribose Inc](https://www.ribose.com).
* All rights reserved.
*
* This code is originally derived from software contributed to
* The NetBSD Foundation by Alistair Crooks (agc@netbsd.org), and
* carried further by Ribose Inc (https://www.ribose.com).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EC_H_
#define EC_H_
#include "config.h"
#include <rnp/rnp_def.h>
#include <repgp/repgp_def.h>
#include "crypto/rng.h"
#include "crypto/mpi.h"
#define MAX_CURVE_BIT_SIZE 521 // secp521r1
/* Maximal byte size of elliptic curve order (NIST P-521) */
#define MAX_CURVE_BYTELEN ((MAX_CURVE_BIT_SIZE + 7) / 8)
/**
* Maximal length of the OID in hex representation.
*
* \see RFC4880 bis01 - 9.2 ECC Curve OID
*/
#define MAX_CURVE_OID_HEX_LEN 10U
/**
* Structure holds description of elliptic curve
*/
typedef struct ec_curve_desc_t {
const pgp_curve_t rnp_curve_id;
const size_t bitlen;
const uint8_t OIDhex[MAX_CURVE_OID_HEX_LEN];
const size_t OIDhex_len;
#if defined(CRYPTO_BACKEND_BOTAN)
const char *botan_name;
#endif
#if defined(CRYPTO_BACKEND_OPENSSL)
const char *openssl_name;
#endif
const char *pgp_name;
/* Curve is supported for keygen/sign/encrypt operations */
bool supported;
/* Curve parameters below. Needed for grip calculation */
const char *p;
const char *a;
const char *b;
const char *n;
const char *gx;
const char *gy;
const char *h;
} ec_curve_desc_t;
typedef struct pgp_ec_key_t {
pgp_curve_t curve;
pgp_mpi_t p;
/* secret mpi */
pgp_mpi_t x;
/* ecdh params */
pgp_hash_alg_t kdf_hash_alg; /* Hash used by kdf */
pgp_symm_alg_t key_wrap_alg; /* Symmetric algorithm used to wrap KEK*/
} pgp_ec_key_t;
typedef struct pgp_ec_signature_t {
pgp_mpi_t r;
pgp_mpi_t s;
} pgp_ec_signature_t;
/*
* @brief Finds curve ID by hex representation of OID
*
* @param oid buffer with OID in hex
* @param oid_len length of oid buffer
*
* @returns success curve ID
* failure PGP_CURVE_MAX is returned
*
* @remarks see RFC 4880 bis 01 - 9.2 ECC Curve OID
*/
pgp_curve_t find_curve_by_OID(const uint8_t *oid, size_t oid_len);
pgp_curve_t find_curve_by_name(const char *name);
/*
* @brief Returns pointer to the curve descriptor
*
* @param Valid curve ID
*
* @returns NULL if wrong ID provided, otherwise descriptor
*
*/
const ec_curve_desc_t *get_curve_desc(const pgp_curve_t curve_id);
bool alg_allows_curve(pgp_pubkey_alg_t alg, pgp_curve_t curve);
/**
* @brief Check whether curve is supported for operations.
* All available curves are supported for reading/parsing key data, however some of them
* may be disabled for use, i.e. for key generation/signing/encryption.
*/
bool curve_supported(pgp_curve_t curve);
/*
* @brief Generates EC key in uncompressed format
*
* @param rng initialized rnp::RNG context*
* @param key key data to be generated
* @param alg_id ID of EC algorithm
* @param curve underlying ECC curve ID
*
* @pre alg_id MUST be supported algorithm
*
* @returns RNP_ERROR_BAD_PARAMETERS unknown curve_id
* @returns RNP_ERROR_OUT_OF_MEMORY memory allocation failed
* @returns RNP_ERROR_KEY_GENERATION implementation error
*/
rnp_result_t ec_generate(rnp::RNG * rng,
pgp_ec_key_t * key,
const pgp_pubkey_alg_t alg_id,
const pgp_curve_t curve);
/*
* @brief Generates x25519 ECDH key in x25519-specific format
*
* @param rng initialized rnp::RNG context*
* @param key key data to be generated
*
* @returns RNP_ERROR_KEY_GENERATION implementation error
*/
rnp_result_t x25519_generate(rnp::RNG *rng, pgp_ec_key_t *key);
/**
* @brief Set least significant/most significant bits of the 25519 secret key as per
* specification.
*
* @param key secret key.
* @return true on success or false otherwise.
*/
bool x25519_tweak_bits(pgp_ec_key_t &key);
/**
* @brief Check whether least significant/most significant bits of 25519 secret key are
* correctly tweaked.
*
* @param key secret key.
* @return true if bits are set correctly, and false otherwise.
*/
bool x25519_bits_tweaked(const pgp_ec_key_t &key);
#endif