/* * Packs signature according to Cryptopro rules * and frees up DSA_SIG structure */ int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen) { *siglen = 2 * order; memset(sig, 0, *siglen); store_bignum(s->s, sig, order); store_bignum(s->r, sig + order, order); DSA_SIG_free(s); return 1; }
/* * Packs signature according to Cryptopro rules * and frees up DSA_SIG structure */ int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen) { *siglen = 2*order; TINYCLR_SSL_MEMSET(sig,0,*siglen); store_bignum(s->s, sig, order); store_bignum(s->r, sig+order,order); dump_signature("serialized",sig,*siglen); DSA_SIG_free(s); return 1; }
static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk) { ASN1_OBJECT *algobj = NULL; ASN1_OCTET_STRING *octet = NULL; void *pval = NULL; unsigned char *buf=NULL,*databuf,*sptr; int i,j,data_len,ret=0; const EC_POINT *pub_key; BIGNUM *X,*Y,*order; const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); int ptype = V_ASN1_UNDEF; algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); if (pk->save_parameters) { ASN1_STRING *params = encode_gost_algor_params(pk); pval = params; ptype = V_ASN1_SEQUENCE; } order = BN_new(); EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL); pub_key=EC_KEY_get0_public_key(ec); if (!pub_key) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); return 0; } X=BN_new(); Y=BN_new(); EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), pub_key,X,Y,NULL); data_len = 2*BN_num_bytes(order); BN_free(order); databuf = OPENSSL_malloc(data_len); memset(databuf,0,data_len); store_bignum(X,databuf+data_len/2,data_len/2); store_bignum(Y,databuf,data_len/2); BN_free(X); BN_free(Y); octet = ASN1_OCTET_STRING_new(); ASN1_STRING_set(octet,NULL,data_len); sptr=ASN1_STRING_data(octet); for (i=0,j=data_len-1;i<data_len;i++,j--) { sptr[i]=databuf[j]; } OPENSSL_free(databuf); ret = i2d_ASN1_OCTET_STRING(octet,&buf); ASN1_BIT_STRING_free(octet); if (ret <0) return 0; return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret); }
/* * Packs signature according to Cryptopro rules * and frees up DSA_SIG structure */ int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen) { const BIGNUM *sig_r = NULL, *sig_s = NULL; DSA_SIG_get0(s, &sig_r, &sig_s); *siglen = 2 * order; memset(sig, 0, *siglen); store_bignum(sig_s, sig, order); store_bignum(sig_r, sig + order, order); DSA_SIG_free(s); return 1; }
/* Implementation of CryptoPro VKO 34.10-2001 algorithm */ static int VKO_compute_key (unsigned char *shared_key, size_t shared_key_size, const EC_POINT * pub_key, EC_KEY * priv_key, const unsigned char *ukm) { unsigned char ukm_be[8], databuf[64], hashbuf[64]; BIGNUM *UKM = NULL, *p = NULL, *order = NULL, *X = NULL, *Y = NULL; const BIGNUM *key = EC_KEY_get0_private_key (priv_key); EC_POINT *pnt = EC_POINT_new (EC_KEY_get0_group (priv_key)); int i; gost_hash_ctx hash_ctx; BN_CTX *ctx = BN_CTX_new (); for (i = 0; i < 8; i++) { ukm_be[7 - i] = ukm[i]; } BN_CTX_start (ctx); UKM = getbnfrombuf (ukm_be, 8); p = BN_CTX_get (ctx); order = BN_CTX_get (ctx); X = BN_CTX_get (ctx); Y = BN_CTX_get (ctx); EC_GROUP_get_order (EC_KEY_get0_group (priv_key), order, ctx); BN_mod_mul (p, key, UKM, order, ctx); EC_POINT_mul (EC_KEY_get0_group (priv_key), pnt, NULL, pub_key, p, ctx); EC_POINT_get_affine_coordinates_GFp (EC_KEY_get0_group (priv_key), pnt, X, Y, ctx); /*Serialize elliptic curve point same way as we do it when saving * key */ store_bignum (Y, databuf, 32); store_bignum (X, databuf + 32, 32); /* And reverse byte order of whole buffer */ for (i = 0; i < 64; i++) { hashbuf[63 - i] = databuf[i]; } init_gost_hash_ctx (&hash_ctx, &GostR3411_94_CryptoProParamSet); start_hash (&hash_ctx); hash_block (&hash_ctx, hashbuf, 64); finish_hash (&hash_ctx, shared_key); done_gost_hash_ctx (&hash_ctx); BN_free (UKM); BN_CTX_end (ctx); BN_CTX_free (ctx); EC_POINT_free (pnt); return 32; }
/* ----------------------------------------------------------------------*/ static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) { ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); ASN1_STRING *params = encode_gost_algor_params(pk); unsigned char /**priv_buf = NULL,*/ *buf = NULL; int key_len = pkey_bits_gost(pk), /*priv_len = 0,*/ i = 0; /*ASN1_STRING *octet = NULL;*/ if (!params) { return 0; } key_len = (key_len < 0) ? 0 : key_len / 8; if (key_len == 0 || !(buf = OPENSSL_malloc(key_len))) { return 0; } if (!store_bignum(gost_get0_priv_key(pk), buf, key_len)) { OPENSSL_free(buf); return 0; } /* Convert buf to Little-endian */ for (i = 0; i < key_len / 2; i++) { unsigned char tmp = buf[i]; buf[i] = buf[key_len - 1 - i]; buf[key_len - 1 - i] = tmp; } /* octet = ASN1_STRING_new(); ASN1_OCTET_STRING_set(octet, buf, key_len); priv_len = i2d_ASN1_OCTET_STRING(octet, &priv_buf); ASN1_STRING_free(octet); OPENSSL_free(buf); return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf, priv_len); */ return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, buf, key_len); }
/* Implementation of CryptoPro VKO 34.10-2001/2012 algorithm */ static int VKO_compute_key(unsigned char *shared_key, size_t shared_key_size, const EC_POINT *pub_key, EC_KEY *priv_key, const unsigned char *ukm, int dgst_nid) { unsigned char *databuf = NULL, *hashbuf = NULL; BIGNUM *UKM = NULL, *p = NULL, *order = NULL, *X = NULL, *Y = NULL; const BIGNUM *key = EC_KEY_get0_private_key(priv_key); EC_POINT *pnt = EC_POINT_new(EC_KEY_get0_group(priv_key)); int i; BN_CTX *ctx = BN_CTX_new(); EVP_MD_CTX mdctx; const EVP_MD *md; int effective_dgst_nid = (dgst_nid == NID_id_GostR3411_2012_512) ? NID_id_GostR3411_2012_256 : dgst_nid; int buf_len = (dgst_nid == NID_id_GostR3411_2012_512) ? 128 : 64, half_len = buf_len >> 1; if (!ctx) { GOSTerr(GOST_F_VKO_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); return 0; } BN_CTX_start(ctx); databuf = OPENSSL_malloc(buf_len); hashbuf = OPENSSL_malloc(buf_len); if (!databuf || !hashbuf) { GOSTerr(GOST_F_VKO_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); goto err; } md = EVP_get_digestbynid(effective_dgst_nid); if (!md) { GOSTerr(GOST_F_VKO_COMPUTE_KEY, GOST_R_INVALID_DIGEST_TYPE); goto err; } UKM = hashsum2bn(ukm, 8); p = BN_CTX_get(ctx); order = BN_CTX_get(ctx); X = BN_CTX_get(ctx); Y = BN_CTX_get(ctx); EC_GROUP_get_order(EC_KEY_get0_group(priv_key), order, ctx); BN_mod_mul(p, key, UKM, order, ctx); if (!EC_POINT_mul (EC_KEY_get0_group(priv_key), pnt, NULL, pub_key, p, ctx)) { GOSTerr(GOST_F_VKO_COMPUTE_KEY, GOST_R_ERROR_POINT_MUL); goto err; } EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(priv_key), pnt, X, Y, ctx); /* * Serialize elliptic curve point same way as we do it when saving key */ store_bignum(Y, databuf, half_len); store_bignum(X, databuf + half_len, half_len); /* And reverse byte order of whole buffer */ for (i = 0; i < buf_len; i++) { hashbuf[buf_len - 1 - i] = databuf[i]; } EVP_MD_CTX_init(&mdctx); EVP_DigestInit_ex(&mdctx, md, NULL); EVP_DigestUpdate(&mdctx, hashbuf, buf_len); EVP_DigestFinal_ex(&mdctx, shared_key, NULL); EVP_MD_CTX_cleanup(&mdctx); err: BN_free(UKM); BN_CTX_end(ctx); BN_CTX_free(ctx); EC_POINT_free(pnt); if (databuf) OPENSSL_free(databuf); if (hashbuf) OPENSSL_free(hashbuf); return 32; }