summaryrefslogtreecommitdiffstats
path: root/src/lib/crypto/ec_curves.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/crypto/ec_curves.cpp')
-rw-r--r--src/lib/crypto/ec_curves.cpp323
1 files changed, 323 insertions, 0 deletions
diff --git a/src/lib/crypto/ec_curves.cpp b/src/lib/crypto/ec_curves.cpp
new file mode 100644
index 0000000..db5cf09
--- /dev/null
+++ b/src/lib/crypto/ec_curves.cpp
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2021, [Ribose Inc](https://www.ribose.com).
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+#include <string.h>
+#include "ec.h"
+#include "types.h"
+#include "utils.h"
+#include "str-utils.h"
+
+/**
+ * EC Curves definition used by implementation
+ *
+ * \see RFC4880 bis01 - 9.2. ECC Curve OID
+ *
+ * Order of the elements in this array corresponds to
+ * values in pgp_curve_t enum.
+ */
+static const ec_curve_desc_t ec_curves[] = {
+ {PGP_CURVE_UNKNOWN, 0, {0}, 0, NULL, NULL},
+
+ {PGP_CURVE_NIST_P_256,
+ 256,
+ {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07},
+ 8,
+#if defined(CRYPTO_BACKEND_BOTAN)
+ "secp256r1",
+#elif defined(CRYPTO_BACKEND_OPENSSL)
+ "prime256v1",
+#endif
+ "NIST P-256",
+ true,
+ "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+ "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
+ "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
+ "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+ "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
+ "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
+ "0x01"},
+ {PGP_CURVE_NIST_P_384,
+ 384,
+ {0x2B, 0x81, 0x04, 0x00, 0x22},
+ 5,
+#if defined(CRYPTO_BACKEND_BOTAN)
+ "secp384r1",
+#elif defined(CRYPTO_BACKEND_OPENSSL)
+ "secp384r1",
+#endif
+ "NIST P-384",
+ true,
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000"
+ "ffffffff",
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000"
+ "fffffffc",
+ "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8ed"
+ "d3ec2aef",
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196a"
+ "ccc52973",
+ "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e38"
+ "72760ab7",
+ "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c"
+ "90ea0e5f",
+ "0x01"},
+ {PGP_CURVE_NIST_P_521,
+ 521,
+ {0x2B, 0x81, 0x04, 0x00, 0x23},
+ 5,
+#if defined(CRYPTO_BACKEND_BOTAN)
+ "secp521r1",
+#elif defined(CRYPTO_BACKEND_OPENSSL)
+ "secp521r1",
+#endif
+ "NIST P-521",
+ true,
+ "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "ffffffffffffffffffffffffffffffffffffffffffff",
+ "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffffffffffffffffffffffffffffffffffffffffffc",
+ "0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652"
+ "c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
+ "0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc"
+ "0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+ "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1d"
+ "c127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
+ "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550"
+ "b9013fad0761353c7086a272c24088be94769fd16650",
+ "0x01"},
+ {PGP_CURVE_ED25519,
+ 255,
+ {0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01},
+ 9,
+#if defined(CRYPTO_BACKEND_BOTAN)
+ "Ed25519",
+#elif defined(CRYPTO_BACKEND_OPENSSL)
+ "ED25519",
+#endif
+ "Ed25519",
+ true,
+ "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed",
+ /* two below are actually negative */
+ "0x01",
+ "0x2dfc9311d490018c7338bf8688861767ff8ff5b2bebe27548a14b235eca6874a",
+ "0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed",
+ "0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a",
+ "0x6666666666666666666666666666666666666666666666666666666666666658",
+ "0x08"},
+ {PGP_CURVE_25519,
+ 255,
+ {0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01},
+ 10,
+#if defined(CRYPTO_BACKEND_BOTAN)
+ "curve25519",
+#elif defined(CRYPTO_BACKEND_OPENSSL)
+ "X25519",
+#endif
+ "Curve25519",
+ true,
+ "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed",
+ "0x01db41",
+ "0x01",
+ "0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed",
+ "0x0000000000000000000000000000000000000000000000000000000000000009",
+ "0x20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9",
+ "0x08"},
+ {PGP_CURVE_BP256,
+ 256,
+ {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07},
+ 9,
+#if defined(CRYPTO_BACKEND_BOTAN)
+ "brainpool256r1",
+#elif defined(CRYPTO_BACKEND_OPENSSL)
+ "brainpoolP256r1",
+#endif
+ "brainpoolP256r1",
+#if defined(ENABLE_BRAINPOOL)
+ true,
+#else
+ false,
+#endif
+ "0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377",
+ "0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9",
+ "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6",
+ "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7",
+ "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262",
+ "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997",
+ "0x01"},
+ {PGP_CURVE_BP384,
+ 384,
+ {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B},
+ 9,
+#if defined(CRYPTO_BACKEND_BOTAN)
+ "brainpool384r1",
+#elif defined(CRYPTO_BACKEND_OPENSSL)
+ "brainpoolP384r1",
+#endif
+ "brainpoolP384r1",
+#if defined(ENABLE_BRAINPOOL)
+ true,
+#else
+ false,
+#endif
+ "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a7187470013"
+ "3107ec53",
+ "0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f8aa5814a503ad4eb04a8c7dd"
+ "22ce2826",
+ "0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d57cb4390295dbc9943ab78696"
+ "fa504c11",
+ "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7cf3ab6af6b7fc3103b883202"
+ "e9046565",
+ "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8e826e03436d646aaef87b2e2"
+ "47d4af1e",
+ "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff99129280e4646217791811142820341"
+ "263c5315",
+ "0x01"},
+ {PGP_CURVE_BP512,
+ 512,
+ {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D},
+ 9,
+#if defined(CRYPTO_BACKEND_BOTAN)
+ "brainpool512r1",
+#elif defined(CRYPTO_BACKEND_OPENSSL)
+ "brainpoolP512r1",
+#endif
+ "brainpoolP512r1",
+#if defined(ENABLE_BRAINPOOL)
+ true,
+#else
+ false,
+#endif
+ "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12a"
+ "e6a380e62881ff2f2d82c68528aa6056583a48f3",
+ "0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c9"
+ "8b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca",
+ "0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca"
+ "dc083e67984050b75ebae5dd2809bd638016f723",
+ "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870553e5c414ca9261941866119"
+ "7fac10471db1d381085ddaddb58796829ca90069",
+ "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098eff3b1f78e2d0d48d50d1687b"
+ "93b97d5f7c6d5047406a5e688b352209bcb9f822",
+ "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111b2dcde494a5f485e5bca4bd8"
+ "8a2763aed1ca2b2fa8f0540678cd1e0f3ad80892",
+ "0x01"},
+ {PGP_CURVE_P256K1,
+ 256,
+ {0x2B, 0x81, 0x04, 0x00, 0x0A},
+ 5,
+#if defined(CRYPTO_BACKEND_BOTAN)
+ "secp256k1",
+#elif defined(CRYPTO_BACKEND_OPENSSL)
+ "secp256k1",
+#endif
+ "secp256k1",
+ true,
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000007",
+ "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
+ "0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
+ "0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
+ "0x01"},
+ {
+ PGP_CURVE_SM2_P_256,
+ 256,
+ {0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D},
+ 8,
+#if defined(CRYPTO_BACKEND_BOTAN)
+ "sm2p256v1",
+#elif defined(CRYPTO_BACKEND_OPENSSL)
+ "sm2",
+#endif
+ "SM2 P-256",
+#if defined(ENABLE_SM2)
+ true,
+#else
+ false,
+#endif
+ "0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",
+ "0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",
+ "0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",
+ "0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",
+ "0x32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",
+ "0xBC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0",
+ },
+};
+
+pgp_curve_t
+find_curve_by_OID(const uint8_t *oid, size_t oid_len)
+{
+ for (size_t i = 0; i < PGP_CURVE_MAX; i++) {
+ if ((oid_len == ec_curves[i].OIDhex_len) &&
+ (!memcmp(oid, ec_curves[i].OIDhex, oid_len))) {
+ return static_cast<pgp_curve_t>(i);
+ }
+ }
+
+ return PGP_CURVE_MAX;
+}
+
+pgp_curve_t
+find_curve_by_name(const char *name)
+{
+ for (size_t i = 1; i < PGP_CURVE_MAX; i++) {
+ if (rnp::str_case_eq(ec_curves[i].pgp_name, name)) {
+ return ec_curves[i].rnp_curve_id;
+ }
+ }
+
+ return PGP_CURVE_MAX;
+}
+
+const ec_curve_desc_t *
+get_curve_desc(const pgp_curve_t curve_id)
+{
+ return (curve_id < PGP_CURVE_MAX && curve_id > 0) ? &ec_curves[curve_id] : NULL;
+}
+
+bool
+alg_allows_curve(pgp_pubkey_alg_t alg, pgp_curve_t curve)
+{
+ /* SM2 curve is only for SM2 algo */
+ if ((alg == PGP_PKA_SM2) || (curve == PGP_CURVE_SM2_P_256)) {
+ return (alg == PGP_PKA_SM2) && (curve == PGP_CURVE_SM2_P_256);
+ }
+ /* EDDSA and PGP_CURVE_ED25519 */
+ if ((alg == PGP_PKA_EDDSA) || (curve == PGP_CURVE_ED25519)) {
+ return (alg == PGP_PKA_EDDSA) && (curve == PGP_CURVE_ED25519);
+ }
+ /* Curve x25519 is only for ECDH */
+ if (curve == PGP_CURVE_25519) {
+ return alg == PGP_PKA_ECDH;
+ }
+ /* Other curves are good for both ECDH and ECDSA */
+ return true;
+}
+
+bool
+curve_supported(pgp_curve_t curve)
+{
+ const ec_curve_desc_t *info = get_curve_desc(curve);
+ return info && info->supported;
+}