1 /* 2 * Copyright (C) 2017 - This file is part of libecc project 3 * 4 * Authors: 5 * Ryad BENADJILA <ryadbenadjila@gmail.com> 6 * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr> 7 * Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr> 8 * 9 * Contributors: 10 * Nicolas VIVET <nicolas.vivet@ssi.gouv.fr> 11 * Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr> 12 * 13 * This software is licensed under a dual BSD and GPL v2 license. 14 * See LICENSE file at the root folder of the project. 15 */ 16 #ifndef __EC_KEY_H__ 17 #define __EC_KEY_H__ 18 19 #include <libecc/lib_ecc_config.h> 20 #include <libecc/lib_ecc_types.h> 21 #include <libecc/fp/fp.h> 22 #include <libecc/curves/ec_params.h> 23 #include <libecc/nn/nn_rand.h> 24 #include <libecc/nn/nn_add.h> 25 #include <libecc/nn/nn_logical.h> 26 #include <libecc/curves/prj_pt.h> 27 #include <libecc/hash/hash_algs.h> 28 29 /* Enum for exported keys */ 30 typedef enum { 31 EC_PUBKEY = 0, 32 EC_PRIVKEY = 1, 33 } ec_key_type; 34 35 /* 36 * Declarations for EC private keys 37 */ 38 39 #define PRIV_KEY_MAGIC ((word_t)(0x2feb91e938a4855dULL)) 40 typedef struct { 41 /* A key type can only be used for a given sig alg */ 42 ec_alg_type key_type; 43 44 /* Elliptic curve parameters */ 45 const ec_params *params; 46 47 /* 48 * Private key (usually an integer in ]0,q[, where q is 49 * the order of G, the generator of the group 50 * on the curve, or a derivative of this). 51 * 52 * For the specific case of EdDSA, this value will instead hold the 53 * digest derivation of the secret value sk that is twice the size of 54 * the digest size. 55 */ 56 nn x; 57 58 word_t magic; 59 } ec_priv_key; 60 61 /* NOTE1: in the specific case of EdDSA, the hash size dictates the size of the 62 * private keys. Although EdDSA only uses specific hash algorithms, we are being 63 * conservative here by taking the maximum digest size (hence accepting losing some space 64 * wen storing the private key for more simplicity). 65 * 66 * NOTE2: we use MAX_DIGEST_SIZE as the basis for EdDSA private key size instead of 67 * (MAX_DIGEST_SIZE / 2) because we store the EdDSA private key in its *derived* formed, 68 * meaning that it is twice the size of a regular standardized private key. 69 * 70 */ 71 #if defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_EDDSA448) 72 73 #define EC_PRIV_KEY_MAX_SIZE (LOCAL_MAX(MAX_DIGEST_SIZE, LOCAL_MAX(BYTECEIL(CURVES_MAX_Q_BIT_LEN), BYTECEIL(CURVES_MAX_P_BIT_LEN)))) 74 75 #define EC_PRIV_KEY_EXPORT_SIZE(priv_key) \ 76 ((u8)(LOCAL_MAX(MAX_DIGEST_SIZE, LOCAL_MAX(BYTECEIL((priv_key)->params->ec_gen_order_bitlen), BYTECEIL((priv_key)->params->ec_fp.p_bitlen))))) 77 78 #else /* !(defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_EDDSA448)) */ 79 80 #define EC_PRIV_KEY_MAX_SIZE (LOCAL_MAX(BYTECEIL(CURVES_MAX_Q_BIT_LEN), BYTECEIL(CURVES_MAX_P_BIT_LEN))) 81 82 #define EC_PRIV_KEY_EXPORT_SIZE(priv_key) \ 83 ((u8)(LOCAL_MAX(BYTECEIL((priv_key)->params->ec_gen_order_bitlen), BYTECEIL((priv_key)->params->ec_fp.p_bitlen)))) 84 85 #endif /* defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_EDDSA448) */ 86 87 #define EC_STRUCTURED_PRIV_KEY_MAX_EXPORT_SIZE (EC_PRIV_KEY_MAX_SIZE + 3) 88 #if (EC_STRUCTURED_PRIV_KEY_MAX_EXPORT_SIZE > 255) 89 #error "All structured priv keys size are expected to fit on an u8." 90 #endif 91 92 #define EC_STRUCTURED_PRIV_KEY_EXPORT_SIZE(priv_key) \ 93 ((u8)(EC_PRIV_KEY_EXPORT_SIZE(priv_key) + (3 * sizeof(u8)))) 94 95 ATTRIBUTE_WARN_UNUSED_RET int priv_key_check_initialized(const ec_priv_key *A); 96 ATTRIBUTE_WARN_UNUSED_RET int priv_key_check_initialized_and_type(const ec_priv_key *A, 97 ec_alg_type sig_type); 98 99 ATTRIBUTE_WARN_UNUSED_RET int ec_priv_key_import_from_buf(ec_priv_key *priv_key, 100 const ec_params *params, 101 const u8 *priv_key_buf, u8 priv_key_buf_len, 102 ec_alg_type ec_key_alg); 103 ATTRIBUTE_WARN_UNUSED_RET int ec_priv_key_export_to_buf(const ec_priv_key *priv_key, u8 *priv_key_buf, 104 u8 priv_key_buf_len); 105 106 ATTRIBUTE_WARN_UNUSED_RET int ec_structured_priv_key_import_from_buf(ec_priv_key *priv_key, 107 const ec_params *params, 108 const u8 *priv_key_buf, 109 u8 priv_key_buf_len, 110 ec_alg_type ec_key_alg); 111 ATTRIBUTE_WARN_UNUSED_RET int ec_structured_priv_key_export_to_buf(const ec_priv_key *priv_key, 112 u8 *priv_key_buf, 113 u8 priv_key_buf_len); 114 115 /* 116 * Declarations for EC public keys 117 */ 118 119 #define PUB_KEY_MAGIC ((word_t)(0x31327f37741ffb76ULL)) 120 typedef struct { 121 /* A key type can only be used for a given sig alg */ 122 ec_alg_type key_type; 123 124 /* Elliptic curve parameters */ 125 const ec_params *params; 126 127 /* Public key, i.e. y = xG mod p */ 128 prj_pt y; 129 130 word_t magic; 131 } ec_pub_key; 132 133 #define EC_PUB_KEY_MAX_SIZE (3 * BYTECEIL(CURVES_MAX_P_BIT_LEN)) 134 135 #define EC_PUB_KEY_EXPORT_SIZE(pub_key) \ 136 (3 * BYTECEIL((pub_key)->params->ec_curve.a.ctx->p_bitlen)) 137 138 #define EC_STRUCTURED_PUB_KEY_MAX_EXPORT_SIZE (EC_PUB_KEY_MAX_SIZE + 3) 139 #if (EC_STRUCTURED_PUB_KEY_MAX_EXPORT_SIZE > 255) 140 #error "All structured pub keys size are expected to fit on an u8." 141 #endif 142 #define EC_STRUCTURED_PUB_KEY_EXPORT_SIZE(pub_key) \ 143 ((u8)(EC_PUB_KEY_EXPORT_SIZE(pub_key) + (u8)(3 * sizeof(u8)))) 144 145 ATTRIBUTE_WARN_UNUSED_RET int pub_key_check_initialized(const ec_pub_key *A); 146 ATTRIBUTE_WARN_UNUSED_RET int pub_key_check_initialized_and_type(const ec_pub_key *A, 147 ec_alg_type sig_type); 148 149 ATTRIBUTE_WARN_UNUSED_RET int ec_pub_key_import_from_buf(ec_pub_key *pub_key, const ec_params *params, 150 const u8 *pub_key_buf, u8 pub_key_buf_len, 151 ec_alg_type ec_key_alg); 152 ATTRIBUTE_WARN_UNUSED_RET int ec_pub_key_export_to_buf(const ec_pub_key *pub_key, u8 *pub_key_buf, 153 u8 pub_key_buf_len); 154 155 ATTRIBUTE_WARN_UNUSED_RET int ec_pub_key_import_from_aff_buf(ec_pub_key *pub_key, const ec_params *params, 156 const u8 *pub_key_buf, u8 pub_key_buf_len, 157 ec_alg_type ec_key_alg); 158 159 ATTRIBUTE_WARN_UNUSED_RET int ec_pub_key_export_to_aff_buf(const ec_pub_key *pub_key, u8 *pub_key_buf, 160 u8 pub_key_buf_len); 161 162 ATTRIBUTE_WARN_UNUSED_RET int ec_structured_pub_key_import_from_buf(ec_pub_key *pub_key, 163 const ec_params *params, 164 const u8 *pub_key_buf, 165 u8 pub_key_buf_len, 166 ec_alg_type ec_key_alg); 167 ATTRIBUTE_WARN_UNUSED_RET int ec_structured_pub_key_export_to_buf(const ec_pub_key *pub_key, 168 u8 *pub_key_buf, u8 pub_key_buf_len); 169 170 /* 171 * Declarations for EC key pairs 172 */ 173 174 typedef struct { 175 ec_priv_key priv_key; 176 ec_pub_key pub_key; 177 } ec_key_pair; 178 179 ATTRIBUTE_WARN_UNUSED_RET int key_pair_check_initialized(const ec_key_pair *A); 180 181 ATTRIBUTE_WARN_UNUSED_RET int key_pair_check_initialized_and_type(const ec_key_pair *A, 182 ec_alg_type sig_type); 183 184 ATTRIBUTE_WARN_UNUSED_RET int ec_key_pair_import_from_priv_key_buf(ec_key_pair *kp, 185 const ec_params *params, 186 const u8 *priv_key, u8 priv_key_len, 187 ec_alg_type ec_key_alg); 188 ATTRIBUTE_WARN_UNUSED_RET int ec_key_pair_gen(ec_key_pair *kp, const ec_params *params, 189 ec_alg_type ec_key_alg); 190 191 ATTRIBUTE_WARN_UNUSED_RET int ec_structured_key_pair_import_from_priv_key_buf(ec_key_pair *kp, 192 const ec_params *params, 193 const u8 *priv_key_buf, 194 u8 priv_key_buf_len, 195 ec_alg_type ec_key_alg); 196 /* 197 * NOTE: please use the following API with care as it does not check the consistency 198 * between the private and public keys! On one side, this "saves" a costly 199 * scalar multiplication when there is confidence in the source of the buffers, 200 * but on the other side the user of the API MUST check the source (integrity) 201 * of the private/public key pair. If unsure, it is advised to use the 202 * ec_structured_key_pair_import_from_priv_key_buf API that safely derives the 203 * public key from the private key. 204 * 205 */ 206 ATTRIBUTE_WARN_UNUSED_RET int ec_structured_key_pair_import_from_buf(ec_key_pair *kp, 207 const ec_params *params, 208 const u8 *priv_key_buf, 209 u8 priv_key_buf_len, 210 const u8 *pub_key_buf, 211 u8 pub_key_buf_len, 212 ec_alg_type ec_key_alg); 213 214 ATTRIBUTE_WARN_UNUSED_RET int generic_gen_priv_key(ec_priv_key *priv_key); 215 216 217 /* Type used for batch verification */ 218 typedef struct { 219 nn number; 220 prj_pt point; 221 u32 index; 222 } verify_batch_scratch_pad; 223 224 #endif /* __EC_KEY_H__ */ 225