static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) { BIO *btmp; const EVP_MD *md; if ((btmp = BIO_new(BIO_f_md())) == NULL) { PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); goto err; } md = EVP_get_digestbyobj(alg->algorithm); if (md == NULL) { PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } BIO_set_md(btmp, md); if (*pbio == NULL) *pbio = btmp; else if (!BIO_push(*pbio, btmp)) { PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); goto err; } btmp = NULL; return 1; err: if (btmp) BIO_free(btmp); return 0; }
/* * Public */ const EVP_MD * GetDigestPtr(VALUE obj) { const EVP_MD *md; ASN1_OBJECT *oid = NULL; if (RB_TYPE_P(obj, T_STRING)) { const char *name = StringValueCStr(obj); md = EVP_get_digestbyname(name); if (!md) { oid = OBJ_txt2obj(name, 0); md = EVP_get_digestbyobj(oid); ASN1_OBJECT_free(oid); } if(!md) ossl_raise(rb_eRuntimeError, "Unsupported digest algorithm (%"PRIsVALUE").", obj); } else { EVP_MD_CTX *ctx; SafeGetDigest(obj, ctx); md = EVP_MD_CTX_md(ctx); } return md; }
static int PKCS7_SIGNER_INFO_sign_0(PKCS7_SIGNER_INFO *si) { EVP_MD_CTX mctx; EVP_PKEY_CTX *pctx; unsigned char *abuf = NULL; int alen; size_t siglen; const EVP_MD *md = NULL; md = EVP_get_digestbyobj(si->digest_alg->algorithm); if (md == NULL) return 0; EVP_MD_CTX_init(&mctx); if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) goto err; if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); goto err; } alen = ASN1_item_i2d((ASN1_VALUE *) si->auth_attr, &abuf, ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); if (!abuf) goto err; if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) goto err; OPENSSL_free(abuf); abuf = NULL; if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) goto err; abuf = OPENSSL_malloc(siglen); if (!abuf) goto err; if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) goto err; if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); goto err; } EVP_MD_CTX_cleanup(&mctx); ASN1_STRING_set0(si->enc_digest, abuf, siglen); return 1; err: if (abuf) OPENSSL_free(abuf); EVP_MD_CTX_cleanup(&mctx); return 0; }
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) { BIO *mdbio = NULL; ASN1_OBJECT *digestoid; const EVP_MD *digest; X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); digest = EVP_get_digestbyobj(digestoid); if (!digest) { CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_UNKNOWN_DIGEST_ALGORIHM); goto err; } mdbio = BIO_new(BIO_f_md()); if (!mdbio || !BIO_set_md(mdbio, digest)) { CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR); goto err; } return mdbio; err: if (mdbio) BIO_free(mdbio); return NULL; }
const EVP_MD* get_digest(lua_State* L, int idx, const char* def_alg) { const EVP_MD* md = NULL; switch (lua_type(L, idx)) { case LUA_TSTRING: md = EVP_get_digestbyname(lua_tostring(L, idx)); break; case LUA_TNUMBER: md = EVP_get_digestbynid(lua_tointeger(L, idx)); break; case LUA_TUSERDATA: if (auxiliar_getclassudata(L, "openssl.asn1_object", idx)) md = EVP_get_digestbyobj(CHECK_OBJECT(idx, ASN1_OBJECT, "openssl.asn1_object")); else if (auxiliar_getclassudata(L, "openssl.evp_digest", idx)) md = CHECK_OBJECT(idx, EVP_MD, "openssl.evp_digest"); break; case LUA_TNONE: case LUA_TNIL: if (def_alg != NULL) md = EVP_get_digestbyname(def_alg); break; } if (md==NULL) { luaL_argerror(L, idx, "must be a string, NID number or asn1_object identity digest method"); } return md; }
/* Generate a MAC */ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, unsigned char *mac, unsigned int *maclen) { const EVP_MD *md_type; HMAC_CTX hmac; unsigned char key[EVP_MAX_MD_SIZE], *salt; int saltlen, iter; int md_size = 0; int md_type_nid; if (!PKCS7_type_is_data(p12->authsafes)) { PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA); return 0; } salt = p12->mac->salt->data; saltlen = p12->mac->salt->length; if (!p12->mac->iter) iter = 1; else iter = ASN1_INTEGER_get(p12->mac->iter); if ((md_type = EVP_get_digestbyobj(p12->mac->dinfo->algor->algorithm)) == NULL) { PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); return 0; } md_size = EVP_MD_size(md_type); md_type_nid = EVP_MD_type(md_type); if (md_size < 0) return 0; if ((md_type_nid == NID_id_GostR3411_94 || md_type_nid == NID_id_GostR3411_2012_256 || md_type_nid == NID_id_GostR3411_2012_512) && !getenv("LEGACY_GOST_PKCS12")) { md_size = TK26_MAC_KEY_LEN; if (!pkcs12_gen_gost_mac_key(pass, passlen, salt, saltlen, iter, md_size, key, md_type)) { PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR); return 0; } } else if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, md_size, key, md_type)) { PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR); return 0; } HMAC_CTX_init(&hmac); if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) || !HMAC_Update(&hmac, p12->authsafes->d.data->data, p12->authsafes->d.data->length) || !HMAC_Final(&hmac, mac, maclen)) { HMAC_CTX_cleanup(&hmac); return 0; } HMAC_CTX_cleanup(&hmac); return 1; }
/* convert algorithm ID to EVP_MD, default SHA1 */ static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) { const EVP_MD *md; if (!alg) return EVP_sha1(); md = EVP_get_digestbyobj(alg->algorithm); if (md == NULL) RSAerr(RSA_F_RSA_ALGOR_TO_MD, RSA_R_UNKNOWN_DIGEST); return md; }
/* convert algorithm ID to EVP_MD, default SHA1 */ static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) { const EVP_MD *md; if (!alg) { return EVP_sha1(); } md = EVP_get_digestbyobj(alg->algorithm); if (md == NULL) { OPENSSL_PUT_ERROR(EVP, rsa_algor_to_md, EVP_R_UNKNOWN_DIGEST); } return md; }
/* convert algorithm ID to EVP_MD, default SHA1 */ static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) { const EVP_MD *md; if (!alg) { return EVP_sha1(); } md = EVP_get_digestbyobj(alg->algorithm); if (md == NULL) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); } return md; }
int CPK_MAP_str2index(const X509_ALGOR *algor, const char *str, int *index) { int ret = 0; const EVP_MD *md; unsigned char dgst[EVP_MAX_MD_SIZE]; unsigned int dgstlen; BIGNUM *bn = NULL; int i, num_index, num_subset; OPENSSL_assert(algor); OPENSSL_assert(algor->algorithm); OPENSSL_assert(str); OPENSSL_assert(strlen(str) > 0); if (!CPK_MAP_is_valid(algor)) { CPKerr(CPK_F_CPK_MAP_STR2INDEX, CPK_R_INVALID_MAP_ALGOR); goto err; } if (!index) { ret = CPK_MAP_num_index(algor); goto err; } if (!(md = EVP_get_digestbyobj(algor->algorithm))) { CPKerr(CPK_F_CPK_MAP_STR2INDEX, ERR_R_EVP_LIB); goto err; } if (!EVP_Digest(str, strlen(str), dgst, &dgstlen, md, NULL)) { CPKerr(CPK_F_CPK_MAP_STR2INDEX, ERR_R_EVP_LIB); return 0; } if (!(bn = BN_new())) { CPKerr(CPK_F_CPK_MAP_STR2INDEX, ERR_R_BN_LIB); goto err; } if (!BN_bin2bn(dgst, dgstlen, bn)) { CPKerr(CPK_F_CPK_MAP_STR2INDEX, ERR_R_BN_LIB); goto err; } num_index = CPK_MAP_num_index(algor); num_subset = CPK_MAP_num_subset(algor); for (i = 0; i < num_index; i++) { int r = BN_mod_word(bn, num_subset); index[i] = num_subset * i + r; } ret = num_index; err: if (bn) BN_free(bn); return ret; }
static X509 *X509_REQ_to_X509_a(X509_REQ *r, int days, EVP_PKEY *pkey) { X509 *ret = NULL; X509_CINF *xi = NULL; X509_NAME *xn; EVP_PKEY* pubkey; if ((ret = X509_new()) == NULL) { X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE); goto err; } /* duplicate the request */ xi = ret->cert_info; if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) { if ((xi->version = M_ASN1_INTEGER_new()) == NULL) goto err; if (!ASN1_INTEGER_set(xi->version, 2)) goto err; /* xi->extensions=ri->attributes; <- bad, should not ever be done ri->attributes=NULL; */ } xn = X509_REQ_get_subject_name(r); if (X509_set_subject_name(ret, xn) == 0) goto err; if (X509_set_issuer_name(ret, xn) == 0) goto err; if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL) goto err; if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) == NULL) goto err; pubkey = X509_REQ_get_pubkey(r); X509_set_pubkey(ret, pubkey); EVP_PKEY_free(pubkey); if (!X509_sign(ret, pkey, EVP_get_digestbyobj(r->sig_alg->algorithm))) goto err; if (0) { err: X509_free(ret); ret = NULL; } return (ret); }
/* Generate a MAC */ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, unsigned char *mac, unsigned int *maclen) { const EVP_MD *md_type; HMAC_CTX hmac; unsigned char key[EVP_MAX_MD_SIZE], *salt; int saltlen, iter; int md_size; if (!PKCS7_type_is_data(p12->authsafes)) { PKCS12error(PKCS12_R_CONTENT_TYPE_NOT_DATA); return 0; } salt = p12->mac->salt->data; saltlen = p12->mac->salt->length; if (!p12->mac->iter) iter = 1; else if ((iter = ASN1_INTEGER_get(p12->mac->iter)) <= 0) { PKCS12error(PKCS12_R_DECODE_ERROR); return 0; } if (!(md_type = EVP_get_digestbyobj( p12->mac->dinfo->algor->algorithm))) { PKCS12error(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); return 0; } md_size = EVP_MD_size(md_type); if (md_size < 0) return 0; if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, md_size, key, md_type)) { PKCS12error(PKCS12_R_KEY_GEN_ERROR); return 0; } HMAC_CTX_init(&hmac); if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) || !HMAC_Update(&hmac, p12->authsafes->d.data->data, p12->authsafes->d.data->length) || !HMAC_Final(&hmac, mac, maclen)) { HMAC_CTX_cleanup(&hmac); return 0; } HMAC_CTX_cleanup(&hmac); return 1; }
const EVP_MD* get_digest(lua_State* L, int idx) { const EVP_MD* md = NULL; if (lua_isstring(L, idx)) md = EVP_get_digestbyname(lua_tostring(L, idx)); else if (lua_isnumber(L, idx)) md = EVP_get_digestbynid(lua_tointeger(L, idx)); else if (auxiliar_isclass(L, "openssl.asn1_object", idx)) md = EVP_get_digestbyobj(CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object")); else if (auxiliar_isclass(L, "openssl.evp_digest", idx)) md = CHECK_OBJECT(idx, EVP_MD, "openssl.evp_digest"); else { luaL_error(L, "argument #1 must be a string, NID number or asn1_object identity digest method"); } return md; }
/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */ static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) { const EVP_MD *md; if (!alg) { return EVP_sha1(); } /* Check mask and lookup mask hash algorithm */ if (OBJ_obj2nid(alg->algorithm) != NID_mgf1 || maskHash == NULL) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); return NULL; } md = EVP_get_digestbyobj(maskHash->algorithm); if (md == NULL) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); return NULL; } return md; }
/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */ static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) { const EVP_MD *md; if (!alg) { return EVP_sha1(); } /* Check mask and lookup mask hash algorithm */ if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) { OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNSUPPORTED_MASK_ALGORITHM); return NULL; } if (!maskHash) { OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNSUPPORTED_MASK_PARAMETER); return NULL; } md = EVP_get_digestbyobj(maskHash->algorithm); if (md == NULL) { OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNKNOWN_MASK_DIGEST); return NULL; } return md; }
/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */ static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) { const EVP_MD *md; if (!alg) return EVP_sha1(); /* Check mask and lookup mask hash algorithm */ if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) { RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNSUPPORTED_MASK_ALGORITHM); return NULL; } if (!maskHash) { RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNSUPPORTED_MASK_PARAMETER); return NULL; } md = EVP_get_digestbyobj(maskHash->algorithm); if (md == NULL) { RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNKNOWN_MASK_DIGEST); return NULL; } return md; }
/* * r = rand(), |r| = hashlen * k = HashToRange(r||Hash(m), q), k in [0, q-1] * U = [k]P in E/F_p * Q = HashToPoint(ID) in E/F_p * v = Hash(e(Ppub, Q)^k) xor r, |v| == hashlen * w = HashBytes(r) xor m */ BFCiphertextBlock *BFIBE_do_encrypt(BFPublicParameters *mpk, const unsigned char *in, size_t inlen, const char *id, size_t idlen) { int e = 1; BFCiphertextBlock *ret = NULL; BN_CTX *bn_ctx = NULL; EC_GROUP *group = NULL; EC_POINT *Ppub = NULL; EC_POINT *point = NULL; BN_GFP2 *theta = NULL; BIGNUM *k; const EVP_MD *md; KDF_FUNC hash_bytes; unsigned char rho[EVP_MAX_MD_SIZE * 2]; unsigned char buf[EVP_MAX_MD_SIZE]; unsigned int len; size_t size; int i; if (!mpk || !in || inlen <= 0 || !id || idlen <= 0) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER); return NULL; } /* BN_CTX */ if (!(bn_ctx = BN_CTX_new())) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_MALLOC_FAILURE); goto end; } BN_CTX_start(bn_ctx); /* EC_GROUP */ if (!(group = EC_GROUP_new_type1curve(mpk->p, mpk->pointP->x, mpk->pointP->y, mpk->q, bn_ctx))) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, BFIBE_R_PARSE_MPK_FAILURE); goto end; } ret = BFCiphertextBlock_new(); Ppub = EC_POINT_new(group); point = EC_POINT_new(group); theta = BN_GFP2_new(); k = BN_CTX_get(bn_ctx); if (!ret || !point || !Ppub || !k || !theta) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_MALLOC_FAILURE); goto end; } /* get kdf from mpk->hashfcn */ if (!(md = EVP_get_digestbyobj(mpk->hashfcn))) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, BFIBE_R_INVALID_BFIBE_HASHFUNC); goto end; } if (!(hash_bytes = KDF_get_ibcs(md))) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, BFIBE_R_INVALID_BFIBE_HASHFUNC); goto end; } /* ret->version */ ret->version = BFIBE_VERSION; /* rho = Rand(hashlen) */ if (!RAND_bytes(rho, EVP_MD_size(md))) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, BFIBE_R_RAND_FAILURE); goto end; } /* k = HashToRange(rho||Hash(in), q) in [0, q - 1] */ len = EVP_MD_size(md); if (!EVP_Digest(in, inlen, rho + EVP_MD_size(md), &len, md, NULL)) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EVP_LIB); goto end; } if (!BN_hash_to_range(md, &k, rho, EVP_MD_size(md) * 2, mpk->q, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_BN_LIB); goto end; } /* ret->u = mpk->pointP * k in E/F_p, mpk->pointP is the generator */ if (!EC_POINT_mul(group, point, k, NULL, NULL, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EC_LIB); goto end; } if (!EC_POINT_get_affine_coordinates_GFp(group, point, ret->u->x, ret->u->y, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EC_LIB); goto end; } /* theta = e(mpk->pointPpub, HashToPoint(ID)) */ if (!EC_POINT_set_affine_coordinates_GFp(group, Ppub, mpk->pointPpub->x, mpk->pointPpub->y, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EC_LIB); goto end; } if (!EC_POINT_hash2point(group, md, id, idlen, point, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EC_LIB); goto end; } if (!EC_type1curve_tate(group, theta, Ppub, point, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EC_LIB); goto end; } /* theta = theta^k */ if (!BN_GFP2_exp(theta, theta, k, mpk->p, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EC_LIB); goto end; } /* ret->v = Hash(theta) xor rho */ size = sizeof(buf); if (!BN_GFP2_canonical(theta, buf, &size, 0, mpk->p, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_BN_LIB); goto end; } len = sizeof(buf); if (!EVP_Digest(buf, size, buf, &len, md, NULL)) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_EVP_LIB); goto end; } for (i = 0; i < EVP_MD_size(md); i++) { buf[i] ^= rho[i]; } if (!ASN1_OCTET_STRING_set(ret->v, buf, EVP_MD_size(md))) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_ASN1_LIB); goto end; } /* ret->w = HashBytes(rho) xor m */ if (!ASN1_OCTET_STRING_set(ret->w, NULL, inlen)) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, ERR_R_MALLOC_FAILURE); goto end; } size = inlen; if (!hash_bytes(rho, EVP_MD_size(md), ret->w->data, &size)) { BFIBEerr(BFIBE_F_BFIBE_DO_ENCRYPT, BFIBE_R_HASH_BYTES_FAILURE); goto end; } for (i = 0; i < inlen; i++) { ret->w->data[i] ^= in[i]; } e = 0; end: if (e && ret) { BFCiphertextBlock_free(ret); ret = NULL; } if (bn_ctx) { BN_CTX_end(bn_ctx); } BN_CTX_free(bn_ctx); EC_GROUP_free(group); EC_POINT_free(Ppub); EC_POINT_free(point); BN_GFP2_free(theta); return ret; }
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) { int i; BIO *out=NULL,*btmp=NULL; X509_ALGOR *xa; const EVP_MD *evp_md; const EVP_CIPHER *evp_cipher=NULL; STACK_OF(X509_ALGOR) *md_sk=NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; X509_ALGOR *xalg=NULL; PKCS7_RECIP_INFO *ri=NULL; EVP_PKEY *pkey; i=OBJ_obj2nid(p7->type); p7->state=PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: md_sk=p7->d.sign->md_algs; break; case NID_pkcs7_signedAndEnveloped: rsk=p7->d.signed_and_enveloped->recipientinfo; md_sk=p7->d.signed_and_enveloped->md_algs; xalg=p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_enveloped: rsk=p7->d.enveloped->recipientinfo; xalg=p7->d.enveloped->enc_data->algorithm; evp_cipher=p7->d.enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; default: PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } if (md_sk != NULL) { for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) { xa=sk_X509_ALGOR_value(md_sk,i); if ((btmp=BIO_new(BIO_f_md())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); goto err; } evp_md=EVP_get_digestbyobj(xa->algorithm); if (evp_md == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } BIO_set_md(btmp,evp_md); if (out == NULL) out=btmp; else BIO_push(out,btmp); btmp=NULL; } } if (evp_cipher != NULL) { unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; int keylen,ivlen; int jj,max; unsigned char *tmp; EVP_CIPHER_CTX *ctx; if ((btmp=BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); goto err; } BIO_get_cipher_ctx(btmp, &ctx); keylen=EVP_CIPHER_key_length(evp_cipher); ivlen=EVP_CIPHER_iv_length(evp_cipher); if (RAND_bytes(key,keylen) <= 0) goto err; xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen); EVP_CipherInit_ex(ctx, evp_cipher, NULL, key, iv, 1); if (ivlen > 0) { if (xalg->parameter == NULL) xalg->parameter=ASN1_TYPE_new(); if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) goto err; } /* Lets do the pub key stuff :-) */ max=0; for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); if (ri->cert == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); goto err; } pkey=X509_get_pubkey(ri->cert); jj=EVP_PKEY_size(pkey); EVP_PKEY_free(pkey); if (max < jj) max=jj; } if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE); goto err; } for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); pkey=X509_get_pubkey(ri->cert); jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); EVP_PKEY_free(pkey); if (jj <= 0) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB); OPENSSL_free(tmp); goto err; } M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj); } OPENSSL_free(tmp); OPENSSL_cleanse(key, keylen); if (out == NULL) out=btmp; else BIO_push(out,btmp); btmp=NULL; } if (bio == NULL) { if (PKCS7_is_detached(p7)) bio=BIO_new(BIO_s_null()); else { ASN1_OCTET_STRING *os; os = PKCS7_get_octet_string(p7->d.sign->contents); if (os && os->length > 0) bio = BIO_new_mem_buf(os->data, os->length); if(bio == NULL) { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } } } BIO_push(out,bio); bio=NULL; if (0) { err: if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); out=NULL; } return(out); }
static SM9Signature *SM9_do_sign_type1curve(SM9PublicParameters *mpk, const unsigned char *dgst, size_t dgstlen, SM9PrivateKey *sk) { int e = 1; SM9Signature *ret = NULL; BN_CTX *bn_ctx = NULL; EC_GROUP *group = NULL; EC_POINT *point = NULL; BN_GFP2 *w = NULL; unsigned char *buf = NULL; BIGNUM *r; BIGNUM *l; const EVP_MD *md; int point_form = POINT_CONVERSION_UNCOMPRESSED; size_t size; if (!mpk || !dgst || dgstlen <= 0 || !sk) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if (dgstlen > EVP_MAX_MD_SIZE) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, SM9_R_INVALID_DIGEST); return NULL; } /* BN_CTX */ if (!(bn_ctx = BN_CTX_new())) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_MALLOC_FAILURE); goto end; } BN_CTX_start(bn_ctx); /* EC_GROUP */ if (!(group = EC_GROUP_new_type1curve_ex(mpk->p, mpk->a, mpk->b, mpk->pointP1->data, mpk->pointP1->length, mpk->order, mpk->cofactor, bn_ctx))) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, SM9_R_INVALID_TYPE1CURVE); goto end; } /* malloc */ ret = SM9Signature_new(); point = EC_POINT_new(group); r = BN_CTX_get(bn_ctx); l = BN_CTX_get(bn_ctx); if (!ret || !point || !r || !l) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_MALLOC_FAILURE); goto end; } /* md = mpk->hashfcn */ if (!(md = EVP_get_digestbyobj(mpk->hashfcn))) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, SM9_R_INVALID_MD); goto end; } do { /* rand r in [1, mpk->order - 1] */ do { if (!BN_rand_range(r, mpk->order)) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_BN_LIB); goto end; } } while (BN_is_zero(r)); /* get w = mpk->g = e(mpk->pointP1, mpk->pointPpub) */ if (!BN_bn2gfp2(mpk->g1, w, mpk->p, bn_ctx)) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_BN_LIB); goto end; } /* w = w^r = (mpk->g)^r in F_p^2 */ if (!BN_GFP2_exp(w, w, r, mpk->p, bn_ctx)) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_BN_LIB); goto end; } /* prepare w buf and canonical(w, order=0) */ if (!BN_GFP2_canonical(w, NULL, &size, 0, mpk->p, bn_ctx)) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_BN_LIB); goto end; } if (!(buf = OPENSSL_malloc(size))) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_MALLOC_FAILURE); goto end; } if (!BN_GFP2_canonical(w, buf, &size, 0, mpk->p, bn_ctx)) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_BN_LIB); goto end; } /* ret->h = H2(H(m)||w) in range defined by mpk->order */ if (!SM9_hash2(md, &ret->h, dgst, dgstlen, buf, size, mpk->order, bn_ctx)) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_SM9_LIB); goto end; } /* l = (r - ret->h) (mod mpk->order) */ if (!BN_mod_sub(l, r, ret->h, mpk->order, bn_ctx)) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_BN_LIB); goto end; } /* if l == 0, re-generate r */ } while (BN_is_zero(l)); /* point = sk->prointPoint */ if (!EC_POINT_oct2point(group, point, sk->privatePoint->data, sk->privatePoint->length, bn_ctx)) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_EC_LIB); goto end; } /* sig->pointS = sk->privatePoint * l */ if (!EC_POINT_mul(group, point, NULL, point, l, bn_ctx)) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_EC_LIB); goto end; } if (!(size = EC_POINT_point2oct(group, point, point_form, NULL, 0, bn_ctx))) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_EC_LIB); goto end; } if (!ASN1_OCTET_STRING_set(ret->pointS, NULL, size)) { SM9err(SM9_F_SM9_DO_SIGN_TYPE1CURVE, ERR_R_EC_LIB); goto end; } if (!EC_POINT_point2oct(group, point, point_form, ret->pointS->data, ret->pointS->length, bn_ctx)) { goto end; } e = 0; end: if (e && ret) { SM9Signature_free(ret); ret = NULL; } if (bn_ctx) { BN_CTX_end(bn_ctx); } BN_CTX_free(bn_ctx); EC_GROUP_free(group); EC_POINT_free(point); BN_GFP2_free(w); OPENSSL_free(buf); return NULL; }
BFPrivateKeyBlock *BFIBE_extract_private_key(BFPublicParameters *mpk, BFMasterSecret *msk, const char *id, size_t idlen) { int e = 1; BFPrivateKeyBlock *ret = NULL; EC_GROUP *group = NULL; EC_POINT *point = NULL; BN_CTX *bn_ctx = NULL; const EVP_MD *md; if (!mpk || !msk || !id || idlen <= 0) { BFIBEerr(BFIBE_F_BFIBE_EXTRACT_PRIVATE_KEY, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if (!(bn_ctx = BN_CTX_new())) { BFIBEerr(BFIBE_F_BFIBE_EXTRACT_PRIVATE_KEY, ERR_R_MALLOC_FAILURE); goto end; } /* * get EC_GROUP from mpk->{p, q, pointP} * get EVP_MD from mpk->hashfcn */ if (!(group = EC_GROUP_new_type1curve(mpk->p, mpk->pointP->x, mpk->pointP->y, mpk->q, bn_ctx))) { BFIBEerr(BFIBE_F_BFIBE_EXTRACT_PRIVATE_KEY, BFIBE_R_PARSE_CURVE_FAILURE); goto end; } if (!(md = EVP_get_digestbyobj(mpk->hashfcn))) { BFIBEerr(BFIBE_F_BFIBE_EXTRACT_PRIVATE_KEY, BFIBE_R_INVALID_BFIBE_HASHFUNC); goto end; } /* prepare tmp variables */ point = EC_POINT_new(group); if (!point) { BFIBEerr(BFIBE_F_BFIBE_EXTRACT_PRIVATE_KEY, ERR_R_MALLOC_FAILURE); goto end; } /* * set ret->version * set ret->privateKey = msk->masterSecret * HashToPoint(ID) */ if (!(ret = BFPrivateKeyBlock_new())) { BFIBEerr(BFIBE_F_BFIBE_EXTRACT_PRIVATE_KEY, ERR_R_MALLOC_FAILURE); return NULL; } ret->version = BFIBE_VERSION; if (!EC_POINT_hash2point(group, md, id, idlen, point, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_EXTRACT_PRIVATE_KEY, ERR_R_EC_LIB); goto end; } if (!EC_POINT_mul(group, point, NULL, point, msk->masterSecret, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_EXTRACT_PRIVATE_KEY, ERR_R_EC_LIB); goto end; } if (!EC_POINT_get_affine_coordinates_GFp(group, point, ret->privateKey->x, ret->privateKey->y, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_EXTRACT_PRIVATE_KEY, ERR_R_EC_LIB); goto end; } e = 0; end: if (e && ret) { BFPrivateKeyBlock_free(ret); ret = NULL; } EC_GROUP_free(group); EC_POINT_free(point); BN_CTX_free(bn_ctx); return ret; }
static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, EVP_PKEY *pkey) { int rv = -1; int saltlen; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_PSS_PARAMS *pss; X509_ALGOR *maskHash; EVP_PKEY_CTX *pkctx; /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); return -1; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg, &maskHash); if (pss == NULL) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_PSS_PARAMETERS); goto err; } /* Check mask and lookup mask hash algorithm */ if (pss->maskGenAlgorithm) { if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) != NID_mgf1) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_ALGORITHM); goto err; } if (!maskHash) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_PARAMETER); goto err; } mgf1md = EVP_get_digestbyobj(maskHash->algorithm); if (mgf1md == NULL) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_MASK_DIGEST); goto err; } } else mgf1md = EVP_sha1(); if (pss->hashAlgorithm) { md = EVP_get_digestbyobj(pss->hashAlgorithm->algorithm); if (md == NULL) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_PSS_DIGEST); goto err; } } else md = EVP_sha1(); if (pss->saltLength) { saltlen = ASN1_INTEGER_get(pss->saltLength); /* Could perform more salt length sanity checks but the main * RSA routines will trap other invalid values anyway. */ if (saltlen < 0) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_SALT_LENGTH); goto err; } } else saltlen = 20; /* low-level routines support only trailer field 0xbc (value 1) * and PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_TRAILER); goto err; } /* We have all parameters now set up context */ if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) goto err; if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) goto err; /* Carry on */ rv = 2; err: RSA_PSS_PARAMS_free(pss); if (maskHash) X509_ALGOR_free(maskHash); return rv; }
int BFIBE_do_decrypt(BFPublicParameters *mpk, const BFCiphertextBlock *in, unsigned char *out, size_t *outlen, BFPrivateKeyBlock *sk) { int ret = 0; BN_CTX *bn_ctx = NULL; EC_GROUP *group = NULL; EC_POINT *point = NULL; EC_POINT *point1 = NULL; BN_GFP2 *theta = NULL; BIGNUM *k; const EVP_MD *md; KDF_FUNC hash_bytes; unsigned char rho[EVP_MAX_MD_SIZE * 2]; size_t size; unsigned int len; int i; if (!mpk || !in || !outlen || !sk) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (!out) { *outlen = in->w->length; return 1; } if (*outlen < in->w->length) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, BFIBE_R_BUFFER_TOO_SMALL); return 0; } /* BN_CTX */ if (!(bn_ctx = BN_CTX_new())) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_MALLOC_FAILURE); goto end; } BN_CTX_start(bn_ctx); /* EC_GROUP */ if (!(group = EC_GROUP_new_type1curve(mpk->p, mpk->pointP->x, mpk->pointP->y, mpk->q, bn_ctx))) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, BFIBE_R_INVALID_TYPE1CURVE); goto end; } point = EC_POINT_new(group); point1 = EC_POINT_new(group); theta = BN_GFP2_new(); k = BN_CTX_get(bn_ctx); if (!point || !point1 || !theta || !k) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_MALLOC_FAILURE); goto end; } /* theta = e(ciphertext->u, sk->privateKey) */ if (!EC_POINT_set_affine_coordinates_GFp(group, point, in->u->x, in->u->y, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EC_LIB); goto end; } if (!EC_POINT_set_affine_coordinates_GFp(group, point1, sk->privateKey->x, sk->privateKey->y, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EC_LIB); goto end; } if (!EC_type1curve_tate(group, theta, point, point1, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EC_LIB); goto end; } /* md = mpk->hashfcn */ if (!(md = EVP_get_digestbyobj(mpk->hashfcn))) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, BFIBE_R_INVALID_BFIBE_HASHFUNC); goto end; } /* rho = Hash(Canoncial(theta)) xor ciphertext->v */ size = sizeof(rho); if (!BN_GFP2_canonical(theta, rho, &size, 0, mpk->p, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EC_LIB); goto end; } len = size; if (!EVP_Digest(rho, size, rho, &len, md, NULL)) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EVP_LIB); goto end; } for (i = 0; i < EVP_MD_size(md); i++) { rho[i] ^= in->v->data[i]; } /* function hash_bytes() = kdf(md) */ if (!(hash_bytes = KDF_get_ibcs(md))) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, BFIBE_R_INVALID_BFIBE_HASHFUNC); goto end; } /* out = HashBytes(rho) xor ciphertext->w */ size = in->w->length; if (!hash_bytes(rho, EVP_MD_size(md), out, &size)) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, BFIBE_R_KDF_FAILURE); goto end; } for (i = 0; i < in->w->length; i++) { out[i] ^= in->w->data[i]; } /* k = HashToRange(rho || Hash(out)) in [0, mpk->q) */ len = EVP_MD_size(md); if (!EVP_Digest(out, in->w->length, rho + EVP_MD_size(md), &len, md, NULL)) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EVP_LIB); goto end; } if (!BN_hash_to_range(md, &k, rho, EVP_MD_size(md) * 2, mpk->q, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_BN_LIB); goto end; } /* Verify that in->u == mpk->pointP * k */ if (!EC_POINT_mul(group, point, k, NULL, NULL, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, ERR_R_EC_LIB); goto end; } if (1 != EC_POINT_cmp_fppoint(group, point, in->u, bn_ctx)) { BFIBEerr(BFIBE_F_BFIBE_DO_DECRYPT, BFIBE_R_BFIBE_CIPHERTEXT_FAILURE); goto end; } *outlen = in->w->length; ret = 1; end: if (bn_ctx) { BN_CTX_end(bn_ctx); } BN_CTX_free(bn_ctx); EC_GROUP_free(group); EC_POINT_free(point); EC_POINT_free(point1); BN_GFP2_free(theta); return ret; }
int SM9_do_verify_type1curve(SM9PublicParameters *mpk, const unsigned char *dgst, size_t dgstlen, const SM9Signature *sig, const char *id, size_t idlen) { int ret = 0; BN_CTX *bn_ctx = NULL; EC_GROUP *group = NULL; EC_POINT *point = NULL; EC_POINT *pointS = NULL; EC_POINT *Ppub = NULL; BN_GFP2 *t = NULL; BN_GFP2 *u = NULL; BN_GFP2 *w = NULL; unsigned char *buf = NULL; BIGNUM *h1; BIGNUM *h2; size_t size; const EVP_MD *md; if (!mpk || !dgst || dgstlen <= 0 || !sig || !id || idlen <= 0) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (dgstlen > EVP_MAX_MD_SIZE) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, SM9_R_INVALID_DIGEST); return 0; } if (idlen > SM9_MAX_ID_LENGTH) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, SM9_R_INVALID_ID); return 0; } /* BN_CTX */ if (!(bn_ctx = BN_CTX_new())) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, ERR_R_MALLOC_FAILURE); goto end; } BN_CTX_start(bn_ctx); /* EC_GROUP */ if (!(group = EC_GROUP_new_type1curve_ex(mpk->p, mpk->a, mpk->b, mpk->pointP1->data, mpk->pointP1->length, mpk->order, mpk->cofactor, bn_ctx))) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, SM9_R_INVALID_TYPE1CURVE); goto end; } /* malloc */ point = EC_POINT_new(group); pointS = EC_POINT_new(group); Ppub = EC_POINT_new(group); t = BN_GFP2_new(); u = BN_GFP2_new(); w = BN_GFP2_new(); h1 = BN_CTX_get(bn_ctx); h2 = BN_CTX_get(bn_ctx); if (!point || !pointS || !Ppub || !t || !u || !w || !h1 || !h2) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, ERR_R_MALLOC_FAILURE); goto end; } /* md = mpk->hashfcn */ if (!(md = EVP_get_digestbyobj(mpk->hashfcn))) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, SM9_R_INVALID_MD); goto end; } /* check sig->h in [1, mpk->order - 1] */ //FIXME: do we need to check sig->h > 0 ? if (BN_is_zero(sig->h) || BN_cmp(sig->h, mpk->order) >= 0) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, SM9_R_INVALID_SIGNATURE); goto end; } /* pointS = sig->pointS */ if (!EC_POINT_oct2point(group, pointS, sig->pointS->data, sig->pointS->length, bn_ctx)) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, SM9_R_INVALID_SIGNATURE); goto end; } /* decode t from mpk->g in F_p^2 */ if (!BN_bn2gfp2(mpk->g1, t, mpk->p, bn_ctx)) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, ERR_R_BN_LIB); goto end; } /* t = t^(sig->h) = (mpk->g)^(sig->h) in F_p^2 */ if (!BN_GFP2_exp(t, t, sig->h, mpk->p, bn_ctx)) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, ERR_R_BN_LIB); goto end; } /* h1 = H1(ID||hid) to range [0, mpk->order) */ if (!SM9_hash1(md, &h1, id, idlen, SM9_HID, mpk->order, bn_ctx)) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, ERR_R_SM9_LIB); goto end; } /* point = mpk->pointP2 * h1 + mpk->pointPpub */ if (!EC_POINT_mul(group, point, h1, NULL, NULL, bn_ctx)) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, ERR_R_EC_LIB); goto end; } if (!EC_POINT_oct2point(group, Ppub, mpk->pointPpub->data, mpk->pointPpub->length, bn_ctx)) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, SM9_R_INVALID_TYPE1CURVE); goto end; } if (!EC_POINT_add(group, point, point, Ppub, bn_ctx)) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, ERR_R_EC_LIB); goto end; } /* u = e(sig->pointS, point) in F_p^2 */ if (!EC_type1curve_tate(group, u, pointS, point, bn_ctx)) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, SM9_R_COMPUTE_PAIRING_FAILURE); goto end; } /* w = u * t in F_p^2 */ if (!BN_GFP2_mul(w, u, t, mpk->p, bn_ctx)) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, ERR_R_BN_LIB); goto end; } /* buf = canonical(w) */ if (!BN_GFP2_canonical(w, NULL, &size, 0, mpk->p, bn_ctx)) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, ERR_R_BN_LIB); goto end; } if (!(buf = OPENSSL_malloc(size))) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, ERR_R_MALLOC_FAILURE); goto end; } if (!BN_GFP2_canonical(w, buf, &size, 0, mpk->p, bn_ctx)) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, ERR_R_BN_LIB); goto end; } /* h2 = H2(M||w) in [0, mpk->order - 1] */ if (!SM9_hash2(md, &h2, dgst, dgstlen, buf, size, mpk->order, bn_ctx)) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, SM9_R_HASH_FAILURE); goto end; } /* check if h2 == sig->h */ if (BN_cmp(h2, sig->h) != 0) { SM9err(SM9_F_SM9_DO_VERIFY_TYPE1CURVE, SM9_R_INVALID_SIGNATURE); goto end; } //FIXME: return value of sig verify ret = 1; end: if (bn_ctx) { BN_CTX_end(bn_ctx); } BN_CTX_free(bn_ctx); EC_GROUP_free(group); EC_POINT_free(point); EC_POINT_free(pointS); EC_POINT_free(Ppub); BN_GFP2_free(t); BN_GFP2_free(u); BN_GFP2_free(w); OPENSSL_free(buf); return ret; }