//Hardcoding this test code for PSS-SHA1
void RsaPssVerification(unsigned int uKeySize, const unsigned char* pMsg, const unsigned char* pSign,
                       unsigned int E, const unsigned char* pN, const unsigned char* pD)
{
    RSA* pRsaKey = NULL;
    const unsigned char* pDigest = NULL;
    size_t uDigestLen = 20;
    unsigned char EM[512];
    unsigned char signature[512];
    unsigned int uLen = 0;
    int status = 0;

    // Generate an RSA key pair
    pRsaKey = GetRsaKey(E, pN, pD);
    if (pRsaKey) {
        //Use the already hashed input message and compute the PSS padded data with max salt size
        pDigest = pMsg;
        printbin("HASH", pDigest, 20);
        status = RSA_padding_add_PKCS1_PSS(pRsaKey, EM, pDigest, EVP_sha1(), -2);
        printbin("EM", EM, uKeySize);
        if (status == 1)  {
            //Now do Rsa Signature (RSA private encrypt)
            status = RSA_private_encrypt(uKeySize, EM, signature, pRsaKey, RSA_NO_PADDING);
            printbin("Sign", signature, uKeySize);
            if (status != -1) {
                //Now its time to verify the signature using RSA public decryption
                //We could directly use signature, but we are here to verify the signature generated by HW KM1
                uLen = hex2bin(signature, pSign);
                //assert(uLen == uKeySize)
                printbin("Sign", signature, uLen);
                status = RSA_public_decrypt(uKeySize, signature, EM, pRsaKey, RSA_NO_PADDING);
                printbin("EM", EM, uKeySize);
                if (status != -1) {
                    //Verify the data against the message with expecting max salt length from ssignature
                    status = RSA_verify_PKCS1_PSS(pRsaKey, pDigest, EVP_sha1(), EM, -2);
                    if (status == 1) {
                        printf("GREAT: Signature verification successful\n");
                    } else {
                        printf("RSA_verify_PKCS1_PSS failed with error %s\n", ERR_error_string(ERR_get_error(), NULL));
                    }
                } else {
                    printf("RSA_public_decrypt failed with error %s\n", ERR_error_string(ERR_get_error(), NULL));
                }
            } else {
                printf("RSA_private_encrypt failed with error %s\n", ERR_error_string(ERR_get_error(), NULL));
            }
        } else {
            printf("RSA_padding_add_PKCS1_PSS failed with error %s\n", ERR_error_string(ERR_get_error(), NULL));
        }
    }

    if (pRsaKey) {
        RSA_free(pRsaKey);
    }
}
Exemple #2
0
bool
signHelper (
    RSA* key,
    Slice message,
    Buffer& modulus,
    Buffer& signature)
{
    int const keySize = RSA_size(key);
    if (!checkModulusLength (keySize))
        return false;

    sha256_hasher h;
    h (message.data(), message.size());
    auto digest = static_cast<sha256_hasher::result_type>(h);

    Buffer buf;

    // Pad the result (-1 -> use hash length as salt length)
    if (!RSA_padding_add_PKCS1_PSS(key,
            buf.alloc(keySize), digest.data(),
            EVP_sha256(), -1))
        return false;

    // Sign - we've manually padded the input already.
    auto ret = RSA_private_encrypt(keySize, buf.data(),
        signature.alloc (buf.size()), key, RSA_NO_PADDING);

    if (ret == -1)
        return false;

    BN_bn2bin (key->n, modulus.alloc(BN_num_bytes (key->n)));
    return true;
}
static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
					const unsigned char *tbs, size_t tbslen)
	{
	int ret;
	RSA_PKEY_CTX *rctx = (RSA_PKEY_CTX*)ctx->data;
	RSA *rsa = ctx->pkey->pkey.rsa;

	if (rctx->md)
		{
		if (tbslen != (size_t)EVP_MD_size(rctx->md))
			{
			RSAerr(RSA_F_PKEY_RSA_SIGN,
					RSA_R_INVALID_DIGEST_LENGTH);
			return -1;
			}
		if (rctx->pad_mode == RSA_X931_PADDING)
			{
			if (!setup_tbuf(rctx, ctx))
				return -1;
			TINYCLR_SSL_MEMCPY(rctx->tbuf, tbs, tbslen);
			rctx->tbuf[tbslen] =
				RSA_X931_hash_id(EVP_MD_type(rctx->md));
			ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
						sig, rsa, RSA_X931_PADDING);
			}
		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
			{
			unsigned int sltmp;
			ret = RSA_sign(EVP_MD_type(rctx->md),
						tbs, tbslen, sig, &sltmp, rsa);
			if (ret <= 0)
				return ret;
			ret = sltmp;
			}
		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
			{
			if (!setup_tbuf(rctx, ctx))
				return -1;
			if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs,
						rctx->md, rctx->saltlen))
				return -1;
			ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
						sig, rsa, RSA_NO_PADDING);
			}
		else
			return -1;
		}
	else
		ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
							rctx->pad_mode);
	if (ret < 0)
		return ret;
	*siglen = ret;
	return 1;
	}
