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 = 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 (EVP_MD_type(rctx->md) == NID_mdc2) {
            unsigned int sltmp;

            if (rctx->pad_mode != RSA_PKCS1_PADDING)
                return -1;
            ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, tbs, tbslen,
                                             sig, &sltmp, rsa);

            if (ret <= 0)
                return ret;
            ret = sltmp;
        } else if (rctx->pad_mode == RSA_X931_PADDING) {
            if (!setup_tbuf(rctx, ctx))
                return -1;
            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_mgf1(rsa, rctx->tbuf,
                                                tbs, rctx->md, rctx->mgf1md, 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 #2
0
static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
                           const unsigned char *sig, size_t siglen,
                           const unsigned char *tbs, size_t tbslen)
{
    RSA_PKEY_CTX *rctx = ctx->data;
    RSA *rsa = ctx->pkey->pkey.rsa;
    size_t rslen;
#ifdef OPENSSL_FIPS
    int rv;
    rv = pkey_fips_check_ctx(ctx);
    if (rv < 0) {
        RSAerr(RSA_F_PKEY_RSA_VERIFY,
               RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
        return -1;
    }
#endif
    if (rctx->md) {
        if (rctx->pad_mode == RSA_PKCS1_PADDING)
            return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
                              sig, siglen, rsa);
        if (rctx->pad_mode == RSA_X931_PADDING) {
            if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, siglen) <= 0)
                return 0;
        } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) {
            int ret;
            if (!setup_tbuf(rctx, ctx))
                return -1;
            ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
                                     rsa, RSA_NO_PADDING);
            if (ret <= 0)
                return 0;
            ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs,
                                            rctx->md, rctx->mgf1md,
                                            rctx->tbuf, rctx->saltlen);
            if (ret <= 0)
                return 0;
            return 1;
        } else
            return -1;
    } else {
        if (!setup_tbuf(rctx, ctx))
            return -1;
        rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
                                   rsa, rctx->pad_mode);
        if (rslen == 0)
            return 0;
    }

    if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
        return 0;

    return 1;

}
Exemple #3
0
static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
					const unsigned char *sig, size_t siglen,
					const unsigned char *tbs, size_t tbslen)
	{
	RSA_PKEY_CTX *rctx = ctx->data;
	RSA *rsa = ctx->pkey->pkey.rsa;
	size_t rslen;
	if (rctx->md)
		{
		if (rctx->pad_mode == RSA_PKCS1_PADDING)
			return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
					sig, siglen, rsa);
		if (rctx->pad_mode == RSA_X931_PADDING)
			{
			if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
					sig, siglen) <= 0)
				return 0;
			}
		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
			{
			int ret;
			if (!setup_tbuf(rctx, ctx))
				return -1;
			ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
							rsa, RSA_NO_PADDING);
			if (ret <= 0)
				return 0;
			ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs,
						rctx->md, rctx->mgf1md,
						rctx->tbuf, rctx->saltlen);
			if (ret <= 0)
				return 0;
			return 1;
			}
		else
			return -1;
		}
	else
		{
		if (!setup_tbuf(rctx, ctx))
			return -1;
		rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
						rsa, rctx->pad_mode);
		if (rslen == 0)
			return 0;
		}

	if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
		return 0;

	return 1;
			
	}
