Exemple #1
0
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;

}
Exemple #2
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;
}
Exemple #3
0
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;

}
Exemple #4
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;
	}
Exemple #5
0
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;
}
Exemple #6
0
/* 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;
}
Exemple #7
0
/* 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;
}
Exemple #8
0
/* 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;
}
Exemple #9
0
/* 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;
}
Exemple #10
0
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;
}
Exemple #11
0
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);
}
Exemple #12
0
/* 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;
}
Exemple #13
0
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;
}
Exemple #14
0
/* 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;
}
Exemple #15
0
/* 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;
}
Exemple #16
0
/* 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;
}
Exemple #17
0
/*
 * 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;
}
Exemple #18
0
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);
	}
Exemple #19
0
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;
}
Exemple #20
0
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;
}
Exemple #22
0
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;
}
Exemple #23
0
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;
}