Exemple #4
0
		void rsa_key::padding_add_PKCS1_PSS(void* out, size_t out_len, const void* buf, size_t buf_len, hash::message_digest_algorithm algorithm, int salt_len) const
		{
			assert(out_len >= algorithm.result_size());
			assert(buf_len >= algorithm.result_size());

			if (out_len < algorithm.result_size())
			{
				throw std::invalid_argument("out_len");
			}

			if (buf_len < algorithm.result_size())
			{
				throw std::invalid_argument("buf_len");
			}

			throw_error_if_not(RSA_padding_add_PKCS1_PSS(ptr().get(), static_cast<unsigned char*>(out), static_cast<const unsigned char*>(buf), algorithm.raw(), salt_len) != 0);
		}
Exemple #5
0
static bool _cjose_jws_build_sig_ps(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err)
{
    bool retval = false;
    uint8_t *em = NULL;
    size_t em_len = 0;

    // ensure jwk is private RSA
    if (jwk->kty != CJOSE_JWK_KTY_RSA)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        goto _cjose_jws_build_sig_ps_cleanup;
    }
    RSA *rsa = (RSA *)jwk->keydata;
    BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
    _cjose_jwk_rsa_get(rsa, &rsa_n, &rsa_e, &rsa_d);
    if (!rsa || !rsa_e || !rsa_n || !rsa_d)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    // make sure we have an alg header
    json_t *alg_obj = json_object_get(jws->hdr, CJOSE_HDR_ALG);
    if (NULL == alg_obj)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }
    const char *alg = json_string_value(alg_obj);

    // build digest using SHA-256/384/512 digest algorithm
    const EVP_MD *digest_alg = NULL;
    if (strcmp(alg, CJOSE_HDR_ALG_PS256) == 0)
        digest_alg = EVP_sha256();
    else if (strcmp(alg, CJOSE_HDR_ALG_PS384) == 0)
        digest_alg = EVP_sha384();
    else if (strcmp(alg, CJOSE_HDR_ALG_PS512) == 0)
        digest_alg = EVP_sha512();

    if (NULL == digest_alg)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_build_sig_ps_cleanup;
    }

    // apply EMSA-PSS encoding (RFC-3447, 8.1.1, step 1)
    // (RSA_padding_add_PKCS1_PSS includes PKCS1_MGF1, -1 => saltlen = hashlen)
    em_len = RSA_size((RSA *)jwk->keydata);
    em = (uint8_t *)cjose_get_alloc()(em_len);
    if (NULL == em)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto _cjose_jws_build_sig_ps_cleanup;
    }
    if (RSA_padding_add_PKCS1_PSS((RSA *)jwk->keydata, em, jws->dig, digest_alg, -1) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_build_sig_ps_cleanup;
    }

    // sign the digest (RFC-3447, 8.1.1, step 2)
    jws->sig_len = em_len;
    jws->sig = (uint8_t *)cjose_get_alloc()(jws->sig_len);
    if (NULL == jws->sig)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto _cjose_jws_build_sig_ps_cleanup;
    }

    if (RSA_private_encrypt(em_len, em, jws->sig, (RSA *)jwk->keydata, RSA_NO_PADDING) != jws->sig_len)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_build_sig_ps_cleanup;
    }

    // base64url encode signed digest
    if (!cjose_base64url_encode((const uint8_t *)jws->sig, jws->sig_len, &jws->sig_b64u, &jws->sig_b64u_len, err))
    {
        goto _cjose_jws_build_sig_ps_cleanup;
    }

    // if we got this far - success
    retval = true;