Exemple #4
0
static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
                            unsigned char *out, size_t *outlen,
                            const unsigned char *in, size_t inlen)
{
    int ret;
    RSA_PKEY_CTX *rctx = ctx->data;
    if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
        int i;
        if (!setup_tbuf(rctx, ctx))
            return -1;
        ret = RSA_private_decrypt(inlen, in, rctx->tbuf,
                                  ctx->pkey->pkey.rsa, RSA_NO_PADDING);
        if (ret <= 0)
            return ret;
        for (i = 0; i < ret; i++) {
            if (rctx->tbuf[i])
                break;
        }
        ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf + i,
                                                ret - i, ret,
                                                rctx->oaep_label,
                                                rctx->oaep_labellen,
                                                rctx->md, rctx->mgf1md);
    } else
        ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
                                  rctx->pad_mode);
    if (ret < 0)
        return ret;
    *outlen = ret;
    return 1;
}
Exemple #5
0
static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
                            unsigned char *out, size_t *outlen,
                            const unsigned char *in, size_t inlen)
{
    int ret;
    RSA_PKEY_CTX *rctx = ctx->data;
    if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
        int klen = RSA_size(ctx->pkey->pkey.rsa);
        if (!setup_tbuf(rctx, ctx))
            return -1;
        if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen,
                                             in, inlen,
                                             rctx->oaep_label,
                                             rctx->oaep_labellen,
                                             rctx->md, rctx->mgf1md))
            return -1;
        ret = RSA_public_encrypt(klen, rctx->tbuf, out,
                                 ctx->pkey->pkey.rsa, RSA_NO_PADDING);
    } else
        ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
                                 rctx->pad_mode);
    if (ret < 0)
        return ret;
    *outlen = ret;
    return 1;
}
Exemple #6
0
static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
                            unsigned char *out, size_t *outlen,
                            const unsigned char *in, size_t inlen)
{
    int ret;
    RSA_PKEY_CTX *rctx = ctx->data;

    if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
        if (!setup_tbuf(rctx, ctx))
            return -1;
        ret = RSA_private_decrypt(inlen, in, rctx->tbuf,
                                  ctx->pkey->pkey.rsa, RSA_NO_PADDING);
        if (ret <= 0)
            return ret;
        ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf,
                                                ret, ret,
                                                rctx->oaep_label,
                                                rctx->oaep_labellen,
                                                rctx->md, rctx->mgf1md);
    } else {
        ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
                                  rctx->pad_mode);
    }
    *outlen = constant_time_select_s(constant_time_msb_s(ret), *outlen, ret);
    ret = constant_time_select_int(constant_time_msb(ret), ret, 1);
    return ret;
}
Exemple #7
0
static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
                            const uint8_t *in, size_t inlen) {
  RSA_PKEY_CTX *rctx = ctx->data;
  RSA *rsa = ctx->pkey->pkey.rsa;
  const size_t key_len = EVP_PKEY_size(ctx->pkey);

  if (!out) {
    *outlen = key_len;
    return 1;
  }

  if (*outlen < key_len) {
    OPENSSL_PUT_ERROR(EVP, pkey_rsa_encrypt, EVP_R_BUFFER_TOO_SMALL);
    return 0;
  }

  if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
    if (!setup_tbuf(rctx, ctx) ||
        !RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, key_len, in, inlen,
                                         rctx->oaep_label, rctx->oaep_labellen,
                                         rctx->md, rctx->mgf1md) ||
        !RSA_encrypt(rsa, outlen, out, *outlen, rctx->tbuf, key_len,
                     RSA_NO_PADDING)) {
      return 0;
    }
    return 1;
  }

  return RSA_encrypt(rsa, outlen, out, *outlen, in, inlen, rctx->pad_mode);
}
Exemple #8
0
static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
					unsigned char *rout, size_t *routlen,
					const unsigned char *sig, size_t siglen)
	{
	int ret;
	RSA_PKEY_CTX *rctx = ctx->data;

	if (rctx->md)
		{
		if (rctx->pad_mode == RSA_X931_PADDING)
			{
			if (!setup_tbuf(rctx, ctx))
				return -1;
			ret = RSA_public_decrypt(siglen, sig,
						rctx->tbuf, ctx->pkey->pkey.rsa,
						RSA_X931_PADDING);
			if (ret < 1)
				return 0;
			ret--;
			if (rctx->tbuf[ret] !=
				RSA_X931_hash_id(EVP_MD_type(rctx->md)))
				{
				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
						RSA_R_ALGORITHM_MISMATCH);
				return 0;
				}
			if (ret != EVP_MD_size(rctx->md))
				{
				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
					RSA_R_INVALID_DIGEST_LENGTH);
				return 0;
				}
			if (rout)
				memcpy(rout, rctx->tbuf, ret);
			}
		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
			{
			size_t sltmp;
			ret = int_rsa_verify(EVP_MD_type(rctx->md),
						NULL, 0, rout, &sltmp,
					sig, siglen, ctx->pkey->pkey.rsa);
			if (ret <= 0)
				return 0;
			ret = sltmp;
			}
		else
			return -1;
		}
	else
		ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
							rctx->pad_mode);
	if (ret < 0)
		return ret;
	*routlen = ret;
	return 1;
	}
