diff options
Diffstat (limited to 'src/lib/crypto/ec.h')
-rw-r--r-- | src/lib/crypto/ec.h | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/lib/crypto/ec.h b/src/lib/crypto/ec.h new file mode 100644 index 0000000..07cb8e8 --- /dev/null +++ b/src/lib/crypto/ec.h @@ -0,0 +1,173 @@ +/* + * 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 |