_cjose_jws_build_sig_ps_cleanup:
    cjose_get_dealloc()(em);

    return retval;
}
Exemple #6
0
bool OSSLRSA::signFinal(ByteString& signature)
{
	// Save necessary state before calling super class signFinal
	OSSLRSAPrivateKey* pk = (OSSLRSAPrivateKey*) currentPrivateKey;
	AsymMech::Type mechanism = currentMechanism;

	if (!AsymmetricAlgorithm::signFinal(signature))
	{
		return false;
	}

	ByteString firstHash, secondHash;

	bool bFirstResult = pCurrentHash->hashFinal(firstHash);
	bool bSecondResult = (pSecondHash != NULL) ? pSecondHash->hashFinal(secondHash) : true;

	delete pCurrentHash;
	pCurrentHash = NULL;

	if (pSecondHash != NULL)
	{
		delete pSecondHash;

		pSecondHash = NULL;
	}

	if (!bFirstResult || !bSecondResult)
	{
		return false;
	}

	ByteString digest = firstHash + secondHash;

	// Resize the data block for the signature to the modulus size of the key
	signature.resize(pk->getN().size());

	// Determine the signature NID type
	int type = 0;
	bool isPSS = false;
	const EVP_MD* hash = NULL;

	switch (mechanism)
	{
		case AsymMech::RSA_MD5_PKCS:
			type = NID_md5;
			break;
		case AsymMech::RSA_SHA1_PKCS:
			type = NID_sha1;
			break;
		case AsymMech::RSA_SHA224_PKCS:
			type = NID_sha224;
			break;
		case AsymMech::RSA_SHA256_PKCS:
			type = NID_sha256;
			break;
		case AsymMech::RSA_SHA384_PKCS:
			type = NID_sha384;
			break;
		case AsymMech::RSA_SHA512_PKCS:
			type = NID_sha512;
			break;
		case AsymMech::RSA_SHA1_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha1();
			break;
		case AsymMech::RSA_SHA224_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha224();
			break;
		case AsymMech::RSA_SHA256_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha256();
			break;
		case AsymMech::RSA_SHA384_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha384();
			break;
		case AsymMech::RSA_SHA512_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha512();
			break;
		case AsymMech::RSA_SSL:
			type = NID_md5_sha1;
			break;
		default:
			break;
	}

	// Perform the signature operation
	unsigned int sigLen = signature.size();

	RSA* rsa = pk->getOSSLKey();

	if (!RSA_blinding_on(rsa, NULL))
	{
		ERROR_MSG("Failed to turn blinding on for OpenSSL RSA key");

		return false;
	}

	bool rv;

	if (isPSS)
	{
		ByteString em;
		em.resize(pk->getN().size());

		rv = (RSA_padding_add_PKCS1_PSS(pk->getOSSLKey(), &em[0], &digest[0],
						hash, sLen) == 1);
		if (!rv)
		{
			ERROR_MSG("RSA PSS padding failed (0x%08X)", ERR_get_error());
		}
		else
		{
			int result = RSA_private_encrypt(em.size(), &em[0], &signature[0],
							 pk->getOSSLKey(), RSA_NO_PADDING);
			if (result >= 0)
			{
				sigLen = result;
				rv = true;
			}
			else
			{
				rv = false;
				ERROR_MSG("RSA private encrypt failed (0x%08X)", ERR_get_error());
			}
		}
	}
	else
	{
		rv = (RSA_sign(type, &digest[0], digest.size(), &signature[0],
			       &sigLen, pk->getOSSLKey()) == 1);
	}

	RSA_blinding_off(rsa);

	signature.resize(sigLen);

	return rv;
}
static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y,
                         unsigned char *sigret, unsigned int *siglen,
                         EVP_MD_SVCTX * sv)
{
    int i = 0, j, ret = 0;
    unsigned int dlen;
    const unsigned char *der;
    unsigned int m_len;
    int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK;
    int rsa_pad_mode = 0;
    RSA *rsa = sv->key;
    /* Largest DigestInfo: 19 (max encoding) + max MD */
    unsigned char tmpdinfo[19 + EVP_MAX_MD_SIZE];
    unsigned char md[EVP_MAX_MD_SIZE + 1];

    EVP_DigestFinal_ex(sv->mctx, md, &m_len);

    if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) {
        ret = rsa->meth->rsa_sign(type, md, m_len, sigret, siglen, rsa);
        goto done;
    }

    if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) {
        int hash_id;
        memcpy(tmpdinfo, md, m_len);
        hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
        if (hash_id == -1) {
            RSAerr(RSA_F_FIPS_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
            return 0;
        }
        tmpdinfo[m_len] = (unsigned char)hash_id;
        i = m_len + 1;
        rsa_pad_mode = RSA_X931_PADDING;
    } else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) {

        der = fips_digestinfo_encoding(type, &dlen);

        if (!der) {
            RSAerr(RSA_F_FIPS_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
            return 0;
        }
        memcpy(tmpdinfo, der, dlen);
        memcpy(tmpdinfo + dlen, md, m_len);

        i = dlen + m_len;
        rsa_pad_mode = RSA_PKCS1_PADDING;

    } else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) {
        unsigned char *sbuf;
        int saltlen;
        i = RSA_size(rsa);
        sbuf = OPENSSL_malloc(RSA_size(rsa));
        saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx);
        if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)
            saltlen = -1;
        else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)
            saltlen = -2;
        if (!sbuf) {
            RSAerr(RSA_F_FIPS_RSA_SIGN, ERR_R_MALLOC_FAILURE);
            goto psserr;
        }
        if (!RSA_padding_add_PKCS1_PSS(rsa, sbuf, md,
                                       M_EVP_MD_CTX_md(sv->mctx), saltlen))
            goto psserr;
        j = rsa->meth->rsa_priv_enc(i, sbuf, sigret, rsa, RSA_NO_PADDING);
        if (j > 0) {
            ret = 1;
            *siglen = j;
        }
 psserr:
        OPENSSL_cleanse(md, m_len);
        OPENSSL_cleanse(sbuf, i);
        OPENSSL_free(sbuf);
        return ret;
    }

    j = RSA_size(rsa);
    if (i > (j - RSA_PKCS1_PADDING_SIZE)) {
        RSAerr(RSA_F_FIPS_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
        goto done;
    }
    /* NB: call underlying method directly to avoid FIPS blocking */
    j = rsa->meth->rsa_priv_enc(i, tmpdinfo, sigret, rsa, rsa_pad_mode);
    if (j > 0) {
        ret = 1;
        *siglen = j;
    }

 done:
    OPENSSL_cleanse(tmpdinfo, i);
    OPENSSL_cleanse(md, m_len);
    return ret;
}