1*f0865ec9SKyle Evans /* 2*f0865ec9SKyle Evans * Copyright (C) 2017 - This file is part of libecc project 3*f0865ec9SKyle Evans * 4*f0865ec9SKyle Evans * Authors: 5*f0865ec9SKyle Evans * Ryad BENADJILA <ryadbenadjila@gmail.com> 6*f0865ec9SKyle Evans * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr> 7*f0865ec9SKyle Evans * Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr> 8*f0865ec9SKyle Evans * 9*f0865ec9SKyle Evans * Contributors: 10*f0865ec9SKyle Evans * Nicolas VIVET <nicolas.vivet@ssi.gouv.fr> 11*f0865ec9SKyle Evans * Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr> 12*f0865ec9SKyle Evans * 13*f0865ec9SKyle Evans * This software is licensed under a dual BSD and GPL v2 license. 14*f0865ec9SKyle Evans * See LICENSE file at the root folder of the project. 15*f0865ec9SKyle Evans */ 16*f0865ec9SKyle Evans #include <libecc/sig/ec_key.h> 17*f0865ec9SKyle Evans #include <libecc/sig/sig_algs.h> 18*f0865ec9SKyle Evans #include <libecc/curves/curves.h> 19*f0865ec9SKyle Evans 20*f0865ec9SKyle Evans /* 21*f0865ec9SKyle Evans * Check if given private key 'A' has been initialized. Returns 0 on success, 22*f0865ec9SKyle Evans * -1 on error 23*f0865ec9SKyle Evans */ 24*f0865ec9SKyle Evans int priv_key_check_initialized(const ec_priv_key *A) 25*f0865ec9SKyle Evans { 26*f0865ec9SKyle Evans int ret = 0; 27*f0865ec9SKyle Evans 28*f0865ec9SKyle Evans MUST_HAVE(((A != NULL) && (A->magic == PRIV_KEY_MAGIC) && (A->params != NULL)), ret, err); 29*f0865ec9SKyle Evans 30*f0865ec9SKyle Evans err: 31*f0865ec9SKyle Evans return ret; 32*f0865ec9SKyle Evans } 33*f0865ec9SKyle Evans 34*f0865ec9SKyle Evans /* 35*f0865ec9SKyle Evans * Same as previous but also verifies that the signature algorithm type does 36*f0865ec9SKyle Evans * match the one passed using 'alg_type'. Returns 0 on success, -1 on error. 37*f0865ec9SKyle Evans */ 38*f0865ec9SKyle Evans int priv_key_check_initialized_and_type(const ec_priv_key *A, 39*f0865ec9SKyle Evans ec_alg_type alg_type) 40*f0865ec9SKyle Evans { 41*f0865ec9SKyle Evans int ret = 0; 42*f0865ec9SKyle Evans 43*f0865ec9SKyle Evans MUST_HAVE(((A != NULL) && (A->magic == PRIV_KEY_MAGIC) && 44*f0865ec9SKyle Evans (A->params != NULL) && (A->key_type == alg_type)), ret, err); 45*f0865ec9SKyle Evans 46*f0865ec9SKyle Evans err: 47*f0865ec9SKyle Evans return ret; 48*f0865ec9SKyle Evans } 49*f0865ec9SKyle Evans 50*f0865ec9SKyle Evans /* 51*f0865ec9SKyle Evans * Import a private key from a buffer with known EC parameters and algorithm 52*f0865ec9SKyle Evans * Note that no sanity check is performed by the function to verify key 53*f0865ec9SKyle Evans * is valid for params. Also note that no deep copy of pointed params is 54*f0865ec9SKyle Evans * performed. The function returns 0 on success, -1 on error. 55*f0865ec9SKyle Evans */ 56*f0865ec9SKyle Evans int ec_priv_key_import_from_buf(ec_priv_key *priv_key, 57*f0865ec9SKyle Evans const ec_params *params, 58*f0865ec9SKyle Evans const u8 *priv_key_buf, u8 priv_key_buf_len, 59*f0865ec9SKyle Evans ec_alg_type ec_key_alg) 60*f0865ec9SKyle Evans { 61*f0865ec9SKyle Evans int ret; 62*f0865ec9SKyle Evans 63*f0865ec9SKyle Evans MUST_HAVE((priv_key != NULL), ret, err); 64*f0865ec9SKyle Evans 65*f0865ec9SKyle Evans ret = nn_init_from_buf(&(priv_key->x), priv_key_buf, priv_key_buf_len); EG(ret, err); 66*f0865ec9SKyle Evans 67*f0865ec9SKyle Evans /* Set key type and pointer to EC params */ 68*f0865ec9SKyle Evans priv_key->key_type = ec_key_alg; 69*f0865ec9SKyle Evans priv_key->params = (const ec_params *)params; 70*f0865ec9SKyle Evans priv_key->magic = PRIV_KEY_MAGIC; 71*f0865ec9SKyle Evans 72*f0865ec9SKyle Evans err: 73*f0865ec9SKyle Evans return ret; 74*f0865ec9SKyle Evans } 75*f0865ec9SKyle Evans 76*f0865ec9SKyle Evans /* 77*f0865ec9SKyle Evans * Export a private key 'priv_key' to a buffer 'priv_key_buf' of length 78*f0865ec9SKyle Evans * 'priv_key_buf_len'. The function returns 0 on sucess, -1 on error. 79*f0865ec9SKyle Evans */ 80*f0865ec9SKyle Evans int ec_priv_key_export_to_buf(const ec_priv_key *priv_key, u8 *priv_key_buf, 81*f0865ec9SKyle Evans u8 priv_key_buf_len) 82*f0865ec9SKyle Evans { 83*f0865ec9SKyle Evans int ret; 84*f0865ec9SKyle Evans bitcnt_t blen; 85*f0865ec9SKyle Evans 86*f0865ec9SKyle Evans ret = priv_key_check_initialized(priv_key); EG(ret, err); 87*f0865ec9SKyle Evans 88*f0865ec9SKyle Evans /* 89*f0865ec9SKyle Evans * Check that there is enough room to export our private key without 90*f0865ec9SKyle Evans * losing information. 91*f0865ec9SKyle Evans */ 92*f0865ec9SKyle Evans ret = nn_bitlen(&(priv_key->x), &blen); EG(ret, err); 93*f0865ec9SKyle Evans MUST_HAVE(((8 * (u32)priv_key_buf_len) >= (u32)blen), ret, err); 94*f0865ec9SKyle Evans 95*f0865ec9SKyle Evans /* Export our private key */ 96*f0865ec9SKyle Evans ret = nn_export_to_buf(priv_key_buf, priv_key_buf_len, &(priv_key->x)); 97*f0865ec9SKyle Evans 98*f0865ec9SKyle Evans err: 99*f0865ec9SKyle Evans return ret; 100*f0865ec9SKyle Evans } 101*f0865ec9SKyle Evans 102*f0865ec9SKyle Evans /* 103*f0865ec9SKyle Evans * Check if given public key 'A' has been initialized. Returns 0 on success, 104*f0865ec9SKyle Evans * -1 on error 105*f0865ec9SKyle Evans */ 106*f0865ec9SKyle Evans int pub_key_check_initialized(const ec_pub_key *A) 107*f0865ec9SKyle Evans { 108*f0865ec9SKyle Evans int ret = 0; 109*f0865ec9SKyle Evans 110*f0865ec9SKyle Evans MUST_HAVE(((A != NULL) && (A->magic == PUB_KEY_MAGIC) && (A->params != NULL)), ret, err); 111*f0865ec9SKyle Evans 112*f0865ec9SKyle Evans err: 113*f0865ec9SKyle Evans return ret; 114*f0865ec9SKyle Evans } 115*f0865ec9SKyle Evans 116*f0865ec9SKyle Evans /* 117*f0865ec9SKyle Evans * Same as previous but also verifies that the signature algorithm type does 118*f0865ec9SKyle Evans * match the one passed using 'alg_type'. Returns 0 on success, -1 on error. 119*f0865ec9SKyle Evans */ 120*f0865ec9SKyle Evans int pub_key_check_initialized_and_type(const ec_pub_key *A, 121*f0865ec9SKyle Evans ec_alg_type alg_type) 122*f0865ec9SKyle Evans { 123*f0865ec9SKyle Evans int ret = 0; 124*f0865ec9SKyle Evans 125*f0865ec9SKyle Evans MUST_HAVE(((A != NULL) && (A->magic == PUB_KEY_MAGIC) && 126*f0865ec9SKyle Evans (A->params != NULL) && (A->key_type == alg_type)), ret, err); 127*f0865ec9SKyle Evans 128*f0865ec9SKyle Evans err: 129*f0865ec9SKyle Evans return ret; 130*f0865ec9SKyle Evans } 131*f0865ec9SKyle Evans 132*f0865ec9SKyle Evans /* 133*f0865ec9SKyle Evans * Import a public key from a buffer with known EC parameters and algorithm 134*f0865ec9SKyle Evans * Note that no sanity check is performed by the function to verify key 135*f0865ec9SKyle Evans * is valid for params. Also note that no deep copy of pointed params is 136*f0865ec9SKyle Evans * performed. The buffer contains projective point coordinates. The function 137*f0865ec9SKyle Evans * returns 0 on success, -1 on error. 138*f0865ec9SKyle Evans */ 139*f0865ec9SKyle Evans int ec_pub_key_import_from_buf(ec_pub_key *pub_key, const ec_params *params, 140*f0865ec9SKyle Evans const u8 *pub_key_buf, u8 pub_key_buf_len, 141*f0865ec9SKyle Evans ec_alg_type ec_key_alg) 142*f0865ec9SKyle Evans { 143*f0865ec9SKyle Evans int ret, isone, check; 144*f0865ec9SKyle Evans 145*f0865ec9SKyle Evans MUST_HAVE(((pub_key != NULL) && (pub_key_buf != NULL) && (params != NULL)), ret, err); 146*f0865ec9SKyle Evans 147*f0865ec9SKyle Evans /* Import the projective point */ 148*f0865ec9SKyle Evans ret = prj_pt_import_from_buf(&(pub_key->y), 149*f0865ec9SKyle Evans pub_key_buf, pub_key_buf_len, 150*f0865ec9SKyle Evans (ec_shortw_crv_src_t)&(params->ec_curve)); EG(ret, err); 151*f0865ec9SKyle Evans 152*f0865ec9SKyle Evans /* If the cofactor of the curve is not 1, we check that 153*f0865ec9SKyle Evans * our public key is indeed in the sub-group generated by 154*f0865ec9SKyle Evans * our generator. 155*f0865ec9SKyle Evans * NOTE: this is indeed a 'costly' operation, but it is necessary 156*f0865ec9SKyle Evans * when we do not trust the public key that is provided, which can 157*f0865ec9SKyle Evans * be the case in some protocols. 158*f0865ec9SKyle Evans */ 159*f0865ec9SKyle Evans ret = nn_isone(&(params->ec_gen_cofactor), &isone); EG(ret, err); 160*f0865ec9SKyle Evans if (!isone) { 161*f0865ec9SKyle Evans ret = check_prj_pt_order(&(pub_key->y), &(params->ec_gen_order), PUBLIC_PT, &check); EG(ret, err); 162*f0865ec9SKyle Evans MUST_HAVE(check, ret, err); 163*f0865ec9SKyle Evans } 164*f0865ec9SKyle Evans 165*f0865ec9SKyle Evans /* Set key type and pointer to EC params */ 166*f0865ec9SKyle Evans pub_key->key_type = ec_key_alg; 167*f0865ec9SKyle Evans pub_key->params = (const ec_params *)params; 168*f0865ec9SKyle Evans pub_key->magic = PUB_KEY_MAGIC; 169*f0865ec9SKyle Evans 170*f0865ec9SKyle Evans err: 171*f0865ec9SKyle Evans return ret; 172*f0865ec9SKyle Evans } 173*f0865ec9SKyle Evans 174*f0865ec9SKyle Evans /* 175*f0865ec9SKyle Evans * Import a public key from a buffer with known EC parameters and algorithm 176*f0865ec9SKyle Evans * Note that no sanity check is performed by the function to verify key 177*f0865ec9SKyle Evans * is valid for params. Also note that no deep copy of pointed params is 178*f0865ec9SKyle Evans * performed. The buffer contains affine point coordinates. The function 179*f0865ec9SKyle Evans * returns 0 on success, -1 on error. 180*f0865ec9SKyle Evans */ 181*f0865ec9SKyle Evans int ec_pub_key_import_from_aff_buf(ec_pub_key *pub_key, const ec_params *params, 182*f0865ec9SKyle Evans const u8 *pub_key_buf, u8 pub_key_buf_len, 183*f0865ec9SKyle Evans ec_alg_type ec_key_alg) 184*f0865ec9SKyle Evans { 185*f0865ec9SKyle Evans int ret, isone, check; 186*f0865ec9SKyle Evans 187*f0865ec9SKyle Evans MUST_HAVE(((pub_key != NULL) && (pub_key_buf != NULL) && (params != NULL)), ret, err); 188*f0865ec9SKyle Evans 189*f0865ec9SKyle Evans /* Import the projective point */ 190*f0865ec9SKyle Evans ret = prj_pt_import_from_aff_buf(&(pub_key->y), 191*f0865ec9SKyle Evans pub_key_buf, pub_key_buf_len, 192*f0865ec9SKyle Evans (ec_shortw_crv_src_t)&(params->ec_curve)); EG(ret, err); 193*f0865ec9SKyle Evans 194*f0865ec9SKyle Evans /* If the cofactor of the curve is not 1, we check that 195*f0865ec9SKyle Evans * our public key is indeed in the sub-group generated by 196*f0865ec9SKyle Evans * our generator. 197*f0865ec9SKyle Evans * NOTE: this is indeed a 'costly' operation, but it is necessary 198*f0865ec9SKyle Evans * when we do not trust the public key that is provided, which can 199*f0865ec9SKyle Evans * be the case in some protocols. 200*f0865ec9SKyle Evans */ 201*f0865ec9SKyle Evans ret = nn_isone(&(params->ec_gen_cofactor), &isone); EG(ret, err); 202*f0865ec9SKyle Evans if (!isone){ 203*f0865ec9SKyle Evans ret = check_prj_pt_order(&(pub_key->y), &(params->ec_gen_order), PUBLIC_PT, &check); EG(ret, err); 204*f0865ec9SKyle Evans MUST_HAVE(check, ret, err); 205*f0865ec9SKyle Evans } 206*f0865ec9SKyle Evans 207*f0865ec9SKyle Evans /* Set key type and pointer to EC params */ 208*f0865ec9SKyle Evans pub_key->key_type = ec_key_alg; 209*f0865ec9SKyle Evans pub_key->params = (const ec_params *)params; 210*f0865ec9SKyle Evans pub_key->magic = PUB_KEY_MAGIC; 211*f0865ec9SKyle Evans 212*f0865ec9SKyle Evans err: 213*f0865ec9SKyle Evans return ret; 214*f0865ec9SKyle Evans } 215*f0865ec9SKyle Evans 216*f0865ec9SKyle Evans /* 217*f0865ec9SKyle Evans * Export a public key to a projective point buffer. The function returns 0 on 218*f0865ec9SKyle Evans * success, -1 on error. 219*f0865ec9SKyle Evans */ 220*f0865ec9SKyle Evans int ec_pub_key_export_to_buf(const ec_pub_key *pub_key, u8 *pub_key_buf, 221*f0865ec9SKyle Evans u8 pub_key_buf_len) 222*f0865ec9SKyle Evans { 223*f0865ec9SKyle Evans int ret; 224*f0865ec9SKyle Evans 225*f0865ec9SKyle Evans ret = pub_key_check_initialized(pub_key); EG(ret, err); 226*f0865ec9SKyle Evans ret = prj_pt_export_to_buf(&(pub_key->y), pub_key_buf, pub_key_buf_len); 227*f0865ec9SKyle Evans 228*f0865ec9SKyle Evans err: 229*f0865ec9SKyle Evans return ret; 230*f0865ec9SKyle Evans } 231*f0865ec9SKyle Evans 232*f0865ec9SKyle Evans /* 233*f0865ec9SKyle Evans * Export a public key to an affine point buffer. The function returns 0 on 234*f0865ec9SKyle Evans * success, -1 on error. 235*f0865ec9SKyle Evans */ 236*f0865ec9SKyle Evans int ec_pub_key_export_to_aff_buf(const ec_pub_key *pub_key, u8 *pub_key_buf, 237*f0865ec9SKyle Evans u8 pub_key_buf_len) 238*f0865ec9SKyle Evans { 239*f0865ec9SKyle Evans int ret; 240*f0865ec9SKyle Evans 241*f0865ec9SKyle Evans ret = pub_key_check_initialized(pub_key); EG(ret, err); 242*f0865ec9SKyle Evans ret = prj_pt_export_to_aff_buf(&(pub_key->y), pub_key_buf, 243*f0865ec9SKyle Evans pub_key_buf_len); 244*f0865ec9SKyle Evans 245*f0865ec9SKyle Evans err: 246*f0865ec9SKyle Evans return ret; 247*f0865ec9SKyle Evans } 248*f0865ec9SKyle Evans 249*f0865ec9SKyle Evans /* 250*f0865ec9SKyle Evans * Check if given key pair 'A' has been initialized. Returns 0 on success, 251*f0865ec9SKyle Evans * -1 on error 252*f0865ec9SKyle Evans */ 253*f0865ec9SKyle Evans int key_pair_check_initialized(const ec_key_pair *A) 254*f0865ec9SKyle Evans { 255*f0865ec9SKyle Evans int ret; 256*f0865ec9SKyle Evans 257*f0865ec9SKyle Evans MUST_HAVE((A != NULL), ret, err); 258*f0865ec9SKyle Evans 259*f0865ec9SKyle Evans ret = priv_key_check_initialized(&A->priv_key); EG(ret, err); 260*f0865ec9SKyle Evans ret = pub_key_check_initialized(&A->pub_key); 261*f0865ec9SKyle Evans 262*f0865ec9SKyle Evans err: 263*f0865ec9SKyle Evans return ret; 264*f0865ec9SKyle Evans } 265*f0865ec9SKyle Evans 266*f0865ec9SKyle Evans /* 267*f0865ec9SKyle Evans * Same as previous but also verifies that the signature algorithm type does 268*f0865ec9SKyle Evans * match the one passed using 'alg_type'. Returns 0 on success, -1 on error. 269*f0865ec9SKyle Evans */ 270*f0865ec9SKyle Evans int key_pair_check_initialized_and_type(const ec_key_pair *A, 271*f0865ec9SKyle Evans ec_alg_type alg_type) 272*f0865ec9SKyle Evans { 273*f0865ec9SKyle Evans int ret; 274*f0865ec9SKyle Evans 275*f0865ec9SKyle Evans MUST_HAVE((A != NULL), ret, err); 276*f0865ec9SKyle Evans 277*f0865ec9SKyle Evans ret = priv_key_check_initialized_and_type(&A->priv_key, alg_type); EG(ret, err); 278*f0865ec9SKyle Evans ret = pub_key_check_initialized_and_type(&A->pub_key, alg_type); 279*f0865ec9SKyle Evans 280*f0865ec9SKyle Evans err: 281*f0865ec9SKyle Evans return ret; 282*f0865ec9SKyle Evans } 283*f0865ec9SKyle Evans 284*f0865ec9SKyle Evans /* 285*f0865ec9SKyle Evans * Import a key pair from a buffer representing the private key. The associated 286*f0865ec9SKyle Evans * public key is computed from the private key. The function returns 0 on 287*f0865ec9SKyle Evans * success, -1 on error. 288*f0865ec9SKyle Evans */ 289*f0865ec9SKyle Evans int ec_key_pair_import_from_priv_key_buf(ec_key_pair *kp, 290*f0865ec9SKyle Evans const ec_params *params, 291*f0865ec9SKyle Evans const u8 *priv_key, u8 priv_key_len, 292*f0865ec9SKyle Evans ec_alg_type ec_key_alg) 293*f0865ec9SKyle Evans { 294*f0865ec9SKyle Evans int ret; 295*f0865ec9SKyle Evans 296*f0865ec9SKyle Evans MUST_HAVE((kp != NULL), ret, err); 297*f0865ec9SKyle Evans 298*f0865ec9SKyle Evans /* Import private key */ 299*f0865ec9SKyle Evans ret = ec_priv_key_import_from_buf(&(kp->priv_key), params, priv_key, 300*f0865ec9SKyle Evans priv_key_len, ec_key_alg); EG(ret, err); 301*f0865ec9SKyle Evans /* Generate associated public key. */ 302*f0865ec9SKyle Evans ret = init_pubkey_from_privkey(&(kp->pub_key), &(kp->priv_key)); 303*f0865ec9SKyle Evans 304*f0865ec9SKyle Evans err: 305*f0865ec9SKyle Evans return ret; 306*f0865ec9SKyle Evans } 307*f0865ec9SKyle Evans 308*f0865ec9SKyle Evans /* 309*f0865ec9SKyle Evans * Import a structured private key to buffer. The structure allows some sanity 310*f0865ec9SKyle Evans * checks. The function returns 0 on success, -1 on error. 311*f0865ec9SKyle Evans */ 312*f0865ec9SKyle Evans int ec_structured_priv_key_import_from_buf(ec_priv_key *priv_key, 313*f0865ec9SKyle Evans const ec_params *params, 314*f0865ec9SKyle Evans const u8 *priv_key_buf, 315*f0865ec9SKyle Evans u8 priv_key_buf_len, 316*f0865ec9SKyle Evans ec_alg_type ec_key_alg) 317*f0865ec9SKyle Evans { 318*f0865ec9SKyle Evans u8 metadata_len = (3 * sizeof(u8)); 319*f0865ec9SKyle Evans u8 crv_name_len; 320*f0865ec9SKyle Evans u32 len; 321*f0865ec9SKyle Evans int ret; 322*f0865ec9SKyle Evans 323*f0865ec9SKyle Evans /* We first pull the metadata, consisting of: 324*f0865ec9SKyle Evans * - One byte = the key type (public or private) 325*f0865ec9SKyle Evans * - One byte = the algorithm type (ECDSA, ECKCDSA, ...) 326*f0865ec9SKyle Evans * - One byte = the curve type (FRP256V1, ...) 327*f0865ec9SKyle Evans */ 328*f0865ec9SKyle Evans MUST_HAVE((priv_key != NULL) && (priv_key_buf != NULL) && (priv_key_buf_len > metadata_len), ret, err); 329*f0865ec9SKyle Evans MUST_HAVE((params != NULL) && (params->curve_name != NULL), ret, err); 330*f0865ec9SKyle Evans 331*f0865ec9SKyle Evans /* Pull and check the key type */ 332*f0865ec9SKyle Evans MUST_HAVE((EC_PRIVKEY == priv_key_buf[0]), ret, err); 333*f0865ec9SKyle Evans 334*f0865ec9SKyle Evans /* Pull and check the algorithm type */ 335*f0865ec9SKyle Evans MUST_HAVE((ec_key_alg == priv_key_buf[1]), ret, err); 336*f0865ec9SKyle Evans 337*f0865ec9SKyle Evans /* Pull and check the curve type */ 338*f0865ec9SKyle Evans ret = local_strlen((const char *)params->curve_name, &len); EG(ret, err); 339*f0865ec9SKyle Evans len += 1; 340*f0865ec9SKyle Evans MUST_HAVE((len < 256), ret, err); 341*f0865ec9SKyle Evans crv_name_len = (u8)len; 342*f0865ec9SKyle Evans 343*f0865ec9SKyle Evans ret = ec_check_curve_type_and_name((ec_curve_type) (priv_key_buf[2]), 344*f0865ec9SKyle Evans params->curve_name, crv_name_len); EG(ret, err); 345*f0865ec9SKyle Evans ret = ec_priv_key_import_from_buf(priv_key, params, 346*f0865ec9SKyle Evans priv_key_buf + metadata_len, 347*f0865ec9SKyle Evans (u8)(priv_key_buf_len - metadata_len), 348*f0865ec9SKyle Evans ec_key_alg); 349*f0865ec9SKyle Evans 350*f0865ec9SKyle Evans err: 351*f0865ec9SKyle Evans return ret; 352*f0865ec9SKyle Evans } 353*f0865ec9SKyle Evans 354*f0865ec9SKyle Evans /* 355*f0865ec9SKyle Evans * Export a structured private key to buffer. The structure allows some sanity 356*f0865ec9SKyle Evans * checks. The function returns 0 on success, -1 on error. 357*f0865ec9SKyle Evans */ 358*f0865ec9SKyle Evans int ec_structured_priv_key_export_to_buf(const ec_priv_key *priv_key, 359*f0865ec9SKyle Evans u8 *priv_key_buf, u8 priv_key_buf_len) 360*f0865ec9SKyle Evans { 361*f0865ec9SKyle Evans 362*f0865ec9SKyle Evans u8 metadata_len = (3 * sizeof(u8)); 363*f0865ec9SKyle Evans const u8 *curve_name; 364*f0865ec9SKyle Evans u8 curve_name_len; 365*f0865ec9SKyle Evans u32 len; 366*f0865ec9SKyle Evans ec_curve_type curve_type; 367*f0865ec9SKyle Evans int ret; 368*f0865ec9SKyle Evans 369*f0865ec9SKyle Evans ret = priv_key_check_initialized(priv_key); EG(ret, err); 370*f0865ec9SKyle Evans 371*f0865ec9SKyle Evans MUST_HAVE((priv_key_buf != NULL) && (priv_key_buf_len > metadata_len) && (priv_key->params->curve_name != NULL), ret, err); 372*f0865ec9SKyle Evans 373*f0865ec9SKyle Evans /* 374*f0865ec9SKyle Evans * We first put the metadata, consisting on: 375*f0865ec9SKyle Evans * - One byte = the key type (public or private) 376*f0865ec9SKyle Evans * - One byte = the algorithm type (ECDSA, ECKCDSA, ...) 377*f0865ec9SKyle Evans * - One byte = the curve type (FRP256V1, ...) 378*f0865ec9SKyle Evans */ 379*f0865ec9SKyle Evans 380*f0865ec9SKyle Evans /* Push the key type */ 381*f0865ec9SKyle Evans priv_key_buf[0] = (u8)EC_PRIVKEY; 382*f0865ec9SKyle Evans 383*f0865ec9SKyle Evans /* Push the algorithm type */ 384*f0865ec9SKyle Evans priv_key_buf[1] = (u8)priv_key->key_type; 385*f0865ec9SKyle Evans 386*f0865ec9SKyle Evans /* Push the curve type */ 387*f0865ec9SKyle Evans curve_name = priv_key->params->curve_name; 388*f0865ec9SKyle Evans 389*f0865ec9SKyle Evans ret = local_strlen((const char *)curve_name, &len); EG(ret, err); 390*f0865ec9SKyle Evans len += 1; 391*f0865ec9SKyle Evans MUST_HAVE((len < 256), ret, err); 392*f0865ec9SKyle Evans curve_name_len = (u8)len; 393*f0865ec9SKyle Evans 394*f0865ec9SKyle Evans ret = ec_get_curve_type_by_name(curve_name, curve_name_len, &curve_type); EG(ret, err); 395*f0865ec9SKyle Evans priv_key_buf[2] = (u8)curve_type; 396*f0865ec9SKyle Evans 397*f0865ec9SKyle Evans /* Push the raw private key buffer */ 398*f0865ec9SKyle Evans ret = ec_priv_key_export_to_buf(priv_key, priv_key_buf + metadata_len, 399*f0865ec9SKyle Evans (u8)(priv_key_buf_len - metadata_len)); 400*f0865ec9SKyle Evans 401*f0865ec9SKyle Evans err: 402*f0865ec9SKyle Evans return ret; 403*f0865ec9SKyle Evans } 404*f0865ec9SKyle Evans 405*f0865ec9SKyle Evans /* 406*f0865ec9SKyle Evans * Import a structured pub key from buffer. The structure allows some sanity 407*f0865ec9SKyle Evans * checks. The function returns 0 on success, -1 on error. 408*f0865ec9SKyle Evans */ 409*f0865ec9SKyle Evans int ec_structured_pub_key_import_from_buf(ec_pub_key *pub_key, 410*f0865ec9SKyle Evans const ec_params *params, 411*f0865ec9SKyle Evans const u8 *pub_key_buf, 412*f0865ec9SKyle Evans u8 pub_key_buf_len, 413*f0865ec9SKyle Evans ec_alg_type ec_key_alg) 414*f0865ec9SKyle Evans { 415*f0865ec9SKyle Evans u8 metadata_len = (3 * sizeof(u8)); 416*f0865ec9SKyle Evans u8 crv_name_len; 417*f0865ec9SKyle Evans u32 len; 418*f0865ec9SKyle Evans int ret; 419*f0865ec9SKyle Evans 420*f0865ec9SKyle Evans MUST_HAVE((pub_key_buf != NULL) && (pub_key_buf_len > metadata_len), ret, err); 421*f0865ec9SKyle Evans MUST_HAVE((params != NULL) && (params->curve_name != NULL), ret, err); 422*f0865ec9SKyle Evans 423*f0865ec9SKyle Evans /* 424*f0865ec9SKyle Evans * We first pull the metadata, consisting of: 425*f0865ec9SKyle Evans * - One byte = the key type (public or private) 426*f0865ec9SKyle Evans * - One byte = the algorithm type (ECDSA, ECKCDSA, ...) 427*f0865ec9SKyle Evans * - One byte = the curve type (FRP256V1, ...) 428*f0865ec9SKyle Evans */ 429*f0865ec9SKyle Evans 430*f0865ec9SKyle Evans /* Pull and check the key type */ 431*f0865ec9SKyle Evans MUST_HAVE((EC_PUBKEY == pub_key_buf[0]), ret, err); 432*f0865ec9SKyle Evans 433*f0865ec9SKyle Evans /* Pull and check the algorithm type */ 434*f0865ec9SKyle Evans MUST_HAVE((ec_key_alg == pub_key_buf[1]), ret, err); 435*f0865ec9SKyle Evans 436*f0865ec9SKyle Evans /* Pull and check the curve type */ 437*f0865ec9SKyle Evans ret = local_strlen((const char *)params->curve_name, &len); EG(ret, err); 438*f0865ec9SKyle Evans len += 1; 439*f0865ec9SKyle Evans MUST_HAVE((len < 256), ret, err); 440*f0865ec9SKyle Evans crv_name_len = (u8)len; 441*f0865ec9SKyle Evans 442*f0865ec9SKyle Evans ret = ec_check_curve_type_and_name((ec_curve_type) (pub_key_buf[2]), 443*f0865ec9SKyle Evans params->curve_name, crv_name_len); EG(ret, err); 444*f0865ec9SKyle Evans ret = ec_pub_key_import_from_buf(pub_key, params, 445*f0865ec9SKyle Evans pub_key_buf + metadata_len, 446*f0865ec9SKyle Evans (u8)(pub_key_buf_len - metadata_len), 447*f0865ec9SKyle Evans ec_key_alg); 448*f0865ec9SKyle Evans 449*f0865ec9SKyle Evans err: 450*f0865ec9SKyle Evans return ret; 451*f0865ec9SKyle Evans } 452*f0865ec9SKyle Evans 453*f0865ec9SKyle Evans /* 454*f0865ec9SKyle Evans * Export a structured pubate key to buffer. The structure allows some sanity 455*f0865ec9SKyle Evans * checks. The function returns 0 on success, -1 on error. 456*f0865ec9SKyle Evans */ 457*f0865ec9SKyle Evans int ec_structured_pub_key_export_to_buf(const ec_pub_key *pub_key, 458*f0865ec9SKyle Evans u8 *pub_key_buf, u8 pub_key_buf_len) 459*f0865ec9SKyle Evans { 460*f0865ec9SKyle Evans u8 metadata_len = (3 * sizeof(u8)); 461*f0865ec9SKyle Evans const u8 *curve_name; 462*f0865ec9SKyle Evans u8 curve_name_len; 463*f0865ec9SKyle Evans u32 len; 464*f0865ec9SKyle Evans ec_curve_type curve_type; 465*f0865ec9SKyle Evans int ret; 466*f0865ec9SKyle Evans 467*f0865ec9SKyle Evans ret = pub_key_check_initialized(pub_key); EG(ret, err); 468*f0865ec9SKyle Evans 469*f0865ec9SKyle Evans MUST_HAVE((pub_key_buf != NULL) && (pub_key_buf_len > metadata_len), ret, err); 470*f0865ec9SKyle Evans MUST_HAVE((pub_key->params->curve_name != NULL), ret, err); 471*f0865ec9SKyle Evans 472*f0865ec9SKyle Evans /* 473*f0865ec9SKyle Evans * We first put the metadata, consisting of: 474*f0865ec9SKyle Evans * - One byte = the key type (public or private) 475*f0865ec9SKyle Evans * - One byte = the algorithm type (ECDSA, ECKCDSA, ...) 476*f0865ec9SKyle Evans * - One byte = the curve type (FRP256V1, ...) 477*f0865ec9SKyle Evans */ 478*f0865ec9SKyle Evans 479*f0865ec9SKyle Evans /* Push the key type */ 480*f0865ec9SKyle Evans pub_key_buf[0] = (u8)EC_PUBKEY; 481*f0865ec9SKyle Evans 482*f0865ec9SKyle Evans /* Push the algorithm type */ 483*f0865ec9SKyle Evans pub_key_buf[1] = (u8)pub_key->key_type; 484*f0865ec9SKyle Evans 485*f0865ec9SKyle Evans /* Push the curve type */ 486*f0865ec9SKyle Evans curve_name = pub_key->params->curve_name; 487*f0865ec9SKyle Evans 488*f0865ec9SKyle Evans ret = local_strlen((const char *)curve_name, &len); EG(ret, err); 489*f0865ec9SKyle Evans len += 1; 490*f0865ec9SKyle Evans MUST_HAVE((len < 256), ret, err); 491*f0865ec9SKyle Evans curve_name_len = (u8)len; 492*f0865ec9SKyle Evans 493*f0865ec9SKyle Evans ret = ec_get_curve_type_by_name(curve_name, curve_name_len, &curve_type); EG(ret, err); 494*f0865ec9SKyle Evans pub_key_buf[2] = (u8)curve_type; 495*f0865ec9SKyle Evans 496*f0865ec9SKyle Evans /* Push the raw pub key buffer */ 497*f0865ec9SKyle Evans ret = ec_pub_key_export_to_buf(pub_key, pub_key_buf + metadata_len, 498*f0865ec9SKyle Evans (u8)(pub_key_buf_len - metadata_len)); 499*f0865ec9SKyle Evans 500*f0865ec9SKyle Evans err: 501*f0865ec9SKyle Evans return ret; 502*f0865ec9SKyle Evans } 503*f0865ec9SKyle Evans 504*f0865ec9SKyle Evans /* 505*f0865ec9SKyle Evans * Import a key pair from a structured private key buffer. The structure allows 506*f0865ec9SKyle Evans * some sanity checks. The function returns 0 on success, -1 on error. 507*f0865ec9SKyle Evans */ 508*f0865ec9SKyle Evans int ec_structured_key_pair_import_from_priv_key_buf(ec_key_pair *kp, 509*f0865ec9SKyle Evans const ec_params *params, 510*f0865ec9SKyle Evans const u8 *priv_key_buf, 511*f0865ec9SKyle Evans u8 priv_key_buf_len, 512*f0865ec9SKyle Evans ec_alg_type ec_key_alg) 513*f0865ec9SKyle Evans { 514*f0865ec9SKyle Evans u8 metadata_len = (3 * sizeof(u8)); 515*f0865ec9SKyle Evans u8 crv_name_len; 516*f0865ec9SKyle Evans u32 len; 517*f0865ec9SKyle Evans int ret; 518*f0865ec9SKyle Evans 519*f0865ec9SKyle Evans MUST_HAVE((kp != NULL) && (priv_key_buf != NULL) && (priv_key_buf_len > metadata_len), ret, err); 520*f0865ec9SKyle Evans MUST_HAVE((params != NULL) && (params->curve_name != NULL), ret, err); 521*f0865ec9SKyle Evans 522*f0865ec9SKyle Evans /* We first pull the metadata, consisting on: 523*f0865ec9SKyle Evans * - One byte = the key type (public or private) 524*f0865ec9SKyle Evans * - One byte = the algorithm type (ECDSA, ECKCDSA, ...) 525*f0865ec9SKyle Evans * - One byte = the curve type (FRP256V1, ...) 526*f0865ec9SKyle Evans */ 527*f0865ec9SKyle Evans 528*f0865ec9SKyle Evans /* Pull and check the key type */ 529*f0865ec9SKyle Evans MUST_HAVE((EC_PRIVKEY == priv_key_buf[0]), ret, err); 530*f0865ec9SKyle Evans 531*f0865ec9SKyle Evans /* Pull and check the algorithm type */ 532*f0865ec9SKyle Evans MUST_HAVE((ec_key_alg == priv_key_buf[1]), ret, err); 533*f0865ec9SKyle Evans 534*f0865ec9SKyle Evans /* Pull and check the curve type */ 535*f0865ec9SKyle Evans ret = local_strlen((const char *)params->curve_name, &len); EG(ret, err); 536*f0865ec9SKyle Evans len += 1; 537*f0865ec9SKyle Evans MUST_HAVE((len < 256), ret, err); 538*f0865ec9SKyle Evans crv_name_len = (u8)len; 539*f0865ec9SKyle Evans 540*f0865ec9SKyle Evans ret = ec_check_curve_type_and_name((ec_curve_type) (priv_key_buf[2]), 541*f0865ec9SKyle Evans params->curve_name, crv_name_len); EG(ret, err); 542*f0865ec9SKyle Evans ret = ec_key_pair_import_from_priv_key_buf(kp, params, 543*f0865ec9SKyle Evans priv_key_buf + metadata_len, 544*f0865ec9SKyle Evans (u8)(priv_key_buf_len - metadata_len), 545*f0865ec9SKyle Evans ec_key_alg); 546*f0865ec9SKyle Evans 547*f0865ec9SKyle Evans err: 548*f0865ec9SKyle Evans return ret; 549*f0865ec9SKyle Evans } 550*f0865ec9SKyle Evans 551*f0865ec9SKyle Evans /* 552*f0865ec9SKyle Evans * Import a key pair from a two structured key buffer (private and public one) 553*f0865ec9SKyle Evans * The function does not verify the coherency between private and public parts. 554*f0865ec9SKyle Evans * The function returns 0 on success, -1 on error. 555*f0865ec9SKyle Evans * 556*f0865ec9SKyle Evans * NOTE: please use this API with care as it does not check the consistency 557*f0865ec9SKyle Evans * between the private and public keys! On one side, this "saves" a costly 558*f0865ec9SKyle Evans * scalar multiplication when there is confidence in the source of the buffers, 559*f0865ec9SKyle Evans * but on the other side the user of the API MUST check the source (integrity) 560*f0865ec9SKyle Evans * of the private/public key pair. If unsure, it is advised to use the 561*f0865ec9SKyle Evans * ec_structured_key_pair_import_from_priv_key_buf API that safely derives the 562*f0865ec9SKyle Evans * public key from the private key. 563*f0865ec9SKyle Evans * 564*f0865ec9SKyle Evans */ 565*f0865ec9SKyle Evans int ec_structured_key_pair_import_from_buf(ec_key_pair *kp, 566*f0865ec9SKyle Evans const ec_params *params, 567*f0865ec9SKyle Evans const u8 *priv_key_buf, 568*f0865ec9SKyle Evans u8 priv_key_buf_len, 569*f0865ec9SKyle Evans const u8 *pub_key_buf, 570*f0865ec9SKyle Evans u8 pub_key_buf_len, 571*f0865ec9SKyle Evans ec_alg_type ec_key_alg) 572*f0865ec9SKyle Evans { 573*f0865ec9SKyle Evans int ret; 574*f0865ec9SKyle Evans 575*f0865ec9SKyle Evans MUST_HAVE((kp != NULL), ret, err); 576*f0865ec9SKyle Evans 577*f0865ec9SKyle Evans ret = ec_structured_pub_key_import_from_buf(&kp->pub_key, params, 578*f0865ec9SKyle Evans pub_key_buf, 579*f0865ec9SKyle Evans pub_key_buf_len, 580*f0865ec9SKyle Evans ec_key_alg); EG(ret, err); 581*f0865ec9SKyle Evans ret = ec_structured_priv_key_import_from_buf(&kp->priv_key, params, 582*f0865ec9SKyle Evans priv_key_buf, 583*f0865ec9SKyle Evans priv_key_buf_len, 584*f0865ec9SKyle Evans ec_key_alg); 585*f0865ec9SKyle Evans 586*f0865ec9SKyle Evans err: 587*f0865ec9SKyle Evans return ret; 588*f0865ec9SKyle Evans } 589*f0865ec9SKyle Evans 590*f0865ec9SKyle Evans /* 591*f0865ec9SKyle Evans * Generate a public/private key pair for given signature algorithm, using 592*f0865ec9SKyle Evans * given EC params. The function returns 0 on success, -1 on error. 593*f0865ec9SKyle Evans */ 594*f0865ec9SKyle Evans int ec_key_pair_gen(ec_key_pair *kp, const ec_params *params, 595*f0865ec9SKyle Evans ec_alg_type ec_key_alg) 596*f0865ec9SKyle Evans { 597*f0865ec9SKyle Evans int ret; 598*f0865ec9SKyle Evans 599*f0865ec9SKyle Evans MUST_HAVE((kp != NULL) && (params != NULL), ret, err); 600*f0865ec9SKyle Evans 601*f0865ec9SKyle Evans /* Get a random value in ]0,q[ */ 602*f0865ec9SKyle Evans ret = nn_get_random_mod(&(kp->priv_key.x), &(params->ec_gen_order)); EG(ret, err); 603*f0865ec9SKyle Evans 604*f0865ec9SKyle Evans /* Set key type and pointer to EC params for private key */ 605*f0865ec9SKyle Evans kp->priv_key.key_type = ec_key_alg; 606*f0865ec9SKyle Evans kp->priv_key.params = (const ec_params *)params; 607*f0865ec9SKyle Evans kp->priv_key.magic = PRIV_KEY_MAGIC; 608*f0865ec9SKyle Evans 609*f0865ec9SKyle Evans /* Call our private key generation function */ 610*f0865ec9SKyle Evans ret = gen_priv_key(&(kp->priv_key)); EG(ret, err); 611*f0865ec9SKyle Evans 612*f0865ec9SKyle Evans /* Generate associated public key. */ 613*f0865ec9SKyle Evans ret = init_pubkey_from_privkey(&(kp->pub_key), &(kp->priv_key)); 614*f0865ec9SKyle Evans 615*f0865ec9SKyle Evans err: 616*f0865ec9SKyle Evans if (ret && (kp != NULL)) { 617*f0865ec9SKyle Evans IGNORE_RET_VAL(local_memset(kp, 0, sizeof(ec_key_pair))); 618*f0865ec9SKyle Evans } 619*f0865ec9SKyle Evans return ret; 620*f0865ec9SKyle Evans } 621