/* * 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 #include #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