/* * 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 #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(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; }