Exemple #9
0
static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
                         const uint8_t *tbs, size_t tbslen) {
  RSA_PKEY_CTX *rctx = ctx->data;
  RSA *rsa = ctx->pkey->pkey.rsa;
  const size_t key_len = EVP_PKEY_size(ctx->pkey);

  if (!sig) {
    *siglen = key_len;
    return 1;
  }

  if (*siglen < key_len) {
    OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_BUFFER_TOO_SMALL);
    return 0;
  }

  if (rctx->md) {
    unsigned int out_len;

    if (tbslen != EVP_MD_size(rctx->md)) {
      OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_INVALID_DIGEST_LENGTH);
      return 0;
    }

    if (EVP_MD_type(rctx->md) == NID_mdc2) {
      OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_NO_MDC2_SUPPORT);
      return 0;
    }

    switch (rctx->pad_mode) {
      case RSA_PKCS1_PADDING:
        if (!RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig, &out_len, rsa)) {
          return 0;
        }
        *siglen = out_len;
        return 1;

      case RSA_PKCS1_PSS_PADDING:
        if (!setup_tbuf(rctx, ctx) ||
            !RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, tbs, rctx->md,
                                            rctx->mgf1md, rctx->saltlen) ||
            !RSA_sign_raw(rsa, siglen, sig, *siglen, rctx->tbuf, key_len,
                          RSA_NO_PADDING)) {
          return 0;
        }
        return 1;

      default:
        return 0;
    }
  }

  return RSA_sign_raw(rsa, siglen, sig, *siglen, tbs, tbslen, rctx->pad_mode);
}
Exemple #10
0
static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig,
                           size_t siglen, const uint8_t *tbs,
                           size_t tbslen) {
  RSA_PKEY_CTX *rctx = ctx->data;
  RSA *rsa = ctx->pkey->pkey.rsa;
  size_t rslen;
  const size_t key_len = EVP_PKEY_size(ctx->pkey);

  if (rctx->md) {
    switch (rctx->pad_mode) {
      case RSA_PKCS1_PADDING:
        return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, sig, siglen, rsa);

      case RSA_PKCS1_PSS_PADDING:
        if (!setup_tbuf(rctx, ctx) ||
            !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen,
                            RSA_NO_PADDING) ||
            !RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, rctx->md, rctx->mgf1md,
                                       rctx->tbuf, rctx->saltlen)) {
          return 0;
        }
        return 1;

      default:
        return 0;
    }
  }

  if (!setup_tbuf(rctx, ctx) ||
      !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen,
                      rctx->pad_mode) ||
      rslen != tbslen ||
      CRYPTO_memcmp(tbs, rctx->tbuf, rslen) != 0) {
    return 0;
  }

  return 1;
}
Exemple #11
0
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 = ctx->data;
	RSA *rsa = ctx->pkey->pkey.rsa;

#ifdef OPENSSL_FIPS
	ret = pkey_fips_check_ctx(ctx);
	if (ret < 0)
		{
		RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
		return -1;
		}
#endif

	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;
			}
#ifdef OPENSSL_FIPS
		if (ret > 0)
			{
			unsigned int slen;
			ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md,
							rctx->pad_mode,
							rctx->saltlen,
							rctx->mgf1md,
							sig, &slen);
			if (ret > 0)
				*siglen = slen;
			else
				*siglen = 0;
			return ret;
			}
#endif

		if (EVP_MD_type(rctx->md) == NID_mdc2)
			{
			unsigned int sltmp;
			if (rctx->pad_mode != RSA_PKCS1_PADDING)
				return -1;
			ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2,
						tbs, tbslen, sig, &sltmp, rsa);

			if (ret <= 0)
				return ret;
			ret = sltmp;
			}
		else if (rctx->pad_mode == RSA_X931_PADDING)
			{
			if (!setup_tbuf(rctx, ctx))
				return -1;
			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_mgf1(rsa,
						rctx->tbuf, tbs,
						rctx->md, rctx->mgf1md,
						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 #12
0
static int pkey_rsa_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out,
                                   size_t *out_len, const uint8_t *sig,
                                   size_t sig_len) {
  RSA_PKEY_CTX *rctx = ctx->data;
  RSA *rsa = ctx->pkey->pkey.rsa;
  const size_t key_len = EVP_PKEY_size(ctx->pkey);

  if (out == NULL) {
    *out_len = key_len;
    return 1;
  }

  if (*out_len < key_len) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
    return 0;
  }

  if (!setup_tbuf(rctx, ctx)) {
    return 0;
  }

  if (rctx->md == NULL) {
    const int ret = RSA_public_decrypt(sig_len, sig, rctx->tbuf,
                                       ctx->pkey->pkey.rsa, rctx->pad_mode);
    if (ret < 0) {
      return 0;
    }
    *out_len = ret;
    memcpy(out, rctx->tbuf, *out_len);
    return 1;
  }

  if (rctx->pad_mode != RSA_PKCS1_PADDING) {
    return 0;
  }

  uint8_t *asn1_prefix;
  size_t asn1_prefix_len;
  int asn1_prefix_allocated;
  if (!RSA_add_pkcs1_prefix(&asn1_prefix, &asn1_prefix_len,
                            &asn1_prefix_allocated, EVP_MD_type(rctx->md), NULL,
                            0)) {
    return 0;
  }

  size_t rslen;
  int ok = 1;
  if (!RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, sig_len,
                      RSA_PKCS1_PADDING) ||
      rslen < asn1_prefix_len ||
      CRYPTO_memcmp(rctx->tbuf, asn1_prefix, asn1_prefix_len) != 0) {
    ok = 0;
  }

  if (asn1_prefix_allocated) {
    OPENSSL_free(asn1_prefix);
  }

  if (!ok) {
    return 0;
  }

  const size_t result_len = rslen - asn1_prefix_len;
  if (result_len != EVP_MD_size(rctx->md)) {
    return 0;
  }

  if (out != NULL) {
    memcpy(out, rctx->tbuf + asn1_prefix_len, result_len);
  }
  *out_len = result_len;

  return 1;
}