static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv) { switch (EVP_PKEY_base_id(pkey)) { case NID_id_GostR3410_94: { DSA *dsa = EVP_PKEY_get0(pkey); if (!dsa) { dsa = DSA_new(); EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),dsa); } dsa->priv_key = BN_dup(priv); if (!EVP_PKEY_missing_parameters(pkey)) gost94_compute_public(dsa); break; } case NID_id_GostR3410_2001: { EC_KEY *ec = EVP_PKEY_get0(pkey); if (!ec) { ec = EC_KEY_new(); EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),ec); } if (!EC_KEY_set_private_key(ec,priv)) return 0; if (!EVP_PKEY_missing_parameters(pkey)) gost2001_compute_public(ec); break; } } return 1; }
static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) { EC_KEY *eto = EVP_PKEY_get0(to); const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from); if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS); return 0; } if (!efrom) { GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING); return 0; } if (!eto) { eto = EC_KEY_new(); EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto); } EC_KEY_set_group(eto,EC_KEY_get0_group(efrom)); if (EC_KEY_get0_private_key(eto)) { gost2001_compute_public(eto); } return 1; }
// Setters for the GOST private key components void OSSLGOSTPrivateKey::setD(const ByteString& d) { GOSTPrivateKey::setD(d); EC_KEY* ec = (EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey); if (ec == NULL) { ByteString der = dummyKey; const unsigned char *p = &der[0]; if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) der.size()) == NULL) { ERROR_MSG("d2i_PrivateKey failed"); return; } ec = (EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey); } const BIGNUM* priv = OSSL::byteString2bn(d); if (EC_KEY_set_private_key(ec, priv) <= 0) { ERROR_MSG("EC_KEY_set_private_key failed"); return; } #ifdef notyet if (gost2001_compute_public(ec) <= 0) ERROR_MSG("gost2001_compute_public failed"); #endif }
// Setters for the GOST private key components void OSSLGOSTPrivateKey::setD(const ByteString& inD) { GOSTPrivateKey::setD(inD); EC_KEY* inEC = (EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey); if (inEC == NULL) { const unsigned char* p = dummyKey; if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) sizeof(dummyKey)) == NULL) { ERROR_MSG("d2i_PrivateKey failed"); return; } inEC = (EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey); } const BIGNUM* priv = OSSL::byteString2bn(inD); if (EC_KEY_set_private_key(inEC, priv) <= 0) { ERROR_MSG("EC_KEY_set_private_key failed"); return; } BN_clear_free((BIGNUM*)priv); #ifdef notyet if (gost2001_compute_public(inEC) <= 0) ERROR_MSG("gost2001_compute_public failed"); #endif }
/* * * Generates GOST R 34.10-2001 keypair * * */ int gost2001_keygen(EC_KEY *ec) { BIGNUM *order = BN_new(), *d = BN_new(); const EC_GROUP *group = EC_KEY_get0_group(ec); if (!group || !EC_GROUP_get_order(group, order, NULL)) { GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR); BN_free(d); BN_free(order); return 0; } do { if (!BN_rand_range(d, order)) { GOSTerr(GOST_F_GOST2001_KEYGEN, GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); BN_free(d); BN_free(order); return 0; } } while (BN_is_zero(d)); if (!EC_KEY_set_private_key(ec, d)) { GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR); BN_free(d); BN_free(order); return 0; } BN_free(d); BN_free(order); return gost2001_compute_public(ec); }
int gost2001_keygen(GOST_KEY *ec) { BIGNUM *order = BN_new(), *d = BN_new(); const EC_GROUP *group = GOST_KEY_get0_group(ec); int rc = 0; if (order == NULL || d == NULL) goto err; if (EC_GROUP_get_order(group, order, NULL) == 0) goto err; do { if (BN_rand_range(d, order) == 0) { GOSTerr(GOST_F_GOST2001_KEYGEN, GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); goto err; } } while (BN_is_zero(d)); if (GOST_KEY_set_private_key(ec, d) == 0) goto err; rc = gost2001_compute_public(ec); err: BN_free(d); BN_free(order); return rc; }
static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) { GOST_KEY *eto = to->pkey.gost; const GOST_KEY *efrom = from->pkey.gost; int ret = 1; if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS); return 0; } if (efrom == NULL) { GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING); return 0; } if (eto == NULL) { eto = GOST_KEY_new(); if (eto == NULL) { GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_MALLOC_FAILURE); return 0; } if (EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto) == 0) { GOST_KEY_free(eto); return 0; } } GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom)); GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom)); if (GOST_KEY_get0_private_key(eto) != NULL) ret = gost2001_compute_public(eto); return ret; }
static int priv_decode_gost01(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) { const unsigned char *pkey_buf = NULL, *p = NULL; int priv_len = 0; BIGNUM *pk_num = NULL; int ret = 0; X509_ALGOR *palg = NULL; ASN1_OBJECT *palg_obj = NULL; ASN1_INTEGER *priv_key = NULL; GOST_KEY *ec; int ptype = V_ASN1_UNDEF; ASN1_STRING *pval = NULL; if (PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf) == 0) return 0; (void)EVP_PKEY_assign_GOST(pk, NULL); X509_ALGOR_get0(NULL, &ptype, (void **)&pval, palg); if (ptype != V_ASN1_SEQUENCE) { GOSTerr(GOST_F_PUB_DECODE_GOST01, GOST_R_BAD_KEY_PARAMETERS_FORMAT); return 0; } p = pval->data; if (decode_gost01_algor_params(pk, &p, pval->length) == 0) return 0; p = pkey_buf; if (V_ASN1_OCTET_STRING == *p) { /* New format - Little endian octet string */ unsigned char rev_buf[32]; int i; ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); if (s == NULL || s->length != 32) { GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); ASN1_STRING_free(s); return 0; } for (i = 0; i < 32; i++) { rev_buf[31 - i] = s->data[i]; } ASN1_STRING_free(s); pk_num = BN_bin2bn(rev_buf, 32, NULL); } else { priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); if (priv_key == NULL) return 0; ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); ASN1_INTEGER_free(priv_key); if (ret == 0) { GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); return 0; } } ec = pk->pkey.gost; if (ec == NULL) { ec = GOST_KEY_new(); if (ec == NULL) { BN_free(pk_num); return 0; } if (EVP_PKEY_assign_GOST(pk, ec) == 0) { BN_free(pk_num); GOST_KEY_free(ec); return 0; } } if (GOST_KEY_set_private_key(ec, pk_num) == 0) { BN_free(pk_num); return 0; } ret = 0; if (EVP_PKEY_missing_parameters(pk) == 0) ret = gost2001_compute_public(ec) != 0; BN_free(pk_num); return ret; }
static isc_result_t opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; isc_mem_t *mctx = key->mctx; EVP_PKEY *pkey = NULL; EC_KEY *eckey; const EC_POINT *pubkey = NULL; BIGNUM *privkey = NULL; const unsigned char *p; /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_ECCGOST, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); if (key->external) { if (priv.nelements != 0) DST_RET(DST_R_INVALIDPRIVATEKEY); if (pub == NULL) DST_RET(DST_R_INVALIDPRIVATEKEY); key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); } INSIST((priv.elements[0].tag == TAG_GOST_PRIVASN1) || (priv.elements[0].tag == TAG_GOST_PRIVRAW)); if (priv.elements[0].tag == TAG_GOST_PRIVASN1) { p = priv.elements[0].data; if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) priv.elements[0].length) == NULL) DST_RET(dst__openssl_toresult2( "d2i_PrivateKey", DST_R_INVALIDPRIVATEKEY)); } else { if ((pub != NULL) && (pub->keydata.pkey != NULL)) { eckey = EVP_PKEY_get0(pub->keydata.pkey); pubkey = EC_KEY_get0_public_key(eckey); } privkey = BN_bin2bn(priv.elements[0].data, priv.elements[0].length, NULL); if (privkey == NULL) DST_RET(ISC_R_NOMEMORY); /* can't create directly the whole key */ p = gost_dummy_key; if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) sizeof(gost_dummy_key)) == NULL) DST_RET(dst__openssl_toresult2( "d2i_PrivateKey", DST_R_INVALIDPRIVATEKEY)); eckey = EVP_PKEY_get0(pkey); if (eckey == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); if (!EC_KEY_set_private_key(eckey, privkey)) DST_RET(ISC_R_NOMEMORY); /* have to (re)set the public key */ #ifdef notyet (void) gost2001_compute_public(eckey); #else if ((pubkey != NULL) && !EC_KEY_set_public_key(eckey, pubkey)) DST_RET(ISC_R_NOMEMORY); #endif BN_clear_free(privkey); privkey = NULL; } key->keydata.pkey = pkey; key->key_size = EVP_PKEY_bits(pkey); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); err: if (privkey != NULL) BN_clear_free(privkey); if (pkey != NULL) EVP_PKEY_free(pkey); opensslgost_destroy(key); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); }