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 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; }