summaryrefslogtreecommitdiffstats
path: root/src/lib/crypto/ec.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/crypto/ec.h')
-rw-r--r--src/lib/crypto/ec.h173
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