diff options
author | deshevoy <deshevoy@yandex-team.ru> | 2022-02-10 16:46:56 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:56 +0300 |
commit | e988f30484abe5fdeedcc7a5d3c226c01a21800c (patch) | |
tree | 0a217b173aabb57b7e51f8a169989b1a3e0309fe /contrib/libs/openssl/crypto/rsa | |
parent | 33ee501c05d3f24036ae89766a858930ae66c548 (diff) | |
download | ydb-e988f30484abe5fdeedcc7a5d3c226c01a21800c.tar.gz |
Restoring authorship annotation for <deshevoy@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/openssl/crypto/rsa')
22 files changed, 6631 insertions, 6631 deletions
diff --git a/contrib/libs/openssl/crypto/rsa/rsa_ameth.c b/contrib/libs/openssl/crypto/rsa/rsa_ameth.c index fb045544a8..e608466d35 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_ameth.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_ameth.c @@ -1,123 +1,123 @@ -/* +/* * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdio.h> -#include "internal/cryptlib.h" -#include <openssl/asn1t.h> -#include <openssl/x509.h> -#include <openssl/bn.h> -#include <openssl/cms.h> + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/asn1t.h> +#include <openssl/x509.h> +#include <openssl/bn.h> +#include <openssl/cms.h> #include "crypto/asn1.h" #include "crypto/evp.h" #include "rsa_local.h" - -#ifndef OPENSSL_NO_CMS -static int rsa_cms_sign(CMS_SignerInfo *si); -static int rsa_cms_verify(CMS_SignerInfo *si); -static int rsa_cms_decrypt(CMS_RecipientInfo *ri); -static int rsa_cms_encrypt(CMS_RecipientInfo *ri); -#endif - -static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg); - -/* Set any parameters associated with pkey */ -static int rsa_param_encode(const EVP_PKEY *pkey, - ASN1_STRING **pstr, int *pstrtype) -{ - const RSA *rsa = pkey->pkey.rsa; - - *pstr = NULL; - /* If RSA it's just NULL type */ - if (pkey->ameth->pkey_id != EVP_PKEY_RSA_PSS) { - *pstrtype = V_ASN1_NULL; - return 1; - } - /* If no PSS parameters we omit parameters entirely */ - if (rsa->pss == NULL) { - *pstrtype = V_ASN1_UNDEF; - return 1; - } - /* Encode PSS parameters */ - if (ASN1_item_pack(rsa->pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), pstr) == NULL) - return 0; - - *pstrtype = V_ASN1_SEQUENCE; - return 1; -} -/* Decode any parameters and set them in RSA structure */ -static int rsa_param_decode(RSA *rsa, const X509_ALGOR *alg) -{ - const ASN1_OBJECT *algoid; - const void *algp; - int algptype; - - X509_ALGOR_get0(&algoid, &algptype, &algp, alg); - if (OBJ_obj2nid(algoid) != EVP_PKEY_RSA_PSS) - return 1; - if (algptype == V_ASN1_UNDEF) - return 1; - if (algptype != V_ASN1_SEQUENCE) { - RSAerr(RSA_F_RSA_PARAM_DECODE, RSA_R_INVALID_PSS_PARAMETERS); - return 0; - } - rsa->pss = rsa_pss_decode(alg); - if (rsa->pss == NULL) - return 0; - return 1; -} - -static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) -{ - unsigned char *penc = NULL; - int penclen; - ASN1_STRING *str; - int strtype; - - if (!rsa_param_encode(pkey, &str, &strtype)) - return 0; - penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); - if (penclen <= 0) - return 0; - if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), - strtype, str, penc, penclen)) - return 1; - - OPENSSL_free(penc); - return 0; -} - -static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) -{ - const unsigned char *p; - int pklen; - X509_ALGOR *alg; - RSA *rsa = NULL; - - if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &alg, pubkey)) - return 0; - if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) { - RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); - return 0; - } - if (!rsa_param_decode(rsa, alg)) { - RSA_free(rsa); - return 0; - } - if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa)) { - RSA_free(rsa); - return 0; - } - return 1; -} - -static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -{ + +#ifndef OPENSSL_NO_CMS +static int rsa_cms_sign(CMS_SignerInfo *si); +static int rsa_cms_verify(CMS_SignerInfo *si); +static int rsa_cms_decrypt(CMS_RecipientInfo *ri); +static int rsa_cms_encrypt(CMS_RecipientInfo *ri); +#endif + +static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg); + +/* Set any parameters associated with pkey */ +static int rsa_param_encode(const EVP_PKEY *pkey, + ASN1_STRING **pstr, int *pstrtype) +{ + const RSA *rsa = pkey->pkey.rsa; + + *pstr = NULL; + /* If RSA it's just NULL type */ + if (pkey->ameth->pkey_id != EVP_PKEY_RSA_PSS) { + *pstrtype = V_ASN1_NULL; + return 1; + } + /* If no PSS parameters we omit parameters entirely */ + if (rsa->pss == NULL) { + *pstrtype = V_ASN1_UNDEF; + return 1; + } + /* Encode PSS parameters */ + if (ASN1_item_pack(rsa->pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), pstr) == NULL) + return 0; + + *pstrtype = V_ASN1_SEQUENCE; + return 1; +} +/* Decode any parameters and set them in RSA structure */ +static int rsa_param_decode(RSA *rsa, const X509_ALGOR *alg) +{ + const ASN1_OBJECT *algoid; + const void *algp; + int algptype; + + X509_ALGOR_get0(&algoid, &algptype, &algp, alg); + if (OBJ_obj2nid(algoid) != EVP_PKEY_RSA_PSS) + return 1; + if (algptype == V_ASN1_UNDEF) + return 1; + if (algptype != V_ASN1_SEQUENCE) { + RSAerr(RSA_F_RSA_PARAM_DECODE, RSA_R_INVALID_PSS_PARAMETERS); + return 0; + } + rsa->pss = rsa_pss_decode(alg); + if (rsa->pss == NULL) + return 0; + return 1; +} + +static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + unsigned char *penc = NULL; + int penclen; + ASN1_STRING *str; + int strtype; + + if (!rsa_param_encode(pkey, &str, &strtype)) + return 0; + penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); + if (penclen <= 0) + return 0; + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), + strtype, str, penc, penclen)) + return 1; + + OPENSSL_free(penc); + return 0; +} + +static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + const unsigned char *p; + int pklen; + X509_ALGOR *alg; + RSA *rsa = NULL; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &alg, pubkey)) + return 0; + if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) { + RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); + return 0; + } + if (!rsa_param_decode(rsa, alg)) { + RSA_free(rsa); + return 0; + } + if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa)) { + RSA_free(rsa); + return 0; + } + return 1; +} + +static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ /* * Don't check the public/private key, this is mostly for smart * cards. @@ -127,388 +127,388 @@ static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) return 1; } - if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 - || BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0) - return 0; - return 1; -} - -static int old_rsa_priv_decode(EVP_PKEY *pkey, - const unsigned char **pder, int derlen) -{ - RSA *rsa; - - if ((rsa = d2i_RSAPrivateKey(NULL, pder, derlen)) == NULL) { - RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB); - return 0; - } - EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); - return 1; -} - -static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) -{ - return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); -} - -static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) -{ - unsigned char *rk = NULL; - int rklen; - ASN1_STRING *str; - int strtype; - - if (!rsa_param_encode(pkey, &str, &strtype)) - return 0; - rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); - - if (rklen <= 0) { - RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); - ASN1_STRING_free(str); - return 0; - } - - if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, - strtype, str, rk, rklen)) { - RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); - ASN1_STRING_free(str); - return 0; - } - - return 1; -} - -static int rsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) -{ - const unsigned char *p; - RSA *rsa; - int pklen; - const X509_ALGOR *alg; - - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &alg, p8)) - return 0; - rsa = d2i_RSAPrivateKey(NULL, &p, pklen); - if (rsa == NULL) { - RSAerr(RSA_F_RSA_PRIV_DECODE, ERR_R_RSA_LIB); - return 0; - } - if (!rsa_param_decode(rsa, alg)) { - RSA_free(rsa); - return 0; - } - EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); - return 1; -} - -static int int_rsa_size(const EVP_PKEY *pkey) -{ - return RSA_size(pkey->pkey.rsa); -} - -static int rsa_bits(const EVP_PKEY *pkey) -{ - return BN_num_bits(pkey->pkey.rsa->n); -} - -static int rsa_security_bits(const EVP_PKEY *pkey) -{ - return RSA_security_bits(pkey->pkey.rsa); -} - -static void int_rsa_free(EVP_PKEY *pkey) -{ - RSA_free(pkey->pkey.rsa); -} - -static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) -{ - if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) - return NULL; - return ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR), - alg->parameter); -} - -static int rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss, - int indent) -{ - int rv = 0; - X509_ALGOR *maskHash = NULL; - - if (!BIO_indent(bp, indent, 128)) - goto err; - if (pss_key) { - if (pss == NULL) { - if (BIO_puts(bp, "No PSS parameter restrictions\n") <= 0) - return 0; - return 1; - } else { - if (BIO_puts(bp, "PSS parameter restrictions:") <= 0) - return 0; - } - } else if (pss == NULL) { - if (BIO_puts(bp,"(INVALID PSS PARAMETERS)\n") <= 0) - return 0; - return 1; - } - if (BIO_puts(bp, "\n") <= 0) - goto err; - if (pss_key) - indent += 2; - if (!BIO_indent(bp, indent, 128)) - goto err; - if (BIO_puts(bp, "Hash Algorithm: ") <= 0) - goto err; - - if (pss->hashAlgorithm) { - if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) - goto err; - } else if (BIO_puts(bp, "sha1 (default)") <= 0) { - goto err; - } - - if (BIO_puts(bp, "\n") <= 0) - goto err; - - if (!BIO_indent(bp, indent, 128)) - goto err; - - if (BIO_puts(bp, "Mask Algorithm: ") <= 0) - goto err; - if (pss->maskGenAlgorithm) { - if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0) - goto err; - if (BIO_puts(bp, " with ") <= 0) - goto err; - maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); - if (maskHash != NULL) { - if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) - goto err; - } else if (BIO_puts(bp, "INVALID") <= 0) { - goto err; - } - } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) { - goto err; - } - BIO_puts(bp, "\n"); - - if (!BIO_indent(bp, indent, 128)) - goto err; - if (BIO_printf(bp, "%s Salt Length: 0x", pss_key ? "Minimum" : "") <= 0) - goto err; - if (pss->saltLength) { - if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) - goto err; - } else if (BIO_puts(bp, "14 (default)") <= 0) { - goto err; - } - BIO_puts(bp, "\n"); - - if (!BIO_indent(bp, indent, 128)) - goto err; - if (BIO_puts(bp, "Trailer Field: 0x") <= 0) - goto err; - if (pss->trailerField) { - if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) - goto err; - } else if (BIO_puts(bp, "BC (default)") <= 0) { - goto err; - } - BIO_puts(bp, "\n"); - - rv = 1; - - err: - X509_ALGOR_free(maskHash); - return rv; - -} - -static int pkey_rsa_print(BIO *bp, const EVP_PKEY *pkey, int off, int priv) -{ - const RSA *x = pkey->pkey.rsa; - char *str; - const char *s; - int ret = 0, mod_len = 0, ex_primes; - - if (x->n != NULL) - mod_len = BN_num_bits(x->n); - ex_primes = sk_RSA_PRIME_INFO_num(x->prime_infos); - - if (!BIO_indent(bp, off, 128)) - goto err; - - if (BIO_printf(bp, "%s ", pkey_is_pss(pkey) ? "RSA-PSS" : "RSA") <= 0) - goto err; - - if (priv && x->d) { - if (BIO_printf(bp, "Private-Key: (%d bit, %d primes)\n", - mod_len, ex_primes <= 0 ? 2 : ex_primes + 2) <= 0) - goto err; - str = "modulus:"; - s = "publicExponent:"; - } else { - if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0) - goto err; - str = "Modulus:"; - s = "Exponent:"; - } - if (!ASN1_bn_print(bp, str, x->n, NULL, off)) - goto err; - if (!ASN1_bn_print(bp, s, x->e, NULL, off)) - goto err; - if (priv) { - int i; - - if (!ASN1_bn_print(bp, "privateExponent:", x->d, NULL, off)) - goto err; - if (!ASN1_bn_print(bp, "prime1:", x->p, NULL, off)) - goto err; - if (!ASN1_bn_print(bp, "prime2:", x->q, NULL, off)) - goto err; - if (!ASN1_bn_print(bp, "exponent1:", x->dmp1, NULL, off)) - goto err; - if (!ASN1_bn_print(bp, "exponent2:", x->dmq1, NULL, off)) - goto err; - if (!ASN1_bn_print(bp, "coefficient:", x->iqmp, NULL, off)) - goto err; - for (i = 0; i < sk_RSA_PRIME_INFO_num(x->prime_infos); i++) { - /* print multi-prime info */ - BIGNUM *bn = NULL; - RSA_PRIME_INFO *pinfo; - int j; - - pinfo = sk_RSA_PRIME_INFO_value(x->prime_infos, i); - for (j = 0; j < 3; j++) { - if (!BIO_indent(bp, off, 128)) - goto err; - switch (j) { - case 0: - if (BIO_printf(bp, "prime%d:", i + 3) <= 0) - goto err; - bn = pinfo->r; - break; - case 1: - if (BIO_printf(bp, "exponent%d:", i + 3) <= 0) - goto err; - bn = pinfo->d; - break; - case 2: - if (BIO_printf(bp, "coefficient%d:", i + 3) <= 0) - goto err; - bn = pinfo->t; - break; - default: - break; - } - if (!ASN1_bn_print(bp, "", bn, NULL, off)) - goto err; - } - } - } - if (pkey_is_pss(pkey) && !rsa_pss_param_print(bp, 1, x->pss, off)) - goto err; - ret = 1; - err: - return ret; -} - -static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return pkey_rsa_print(bp, pkey, indent, 0); -} - -static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return pkey_rsa_print(bp, pkey, indent, 1); -} - -static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg) -{ - RSA_PSS_PARAMS *pss; - - pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_PSS_PARAMS), - alg->parameter); - - if (pss == NULL) - return NULL; - - if (pss->maskGenAlgorithm != NULL) { - pss->maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); - if (pss->maskHash == NULL) { - RSA_PSS_PARAMS_free(pss); - return NULL; - } - } - - return pss; -} - -static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, - const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) -{ - if (OBJ_obj2nid(sigalg->algorithm) == EVP_PKEY_RSA_PSS) { - int rv; - RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg); - - rv = rsa_pss_param_print(bp, 0, pss, indent); - RSA_PSS_PARAMS_free(pss); - if (!rv) - return 0; - } else if (!sig && BIO_puts(bp, "\n") <= 0) { - return 0; - } - if (sig) - return X509_signature_dump(bp, sig, indent); - return 1; -} - -static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - X509_ALGOR *alg = NULL; + if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 + || BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0) + return 0; + return 1; +} + +static int old_rsa_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + RSA *rsa; + + if ((rsa = d2i_RSAPrivateKey(NULL, pder, derlen)) == NULL) { + RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB); + return 0; + } + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); + return 1; +} + +static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); +} + +static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + unsigned char *rk = NULL; + int rklen; + ASN1_STRING *str; + int strtype; + + if (!rsa_param_encode(pkey, &str, &strtype)) + return 0; + rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); + + if (rklen <= 0) { + RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(str); + return 0; + } + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, + strtype, str, rk, rklen)) { + RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(str); + return 0; + } + + return 1; +} + +static int rsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) +{ + const unsigned char *p; + RSA *rsa; + int pklen; + const X509_ALGOR *alg; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &alg, p8)) + return 0; + rsa = d2i_RSAPrivateKey(NULL, &p, pklen); + if (rsa == NULL) { + RSAerr(RSA_F_RSA_PRIV_DECODE, ERR_R_RSA_LIB); + return 0; + } + if (!rsa_param_decode(rsa, alg)) { + RSA_free(rsa); + return 0; + } + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); + return 1; +} + +static int int_rsa_size(const EVP_PKEY *pkey) +{ + return RSA_size(pkey->pkey.rsa); +} + +static int rsa_bits(const EVP_PKEY *pkey) +{ + return BN_num_bits(pkey->pkey.rsa->n); +} + +static int rsa_security_bits(const EVP_PKEY *pkey) +{ + return RSA_security_bits(pkey->pkey.rsa); +} + +static void int_rsa_free(EVP_PKEY *pkey) +{ + RSA_free(pkey->pkey.rsa); +} + +static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) +{ + if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) + return NULL; + return ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR), + alg->parameter); +} + +static int rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss, + int indent) +{ + int rv = 0; + X509_ALGOR *maskHash = NULL; + + if (!BIO_indent(bp, indent, 128)) + goto err; + if (pss_key) { + if (pss == NULL) { + if (BIO_puts(bp, "No PSS parameter restrictions\n") <= 0) + return 0; + return 1; + } else { + if (BIO_puts(bp, "PSS parameter restrictions:") <= 0) + return 0; + } + } else if (pss == NULL) { + if (BIO_puts(bp,"(INVALID PSS PARAMETERS)\n") <= 0) + return 0; + return 1; + } + if (BIO_puts(bp, "\n") <= 0) + goto err; + if (pss_key) + indent += 2; + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_puts(bp, "Hash Algorithm: ") <= 0) + goto err; + + if (pss->hashAlgorithm) { + if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) + goto err; + } else if (BIO_puts(bp, "sha1 (default)") <= 0) { + goto err; + } + + if (BIO_puts(bp, "\n") <= 0) + goto err; + + if (!BIO_indent(bp, indent, 128)) + goto err; + + if (BIO_puts(bp, "Mask Algorithm: ") <= 0) + goto err; + if (pss->maskGenAlgorithm) { + if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0) + goto err; + if (BIO_puts(bp, " with ") <= 0) + goto err; + maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); + if (maskHash != NULL) { + if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) + goto err; + } else if (BIO_puts(bp, "INVALID") <= 0) { + goto err; + } + } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) { + goto err; + } + BIO_puts(bp, "\n"); + + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_printf(bp, "%s Salt Length: 0x", pss_key ? "Minimum" : "") <= 0) + goto err; + if (pss->saltLength) { + if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) + goto err; + } else if (BIO_puts(bp, "14 (default)") <= 0) { + goto err; + } + BIO_puts(bp, "\n"); + + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_puts(bp, "Trailer Field: 0x") <= 0) + goto err; + if (pss->trailerField) { + if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) + goto err; + } else if (BIO_puts(bp, "BC (default)") <= 0) { + goto err; + } + BIO_puts(bp, "\n"); + + rv = 1; + + err: + X509_ALGOR_free(maskHash); + return rv; + +} + +static int pkey_rsa_print(BIO *bp, const EVP_PKEY *pkey, int off, int priv) +{ + const RSA *x = pkey->pkey.rsa; + char *str; + const char *s; + int ret = 0, mod_len = 0, ex_primes; + + if (x->n != NULL) + mod_len = BN_num_bits(x->n); + ex_primes = sk_RSA_PRIME_INFO_num(x->prime_infos); + + if (!BIO_indent(bp, off, 128)) + goto err; + + if (BIO_printf(bp, "%s ", pkey_is_pss(pkey) ? "RSA-PSS" : "RSA") <= 0) + goto err; + + if (priv && x->d) { + if (BIO_printf(bp, "Private-Key: (%d bit, %d primes)\n", + mod_len, ex_primes <= 0 ? 2 : ex_primes + 2) <= 0) + goto err; + str = "modulus:"; + s = "publicExponent:"; + } else { + if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0) + goto err; + str = "Modulus:"; + s = "Exponent:"; + } + if (!ASN1_bn_print(bp, str, x->n, NULL, off)) + goto err; + if (!ASN1_bn_print(bp, s, x->e, NULL, off)) + goto err; + if (priv) { + int i; + + if (!ASN1_bn_print(bp, "privateExponent:", x->d, NULL, off)) + goto err; + if (!ASN1_bn_print(bp, "prime1:", x->p, NULL, off)) + goto err; + if (!ASN1_bn_print(bp, "prime2:", x->q, NULL, off)) + goto err; + if (!ASN1_bn_print(bp, "exponent1:", x->dmp1, NULL, off)) + goto err; + if (!ASN1_bn_print(bp, "exponent2:", x->dmq1, NULL, off)) + goto err; + if (!ASN1_bn_print(bp, "coefficient:", x->iqmp, NULL, off)) + goto err; + for (i = 0; i < sk_RSA_PRIME_INFO_num(x->prime_infos); i++) { + /* print multi-prime info */ + BIGNUM *bn = NULL; + RSA_PRIME_INFO *pinfo; + int j; + + pinfo = sk_RSA_PRIME_INFO_value(x->prime_infos, i); + for (j = 0; j < 3; j++) { + if (!BIO_indent(bp, off, 128)) + goto err; + switch (j) { + case 0: + if (BIO_printf(bp, "prime%d:", i + 3) <= 0) + goto err; + bn = pinfo->r; + break; + case 1: + if (BIO_printf(bp, "exponent%d:", i + 3) <= 0) + goto err; + bn = pinfo->d; + break; + case 2: + if (BIO_printf(bp, "coefficient%d:", i + 3) <= 0) + goto err; + bn = pinfo->t; + break; + default: + break; + } + if (!ASN1_bn_print(bp, "", bn, NULL, off)) + goto err; + } + } + } + if (pkey_is_pss(pkey) && !rsa_pss_param_print(bp, 1, x->pss, off)) + goto err; + ret = 1; + err: + return ret; +} + +static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return pkey_rsa_print(bp, pkey, indent, 0); +} + +static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return pkey_rsa_print(bp, pkey, indent, 1); +} + +static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg) +{ + RSA_PSS_PARAMS *pss; + + pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_PSS_PARAMS), + alg->parameter); + + if (pss == NULL) + return NULL; + + if (pss->maskGenAlgorithm != NULL) { + pss->maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); + if (pss->maskHash == NULL) { + RSA_PSS_PARAMS_free(pss); + return NULL; + } + } + + return pss; +} + +static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, + const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) +{ + if (OBJ_obj2nid(sigalg->algorithm) == EVP_PKEY_RSA_PSS) { + int rv; + RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg); + + rv = rsa_pss_param_print(bp, 0, pss, indent); + RSA_PSS_PARAMS_free(pss); + if (!rv) + return 0; + } else if (!sig && BIO_puts(bp, "\n") <= 0) { + return 0; + } + if (sig) + return X509_signature_dump(bp, sig, indent); + return 1; +} + +static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + X509_ALGOR *alg = NULL; const EVP_MD *md; const EVP_MD *mgf1md; int min_saltlen; - - switch (op) { - - case ASN1_PKEY_CTRL_PKCS7_SIGN: - if (arg1 == 0) - PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg); - break; - - case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: - if (pkey_is_pss(pkey)) - return -2; - if (arg1 == 0) - PKCS7_RECIP_INFO_get0_alg(arg2, &alg); - break; -#ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) - return rsa_cms_sign(arg2); - else if (arg1 == 1) - return rsa_cms_verify(arg2); - break; - - case ASN1_PKEY_CTRL_CMS_ENVELOPE: - if (pkey_is_pss(pkey)) - return -2; - if (arg1 == 0) - return rsa_cms_encrypt(arg2); - else if (arg1 == 1) - return rsa_cms_decrypt(arg2); - break; - - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - if (pkey_is_pss(pkey)) - return -2; - *(int *)arg2 = CMS_RECIPINFO_TRANS; - return 1; -#endif - - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + + switch (op) { + + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg); + break; + + case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: + if (pkey_is_pss(pkey)) + return -2; + if (arg1 == 0) + PKCS7_RECIP_INFO_get0_alg(arg2, &alg); + break; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) + return rsa_cms_sign(arg2); + else if (arg1 == 1) + return rsa_cms_verify(arg2); + break; + + case ASN1_PKEY_CTRL_CMS_ENVELOPE: + if (pkey_is_pss(pkey)) + return -2; + if (arg1 == 0) + return rsa_cms_encrypt(arg2); + else if (arg1 == 1) + return rsa_cms_decrypt(arg2); + break; + + case ASN1_PKEY_CTRL_CMS_RI_TYPE: + if (pkey_is_pss(pkey)) + return -2; + *(int *)arg2 = CMS_RECIPINFO_TRANS; + return 1; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: if (pkey->pkey.rsa->pss != NULL) { if (!rsa_pss_get_param(pkey->pkey.rsa->pss, &md, &mgf1md, &min_saltlen)) { @@ -519,611 +519,611 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) /* Return of 2 indicates this MD is mandatory */ return 2; } - *(int *)arg2 = NID_sha256; - return 1; - - default: - return -2; - - } - - if (alg) - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - - return 1; - -} - -/* allocate and set algorithm ID from EVP_MD, default SHA1 */ -static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) -{ - if (md == NULL || EVP_MD_type(md) == NID_sha1) - return 1; - *palg = X509_ALGOR_new(); - if (*palg == NULL) - return 0; - X509_ALGOR_set_md(*palg, md); - return 1; -} - -/* Allocate and set MGF1 algorithm ID from EVP_MD */ -static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) -{ - X509_ALGOR *algtmp = NULL; - ASN1_STRING *stmp = NULL; - - *palg = NULL; - if (mgf1md == NULL || EVP_MD_type(mgf1md) == NID_sha1) - return 1; - /* need to embed algorithm ID inside another */ - if (!rsa_md_to_algor(&algtmp, mgf1md)) - goto err; - if (ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp) == NULL) - goto err; - *palg = X509_ALGOR_new(); - if (*palg == NULL) - goto err; - X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); - stmp = NULL; - err: - ASN1_STRING_free(stmp); - X509_ALGOR_free(algtmp); - if (*palg) - return 1; - return 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; -} - -/* - * Convert EVP_PKEY_CTX in PSS mode into corresponding algorithm parameter, - * suitable for setting an AlgorithmIdentifier. - */ - -static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) -{ - const EVP_MD *sigmd, *mgf1md; - EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); - int saltlen; - - if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0) - return NULL; - if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) - return NULL; - if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) - return NULL; - if (saltlen == -1) { - saltlen = EVP_MD_size(sigmd); + *(int *)arg2 = NID_sha256; + return 1; + + default: + return -2; + + } + + if (alg) + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + + return 1; + +} + +/* allocate and set algorithm ID from EVP_MD, default SHA1 */ +static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) +{ + if (md == NULL || EVP_MD_type(md) == NID_sha1) + return 1; + *palg = X509_ALGOR_new(); + if (*palg == NULL) + return 0; + X509_ALGOR_set_md(*palg, md); + return 1; +} + +/* Allocate and set MGF1 algorithm ID from EVP_MD */ +static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) +{ + X509_ALGOR *algtmp = NULL; + ASN1_STRING *stmp = NULL; + + *palg = NULL; + if (mgf1md == NULL || EVP_MD_type(mgf1md) == NID_sha1) + return 1; + /* need to embed algorithm ID inside another */ + if (!rsa_md_to_algor(&algtmp, mgf1md)) + goto err; + if (ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp) == NULL) + goto err; + *palg = X509_ALGOR_new(); + if (*palg == NULL) + goto err; + X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); + stmp = NULL; + err: + ASN1_STRING_free(stmp); + X509_ALGOR_free(algtmp); + if (*palg) + return 1; + return 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; +} + +/* + * Convert EVP_PKEY_CTX in PSS mode into corresponding algorithm parameter, + * suitable for setting an AlgorithmIdentifier. + */ + +static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) +{ + const EVP_MD *sigmd, *mgf1md; + EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); + int saltlen; + + if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0) + return NULL; + if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) + return NULL; + if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) + return NULL; + if (saltlen == -1) { + saltlen = EVP_MD_size(sigmd); } else if (saltlen == -2 || saltlen == -3) { - saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; - if ((EVP_PKEY_bits(pk) & 0x7) == 1) - saltlen--; + saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; + if ((EVP_PKEY_bits(pk) & 0x7) == 1) + saltlen--; if (saltlen < 0) return NULL; - } - - return rsa_pss_params_create(sigmd, mgf1md, saltlen); -} - -RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd, - const EVP_MD *mgf1md, int saltlen) -{ - RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new(); - - if (pss == NULL) - goto err; - if (saltlen != 20) { - pss->saltLength = ASN1_INTEGER_new(); - if (pss->saltLength == NULL) - goto err; - if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) - goto err; - } - if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd)) - goto err; - if (mgf1md == NULL) - mgf1md = sigmd; - if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) - goto err; - if (!rsa_md_to_algor(&pss->maskHash, mgf1md)) - goto err; - return pss; - err: - RSA_PSS_PARAMS_free(pss); - return NULL; -} - -static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) -{ - RSA_PSS_PARAMS *pss = rsa_ctx_to_pss(pkctx); - ASN1_STRING *os; - - if (pss == NULL) - return NULL; - - os = ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), NULL); - RSA_PSS_PARAMS_free(pss); - return os; -} - -/* - * From PSS AlgorithmIdentifier set public key parameters. If pkey isn't NULL - * then the EVP_MD_CTX is setup and initialised. If it is NULL parameters are - * passed to pkctx instead. - */ - -static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, - X509_ALGOR *sigalg, EVP_PKEY *pkey) -{ - int rv = -1; - int saltlen; - const EVP_MD *mgf1md = NULL, *md = NULL; - RSA_PSS_PARAMS *pss; - - /* Sanity check: make sure it is PSS */ - if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); - return -1; - } - /* Decode PSS parameters */ - pss = rsa_pss_decode(sigalg); - - if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS); - goto err; - } - - /* We have all parameters now set up context */ - if (pkey) { - if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) - goto err; - } else { - const EVP_MD *checkmd; - if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) - goto err; - if (EVP_MD_type(md) != EVP_MD_type(checkmd)) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH); - 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 = 1; - - err: - RSA_PSS_PARAMS_free(pss); - return rv; -} - -int rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, - const EVP_MD **pmgf1md, int *psaltlen) -{ - if (pss == NULL) - return 0; - *pmd = rsa_algor_to_md(pss->hashAlgorithm); - if (*pmd == NULL) - return 0; - *pmgf1md = rsa_algor_to_md(pss->maskHash); - if (*pmgf1md == NULL) - return 0; - if (pss->saltLength) { - *psaltlen = ASN1_INTEGER_get(pss->saltLength); - if (*psaltlen < 0) { - RSAerr(RSA_F_RSA_PSS_GET_PARAM, RSA_R_INVALID_SALT_LENGTH); - return 0; - } - } else { - *psaltlen = 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_PSS_GET_PARAM, RSA_R_INVALID_TRAILER); - return 0; - } - - return 1; -} - -#ifndef OPENSSL_NO_CMS -static int rsa_cms_verify(CMS_SignerInfo *si) -{ - int nid, nid2; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); - - CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); - nid = OBJ_obj2nid(alg->algorithm); - if (nid == EVP_PKEY_RSA_PSS) - return rsa_pss_to_ctx(NULL, pkctx, alg, NULL); - /* Only PSS allowed for PSS keys */ - if (pkey_ctx_is_pss(pkctx)) { - RSAerr(RSA_F_RSA_CMS_VERIFY, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); - return 0; - } - if (nid == NID_rsaEncryption) - return 1; - /* Workaround for some implementation that use a signature OID */ - if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { - if (nid2 == NID_rsaEncryption) - return 1; - } - return 0; -} -#endif - -/* - * Customised RSA item verification routine. This is called when a signature - * is encountered requiring special handling. We currently only handle PSS. - */ - -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) -{ - /* Sanity check: make sure it is PSS */ - if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { - RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); - return -1; - } - if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { - /* Carry on */ - return 2; - } - return -1; -} - -#ifndef OPENSSL_NO_CMS -static int rsa_cms_sign(CMS_SignerInfo *si) -{ - int pad_mode = RSA_PKCS1_PADDING; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); - ASN1_STRING *os = NULL; - - CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); - if (pkctx) { - if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) - return 0; - } - if (pad_mode == RSA_PKCS1_PADDING) { - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - return 1; - } - /* We don't support it */ - if (pad_mode != RSA_PKCS1_PSS_PADDING) - return 0; - os = rsa_ctx_to_pss_string(pkctx); - if (!os) - return 0; - X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os); - return 1; -} -#endif - -static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *alg1, X509_ALGOR *alg2, - ASN1_BIT_STRING *sig) -{ - int pad_mode; - EVP_PKEY_CTX *pkctx = EVP_MD_CTX_pkey_ctx(ctx); - - if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) - return 0; - if (pad_mode == RSA_PKCS1_PADDING) - return 2; - if (pad_mode == RSA_PKCS1_PSS_PADDING) { - ASN1_STRING *os1 = NULL; - os1 = rsa_ctx_to_pss_string(pkctx); - if (!os1) - return 0; - /* Duplicate parameters if we have to */ - if (alg2) { - ASN1_STRING *os2 = ASN1_STRING_dup(os1); - if (!os2) { - ASN1_STRING_free(os1); - return 0; - } - X509_ALGOR_set0(alg2, OBJ_nid2obj(EVP_PKEY_RSA_PSS), - V_ASN1_SEQUENCE, os2); - } - X509_ALGOR_set0(alg1, OBJ_nid2obj(EVP_PKEY_RSA_PSS), - V_ASN1_SEQUENCE, os1); - return 3; - } - return 2; -} - -static int rsa_sig_info_set(X509_SIG_INFO *siginf, const X509_ALGOR *sigalg, - const ASN1_STRING *sig) -{ - int rv = 0; - int mdnid, saltlen; - uint32_t flags; - const EVP_MD *mgf1md = NULL, *md = NULL; - RSA_PSS_PARAMS *pss; - - /* Sanity check: make sure it is PSS */ - if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) - return 0; - /* Decode PSS parameters */ - pss = rsa_pss_decode(sigalg); - if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) - goto err; - mdnid = EVP_MD_type(md); - /* - * For TLS need SHA256, SHA384 or SHA512, digest and MGF1 digest must - * match and salt length must equal digest size - */ - if ((mdnid == NID_sha256 || mdnid == NID_sha384 || mdnid == NID_sha512) - && mdnid == EVP_MD_type(mgf1md) && saltlen == EVP_MD_size(md)) - flags = X509_SIG_INFO_TLS; - else - flags = 0; - /* Note: security bits half number of digest bits */ - X509_SIG_INFO_set(siginf, mdnid, EVP_PKEY_RSA_PSS, EVP_MD_size(md) * 4, - flags); - rv = 1; - err: - RSA_PSS_PARAMS_free(pss); - return rv; -} - -#ifndef OPENSSL_NO_CMS -static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg) -{ - RSA_OAEP_PARAMS *oaep; - - oaep = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS), - alg->parameter); - - if (oaep == NULL) - return NULL; - - if (oaep->maskGenFunc != NULL) { - oaep->maskHash = rsa_mgf1_decode(oaep->maskGenFunc); - if (oaep->maskHash == NULL) { - RSA_OAEP_PARAMS_free(oaep); - return NULL; - } - } - return oaep; -} - -static int rsa_cms_decrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pkctx; - X509_ALGOR *cmsalg; - int nid; - int rv = -1; - unsigned char *label = NULL; - int labellen = 0; - const EVP_MD *mgf1md = NULL, *md = NULL; - RSA_OAEP_PARAMS *oaep; - - pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (pkctx == NULL) - return 0; - if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg)) - return -1; - nid = OBJ_obj2nid(cmsalg->algorithm); - if (nid == NID_rsaEncryption) - return 1; - if (nid != NID_rsaesOaep) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE); - return -1; - } - /* Decode OAEP parameters */ - oaep = rsa_oaep_decode(cmsalg); - - if (oaep == NULL) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_OAEP_PARAMETERS); - goto err; - } - - mgf1md = rsa_algor_to_md(oaep->maskHash); - if (mgf1md == NULL) - goto err; - md = rsa_algor_to_md(oaep->hashFunc); - if (md == NULL) - goto err; - - if (oaep->pSourceFunc != NULL) { - X509_ALGOR *plab = oaep->pSourceFunc; - - if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE); - goto err; - } - if (plab->parameter->type != V_ASN1_OCTET_STRING) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL); - goto err; - } - - label = plab->parameter->value.octet_string->data; - /* Stop label being freed when OAEP parameters are freed */ - plab->parameter->value.octet_string->data = NULL; - labellen = plab->parameter->value.octet_string->length; - } - - if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) - goto err; - if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0) - goto err; - if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) - goto err; - if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) - goto err; - /* Carry on */ - rv = 1; - - err: - RSA_OAEP_PARAMS_free(oaep); - return rv; -} - -static int rsa_cms_encrypt(CMS_RecipientInfo *ri) -{ - const EVP_MD *md, *mgf1md; - RSA_OAEP_PARAMS *oaep = NULL; - ASN1_STRING *os = NULL; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; - unsigned char *label; - - if (CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg) <= 0) - return 0; - if (pkctx) { - if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) - return 0; - } - if (pad_mode == RSA_PKCS1_PADDING) { - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - return 1; - } - /* Not supported */ - if (pad_mode != RSA_PKCS1_OAEP_PADDING) - return 0; - if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) - goto err; - if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) - goto err; - labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); - if (labellen < 0) - goto err; - oaep = RSA_OAEP_PARAMS_new(); - if (oaep == NULL) - goto err; - if (!rsa_md_to_algor(&oaep->hashFunc, md)) - goto err; - if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) - goto err; - if (labellen > 0) { - ASN1_OCTET_STRING *los; - oaep->pSourceFunc = X509_ALGOR_new(); - if (oaep->pSourceFunc == NULL) - goto err; - los = ASN1_OCTET_STRING_new(); - if (los == NULL) - goto err; - if (!ASN1_OCTET_STRING_set(los, label, labellen)) { - ASN1_OCTET_STRING_free(los); - goto err; - } - X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), - V_ASN1_OCTET_STRING, los); - } - /* create string with pss parameter encoding. */ - if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) - goto err; - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); - os = NULL; - rv = 1; - err: - RSA_OAEP_PARAMS_free(oaep); - ASN1_STRING_free(os); - return rv; -} -#endif - -static int rsa_pkey_check(const EVP_PKEY *pkey) -{ - return RSA_check_key_ex(pkey->pkey.rsa, NULL); -} - -const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = { - { - EVP_PKEY_RSA, - EVP_PKEY_RSA, - ASN1_PKEY_SIGPARAM_NULL, - - "RSA", - "OpenSSL RSA method", - - rsa_pub_decode, - rsa_pub_encode, - rsa_pub_cmp, - rsa_pub_print, - - rsa_priv_decode, - rsa_priv_encode, - rsa_priv_print, - - int_rsa_size, - rsa_bits, - rsa_security_bits, - - 0, 0, 0, 0, 0, 0, - - rsa_sig_print, - int_rsa_free, - rsa_pkey_ctrl, - old_rsa_priv_decode, - old_rsa_priv_encode, - rsa_item_verify, - rsa_item_sign, - rsa_sig_info_set, - rsa_pkey_check - }, - - { - EVP_PKEY_RSA2, - EVP_PKEY_RSA, - ASN1_PKEY_ALIAS} -}; - -const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth = { - EVP_PKEY_RSA_PSS, - EVP_PKEY_RSA_PSS, - ASN1_PKEY_SIGPARAM_NULL, - - "RSA-PSS", - "OpenSSL RSA-PSS method", - - rsa_pub_decode, - rsa_pub_encode, - rsa_pub_cmp, - rsa_pub_print, - - rsa_priv_decode, - rsa_priv_encode, - rsa_priv_print, - - int_rsa_size, - rsa_bits, - rsa_security_bits, - - 0, 0, 0, 0, 0, 0, - - rsa_sig_print, - int_rsa_free, - rsa_pkey_ctrl, - 0, 0, - rsa_item_verify, - rsa_item_sign, - 0, - rsa_pkey_check -}; + } + + return rsa_pss_params_create(sigmd, mgf1md, saltlen); +} + +RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd, + const EVP_MD *mgf1md, int saltlen) +{ + RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new(); + + if (pss == NULL) + goto err; + if (saltlen != 20) { + pss->saltLength = ASN1_INTEGER_new(); + if (pss->saltLength == NULL) + goto err; + if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) + goto err; + } + if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd)) + goto err; + if (mgf1md == NULL) + mgf1md = sigmd; + if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) + goto err; + if (!rsa_md_to_algor(&pss->maskHash, mgf1md)) + goto err; + return pss; + err: + RSA_PSS_PARAMS_free(pss); + return NULL; +} + +static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) +{ + RSA_PSS_PARAMS *pss = rsa_ctx_to_pss(pkctx); + ASN1_STRING *os; + + if (pss == NULL) + return NULL; + + os = ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), NULL); + RSA_PSS_PARAMS_free(pss); + return os; +} + +/* + * From PSS AlgorithmIdentifier set public key parameters. If pkey isn't NULL + * then the EVP_MD_CTX is setup and initialised. If it is NULL parameters are + * passed to pkctx instead. + */ + +static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, + X509_ALGOR *sigalg, EVP_PKEY *pkey) +{ + int rv = -1; + int saltlen; + const EVP_MD *mgf1md = NULL, *md = NULL; + RSA_PSS_PARAMS *pss; + + /* Sanity check: make sure it is PSS */ + if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { + RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); + return -1; + } + /* Decode PSS parameters */ + pss = rsa_pss_decode(sigalg); + + if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) { + RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS); + goto err; + } + + /* We have all parameters now set up context */ + if (pkey) { + if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) + goto err; + } else { + const EVP_MD *checkmd; + if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) + goto err; + if (EVP_MD_type(md) != EVP_MD_type(checkmd)) { + RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH); + 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 = 1; + + err: + RSA_PSS_PARAMS_free(pss); + return rv; +} + +int rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, + const EVP_MD **pmgf1md, int *psaltlen) +{ + if (pss == NULL) + return 0; + *pmd = rsa_algor_to_md(pss->hashAlgorithm); + if (*pmd == NULL) + return 0; + *pmgf1md = rsa_algor_to_md(pss->maskHash); + if (*pmgf1md == NULL) + return 0; + if (pss->saltLength) { + *psaltlen = ASN1_INTEGER_get(pss->saltLength); + if (*psaltlen < 0) { + RSAerr(RSA_F_RSA_PSS_GET_PARAM, RSA_R_INVALID_SALT_LENGTH); + return 0; + } + } else { + *psaltlen = 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_PSS_GET_PARAM, RSA_R_INVALID_TRAILER); + return 0; + } + + return 1; +} + +#ifndef OPENSSL_NO_CMS +static int rsa_cms_verify(CMS_SignerInfo *si) +{ + int nid, nid2; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); + + CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); + nid = OBJ_obj2nid(alg->algorithm); + if (nid == EVP_PKEY_RSA_PSS) + return rsa_pss_to_ctx(NULL, pkctx, alg, NULL); + /* Only PSS allowed for PSS keys */ + if (pkey_ctx_is_pss(pkctx)) { + RSAerr(RSA_F_RSA_CMS_VERIFY, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return 0; + } + if (nid == NID_rsaEncryption) + return 1; + /* Workaround for some implementation that use a signature OID */ + if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { + if (nid2 == NID_rsaEncryption) + return 1; + } + return 0; +} +#endif + +/* + * Customised RSA item verification routine. This is called when a signature + * is encountered requiring special handling. We currently only handle PSS. + */ + +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) +{ + /* Sanity check: make sure it is PSS */ + if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { + RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); + return -1; + } + if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { + /* Carry on */ + return 2; + } + return -1; +} + +#ifndef OPENSSL_NO_CMS +static int rsa_cms_sign(CMS_SignerInfo *si) +{ + int pad_mode = RSA_PKCS1_PADDING; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); + ASN1_STRING *os = NULL; + + CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); + if (pkctx) { + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + } + if (pad_mode == RSA_PKCS1_PADDING) { + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return 1; + } + /* We don't support it */ + if (pad_mode != RSA_PKCS1_PSS_PADDING) + return 0; + os = rsa_ctx_to_pss_string(pkctx); + if (!os) + return 0; + X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os); + return 1; +} +#endif + +static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *alg1, X509_ALGOR *alg2, + ASN1_BIT_STRING *sig) +{ + int pad_mode; + EVP_PKEY_CTX *pkctx = EVP_MD_CTX_pkey_ctx(ctx); + + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + if (pad_mode == RSA_PKCS1_PADDING) + return 2; + if (pad_mode == RSA_PKCS1_PSS_PADDING) { + ASN1_STRING *os1 = NULL; + os1 = rsa_ctx_to_pss_string(pkctx); + if (!os1) + return 0; + /* Duplicate parameters if we have to */ + if (alg2) { + ASN1_STRING *os2 = ASN1_STRING_dup(os1); + if (!os2) { + ASN1_STRING_free(os1); + return 0; + } + X509_ALGOR_set0(alg2, OBJ_nid2obj(EVP_PKEY_RSA_PSS), + V_ASN1_SEQUENCE, os2); + } + X509_ALGOR_set0(alg1, OBJ_nid2obj(EVP_PKEY_RSA_PSS), + V_ASN1_SEQUENCE, os1); + return 3; + } + return 2; +} + +static int rsa_sig_info_set(X509_SIG_INFO *siginf, const X509_ALGOR *sigalg, + const ASN1_STRING *sig) +{ + int rv = 0; + int mdnid, saltlen; + uint32_t flags; + const EVP_MD *mgf1md = NULL, *md = NULL; + RSA_PSS_PARAMS *pss; + + /* Sanity check: make sure it is PSS */ + if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) + return 0; + /* Decode PSS parameters */ + pss = rsa_pss_decode(sigalg); + if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) + goto err; + mdnid = EVP_MD_type(md); + /* + * For TLS need SHA256, SHA384 or SHA512, digest and MGF1 digest must + * match and salt length must equal digest size + */ + if ((mdnid == NID_sha256 || mdnid == NID_sha384 || mdnid == NID_sha512) + && mdnid == EVP_MD_type(mgf1md) && saltlen == EVP_MD_size(md)) + flags = X509_SIG_INFO_TLS; + else + flags = 0; + /* Note: security bits half number of digest bits */ + X509_SIG_INFO_set(siginf, mdnid, EVP_PKEY_RSA_PSS, EVP_MD_size(md) * 4, + flags); + rv = 1; + err: + RSA_PSS_PARAMS_free(pss); + return rv; +} + +#ifndef OPENSSL_NO_CMS +static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg) +{ + RSA_OAEP_PARAMS *oaep; + + oaep = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS), + alg->parameter); + + if (oaep == NULL) + return NULL; + + if (oaep->maskGenFunc != NULL) { + oaep->maskHash = rsa_mgf1_decode(oaep->maskGenFunc); + if (oaep->maskHash == NULL) { + RSA_OAEP_PARAMS_free(oaep); + return NULL; + } + } + return oaep; +} + +static int rsa_cms_decrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pkctx; + X509_ALGOR *cmsalg; + int nid; + int rv = -1; + unsigned char *label = NULL; + int labellen = 0; + const EVP_MD *mgf1md = NULL, *md = NULL; + RSA_OAEP_PARAMS *oaep; + + pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (pkctx == NULL) + return 0; + if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg)) + return -1; + nid = OBJ_obj2nid(cmsalg->algorithm); + if (nid == NID_rsaEncryption) + return 1; + if (nid != NID_rsaesOaep) { + RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE); + return -1; + } + /* Decode OAEP parameters */ + oaep = rsa_oaep_decode(cmsalg); + + if (oaep == NULL) { + RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_OAEP_PARAMETERS); + goto err; + } + + mgf1md = rsa_algor_to_md(oaep->maskHash); + if (mgf1md == NULL) + goto err; + md = rsa_algor_to_md(oaep->hashFunc); + if (md == NULL) + goto err; + + if (oaep->pSourceFunc != NULL) { + X509_ALGOR *plab = oaep->pSourceFunc; + + if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { + RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE); + goto err; + } + if (plab->parameter->type != V_ASN1_OCTET_STRING) { + RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL); + goto err; + } + + label = plab->parameter->value.octet_string->data; + /* Stop label being freed when OAEP parameters are freed */ + plab->parameter->value.octet_string->data = NULL; + labellen = plab->parameter->value.octet_string->length; + } + + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) + goto err; + if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0) + goto err; + if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) + goto err; + if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) + goto err; + /* Carry on */ + rv = 1; + + err: + RSA_OAEP_PARAMS_free(oaep); + return rv; +} + +static int rsa_cms_encrypt(CMS_RecipientInfo *ri) +{ + const EVP_MD *md, *mgf1md; + RSA_OAEP_PARAMS *oaep = NULL; + ASN1_STRING *os = NULL; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; + unsigned char *label; + + if (CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg) <= 0) + return 0; + if (pkctx) { + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + } + if (pad_mode == RSA_PKCS1_PADDING) { + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return 1; + } + /* Not supported */ + if (pad_mode != RSA_PKCS1_OAEP_PADDING) + return 0; + if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) + goto err; + if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) + goto err; + labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); + if (labellen < 0) + goto err; + oaep = RSA_OAEP_PARAMS_new(); + if (oaep == NULL) + goto err; + if (!rsa_md_to_algor(&oaep->hashFunc, md)) + goto err; + if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) + goto err; + if (labellen > 0) { + ASN1_OCTET_STRING *los; + oaep->pSourceFunc = X509_ALGOR_new(); + if (oaep->pSourceFunc == NULL) + goto err; + los = ASN1_OCTET_STRING_new(); + if (los == NULL) + goto err; + if (!ASN1_OCTET_STRING_set(los, label, labellen)) { + ASN1_OCTET_STRING_free(los); + goto err; + } + X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), + V_ASN1_OCTET_STRING, los); + } + /* create string with pss parameter encoding. */ + if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) + goto err; + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); + os = NULL; + rv = 1; + err: + RSA_OAEP_PARAMS_free(oaep); + ASN1_STRING_free(os); + return rv; +} +#endif + +static int rsa_pkey_check(const EVP_PKEY *pkey) +{ + return RSA_check_key_ex(pkey->pkey.rsa, NULL); +} + +const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = { + { + EVP_PKEY_RSA, + EVP_PKEY_RSA, + ASN1_PKEY_SIGPARAM_NULL, + + "RSA", + "OpenSSL RSA method", + + rsa_pub_decode, + rsa_pub_encode, + rsa_pub_cmp, + rsa_pub_print, + + rsa_priv_decode, + rsa_priv_encode, + rsa_priv_print, + + int_rsa_size, + rsa_bits, + rsa_security_bits, + + 0, 0, 0, 0, 0, 0, + + rsa_sig_print, + int_rsa_free, + rsa_pkey_ctrl, + old_rsa_priv_decode, + old_rsa_priv_encode, + rsa_item_verify, + rsa_item_sign, + rsa_sig_info_set, + rsa_pkey_check + }, + + { + EVP_PKEY_RSA2, + EVP_PKEY_RSA, + ASN1_PKEY_ALIAS} +}; + +const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth = { + EVP_PKEY_RSA_PSS, + EVP_PKEY_RSA_PSS, + ASN1_PKEY_SIGPARAM_NULL, + + "RSA-PSS", + "OpenSSL RSA-PSS method", + + rsa_pub_decode, + rsa_pub_encode, + rsa_pub_cmp, + rsa_pub_print, + + rsa_priv_decode, + rsa_priv_encode, + rsa_priv_print, + + int_rsa_size, + rsa_bits, + rsa_security_bits, + + 0, 0, 0, 0, 0, 0, + + rsa_sig_print, + int_rsa_free, + rsa_pkey_ctrl, + 0, 0, + rsa_item_verify, + rsa_item_sign, + 0, + rsa_pkey_check +}; diff --git a/contrib/libs/openssl/crypto/rsa/rsa_asn1.c b/contrib/libs/openssl/crypto/rsa/rsa_asn1.c index e8df8d762e..7782397aec 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_asn1.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_asn1.c @@ -1,121 +1,121 @@ -/* - * Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdio.h> -#include "internal/cryptlib.h" -#include <openssl/bn.h> -#include <openssl/x509.h> -#include <openssl/asn1t.h> +/* + * Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/bn.h> +#include <openssl/x509.h> +#include <openssl/asn1t.h> #include "rsa_local.h" - -/* - * Override the default free and new methods, - * and calculate helper products for multi-prime - * RSA keys. - */ -static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_NEW_PRE) { - *pval = (ASN1_VALUE *)RSA_new(); - if (*pval != NULL) - return 2; - return 0; - } else if (operation == ASN1_OP_FREE_PRE) { - RSA_free((RSA *)*pval); - *pval = NULL; - return 2; - } else if (operation == ASN1_OP_D2I_POST) { - if (((RSA *)*pval)->version != RSA_ASN1_VERSION_MULTI) { - /* not a multi-prime key, skip */ - return 1; - } - return (rsa_multip_calc_product((RSA *)*pval) == 1) ? 2 : 0; - } - return 1; -} - -/* Based on definitions in RFC 8017 appendix A.1.2 */ -ASN1_SEQUENCE(RSA_PRIME_INFO) = { - ASN1_SIMPLE(RSA_PRIME_INFO, r, CBIGNUM), - ASN1_SIMPLE(RSA_PRIME_INFO, d, CBIGNUM), - ASN1_SIMPLE(RSA_PRIME_INFO, t, CBIGNUM), -} ASN1_SEQUENCE_END(RSA_PRIME_INFO) - -ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = { - ASN1_EMBED(RSA, version, INT32), - ASN1_SIMPLE(RSA, n, BIGNUM), - ASN1_SIMPLE(RSA, e, BIGNUM), - ASN1_SIMPLE(RSA, d, CBIGNUM), - ASN1_SIMPLE(RSA, p, CBIGNUM), - ASN1_SIMPLE(RSA, q, CBIGNUM), - ASN1_SIMPLE(RSA, dmp1, CBIGNUM), - ASN1_SIMPLE(RSA, dmq1, CBIGNUM), - ASN1_SIMPLE(RSA, iqmp, CBIGNUM), - ASN1_SEQUENCE_OF_OPT(RSA, prime_infos, RSA_PRIME_INFO) -} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey) - - -ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = { - ASN1_SIMPLE(RSA, n, BIGNUM), - ASN1_SIMPLE(RSA, e, BIGNUM), -} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey) - -/* Free up maskHash */ -static int rsa_pss_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_FREE_PRE) { - RSA_PSS_PARAMS *pss = (RSA_PSS_PARAMS *)*pval; - X509_ALGOR_free(pss->maskHash); - } - return 1; -} - -ASN1_SEQUENCE_cb(RSA_PSS_PARAMS, rsa_pss_cb) = { - ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0), - ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1), - ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2), - ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3) -} ASN1_SEQUENCE_END_cb(RSA_PSS_PARAMS, RSA_PSS_PARAMS) - -IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS) - -/* Free up maskHash */ -static int rsa_oaep_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_FREE_PRE) { - RSA_OAEP_PARAMS *oaep = (RSA_OAEP_PARAMS *)*pval; - X509_ALGOR_free(oaep->maskHash); - } - return 1; -} - -ASN1_SEQUENCE_cb(RSA_OAEP_PARAMS, rsa_oaep_cb) = { - ASN1_EXP_OPT(RSA_OAEP_PARAMS, hashFunc, X509_ALGOR, 0), - ASN1_EXP_OPT(RSA_OAEP_PARAMS, maskGenFunc, X509_ALGOR, 1), - ASN1_EXP_OPT(RSA_OAEP_PARAMS, pSourceFunc, X509_ALGOR, 2), -} ASN1_SEQUENCE_END_cb(RSA_OAEP_PARAMS, RSA_OAEP_PARAMS) - -IMPLEMENT_ASN1_FUNCTIONS(RSA_OAEP_PARAMS) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey) - -RSA *RSAPublicKey_dup(RSA *rsa) -{ - return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa); -} - -RSA *RSAPrivateKey_dup(RSA *rsa) -{ - return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa); -} + +/* + * Override the default free and new methods, + * and calculate helper products for multi-prime + * RSA keys. + */ +static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + *pval = (ASN1_VALUE *)RSA_new(); + if (*pval != NULL) + return 2; + return 0; + } else if (operation == ASN1_OP_FREE_PRE) { + RSA_free((RSA *)*pval); + *pval = NULL; + return 2; + } else if (operation == ASN1_OP_D2I_POST) { + if (((RSA *)*pval)->version != RSA_ASN1_VERSION_MULTI) { + /* not a multi-prime key, skip */ + return 1; + } + return (rsa_multip_calc_product((RSA *)*pval) == 1) ? 2 : 0; + } + return 1; +} + +/* Based on definitions in RFC 8017 appendix A.1.2 */ +ASN1_SEQUENCE(RSA_PRIME_INFO) = { + ASN1_SIMPLE(RSA_PRIME_INFO, r, CBIGNUM), + ASN1_SIMPLE(RSA_PRIME_INFO, d, CBIGNUM), + ASN1_SIMPLE(RSA_PRIME_INFO, t, CBIGNUM), +} ASN1_SEQUENCE_END(RSA_PRIME_INFO) + +ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = { + ASN1_EMBED(RSA, version, INT32), + ASN1_SIMPLE(RSA, n, BIGNUM), + ASN1_SIMPLE(RSA, e, BIGNUM), + ASN1_SIMPLE(RSA, d, CBIGNUM), + ASN1_SIMPLE(RSA, p, CBIGNUM), + ASN1_SIMPLE(RSA, q, CBIGNUM), + ASN1_SIMPLE(RSA, dmp1, CBIGNUM), + ASN1_SIMPLE(RSA, dmq1, CBIGNUM), + ASN1_SIMPLE(RSA, iqmp, CBIGNUM), + ASN1_SEQUENCE_OF_OPT(RSA, prime_infos, RSA_PRIME_INFO) +} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey) + + +ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = { + ASN1_SIMPLE(RSA, n, BIGNUM), + ASN1_SIMPLE(RSA, e, BIGNUM), +} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey) + +/* Free up maskHash */ +static int rsa_pss_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_PRE) { + RSA_PSS_PARAMS *pss = (RSA_PSS_PARAMS *)*pval; + X509_ALGOR_free(pss->maskHash); + } + return 1; +} + +ASN1_SEQUENCE_cb(RSA_PSS_PARAMS, rsa_pss_cb) = { + ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0), + ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1), + ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2), + ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3) +} ASN1_SEQUENCE_END_cb(RSA_PSS_PARAMS, RSA_PSS_PARAMS) + +IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS) + +/* Free up maskHash */ +static int rsa_oaep_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_PRE) { + RSA_OAEP_PARAMS *oaep = (RSA_OAEP_PARAMS *)*pval; + X509_ALGOR_free(oaep->maskHash); + } + return 1; +} + +ASN1_SEQUENCE_cb(RSA_OAEP_PARAMS, rsa_oaep_cb) = { + ASN1_EXP_OPT(RSA_OAEP_PARAMS, hashFunc, X509_ALGOR, 0), + ASN1_EXP_OPT(RSA_OAEP_PARAMS, maskGenFunc, X509_ALGOR, 1), + ASN1_EXP_OPT(RSA_OAEP_PARAMS, pSourceFunc, X509_ALGOR, 2), +} ASN1_SEQUENCE_END_cb(RSA_OAEP_PARAMS, RSA_OAEP_PARAMS) + +IMPLEMENT_ASN1_FUNCTIONS(RSA_OAEP_PARAMS) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey) + +RSA *RSAPublicKey_dup(RSA *rsa) +{ + return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa); +} + +RSA *RSAPrivateKey_dup(RSA *rsa) +{ + return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa); +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_chk.c b/contrib/libs/openssl/crypto/rsa/rsa_chk.c index b4ba7fce3f..038af11ad4 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_chk.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_chk.c @@ -1,228 +1,228 @@ -/* - * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <openssl/bn.h> -#include <openssl/err.h> +/* + * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/bn.h> +#include <openssl/err.h> #include "rsa_local.h" - -int RSA_check_key(const RSA *key) -{ - return RSA_check_key_ex(key, NULL); -} - -int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) -{ - BIGNUM *i, *j, *k, *l, *m; - BN_CTX *ctx; - int ret = 1, ex_primes = 0, idx; - RSA_PRIME_INFO *pinfo; - - if (key->p == NULL || key->q == NULL || key->n == NULL - || key->e == NULL || key->d == NULL) { - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_VALUE_MISSING); - return 0; - } - - /* multi-prime? */ - if (key->version == RSA_ASN1_VERSION_MULTI) { - ex_primes = sk_RSA_PRIME_INFO_num(key->prime_infos); - if (ex_primes <= 0 - || (ex_primes + 2) > rsa_multip_cap(BN_num_bits(key->n))) { - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_INVALID_MULTI_PRIME_KEY); - return 0; - } - } - - i = BN_new(); - j = BN_new(); - k = BN_new(); - l = BN_new(); - m = BN_new(); - ctx = BN_CTX_new(); - if (i == NULL || j == NULL || k == NULL || l == NULL - || m == NULL || ctx == NULL) { - ret = -1; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (BN_is_one(key->e)) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE); - } - if (!BN_is_odd(key->e)) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE); - } - - /* p prime? */ - if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, cb) != 1) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_P_NOT_PRIME); - } - - /* q prime? */ - if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, cb) != 1) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_Q_NOT_PRIME); - } - - /* r_i prime? */ - for (idx = 0; idx < ex_primes; idx++) { - pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); - if (BN_is_prime_ex(pinfo->r, BN_prime_checks, NULL, cb) != 1) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_R_NOT_PRIME); - } - } - - /* n = p*q * r_3...r_i? */ - if (!BN_mul(i, key->p, key->q, ctx)) { - ret = -1; - goto err; - } - for (idx = 0; idx < ex_primes; idx++) { - pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); - if (!BN_mul(i, i, pinfo->r, ctx)) { - ret = -1; - goto err; - } - } - if (BN_cmp(i, key->n) != 0) { - ret = 0; - if (ex_primes) - RSAerr(RSA_F_RSA_CHECK_KEY_EX, - RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES); - else - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_N_DOES_NOT_EQUAL_P_Q); - } - - /* d*e = 1 mod \lambda(n)? */ - if (!BN_sub(i, key->p, BN_value_one())) { - ret = -1; - goto err; - } - if (!BN_sub(j, key->q, BN_value_one())) { - ret = -1; - goto err; - } - - /* now compute k = \lambda(n) = LCM(i, j, r_3 - 1...) */ - if (!BN_mul(l, i, j, ctx)) { - ret = -1; - goto err; - } - if (!BN_gcd(m, i, j, ctx)) { - ret = -1; - goto err; - } - for (idx = 0; idx < ex_primes; idx++) { - pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); - if (!BN_sub(k, pinfo->r, BN_value_one())) { - ret = -1; - goto err; - } - if (!BN_mul(l, l, k, ctx)) { - ret = -1; - goto err; - } - if (!BN_gcd(m, m, k, ctx)) { - ret = -1; - goto err; - } - } - if (!BN_div(k, NULL, l, m, ctx)) { /* remainder is 0 */ - ret = -1; - goto err; - } - if (!BN_mod_mul(i, key->d, key->e, k, ctx)) { - ret = -1; - goto err; - } - - if (!BN_is_one(i)) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_D_E_NOT_CONGRUENT_TO_1); - } - - if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { - /* dmp1 = d mod (p-1)? */ - if (!BN_sub(i, key->p, BN_value_one())) { - ret = -1; - goto err; - } - if (!BN_mod(j, key->d, i, ctx)) { - ret = -1; - goto err; - } - if (BN_cmp(j, key->dmp1) != 0) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMP1_NOT_CONGRUENT_TO_D); - } - - /* dmq1 = d mod (q-1)? */ - if (!BN_sub(i, key->q, BN_value_one())) { - ret = -1; - goto err; - } - if (!BN_mod(j, key->d, i, ctx)) { - ret = -1; - goto err; - } - if (BN_cmp(j, key->dmq1) != 0) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMQ1_NOT_CONGRUENT_TO_D); - } - - /* iqmp = q^-1 mod p? */ - if (!BN_mod_inverse(i, key->q, key->p, ctx)) { - ret = -1; - goto err; - } - if (BN_cmp(i, key->iqmp) != 0) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_IQMP_NOT_INVERSE_OF_Q); - } - } - - for (idx = 0; idx < ex_primes; idx++) { - pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); - /* d_i = d mod (r_i - 1)? */ - if (!BN_sub(i, pinfo->r, BN_value_one())) { - ret = -1; - goto err; - } - if (!BN_mod(j, key->d, i, ctx)) { - ret = -1; - goto err; - } - if (BN_cmp(j, pinfo->d) != 0) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D); - } - /* t_i = R_i ^ -1 mod r_i ? */ - if (!BN_mod_inverse(i, pinfo->pp, pinfo->r, ctx)) { - ret = -1; - goto err; - } - if (BN_cmp(i, pinfo->t) != 0) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R); - } - } - - err: - BN_free(i); - BN_free(j); - BN_free(k); - BN_free(l); - BN_free(m); - BN_CTX_free(ctx); - return ret; -} + +int RSA_check_key(const RSA *key) +{ + return RSA_check_key_ex(key, NULL); +} + +int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) +{ + BIGNUM *i, *j, *k, *l, *m; + BN_CTX *ctx; + int ret = 1, ex_primes = 0, idx; + RSA_PRIME_INFO *pinfo; + + if (key->p == NULL || key->q == NULL || key->n == NULL + || key->e == NULL || key->d == NULL) { + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_VALUE_MISSING); + return 0; + } + + /* multi-prime? */ + if (key->version == RSA_ASN1_VERSION_MULTI) { + ex_primes = sk_RSA_PRIME_INFO_num(key->prime_infos); + if (ex_primes <= 0 + || (ex_primes + 2) > rsa_multip_cap(BN_num_bits(key->n))) { + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_INVALID_MULTI_PRIME_KEY); + return 0; + } + } + + i = BN_new(); + j = BN_new(); + k = BN_new(); + l = BN_new(); + m = BN_new(); + ctx = BN_CTX_new(); + if (i == NULL || j == NULL || k == NULL || l == NULL + || m == NULL || ctx == NULL) { + ret = -1; + RSAerr(RSA_F_RSA_CHECK_KEY_EX, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (BN_is_one(key->e)) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE); + } + if (!BN_is_odd(key->e)) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE); + } + + /* p prime? */ + if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, cb) != 1) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_P_NOT_PRIME); + } + + /* q prime? */ + if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, cb) != 1) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_Q_NOT_PRIME); + } + + /* r_i prime? */ + for (idx = 0; idx < ex_primes; idx++) { + pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); + if (BN_is_prime_ex(pinfo->r, BN_prime_checks, NULL, cb) != 1) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_R_NOT_PRIME); + } + } + + /* n = p*q * r_3...r_i? */ + if (!BN_mul(i, key->p, key->q, ctx)) { + ret = -1; + goto err; + } + for (idx = 0; idx < ex_primes; idx++) { + pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); + if (!BN_mul(i, i, pinfo->r, ctx)) { + ret = -1; + goto err; + } + } + if (BN_cmp(i, key->n) != 0) { + ret = 0; + if (ex_primes) + RSAerr(RSA_F_RSA_CHECK_KEY_EX, + RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES); + else + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_N_DOES_NOT_EQUAL_P_Q); + } + + /* d*e = 1 mod \lambda(n)? */ + if (!BN_sub(i, key->p, BN_value_one())) { + ret = -1; + goto err; + } + if (!BN_sub(j, key->q, BN_value_one())) { + ret = -1; + goto err; + } + + /* now compute k = \lambda(n) = LCM(i, j, r_3 - 1...) */ + if (!BN_mul(l, i, j, ctx)) { + ret = -1; + goto err; + } + if (!BN_gcd(m, i, j, ctx)) { + ret = -1; + goto err; + } + for (idx = 0; idx < ex_primes; idx++) { + pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); + if (!BN_sub(k, pinfo->r, BN_value_one())) { + ret = -1; + goto err; + } + if (!BN_mul(l, l, k, ctx)) { + ret = -1; + goto err; + } + if (!BN_gcd(m, m, k, ctx)) { + ret = -1; + goto err; + } + } + if (!BN_div(k, NULL, l, m, ctx)) { /* remainder is 0 */ + ret = -1; + goto err; + } + if (!BN_mod_mul(i, key->d, key->e, k, ctx)) { + ret = -1; + goto err; + } + + if (!BN_is_one(i)) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_D_E_NOT_CONGRUENT_TO_1); + } + + if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { + /* dmp1 = d mod (p-1)? */ + if (!BN_sub(i, key->p, BN_value_one())) { + ret = -1; + goto err; + } + if (!BN_mod(j, key->d, i, ctx)) { + ret = -1; + goto err; + } + if (BN_cmp(j, key->dmp1) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMP1_NOT_CONGRUENT_TO_D); + } + + /* dmq1 = d mod (q-1)? */ + if (!BN_sub(i, key->q, BN_value_one())) { + ret = -1; + goto err; + } + if (!BN_mod(j, key->d, i, ctx)) { + ret = -1; + goto err; + } + if (BN_cmp(j, key->dmq1) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMQ1_NOT_CONGRUENT_TO_D); + } + + /* iqmp = q^-1 mod p? */ + if (!BN_mod_inverse(i, key->q, key->p, ctx)) { + ret = -1; + goto err; + } + if (BN_cmp(i, key->iqmp) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_IQMP_NOT_INVERSE_OF_Q); + } + } + + for (idx = 0; idx < ex_primes; idx++) { + pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); + /* d_i = d mod (r_i - 1)? */ + if (!BN_sub(i, pinfo->r, BN_value_one())) { + ret = -1; + goto err; + } + if (!BN_mod(j, key->d, i, ctx)) { + ret = -1; + goto err; + } + if (BN_cmp(j, pinfo->d) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D); + } + /* t_i = R_i ^ -1 mod r_i ? */ + if (!BN_mod_inverse(i, pinfo->pp, pinfo->r, ctx)) { + ret = -1; + goto err; + } + if (BN_cmp(i, pinfo->t) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R); + } + } + + err: + BN_free(i); + BN_free(j); + BN_free(k); + BN_free(l); + BN_free(m); + BN_CTX_free(ctx); + return ret; +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_crpt.c b/contrib/libs/openssl/crypto/rsa/rsa_crpt.c index f1131ce9e0..ef0b347b22 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_crpt.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_crpt.c @@ -1,169 +1,169 @@ -/* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdio.h> -#include <openssl/crypto.h> -#include "internal/cryptlib.h" +/* + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include <openssl/crypto.h> +#include "internal/cryptlib.h" #include "crypto/bn.h" -#include <openssl/rand.h> +#include <openssl/rand.h> #include "rsa_local.h" - -int RSA_bits(const RSA *r) -{ - return BN_num_bits(r->n); -} - -int RSA_size(const RSA *r) -{ - return BN_num_bytes(r->n); -} - -int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, - RSA *rsa, int padding) -{ - return rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding); -} - -int RSA_private_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - return rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding); -} - -int RSA_private_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - return rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding); -} - -int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, - RSA *rsa, int padding) -{ - return rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding); -} - -int RSA_flags(const RSA *r) -{ - return r == NULL ? 0 : r->meth->flags; -} - -void RSA_blinding_off(RSA *rsa) -{ - BN_BLINDING_free(rsa->blinding); - rsa->blinding = NULL; - rsa->flags &= ~RSA_FLAG_BLINDING; - rsa->flags |= RSA_FLAG_NO_BLINDING; -} - -int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) -{ - int ret = 0; - - if (rsa->blinding != NULL) - RSA_blinding_off(rsa); - - rsa->blinding = RSA_setup_blinding(rsa, ctx); - if (rsa->blinding == NULL) - goto err; - - rsa->flags |= RSA_FLAG_BLINDING; - rsa->flags &= ~RSA_FLAG_NO_BLINDING; - ret = 1; - err: - return ret; -} - -static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p, - const BIGNUM *q, BN_CTX *ctx) -{ - BIGNUM *ret = NULL, *r0, *r1, *r2; - - if (d == NULL || p == NULL || q == NULL) - return NULL; - - BN_CTX_start(ctx); - r0 = BN_CTX_get(ctx); - r1 = BN_CTX_get(ctx); - r2 = BN_CTX_get(ctx); - if (r2 == NULL) - goto err; - - if (!BN_sub(r1, p, BN_value_one())) - goto err; - if (!BN_sub(r2, q, BN_value_one())) - goto err; - if (!BN_mul(r0, r1, r2, ctx)) - goto err; - - ret = BN_mod_inverse(NULL, d, r0, ctx); - err: - BN_CTX_end(ctx); - return ret; -} - -BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) -{ - BIGNUM *e; - BN_CTX *ctx; - BN_BLINDING *ret = NULL; - - if (in_ctx == NULL) { - if ((ctx = BN_CTX_new()) == NULL) - return 0; - } else { - ctx = in_ctx; - } - - BN_CTX_start(ctx); - e = BN_CTX_get(ctx); - if (e == NULL) { - RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (rsa->e == NULL) { - e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); - if (e == NULL) { - RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); - goto err; - } - } else { - e = rsa->e; - } - - { - BIGNUM *n = BN_new(); - - if (n == NULL) { - RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); - goto err; - } - BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); - - ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp, - rsa->_method_mod_n); - /* We MUST free n before any further use of rsa->n */ - BN_free(n); - } - if (ret == NULL) { - RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); - goto err; - } - - BN_BLINDING_set_current_thread(ret); - - err: - BN_CTX_end(ctx); - if (ctx != in_ctx) - BN_CTX_free(ctx); - if (e != rsa->e) - BN_free(e); - - return ret; -} + +int RSA_bits(const RSA *r) +{ + return BN_num_bits(r->n); +} + +int RSA_size(const RSA *r) +{ + return BN_num_bytes(r->n); +} + +int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ + return rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding); +} + +int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + return rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding); +} + +int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + return rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding); +} + +int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ + return rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding); +} + +int RSA_flags(const RSA *r) +{ + return r == NULL ? 0 : r->meth->flags; +} + +void RSA_blinding_off(RSA *rsa) +{ + BN_BLINDING_free(rsa->blinding); + rsa->blinding = NULL; + rsa->flags &= ~RSA_FLAG_BLINDING; + rsa->flags |= RSA_FLAG_NO_BLINDING; +} + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) +{ + int ret = 0; + + if (rsa->blinding != NULL) + RSA_blinding_off(rsa); + + rsa->blinding = RSA_setup_blinding(rsa, ctx); + if (rsa->blinding == NULL) + goto err; + + rsa->flags |= RSA_FLAG_BLINDING; + rsa->flags &= ~RSA_FLAG_NO_BLINDING; + ret = 1; + err: + return ret; +} + +static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p, + const BIGNUM *q, BN_CTX *ctx) +{ + BIGNUM *ret = NULL, *r0, *r1, *r2; + + if (d == NULL || p == NULL || q == NULL) + return NULL; + + BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + if (r2 == NULL) + goto err; + + if (!BN_sub(r1, p, BN_value_one())) + goto err; + if (!BN_sub(r2, q, BN_value_one())) + goto err; + if (!BN_mul(r0, r1, r2, ctx)) + goto err; + + ret = BN_mod_inverse(NULL, d, r0, ctx); + err: + BN_CTX_end(ctx); + return ret; +} + +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) +{ + BIGNUM *e; + BN_CTX *ctx; + BN_BLINDING *ret = NULL; + + if (in_ctx == NULL) { + if ((ctx = BN_CTX_new()) == NULL) + return 0; + } else { + ctx = in_ctx; + } + + BN_CTX_start(ctx); + e = BN_CTX_get(ctx); + if (e == NULL) { + RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (rsa->e == NULL) { + e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); + if (e == NULL) { + RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); + goto err; + } + } else { + e = rsa->e; + } + + { + BIGNUM *n = BN_new(); + + if (n == NULL) { + RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); + goto err; + } + BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); + + ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp, + rsa->_method_mod_n); + /* We MUST free n before any further use of rsa->n */ + BN_free(n); + } + if (ret == NULL) { + RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); + goto err; + } + + BN_BLINDING_set_current_thread(ret); + + err: + BN_CTX_end(ctx); + if (ctx != in_ctx) + BN_CTX_free(ctx); + if (e != rsa->e) + BN_free(e); + + return ret; +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_depr.c b/contrib/libs/openssl/crypto/rsa/rsa_depr.c index 21e0562525..91e0445559 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_depr.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_depr.c @@ -1,61 +1,61 @@ -/* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * NB: This file contains deprecated functions (compatibility wrappers to the - * "new" versions). - */ - -#include <openssl/opensslconf.h> -#if OPENSSL_API_COMPAT >= 0x00908000L -NON_EMPTY_TRANSLATION_UNIT - -#else - -# include <stdio.h> -# include <time.h> -# include "internal/cryptlib.h" -# include <openssl/bn.h> -# include <openssl/rsa.h> - -RSA *RSA_generate_key(int bits, unsigned long e_value, - void (*callback) (int, int, void *), void *cb_arg) -{ - int i; - BN_GENCB *cb = BN_GENCB_new(); - RSA *rsa = RSA_new(); - BIGNUM *e = BN_new(); - - if (cb == NULL || rsa == NULL || e == NULL) - goto err; - - /* - * The problem is when building with 8, 16, or 32 BN_ULONG, unsigned long - * can be larger - */ - for (i = 0; i < (int)sizeof(unsigned long) * 8; i++) { - if (e_value & (1UL << i)) - if (BN_set_bit(e, i) == 0) - goto err; - } - - BN_GENCB_set_old(cb, callback, cb_arg); - - if (RSA_generate_key_ex(rsa, bits, e, cb)) { - BN_free(e); - BN_GENCB_free(cb); - return rsa; - } - err: - BN_free(e); - RSA_free(rsa); - BN_GENCB_free(cb); - return 0; -} -#endif +/* + * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * NB: This file contains deprecated functions (compatibility wrappers to the + * "new" versions). + */ + +#include <openssl/opensslconf.h> +#if OPENSSL_API_COMPAT >= 0x00908000L +NON_EMPTY_TRANSLATION_UNIT + +#else + +# include <stdio.h> +# include <time.h> +# include "internal/cryptlib.h" +# include <openssl/bn.h> +# include <openssl/rsa.h> + +RSA *RSA_generate_key(int bits, unsigned long e_value, + void (*callback) (int, int, void *), void *cb_arg) +{ + int i; + BN_GENCB *cb = BN_GENCB_new(); + RSA *rsa = RSA_new(); + BIGNUM *e = BN_new(); + + if (cb == NULL || rsa == NULL || e == NULL) + goto err; + + /* + * The problem is when building with 8, 16, or 32 BN_ULONG, unsigned long + * can be larger + */ + for (i = 0; i < (int)sizeof(unsigned long) * 8; i++) { + if (e_value & (1UL << i)) + if (BN_set_bit(e, i) == 0) + goto err; + } + + BN_GENCB_set_old(cb, callback, cb_arg); + + if (RSA_generate_key_ex(rsa, bits, e, cb)) { + BN_free(e); + BN_GENCB_free(cb); + return rsa; + } + err: + BN_free(e); + RSA_free(rsa); + BN_GENCB_free(cb); + return 0; +} +#endif diff --git a/contrib/libs/openssl/crypto/rsa/rsa_err.c b/contrib/libs/openssl/crypto/rsa/rsa_err.c index 0687c1e626..534f7365f1 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_err.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_err.c @@ -1,248 +1,248 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT +/* + * Generated by util/mkerr.pl DO NOT EDIT * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <openssl/err.h> -#include <openssl/rsaerr.h> - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA RSA_str_functs[] = { - {ERR_PACK(ERR_LIB_RSA, RSA_F_CHECK_PADDING_MD, 0), "check_padding_md"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_ENCODE_PKCS1, 0), "encode_pkcs1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_INT_RSA_VERIFY, 0), "int_rsa_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_OLD_RSA_PRIV_DECODE, 0), - "old_rsa_priv_decode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_PSS_INIT, 0), "pkey_pss_init"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, 0), "pkey_rsa_ctrl"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL_STR, 0), "pkey_rsa_ctrl_str"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_SIGN, 0), "pkey_rsa_sign"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_VERIFY, 0), "pkey_rsa_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_VERIFYRECOVER, 0), - "pkey_rsa_verifyrecover"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_ALGOR_TO_MD, 0), "rsa_algor_to_md"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_BUILTIN_KEYGEN, 0), "rsa_builtin_keygen"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CHECK_KEY, 0), "RSA_check_key"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CHECK_KEY_EX, 0), "RSA_check_key_ex"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_DECRYPT, 0), "rsa_cms_decrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_VERIFY, 0), "rsa_cms_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_ITEM_VERIFY, 0), "rsa_item_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_DUP, 0), "RSA_meth_dup"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_NEW, 0), "RSA_meth_new"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_SET1_NAME, 0), "RSA_meth_set1_name"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_MGF1_TO_MD, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_MULTIP_INFO_NEW, 0), - "rsa_multip_info_new"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NEW_METHOD, 0), "RSA_new_method"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_DECRYPT, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_ENCRYPT, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PUBLIC_DECRYPT, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PUBLIC_ENCRYPT, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, 0), - "rsa_ossl_private_decrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, 0), - "rsa_ossl_private_encrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, 0), - "rsa_ossl_public_decrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, 0), - "rsa_ossl_public_encrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_NONE, 0), - "RSA_padding_add_none"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, 0), - "RSA_padding_add_PKCS1_OAEP"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, 0), - "RSA_padding_add_PKCS1_OAEP_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_PSS, 0), - "RSA_padding_add_PKCS1_PSS"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, 0), - "RSA_padding_add_PKCS1_PSS_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1, 0), - "RSA_padding_add_PKCS1_type_1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2, 0), - "RSA_padding_add_PKCS1_type_2"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_SSLV23, 0), - "RSA_padding_add_SSLv23"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_X931, 0), - "RSA_padding_add_X931"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_NONE, 0), - "RSA_padding_check_none"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, 0), - "RSA_padding_check_PKCS1_OAEP"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, 0), - "RSA_padding_check_PKCS1_OAEP_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, 0), - "RSA_padding_check_PKCS1_type_1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, 0), - "RSA_padding_check_PKCS1_type_2"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_SSLV23, 0), - "RSA_padding_check_SSLv23"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_X931, 0), - "RSA_padding_check_X931"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PARAM_DECODE, 0), "rsa_param_decode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT, 0), "RSA_print"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT_FP, 0), "RSA_print_fp"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_DECODE, 0), "rsa_priv_decode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_ENCODE, 0), "rsa_priv_encode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_GET_PARAM, 0), "rsa_pss_get_param"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_TO_CTX, 0), "rsa_pss_to_ctx"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUB_DECODE, 0), "rsa_pub_decode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SETUP_BLINDING, 0), "RSA_setup_blinding"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN, 0), "RSA_sign"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN_ASN1_OCTET_STRING, 0), - "RSA_sign_ASN1_OCTET_STRING"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY, 0), "RSA_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, 0), - "RSA_verify_ASN1_OCTET_STRING"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, 0), - "RSA_verify_PKCS1_PSS_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_SETUP_TBUF, 0), "setup_tbuf"}, - {0, NULL} -}; - -static const ERR_STRING_DATA RSA_str_reasons[] = { - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_ALGORITHM_MISMATCH), "algorithm mismatch"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_E_VALUE), "bad e value"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_FIXED_HEADER_DECRYPT), - "bad fixed header decrypt"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_PAD_BYTE_COUNT), "bad pad byte count"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_SIGNATURE), "bad signature"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BLOCK_TYPE_IS_NOT_01), - "block type is not 01"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BLOCK_TYPE_IS_NOT_02), - "block type is not 02"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_GREATER_THAN_MOD_LEN), - "data greater than mod len"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_LARGE), "data too large"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), - "data too large for key size"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_LARGE_FOR_MODULUS), - "data too large for modulus"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_SMALL), "data too small"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE), - "data too small for key size"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DIGEST_DOES_NOT_MATCH), - "digest does not match"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DIGEST_NOT_ALLOWED), "digest not allowed"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY), - "digest too big for rsa key"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DMP1_NOT_CONGRUENT_TO_D), - "dmp1 not congruent to d"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DMQ1_NOT_CONGRUENT_TO_D), - "dmq1 not congruent to d"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_D_E_NOT_CONGRUENT_TO_1), - "d e not congruent to 1"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_FIRST_OCTET_INVALID), - "first octet invalid"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), - "illegal or unsupported padding mode"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_DIGEST), "invalid digest"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_DIGEST_LENGTH), - "invalid digest length"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_HEADER), "invalid header"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_LABEL), "invalid label"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MESSAGE_LENGTH), - "invalid message length"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MGF1_MD), "invalid mgf1 md"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MULTI_PRIME_KEY), - "invalid multi prime key"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_OAEP_PARAMETERS), - "invalid oaep parameters"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PADDING), "invalid padding"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PADDING_MODE), - "invalid padding mode"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PSS_PARAMETERS), - "invalid pss parameters"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PSS_SALTLEN), - "invalid pss saltlen"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_SALT_LENGTH), - "invalid salt length"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_TRAILER), "invalid trailer"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_X931_DIGEST), - "invalid x931 digest"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_IQMP_NOT_INVERSE_OF_Q), - "iqmp not inverse of q"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_KEY_PRIME_NUM_INVALID), - "key prime num invalid"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_KEY_SIZE_TOO_SMALL), "key size too small"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_LAST_OCTET_INVALID), "last octet invalid"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MGF1_DIGEST_NOT_ALLOWED), - "mgf1 digest not allowed"}, + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/err.h> +#include <openssl/rsaerr.h> + +#ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA RSA_str_functs[] = { + {ERR_PACK(ERR_LIB_RSA, RSA_F_CHECK_PADDING_MD, 0), "check_padding_md"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_ENCODE_PKCS1, 0), "encode_pkcs1"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_INT_RSA_VERIFY, 0), "int_rsa_verify"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_OLD_RSA_PRIV_DECODE, 0), + "old_rsa_priv_decode"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_PSS_INIT, 0), "pkey_pss_init"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, 0), "pkey_rsa_ctrl"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL_STR, 0), "pkey_rsa_ctrl_str"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_SIGN, 0), "pkey_rsa_sign"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_VERIFY, 0), "pkey_rsa_verify"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_VERIFYRECOVER, 0), + "pkey_rsa_verifyrecover"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_ALGOR_TO_MD, 0), "rsa_algor_to_md"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_BUILTIN_KEYGEN, 0), "rsa_builtin_keygen"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CHECK_KEY, 0), "RSA_check_key"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CHECK_KEY_EX, 0), "RSA_check_key_ex"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_DECRYPT, 0), "rsa_cms_decrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_VERIFY, 0), "rsa_cms_verify"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_ITEM_VERIFY, 0), "rsa_item_verify"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_DUP, 0), "RSA_meth_dup"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_NEW, 0), "RSA_meth_new"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_SET1_NAME, 0), "RSA_meth_set1_name"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_MGF1_TO_MD, 0), ""}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_MULTIP_INFO_NEW, 0), + "rsa_multip_info_new"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NEW_METHOD, 0), "RSA_new_method"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL, 0), ""}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_DECRYPT, 0), ""}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_ENCRYPT, 0), ""}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PUBLIC_DECRYPT, 0), ""}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PUBLIC_ENCRYPT, 0), ""}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, 0), + "rsa_ossl_private_decrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, 0), + "rsa_ossl_private_encrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, 0), + "rsa_ossl_public_decrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, 0), + "rsa_ossl_public_encrypt"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_NONE, 0), + "RSA_padding_add_none"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, 0), + "RSA_padding_add_PKCS1_OAEP"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, 0), + "RSA_padding_add_PKCS1_OAEP_mgf1"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_PSS, 0), + "RSA_padding_add_PKCS1_PSS"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, 0), + "RSA_padding_add_PKCS1_PSS_mgf1"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1, 0), + "RSA_padding_add_PKCS1_type_1"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2, 0), + "RSA_padding_add_PKCS1_type_2"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_SSLV23, 0), + "RSA_padding_add_SSLv23"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_X931, 0), + "RSA_padding_add_X931"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_NONE, 0), + "RSA_padding_check_none"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, 0), + "RSA_padding_check_PKCS1_OAEP"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, 0), + "RSA_padding_check_PKCS1_OAEP_mgf1"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, 0), + "RSA_padding_check_PKCS1_type_1"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, 0), + "RSA_padding_check_PKCS1_type_2"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_SSLV23, 0), + "RSA_padding_check_SSLv23"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_X931, 0), + "RSA_padding_check_X931"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PARAM_DECODE, 0), "rsa_param_decode"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT, 0), "RSA_print"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT_FP, 0), "RSA_print_fp"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_DECODE, 0), "rsa_priv_decode"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_ENCODE, 0), "rsa_priv_encode"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_GET_PARAM, 0), "rsa_pss_get_param"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_TO_CTX, 0), "rsa_pss_to_ctx"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUB_DECODE, 0), "rsa_pub_decode"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SETUP_BLINDING, 0), "RSA_setup_blinding"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN, 0), "RSA_sign"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN_ASN1_OCTET_STRING, 0), + "RSA_sign_ASN1_OCTET_STRING"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY, 0), "RSA_verify"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, 0), + "RSA_verify_ASN1_OCTET_STRING"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, 0), + "RSA_verify_PKCS1_PSS_mgf1"}, + {ERR_PACK(ERR_LIB_RSA, RSA_F_SETUP_TBUF, 0), "setup_tbuf"}, + {0, NULL} +}; + +static const ERR_STRING_DATA RSA_str_reasons[] = { + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_ALGORITHM_MISMATCH), "algorithm mismatch"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_E_VALUE), "bad e value"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_FIXED_HEADER_DECRYPT), + "bad fixed header decrypt"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_PAD_BYTE_COUNT), "bad pad byte count"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_SIGNATURE), "bad signature"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BLOCK_TYPE_IS_NOT_01), + "block type is not 01"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BLOCK_TYPE_IS_NOT_02), + "block type is not 02"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_GREATER_THAN_MOD_LEN), + "data greater than mod len"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_LARGE), "data too large"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), + "data too large for key size"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_LARGE_FOR_MODULUS), + "data too large for modulus"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_SMALL), "data too small"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE), + "data too small for key size"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DIGEST_DOES_NOT_MATCH), + "digest does not match"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DIGEST_NOT_ALLOWED), "digest not allowed"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY), + "digest too big for rsa key"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DMP1_NOT_CONGRUENT_TO_D), + "dmp1 not congruent to d"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DMQ1_NOT_CONGRUENT_TO_D), + "dmq1 not congruent to d"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_D_E_NOT_CONGRUENT_TO_1), + "d e not congruent to 1"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_FIRST_OCTET_INVALID), + "first octet invalid"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), + "illegal or unsupported padding mode"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_DIGEST), "invalid digest"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_DIGEST_LENGTH), + "invalid digest length"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_HEADER), "invalid header"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_LABEL), "invalid label"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MESSAGE_LENGTH), + "invalid message length"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MGF1_MD), "invalid mgf1 md"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MULTI_PRIME_KEY), + "invalid multi prime key"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_OAEP_PARAMETERS), + "invalid oaep parameters"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PADDING), "invalid padding"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PADDING_MODE), + "invalid padding mode"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PSS_PARAMETERS), + "invalid pss parameters"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PSS_SALTLEN), + "invalid pss saltlen"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_SALT_LENGTH), + "invalid salt length"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_TRAILER), "invalid trailer"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_X931_DIGEST), + "invalid x931 digest"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_IQMP_NOT_INVERSE_OF_Q), + "iqmp not inverse of q"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_KEY_PRIME_NUM_INVALID), + "key prime num invalid"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_KEY_SIZE_TOO_SMALL), "key size too small"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_LAST_OCTET_INVALID), "last octet invalid"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MGF1_DIGEST_NOT_ALLOWED), + "mgf1 digest not allowed"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MISSING_PRIVATE_KEY), "missing private key"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MODULUS_TOO_LARGE), "modulus too large"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R), - "mp coefficient not inverse of r"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D), - "mp exponent not congruent to d"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_R_NOT_PRIME), "mp r not prime"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NO_PUBLIC_EXPONENT), "no public exponent"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NULL_BEFORE_BLOCK_MISSING), - "null before block missing"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES), - "n does not equal product of primes"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_N_DOES_NOT_EQUAL_P_Q), - "n does not equal p q"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OAEP_DECODING_ERROR), - "oaep decoding error"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), - "operation not supported for this keytype"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PADDING_CHECK_FAILED), - "padding check failed"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PKCS_DECODING_ERROR), - "pkcs decoding error"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PSS_SALTLEN_TOO_SMALL), - "pss saltlen too small"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_P_NOT_PRIME), "p not prime"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_Q_NOT_PRIME), "q not prime"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED), - "rsa operations not supported"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_SLEN_CHECK_FAILED), - "salt length check failed"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_SLEN_RECOVERY_FAILED), - "salt length recovery failed"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_SSLV3_ROLLBACK_ATTACK), - "sslv3 rollback attack"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), - "the asn1 object identifier is not known for this md"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNKNOWN_ALGORITHM_TYPE), - "unknown algorithm type"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNKNOWN_DIGEST), "unknown digest"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNKNOWN_MASK_DIGEST), - "unknown mask digest"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNKNOWN_PADDING_TYPE), - "unknown padding type"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE), - "unsupported encryption type"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_LABEL_SOURCE), - "unsupported label source"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_MASK_ALGORITHM), - "unsupported mask algorithm"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_MASK_PARAMETER), - "unsupported mask parameter"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_SIGNATURE_TYPE), - "unsupported signature type"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_VALUE_MISSING), "value missing"}, - {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_WRONG_SIGNATURE_LENGTH), - "wrong signature length"}, - {0, NULL} -}; - -#endif - -int ERR_load_RSA_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(RSA_str_functs[0].error) == NULL) { - ERR_load_strings_const(RSA_str_functs); - ERR_load_strings_const(RSA_str_reasons); - } -#endif - return 1; -} + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R), + "mp coefficient not inverse of r"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D), + "mp exponent not congruent to d"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_R_NOT_PRIME), "mp r not prime"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NO_PUBLIC_EXPONENT), "no public exponent"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NULL_BEFORE_BLOCK_MISSING), + "null before block missing"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES), + "n does not equal product of primes"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_N_DOES_NOT_EQUAL_P_Q), + "n does not equal p q"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OAEP_DECODING_ERROR), + "oaep decoding error"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), + "operation not supported for this keytype"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PADDING_CHECK_FAILED), + "padding check failed"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PKCS_DECODING_ERROR), + "pkcs decoding error"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PSS_SALTLEN_TOO_SMALL), + "pss saltlen too small"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_P_NOT_PRIME), "p not prime"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_Q_NOT_PRIME), "q not prime"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED), + "rsa operations not supported"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_SLEN_CHECK_FAILED), + "salt length check failed"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_SLEN_RECOVERY_FAILED), + "salt length recovery failed"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_SSLV3_ROLLBACK_ATTACK), + "sslv3 rollback attack"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), + "the asn1 object identifier is not known for this md"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNKNOWN_ALGORITHM_TYPE), + "unknown algorithm type"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNKNOWN_DIGEST), "unknown digest"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNKNOWN_MASK_DIGEST), + "unknown mask digest"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNKNOWN_PADDING_TYPE), + "unknown padding type"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE), + "unsupported encryption type"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_LABEL_SOURCE), + "unsupported label source"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_MASK_ALGORITHM), + "unsupported mask algorithm"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_MASK_PARAMETER), + "unsupported mask parameter"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_SIGNATURE_TYPE), + "unsupported signature type"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_VALUE_MISSING), "value missing"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_WRONG_SIGNATURE_LENGTH), + "wrong signature length"}, + {0, NULL} +}; + +#endif + +int ERR_load_RSA_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(RSA_str_functs[0].error) == NULL) { + ERR_load_strings_const(RSA_str_functs); + ERR_load_strings_const(RSA_str_reasons); + } +#endif + return 1; +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_gen.c b/contrib/libs/openssl/crypto/rsa/rsa_gen.c index 29056a62a1..139d96c70c 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_gen.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_gen.c @@ -1,393 +1,393 @@ -/* +/* * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * NB: these functions have been "upgraded", the deprecated versions (which - * are compatibility wrappers using these functions) are in rsa_depr.c. - - * Geoff - */ - -#include <stdio.h> -#include <time.h> -#include "internal/cryptlib.h" -#include <openssl/bn.h> + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * NB: these functions have been "upgraded", the deprecated versions (which + * are compatibility wrappers using these functions) are in rsa_depr.c. - + * Geoff + */ + +#include <stdio.h> +#include <time.h> +#include "internal/cryptlib.h" +#include <openssl/bn.h> #include "rsa_local.h" - -static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, - BN_GENCB *cb); - -/* - * NB: this wrapper would normally be placed in rsa_lib.c and the static - * implementation would probably be in rsa_eay.c. Nonetheless, is kept here - * so that we don't introduce a new linker dependency. Eg. any application - * that wasn't previously linking object code related to key-generation won't - * have to now just because key-generation is part of RSA_METHOD. - */ -int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) -{ - if (rsa->meth->rsa_keygen != NULL) - return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); - - return RSA_generate_multi_prime_key(rsa, bits, RSA_DEFAULT_PRIME_NUM, - e_value, cb); -} - -int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, - BIGNUM *e_value, BN_GENCB *cb) -{ - /* multi-prime is only supported with the builtin key generation */ - if (rsa->meth->rsa_multi_prime_keygen != NULL) { - return rsa->meth->rsa_multi_prime_keygen(rsa, bits, primes, - e_value, cb); - } else if (rsa->meth->rsa_keygen != NULL) { - /* - * However, if rsa->meth implements only rsa_keygen, then we - * have to honour it in 2-prime case and assume that it wouldn't - * know what to do with multi-prime key generated by builtin - * subroutine... - */ - if (primes == 2) - return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); - else - return 0; - } - - return rsa_builtin_keygen(rsa, bits, primes, e_value, cb); -} - -static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, - BN_GENCB *cb) -{ - BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *tmp, *prime; - int ok = -1, n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0; - int i = 0, quo = 0, rmd = 0, adj = 0, retries = 0; - RSA_PRIME_INFO *pinfo = NULL; - STACK_OF(RSA_PRIME_INFO) *prime_infos = NULL; - BN_CTX *ctx = NULL; - BN_ULONG bitst = 0; - unsigned long error = 0; - - if (bits < RSA_MIN_MODULUS_BITS) { - ok = 0; /* we set our own err */ - RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); - goto err; - } - - if (primes < RSA_DEFAULT_PRIME_NUM || primes > rsa_multip_cap(bits)) { - ok = 0; /* we set our own err */ - RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_PRIME_NUM_INVALID); - goto err; - } - - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - BN_CTX_start(ctx); - r0 = BN_CTX_get(ctx); - r1 = BN_CTX_get(ctx); - r2 = BN_CTX_get(ctx); - if (r2 == NULL) - goto err; - - /* divide bits into 'primes' pieces evenly */ - quo = bits / primes; - rmd = bits % primes; - - for (i = 0; i < primes; i++) - bitsr[i] = (i < rmd) ? quo + 1 : quo; - - /* We need the RSA components non-NULL */ - if (!rsa->n && ((rsa->n = BN_new()) == NULL)) - goto err; - if (!rsa->d && ((rsa->d = BN_secure_new()) == NULL)) - goto err; - if (!rsa->e && ((rsa->e = BN_new()) == NULL)) - goto err; - if (!rsa->p && ((rsa->p = BN_secure_new()) == NULL)) - goto err; - if (!rsa->q && ((rsa->q = BN_secure_new()) == NULL)) - goto err; - if (!rsa->dmp1 && ((rsa->dmp1 = BN_secure_new()) == NULL)) - goto err; - if (!rsa->dmq1 && ((rsa->dmq1 = BN_secure_new()) == NULL)) - goto err; - if (!rsa->iqmp && ((rsa->iqmp = BN_secure_new()) == NULL)) - goto err; - - /* initialize multi-prime components */ - if (primes > RSA_DEFAULT_PRIME_NUM) { - rsa->version = RSA_ASN1_VERSION_MULTI; - prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, primes - 2); - if (prime_infos == NULL) - goto err; - if (rsa->prime_infos != NULL) { - /* could this happen? */ - sk_RSA_PRIME_INFO_pop_free(rsa->prime_infos, rsa_multip_info_free); - } - rsa->prime_infos = prime_infos; - - /* prime_info from 2 to |primes| -1 */ - for (i = 2; i < primes; i++) { - pinfo = rsa_multip_info_new(); - if (pinfo == NULL) - goto err; - (void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo); - } - } - - if (BN_copy(rsa->e, e_value) == NULL) - goto err; - - /* generate p, q and other primes (if any) */ - for (i = 0; i < primes; i++) { - adj = 0; - retries = 0; - - if (i == 0) { - prime = rsa->p; - } else if (i == 1) { - prime = rsa->q; - } else { - pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2); - prime = pinfo->r; - } - BN_set_flags(prime, BN_FLG_CONSTTIME); - - for (;;) { - redo: - if (!BN_generate_prime_ex(prime, bitsr[i] + adj, 0, NULL, NULL, cb)) - goto err; - /* - * prime should not be equal to p, q, r_3... - * (those primes prior to this one) - */ - { - int j; - - for (j = 0; j < i; j++) { - BIGNUM *prev_prime; - - if (j == 0) - prev_prime = rsa->p; - else if (j == 1) - prev_prime = rsa->q; - else - prev_prime = sk_RSA_PRIME_INFO_value(prime_infos, - j - 2)->r; - - if (!BN_cmp(prime, prev_prime)) { - goto redo; - } - } - } - if (!BN_sub(r2, prime, BN_value_one())) - goto err; - ERR_set_mark(); - BN_set_flags(r2, BN_FLG_CONSTTIME); - if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) { - /* GCD == 1 since inverse exists */ - break; - } - error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) == ERR_LIB_BN - && ERR_GET_REASON(error) == BN_R_NO_INVERSE) { - /* GCD != 1 */ - ERR_pop_to_mark(); - } else { - goto err; - } - if (!BN_GENCB_call(cb, 2, n++)) - goto err; - } - - bitse += bitsr[i]; - - /* calculate n immediately to see if it's sufficient */ - if (i == 1) { - /* we get at least 2 primes */ - if (!BN_mul(r1, rsa->p, rsa->q, ctx)) - goto err; - } else if (i != 0) { - /* modulus n = p * q * r_3 * r_4 ... */ - if (!BN_mul(r1, rsa->n, prime, ctx)) - goto err; - } else { - /* i == 0, do nothing */ - if (!BN_GENCB_call(cb, 3, i)) - goto err; - continue; - } - /* - * if |r1|, product of factors so far, is not as long as expected - * (by checking the first 4 bits are less than 0x9 or greater than - * 0xF). If so, re-generate the last prime. - * - * NOTE: This actually can't happen in two-prime case, because of - * the way factors are generated. - * - * Besides, another consideration is, for multi-prime case, even the - * length modulus is as long as expected, the modulus could start at - * 0x8, which could be utilized to distinguish a multi-prime private - * key by using the modulus in a certificate. This is also covered - * by checking the length should not be less than 0x9. - */ - if (!BN_rshift(r2, r1, bitse - 4)) - goto err; - bitst = BN_get_word(r2); - - if (bitst < 0x9 || bitst > 0xF) { - /* - * For keys with more than 4 primes, we attempt longer factor to - * meet length requirement. - * - * Otherwise, we just re-generate the prime with the same length. - * - * This strategy has the following goals: - * + +static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, + BN_GENCB *cb); + +/* + * NB: this wrapper would normally be placed in rsa_lib.c and the static + * implementation would probably be in rsa_eay.c. Nonetheless, is kept here + * so that we don't introduce a new linker dependency. Eg. any application + * that wasn't previously linking object code related to key-generation won't + * have to now just because key-generation is part of RSA_METHOD. + */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) +{ + if (rsa->meth->rsa_keygen != NULL) + return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); + + return RSA_generate_multi_prime_key(rsa, bits, RSA_DEFAULT_PRIME_NUM, + e_value, cb); +} + +int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, + BIGNUM *e_value, BN_GENCB *cb) +{ + /* multi-prime is only supported with the builtin key generation */ + if (rsa->meth->rsa_multi_prime_keygen != NULL) { + return rsa->meth->rsa_multi_prime_keygen(rsa, bits, primes, + e_value, cb); + } else if (rsa->meth->rsa_keygen != NULL) { + /* + * However, if rsa->meth implements only rsa_keygen, then we + * have to honour it in 2-prime case and assume that it wouldn't + * know what to do with multi-prime key generated by builtin + * subroutine... + */ + if (primes == 2) + return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); + else + return 0; + } + + return rsa_builtin_keygen(rsa, bits, primes, e_value, cb); +} + +static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, + BN_GENCB *cb) +{ + BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *tmp, *prime; + int ok = -1, n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0; + int i = 0, quo = 0, rmd = 0, adj = 0, retries = 0; + RSA_PRIME_INFO *pinfo = NULL; + STACK_OF(RSA_PRIME_INFO) *prime_infos = NULL; + BN_CTX *ctx = NULL; + BN_ULONG bitst = 0; + unsigned long error = 0; + + if (bits < RSA_MIN_MODULUS_BITS) { + ok = 0; /* we set our own err */ + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } + + if (primes < RSA_DEFAULT_PRIME_NUM || primes > rsa_multip_cap(bits)) { + ok = 0; /* we set our own err */ + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_PRIME_NUM_INVALID); + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + if (r2 == NULL) + goto err; + + /* divide bits into 'primes' pieces evenly */ + quo = bits / primes; + rmd = bits % primes; + + for (i = 0; i < primes; i++) + bitsr[i] = (i < rmd) ? quo + 1 : quo; + + /* We need the RSA components non-NULL */ + if (!rsa->n && ((rsa->n = BN_new()) == NULL)) + goto err; + if (!rsa->d && ((rsa->d = BN_secure_new()) == NULL)) + goto err; + if (!rsa->e && ((rsa->e = BN_new()) == NULL)) + goto err; + if (!rsa->p && ((rsa->p = BN_secure_new()) == NULL)) + goto err; + if (!rsa->q && ((rsa->q = BN_secure_new()) == NULL)) + goto err; + if (!rsa->dmp1 && ((rsa->dmp1 = BN_secure_new()) == NULL)) + goto err; + if (!rsa->dmq1 && ((rsa->dmq1 = BN_secure_new()) == NULL)) + goto err; + if (!rsa->iqmp && ((rsa->iqmp = BN_secure_new()) == NULL)) + goto err; + + /* initialize multi-prime components */ + if (primes > RSA_DEFAULT_PRIME_NUM) { + rsa->version = RSA_ASN1_VERSION_MULTI; + prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, primes - 2); + if (prime_infos == NULL) + goto err; + if (rsa->prime_infos != NULL) { + /* could this happen? */ + sk_RSA_PRIME_INFO_pop_free(rsa->prime_infos, rsa_multip_info_free); + } + rsa->prime_infos = prime_infos; + + /* prime_info from 2 to |primes| -1 */ + for (i = 2; i < primes; i++) { + pinfo = rsa_multip_info_new(); + if (pinfo == NULL) + goto err; + (void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo); + } + } + + if (BN_copy(rsa->e, e_value) == NULL) + goto err; + + /* generate p, q and other primes (if any) */ + for (i = 0; i < primes; i++) { + adj = 0; + retries = 0; + + if (i == 0) { + prime = rsa->p; + } else if (i == 1) { + prime = rsa->q; + } else { + pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2); + prime = pinfo->r; + } + BN_set_flags(prime, BN_FLG_CONSTTIME); + + for (;;) { + redo: + if (!BN_generate_prime_ex(prime, bitsr[i] + adj, 0, NULL, NULL, cb)) + goto err; + /* + * prime should not be equal to p, q, r_3... + * (those primes prior to this one) + */ + { + int j; + + for (j = 0; j < i; j++) { + BIGNUM *prev_prime; + + if (j == 0) + prev_prime = rsa->p; + else if (j == 1) + prev_prime = rsa->q; + else + prev_prime = sk_RSA_PRIME_INFO_value(prime_infos, + j - 2)->r; + + if (!BN_cmp(prime, prev_prime)) { + goto redo; + } + } + } + if (!BN_sub(r2, prime, BN_value_one())) + goto err; + ERR_set_mark(); + BN_set_flags(r2, BN_FLG_CONSTTIME); + if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) { + /* GCD == 1 since inverse exists */ + break; + } + error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) == ERR_LIB_BN + && ERR_GET_REASON(error) == BN_R_NO_INVERSE) { + /* GCD != 1 */ + ERR_pop_to_mark(); + } else { + goto err; + } + if (!BN_GENCB_call(cb, 2, n++)) + goto err; + } + + bitse += bitsr[i]; + + /* calculate n immediately to see if it's sufficient */ + if (i == 1) { + /* we get at least 2 primes */ + if (!BN_mul(r1, rsa->p, rsa->q, ctx)) + goto err; + } else if (i != 0) { + /* modulus n = p * q * r_3 * r_4 ... */ + if (!BN_mul(r1, rsa->n, prime, ctx)) + goto err; + } else { + /* i == 0, do nothing */ + if (!BN_GENCB_call(cb, 3, i)) + goto err; + continue; + } + /* + * if |r1|, product of factors so far, is not as long as expected + * (by checking the first 4 bits are less than 0x9 or greater than + * 0xF). If so, re-generate the last prime. + * + * NOTE: This actually can't happen in two-prime case, because of + * the way factors are generated. + * + * Besides, another consideration is, for multi-prime case, even the + * length modulus is as long as expected, the modulus could start at + * 0x8, which could be utilized to distinguish a multi-prime private + * key by using the modulus in a certificate. This is also covered + * by checking the length should not be less than 0x9. + */ + if (!BN_rshift(r2, r1, bitse - 4)) + goto err; + bitst = BN_get_word(r2); + + if (bitst < 0x9 || bitst > 0xF) { + /* + * For keys with more than 4 primes, we attempt longer factor to + * meet length requirement. + * + * Otherwise, we just re-generate the prime with the same length. + * + * This strategy has the following goals: + * * 1. 1024-bit factors are efficient when using 3072 and 4096-bit key - * 2. stay the same logic with normal 2-prime key - */ - bitse -= bitsr[i]; - if (!BN_GENCB_call(cb, 2, n++)) - goto err; - if (primes > 4) { - if (bitst < 0x9) - adj++; - else - adj--; - } else if (retries == 4) { - /* - * re-generate all primes from scratch, mainly used - * in 4 prime case to avoid long loop. Max retry times - * is set to 4. - */ - i = -1; - bitse = 0; - continue; - } - retries++; - goto redo; - } - /* save product of primes for further use, for multi-prime only */ - if (i > 1 && BN_copy(pinfo->pp, rsa->n) == NULL) - goto err; - if (BN_copy(rsa->n, r1) == NULL) - goto err; - if (!BN_GENCB_call(cb, 3, i)) - goto err; - } - - if (BN_cmp(rsa->p, rsa->q) < 0) { - tmp = rsa->p; - rsa->p = rsa->q; - rsa->q = tmp; - } - - /* calculate d */ - - /* p - 1 */ - if (!BN_sub(r1, rsa->p, BN_value_one())) - goto err; - /* q - 1 */ - if (!BN_sub(r2, rsa->q, BN_value_one())) - goto err; - /* (p - 1)(q - 1) */ - if (!BN_mul(r0, r1, r2, ctx)) - goto err; - /* multi-prime */ - for (i = 2; i < primes; i++) { - pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2); - /* save r_i - 1 to pinfo->d temporarily */ - if (!BN_sub(pinfo->d, pinfo->r, BN_value_one())) - goto err; - if (!BN_mul(r0, r0, pinfo->d, ctx)) - goto err; - } - - { - BIGNUM *pr0 = BN_new(); - - if (pr0 == NULL) - goto err; - - BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); - if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) { - BN_free(pr0); - goto err; /* d */ - } - /* We MUST free pr0 before any further use of r0 */ - BN_free(pr0); - } - - { - BIGNUM *d = BN_new(); - - if (d == NULL) - goto err; - - BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); - - /* calculate d mod (p-1) and d mod (q - 1) */ - if (!BN_mod(rsa->dmp1, d, r1, ctx) - || !BN_mod(rsa->dmq1, d, r2, ctx)) { - BN_free(d); - goto err; - } - - /* calculate CRT exponents */ - for (i = 2; i < primes; i++) { - pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2); - /* pinfo->d == r_i - 1 */ - if (!BN_mod(pinfo->d, d, pinfo->d, ctx)) { - BN_free(d); - goto err; - } - } - - /* We MUST free d before any further use of rsa->d */ - BN_free(d); - } - - { - BIGNUM *p = BN_new(); - - if (p == NULL) - goto err; - BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); - - /* calculate inverse of q mod p */ - if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) { - BN_free(p); - goto err; - } - - /* calculate CRT coefficient for other primes */ - for (i = 2; i < primes; i++) { - pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2); - BN_with_flags(p, pinfo->r, BN_FLG_CONSTTIME); - if (!BN_mod_inverse(pinfo->t, pinfo->pp, p, ctx)) { - BN_free(p); - goto err; - } - } - - /* We MUST free p before any further use of rsa->p */ - BN_free(p); - } - - ok = 1; - err: - if (ok == -1) { - RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN); - ok = 0; - } + * 2. stay the same logic with normal 2-prime key + */ + bitse -= bitsr[i]; + if (!BN_GENCB_call(cb, 2, n++)) + goto err; + if (primes > 4) { + if (bitst < 0x9) + adj++; + else + adj--; + } else if (retries == 4) { + /* + * re-generate all primes from scratch, mainly used + * in 4 prime case to avoid long loop. Max retry times + * is set to 4. + */ + i = -1; + bitse = 0; + continue; + } + retries++; + goto redo; + } + /* save product of primes for further use, for multi-prime only */ + if (i > 1 && BN_copy(pinfo->pp, rsa->n) == NULL) + goto err; + if (BN_copy(rsa->n, r1) == NULL) + goto err; + if (!BN_GENCB_call(cb, 3, i)) + goto err; + } + + if (BN_cmp(rsa->p, rsa->q) < 0) { + tmp = rsa->p; + rsa->p = rsa->q; + rsa->q = tmp; + } + + /* calculate d */ + + /* p - 1 */ + if (!BN_sub(r1, rsa->p, BN_value_one())) + goto err; + /* q - 1 */ + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; + /* (p - 1)(q - 1) */ + if (!BN_mul(r0, r1, r2, ctx)) + goto err; + /* multi-prime */ + for (i = 2; i < primes; i++) { + pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2); + /* save r_i - 1 to pinfo->d temporarily */ + if (!BN_sub(pinfo->d, pinfo->r, BN_value_one())) + goto err; + if (!BN_mul(r0, r0, pinfo->d, ctx)) + goto err; + } + + { + BIGNUM *pr0 = BN_new(); + + if (pr0 == NULL) + goto err; + + BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); + if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) { + BN_free(pr0); + goto err; /* d */ + } + /* We MUST free pr0 before any further use of r0 */ + BN_free(pr0); + } + + { + BIGNUM *d = BN_new(); + + if (d == NULL) + goto err; + + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + + /* calculate d mod (p-1) and d mod (q - 1) */ + if (!BN_mod(rsa->dmp1, d, r1, ctx) + || !BN_mod(rsa->dmq1, d, r2, ctx)) { + BN_free(d); + goto err; + } + + /* calculate CRT exponents */ + for (i = 2; i < primes; i++) { + pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2); + /* pinfo->d == r_i - 1 */ + if (!BN_mod(pinfo->d, d, pinfo->d, ctx)) { + BN_free(d); + goto err; + } + } + + /* We MUST free d before any further use of rsa->d */ + BN_free(d); + } + + { + BIGNUM *p = BN_new(); + + if (p == NULL) + goto err; + BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); + + /* calculate inverse of q mod p */ + if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) { + BN_free(p); + goto err; + } + + /* calculate CRT coefficient for other primes */ + for (i = 2; i < primes; i++) { + pinfo = sk_RSA_PRIME_INFO_value(prime_infos, i - 2); + BN_with_flags(p, pinfo->r, BN_FLG_CONSTTIME); + if (!BN_mod_inverse(pinfo->t, pinfo->pp, p, ctx)) { + BN_free(p); + goto err; + } + } + + /* We MUST free p before any further use of rsa->p */ + BN_free(p); + } + + ok = 1; + err: + if (ok == -1) { + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN); + ok = 0; + } BN_CTX_end(ctx); - BN_CTX_free(ctx); - return ok; -} + BN_CTX_free(ctx); + return ok; +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_lib.c b/contrib/libs/openssl/crypto/rsa/rsa_lib.c index 63fd1a6db4..9d8c0e8c1e 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_lib.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_lib.c @@ -1,493 +1,493 @@ -/* +/* * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdio.h> -#include <openssl/crypto.h> -#include "internal/cryptlib.h" -#include "internal/refcount.h" + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include <openssl/crypto.h> +#include "internal/cryptlib.h" +#include "internal/refcount.h" #include "crypto/bn.h" -#include <openssl/engine.h> -#include <openssl/evp.h> +#include <openssl/engine.h> +#include <openssl/evp.h> #include "crypto/evp.h" #include "rsa_local.h" - -RSA *RSA_new(void) -{ - return RSA_new_method(NULL); -} - -const RSA_METHOD *RSA_get_method(const RSA *rsa) -{ - return rsa->meth; -} - -int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) -{ - /* - * NB: The caller is specifically setting a method, so it's not up to us - * to deal with which ENGINE it comes from. - */ - const RSA_METHOD *mtmp; - mtmp = rsa->meth; - if (mtmp->finish) - mtmp->finish(rsa); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(rsa->engine); - rsa->engine = NULL; -#endif - rsa->meth = meth; - if (meth->init) - meth->init(rsa); - return 1; -} - -RSA *RSA_new_method(ENGINE *engine) -{ - RSA *ret = OPENSSL_zalloc(sizeof(*ret)); - - if (ret == NULL) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); - return NULL; - } - - ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); - OPENSSL_free(ret); - return NULL; - } - - ret->meth = RSA_get_default_method(); -#ifndef OPENSSL_NO_ENGINE - ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; - if (engine) { - if (!ENGINE_init(engine)) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); - goto err; - } - ret->engine = engine; - } else { - ret->engine = ENGINE_get_default_RSA(); - } - if (ret->engine) { - ret->meth = ENGINE_get_RSA(ret->engine); - if (ret->meth == NULL) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); - goto err; - } - } -#endif - - ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { - goto err; - } - - if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_INIT_FAIL); - goto err; - } - - return ret; - - err: - RSA_free(ret); - return NULL; -} - -void RSA_free(RSA *r) -{ - int i; - - if (r == NULL) - return; - - CRYPTO_DOWN_REF(&r->references, &i, r->lock); - REF_PRINT_COUNT("RSA", r); - if (i > 0) - return; - REF_ASSERT_ISNT(i < 0); - - if (r->meth != NULL && r->meth->finish != NULL) - r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(r->engine); -#endif - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); - - CRYPTO_THREAD_lock_free(r->lock); - - BN_free(r->n); - BN_free(r->e); - BN_clear_free(r->d); - BN_clear_free(r->p); - BN_clear_free(r->q); - BN_clear_free(r->dmp1); - BN_clear_free(r->dmq1); - BN_clear_free(r->iqmp); - RSA_PSS_PARAMS_free(r->pss); - sk_RSA_PRIME_INFO_pop_free(r->prime_infos, rsa_multip_info_free); - BN_BLINDING_free(r->blinding); - BN_BLINDING_free(r->mt_blinding); - OPENSSL_free(r->bignum_data); - OPENSSL_free(r); -} - -int RSA_up_ref(RSA *r) -{ - int i; - - if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) - return 0; - - REF_PRINT_COUNT("RSA", r); - REF_ASSERT_ISNT(i < 2); - return i > 1 ? 1 : 0; -} - -int RSA_set_ex_data(RSA *r, int idx, void *arg) -{ - return CRYPTO_set_ex_data(&r->ex_data, idx, arg); -} - -void *RSA_get_ex_data(const RSA *r, int idx) -{ - return CRYPTO_get_ex_data(&r->ex_data, idx); -} - -int RSA_security_bits(const RSA *rsa) -{ - int bits = BN_num_bits(rsa->n); - - if (rsa->version == RSA_ASN1_VERSION_MULTI) { - /* This ought to mean that we have private key at hand. */ - int ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos); - - if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(bits)) - return 0; - } - return BN_security_bits(bits, -1); -} - -int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) -{ - /* If the fields n and e in r are NULL, the corresponding input - * parameters MUST be non-NULL for n and e. d may be - * left NULL (in case only the public key is used). - */ - if ((r->n == NULL && n == NULL) - || (r->e == NULL && e == NULL)) - return 0; - - if (n != NULL) { - BN_free(r->n); - r->n = n; - } - if (e != NULL) { - BN_free(r->e); - r->e = e; - } - if (d != NULL) { - BN_clear_free(r->d); - r->d = d; + +RSA *RSA_new(void) +{ + return RSA_new_method(NULL); +} + +const RSA_METHOD *RSA_get_method(const RSA *rsa) +{ + return rsa->meth; +} + +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) +{ + /* + * NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. + */ + const RSA_METHOD *mtmp; + mtmp = rsa->meth; + if (mtmp->finish) + mtmp->finish(rsa); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(rsa->engine); + rsa->engine = NULL; +#endif + rsa->meth = meth; + if (meth->init) + meth->init(rsa); + return 1; +} + +RSA *RSA_new_method(ENGINE *engine) +{ + RSA *ret = OPENSSL_zalloc(sizeof(*ret)); + + if (ret == NULL) { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->references = 1; + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return NULL; + } + + ret->meth = RSA_get_default_method(); +#ifndef OPENSSL_NO_ENGINE + ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; + if (engine) { + if (!ENGINE_init(engine)) { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + goto err; + } + ret->engine = engine; + } else { + ret->engine = ENGINE_get_default_RSA(); + } + if (ret->engine) { + ret->meth = ENGINE_get_RSA(ret->engine); + if (ret->meth == NULL) { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + goto err; + } + } +#endif + + ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { + goto err; + } + + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_INIT_FAIL); + goto err; + } + + return ret; + + err: + RSA_free(ret); + return NULL; +} + +void RSA_free(RSA *r) +{ + int i; + + if (r == NULL) + return; + + CRYPTO_DOWN_REF(&r->references, &i, r->lock); + REF_PRINT_COUNT("RSA", r); + if (i > 0) + return; + REF_ASSERT_ISNT(i < 0); + + if (r->meth != NULL && r->meth->finish != NULL) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); + + CRYPTO_THREAD_lock_free(r->lock); + + BN_free(r->n); + BN_free(r->e); + BN_clear_free(r->d); + BN_clear_free(r->p); + BN_clear_free(r->q); + BN_clear_free(r->dmp1); + BN_clear_free(r->dmq1); + BN_clear_free(r->iqmp); + RSA_PSS_PARAMS_free(r->pss); + sk_RSA_PRIME_INFO_pop_free(r->prime_infos, rsa_multip_info_free); + BN_BLINDING_free(r->blinding); + BN_BLINDING_free(r->mt_blinding); + OPENSSL_free(r->bignum_data); + OPENSSL_free(r); +} + +int RSA_up_ref(RSA *r) +{ + int i; + + if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) + return 0; + + REF_PRINT_COUNT("RSA", r); + REF_ASSERT_ISNT(i < 2); + return i > 1 ? 1 : 0; +} + +int RSA_set_ex_data(RSA *r, int idx, void *arg) +{ + return CRYPTO_set_ex_data(&r->ex_data, idx, arg); +} + +void *RSA_get_ex_data(const RSA *r, int idx) +{ + return CRYPTO_get_ex_data(&r->ex_data, idx); +} + +int RSA_security_bits(const RSA *rsa) +{ + int bits = BN_num_bits(rsa->n); + + if (rsa->version == RSA_ASN1_VERSION_MULTI) { + /* This ought to mean that we have private key at hand. */ + int ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos); + + if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(bits)) + return 0; + } + return BN_security_bits(bits, -1); +} + +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) +{ + /* If the fields n and e in r are NULL, the corresponding input + * parameters MUST be non-NULL for n and e. d may be + * left NULL (in case only the public key is used). + */ + if ((r->n == NULL && n == NULL) + || (r->e == NULL && e == NULL)) + return 0; + + if (n != NULL) { + BN_free(r->n); + r->n = n; + } + if (e != NULL) { + BN_free(r->e); + r->e = e; + } + if (d != NULL) { + BN_clear_free(r->d); + r->d = d; BN_set_flags(r->d, BN_FLG_CONSTTIME); - } - - return 1; -} - -int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) -{ - /* If the fields p and q in r are NULL, the corresponding input - * parameters MUST be non-NULL. - */ - if ((r->p == NULL && p == NULL) - || (r->q == NULL && q == NULL)) - return 0; - - if (p != NULL) { - BN_clear_free(r->p); - r->p = p; + } + + return 1; +} + +int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) +{ + /* If the fields p and q in r are NULL, the corresponding input + * parameters MUST be non-NULL. + */ + if ((r->p == NULL && p == NULL) + || (r->q == NULL && q == NULL)) + return 0; + + if (p != NULL) { + BN_clear_free(r->p); + r->p = p; BN_set_flags(r->p, BN_FLG_CONSTTIME); - } - if (q != NULL) { - BN_clear_free(r->q); - r->q = q; + } + if (q != NULL) { + BN_clear_free(r->q); + r->q = q; BN_set_flags(r->q, BN_FLG_CONSTTIME); - } - - return 1; -} - -int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) -{ - /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input - * parameters MUST be non-NULL. - */ - if ((r->dmp1 == NULL && dmp1 == NULL) - || (r->dmq1 == NULL && dmq1 == NULL) - || (r->iqmp == NULL && iqmp == NULL)) - return 0; - - if (dmp1 != NULL) { - BN_clear_free(r->dmp1); - r->dmp1 = dmp1; + } + + return 1; +} + +int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) +{ + /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input + * parameters MUST be non-NULL. + */ + if ((r->dmp1 == NULL && dmp1 == NULL) + || (r->dmq1 == NULL && dmq1 == NULL) + || (r->iqmp == NULL && iqmp == NULL)) + return 0; + + if (dmp1 != NULL) { + BN_clear_free(r->dmp1); + r->dmp1 = dmp1; BN_set_flags(r->dmp1, BN_FLG_CONSTTIME); - } - if (dmq1 != NULL) { - BN_clear_free(r->dmq1); - r->dmq1 = dmq1; + } + if (dmq1 != NULL) { + BN_clear_free(r->dmq1); + r->dmq1 = dmq1; BN_set_flags(r->dmq1, BN_FLG_CONSTTIME); - } - if (iqmp != NULL) { - BN_clear_free(r->iqmp); - r->iqmp = iqmp; + } + if (iqmp != NULL) { + BN_clear_free(r->iqmp); + r->iqmp = iqmp; BN_set_flags(r->iqmp, BN_FLG_CONSTTIME); - } - - return 1; -} - -/* - * Is it better to export RSA_PRIME_INFO structure - * and related functions to let user pass a triplet? - */ -int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], - BIGNUM *coeffs[], int pnum) -{ - STACK_OF(RSA_PRIME_INFO) *prime_infos, *old = NULL; - RSA_PRIME_INFO *pinfo; - int i; - - if (primes == NULL || exps == NULL || coeffs == NULL || pnum == 0) - return 0; - - prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum); - if (prime_infos == NULL) - return 0; - - if (r->prime_infos != NULL) - old = r->prime_infos; - - for (i = 0; i < pnum; i++) { - pinfo = rsa_multip_info_new(); - if (pinfo == NULL) - goto err; - if (primes[i] != NULL && exps[i] != NULL && coeffs[i] != NULL) { + } + + return 1; +} + +/* + * Is it better to export RSA_PRIME_INFO structure + * and related functions to let user pass a triplet? + */ +int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], + BIGNUM *coeffs[], int pnum) +{ + STACK_OF(RSA_PRIME_INFO) *prime_infos, *old = NULL; + RSA_PRIME_INFO *pinfo; + int i; + + if (primes == NULL || exps == NULL || coeffs == NULL || pnum == 0) + return 0; + + prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum); + if (prime_infos == NULL) + return 0; + + if (r->prime_infos != NULL) + old = r->prime_infos; + + for (i = 0; i < pnum; i++) { + pinfo = rsa_multip_info_new(); + if (pinfo == NULL) + goto err; + if (primes[i] != NULL && exps[i] != NULL && coeffs[i] != NULL) { BN_clear_free(pinfo->r); BN_clear_free(pinfo->d); BN_clear_free(pinfo->t); - pinfo->r = primes[i]; - pinfo->d = exps[i]; - pinfo->t = coeffs[i]; + pinfo->r = primes[i]; + pinfo->d = exps[i]; + pinfo->t = coeffs[i]; BN_set_flags(pinfo->r, BN_FLG_CONSTTIME); BN_set_flags(pinfo->d, BN_FLG_CONSTTIME); BN_set_flags(pinfo->t, BN_FLG_CONSTTIME); - } else { - rsa_multip_info_free(pinfo); - goto err; - } - (void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo); - } - - r->prime_infos = prime_infos; - - if (!rsa_multip_calc_product(r)) { - r->prime_infos = old; - goto err; - } - - if (old != NULL) { - /* - * This is hard to deal with, since the old infos could - * also be set by this function and r, d, t should not - * be freed in that case. So currently, stay consistent - * with other *set0* functions: just free it... - */ - sk_RSA_PRIME_INFO_pop_free(old, rsa_multip_info_free); - } - - r->version = RSA_ASN1_VERSION_MULTI; - - return 1; - err: - /* r, d, t should not be freed */ - sk_RSA_PRIME_INFO_pop_free(prime_infos, rsa_multip_info_free_ex); - return 0; -} - -void RSA_get0_key(const RSA *r, - const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) -{ - if (n != NULL) - *n = r->n; - if (e != NULL) - *e = r->e; - if (d != NULL) - *d = r->d; -} - -void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) -{ - if (p != NULL) - *p = r->p; - if (q != NULL) - *q = r->q; -} - -int RSA_get_multi_prime_extra_count(const RSA *r) -{ - int pnum; - - pnum = sk_RSA_PRIME_INFO_num(r->prime_infos); - if (pnum <= 0) - pnum = 0; - return pnum; -} - -int RSA_get0_multi_prime_factors(const RSA *r, const BIGNUM *primes[]) -{ - int pnum, i; - RSA_PRIME_INFO *pinfo; - - if ((pnum = RSA_get_multi_prime_extra_count(r)) == 0) - return 0; - - /* - * return other primes - * it's caller's responsibility to allocate oth_primes[pnum] - */ - for (i = 0; i < pnum; i++) { - pinfo = sk_RSA_PRIME_INFO_value(r->prime_infos, i); - primes[i] = pinfo->r; - } - - return 1; -} - -void RSA_get0_crt_params(const RSA *r, - const BIGNUM **dmp1, const BIGNUM **dmq1, - const BIGNUM **iqmp) -{ - if (dmp1 != NULL) - *dmp1 = r->dmp1; - if (dmq1 != NULL) - *dmq1 = r->dmq1; - if (iqmp != NULL) - *iqmp = r->iqmp; -} - -int RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[], - const BIGNUM *coeffs[]) -{ - int pnum; - - if ((pnum = RSA_get_multi_prime_extra_count(r)) == 0) - return 0; - - /* return other primes */ - if (exps != NULL || coeffs != NULL) { - RSA_PRIME_INFO *pinfo; - int i; - - /* it's the user's job to guarantee the buffer length */ - for (i = 0; i < pnum; i++) { - pinfo = sk_RSA_PRIME_INFO_value(r->prime_infos, i); - if (exps != NULL) - exps[i] = pinfo->d; - if (coeffs != NULL) - coeffs[i] = pinfo->t; - } - } - - return 1; -} - -const BIGNUM *RSA_get0_n(const RSA *r) -{ - return r->n; -} - -const BIGNUM *RSA_get0_e(const RSA *r) -{ - return r->e; -} - -const BIGNUM *RSA_get0_d(const RSA *r) -{ - return r->d; -} - -const BIGNUM *RSA_get0_p(const RSA *r) -{ - return r->p; -} - -const BIGNUM *RSA_get0_q(const RSA *r) -{ - return r->q; -} - -const BIGNUM *RSA_get0_dmp1(const RSA *r) -{ - return r->dmp1; -} - -const BIGNUM *RSA_get0_dmq1(const RSA *r) -{ - return r->dmq1; -} - -const BIGNUM *RSA_get0_iqmp(const RSA *r) -{ - return r->iqmp; -} - + } else { + rsa_multip_info_free(pinfo); + goto err; + } + (void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo); + } + + r->prime_infos = prime_infos; + + if (!rsa_multip_calc_product(r)) { + r->prime_infos = old; + goto err; + } + + if (old != NULL) { + /* + * This is hard to deal with, since the old infos could + * also be set by this function and r, d, t should not + * be freed in that case. So currently, stay consistent + * with other *set0* functions: just free it... + */ + sk_RSA_PRIME_INFO_pop_free(old, rsa_multip_info_free); + } + + r->version = RSA_ASN1_VERSION_MULTI; + + return 1; + err: + /* r, d, t should not be freed */ + sk_RSA_PRIME_INFO_pop_free(prime_infos, rsa_multip_info_free_ex); + return 0; +} + +void RSA_get0_key(const RSA *r, + const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +{ + if (n != NULL) + *n = r->n; + if (e != NULL) + *e = r->e; + if (d != NULL) + *d = r->d; +} + +void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) +{ + if (p != NULL) + *p = r->p; + if (q != NULL) + *q = r->q; +} + +int RSA_get_multi_prime_extra_count(const RSA *r) +{ + int pnum; + + pnum = sk_RSA_PRIME_INFO_num(r->prime_infos); + if (pnum <= 0) + pnum = 0; + return pnum; +} + +int RSA_get0_multi_prime_factors(const RSA *r, const BIGNUM *primes[]) +{ + int pnum, i; + RSA_PRIME_INFO *pinfo; + + if ((pnum = RSA_get_multi_prime_extra_count(r)) == 0) + return 0; + + /* + * return other primes + * it's caller's responsibility to allocate oth_primes[pnum] + */ + for (i = 0; i < pnum; i++) { + pinfo = sk_RSA_PRIME_INFO_value(r->prime_infos, i); + primes[i] = pinfo->r; + } + + return 1; +} + +void RSA_get0_crt_params(const RSA *r, + const BIGNUM **dmp1, const BIGNUM **dmq1, + const BIGNUM **iqmp) +{ + if (dmp1 != NULL) + *dmp1 = r->dmp1; + if (dmq1 != NULL) + *dmq1 = r->dmq1; + if (iqmp != NULL) + *iqmp = r->iqmp; +} + +int RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[], + const BIGNUM *coeffs[]) +{ + int pnum; + + if ((pnum = RSA_get_multi_prime_extra_count(r)) == 0) + return 0; + + /* return other primes */ + if (exps != NULL || coeffs != NULL) { + RSA_PRIME_INFO *pinfo; + int i; + + /* it's the user's job to guarantee the buffer length */ + for (i = 0; i < pnum; i++) { + pinfo = sk_RSA_PRIME_INFO_value(r->prime_infos, i); + if (exps != NULL) + exps[i] = pinfo->d; + if (coeffs != NULL) + coeffs[i] = pinfo->t; + } + } + + return 1; +} + +const BIGNUM *RSA_get0_n(const RSA *r) +{ + return r->n; +} + +const BIGNUM *RSA_get0_e(const RSA *r) +{ + return r->e; +} + +const BIGNUM *RSA_get0_d(const RSA *r) +{ + return r->d; +} + +const BIGNUM *RSA_get0_p(const RSA *r) +{ + return r->p; +} + +const BIGNUM *RSA_get0_q(const RSA *r) +{ + return r->q; +} + +const BIGNUM *RSA_get0_dmp1(const RSA *r) +{ + return r->dmp1; +} + +const BIGNUM *RSA_get0_dmq1(const RSA *r) +{ + return r->dmq1; +} + +const BIGNUM *RSA_get0_iqmp(const RSA *r) +{ + return r->iqmp; +} + const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r) { return r->pss; } -void RSA_clear_flags(RSA *r, int flags) -{ - r->flags &= ~flags; -} - -int RSA_test_flags(const RSA *r, int flags) -{ - return r->flags & flags; -} - -void RSA_set_flags(RSA *r, int flags) -{ - r->flags |= flags; -} - -int RSA_get_version(RSA *r) -{ - /* { two-prime(0), multi(1) } */ - return r->version; -} - -ENGINE *RSA_get0_engine(const RSA *r) -{ - return r->engine; -} - -int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2) -{ - /* If key type not RSA or RSA-PSS return error */ - if (ctx != NULL && ctx->pmeth != NULL - && ctx->pmeth->pkey_id != EVP_PKEY_RSA - && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) - return -1; - return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2); -} +void RSA_clear_flags(RSA *r, int flags) +{ + r->flags &= ~flags; +} + +int RSA_test_flags(const RSA *r, int flags) +{ + return r->flags & flags; +} + +void RSA_set_flags(RSA *r, int flags) +{ + r->flags |= flags; +} + +int RSA_get_version(RSA *r) +{ + /* { two-prime(0), multi(1) } */ + return r->version; +} + +ENGINE *RSA_get0_engine(const RSA *r) +{ + return r->engine; +} + +int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2) +{ + /* If key type not RSA or RSA-PSS return error */ + if (ctx != NULL && ctx->pmeth != NULL + && ctx->pmeth->pkey_id != EVP_PKEY_RSA + && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return -1; + return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2); +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_meth.c b/contrib/libs/openssl/crypto/rsa/rsa_meth.c index 2845b79db8..19be0574f2 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_meth.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_meth.c @@ -1,287 +1,287 @@ -/* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <string.h> +/* + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <string.h> #include "rsa_local.h" -#include <openssl/err.h> - -RSA_METHOD *RSA_meth_new(const char *name, int flags) -{ - RSA_METHOD *meth = OPENSSL_zalloc(sizeof(*meth)); - - if (meth != NULL) { - meth->flags = flags; - - meth->name = OPENSSL_strdup(name); - if (meth->name != NULL) - return meth; - - OPENSSL_free(meth); - } - - RSAerr(RSA_F_RSA_METH_NEW, ERR_R_MALLOC_FAILURE); - return NULL; -} - -void RSA_meth_free(RSA_METHOD *meth) -{ - if (meth != NULL) { - OPENSSL_free(meth->name); - OPENSSL_free(meth); - } -} - -RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth) -{ - RSA_METHOD *ret = OPENSSL_malloc(sizeof(*ret)); - - if (ret != NULL) { - memcpy(ret, meth, sizeof(*meth)); - - ret->name = OPENSSL_strdup(meth->name); - if (ret->name != NULL) - return ret; - - OPENSSL_free(ret); - } - - RSAerr(RSA_F_RSA_METH_DUP, ERR_R_MALLOC_FAILURE); - return NULL; -} - -const char *RSA_meth_get0_name(const RSA_METHOD *meth) -{ - return meth->name; -} - -int RSA_meth_set1_name(RSA_METHOD *meth, const char *name) -{ - char *tmpname = OPENSSL_strdup(name); - - if (tmpname == NULL) { - RSAerr(RSA_F_RSA_METH_SET1_NAME, ERR_R_MALLOC_FAILURE); - return 0; - } - - OPENSSL_free(meth->name); - meth->name = tmpname; - - return 1; -} - -int RSA_meth_get_flags(const RSA_METHOD *meth) -{ - return meth->flags; -} - -int RSA_meth_set_flags(RSA_METHOD *meth, int flags) -{ - meth->flags = flags; - return 1; -} - -void *RSA_meth_get0_app_data(const RSA_METHOD *meth) -{ - return meth->app_data; -} - -int RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data) -{ - meth->app_data = app_data; - return 1; -} - -int (*RSA_meth_get_pub_enc(const RSA_METHOD *meth)) - (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - return meth->rsa_pub_enc; -} - -int RSA_meth_set_pub_enc(RSA_METHOD *meth, - int (*pub_enc) (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, - int padding)) -{ - meth->rsa_pub_enc = pub_enc; - return 1; -} - -int (*RSA_meth_get_pub_dec(const RSA_METHOD *meth)) - (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - return meth->rsa_pub_dec; -} - -int RSA_meth_set_pub_dec(RSA_METHOD *meth, - int (*pub_dec) (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, - int padding)) -{ - meth->rsa_pub_dec = pub_dec; - return 1; -} - -int (*RSA_meth_get_priv_enc(const RSA_METHOD *meth)) - (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - return meth->rsa_priv_enc; -} - -int RSA_meth_set_priv_enc(RSA_METHOD *meth, - int (*priv_enc) (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, - int padding)) -{ - meth->rsa_priv_enc = priv_enc; - return 1; -} - -int (*RSA_meth_get_priv_dec(const RSA_METHOD *meth)) - (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - return meth->rsa_priv_dec; -} - -int RSA_meth_set_priv_dec(RSA_METHOD *meth, - int (*priv_dec) (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, - int padding)) -{ - meth->rsa_priv_dec = priv_dec; - return 1; -} - - /* Can be null */ -int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth)) - (BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx) -{ - return meth->rsa_mod_exp; -} - -int RSA_meth_set_mod_exp(RSA_METHOD *meth, - int (*mod_exp) (BIGNUM *r0, const BIGNUM *i, RSA *rsa, - BN_CTX *ctx)) -{ - meth->rsa_mod_exp = mod_exp; - return 1; -} - - /* Can be null */ -int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth)) - (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) -{ - return meth->bn_mod_exp; -} - -int RSA_meth_set_bn_mod_exp(RSA_METHOD *meth, - int (*bn_mod_exp) (BIGNUM *r, - const BIGNUM *a, - const BIGNUM *p, - const BIGNUM *m, - BN_CTX *ctx, - BN_MONT_CTX *m_ctx)) -{ - meth->bn_mod_exp = bn_mod_exp; - return 1; -} - - /* called at new */ -int (*RSA_meth_get_init(const RSA_METHOD *meth)) (RSA *rsa) -{ - return meth->init; -} - -int RSA_meth_set_init(RSA_METHOD *meth, int (*init) (RSA *rsa)) -{ - meth->init = init; - return 1; -} - - /* called at free */ -int (*RSA_meth_get_finish(const RSA_METHOD *meth)) (RSA *rsa) -{ - return meth->finish; -} - -int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)) -{ - meth->finish = finish; - return 1; -} - -int (*RSA_meth_get_sign(const RSA_METHOD *meth)) - (int type, - const unsigned char *m, unsigned int m_length, - unsigned char *sigret, unsigned int *siglen, - const RSA *rsa) -{ - return meth->rsa_sign; -} - -int RSA_meth_set_sign(RSA_METHOD *meth, - int (*sign) (int type, const unsigned char *m, - unsigned int m_length, - unsigned char *sigret, unsigned int *siglen, - const RSA *rsa)) -{ - meth->rsa_sign = sign; - return 1; -} - -int (*RSA_meth_get_verify(const RSA_METHOD *meth)) - (int dtype, const unsigned char *m, - unsigned int m_length, const unsigned char *sigbuf, - unsigned int siglen, const RSA *rsa) -{ - return meth->rsa_verify; -} - -int RSA_meth_set_verify(RSA_METHOD *meth, - int (*verify) (int dtype, const unsigned char *m, - unsigned int m_length, - const unsigned char *sigbuf, - unsigned int siglen, const RSA *rsa)) -{ - meth->rsa_verify = verify; - return 1; -} - -int (*RSA_meth_get_keygen(const RSA_METHOD *meth)) - (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) -{ - return meth->rsa_keygen; -} - -int RSA_meth_set_keygen(RSA_METHOD *meth, - int (*keygen) (RSA *rsa, int bits, BIGNUM *e, - BN_GENCB *cb)) -{ - meth->rsa_keygen = keygen; - return 1; -} - -int (*RSA_meth_get_multi_prime_keygen(const RSA_METHOD *meth)) - (RSA *rsa, int bits, int primes, BIGNUM *e, BN_GENCB *cb) -{ - return meth->rsa_multi_prime_keygen; -} - -int RSA_meth_set_multi_prime_keygen(RSA_METHOD *meth, - int (*keygen) (RSA *rsa, int bits, - int primes, BIGNUM *e, - BN_GENCB *cb)) -{ - meth->rsa_multi_prime_keygen = keygen; - return 1; -} +#include <openssl/err.h> + +RSA_METHOD *RSA_meth_new(const char *name, int flags) +{ + RSA_METHOD *meth = OPENSSL_zalloc(sizeof(*meth)); + + if (meth != NULL) { + meth->flags = flags; + + meth->name = OPENSSL_strdup(name); + if (meth->name != NULL) + return meth; + + OPENSSL_free(meth); + } + + RSAerr(RSA_F_RSA_METH_NEW, ERR_R_MALLOC_FAILURE); + return NULL; +} + +void RSA_meth_free(RSA_METHOD *meth) +{ + if (meth != NULL) { + OPENSSL_free(meth->name); + OPENSSL_free(meth); + } +} + +RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth) +{ + RSA_METHOD *ret = OPENSSL_malloc(sizeof(*ret)); + + if (ret != NULL) { + memcpy(ret, meth, sizeof(*meth)); + + ret->name = OPENSSL_strdup(meth->name); + if (ret->name != NULL) + return ret; + + OPENSSL_free(ret); + } + + RSAerr(RSA_F_RSA_METH_DUP, ERR_R_MALLOC_FAILURE); + return NULL; +} + +const char *RSA_meth_get0_name(const RSA_METHOD *meth) +{ + return meth->name; +} + +int RSA_meth_set1_name(RSA_METHOD *meth, const char *name) +{ + char *tmpname = OPENSSL_strdup(name); + + if (tmpname == NULL) { + RSAerr(RSA_F_RSA_METH_SET1_NAME, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_free(meth->name); + meth->name = tmpname; + + return 1; +} + +int RSA_meth_get_flags(const RSA_METHOD *meth) +{ + return meth->flags; +} + +int RSA_meth_set_flags(RSA_METHOD *meth, int flags) +{ + meth->flags = flags; + return 1; +} + +void *RSA_meth_get0_app_data(const RSA_METHOD *meth) +{ + return meth->app_data; +} + +int RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data) +{ + meth->app_data = app_data; + return 1; +} + +int (*RSA_meth_get_pub_enc(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + return meth->rsa_pub_enc; +} + +int RSA_meth_set_pub_enc(RSA_METHOD *meth, + int (*pub_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)) +{ + meth->rsa_pub_enc = pub_enc; + return 1; +} + +int (*RSA_meth_get_pub_dec(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + return meth->rsa_pub_dec; +} + +int RSA_meth_set_pub_dec(RSA_METHOD *meth, + int (*pub_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)) +{ + meth->rsa_pub_dec = pub_dec; + return 1; +} + +int (*RSA_meth_get_priv_enc(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + return meth->rsa_priv_enc; +} + +int RSA_meth_set_priv_enc(RSA_METHOD *meth, + int (*priv_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)) +{ + meth->rsa_priv_enc = priv_enc; + return 1; +} + +int (*RSA_meth_get_priv_dec(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + return meth->rsa_priv_dec; +} + +int RSA_meth_set_priv_dec(RSA_METHOD *meth, + int (*priv_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)) +{ + meth->rsa_priv_dec = priv_dec; + return 1; +} + + /* Can be null */ +int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth)) + (BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx) +{ + return meth->rsa_mod_exp; +} + +int RSA_meth_set_mod_exp(RSA_METHOD *meth, + int (*mod_exp) (BIGNUM *r0, const BIGNUM *i, RSA *rsa, + BN_CTX *ctx)) +{ + meth->rsa_mod_exp = mod_exp; + return 1; +} + + /* Can be null */ +int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth)) + (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return meth->bn_mod_exp; +} + +int RSA_meth_set_bn_mod_exp(RSA_METHOD *meth, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx)) +{ + meth->bn_mod_exp = bn_mod_exp; + return 1; +} + + /* called at new */ +int (*RSA_meth_get_init(const RSA_METHOD *meth)) (RSA *rsa) +{ + return meth->init; +} + +int RSA_meth_set_init(RSA_METHOD *meth, int (*init) (RSA *rsa)) +{ + meth->init = init; + return 1; +} + + /* called at free */ +int (*RSA_meth_get_finish(const RSA_METHOD *meth)) (RSA *rsa) +{ + return meth->finish; +} + +int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)) +{ + meth->finish = finish; + return 1; +} + +int (*RSA_meth_get_sign(const RSA_METHOD *meth)) + (int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa) +{ + return meth->rsa_sign; +} + +int RSA_meth_set_sign(RSA_METHOD *meth, + int (*sign) (int type, const unsigned char *m, + unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa)) +{ + meth->rsa_sign = sign; + return 1; +} + +int (*RSA_meth_get_verify(const RSA_METHOD *meth)) + (int dtype, const unsigned char *m, + unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa) +{ + return meth->rsa_verify; +} + +int RSA_meth_set_verify(RSA_METHOD *meth, + int (*verify) (int dtype, const unsigned char *m, + unsigned int m_length, + const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa)) +{ + meth->rsa_verify = verify; + return 1; +} + +int (*RSA_meth_get_keygen(const RSA_METHOD *meth)) + (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) +{ + return meth->rsa_keygen; +} + +int RSA_meth_set_keygen(RSA_METHOD *meth, + int (*keygen) (RSA *rsa, int bits, BIGNUM *e, + BN_GENCB *cb)) +{ + meth->rsa_keygen = keygen; + return 1; +} + +int (*RSA_meth_get_multi_prime_keygen(const RSA_METHOD *meth)) + (RSA *rsa, int bits, int primes, BIGNUM *e, BN_GENCB *cb) +{ + return meth->rsa_multi_prime_keygen; +} + +int RSA_meth_set_multi_prime_keygen(RSA_METHOD *meth, + int (*keygen) (RSA *rsa, int bits, + int primes, BIGNUM *e, + BN_GENCB *cb)) +{ + meth->rsa_multi_prime_keygen = keygen; + return 1; +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_mp.c b/contrib/libs/openssl/crypto/rsa/rsa_mp.c index 44dda8f800..01fda5c357 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_mp.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_mp.c @@ -1,115 +1,115 @@ -/* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. - * Copyright 2017 BaishanCloud. All rights reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <openssl/bn.h> -#include <openssl/err.h> +/* + * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017 BaishanCloud. All rights reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/bn.h> +#include <openssl/err.h> #include "rsa_local.h" - -void rsa_multip_info_free_ex(RSA_PRIME_INFO *pinfo) -{ - /* free pp and pinfo only */ - BN_clear_free(pinfo->pp); - OPENSSL_free(pinfo); -} - -void rsa_multip_info_free(RSA_PRIME_INFO *pinfo) -{ - /* free a RSA_PRIME_INFO structure */ - BN_clear_free(pinfo->r); - BN_clear_free(pinfo->d); - BN_clear_free(pinfo->t); - rsa_multip_info_free_ex(pinfo); -} - -RSA_PRIME_INFO *rsa_multip_info_new(void) -{ - RSA_PRIME_INFO *pinfo; - - /* create a RSA_PRIME_INFO structure */ - if ((pinfo = OPENSSL_zalloc(sizeof(RSA_PRIME_INFO))) == NULL) { - RSAerr(RSA_F_RSA_MULTIP_INFO_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - if ((pinfo->r = BN_secure_new()) == NULL) - goto err; - if ((pinfo->d = BN_secure_new()) == NULL) - goto err; - if ((pinfo->t = BN_secure_new()) == NULL) - goto err; - if ((pinfo->pp = BN_secure_new()) == NULL) - goto err; - - return pinfo; - - err: - BN_free(pinfo->r); - BN_free(pinfo->d); - BN_free(pinfo->t); - BN_free(pinfo->pp); - OPENSSL_free(pinfo); - return NULL; -} - -/* Refill products of primes */ -int rsa_multip_calc_product(RSA *rsa) -{ - RSA_PRIME_INFO *pinfo; - BIGNUM *p1 = NULL, *p2 = NULL; - BN_CTX *ctx = NULL; - int i, rv = 0, ex_primes; - - if ((ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) <= 0) { - /* invalid */ - goto err; - } - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - - /* calculate pinfo->pp = p * q for first 'extra' prime */ - p1 = rsa->p; - p2 = rsa->q; - - for (i = 0; i < ex_primes; i++) { - pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); - if (pinfo->pp == NULL) { - pinfo->pp = BN_secure_new(); - if (pinfo->pp == NULL) - goto err; - } - if (!BN_mul(pinfo->pp, p1, p2, ctx)) - goto err; - /* save previous one */ - p1 = pinfo->pp; - p2 = pinfo->r; - } - - rv = 1; - err: - BN_CTX_free(ctx); - return rv; -} - -int rsa_multip_cap(int bits) -{ - int cap = 5; - - if (bits < 1024) - cap = 2; - else if (bits < 4096) - cap = 3; - else if (bits < 8192) - cap = 4; - - if (cap > RSA_MAX_PRIME_NUM) - cap = RSA_MAX_PRIME_NUM; - - return cap; -} + +void rsa_multip_info_free_ex(RSA_PRIME_INFO *pinfo) +{ + /* free pp and pinfo only */ + BN_clear_free(pinfo->pp); + OPENSSL_free(pinfo); +} + +void rsa_multip_info_free(RSA_PRIME_INFO *pinfo) +{ + /* free a RSA_PRIME_INFO structure */ + BN_clear_free(pinfo->r); + BN_clear_free(pinfo->d); + BN_clear_free(pinfo->t); + rsa_multip_info_free_ex(pinfo); +} + +RSA_PRIME_INFO *rsa_multip_info_new(void) +{ + RSA_PRIME_INFO *pinfo; + + /* create a RSA_PRIME_INFO structure */ + if ((pinfo = OPENSSL_zalloc(sizeof(RSA_PRIME_INFO))) == NULL) { + RSAerr(RSA_F_RSA_MULTIP_INFO_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + if ((pinfo->r = BN_secure_new()) == NULL) + goto err; + if ((pinfo->d = BN_secure_new()) == NULL) + goto err; + if ((pinfo->t = BN_secure_new()) == NULL) + goto err; + if ((pinfo->pp = BN_secure_new()) == NULL) + goto err; + + return pinfo; + + err: + BN_free(pinfo->r); + BN_free(pinfo->d); + BN_free(pinfo->t); + BN_free(pinfo->pp); + OPENSSL_free(pinfo); + return NULL; +} + +/* Refill products of primes */ +int rsa_multip_calc_product(RSA *rsa) +{ + RSA_PRIME_INFO *pinfo; + BIGNUM *p1 = NULL, *p2 = NULL; + BN_CTX *ctx = NULL; + int i, rv = 0, ex_primes; + + if ((ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) <= 0) { + /* invalid */ + goto err; + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + /* calculate pinfo->pp = p * q for first 'extra' prime */ + p1 = rsa->p; + p2 = rsa->q; + + for (i = 0; i < ex_primes; i++) { + pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); + if (pinfo->pp == NULL) { + pinfo->pp = BN_secure_new(); + if (pinfo->pp == NULL) + goto err; + } + if (!BN_mul(pinfo->pp, p1, p2, ctx)) + goto err; + /* save previous one */ + p1 = pinfo->pp; + p2 = pinfo->r; + } + + rv = 1; + err: + BN_CTX_free(ctx); + return rv; +} + +int rsa_multip_cap(int bits) +{ + int cap = 5; + + if (bits < 1024) + cap = 2; + else if (bits < 4096) + cap = 3; + else if (bits < 8192) + cap = 4; + + if (cap > RSA_MAX_PRIME_NUM) + cap = RSA_MAX_PRIME_NUM; + + return cap; +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_none.c b/contrib/libs/openssl/crypto/rsa/rsa_none.c index f16cc67066..6a013937b8 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_none.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_none.c @@ -1,43 +1,43 @@ -/* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include "internal/cryptlib.h" -#include <openssl/bn.h> -#include <openssl/rsa.h> - -int RSA_padding_add_none(unsigned char *to, int tlen, - const unsigned char *from, int flen) -{ - if (flen > tlen) { - RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return 0; - } - - if (flen < tlen) { - RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE); - return 0; - } - - memcpy(to, from, (unsigned int)flen); - return 1; -} - -int RSA_padding_check_none(unsigned char *to, int tlen, - const unsigned char *from, int flen, int num) -{ - - if (flen > tlen) { - RSAerr(RSA_F_RSA_PADDING_CHECK_NONE, RSA_R_DATA_TOO_LARGE); - return -1; - } - - memset(to, 0, tlen - flen); - memcpy(to + tlen - flen, from, flen); - return tlen; -} +/* + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/cryptlib.h" +#include <openssl/bn.h> +#include <openssl/rsa.h> + +int RSA_padding_add_none(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + if (flen > tlen) { + RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + if (flen < tlen) { + RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE); + return 0; + } + + memcpy(to, from, (unsigned int)flen); + return 1; +} + +int RSA_padding_check_none(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num) +{ + + if (flen > tlen) { + RSAerr(RSA_F_RSA_PADDING_CHECK_NONE, RSA_R_DATA_TOO_LARGE); + return -1; + } + + memset(to, 0, tlen - flen); + memcpy(to + tlen - flen, from, flen); + return tlen; +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_oaep.c b/contrib/libs/openssl/crypto/rsa/rsa_oaep.c index 302360a964..fa35c7fe9c 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_oaep.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_oaep.c @@ -1,239 +1,239 @@ -/* +/* * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */ - -/* - * See Victor Shoup, "OAEP reconsidered," Nov. 2000, <URL: - * http://www.shoup.net/papers/oaep.ps.Z> for problems with the security - * proof for the original OAEP scheme, which EME-OAEP is based on. A new - * proof can be found in E. Fujisaki, T. Okamoto, D. Pointcheval, J. Stern, - * "RSA-OEAP is Still Alive!", Dec. 2000, <URL: - * http://eprint.iacr.org/2000/061/>. The new proof has stronger requirements - * for the underlying permutation: "partial-one-wayness" instead of - * one-wayness. For the RSA function, this is an equivalent notion. - */ - + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */ + +/* + * See Victor Shoup, "OAEP reconsidered," Nov. 2000, <URL: + * http://www.shoup.net/papers/oaep.ps.Z> for problems with the security + * proof for the original OAEP scheme, which EME-OAEP is based on. A new + * proof can be found in E. Fujisaki, T. Okamoto, D. Pointcheval, J. Stern, + * "RSA-OEAP is Still Alive!", Dec. 2000, <URL: + * http://eprint.iacr.org/2000/061/>. The new proof has stronger requirements + * for the underlying permutation: "partial-one-wayness" instead of + * one-wayness. For the RSA function, this is an equivalent notion. + */ + #include "internal/constant_time.h" - -#include <stdio.h> -#include "internal/cryptlib.h" -#include <openssl/bn.h> -#include <openssl/evp.h> -#include <openssl/rand.h> -#include <openssl/sha.h> + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/bn.h> +#include <openssl/evp.h> +#include <openssl/rand.h> +#include <openssl/sha.h> #include "rsa_local.h" - -int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, - const unsigned char *from, int flen, - const unsigned char *param, int plen) -{ - return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen, - param, plen, NULL, NULL); -} - -int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, - const unsigned char *from, int flen, - const unsigned char *param, int plen, - const EVP_MD *md, const EVP_MD *mgf1md) -{ - int rv = 0; - int i, emlen = tlen - 1; - unsigned char *db, *seed; - unsigned char *dbmask = NULL; - unsigned char seedmask[EVP_MAX_MD_SIZE]; - int mdlen, dbmask_len = 0; - - if (md == NULL) - md = EVP_sha1(); - if (mgf1md == NULL) - mgf1md = md; - - mdlen = EVP_MD_size(md); - - if (flen > emlen - 2 * mdlen - 1) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return 0; - } - - if (emlen < 2 * mdlen + 1) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, - RSA_R_KEY_SIZE_TOO_SMALL); - return 0; - } - - to[0] = 0; - seed = to + 1; - db = to + mdlen + 1; - - if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) - goto err; - memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1); - db[emlen - flen - mdlen - 1] = 0x01; - memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen); - if (RAND_bytes(seed, mdlen) <= 0) - goto err; - - dbmask_len = emlen - mdlen; - dbmask = OPENSSL_malloc(dbmask_len); - if (dbmask == NULL) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (PKCS1_MGF1(dbmask, dbmask_len, seed, mdlen, mgf1md) < 0) - goto err; - for (i = 0; i < dbmask_len; i++) - db[i] ^= dbmask[i]; - - if (PKCS1_MGF1(seedmask, mdlen, db, dbmask_len, mgf1md) < 0) - goto err; - for (i = 0; i < mdlen; i++) - seed[i] ^= seedmask[i]; - rv = 1; - - err: - OPENSSL_cleanse(seedmask, sizeof(seedmask)); - OPENSSL_clear_free(dbmask, dbmask_len); - return rv; -} - -int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, - const unsigned char *from, int flen, int num, - const unsigned char *param, int plen) -{ - return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from, flen, num, - param, plen, NULL, NULL); -} - -int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, - const unsigned char *from, int flen, - int num, const unsigned char *param, - int plen, const EVP_MD *md, - const EVP_MD *mgf1md) -{ - int i, dblen = 0, mlen = -1, one_index = 0, msg_index; - unsigned int good = 0, found_one_byte, mask; - const unsigned char *maskedseed, *maskeddb; - /* - * |em| is the encoded message, zero-padded to exactly |num| bytes: em = - * Y || maskedSeed || maskedDB - */ - unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE], - phash[EVP_MAX_MD_SIZE]; - int mdlen; - - if (md == NULL) - md = EVP_sha1(); - if (mgf1md == NULL) - mgf1md = md; - - mdlen = EVP_MD_size(md); - - if (tlen <= 0 || flen <= 0) - return -1; - /* - * |num| is the length of the modulus; |flen| is the length of the - * encoded message. Therefore, for any |from| that was obtained by - * decrypting a ciphertext, we must have |flen| <= |num|. Similarly, + +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, int plen) +{ + return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen, + param, plen, NULL, NULL); +} + +int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, int plen, + const EVP_MD *md, const EVP_MD *mgf1md) +{ + int rv = 0; + int i, emlen = tlen - 1; + unsigned char *db, *seed; + unsigned char *dbmask = NULL; + unsigned char seedmask[EVP_MAX_MD_SIZE]; + int mdlen, dbmask_len = 0; + + if (md == NULL) + md = EVP_sha1(); + if (mgf1md == NULL) + mgf1md = md; + + mdlen = EVP_MD_size(md); + + if (flen > emlen - 2 * mdlen - 1) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + if (emlen < 2 * mdlen + 1) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, + RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + to[0] = 0; + seed = to + 1; + db = to + mdlen + 1; + + if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) + goto err; + memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1); + db[emlen - flen - mdlen - 1] = 0x01; + memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen); + if (RAND_bytes(seed, mdlen) <= 0) + goto err; + + dbmask_len = emlen - mdlen; + dbmask = OPENSSL_malloc(dbmask_len); + if (dbmask == NULL) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (PKCS1_MGF1(dbmask, dbmask_len, seed, mdlen, mgf1md) < 0) + goto err; + for (i = 0; i < dbmask_len; i++) + db[i] ^= dbmask[i]; + + if (PKCS1_MGF1(seedmask, mdlen, db, dbmask_len, mgf1md) < 0) + goto err; + for (i = 0; i < mdlen; i++) + seed[i] ^= seedmask[i]; + rv = 1; + + err: + OPENSSL_cleanse(seedmask, sizeof(seedmask)); + OPENSSL_clear_free(dbmask, dbmask_len); + return rv; +} + +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num, + const unsigned char *param, int plen) +{ + return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from, flen, num, + param, plen, NULL, NULL); +} + +int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num, const unsigned char *param, + int plen, const EVP_MD *md, + const EVP_MD *mgf1md) +{ + int i, dblen = 0, mlen = -1, one_index = 0, msg_index; + unsigned int good = 0, found_one_byte, mask; + const unsigned char *maskedseed, *maskeddb; + /* + * |em| is the encoded message, zero-padded to exactly |num| bytes: em = + * Y || maskedSeed || maskedDB + */ + unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE], + phash[EVP_MAX_MD_SIZE]; + int mdlen; + + if (md == NULL) + md = EVP_sha1(); + if (mgf1md == NULL) + mgf1md = md; + + mdlen = EVP_MD_size(md); + + if (tlen <= 0 || flen <= 0) + return -1; + /* + * |num| is the length of the modulus; |flen| is the length of the + * encoded message. Therefore, for any |from| that was obtained by + * decrypting a ciphertext, we must have |flen| <= |num|. Similarly, * |num| >= 2 * |mdlen| + 2 must hold for the modulus irrespective of - * the ciphertext, see PKCS #1 v2.2, section 7.1.2. - * This does not leak any side-channel information. - */ - if (num < flen || num < 2 * mdlen + 2) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, - RSA_R_OAEP_DECODING_ERROR); - return -1; - } - - dblen = num - mdlen - 1; - db = OPENSSL_malloc(dblen); - if (db == NULL) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); - goto cleanup; - } - - em = OPENSSL_malloc(num); - if (em == NULL) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, - ERR_R_MALLOC_FAILURE); - goto cleanup; - } - - /* - * Caller is encouraged to pass zero-padded message created with - * BN_bn2binpad. Trouble is that since we can't read out of |from|'s - * bounds, it's impossible to have an invariant memory access pattern - * in case |from| was not zero-padded in advance. - */ - for (from += flen, em += num, i = 0; i < num; i++) { - mask = ~constant_time_is_zero(flen); - flen -= 1 & mask; - from -= 1 & mask; - *--em = *from & mask; - } - - /* - * The first byte must be zero, however we must not leak if this is - * true. See James H. Manger, "A Chosen Ciphertext Attack on RSA - * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001). - */ + * the ciphertext, see PKCS #1 v2.2, section 7.1.2. + * This does not leak any side-channel information. + */ + if (num < flen || num < 2 * mdlen + 2) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, + RSA_R_OAEP_DECODING_ERROR); + return -1; + } + + dblen = num - mdlen - 1; + db = OPENSSL_malloc(dblen); + if (db == NULL) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); + goto cleanup; + } + + em = OPENSSL_malloc(num); + if (em == NULL) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, + ERR_R_MALLOC_FAILURE); + goto cleanup; + } + + /* + * Caller is encouraged to pass zero-padded message created with + * BN_bn2binpad. Trouble is that since we can't read out of |from|'s + * bounds, it's impossible to have an invariant memory access pattern + * in case |from| was not zero-padded in advance. + */ + for (from += flen, em += num, i = 0; i < num; i++) { + mask = ~constant_time_is_zero(flen); + flen -= 1 & mask; + from -= 1 & mask; + *--em = *from & mask; + } + + /* + * The first byte must be zero, however we must not leak if this is + * true. See James H. Manger, "A Chosen Ciphertext Attack on RSA + * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001). + */ good = constant_time_is_zero(em[0]); - + maskedseed = em + 1; maskeddb = em + 1 + mdlen; - - if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) - goto cleanup; - for (i = 0; i < mdlen; i++) - seed[i] ^= maskedseed[i]; - - if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) - goto cleanup; - for (i = 0; i < dblen; i++) - db[i] ^= maskeddb[i]; - - if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL)) - goto cleanup; - - good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen)); - - found_one_byte = 0; - for (i = mdlen; i < dblen; i++) { - /* - * Padding consists of a number of 0-bytes, followed by a 1. - */ - unsigned int equals1 = constant_time_eq(db[i], 1); - unsigned int equals0 = constant_time_is_zero(db[i]); - one_index = constant_time_select_int(~found_one_byte & equals1, - i, one_index); - found_one_byte |= equals1; - good &= (found_one_byte | equals0); - } - - good &= found_one_byte; - - /* - * At this point |good| is zero unless the plaintext was valid, - * so plaintext-awareness ensures timing side-channels are no longer a - * concern. - */ - msg_index = one_index + 1; - mlen = dblen - msg_index; - - /* + + if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) + goto cleanup; + for (i = 0; i < mdlen; i++) + seed[i] ^= maskedseed[i]; + + if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) + goto cleanup; + for (i = 0; i < dblen; i++) + db[i] ^= maskeddb[i]; + + if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL)) + goto cleanup; + + good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen)); + + found_one_byte = 0; + for (i = mdlen; i < dblen; i++) { + /* + * Padding consists of a number of 0-bytes, followed by a 1. + */ + unsigned int equals1 = constant_time_eq(db[i], 1); + unsigned int equals0 = constant_time_is_zero(db[i]); + one_index = constant_time_select_int(~found_one_byte & equals1, + i, one_index); + found_one_byte |= equals1; + good &= (found_one_byte | equals0); + } + + good &= found_one_byte; + + /* + * At this point |good| is zero unless the plaintext was valid, + * so plaintext-awareness ensures timing side-channels are no longer a + * concern. + */ + msg_index = one_index + 1; + mlen = dblen - msg_index; + + /* * For good measure, do this check in constant time as well. - */ - good &= constant_time_ge(tlen, mlen); - - /* + */ + good &= constant_time_ge(tlen, mlen); + + /* * Move the result in-place by |dblen|-|mdlen|-1-|mlen| bytes to the left. * Then if |good| move |mlen| bytes from |db|+|mdlen|+1 to |to|. * Otherwise leave |to| unchanged. @@ -242,72 +242,72 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, * parts of the buffer multiple times based on the bits set in the real * length. Clear bits do a non-copy with identical access pattern. * The loop below has overall complexity of O(N*log(N)). - */ + */ tlen = constant_time_select_int(constant_time_lt(dblen - mdlen - 1, tlen), dblen - mdlen - 1, tlen); for (msg_index = 1; msg_index < dblen - mdlen - 1; msg_index <<= 1) { mask = ~constant_time_eq(msg_index & (dblen - mdlen - 1 - mlen), 0); for (i = mdlen + 1; i < dblen - msg_index; i++) db[i] = constant_time_select_8(mask, db[i + msg_index], db[i]); - } + } for (i = 0; i < tlen; i++) { mask = good & constant_time_lt(i, mlen); to[i] = constant_time_select_8(mask, db[i + mdlen + 1], to[i]); } - - /* - * To avoid chosen ciphertext attacks, the error message should not - * reveal which kind of decoding error happened. - */ - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, - RSA_R_OAEP_DECODING_ERROR); - err_clear_last_constant_time(1 & good); - cleanup: - OPENSSL_cleanse(seed, sizeof(seed)); - OPENSSL_clear_free(db, dblen); - OPENSSL_clear_free(em, num); - - return constant_time_select_int(good, mlen, -1); -} - -int PKCS1_MGF1(unsigned char *mask, long len, - const unsigned char *seed, long seedlen, const EVP_MD *dgst) -{ - long i, outlen = 0; - unsigned char cnt[4]; - EVP_MD_CTX *c = EVP_MD_CTX_new(); - unsigned char md[EVP_MAX_MD_SIZE]; - int mdlen; - int rv = -1; - - if (c == NULL) - goto err; - mdlen = EVP_MD_size(dgst); - if (mdlen < 0) - goto err; - for (i = 0; outlen < len; i++) { - cnt[0] = (unsigned char)((i >> 24) & 255); - cnt[1] = (unsigned char)((i >> 16) & 255); - cnt[2] = (unsigned char)((i >> 8)) & 255; - cnt[3] = (unsigned char)(i & 255); - if (!EVP_DigestInit_ex(c, dgst, NULL) - || !EVP_DigestUpdate(c, seed, seedlen) - || !EVP_DigestUpdate(c, cnt, 4)) - goto err; - if (outlen + mdlen <= len) { - if (!EVP_DigestFinal_ex(c, mask + outlen, NULL)) - goto err; - outlen += mdlen; - } else { - if (!EVP_DigestFinal_ex(c, md, NULL)) - goto err; - memcpy(mask + outlen, md, len - outlen); - outlen = len; - } - } - rv = 0; - err: - OPENSSL_cleanse(md, sizeof(md)); - EVP_MD_CTX_free(c); - return rv; -} + + /* + * To avoid chosen ciphertext attacks, the error message should not + * reveal which kind of decoding error happened. + */ + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, + RSA_R_OAEP_DECODING_ERROR); + err_clear_last_constant_time(1 & good); + cleanup: + OPENSSL_cleanse(seed, sizeof(seed)); + OPENSSL_clear_free(db, dblen); + OPENSSL_clear_free(em, num); + + return constant_time_select_int(good, mlen, -1); +} + +int PKCS1_MGF1(unsigned char *mask, long len, + const unsigned char *seed, long seedlen, const EVP_MD *dgst) +{ + long i, outlen = 0; + unsigned char cnt[4]; + EVP_MD_CTX *c = EVP_MD_CTX_new(); + unsigned char md[EVP_MAX_MD_SIZE]; + int mdlen; + int rv = -1; + + if (c == NULL) + goto err; + mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + goto err; + for (i = 0; outlen < len; i++) { + cnt[0] = (unsigned char)((i >> 24) & 255); + cnt[1] = (unsigned char)((i >> 16) & 255); + cnt[2] = (unsigned char)((i >> 8)) & 255; + cnt[3] = (unsigned char)(i & 255); + if (!EVP_DigestInit_ex(c, dgst, NULL) + || !EVP_DigestUpdate(c, seed, seedlen) + || !EVP_DigestUpdate(c, cnt, 4)) + goto err; + if (outlen + mdlen <= len) { + if (!EVP_DigestFinal_ex(c, mask + outlen, NULL)) + goto err; + outlen += mdlen; + } else { + if (!EVP_DigestFinal_ex(c, md, NULL)) + goto err; + memcpy(mask + outlen, md, len - outlen); + outlen = len; + } + } + rv = 0; + err: + OPENSSL_cleanse(md, sizeof(md)); + EVP_MD_CTX_free(c); + return rv; +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_ossl.c b/contrib/libs/openssl/crypto/rsa/rsa_ossl.c index b52a66f6a6..e232fa3626 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_ossl.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_ossl.c @@ -1,976 +1,976 @@ -/* +/* * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include "internal/cryptlib.h" + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/cryptlib.h" #include "crypto/bn.h" #include "rsa_local.h" #include "internal/constant_time.h" - -static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, - BN_CTX *ctx); -static int rsa_ossl_init(RSA *rsa); -static int rsa_ossl_finish(RSA *rsa); -static RSA_METHOD rsa_pkcs1_ossl_meth = { - "OpenSSL PKCS#1 RSA", - rsa_ossl_public_encrypt, - rsa_ossl_public_decrypt, /* signature verification */ - rsa_ossl_private_encrypt, /* signing */ - rsa_ossl_private_decrypt, - rsa_ossl_mod_exp, - BN_mod_exp_mont, /* XXX probably we should not use Montgomery - * if e == 3 */ - rsa_ossl_init, - rsa_ossl_finish, - RSA_FLAG_FIPS_METHOD, /* flags */ - NULL, - 0, /* rsa_sign */ - 0, /* rsa_verify */ - NULL, /* rsa_keygen */ - NULL /* rsa_multi_prime_keygen */ -}; - -static const RSA_METHOD *default_RSA_meth = &rsa_pkcs1_ossl_meth; - -void RSA_set_default_method(const RSA_METHOD *meth) -{ - default_RSA_meth = meth; -} - -const RSA_METHOD *RSA_get_default_method(void) -{ - return default_RSA_meth; -} - -const RSA_METHOD *RSA_PKCS1_OpenSSL(void) -{ - return &rsa_pkcs1_ossl_meth; -} - -const RSA_METHOD *RSA_null_method(void) -{ - return NULL; -} - -static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - BIGNUM *f, *ret; - int i, num = 0, r = -1; - unsigned char *buf = NULL; - BN_CTX *ctx = NULL; - - if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); - return -1; - } - - if (BN_ucmp(rsa->n, rsa->e) <= 0) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); - return -1; - } - - /* for large moduli, enforce exponent limit */ - if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { - if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); - return -1; - } - } - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - ret = BN_CTX_get(ctx); - num = BN_num_bytes(rsa->n); - buf = OPENSSL_malloc(num); - if (ret == NULL || buf == NULL) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - switch (padding) { - case RSA_PKCS1_PADDING: - i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen); - break; - case RSA_PKCS1_OAEP_PADDING: - i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); - break; - case RSA_SSLV23_PADDING: - i = RSA_padding_add_SSLv23(buf, num, from, flen); - break; - case RSA_NO_PADDING: - i = RSA_padding_add_none(buf, num, from, flen); - break; - default: - RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); - goto err; - } - if (i <= 0) - goto err; - - if (BN_bin2bn(buf, num, f) == NULL) - goto err; - - if (BN_ucmp(f, rsa->n) >= 0) { - /* usually the padding functions would catch this */ - RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, - RSA_R_DATA_TOO_LARGE_FOR_MODULUS); - goto err; - } - - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, - rsa->n, ctx)) - goto err; - - if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, - rsa->_method_mod_n)) - goto err; - - /* - * BN_bn2binpad puts in leading 0 bytes if the number is less than - * the length of the modulus. - */ - r = BN_bn2binpad(ret, to, num); - err: + +static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, + BN_CTX *ctx); +static int rsa_ossl_init(RSA *rsa); +static int rsa_ossl_finish(RSA *rsa); +static RSA_METHOD rsa_pkcs1_ossl_meth = { + "OpenSSL PKCS#1 RSA", + rsa_ossl_public_encrypt, + rsa_ossl_public_decrypt, /* signature verification */ + rsa_ossl_private_encrypt, /* signing */ + rsa_ossl_private_decrypt, + rsa_ossl_mod_exp, + BN_mod_exp_mont, /* XXX probably we should not use Montgomery + * if e == 3 */ + rsa_ossl_init, + rsa_ossl_finish, + RSA_FLAG_FIPS_METHOD, /* flags */ + NULL, + 0, /* rsa_sign */ + 0, /* rsa_verify */ + NULL, /* rsa_keygen */ + NULL /* rsa_multi_prime_keygen */ +}; + +static const RSA_METHOD *default_RSA_meth = &rsa_pkcs1_ossl_meth; + +void RSA_set_default_method(const RSA_METHOD *meth) +{ + default_RSA_meth = meth; +} + +const RSA_METHOD *RSA_get_default_method(void) +{ + return default_RSA_meth; +} + +const RSA_METHOD *RSA_PKCS1_OpenSSL(void) +{ + return &rsa_pkcs1_ossl_meth; +} + +const RSA_METHOD *RSA_null_method(void) +{ + return NULL; +} + +static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + BIGNUM *f, *ret; + int i, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { + RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (BN_ucmp(rsa->n, rsa->e) <= 0) { + RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + + /* for large moduli, enforce exponent limit */ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { + if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { + RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (ret == NULL || buf == NULL) { + RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen); + break; + case RSA_PKCS1_OAEP_PADDING: + i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); + break; + case RSA_SSLV23_PADDING: + i = RSA_padding_add_SSLv23(buf, num, from, flen); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, num, from, flen); + break; + default: + RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) + goto err; + + if (BN_bin2bn(buf, num, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, + RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, + rsa->n, ctx)) + goto err; + + if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + + /* + * BN_bn2binpad puts in leading 0 bytes if the number is less than + * the length of the modulus. + */ + r = BN_bn2binpad(ret, to, num); + err: BN_CTX_end(ctx); - BN_CTX_free(ctx); - OPENSSL_clear_free(buf, num); - return r; -} - -static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) -{ - BN_BLINDING *ret; - - CRYPTO_THREAD_write_lock(rsa->lock); - - if (rsa->blinding == NULL) { - rsa->blinding = RSA_setup_blinding(rsa, ctx); - } - - ret = rsa->blinding; - if (ret == NULL) - goto err; - - if (BN_BLINDING_is_current_thread(ret)) { - /* rsa->blinding is ours! */ - - *local = 1; - } else { - /* resort to rsa->mt_blinding instead */ - - /* - * instructs rsa_blinding_convert(), rsa_blinding_invert() that the - * BN_BLINDING is shared, meaning that accesses require locks, and - * that the blinding factor must be stored outside the BN_BLINDING - */ - *local = 0; - - if (rsa->mt_blinding == NULL) { - rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); - } - ret = rsa->mt_blinding; - } - - err: - CRYPTO_THREAD_unlock(rsa->lock); - return ret; -} - -static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, - BN_CTX *ctx) -{ - if (unblind == NULL) { - /* - * Local blinding: store the unblinding factor in BN_BLINDING. - */ - return BN_BLINDING_convert_ex(f, NULL, b, ctx); - } else { - /* - * Shared blinding: store the unblinding factor outside BN_BLINDING. - */ - int ret; - - BN_BLINDING_lock(b); - ret = BN_BLINDING_convert_ex(f, unblind, b, ctx); - BN_BLINDING_unlock(b); - - return ret; - } -} - -static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, - BN_CTX *ctx) -{ - /* - * For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex - * will use the unblinding factor stored in BN_BLINDING. If BN_BLINDING - * is shared between threads, unblind must be non-null: - * BN_BLINDING_invert_ex will then use the local unblinding factor, and - * will only read the modulus from BN_BLINDING. In both cases it's safe - * to access the blinding without a lock. - */ - return BN_BLINDING_invert_ex(f, unblind, b, ctx); -} - -/* signing */ -static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - BIGNUM *f, *ret, *res; - int i, num = 0, r = -1; - unsigned char *buf = NULL; - BN_CTX *ctx = NULL; - int local_blinding = 0; - /* - * Used only if the blinding structure is shared. A non-NULL unblind - * instructs rsa_blinding_convert() and rsa_blinding_invert() to store - * the unblinding factor outside the blinding structure. - */ - BIGNUM *unblind = NULL; - BN_BLINDING *blinding = NULL; - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - ret = BN_CTX_get(ctx); - num = BN_num_bytes(rsa->n); - buf = OPENSSL_malloc(num); - if (ret == NULL || buf == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - switch (padding) { - case RSA_PKCS1_PADDING: - i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen); - break; - case RSA_X931_PADDING: - i = RSA_padding_add_X931(buf, num, from, flen); - break; - case RSA_NO_PADDING: - i = RSA_padding_add_none(buf, num, from, flen); - break; - case RSA_SSLV23_PADDING: - default: - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); - goto err; - } - if (i <= 0) - goto err; - - if (BN_bin2bn(buf, num, f) == NULL) - goto err; - - if (BN_ucmp(f, rsa->n) >= 0) { - /* usually the padding functions would catch this */ - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, - RSA_R_DATA_TOO_LARGE_FOR_MODULUS); - goto err; - } - - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, - rsa->n, ctx)) - goto err; - - if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { - blinding = rsa_get_blinding(rsa, &local_blinding, ctx); - if (blinding == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - if (blinding != NULL) { - if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!rsa_blinding_convert(blinding, f, unblind, ctx)) - goto err; - } - - if ((rsa->flags & RSA_FLAG_EXT_PKEY) || - (rsa->version == RSA_ASN1_VERSION_MULTI) || - ((rsa->p != NULL) && - (rsa->q != NULL) && - (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { - if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) - goto err; - } else { - BIGNUM *d = BN_new(); - if (d == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } + BN_CTX_free(ctx); + OPENSSL_clear_free(buf, num); + return r; +} + +static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) +{ + BN_BLINDING *ret; + + CRYPTO_THREAD_write_lock(rsa->lock); + + if (rsa->blinding == NULL) { + rsa->blinding = RSA_setup_blinding(rsa, ctx); + } + + ret = rsa->blinding; + if (ret == NULL) + goto err; + + if (BN_BLINDING_is_current_thread(ret)) { + /* rsa->blinding is ours! */ + + *local = 1; + } else { + /* resort to rsa->mt_blinding instead */ + + /* + * instructs rsa_blinding_convert(), rsa_blinding_invert() that the + * BN_BLINDING is shared, meaning that accesses require locks, and + * that the blinding factor must be stored outside the BN_BLINDING + */ + *local = 0; + + if (rsa->mt_blinding == NULL) { + rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); + } + ret = rsa->mt_blinding; + } + + err: + CRYPTO_THREAD_unlock(rsa->lock); + return ret; +} + +static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, + BN_CTX *ctx) +{ + if (unblind == NULL) { + /* + * Local blinding: store the unblinding factor in BN_BLINDING. + */ + return BN_BLINDING_convert_ex(f, NULL, b, ctx); + } else { + /* + * Shared blinding: store the unblinding factor outside BN_BLINDING. + */ + int ret; + + BN_BLINDING_lock(b); + ret = BN_BLINDING_convert_ex(f, unblind, b, ctx); + BN_BLINDING_unlock(b); + + return ret; + } +} + +static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, + BN_CTX *ctx) +{ + /* + * For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex + * will use the unblinding factor stored in BN_BLINDING. If BN_BLINDING + * is shared between threads, unblind must be non-null: + * BN_BLINDING_invert_ex will then use the local unblinding factor, and + * will only read the modulus from BN_BLINDING. In both cases it's safe + * to access the blinding without a lock. + */ + return BN_BLINDING_invert_ex(f, unblind, b, ctx); +} + +/* signing */ +static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + BIGNUM *f, *ret, *res; + int i, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + int local_blinding = 0; + /* + * Used only if the blinding structure is shared. A non-NULL unblind + * instructs rsa_blinding_convert() and rsa_blinding_invert() to store + * the unblinding factor outside the blinding structure. + */ + BIGNUM *unblind = NULL; + BN_BLINDING *blinding = NULL; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (ret == NULL || buf == NULL) { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen); + break; + case RSA_X931_PADDING: + i = RSA_padding_add_X931(buf, num, from, flen); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, num, from, flen); + break; + case RSA_SSLV23_PADDING: + default: + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) + goto err; + + if (BN_bin2bn(buf, num, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, + RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, + rsa->n, ctx)) + goto err; + + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) { + if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!rsa_blinding_convert(blinding, f, unblind, ctx)) + goto err; + } + + if ((rsa->flags & RSA_FLAG_EXT_PKEY) || + (rsa->version == RSA_ASN1_VERSION_MULTI) || + ((rsa->p != NULL) && + (rsa->q != NULL) && + (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { + if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) + goto err; + } else { + BIGNUM *d = BN_new(); + if (d == NULL) { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } if (rsa->d == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_MISSING_PRIVATE_KEY); BN_free(d); goto err; } - BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); - - if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, - rsa->_method_mod_n)) { - BN_free(d); - goto err; - } - /* We MUST free d before any further use of rsa->d */ - BN_free(d); - } - - if (blinding) - if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) - goto err; - - if (padding == RSA_X931_PADDING) { - if (!BN_sub(f, rsa->n, ret)) - goto err; - if (BN_cmp(ret, f) > 0) - res = f; - else - res = ret; - } else { - res = ret; - } - - /* - * BN_bn2binpad puts in leading 0 bytes if the number is less than - * the length of the modulus. - */ - r = BN_bn2binpad(res, to, num); - err: + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + + if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, + rsa->_method_mod_n)) { + BN_free(d); + goto err; + } + /* We MUST free d before any further use of rsa->d */ + BN_free(d); + } + + if (blinding) + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) + goto err; + + if (padding == RSA_X931_PADDING) { + if (!BN_sub(f, rsa->n, ret)) + goto err; + if (BN_cmp(ret, f) > 0) + res = f; + else + res = ret; + } else { + res = ret; + } + + /* + * BN_bn2binpad puts in leading 0 bytes if the number is less than + * the length of the modulus. + */ + r = BN_bn2binpad(res, to, num); + err: BN_CTX_end(ctx); - BN_CTX_free(ctx); - OPENSSL_clear_free(buf, num); - return r; -} - -static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - BIGNUM *f, *ret; - int j, num = 0, r = -1; - unsigned char *buf = NULL; - BN_CTX *ctx = NULL; - int local_blinding = 0; - /* - * Used only if the blinding structure is shared. A non-NULL unblind - * instructs rsa_blinding_convert() and rsa_blinding_invert() to store - * the unblinding factor outside the blinding structure. - */ - BIGNUM *unblind = NULL; - BN_BLINDING *blinding = NULL; - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - ret = BN_CTX_get(ctx); - num = BN_num_bytes(rsa->n); - buf = OPENSSL_malloc(num); - if (ret == NULL || buf == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * This check was for equality but PGP does evil things and chops off the - * top '0' bytes - */ - if (flen > num) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, - RSA_R_DATA_GREATER_THAN_MOD_LEN); - goto err; - } - - /* make data into a big number */ - if (BN_bin2bn(from, (int)flen, f) == NULL) - goto err; - - if (BN_ucmp(f, rsa->n) >= 0) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, - RSA_R_DATA_TOO_LARGE_FOR_MODULUS); - goto err; - } - - if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { - blinding = rsa_get_blinding(rsa, &local_blinding, ctx); - if (blinding == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - if (blinding != NULL) { - if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!rsa_blinding_convert(blinding, f, unblind, ctx)) - goto err; - } - - /* do the decrypt */ - if ((rsa->flags & RSA_FLAG_EXT_PKEY) || - (rsa->version == RSA_ASN1_VERSION_MULTI) || - ((rsa->p != NULL) && - (rsa->q != NULL) && - (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { - if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) - goto err; - } else { - BIGNUM *d = BN_new(); - if (d == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } + BN_CTX_free(ctx); + OPENSSL_clear_free(buf, num); + return r; +} + +static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + BIGNUM *f, *ret; + int j, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + int local_blinding = 0; + /* + * Used only if the blinding structure is shared. A non-NULL unblind + * instructs rsa_blinding_convert() and rsa_blinding_invert() to store + * the unblinding factor outside the blinding structure. + */ + BIGNUM *unblind = NULL; + BN_BLINDING *blinding = NULL; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (ret == NULL || buf == NULL) { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * This check was for equality but PGP does evil things and chops off the + * top '0' bytes + */ + if (flen > num) { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, + RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + /* make data into a big number */ + if (BN_bin2bn(from, (int)flen, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, + RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) { + if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!rsa_blinding_convert(blinding, f, unblind, ctx)) + goto err; + } + + /* do the decrypt */ + if ((rsa->flags & RSA_FLAG_EXT_PKEY) || + (rsa->version == RSA_ASN1_VERSION_MULTI) || + ((rsa->p != NULL) && + (rsa->q != NULL) && + (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { + if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) + goto err; + } else { + BIGNUM *d = BN_new(); + if (d == NULL) { + RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } if (rsa->d == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_MISSING_PRIVATE_KEY); BN_free(d); goto err; } - BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); - - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, - rsa->n, ctx)) { - BN_free(d); - goto err; - } - if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, - rsa->_method_mod_n)) { - BN_free(d); - goto err; - } - /* We MUST free d before any further use of rsa->d */ - BN_free(d); - } - - if (blinding) - if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) - goto err; - - j = BN_bn2binpad(ret, buf, num); - - switch (padding) { - case RSA_PKCS1_PADDING: - r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num); - break; - case RSA_PKCS1_OAEP_PADDING: - r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); - break; - case RSA_SSLV23_PADDING: - r = RSA_padding_check_SSLv23(to, num, buf, j, num); - break; - case RSA_NO_PADDING: - memcpy(to, buf, (r = j)); - break; - default: - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); - goto err; - } - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, + rsa->n, ctx)) { + BN_free(d); + goto err; + } + if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, + rsa->_method_mod_n)) { + BN_free(d); + goto err; + } + /* We MUST free d before any further use of rsa->d */ + BN_free(d); + } + + if (blinding) + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) + goto err; + + j = BN_bn2binpad(ret, buf, num); + + switch (padding) { + case RSA_PKCS1_PADDING: + r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num); + break; + case RSA_PKCS1_OAEP_PADDING: + r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); + break; + case RSA_SSLV23_PADDING: + r = RSA_padding_check_SSLv23(to, num, buf, j, num); + break; + case RSA_NO_PADDING: + memcpy(to, buf, (r = j)); + break; + default: + RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); err_clear_last_constant_time(1 & ~constant_time_msb(r)); - - err: - BN_CTX_end(ctx); - BN_CTX_free(ctx); - OPENSSL_clear_free(buf, num); - return r; -} - -/* signature verification */ -static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - BIGNUM *f, *ret; - int i, num = 0, r = -1; - unsigned char *buf = NULL; - BN_CTX *ctx = NULL; - - if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); - return -1; - } - - if (BN_ucmp(rsa->n, rsa->e) <= 0) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); - return -1; - } - - /* for large moduli, enforce exponent limit */ - if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { - if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); - return -1; - } - } - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - ret = BN_CTX_get(ctx); - num = BN_num_bytes(rsa->n); - buf = OPENSSL_malloc(num); - if (ret == NULL || buf == NULL) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * This check was for equality but PGP does evil things and chops off the - * top '0' bytes - */ - if (flen > num) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN); - goto err; - } - - if (BN_bin2bn(from, flen, f) == NULL) - goto err; - - if (BN_ucmp(f, rsa->n) >= 0) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, - RSA_R_DATA_TOO_LARGE_FOR_MODULUS); - goto err; - } - - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, - rsa->n, ctx)) - goto err; - - if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, - rsa->_method_mod_n)) - goto err; - - if ((padding == RSA_X931_PADDING) && ((bn_get_words(ret)[0] & 0xf) != 12)) - if (!BN_sub(ret, rsa->n, ret)) - goto err; - - i = BN_bn2binpad(ret, buf, num); - - switch (padding) { - case RSA_PKCS1_PADDING: - r = RSA_padding_check_PKCS1_type_1(to, num, buf, i, num); - break; - case RSA_X931_PADDING: - r = RSA_padding_check_X931(to, num, buf, i, num); - break; - case RSA_NO_PADDING: - memcpy(to, buf, (r = i)); - break; - default: - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); - goto err; - } - if (r < 0) - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_PADDING_CHECK_FAILED); - - err: + + err: BN_CTX_end(ctx); - BN_CTX_free(ctx); - OPENSSL_clear_free(buf, num); - return r; -} - -static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) -{ - BIGNUM *r1, *m1, *vrfy, *r2, *m[RSA_MAX_PRIME_NUM - 2]; - int ret = 0, i, ex_primes = 0, smooth = 0; - RSA_PRIME_INFO *pinfo; - - BN_CTX_start(ctx); - - r1 = BN_CTX_get(ctx); - r2 = BN_CTX_get(ctx); - m1 = BN_CTX_get(ctx); - vrfy = BN_CTX_get(ctx); - if (vrfy == NULL) - goto err; - - if (rsa->version == RSA_ASN1_VERSION_MULTI - && ((ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) <= 0 - || ex_primes > RSA_MAX_PRIME_NUM - 2)) - goto err; - - if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { - BIGNUM *factor = BN_new(); - - if (factor == NULL) - goto err; - - /* - * Make sure BN_mod_inverse in Montgomery initialization uses the - * BN_FLG_CONSTTIME flag - */ - if (!(BN_with_flags(factor, rsa->p, BN_FLG_CONSTTIME), - BN_MONT_CTX_set_locked(&rsa->_method_mod_p, rsa->lock, - factor, ctx)) - || !(BN_with_flags(factor, rsa->q, BN_FLG_CONSTTIME), - BN_MONT_CTX_set_locked(&rsa->_method_mod_q, rsa->lock, - factor, ctx))) { - BN_free(factor); - goto err; - } - for (i = 0; i < ex_primes; i++) { - pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); - BN_with_flags(factor, pinfo->r, BN_FLG_CONSTTIME); - if (!BN_MONT_CTX_set_locked(&pinfo->m, rsa->lock, factor, ctx)) { - BN_free(factor); - goto err; - } - } - /* - * We MUST free |factor| before any further use of the prime factors - */ - BN_free(factor); - - smooth = (ex_primes == 0) - && (rsa->meth->bn_mod_exp == BN_mod_exp_mont) - && (BN_num_bits(rsa->q) == BN_num_bits(rsa->p)); - } - - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, - rsa->n, ctx)) - goto err; - - if (smooth) { - /* - * Conversion from Montgomery domain, a.k.a. Montgomery reduction, - * accepts values in [0-m*2^w) range. w is m's bit width rounded up - * to limb width. So that at the very least if |I| is fully reduced, - * i.e. less than p*q, we can count on from-to round to perform - * below modulo operations on |I|. Unlike BN_mod it's constant time. - */ - if (/* m1 = I moq q */ - !bn_from_mont_fixed_top(m1, I, rsa->_method_mod_q, ctx) - || !bn_to_mont_fixed_top(m1, m1, rsa->_method_mod_q, ctx) - /* m1 = m1^dmq1 mod q */ - || !BN_mod_exp_mont_consttime(m1, m1, rsa->dmq1, rsa->q, ctx, - rsa->_method_mod_q) - /* r1 = I mod p */ - || !bn_from_mont_fixed_top(r1, I, rsa->_method_mod_p, ctx) - || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) - /* r1 = r1^dmp1 mod p */ - || !BN_mod_exp_mont_consttime(r1, r1, rsa->dmp1, rsa->p, ctx, - rsa->_method_mod_p) - /* r1 = (r1 - m1) mod p */ - /* - * bn_mod_sub_fixed_top is not regular modular subtraction, - * it can tolerate subtrahend to be larger than modulus, but - * not bit-wise wider. This makes up for uncommon q>p case, - * when |m1| can be larger than |rsa->p|. - */ - || !bn_mod_sub_fixed_top(r1, r1, m1, rsa->p) - - /* r1 = r1 * iqmp mod p */ - || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) - || !bn_mul_mont_fixed_top(r1, r1, rsa->iqmp, rsa->_method_mod_p, - ctx) - /* r0 = r1 * q + m1 */ - || !bn_mul_fixed_top(r0, r1, rsa->q, ctx) - || !bn_mod_add_fixed_top(r0, r0, m1, rsa->n)) - goto err; - - goto tail; - } - - /* compute I mod q */ - { - BIGNUM *c = BN_new(); - if (c == NULL) - goto err; - BN_with_flags(c, I, BN_FLG_CONSTTIME); - - if (!BN_mod(r1, c, rsa->q, ctx)) { - BN_free(c); - goto err; - } - - { - BIGNUM *dmq1 = BN_new(); - if (dmq1 == NULL) { - BN_free(c); - goto err; - } - BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); - - /* compute r1^dmq1 mod q */ - if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, - rsa->_method_mod_q)) { - BN_free(c); - BN_free(dmq1); - goto err; - } - /* We MUST free dmq1 before any further use of rsa->dmq1 */ - BN_free(dmq1); - } - - /* compute I mod p */ - if (!BN_mod(r1, c, rsa->p, ctx)) { - BN_free(c); - goto err; - } - /* We MUST free c before any further use of I */ - BN_free(c); - } - - { - BIGNUM *dmp1 = BN_new(); - if (dmp1 == NULL) - goto err; - BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); - - /* compute r1^dmp1 mod p */ - if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, - rsa->_method_mod_p)) { - BN_free(dmp1); - goto err; - } - /* We MUST free dmp1 before any further use of rsa->dmp1 */ - BN_free(dmp1); - } - - /* - * calculate m_i in multi-prime case - * - * TODO: - * 1. squash the following two loops and calculate |m_i| there. - * 2. remove cc and reuse |c|. - * 3. remove |dmq1| and |dmp1| in previous block and use |di|. - * - * If these things are done, the code will be more readable. - */ - if (ex_primes > 0) { - BIGNUM *di = BN_new(), *cc = BN_new(); - - if (cc == NULL || di == NULL) { - BN_free(cc); - BN_free(di); - goto err; - } - - for (i = 0; i < ex_primes; i++) { - /* prepare m_i */ - if ((m[i] = BN_CTX_get(ctx)) == NULL) { - BN_free(cc); - BN_free(di); - goto err; - } - - pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); - - /* prepare c and d_i */ - BN_with_flags(cc, I, BN_FLG_CONSTTIME); - BN_with_flags(di, pinfo->d, BN_FLG_CONSTTIME); - - if (!BN_mod(r1, cc, pinfo->r, ctx)) { - BN_free(cc); - BN_free(di); - goto err; - } - /* compute r1 ^ d_i mod r_i */ - if (!rsa->meth->bn_mod_exp(m[i], r1, di, pinfo->r, ctx, pinfo->m)) { - BN_free(cc); - BN_free(di); - goto err; - } - } - - BN_free(cc); - BN_free(di); - } - - if (!BN_sub(r0, r0, m1)) - goto err; - /* - * This will help stop the size of r0 increasing, which does affect the - * multiply if it optimised for a power of 2 size - */ - if (BN_is_negative(r0)) - if (!BN_add(r0, r0, rsa->p)) - goto err; - - if (!BN_mul(r1, r0, rsa->iqmp, ctx)) - goto err; - - { - BIGNUM *pr1 = BN_new(); - if (pr1 == NULL) - goto err; - BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); - - if (!BN_mod(r0, pr1, rsa->p, ctx)) { - BN_free(pr1); - goto err; - } - /* We MUST free pr1 before any further use of r1 */ - BN_free(pr1); - } - - /* - * If p < q it is occasionally possible for the correction of adding 'p' - * if r0 is negative above to leave the result still negative. This can - * break the private key operations: the following second correction - * should *always* correct this rare occurrence. This will *never* happen - * with OpenSSL generated keys because they ensure p > q [steve] - */ - if (BN_is_negative(r0)) - if (!BN_add(r0, r0, rsa->p)) - goto err; - if (!BN_mul(r1, r0, rsa->q, ctx)) - goto err; - if (!BN_add(r0, r1, m1)) - goto err; - - /* add m_i to m in multi-prime case */ - if (ex_primes > 0) { - BIGNUM *pr2 = BN_new(); - - if (pr2 == NULL) - goto err; - - for (i = 0; i < ex_primes; i++) { - pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); - if (!BN_sub(r1, m[i], r0)) { - BN_free(pr2); - goto err; - } - - if (!BN_mul(r2, r1, pinfo->t, ctx)) { - BN_free(pr2); - goto err; - } - - BN_with_flags(pr2, r2, BN_FLG_CONSTTIME); - - if (!BN_mod(r1, pr2, pinfo->r, ctx)) { - BN_free(pr2); - goto err; - } - - if (BN_is_negative(r1)) - if (!BN_add(r1, r1, pinfo->r)) { - BN_free(pr2); - goto err; - } - if (!BN_mul(r1, r1, pinfo->pp, ctx)) { - BN_free(pr2); - goto err; - } - if (!BN_add(r0, r0, r1)) { - BN_free(pr2); - goto err; - } - } - BN_free(pr2); - } - - tail: - if (rsa->e && rsa->n) { - if (rsa->meth->bn_mod_exp == BN_mod_exp_mont) { - if (!BN_mod_exp_mont(vrfy, r0, rsa->e, rsa->n, ctx, - rsa->_method_mod_n)) - goto err; - } else { - bn_correct_top(r0); - if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, - rsa->_method_mod_n)) - goto err; - } - /* - * If 'I' was greater than (or equal to) rsa->n, the operation will - * be equivalent to using 'I mod n'. However, the result of the - * verify will *always* be less than 'n' so we don't check for - * absolute equality, just congruency. - */ - if (!BN_sub(vrfy, vrfy, I)) - goto err; - if (BN_is_zero(vrfy)) { - bn_correct_top(r0); - ret = 1; - goto err; /* not actually error */ - } - if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) - goto err; - if (BN_is_negative(vrfy)) - if (!BN_add(vrfy, vrfy, rsa->n)) - goto err; - if (!BN_is_zero(vrfy)) { - /* - * 'I' and 'vrfy' aren't congruent mod n. Don't leak - * miscalculated CRT output, just do a raw (slower) mod_exp and - * return that instead. - */ - - BIGNUM *d = BN_new(); - if (d == NULL) - goto err; - BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); - - if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, - rsa->_method_mod_n)) { - BN_free(d); - goto err; - } - /* We MUST free d before any further use of rsa->d */ - BN_free(d); - } - } - /* - * It's unfortunate that we have to bn_correct_top(r0). What hopefully - * saves the day is that correction is highly unlike, and private key - * operations are customarily performed on blinded message. Which means - * that attacker won't observe correlation with chosen plaintext. - * Secondly, remaining code would still handle it in same computational - * time and even conceal memory access pattern around corrected top. - */ - bn_correct_top(r0); - ret = 1; - err: + BN_CTX_free(ctx); + OPENSSL_clear_free(buf, num); + return r; +} + +/* signature verification */ +static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + BIGNUM *f, *ret; + int i, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { + RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (BN_ucmp(rsa->n, rsa->e) <= 0) { + RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + + /* for large moduli, enforce exponent limit */ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { + if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { + RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (ret == NULL || buf == NULL) { + RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * This check was for equality but PGP does evil things and chops off the + * top '0' bytes + */ + if (flen > num) { + RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + if (BN_bin2bn(from, flen, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, + RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, + rsa->n, ctx)) + goto err; + + if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + + if ((padding == RSA_X931_PADDING) && ((bn_get_words(ret)[0] & 0xf) != 12)) + if (!BN_sub(ret, rsa->n, ret)) + goto err; + + i = BN_bn2binpad(ret, buf, num); + + switch (padding) { + case RSA_PKCS1_PADDING: + r = RSA_padding_check_PKCS1_type_1(to, num, buf, i, num); + break; + case RSA_X931_PADDING: + r = RSA_padding_check_X931(to, num, buf, i, num); + break; + case RSA_NO_PADDING: + memcpy(to, buf, (r = i)); + break; + default: + RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_PADDING_CHECK_FAILED); + + err: BN_CTX_end(ctx); - return ret; -} - -static int rsa_ossl_init(RSA *rsa) -{ - rsa->flags |= RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE; - return 1; -} - -static int rsa_ossl_finish(RSA *rsa) -{ - int i; - RSA_PRIME_INFO *pinfo; - - BN_MONT_CTX_free(rsa->_method_mod_n); - BN_MONT_CTX_free(rsa->_method_mod_p); - BN_MONT_CTX_free(rsa->_method_mod_q); - for (i = 0; i < sk_RSA_PRIME_INFO_num(rsa->prime_infos); i++) { - pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); - BN_MONT_CTX_free(pinfo->m); - } - return 1; -} + BN_CTX_free(ctx); + OPENSSL_clear_free(buf, num); + return r; +} + +static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) +{ + BIGNUM *r1, *m1, *vrfy, *r2, *m[RSA_MAX_PRIME_NUM - 2]; + int ret = 0, i, ex_primes = 0, smooth = 0; + RSA_PRIME_INFO *pinfo; + + BN_CTX_start(ctx); + + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + m1 = BN_CTX_get(ctx); + vrfy = BN_CTX_get(ctx); + if (vrfy == NULL) + goto err; + + if (rsa->version == RSA_ASN1_VERSION_MULTI + && ((ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) <= 0 + || ex_primes > RSA_MAX_PRIME_NUM - 2)) + goto err; + + if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { + BIGNUM *factor = BN_new(); + + if (factor == NULL) + goto err; + + /* + * Make sure BN_mod_inverse in Montgomery initialization uses the + * BN_FLG_CONSTTIME flag + */ + if (!(BN_with_flags(factor, rsa->p, BN_FLG_CONSTTIME), + BN_MONT_CTX_set_locked(&rsa->_method_mod_p, rsa->lock, + factor, ctx)) + || !(BN_with_flags(factor, rsa->q, BN_FLG_CONSTTIME), + BN_MONT_CTX_set_locked(&rsa->_method_mod_q, rsa->lock, + factor, ctx))) { + BN_free(factor); + goto err; + } + for (i = 0; i < ex_primes; i++) { + pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); + BN_with_flags(factor, pinfo->r, BN_FLG_CONSTTIME); + if (!BN_MONT_CTX_set_locked(&pinfo->m, rsa->lock, factor, ctx)) { + BN_free(factor); + goto err; + } + } + /* + * We MUST free |factor| before any further use of the prime factors + */ + BN_free(factor); + + smooth = (ex_primes == 0) + && (rsa->meth->bn_mod_exp == BN_mod_exp_mont) + && (BN_num_bits(rsa->q) == BN_num_bits(rsa->p)); + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, rsa->lock, + rsa->n, ctx)) + goto err; + + if (smooth) { + /* + * Conversion from Montgomery domain, a.k.a. Montgomery reduction, + * accepts values in [0-m*2^w) range. w is m's bit width rounded up + * to limb width. So that at the very least if |I| is fully reduced, + * i.e. less than p*q, we can count on from-to round to perform + * below modulo operations on |I|. Unlike BN_mod it's constant time. + */ + if (/* m1 = I moq q */ + !bn_from_mont_fixed_top(m1, I, rsa->_method_mod_q, ctx) + || !bn_to_mont_fixed_top(m1, m1, rsa->_method_mod_q, ctx) + /* m1 = m1^dmq1 mod q */ + || !BN_mod_exp_mont_consttime(m1, m1, rsa->dmq1, rsa->q, ctx, + rsa->_method_mod_q) + /* r1 = I mod p */ + || !bn_from_mont_fixed_top(r1, I, rsa->_method_mod_p, ctx) + || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) + /* r1 = r1^dmp1 mod p */ + || !BN_mod_exp_mont_consttime(r1, r1, rsa->dmp1, rsa->p, ctx, + rsa->_method_mod_p) + /* r1 = (r1 - m1) mod p */ + /* + * bn_mod_sub_fixed_top is not regular modular subtraction, + * it can tolerate subtrahend to be larger than modulus, but + * not bit-wise wider. This makes up for uncommon q>p case, + * when |m1| can be larger than |rsa->p|. + */ + || !bn_mod_sub_fixed_top(r1, r1, m1, rsa->p) + + /* r1 = r1 * iqmp mod p */ + || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) + || !bn_mul_mont_fixed_top(r1, r1, rsa->iqmp, rsa->_method_mod_p, + ctx) + /* r0 = r1 * q + m1 */ + || !bn_mul_fixed_top(r0, r1, rsa->q, ctx) + || !bn_mod_add_fixed_top(r0, r0, m1, rsa->n)) + goto err; + + goto tail; + } + + /* compute I mod q */ + { + BIGNUM *c = BN_new(); + if (c == NULL) + goto err; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + + if (!BN_mod(r1, c, rsa->q, ctx)) { + BN_free(c); + goto err; + } + + { + BIGNUM *dmq1 = BN_new(); + if (dmq1 == NULL) { + BN_free(c); + goto err; + } + BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); + + /* compute r1^dmq1 mod q */ + if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, + rsa->_method_mod_q)) { + BN_free(c); + BN_free(dmq1); + goto err; + } + /* We MUST free dmq1 before any further use of rsa->dmq1 */ + BN_free(dmq1); + } + + /* compute I mod p */ + if (!BN_mod(r1, c, rsa->p, ctx)) { + BN_free(c); + goto err; + } + /* We MUST free c before any further use of I */ + BN_free(c); + } + + { + BIGNUM *dmp1 = BN_new(); + if (dmp1 == NULL) + goto err; + BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); + + /* compute r1^dmp1 mod p */ + if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, + rsa->_method_mod_p)) { + BN_free(dmp1); + goto err; + } + /* We MUST free dmp1 before any further use of rsa->dmp1 */ + BN_free(dmp1); + } + + /* + * calculate m_i in multi-prime case + * + * TODO: + * 1. squash the following two loops and calculate |m_i| there. + * 2. remove cc and reuse |c|. + * 3. remove |dmq1| and |dmp1| in previous block and use |di|. + * + * If these things are done, the code will be more readable. + */ + if (ex_primes > 0) { + BIGNUM *di = BN_new(), *cc = BN_new(); + + if (cc == NULL || di == NULL) { + BN_free(cc); + BN_free(di); + goto err; + } + + for (i = 0; i < ex_primes; i++) { + /* prepare m_i */ + if ((m[i] = BN_CTX_get(ctx)) == NULL) { + BN_free(cc); + BN_free(di); + goto err; + } + + pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); + + /* prepare c and d_i */ + BN_with_flags(cc, I, BN_FLG_CONSTTIME); + BN_with_flags(di, pinfo->d, BN_FLG_CONSTTIME); + + if (!BN_mod(r1, cc, pinfo->r, ctx)) { + BN_free(cc); + BN_free(di); + goto err; + } + /* compute r1 ^ d_i mod r_i */ + if (!rsa->meth->bn_mod_exp(m[i], r1, di, pinfo->r, ctx, pinfo->m)) { + BN_free(cc); + BN_free(di); + goto err; + } + } + + BN_free(cc); + BN_free(di); + } + + if (!BN_sub(r0, r0, m1)) + goto err; + /* + * This will help stop the size of r0 increasing, which does affect the + * multiply if it optimised for a power of 2 size + */ + if (BN_is_negative(r0)) + if (!BN_add(r0, r0, rsa->p)) + goto err; + + if (!BN_mul(r1, r0, rsa->iqmp, ctx)) + goto err; + + { + BIGNUM *pr1 = BN_new(); + if (pr1 == NULL) + goto err; + BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); + + if (!BN_mod(r0, pr1, rsa->p, ctx)) { + BN_free(pr1); + goto err; + } + /* We MUST free pr1 before any further use of r1 */ + BN_free(pr1); + } + + /* + * If p < q it is occasionally possible for the correction of adding 'p' + * if r0 is negative above to leave the result still negative. This can + * break the private key operations: the following second correction + * should *always* correct this rare occurrence. This will *never* happen + * with OpenSSL generated keys because they ensure p > q [steve] + */ + if (BN_is_negative(r0)) + if (!BN_add(r0, r0, rsa->p)) + goto err; + if (!BN_mul(r1, r0, rsa->q, ctx)) + goto err; + if (!BN_add(r0, r1, m1)) + goto err; + + /* add m_i to m in multi-prime case */ + if (ex_primes > 0) { + BIGNUM *pr2 = BN_new(); + + if (pr2 == NULL) + goto err; + + for (i = 0; i < ex_primes; i++) { + pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); + if (!BN_sub(r1, m[i], r0)) { + BN_free(pr2); + goto err; + } + + if (!BN_mul(r2, r1, pinfo->t, ctx)) { + BN_free(pr2); + goto err; + } + + BN_with_flags(pr2, r2, BN_FLG_CONSTTIME); + + if (!BN_mod(r1, pr2, pinfo->r, ctx)) { + BN_free(pr2); + goto err; + } + + if (BN_is_negative(r1)) + if (!BN_add(r1, r1, pinfo->r)) { + BN_free(pr2); + goto err; + } + if (!BN_mul(r1, r1, pinfo->pp, ctx)) { + BN_free(pr2); + goto err; + } + if (!BN_add(r0, r0, r1)) { + BN_free(pr2); + goto err; + } + } + BN_free(pr2); + } + + tail: + if (rsa->e && rsa->n) { + if (rsa->meth->bn_mod_exp == BN_mod_exp_mont) { + if (!BN_mod_exp_mont(vrfy, r0, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + } else { + bn_correct_top(r0); + if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + } + /* + * If 'I' was greater than (or equal to) rsa->n, the operation will + * be equivalent to using 'I mod n'. However, the result of the + * verify will *always* be less than 'n' so we don't check for + * absolute equality, just congruency. + */ + if (!BN_sub(vrfy, vrfy, I)) + goto err; + if (BN_is_zero(vrfy)) { + bn_correct_top(r0); + ret = 1; + goto err; /* not actually error */ + } + if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) + goto err; + if (BN_is_negative(vrfy)) + if (!BN_add(vrfy, vrfy, rsa->n)) + goto err; + if (!BN_is_zero(vrfy)) { + /* + * 'I' and 'vrfy' aren't congruent mod n. Don't leak + * miscalculated CRT output, just do a raw (slower) mod_exp and + * return that instead. + */ + + BIGNUM *d = BN_new(); + if (d == NULL) + goto err; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + + if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, + rsa->_method_mod_n)) { + BN_free(d); + goto err; + } + /* We MUST free d before any further use of rsa->d */ + BN_free(d); + } + } + /* + * It's unfortunate that we have to bn_correct_top(r0). What hopefully + * saves the day is that correction is highly unlike, and private key + * operations are customarily performed on blinded message. Which means + * that attacker won't observe correlation with chosen plaintext. + * Secondly, remaining code would still handle it in same computational + * time and even conceal memory access pattern around corrected top. + */ + bn_correct_top(r0); + ret = 1; + err: + BN_CTX_end(ctx); + return ret; +} + +static int rsa_ossl_init(RSA *rsa) +{ + rsa->flags |= RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE; + return 1; +} + +static int rsa_ossl_finish(RSA *rsa) +{ + int i; + RSA_PRIME_INFO *pinfo; + + BN_MONT_CTX_free(rsa->_method_mod_n); + BN_MONT_CTX_free(rsa->_method_mod_p); + BN_MONT_CTX_free(rsa->_method_mod_q); + for (i = 0; i < sk_RSA_PRIME_INFO_num(rsa->prime_infos); i++) { + pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); + BN_MONT_CTX_free(pinfo->m); + } + return 1; +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_pk1.c b/contrib/libs/openssl/crypto/rsa/rsa_pk1.c index a3d0b7cef8..fa09257121 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_pk1.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_pk1.c @@ -1,231 +1,231 @@ -/* +/* * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + #include "internal/constant_time.h" - -#include <stdio.h> -#include "internal/cryptlib.h" -#include <openssl/bn.h> -#include <openssl/rsa.h> -#include <openssl/rand.h> - -int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, - const unsigned char *from, int flen) -{ - int j; - unsigned char *p; - - if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return 0; - } - - p = (unsigned char *)to; - - *(p++) = 0; - *(p++) = 1; /* Private Key BT (Block Type) */ - - /* pad out with 0xff data */ - j = tlen - 3 - flen; - memset(p, 0xff, j); - p += j; - *(p++) = '\0'; - memcpy(p, from, (unsigned int)flen); - return 1; -} - -int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, - const unsigned char *from, int flen, - int num) -{ - int i, j; - const unsigned char *p; - - p = from; - - /* - * The format is - * 00 || 01 || PS || 00 || D - * PS - padding string, at least 8 bytes of FF - * D - data. - */ - + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/bn.h> +#include <openssl/rsa.h> +#include <openssl/rand.h> + +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int j; + unsigned char *p; + + if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + p = (unsigned char *)to; + + *(p++) = 0; + *(p++) = 1; /* Private Key BT (Block Type) */ + + /* pad out with 0xff data */ + j = tlen - 3 - flen; + memset(p, 0xff, j); + p += j; + *(p++) = '\0'; + memcpy(p, from, (unsigned int)flen); + return 1; +} + +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num) +{ + int i, j; + const unsigned char *p; + + p = from; + + /* + * The format is + * 00 || 01 || PS || 00 || D + * PS - padding string, at least 8 bytes of FF + * D - data. + */ + if (num < RSA_PKCS1_PADDING_SIZE) - return -1; - - /* Accept inputs with and without the leading 0-byte. */ - if (num == flen) { - if ((*p++) != 0x00) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_INVALID_PADDING); - return -1; - } - flen--; - } - - if ((num != (flen + 1)) || (*(p++) != 0x01)) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_BLOCK_TYPE_IS_NOT_01); - return -1; - } - - /* scan over padding data */ - j = flen - 1; /* one for type. */ - for (i = 0; i < j; i++) { - if (*p != 0xff) { /* should decrypt to 0xff */ - if (*p == 0) { - p++; - break; - } else { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_BAD_FIXED_HEADER_DECRYPT); - return -1; - } - } - p++; - } - - if (i == j) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_NULL_BEFORE_BLOCK_MISSING); - return -1; - } - - if (i < 8) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_BAD_PAD_BYTE_COUNT); - return -1; - } - i++; /* Skip over the '\0' */ - j -= i; - if (j > tlen) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, RSA_R_DATA_TOO_LARGE); - return -1; - } - memcpy(to, p, (unsigned int)j); - - return j; -} - -int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, - const unsigned char *from, int flen) -{ - int i, j; - unsigned char *p; - + return -1; + + /* Accept inputs with and without the leading 0-byte. */ + if (num == flen) { + if ((*p++) != 0x00) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_INVALID_PADDING); + return -1; + } + flen--; + } + + if ((num != (flen + 1)) || (*(p++) != 0x01)) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_BLOCK_TYPE_IS_NOT_01); + return -1; + } + + /* scan over padding data */ + j = flen - 1; /* one for type. */ + for (i = 0; i < j; i++) { + if (*p != 0xff) { /* should decrypt to 0xff */ + if (*p == 0) { + p++; + break; + } else { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_BAD_FIXED_HEADER_DECRYPT); + return -1; + } + } + p++; + } + + if (i == j) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_NULL_BEFORE_BLOCK_MISSING); + return -1; + } + + if (i < 8) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_BAD_PAD_BYTE_COUNT); + return -1; + } + i++; /* Skip over the '\0' */ + j -= i; + if (j > tlen) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, RSA_R_DATA_TOO_LARGE); + return -1; + } + memcpy(to, p, (unsigned int)j); + + return j; +} + +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int i, j; + unsigned char *p; + if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return 0; - } - - p = (unsigned char *)to; - - *(p++) = 0; - *(p++) = 2; /* Public Key BT (Block Type) */ - - /* pad out with non-zero random data */ - j = tlen - 3 - flen; - - if (RAND_bytes(p, j) <= 0) - return 0; - for (i = 0; i < j; i++) { - if (*p == '\0') - do { - if (RAND_bytes(p, 1) <= 0) - return 0; - } while (*p == '\0'); - p++; - } - - *(p++) = '\0'; - - memcpy(p, from, (unsigned int)flen); - return 1; -} - -int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, - const unsigned char *from, int flen, - int num) -{ - int i; - /* |em| is the encoded message, zero-padded to exactly |num| bytes */ - unsigned char *em = NULL; - unsigned int good, found_zero_byte, mask; - int zero_index = 0, msg_index, mlen = -1; - - if (tlen <= 0 || flen <= 0) - return -1; - - /* - * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard", - * section 7.2.2. - */ - + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + p = (unsigned char *)to; + + *(p++) = 0; + *(p++) = 2; /* Public Key BT (Block Type) */ + + /* pad out with non-zero random data */ + j = tlen - 3 - flen; + + if (RAND_bytes(p, j) <= 0) + return 0; + for (i = 0; i < j; i++) { + if (*p == '\0') + do { + if (RAND_bytes(p, 1) <= 0) + return 0; + } while (*p == '\0'); + p++; + } + + *(p++) = '\0'; + + memcpy(p, from, (unsigned int)flen); + return 1; +} + +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num) +{ + int i; + /* |em| is the encoded message, zero-padded to exactly |num| bytes */ + unsigned char *em = NULL; + unsigned int good, found_zero_byte, mask; + int zero_index = 0, msg_index, mlen = -1; + + if (tlen <= 0 || flen <= 0) + return -1; + + /* + * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard", + * section 7.2.2. + */ + if (flen > num || num < RSA_PKCS1_PADDING_SIZE) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, - RSA_R_PKCS_DECODING_ERROR); - return -1; - } - - em = OPENSSL_malloc(num); - if (em == NULL) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE); - return -1; - } - /* - * Caller is encouraged to pass zero-padded message created with - * BN_bn2binpad. Trouble is that since we can't read out of |from|'s - * bounds, it's impossible to have an invariant memory access pattern - * in case |from| was not zero-padded in advance. - */ - for (from += flen, em += num, i = 0; i < num; i++) { - mask = ~constant_time_is_zero(flen); - flen -= 1 & mask; - from -= 1 & mask; - *--em = *from & mask; - } - + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, + RSA_R_PKCS_DECODING_ERROR); + return -1; + } + + em = OPENSSL_malloc(num); + if (em == NULL) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE); + return -1; + } + /* + * Caller is encouraged to pass zero-padded message created with + * BN_bn2binpad. Trouble is that since we can't read out of |from|'s + * bounds, it's impossible to have an invariant memory access pattern + * in case |from| was not zero-padded in advance. + */ + for (from += flen, em += num, i = 0; i < num; i++) { + mask = ~constant_time_is_zero(flen); + flen -= 1 & mask; + from -= 1 & mask; + *--em = *from & mask; + } + good = constant_time_is_zero(em[0]); good &= constant_time_eq(em[1], 2); - - /* scan over padding data */ - found_zero_byte = 0; - for (i = 2; i < num; i++) { + + /* scan over padding data */ + found_zero_byte = 0; + for (i = 2; i < num; i++) { unsigned int equals0 = constant_time_is_zero(em[i]); - - zero_index = constant_time_select_int(~found_zero_byte & equals0, - i, zero_index); - found_zero_byte |= equals0; - } - - /* + + zero_index = constant_time_select_int(~found_zero_byte & equals0, + i, zero_index); + found_zero_byte |= equals0; + } + + /* * PS must be at least 8 bytes long, and it starts two bytes into |em|. - * If we never found a 0-byte, then |zero_index| is 0 and the check - * also fails. - */ - good &= constant_time_ge(zero_index, 2 + 8); - - /* - * Skip the zero byte. This is incorrect if we never found a zero-byte - * but in this case we also do not copy the message out. - */ - msg_index = zero_index + 1; - mlen = num - msg_index; - - /* - * For good measure, do this check in constant time as well. - */ - good &= constant_time_ge(tlen, mlen); - - /* + * If we never found a 0-byte, then |zero_index| is 0 and the check + * also fails. + */ + good &= constant_time_ge(zero_index, 2 + 8); + + /* + * Skip the zero byte. This is incorrect if we never found a zero-byte + * but in this case we also do not copy the message out. + */ + msg_index = zero_index + 1; + mlen = num - msg_index; + + /* + * For good measure, do this check in constant time as well. + */ + good &= constant_time_ge(tlen, mlen); + + /* * Move the result in-place by |num|-RSA_PKCS1_PADDING_SIZE-|mlen| bytes to the left. * Then if |good| move |mlen| bytes from |em|+RSA_PKCS1_PADDING_SIZE to |to|. * Otherwise leave |to| unchanged. @@ -234,22 +234,22 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, * parts of the buffer multiple times based on the bits set in the real * length. Clear bits do a non-copy with identical access pattern. * The loop below has overall complexity of O(N*log(N)). - */ + */ tlen = constant_time_select_int(constant_time_lt(num - RSA_PKCS1_PADDING_SIZE, tlen), num - RSA_PKCS1_PADDING_SIZE, tlen); for (msg_index = 1; msg_index < num - RSA_PKCS1_PADDING_SIZE; msg_index <<= 1) { mask = ~constant_time_eq(msg_index & (num - RSA_PKCS1_PADDING_SIZE - mlen), 0); for (i = RSA_PKCS1_PADDING_SIZE; i < num - msg_index; i++) em[i] = constant_time_select_8(mask, em[i + msg_index], em[i]); - } + } for (i = 0; i < tlen; i++) { mask = good & constant_time_lt(i, mlen); to[i] = constant_time_select_8(mask, em[i + RSA_PKCS1_PADDING_SIZE], to[i]); } - - OPENSSL_clear_free(em, num); - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR); - err_clear_last_constant_time(1 & good); - - return constant_time_select_int(good, mlen, -1); -} + + OPENSSL_clear_free(em, num); + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR); + err_clear_last_constant_time(1 & good); + + return constant_time_select_int(good, mlen, -1); +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_pmeth.c b/contrib/libs/openssl/crypto/rsa/rsa_pmeth.c index 0eb21c8af9..2528da454e 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_pmeth.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_pmeth.c @@ -1,861 +1,861 @@ -/* +/* * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + #include "internal/constant_time.h" -#include <stdio.h> -#include "internal/cryptlib.h" -#include <openssl/asn1t.h> -#include <openssl/x509.h> -#include <openssl/rsa.h> -#include <openssl/bn.h> -#include <openssl/evp.h> -#include <openssl/x509v3.h> -#include <openssl/cms.h> +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/asn1t.h> +#include <openssl/x509.h> +#include <openssl/rsa.h> +#include <openssl/bn.h> +#include <openssl/evp.h> +#include <openssl/x509v3.h> +#include <openssl/cms.h> #include "crypto/evp.h" #include "rsa_local.h" - -/* RSA pkey context structure */ - -typedef struct { - /* Key gen parameters */ - int nbits; - BIGNUM *pub_exp; - int primes; - /* Keygen callback info */ - int gentmp[2]; - /* RSA padding mode */ - int pad_mode; - /* message digest */ - const EVP_MD *md; - /* message digest for MGF1 */ - const EVP_MD *mgf1md; - /* PSS salt length */ - int saltlen; - /* Minimum salt length or -1 if no PSS parameter restriction */ - int min_saltlen; - /* Temp buffer */ - unsigned char *tbuf; - /* OAEP label */ - unsigned char *oaep_label; - size_t oaep_labellen; -} RSA_PKEY_CTX; - -/* True if PSS parameters are restricted */ -#define rsa_pss_restricted(rctx) (rctx->min_saltlen != -1) - -static int pkey_rsa_init(EVP_PKEY_CTX *ctx) -{ - RSA_PKEY_CTX *rctx = OPENSSL_zalloc(sizeof(*rctx)); - - if (rctx == NULL) - return 0; + +/* RSA pkey context structure */ + +typedef struct { + /* Key gen parameters */ + int nbits; + BIGNUM *pub_exp; + int primes; + /* Keygen callback info */ + int gentmp[2]; + /* RSA padding mode */ + int pad_mode; + /* message digest */ + const EVP_MD *md; + /* message digest for MGF1 */ + const EVP_MD *mgf1md; + /* PSS salt length */ + int saltlen; + /* Minimum salt length or -1 if no PSS parameter restriction */ + int min_saltlen; + /* Temp buffer */ + unsigned char *tbuf; + /* OAEP label */ + unsigned char *oaep_label; + size_t oaep_labellen; +} RSA_PKEY_CTX; + +/* True if PSS parameters are restricted */ +#define rsa_pss_restricted(rctx) (rctx->min_saltlen != -1) + +static int pkey_rsa_init(EVP_PKEY_CTX *ctx) +{ + RSA_PKEY_CTX *rctx = OPENSSL_zalloc(sizeof(*rctx)); + + if (rctx == NULL) + return 0; rctx->nbits = 2048; - rctx->primes = RSA_DEFAULT_PRIME_NUM; - if (pkey_ctx_is_pss(ctx)) - rctx->pad_mode = RSA_PKCS1_PSS_PADDING; - else - rctx->pad_mode = RSA_PKCS1_PADDING; - /* Maximum for sign, auto for verify */ - rctx->saltlen = RSA_PSS_SALTLEN_AUTO; - rctx->min_saltlen = -1; - ctx->data = rctx; - ctx->keygen_info = rctx->gentmp; - ctx->keygen_info_count = 2; - - return 1; -} - -static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - RSA_PKEY_CTX *dctx, *sctx; - - if (!pkey_rsa_init(dst)) - return 0; - sctx = src->data; - dctx = dst->data; - dctx->nbits = sctx->nbits; - if (sctx->pub_exp) { - dctx->pub_exp = BN_dup(sctx->pub_exp); - if (!dctx->pub_exp) - return 0; - } - dctx->pad_mode = sctx->pad_mode; - dctx->md = sctx->md; - dctx->mgf1md = sctx->mgf1md; - if (sctx->oaep_label) { - OPENSSL_free(dctx->oaep_label); - dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen); - if (!dctx->oaep_label) - return 0; - dctx->oaep_labellen = sctx->oaep_labellen; - } - return 1; -} - -static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) -{ - if (ctx->tbuf != NULL) - return 1; - if ((ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey))) == NULL) { - RSAerr(RSA_F_SETUP_TBUF, ERR_R_MALLOC_FAILURE); - return 0; - } - return 1; -} - -static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) -{ - RSA_PKEY_CTX *rctx = ctx->data; - if (rctx) { - BN_free(rctx->pub_exp); - OPENSSL_free(rctx->tbuf); - OPENSSL_free(rctx->oaep_label); - OPENSSL_free(rctx); - } -} - -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(0, - tbs, tbslen, sig, &sltmp, rsa); - - if (ret <= 0) - return ret; - ret = sltmp; - } else if (rctx->pad_mode == RSA_X931_PADDING) { - if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) { - RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL); - return -1; - } - if (!setup_tbuf(rctx, ctx)) { - RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE); - 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; -} - -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; -} - -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 (tbslen != (size_t)EVP_MD_size(rctx->md)) { - RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); - return -1; - } - 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; - -} - -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; -} - -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); - } + rctx->primes = RSA_DEFAULT_PRIME_NUM; + if (pkey_ctx_is_pss(ctx)) + rctx->pad_mode = RSA_PKCS1_PSS_PADDING; + else + rctx->pad_mode = RSA_PKCS1_PADDING; + /* Maximum for sign, auto for verify */ + rctx->saltlen = RSA_PSS_SALTLEN_AUTO; + rctx->min_saltlen = -1; + ctx->data = rctx; + ctx->keygen_info = rctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; +} + +static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + RSA_PKEY_CTX *dctx, *sctx; + + if (!pkey_rsa_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->nbits = sctx->nbits; + if (sctx->pub_exp) { + dctx->pub_exp = BN_dup(sctx->pub_exp); + if (!dctx->pub_exp) + return 0; + } + dctx->pad_mode = sctx->pad_mode; + dctx->md = sctx->md; + dctx->mgf1md = sctx->mgf1md; + if (sctx->oaep_label) { + OPENSSL_free(dctx->oaep_label); + dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen); + if (!dctx->oaep_label) + return 0; + dctx->oaep_labellen = sctx->oaep_labellen; + } + return 1; +} + +static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) +{ + if (ctx->tbuf != NULL) + return 1; + if ((ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey))) == NULL) { + RSAerr(RSA_F_SETUP_TBUF, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) +{ + RSA_PKEY_CTX *rctx = ctx->data; + if (rctx) { + BN_free(rctx->pub_exp); + OPENSSL_free(rctx->tbuf); + OPENSSL_free(rctx->oaep_label); + OPENSSL_free(rctx); + } +} + +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(0, + tbs, tbslen, sig, &sltmp, rsa); + + if (ret <= 0) + return ret; + ret = sltmp; + } else if (rctx->pad_mode == RSA_X931_PADDING) { + if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) { + RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + if (!setup_tbuf(rctx, ctx)) { + RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE); + 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; +} + +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; +} + +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 (tbslen != (size_t)EVP_MD_size(rctx->md)) { + RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); + return -1; + } + 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; + +} + +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; +} + +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; -} - -static int check_padding_md(const EVP_MD *md, int padding) -{ - int mdnid; - - if (!md) - return 1; - - mdnid = EVP_MD_type(md); - - if (padding == RSA_NO_PADDING) { - RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE); - return 0; - } - - if (padding == RSA_X931_PADDING) { - if (RSA_X931_hash_id(mdnid) == -1) { - RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_X931_DIGEST); - return 0; - } - } else { - switch(mdnid) { - /* List of all supported RSA digests */ - case NID_sha1: - case NID_sha224: - case NID_sha256: - case NID_sha384: - case NID_sha512: - case NID_md5: - case NID_md5_sha1: - case NID_md2: - case NID_md4: - case NID_mdc2: - case NID_ripemd160: - case NID_sha3_224: - case NID_sha3_256: - case NID_sha3_384: - case NID_sha3_512: - return 1; - - default: - RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_DIGEST); - return 0; - - } - } - - return 1; -} - -static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - RSA_PKEY_CTX *rctx = ctx->data; - - switch (type) { - case EVP_PKEY_CTRL_RSA_PADDING: - if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) { - if (!check_padding_md(rctx->md, p1)) - return 0; - if (p1 == RSA_PKCS1_PSS_PADDING) { - if (!(ctx->operation & - (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) - goto bad_pad; - if (!rctx->md) - rctx->md = EVP_sha1(); - } else if (pkey_ctx_is_pss(ctx)) { - goto bad_pad; - } - if (p1 == RSA_PKCS1_OAEP_PADDING) { - if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) - goto bad_pad; - if (!rctx->md) - rctx->md = EVP_sha1(); - } - rctx->pad_mode = p1; - return 1; - } - bad_pad: - RSAerr(RSA_F_PKEY_RSA_CTRL, - RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); - return -2; - - case EVP_PKEY_CTRL_GET_RSA_PADDING: - *(int *)p2 = rctx->pad_mode; - return 1; - - case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: - case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: - if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); - return -2; - } - if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { - *(int *)p2 = rctx->saltlen; - } else { - if (p1 < RSA_PSS_SALTLEN_MAX) - return -2; - if (rsa_pss_restricted(rctx)) { - if (p1 == RSA_PSS_SALTLEN_AUTO - && ctx->operation == EVP_PKEY_OP_VERIFY) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); - return -2; - } - if ((p1 == RSA_PSS_SALTLEN_DIGEST - && rctx->min_saltlen > EVP_MD_size(rctx->md)) - || (p1 >= 0 && p1 < rctx->min_saltlen)) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_PSS_SALTLEN_TOO_SMALL); - return 0; - } - } - rctx->saltlen = p1; - } - return 1; - - case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: - if (p1 < RSA_MIN_MODULUS_BITS) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL); - return -2; - } - rctx->nbits = p1; - return 1; - - case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: - if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || BN_is_one((BIGNUM *)p2)) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_BAD_E_VALUE); - return -2; - } - BN_free(rctx->pub_exp); - rctx->pub_exp = p2; - return 1; - - case EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES: - if (p1 < RSA_DEFAULT_PRIME_NUM || p1 > RSA_MAX_PRIME_NUM) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_PRIME_NUM_INVALID); - return -2; - } - rctx->primes = p1; - return 1; - - case EVP_PKEY_CTRL_RSA_OAEP_MD: - case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: - if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); - return -2; - } - if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) - *(const EVP_MD **)p2 = rctx->md; - else - rctx->md = p2; - return 1; - - case EVP_PKEY_CTRL_MD: - if (!check_padding_md(p2, rctx->pad_mode)) - return 0; - if (rsa_pss_restricted(rctx)) { - if (EVP_MD_type(rctx->md) == EVP_MD_type(p2)) - return 1; - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_DIGEST_NOT_ALLOWED); - return 0; - } - rctx->md = p2; - return 1; - - case EVP_PKEY_CTRL_GET_MD: - *(const EVP_MD **)p2 = rctx->md; - return 1; - - case EVP_PKEY_CTRL_RSA_MGF1_MD: - case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: - if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING - && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD); - return -2; - } - if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { - if (rctx->mgf1md) - *(const EVP_MD **)p2 = rctx->mgf1md; - else - *(const EVP_MD **)p2 = rctx->md; - } else { - if (rsa_pss_restricted(rctx)) { - if (EVP_MD_type(rctx->mgf1md) == EVP_MD_type(p2)) - return 1; - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_MGF1_DIGEST_NOT_ALLOWED); - return 0; - } - rctx->mgf1md = p2; - } - return 1; - - case EVP_PKEY_CTRL_RSA_OAEP_LABEL: - if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); - return -2; - } - OPENSSL_free(rctx->oaep_label); - if (p2 && p1 > 0) { - rctx->oaep_label = p2; - rctx->oaep_labellen = p1; - } else { - rctx->oaep_label = NULL; - rctx->oaep_labellen = 0; - } - return 1; - - case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: - if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); - return -2; - } - *(unsigned char **)p2 = rctx->oaep_label; - return rctx->oaep_labellen; - - case EVP_PKEY_CTRL_DIGESTINIT: - case EVP_PKEY_CTRL_PKCS7_SIGN: -#ifndef OPENSSL_NO_CMS - case EVP_PKEY_CTRL_CMS_SIGN: -#endif - return 1; - - case EVP_PKEY_CTRL_PKCS7_ENCRYPT: - case EVP_PKEY_CTRL_PKCS7_DECRYPT: -#ifndef OPENSSL_NO_CMS - case EVP_PKEY_CTRL_CMS_DECRYPT: - case EVP_PKEY_CTRL_CMS_ENCRYPT: -#endif - if (!pkey_ctx_is_pss(ctx)) - return 1; - /* fall through */ - case EVP_PKEY_CTRL_PEER_KEY: - RSAerr(RSA_F_PKEY_RSA_CTRL, - RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - - default: - return -2; - - } -} - -static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (value == NULL) { - RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); - return 0; - } - if (strcmp(type, "rsa_padding_mode") == 0) { - int pm; - - if (strcmp(value, "pkcs1") == 0) { - pm = RSA_PKCS1_PADDING; - } else if (strcmp(value, "sslv23") == 0) { - pm = RSA_SSLV23_PADDING; - } else if (strcmp(value, "none") == 0) { - pm = RSA_NO_PADDING; - } else if (strcmp(value, "oeap") == 0) { - pm = RSA_PKCS1_OAEP_PADDING; - } else if (strcmp(value, "oaep") == 0) { - pm = RSA_PKCS1_OAEP_PADDING; - } else if (strcmp(value, "x931") == 0) { - pm = RSA_X931_PADDING; - } else if (strcmp(value, "pss") == 0) { - pm = RSA_PKCS1_PSS_PADDING; - } else { - RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE); - return -2; - } - return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); - } - - if (strcmp(type, "rsa_pss_saltlen") == 0) { - int saltlen; - - if (!strcmp(value, "digest")) - saltlen = RSA_PSS_SALTLEN_DIGEST; - else if (!strcmp(value, "max")) - saltlen = RSA_PSS_SALTLEN_MAX; - else if (!strcmp(value, "auto")) - saltlen = RSA_PSS_SALTLEN_AUTO; - else - saltlen = atoi(value); - return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); - } - - if (strcmp(type, "rsa_keygen_bits") == 0) { - int nbits = atoi(value); - - return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); - } - - if (strcmp(type, "rsa_keygen_pubexp") == 0) { - int ret; - - BIGNUM *pubexp = NULL; - if (!BN_asc2bn(&pubexp, value)) - return 0; - ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); - if (ret <= 0) - BN_free(pubexp); - return ret; - } - - if (strcmp(type, "rsa_keygen_primes") == 0) { - int nprimes = atoi(value); - - return EVP_PKEY_CTX_set_rsa_keygen_primes(ctx, nprimes); - } - - if (strcmp(type, "rsa_mgf1_md") == 0) - return EVP_PKEY_CTX_md(ctx, - EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, - EVP_PKEY_CTRL_RSA_MGF1_MD, value); - - if (pkey_ctx_is_pss(ctx)) { - - if (strcmp(type, "rsa_pss_keygen_mgf1_md") == 0) - return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN, - EVP_PKEY_CTRL_RSA_MGF1_MD, value); - - if (strcmp(type, "rsa_pss_keygen_md") == 0) - return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN, - EVP_PKEY_CTRL_MD, value); - - if (strcmp(type, "rsa_pss_keygen_saltlen") == 0) { - int saltlen = atoi(value); - - return EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, saltlen); - } - } - - if (strcmp(type, "rsa_oaep_md") == 0) - return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_CRYPT, - EVP_PKEY_CTRL_RSA_OAEP_MD, value); - - if (strcmp(type, "rsa_oaep_label") == 0) { - unsigned char *lab; - long lablen; - int ret; - - lab = OPENSSL_hexstr2buf(value, &lablen); - if (!lab) - return 0; - ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); - if (ret <= 0) - OPENSSL_free(lab); - return ret; - } - - return -2; -} - -/* Set PSS parameters when generating a key, if necessary */ -static int rsa_set_pss_param(RSA *rsa, EVP_PKEY_CTX *ctx) -{ - RSA_PKEY_CTX *rctx = ctx->data; - - if (!pkey_ctx_is_pss(ctx)) - return 1; - /* If all parameters are default values don't set pss */ - if (rctx->md == NULL && rctx->mgf1md == NULL && rctx->saltlen == -2) - return 1; - rsa->pss = rsa_pss_params_create(rctx->md, rctx->mgf1md, - rctx->saltlen == -2 ? 0 : rctx->saltlen); - if (rsa->pss == NULL) - return 0; - return 1; -} - -static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - RSA *rsa = NULL; - RSA_PKEY_CTX *rctx = ctx->data; - BN_GENCB *pcb; - int ret; - - if (rctx->pub_exp == NULL) { - rctx->pub_exp = BN_new(); - if (rctx->pub_exp == NULL || !BN_set_word(rctx->pub_exp, RSA_F4)) - return 0; - } - rsa = RSA_new(); - if (rsa == NULL) - return 0; - if (ctx->pkey_gencb) { - pcb = BN_GENCB_new(); - if (pcb == NULL) { - RSA_free(rsa); - return 0; - } - evp_pkey_set_cb_translate(pcb, ctx); - } else { - pcb = NULL; - } - ret = RSA_generate_multi_prime_key(rsa, rctx->nbits, rctx->primes, - rctx->pub_exp, pcb); - BN_GENCB_free(pcb); - if (ret > 0 && !rsa_set_pss_param(rsa, ctx)) { - RSA_free(rsa); - return 0; - } - if (ret > 0) - EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, rsa); - else - RSA_free(rsa); - return ret; -} - -const EVP_PKEY_METHOD rsa_pkey_meth = { - EVP_PKEY_RSA, - EVP_PKEY_FLAG_AUTOARGLEN, - pkey_rsa_init, - pkey_rsa_copy, - pkey_rsa_cleanup, - - 0, 0, - - 0, - pkey_rsa_keygen, - - 0, - pkey_rsa_sign, - - 0, - pkey_rsa_verify, - - 0, - pkey_rsa_verifyrecover, - - 0, 0, 0, 0, - - 0, - pkey_rsa_encrypt, - - 0, - pkey_rsa_decrypt, - - 0, 0, - - pkey_rsa_ctrl, - pkey_rsa_ctrl_str -}; - -/* - * Called for PSS sign or verify initialisation: checks PSS parameter - * sanity and sets any restrictions on key usage. - */ - -static int pkey_pss_init(EVP_PKEY_CTX *ctx) -{ - RSA *rsa; - RSA_PKEY_CTX *rctx = ctx->data; - const EVP_MD *md; - const EVP_MD *mgf1md; - int min_saltlen, max_saltlen; - - /* Should never happen */ - if (!pkey_ctx_is_pss(ctx)) - return 0; - rsa = ctx->pkey->pkey.rsa; - /* If no restrictions just return */ - if (rsa->pss == NULL) - return 1; - /* Get and check parameters */ - if (!rsa_pss_get_param(rsa->pss, &md, &mgf1md, &min_saltlen)) - return 0; - - /* See if minimum salt length exceeds maximum possible */ - max_saltlen = RSA_size(rsa) - EVP_MD_size(md); - if ((RSA_bits(rsa) & 0x7) == 1) - max_saltlen--; - if (min_saltlen > max_saltlen) { - RSAerr(RSA_F_PKEY_PSS_INIT, RSA_R_INVALID_SALT_LENGTH); - return 0; - } - - rctx->min_saltlen = min_saltlen; - - /* - * Set PSS restrictions as defaults: we can then block any attempt to - * use invalid values in pkey_rsa_ctrl - */ - - rctx->md = md; - rctx->mgf1md = mgf1md; - rctx->saltlen = min_saltlen; - - return 1; -} - -const EVP_PKEY_METHOD rsa_pss_pkey_meth = { - EVP_PKEY_RSA_PSS, - EVP_PKEY_FLAG_AUTOARGLEN, - pkey_rsa_init, - pkey_rsa_copy, - pkey_rsa_cleanup, - - 0, 0, - - 0, - pkey_rsa_keygen, - - pkey_pss_init, - pkey_rsa_sign, - - pkey_pss_init, - pkey_rsa_verify, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - pkey_rsa_ctrl, - pkey_rsa_ctrl_str -}; +} + +static int check_padding_md(const EVP_MD *md, int padding) +{ + int mdnid; + + if (!md) + return 1; + + mdnid = EVP_MD_type(md); + + if (padding == RSA_NO_PADDING) { + RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE); + return 0; + } + + if (padding == RSA_X931_PADDING) { + if (RSA_X931_hash_id(mdnid) == -1) { + RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_X931_DIGEST); + return 0; + } + } else { + switch(mdnid) { + /* List of all supported RSA digests */ + case NID_sha1: + case NID_sha224: + case NID_sha256: + case NID_sha384: + case NID_sha512: + case NID_md5: + case NID_md5_sha1: + case NID_md2: + case NID_md4: + case NID_mdc2: + case NID_ripemd160: + case NID_sha3_224: + case NID_sha3_256: + case NID_sha3_384: + case NID_sha3_512: + return 1; + + default: + RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_DIGEST); + return 0; + + } + } + + return 1; +} + +static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + RSA_PKEY_CTX *rctx = ctx->data; + + switch (type) { + case EVP_PKEY_CTRL_RSA_PADDING: + if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) { + if (!check_padding_md(rctx->md, p1)) + return 0; + if (p1 == RSA_PKCS1_PSS_PADDING) { + if (!(ctx->operation & + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) + goto bad_pad; + if (!rctx->md) + rctx->md = EVP_sha1(); + } else if (pkey_ctx_is_pss(ctx)) { + goto bad_pad; + } + if (p1 == RSA_PKCS1_OAEP_PADDING) { + if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) + goto bad_pad; + if (!rctx->md) + rctx->md = EVP_sha1(); + } + rctx->pad_mode = p1; + return 1; + } + bad_pad: + RSAerr(RSA_F_PKEY_RSA_CTRL, + RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return -2; + + case EVP_PKEY_CTRL_GET_RSA_PADDING: + *(int *)p2 = rctx->pad_mode; + return 1; + + case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: + case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: + if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); + return -2; + } + if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { + *(int *)p2 = rctx->saltlen; + } else { + if (p1 < RSA_PSS_SALTLEN_MAX) + return -2; + if (rsa_pss_restricted(rctx)) { + if (p1 == RSA_PSS_SALTLEN_AUTO + && ctx->operation == EVP_PKEY_OP_VERIFY) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); + return -2; + } + if ((p1 == RSA_PSS_SALTLEN_DIGEST + && rctx->min_saltlen > EVP_MD_size(rctx->md)) + || (p1 >= 0 && p1 < rctx->min_saltlen)) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_PSS_SALTLEN_TOO_SMALL); + return 0; + } + } + rctx->saltlen = p1; + } + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: + if (p1 < RSA_MIN_MODULUS_BITS) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL); + return -2; + } + rctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: + if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || BN_is_one((BIGNUM *)p2)) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_BAD_E_VALUE); + return -2; + } + BN_free(rctx->pub_exp); + rctx->pub_exp = p2; + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES: + if (p1 < RSA_DEFAULT_PRIME_NUM || p1 > RSA_MAX_PRIME_NUM) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_PRIME_NUM_INVALID); + return -2; + } + rctx->primes = p1; + return 1; + + case EVP_PKEY_CTRL_RSA_OAEP_MD: + case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); + return -2; + } + if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) + *(const EVP_MD **)p2 = rctx->md; + else + rctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_MD: + if (!check_padding_md(p2, rctx->pad_mode)) + return 0; + if (rsa_pss_restricted(rctx)) { + if (EVP_MD_type(rctx->md) == EVP_MD_type(p2)) + return 1; + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_DIGEST_NOT_ALLOWED); + return 0; + } + rctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_GET_MD: + *(const EVP_MD **)p2 = rctx->md; + return 1; + + case EVP_PKEY_CTRL_RSA_MGF1_MD: + case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: + if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING + && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD); + return -2; + } + if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { + if (rctx->mgf1md) + *(const EVP_MD **)p2 = rctx->mgf1md; + else + *(const EVP_MD **)p2 = rctx->md; + } else { + if (rsa_pss_restricted(rctx)) { + if (EVP_MD_type(rctx->mgf1md) == EVP_MD_type(p2)) + return 1; + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_MGF1_DIGEST_NOT_ALLOWED); + return 0; + } + rctx->mgf1md = p2; + } + return 1; + + case EVP_PKEY_CTRL_RSA_OAEP_LABEL: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); + return -2; + } + OPENSSL_free(rctx->oaep_label); + if (p2 && p1 > 0) { + rctx->oaep_label = p2; + rctx->oaep_labellen = p1; + } else { + rctx->oaep_label = NULL; + rctx->oaep_labellen = 0; + } + return 1; + + case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); + return -2; + } + *(unsigned char **)p2 = rctx->oaep_label; + return rctx->oaep_labellen; + + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_SIGN: +#ifndef OPENSSL_NO_CMS + case EVP_PKEY_CTRL_CMS_SIGN: +#endif + return 1; + + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: +#ifndef OPENSSL_NO_CMS + case EVP_PKEY_CTRL_CMS_DECRYPT: + case EVP_PKEY_CTRL_CMS_ENCRYPT: +#endif + if (!pkey_ctx_is_pss(ctx)) + return 1; + /* fall through */ + case EVP_PKEY_CTRL_PEER_KEY: + RSAerr(RSA_F_PKEY_RSA_CTRL, + RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + + default: + return -2; + + } +} + +static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (value == NULL) { + RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); + return 0; + } + if (strcmp(type, "rsa_padding_mode") == 0) { + int pm; + + if (strcmp(value, "pkcs1") == 0) { + pm = RSA_PKCS1_PADDING; + } else if (strcmp(value, "sslv23") == 0) { + pm = RSA_SSLV23_PADDING; + } else if (strcmp(value, "none") == 0) { + pm = RSA_NO_PADDING; + } else if (strcmp(value, "oeap") == 0) { + pm = RSA_PKCS1_OAEP_PADDING; + } else if (strcmp(value, "oaep") == 0) { + pm = RSA_PKCS1_OAEP_PADDING; + } else if (strcmp(value, "x931") == 0) { + pm = RSA_X931_PADDING; + } else if (strcmp(value, "pss") == 0) { + pm = RSA_PKCS1_PSS_PADDING; + } else { + RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE); + return -2; + } + return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); + } + + if (strcmp(type, "rsa_pss_saltlen") == 0) { + int saltlen; + + if (!strcmp(value, "digest")) + saltlen = RSA_PSS_SALTLEN_DIGEST; + else if (!strcmp(value, "max")) + saltlen = RSA_PSS_SALTLEN_MAX; + else if (!strcmp(value, "auto")) + saltlen = RSA_PSS_SALTLEN_AUTO; + else + saltlen = atoi(value); + return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); + } + + if (strcmp(type, "rsa_keygen_bits") == 0) { + int nbits = atoi(value); + + return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); + } + + if (strcmp(type, "rsa_keygen_pubexp") == 0) { + int ret; + + BIGNUM *pubexp = NULL; + if (!BN_asc2bn(&pubexp, value)) + return 0; + ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); + if (ret <= 0) + BN_free(pubexp); + return ret; + } + + if (strcmp(type, "rsa_keygen_primes") == 0) { + int nprimes = atoi(value); + + return EVP_PKEY_CTX_set_rsa_keygen_primes(ctx, nprimes); + } + + if (strcmp(type, "rsa_mgf1_md") == 0) + return EVP_PKEY_CTX_md(ctx, + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_MGF1_MD, value); + + if (pkey_ctx_is_pss(ctx)) { + + if (strcmp(type, "rsa_pss_keygen_mgf1_md") == 0) + return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_MGF1_MD, value); + + if (strcmp(type, "rsa_pss_keygen_md") == 0) + return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_MD, value); + + if (strcmp(type, "rsa_pss_keygen_saltlen") == 0) { + int saltlen = atoi(value); + + return EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, saltlen); + } + } + + if (strcmp(type, "rsa_oaep_md") == 0) + return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_MD, value); + + if (strcmp(type, "rsa_oaep_label") == 0) { + unsigned char *lab; + long lablen; + int ret; + + lab = OPENSSL_hexstr2buf(value, &lablen); + if (!lab) + return 0; + ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); + if (ret <= 0) + OPENSSL_free(lab); + return ret; + } + + return -2; +} + +/* Set PSS parameters when generating a key, if necessary */ +static int rsa_set_pss_param(RSA *rsa, EVP_PKEY_CTX *ctx) +{ + RSA_PKEY_CTX *rctx = ctx->data; + + if (!pkey_ctx_is_pss(ctx)) + return 1; + /* If all parameters are default values don't set pss */ + if (rctx->md == NULL && rctx->mgf1md == NULL && rctx->saltlen == -2) + return 1; + rsa->pss = rsa_pss_params_create(rctx->md, rctx->mgf1md, + rctx->saltlen == -2 ? 0 : rctx->saltlen); + if (rsa->pss == NULL) + return 0; + return 1; +} + +static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + RSA *rsa = NULL; + RSA_PKEY_CTX *rctx = ctx->data; + BN_GENCB *pcb; + int ret; + + if (rctx->pub_exp == NULL) { + rctx->pub_exp = BN_new(); + if (rctx->pub_exp == NULL || !BN_set_word(rctx->pub_exp, RSA_F4)) + return 0; + } + rsa = RSA_new(); + if (rsa == NULL) + return 0; + if (ctx->pkey_gencb) { + pcb = BN_GENCB_new(); + if (pcb == NULL) { + RSA_free(rsa); + return 0; + } + evp_pkey_set_cb_translate(pcb, ctx); + } else { + pcb = NULL; + } + ret = RSA_generate_multi_prime_key(rsa, rctx->nbits, rctx->primes, + rctx->pub_exp, pcb); + BN_GENCB_free(pcb); + if (ret > 0 && !rsa_set_pss_param(rsa, ctx)) { + RSA_free(rsa); + return 0; + } + if (ret > 0) + EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, rsa); + else + RSA_free(rsa); + return ret; +} + +const EVP_PKEY_METHOD rsa_pkey_meth = { + EVP_PKEY_RSA, + EVP_PKEY_FLAG_AUTOARGLEN, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, + + 0, 0, + + 0, + pkey_rsa_keygen, + + 0, + pkey_rsa_sign, + + 0, + pkey_rsa_verify, + + 0, + pkey_rsa_verifyrecover, + + 0, 0, 0, 0, + + 0, + pkey_rsa_encrypt, + + 0, + pkey_rsa_decrypt, + + 0, 0, + + pkey_rsa_ctrl, + pkey_rsa_ctrl_str +}; + +/* + * Called for PSS sign or verify initialisation: checks PSS parameter + * sanity and sets any restrictions on key usage. + */ + +static int pkey_pss_init(EVP_PKEY_CTX *ctx) +{ + RSA *rsa; + RSA_PKEY_CTX *rctx = ctx->data; + const EVP_MD *md; + const EVP_MD *mgf1md; + int min_saltlen, max_saltlen; + + /* Should never happen */ + if (!pkey_ctx_is_pss(ctx)) + return 0; + rsa = ctx->pkey->pkey.rsa; + /* If no restrictions just return */ + if (rsa->pss == NULL) + return 1; + /* Get and check parameters */ + if (!rsa_pss_get_param(rsa->pss, &md, &mgf1md, &min_saltlen)) + return 0; + + /* See if minimum salt length exceeds maximum possible */ + max_saltlen = RSA_size(rsa) - EVP_MD_size(md); + if ((RSA_bits(rsa) & 0x7) == 1) + max_saltlen--; + if (min_saltlen > max_saltlen) { + RSAerr(RSA_F_PKEY_PSS_INIT, RSA_R_INVALID_SALT_LENGTH); + return 0; + } + + rctx->min_saltlen = min_saltlen; + + /* + * Set PSS restrictions as defaults: we can then block any attempt to + * use invalid values in pkey_rsa_ctrl + */ + + rctx->md = md; + rctx->mgf1md = mgf1md; + rctx->saltlen = min_saltlen; + + return 1; +} + +const EVP_PKEY_METHOD rsa_pss_pkey_meth = { + EVP_PKEY_RSA_PSS, + EVP_PKEY_FLAG_AUTOARGLEN, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, + + 0, 0, + + 0, + pkey_rsa_keygen, + + pkey_pss_init, + pkey_rsa_sign, + + pkey_pss_init, + pkey_rsa_verify, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + pkey_rsa_ctrl, + pkey_rsa_ctrl_str +}; diff --git a/contrib/libs/openssl/crypto/rsa/rsa_prn.c b/contrib/libs/openssl/crypto/rsa/rsa_prn.c index 23df448a52..7ac302c120 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_prn.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_prn.c @@ -1,44 +1,44 @@ -/* +/* * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdio.h> -#include "internal/cryptlib.h" -#include <openssl/rsa.h> -#include <openssl/evp.h> - -#ifndef OPENSSL_NO_STDIO -int RSA_print_fp(FILE *fp, const RSA *x, int off) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - RSAerr(RSA_F_RSA_PRINT_FP, ERR_R_BUF_LIB); - return 0; - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = RSA_print(b, x, off); - BIO_free(b); - return ret; -} -#endif - -int RSA_print(BIO *bp, const RSA *x, int off) -{ - EVP_PKEY *pk; - int ret; - pk = EVP_PKEY_new(); + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/rsa.h> +#include <openssl/evp.h> + +#ifndef OPENSSL_NO_STDIO +int RSA_print_fp(FILE *fp, const RSA *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + RSAerr(RSA_F_RSA_PRINT_FP, ERR_R_BUF_LIB); + return 0; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = RSA_print(b, x, off); + BIO_free(b); + return ret; +} +#endif + +int RSA_print(BIO *bp, const RSA *x, int off) +{ + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); if (pk == NULL) - return 0; + return 0; ret = EVP_PKEY_set1_RSA(pk, (RSA *)x); if (ret) ret = EVP_PKEY_print_private(bp, pk, off, NULL); - EVP_PKEY_free(pk); - return ret; -} + EVP_PKEY_free(pk); + return ret; +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_pss.c b/contrib/libs/openssl/crypto/rsa/rsa_pss.c index 40ce1c4d37..edff837fb0 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_pss.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_pss.c @@ -1,255 +1,255 @@ -/* - * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdio.h> -#include "internal/cryptlib.h" -#include <openssl/bn.h> -#include <openssl/rsa.h> -#include <openssl/evp.h> -#include <openssl/rand.h> -#include <openssl/sha.h> +/* + * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/bn.h> +#include <openssl/rsa.h> +#include <openssl/evp.h> +#include <openssl/rand.h> +#include <openssl/sha.h> #include "rsa_local.h" - -static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -#if defined(_MSC_VER) && defined(_ARM_) -# pragma optimize("g", off) -#endif - -int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, - const EVP_MD *Hash, const unsigned char *EM, - int sLen) -{ - return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen); -} - -int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, - const EVP_MD *Hash, const EVP_MD *mgf1Hash, - const unsigned char *EM, int sLen) -{ - int i; - int ret = 0; - int hLen, maskedDBLen, MSBits, emLen; - const unsigned char *H; - unsigned char *DB = NULL; - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); - unsigned char H_[EVP_MAX_MD_SIZE]; - - if (ctx == NULL) - goto err; - - if (mgf1Hash == NULL) - mgf1Hash = Hash; - - hLen = EVP_MD_size(Hash); - if (hLen < 0) - goto err; - /*- - * Negative sLen has special meanings: - * -1 sLen == hLen - * -2 salt length is autorecovered from signature - * -3 salt length is maximized - * -N reserved - */ - if (sLen == RSA_PSS_SALTLEN_DIGEST) { - sLen = hLen; - } else if (sLen < RSA_PSS_SALTLEN_MAX) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); - goto err; - } - - MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; - emLen = RSA_size(rsa); - if (EM[0] & (0xFF << MSBits)) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID); - goto err; - } - if (MSBits == 0) { - EM++; - emLen--; - } - if (emLen < hLen + 2) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); - goto err; - } - if (sLen == RSA_PSS_SALTLEN_MAX) { - sLen = emLen - hLen - 2; - } else if (sLen > emLen - hLen - 2) { /* sLen can be small negative */ - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); - goto err; - } - if (EM[emLen - 1] != 0xbc) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID); - goto err; - } - maskedDBLen = emLen - hLen - 1; - H = EM + maskedDBLen; - DB = OPENSSL_malloc(maskedDBLen); - if (DB == NULL) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE); - goto err; - } - if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0) - goto err; - for (i = 0; i < maskedDBLen; i++) - DB[i] ^= EM[i]; - if (MSBits) - DB[0] &= 0xFF >> (8 - MSBits); - for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ; - if (DB[i++] != 0x1) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED); - goto err; - } - if (sLen != RSA_PSS_SALTLEN_AUTO && (maskedDBLen - i) != sLen) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); - goto err; - } - if (!EVP_DigestInit_ex(ctx, Hash, NULL) - || !EVP_DigestUpdate(ctx, zeroes, sizeof(zeroes)) - || !EVP_DigestUpdate(ctx, mHash, hLen)) - goto err; - if (maskedDBLen - i) { - if (!EVP_DigestUpdate(ctx, DB + i, maskedDBLen - i)) - goto err; - } - if (!EVP_DigestFinal_ex(ctx, H_, NULL)) - goto err; - if (memcmp(H_, H, hLen)) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE); - ret = 0; - } else { - ret = 1; - } - - err: - OPENSSL_free(DB); - EVP_MD_CTX_free(ctx); - - return ret; - -} - -int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, - const unsigned char *mHash, - const EVP_MD *Hash, int sLen) -{ - return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen); -} - -int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, - const unsigned char *mHash, - const EVP_MD *Hash, const EVP_MD *mgf1Hash, - int sLen) -{ - int i; - int ret = 0; - int hLen, maskedDBLen, MSBits, emLen; - unsigned char *H, *salt = NULL, *p; - EVP_MD_CTX *ctx = NULL; - - if (mgf1Hash == NULL) - mgf1Hash = Hash; - - hLen = EVP_MD_size(Hash); - if (hLen < 0) - goto err; - /*- - * Negative sLen has special meanings: - * -1 sLen == hLen - * -2 salt length is maximized - * -3 same as above (on signing) - * -N reserved - */ - if (sLen == RSA_PSS_SALTLEN_DIGEST) { - sLen = hLen; - } else if (sLen == RSA_PSS_SALTLEN_MAX_SIGN) { - sLen = RSA_PSS_SALTLEN_MAX; - } else if (sLen < RSA_PSS_SALTLEN_MAX) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); - goto err; - } - - MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; - emLen = RSA_size(rsa); - if (MSBits == 0) { - *EM++ = 0; - emLen--; - } - if (emLen < hLen + 2) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - goto err; - } - if (sLen == RSA_PSS_SALTLEN_MAX) { - sLen = emLen - hLen - 2; - } else if (sLen > emLen - hLen - 2) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - goto err; - } - if (sLen > 0) { - salt = OPENSSL_malloc(sLen); - if (salt == NULL) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, - ERR_R_MALLOC_FAILURE); - goto err; - } - if (RAND_bytes(salt, sLen) <= 0) - goto err; - } - maskedDBLen = emLen - hLen - 1; - H = EM + maskedDBLen; - ctx = EVP_MD_CTX_new(); - if (ctx == NULL) - goto err; - if (!EVP_DigestInit_ex(ctx, Hash, NULL) - || !EVP_DigestUpdate(ctx, zeroes, sizeof(zeroes)) - || !EVP_DigestUpdate(ctx, mHash, hLen)) - goto err; - if (sLen && !EVP_DigestUpdate(ctx, salt, sLen)) - goto err; - if (!EVP_DigestFinal_ex(ctx, H, NULL)) - goto err; - - /* Generate dbMask in place then perform XOR on it */ - if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) - goto err; - - p = EM; - - /* - * Initial PS XORs with all zeroes which is a NOP so just update pointer. - * Note from a test above this value is guaranteed to be non-negative. - */ - p += emLen - sLen - hLen - 2; - *p++ ^= 0x1; - if (sLen > 0) { - for (i = 0; i < sLen; i++) - *p++ ^= salt[i]; - } - if (MSBits) - EM[0] &= 0xFF >> (8 - MSBits); - - /* H is already in place so just set final 0xbc */ - - EM[emLen - 1] = 0xbc; - - ret = 1; - - err: - EVP_MD_CTX_free(ctx); - OPENSSL_clear_free(salt, (size_t)sLen); /* salt != NULL implies sLen > 0 */ - - return ret; - -} - -#if defined(_MSC_VER) -# pragma optimize("",on) -#endif + +static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +#if defined(_MSC_VER) && defined(_ARM_) +# pragma optimize("g", off) +#endif + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, + int sLen) +{ + return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen); +} + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const unsigned char *EM, int sLen) +{ + int i; + int ret = 0; + int hLen, maskedDBLen, MSBits, emLen; + const unsigned char *H; + unsigned char *DB = NULL; + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + unsigned char H_[EVP_MAX_MD_SIZE]; + + if (ctx == NULL) + goto err; + + if (mgf1Hash == NULL) + mgf1Hash = Hash; + + hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; + /*- + * Negative sLen has special meanings: + * -1 sLen == hLen + * -2 salt length is autorecovered from signature + * -3 salt length is maximized + * -N reserved + */ + if (sLen == RSA_PSS_SALTLEN_DIGEST) { + sLen = hLen; + } else if (sLen < RSA_PSS_SALTLEN_MAX) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (EM[0] & (0xFF << MSBits)) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID); + goto err; + } + if (MSBits == 0) { + EM++; + emLen--; + } + if (emLen < hLen + 2) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); + goto err; + } + if (sLen == RSA_PSS_SALTLEN_MAX) { + sLen = emLen - hLen - 2; + } else if (sLen > emLen - hLen - 2) { /* sLen can be small negative */ + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); + goto err; + } + if (EM[emLen - 1] != 0xbc) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID); + goto err; + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + DB = OPENSSL_malloc(maskedDBLen); + if (DB == NULL) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE); + goto err; + } + if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0) + goto err; + for (i = 0; i < maskedDBLen; i++) + DB[i] ^= EM[i]; + if (MSBits) + DB[0] &= 0xFF >> (8 - MSBits); + for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ; + if (DB[i++] != 0x1) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED); + goto err; + } + if (sLen != RSA_PSS_SALTLEN_AUTO && (maskedDBLen - i) != sLen) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + if (!EVP_DigestInit_ex(ctx, Hash, NULL) + || !EVP_DigestUpdate(ctx, zeroes, sizeof(zeroes)) + || !EVP_DigestUpdate(ctx, mHash, hLen)) + goto err; + if (maskedDBLen - i) { + if (!EVP_DigestUpdate(ctx, DB + i, maskedDBLen - i)) + goto err; + } + if (!EVP_DigestFinal_ex(ctx, H_, NULL)) + goto err; + if (memcmp(H_, H, hLen)) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE); + ret = 0; + } else { + ret = 1; + } + + err: + OPENSSL_free(DB); + EVP_MD_CTX_free(ctx); + + return ret; + +} + +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, int sLen) +{ + return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen); +} + +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen) +{ + int i; + int ret = 0; + int hLen, maskedDBLen, MSBits, emLen; + unsigned char *H, *salt = NULL, *p; + EVP_MD_CTX *ctx = NULL; + + if (mgf1Hash == NULL) + mgf1Hash = Hash; + + hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; + /*- + * Negative sLen has special meanings: + * -1 sLen == hLen + * -2 salt length is maximized + * -3 same as above (on signing) + * -N reserved + */ + if (sLen == RSA_PSS_SALTLEN_DIGEST) { + sLen = hLen; + } else if (sLen == RSA_PSS_SALTLEN_MAX_SIGN) { + sLen = RSA_PSS_SALTLEN_MAX; + } else if (sLen < RSA_PSS_SALTLEN_MAX) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (MSBits == 0) { + *EM++ = 0; + emLen--; + } + if (emLen < hLen + 2) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + goto err; + } + if (sLen == RSA_PSS_SALTLEN_MAX) { + sLen = emLen - hLen - 2; + } else if (sLen > emLen - hLen - 2) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + goto err; + } + if (sLen > 0) { + salt = OPENSSL_malloc(sLen); + if (salt == NULL) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (RAND_bytes(salt, sLen) <= 0) + goto err; + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + goto err; + if (!EVP_DigestInit_ex(ctx, Hash, NULL) + || !EVP_DigestUpdate(ctx, zeroes, sizeof(zeroes)) + || !EVP_DigestUpdate(ctx, mHash, hLen)) + goto err; + if (sLen && !EVP_DigestUpdate(ctx, salt, sLen)) + goto err; + if (!EVP_DigestFinal_ex(ctx, H, NULL)) + goto err; + + /* Generate dbMask in place then perform XOR on it */ + if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) + goto err; + + p = EM; + + /* + * Initial PS XORs with all zeroes which is a NOP so just update pointer. + * Note from a test above this value is guaranteed to be non-negative. + */ + p += emLen - sLen - hLen - 2; + *p++ ^= 0x1; + if (sLen > 0) { + for (i = 0; i < sLen; i++) + *p++ ^= salt[i]; + } + if (MSBits) + EM[0] &= 0xFF >> (8 - MSBits); + + /* H is already in place so just set final 0xbc */ + + EM[emLen - 1] = 0xbc; + + ret = 1; + + err: + EVP_MD_CTX_free(ctx); + OPENSSL_clear_free(salt, (size_t)sLen); /* salt != NULL implies sLen > 0 */ + + return ret; + +} + +#if defined(_MSC_VER) +# pragma optimize("",on) +#endif diff --git a/contrib/libs/openssl/crypto/rsa/rsa_saos.c b/contrib/libs/openssl/crypto/rsa/rsa_saos.c index 8336f32f16..7b0ce4eb8c 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_saos.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_saos.c @@ -1,95 +1,95 @@ -/* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdio.h> -#include "internal/cryptlib.h" -#include <openssl/bn.h> -#include <openssl/rsa.h> -#include <openssl/objects.h> -#include <openssl/x509.h> - -int RSA_sign_ASN1_OCTET_STRING(int type, - const unsigned char *m, unsigned int m_len, - unsigned char *sigret, unsigned int *siglen, - RSA *rsa) -{ - ASN1_OCTET_STRING sig; - int i, j, ret = 1; - unsigned char *p, *s; - - sig.type = V_ASN1_OCTET_STRING; - sig.length = m_len; - sig.data = (unsigned char *)m; - - i = i2d_ASN1_OCTET_STRING(&sig, NULL); - j = RSA_size(rsa); - if (i > (j - RSA_PKCS1_PADDING_SIZE)) { - RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, - RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); - return 0; - } - s = OPENSSL_malloc((unsigned int)j + 1); - if (s == NULL) { - RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); - return 0; - } - p = s; - i2d_ASN1_OCTET_STRING(&sig, &p); - i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); - if (i <= 0) - ret = 0; - else - *siglen = i; - - OPENSSL_clear_free(s, (unsigned int)j + 1); - return ret; -} - -int RSA_verify_ASN1_OCTET_STRING(int dtype, - const unsigned char *m, - unsigned int m_len, unsigned char *sigbuf, - unsigned int siglen, RSA *rsa) -{ - int i, ret = 0; - unsigned char *s; - const unsigned char *p; - ASN1_OCTET_STRING *sig = NULL; - - if (siglen != (unsigned int)RSA_size(rsa)) { - RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, - RSA_R_WRONG_SIGNATURE_LENGTH); - return 0; - } - - s = OPENSSL_malloc((unsigned int)siglen); - if (s == NULL) { - RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); - goto err; - } - i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); - - if (i <= 0) - goto err; - - p = s; - sig = d2i_ASN1_OCTET_STRING(NULL, &p, (long)i); - if (sig == NULL) - goto err; - - if (((unsigned int)sig->length != m_len) || - (memcmp(m, sig->data, m_len) != 0)) { - RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, RSA_R_BAD_SIGNATURE); - } else { - ret = 1; - } - err: - ASN1_OCTET_STRING_free(sig); - OPENSSL_clear_free(s, (unsigned int)siglen); - return ret; -} +/* + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/bn.h> +#include <openssl/rsa.h> +#include <openssl/objects.h> +#include <openssl/x509.h> + +int RSA_sign_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, + RSA *rsa) +{ + ASN1_OCTET_STRING sig; + int i, j, ret = 1; + unsigned char *p, *s; + + sig.type = V_ASN1_OCTET_STRING; + sig.length = m_len; + sig.data = (unsigned char *)m; + + i = i2d_ASN1_OCTET_STRING(&sig, NULL); + j = RSA_size(rsa); + if (i > (j - RSA_PKCS1_PADDING_SIZE)) { + RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, + RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + return 0; + } + s = OPENSSL_malloc((unsigned int)j + 1); + if (s == NULL) { + RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); + return 0; + } + p = s; + i2d_ASN1_OCTET_STRING(&sig, &p); + i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); + if (i <= 0) + ret = 0; + else + *siglen = i; + + OPENSSL_clear_free(s, (unsigned int)j + 1); + return ret; +} + +int RSA_verify_ASN1_OCTET_STRING(int dtype, + const unsigned char *m, + unsigned int m_len, unsigned char *sigbuf, + unsigned int siglen, RSA *rsa) +{ + int i, ret = 0; + unsigned char *s; + const unsigned char *p; + ASN1_OCTET_STRING *sig = NULL; + + if (siglen != (unsigned int)RSA_size(rsa)) { + RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, + RSA_R_WRONG_SIGNATURE_LENGTH); + return 0; + } + + s = OPENSSL_malloc((unsigned int)siglen); + if (s == NULL) { + RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); + goto err; + } + i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); + + if (i <= 0) + goto err; + + p = s; + sig = d2i_ASN1_OCTET_STRING(NULL, &p, (long)i); + if (sig == NULL) + goto err; + + if (((unsigned int)sig->length != m_len) || + (memcmp(m, sig->data, m_len) != 0)) { + RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, RSA_R_BAD_SIGNATURE); + } else { + ret = 1; + } + err: + ASN1_OCTET_STRING_free(sig); + OPENSSL_clear_free(s, (unsigned int)siglen); + return ret; +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_sign.c b/contrib/libs/openssl/crypto/rsa/rsa_sign.c index 7fc69361bf..8a2e899ac5 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_sign.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_sign.c @@ -1,248 +1,248 @@ -/* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdio.h> -#include "internal/cryptlib.h" -#include <openssl/bn.h> -#include <openssl/rsa.h> -#include <openssl/objects.h> -#include <openssl/x509.h> +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/bn.h> +#include <openssl/rsa.h> +#include <openssl/objects.h> +#include <openssl/x509.h> #include "crypto/x509.h" #include "rsa_local.h" - -/* Size of an SSL signature: MD5+SHA1 */ -#define SSL_SIG_LENGTH 36 - -/* - * encode_pkcs1 encodes a DigestInfo prefix of hash |type| and digest |m|, as - * described in EMSA-PKCS1-v1_5-ENCODE, RFC 3447 section 9.2 step 2. This - * encodes the DigestInfo (T and tLen) but does not add the padding. - * - * On success, it returns one and sets |*out| to a newly allocated buffer - * containing the result and |*out_len| to its length. The caller must free - * |*out| with |OPENSSL_free|. Otherwise, it returns zero. - */ -static int encode_pkcs1(unsigned char **out, int *out_len, int type, - const unsigned char *m, unsigned int m_len) -{ - X509_SIG sig; - X509_ALGOR algor; - ASN1_TYPE parameter; - ASN1_OCTET_STRING digest; - uint8_t *der = NULL; - int len; - - sig.algor = &algor; - sig.algor->algorithm = OBJ_nid2obj(type); - if (sig.algor->algorithm == NULL) { - RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_UNKNOWN_ALGORITHM_TYPE); - return 0; - } - if (OBJ_length(sig.algor->algorithm) == 0) { - RSAerr(RSA_F_ENCODE_PKCS1, - RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); - return 0; - } - parameter.type = V_ASN1_NULL; - parameter.value.ptr = NULL; - sig.algor->parameter = ¶meter; - - sig.digest = &digest; - sig.digest->data = (unsigned char *)m; - sig.digest->length = m_len; - - len = i2d_X509_SIG(&sig, &der); - if (len < 0) - return 0; - - *out = der; - *out_len = len; - return 1; -} - -int RSA_sign(int type, const unsigned char *m, unsigned int m_len, - unsigned char *sigret, unsigned int *siglen, RSA *rsa) -{ - int encrypt_len, encoded_len = 0, ret = 0; - unsigned char *tmps = NULL; - const unsigned char *encoded = NULL; - - if (rsa->meth->rsa_sign) { - return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); - } - - /* Compute the encoded digest. */ - if (type == NID_md5_sha1) { - /* - * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and - * earlier. It has no DigestInfo wrapper but otherwise is - * RSASSA-PKCS1-v1_5. - */ - if (m_len != SSL_SIG_LENGTH) { - RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH); - return 0; - } - encoded_len = SSL_SIG_LENGTH; - encoded = m; - } else { - if (!encode_pkcs1(&tmps, &encoded_len, type, m, m_len)) - goto err; - encoded = tmps; - } - - if (encoded_len > RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE) { - RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); - goto err; - } - encrypt_len = RSA_private_encrypt(encoded_len, encoded, sigret, rsa, - RSA_PKCS1_PADDING); - if (encrypt_len <= 0) - goto err; - - *siglen = encrypt_len; - ret = 1; - -err: - OPENSSL_clear_free(tmps, (size_t)encoded_len); - return ret; -} - -/* - * int_rsa_verify verifies an RSA signature in |sigbuf| using |rsa|. It may be - * called in two modes. If |rm| is NULL, it verifies the signature for digest - * |m|. Otherwise, it recovers the digest from the signature, writing the digest - * to |rm| and the length to |*prm_len|. |type| is the NID of the digest - * algorithm to use. It returns one on successful verification and zero - * otherwise. - */ -int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, - unsigned char *rm, size_t *prm_len, - const unsigned char *sigbuf, size_t siglen, RSA *rsa) -{ - int decrypt_len, ret = 0, encoded_len = 0; - unsigned char *decrypt_buf = NULL, *encoded = NULL; - - if (siglen != (size_t)RSA_size(rsa)) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH); - return 0; - } - - /* Recover the encoded digest. */ - decrypt_buf = OPENSSL_malloc(siglen); - if (decrypt_buf == NULL) { - RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - - decrypt_len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, rsa, - RSA_PKCS1_PADDING); - if (decrypt_len <= 0) - goto err; - - if (type == NID_md5_sha1) { - /* - * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and - * earlier. It has no DigestInfo wrapper but otherwise is - * RSASSA-PKCS1-v1_5. - */ - if (decrypt_len != SSL_SIG_LENGTH) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); - goto err; - } - - if (rm != NULL) { - memcpy(rm, decrypt_buf, SSL_SIG_LENGTH); - *prm_len = SSL_SIG_LENGTH; - } else { - if (m_len != SSL_SIG_LENGTH) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); - goto err; - } - - if (memcmp(decrypt_buf, m, SSL_SIG_LENGTH) != 0) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); - goto err; - } - } - } else if (type == NID_mdc2 && decrypt_len == 2 + 16 - && decrypt_buf[0] == 0x04 && decrypt_buf[1] == 0x10) { - /* - * Oddball MDC2 case: signature can be OCTET STRING. check for correct - * tag and length octets. - */ - if (rm != NULL) { - memcpy(rm, decrypt_buf + 2, 16); - *prm_len = 16; - } else { - if (m_len != 16) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); - goto err; - } - - if (memcmp(m, decrypt_buf + 2, 16) != 0) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); - goto err; - } - } - } else { - /* - * If recovering the digest, extract a digest-sized output from the end - * of |decrypt_buf| for |encode_pkcs1|, then compare the decryption - * output as in a standard verification. - */ - if (rm != NULL) { - const EVP_MD *md = EVP_get_digestbynid(type); - if (md == NULL) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_UNKNOWN_ALGORITHM_TYPE); - goto err; - } - - m_len = EVP_MD_size(md); - if (m_len > (size_t)decrypt_len) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); - goto err; - } - m = decrypt_buf + decrypt_len - m_len; - } - - /* Construct the encoded digest and ensure it matches. */ - if (!encode_pkcs1(&encoded, &encoded_len, type, m, m_len)) - goto err; - - if (encoded_len != decrypt_len - || memcmp(encoded, decrypt_buf, encoded_len) != 0) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); - goto err; - } - - /* Output the recovered digest. */ - if (rm != NULL) { - memcpy(rm, m, m_len); - *prm_len = m_len; - } - } - - ret = 1; - -err: - OPENSSL_clear_free(encoded, (size_t)encoded_len); - OPENSSL_clear_free(decrypt_buf, siglen); - return ret; -} - -int RSA_verify(int type, const unsigned char *m, unsigned int m_len, - const unsigned char *sigbuf, unsigned int siglen, RSA *rsa) -{ - - if (rsa->meth->rsa_verify) { - return rsa->meth->rsa_verify(type, m, m_len, sigbuf, siglen, rsa); - } - - return int_rsa_verify(type, m, m_len, NULL, NULL, sigbuf, siglen, rsa); -} + +/* Size of an SSL signature: MD5+SHA1 */ +#define SSL_SIG_LENGTH 36 + +/* + * encode_pkcs1 encodes a DigestInfo prefix of hash |type| and digest |m|, as + * described in EMSA-PKCS1-v1_5-ENCODE, RFC 3447 section 9.2 step 2. This + * encodes the DigestInfo (T and tLen) but does not add the padding. + * + * On success, it returns one and sets |*out| to a newly allocated buffer + * containing the result and |*out_len| to its length. The caller must free + * |*out| with |OPENSSL_free|. Otherwise, it returns zero. + */ +static int encode_pkcs1(unsigned char **out, int *out_len, int type, + const unsigned char *m, unsigned int m_len) +{ + X509_SIG sig; + X509_ALGOR algor; + ASN1_TYPE parameter; + ASN1_OCTET_STRING digest; + uint8_t *der = NULL; + int len; + + sig.algor = &algor; + sig.algor->algorithm = OBJ_nid2obj(type); + if (sig.algor->algorithm == NULL) { + RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + } + if (OBJ_length(sig.algor->algorithm) == 0) { + RSAerr(RSA_F_ENCODE_PKCS1, + RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); + return 0; + } + parameter.type = V_ASN1_NULL; + parameter.value.ptr = NULL; + sig.algor->parameter = ¶meter; + + sig.digest = &digest; + sig.digest->data = (unsigned char *)m; + sig.digest->length = m_len; + + len = i2d_X509_SIG(&sig, &der); + if (len < 0) + return 0; + + *out = der; + *out_len = len; + return 1; +} + +int RSA_sign(int type, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, RSA *rsa) +{ + int encrypt_len, encoded_len = 0, ret = 0; + unsigned char *tmps = NULL; + const unsigned char *encoded = NULL; + + if (rsa->meth->rsa_sign) { + return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); + } + + /* Compute the encoded digest. */ + if (type == NID_md5_sha1) { + /* + * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and + * earlier. It has no DigestInfo wrapper but otherwise is + * RSASSA-PKCS1-v1_5. + */ + if (m_len != SSL_SIG_LENGTH) { + RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + encoded_len = SSL_SIG_LENGTH; + encoded = m; + } else { + if (!encode_pkcs1(&tmps, &encoded_len, type, m, m_len)) + goto err; + encoded = tmps; + } + + if (encoded_len > RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE) { + RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + goto err; + } + encrypt_len = RSA_private_encrypt(encoded_len, encoded, sigret, rsa, + RSA_PKCS1_PADDING); + if (encrypt_len <= 0) + goto err; + + *siglen = encrypt_len; + ret = 1; + +err: + OPENSSL_clear_free(tmps, (size_t)encoded_len); + return ret; +} + +/* + * int_rsa_verify verifies an RSA signature in |sigbuf| using |rsa|. It may be + * called in two modes. If |rm| is NULL, it verifies the signature for digest + * |m|. Otherwise, it recovers the digest from the signature, writing the digest + * to |rm| and the length to |*prm_len|. |type| is the NID of the digest + * algorithm to use. It returns one on successful verification and zero + * otherwise. + */ +int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, + unsigned char *rm, size_t *prm_len, + const unsigned char *sigbuf, size_t siglen, RSA *rsa) +{ + int decrypt_len, ret = 0, encoded_len = 0; + unsigned char *decrypt_buf = NULL, *encoded = NULL; + + if (siglen != (size_t)RSA_size(rsa)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH); + return 0; + } + + /* Recover the encoded digest. */ + decrypt_buf = OPENSSL_malloc(siglen); + if (decrypt_buf == NULL) { + RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + + decrypt_len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, rsa, + RSA_PKCS1_PADDING); + if (decrypt_len <= 0) + goto err; + + if (type == NID_md5_sha1) { + /* + * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and + * earlier. It has no DigestInfo wrapper but otherwise is + * RSASSA-PKCS1-v1_5. + */ + if (decrypt_len != SSL_SIG_LENGTH) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + goto err; + } + + if (rm != NULL) { + memcpy(rm, decrypt_buf, SSL_SIG_LENGTH); + *prm_len = SSL_SIG_LENGTH; + } else { + if (m_len != SSL_SIG_LENGTH) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); + goto err; + } + + if (memcmp(decrypt_buf, m, SSL_SIG_LENGTH) != 0) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + goto err; + } + } + } else if (type == NID_mdc2 && decrypt_len == 2 + 16 + && decrypt_buf[0] == 0x04 && decrypt_buf[1] == 0x10) { + /* + * Oddball MDC2 case: signature can be OCTET STRING. check for correct + * tag and length octets. + */ + if (rm != NULL) { + memcpy(rm, decrypt_buf + 2, 16); + *prm_len = 16; + } else { + if (m_len != 16) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); + goto err; + } + + if (memcmp(m, decrypt_buf + 2, 16) != 0) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + goto err; + } + } + } else { + /* + * If recovering the digest, extract a digest-sized output from the end + * of |decrypt_buf| for |encode_pkcs1|, then compare the decryption + * output as in a standard verification. + */ + if (rm != NULL) { + const EVP_MD *md = EVP_get_digestbynid(type); + if (md == NULL) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_UNKNOWN_ALGORITHM_TYPE); + goto err; + } + + m_len = EVP_MD_size(md); + if (m_len > (size_t)decrypt_len) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); + goto err; + } + m = decrypt_buf + decrypt_len - m_len; + } + + /* Construct the encoded digest and ensure it matches. */ + if (!encode_pkcs1(&encoded, &encoded_len, type, m, m_len)) + goto err; + + if (encoded_len != decrypt_len + || memcmp(encoded, decrypt_buf, encoded_len) != 0) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + goto err; + } + + /* Output the recovered digest. */ + if (rm != NULL) { + memcpy(rm, m, m_len); + *prm_len = m_len; + } + } + + ret = 1; + +err: + OPENSSL_clear_free(encoded, (size_t)encoded_len); + OPENSSL_clear_free(decrypt_buf, siglen); + return ret; +} + +int RSA_verify(int type, const unsigned char *m, unsigned int m_len, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa) +{ + + if (rsa->meth->rsa_verify) { + return rsa->meth->rsa_verify(type, m, m_len, sigbuf, siglen, rsa); + } + + return int_rsa_verify(type, m, m_len, NULL, NULL, sigbuf, siglen, rsa); +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_ssl.c b/contrib/libs/openssl/crypto/rsa/rsa_ssl.c index e1c755ae46..1a81cec40d 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_ssl.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_ssl.c @@ -1,127 +1,127 @@ -/* +/* * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdio.h> -#include "internal/cryptlib.h" -#include <openssl/bn.h> -#include <openssl/rsa.h> -#include <openssl/rand.h> + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/bn.h> +#include <openssl/rsa.h> +#include <openssl/rand.h> #include "internal/constant_time.h" - -int RSA_padding_add_SSLv23(unsigned char *to, int tlen, - const unsigned char *from, int flen) -{ - int i, j; - unsigned char *p; - + +int RSA_padding_add_SSLv23(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int i, j; + unsigned char *p; + if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) { - RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return 0; - } - - p = (unsigned char *)to; - - *(p++) = 0; - *(p++) = 2; /* Public Key BT (Block Type) */ - - /* pad out with non-zero random data */ - j = tlen - 3 - 8 - flen; - - if (RAND_bytes(p, j) <= 0) - return 0; - for (i = 0; i < j; i++) { - if (*p == '\0') - do { - if (RAND_bytes(p, 1) <= 0) - return 0; - } while (*p == '\0'); - p++; - } - - memset(p, 3, 8); - p += 8; - *(p++) = '\0'; - - memcpy(p, from, (unsigned int)flen); - return 1; -} - -/* - * Copy of RSA_padding_check_PKCS1_type_2 with a twist that rejects padding + RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + p = (unsigned char *)to; + + *(p++) = 0; + *(p++) = 2; /* Public Key BT (Block Type) */ + + /* pad out with non-zero random data */ + j = tlen - 3 - 8 - flen; + + if (RAND_bytes(p, j) <= 0) + return 0; + for (i = 0; i < j; i++) { + if (*p == '\0') + do { + if (RAND_bytes(p, 1) <= 0) + return 0; + } while (*p == '\0'); + p++; + } + + memset(p, 3, 8); + p += 8; + *(p++) = '\0'; + + memcpy(p, from, (unsigned int)flen); + return 1; +} + +/* + * Copy of RSA_padding_check_PKCS1_type_2 with a twist that rejects padding * if nul delimiter is preceded by 8 consecutive 0x03 bytes. It also - * preserves error code reporting for backward compatibility. - */ -int RSA_padding_check_SSLv23(unsigned char *to, int tlen, - const unsigned char *from, int flen, int num) -{ - int i; - /* |em| is the encoded message, zero-padded to exactly |num| bytes */ - unsigned char *em = NULL; - unsigned int good, found_zero_byte, mask, threes_in_row; - int zero_index = 0, msg_index, mlen = -1, err; - + * preserves error code reporting for backward compatibility. + */ +int RSA_padding_check_SSLv23(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num) +{ + int i; + /* |em| is the encoded message, zero-padded to exactly |num| bytes */ + unsigned char *em = NULL; + unsigned int good, found_zero_byte, mask, threes_in_row; + int zero_index = 0, msg_index, mlen = -1, err; + if (tlen <= 0 || flen <= 0) return -1; if (flen > num || num < RSA_PKCS1_PADDING_SIZE) { - RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL); - return -1; - } - - em = OPENSSL_malloc(num); - if (em == NULL) { - RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, ERR_R_MALLOC_FAILURE); - return -1; - } - /* - * Caller is encouraged to pass zero-padded message created with - * BN_bn2binpad. Trouble is that since we can't read out of |from|'s - * bounds, it's impossible to have an invariant memory access pattern - * in case |from| was not zero-padded in advance. - */ - for (from += flen, em += num, i = 0; i < num; i++) { - mask = ~constant_time_is_zero(flen); - flen -= 1 & mask; - from -= 1 & mask; - *--em = *from & mask; - } - + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL); + return -1; + } + + em = OPENSSL_malloc(num); + if (em == NULL) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, ERR_R_MALLOC_FAILURE); + return -1; + } + /* + * Caller is encouraged to pass zero-padded message created with + * BN_bn2binpad. Trouble is that since we can't read out of |from|'s + * bounds, it's impossible to have an invariant memory access pattern + * in case |from| was not zero-padded in advance. + */ + for (from += flen, em += num, i = 0; i < num; i++) { + mask = ~constant_time_is_zero(flen); + flen -= 1 & mask; + from -= 1 & mask; + *--em = *from & mask; + } + good = constant_time_is_zero(em[0]); good &= constant_time_eq(em[1], 2); - err = constant_time_select_int(good, 0, RSA_R_BLOCK_TYPE_IS_NOT_02); - mask = ~good; - - /* scan over padding data */ - found_zero_byte = 0; - threes_in_row = 0; - for (i = 2; i < num; i++) { + err = constant_time_select_int(good, 0, RSA_R_BLOCK_TYPE_IS_NOT_02); + mask = ~good; + + /* scan over padding data */ + found_zero_byte = 0; + threes_in_row = 0; + for (i = 2; i < num; i++) { unsigned int equals0 = constant_time_is_zero(em[i]); - - zero_index = constant_time_select_int(~found_zero_byte & equals0, - i, zero_index); - found_zero_byte |= equals0; - - threes_in_row += 1 & ~found_zero_byte; + + zero_index = constant_time_select_int(~found_zero_byte & equals0, + i, zero_index); + found_zero_byte |= equals0; + + threes_in_row += 1 & ~found_zero_byte; threes_in_row &= found_zero_byte | constant_time_eq(em[i], 3); - } - - /* + } + + /* * PS must be at least 8 bytes long, and it starts two bytes into |em|. - * If we never found a 0-byte, then |zero_index| is 0 and the check - * also fails. - */ - good &= constant_time_ge(zero_index, 2 + 8); - err = constant_time_select_int(mask | good, err, - RSA_R_NULL_BEFORE_BLOCK_MISSING); - mask = ~good; - + * If we never found a 0-byte, then |zero_index| is 0 and the check + * also fails. + */ + good &= constant_time_ge(zero_index, 2 + 8); + err = constant_time_select_int(mask | good, err, + RSA_R_NULL_BEFORE_BLOCK_MISSING); + mask = ~good; + /* * Reject if nul delimiter is preceded by 8 consecutive 0x03 bytes. Note * that RFC5246 incorrectly states this the other way around, i.e. reject @@ -129,24 +129,24 @@ int RSA_padding_check_SSLv23(unsigned char *to, int tlen, * corrected in subsequent errata for that RFC. */ good &= constant_time_lt(threes_in_row, 8); - err = constant_time_select_int(mask | good, err, - RSA_R_SSLV3_ROLLBACK_ATTACK); - mask = ~good; - - /* - * Skip the zero byte. This is incorrect if we never found a zero-byte - * but in this case we also do not copy the message out. - */ - msg_index = zero_index + 1; - mlen = num - msg_index; - - /* - * For good measure, do this check in constant time as well. - */ - good &= constant_time_ge(tlen, mlen); - err = constant_time_select_int(mask | good, err, RSA_R_DATA_TOO_LARGE); - - /* + err = constant_time_select_int(mask | good, err, + RSA_R_SSLV3_ROLLBACK_ATTACK); + mask = ~good; + + /* + * Skip the zero byte. This is incorrect if we never found a zero-byte + * but in this case we also do not copy the message out. + */ + msg_index = zero_index + 1; + mlen = num - msg_index; + + /* + * For good measure, do this check in constant time as well. + */ + good &= constant_time_ge(tlen, mlen); + err = constant_time_select_int(mask | good, err, RSA_R_DATA_TOO_LARGE); + + /* * Move the result in-place by |num|-RSA_PKCS1_PADDING_SIZE-|mlen| bytes to the left. * Then if |good| move |mlen| bytes from |em|+RSA_PKCS1_PADDING_SIZE to |to|. * Otherwise leave |to| unchanged. @@ -155,22 +155,22 @@ int RSA_padding_check_SSLv23(unsigned char *to, int tlen, * parts of the buffer multiple times based on the bits set in the real * length. Clear bits do a non-copy with identical access pattern. * The loop below has overall complexity of O(N*log(N)). - */ + */ tlen = constant_time_select_int(constant_time_lt(num - RSA_PKCS1_PADDING_SIZE, tlen), num - RSA_PKCS1_PADDING_SIZE, tlen); for (msg_index = 1; msg_index < num - RSA_PKCS1_PADDING_SIZE; msg_index <<= 1) { mask = ~constant_time_eq(msg_index & (num - RSA_PKCS1_PADDING_SIZE - mlen), 0); for (i = RSA_PKCS1_PADDING_SIZE; i < num - msg_index; i++) em[i] = constant_time_select_8(mask, em[i + msg_index], em[i]); - } + } for (i = 0; i < tlen; i++) { mask = good & constant_time_lt(i, mlen); to[i] = constant_time_select_8(mask, em[i + RSA_PKCS1_PADDING_SIZE], to[i]); } - - OPENSSL_clear_free(em, num); - RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, err); - err_clear_last_constant_time(1 & good); - - return constant_time_select_int(good, mlen, -1); -} + + OPENSSL_clear_free(em, num); + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, err); + err_clear_last_constant_time(1 & good); + + return constant_time_select_int(good, mlen, -1); +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_x931.c b/contrib/libs/openssl/crypto/rsa/rsa_x931.c index 7b0486c0f2..f34fadb343 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_x931.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_x931.c @@ -1,117 +1,117 @@ -/* - * Copyright 2005-2017 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdio.h> -#include "internal/cryptlib.h" -#include <openssl/bn.h> -#include <openssl/rsa.h> -#include <openssl/objects.h> - -int RSA_padding_add_X931(unsigned char *to, int tlen, - const unsigned char *from, int flen) -{ - int j; - unsigned char *p; - - /* - * Absolute minimum amount of padding is 1 header nibble, 1 padding - * nibble and 2 trailer bytes: but 1 hash if is already in 'from'. - */ - - j = tlen - flen - 2; - - if (j < 0) { - RSAerr(RSA_F_RSA_PADDING_ADD_X931, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return -1; - } - - p = (unsigned char *)to; - - /* If no padding start and end nibbles are in one byte */ - if (j == 0) { - *p++ = 0x6A; - } else { - *p++ = 0x6B; - if (j > 1) { - memset(p, 0xBB, j - 1); - p += j - 1; - } - *p++ = 0xBA; - } - memcpy(p, from, (unsigned int)flen); - p += flen; - *p = 0xCC; - return 1; -} - -int RSA_padding_check_X931(unsigned char *to, int tlen, - const unsigned char *from, int flen, int num) -{ - int i = 0, j; - const unsigned char *p; - - p = from; - if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B))) { - RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_HEADER); - return -1; - } - - if (*p++ == 0x6B) { - j = flen - 3; - for (i = 0; i < j; i++) { - unsigned char c = *p++; - if (c == 0xBA) - break; - if (c != 0xBB) { - RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); - return -1; - } - } - - j -= i; - - if (i == 0) { - RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); - return -1; - } - - } else { - j = flen - 2; - } - - if (p[j] != 0xCC) { - RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER); - return -1; - } - - memcpy(to, p, (unsigned int)j); - - return j; -} - -/* Translate between X931 hash ids and NIDs */ - -int RSA_X931_hash_id(int nid) -{ - switch (nid) { - case NID_sha1: - return 0x33; - - case NID_sha256: - return 0x34; - - case NID_sha384: - return 0x36; - - case NID_sha512: - return 0x35; - - } - return -1; -} +/* + * Copyright 2005-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/bn.h> +#include <openssl/rsa.h> +#include <openssl/objects.h> + +int RSA_padding_add_X931(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int j; + unsigned char *p; + + /* + * Absolute minimum amount of padding is 1 header nibble, 1 padding + * nibble and 2 trailer bytes: but 1 hash if is already in 'from'. + */ + + j = tlen - flen - 2; + + if (j < 0) { + RSAerr(RSA_F_RSA_PADDING_ADD_X931, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return -1; + } + + p = (unsigned char *)to; + + /* If no padding start and end nibbles are in one byte */ + if (j == 0) { + *p++ = 0x6A; + } else { + *p++ = 0x6B; + if (j > 1) { + memset(p, 0xBB, j - 1); + p += j - 1; + } + *p++ = 0xBA; + } + memcpy(p, from, (unsigned int)flen); + p += flen; + *p = 0xCC; + return 1; +} + +int RSA_padding_check_X931(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num) +{ + int i = 0, j; + const unsigned char *p; + + p = from; + if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B))) { + RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_HEADER); + return -1; + } + + if (*p++ == 0x6B) { + j = flen - 3; + for (i = 0; i < j; i++) { + unsigned char c = *p++; + if (c == 0xBA) + break; + if (c != 0xBB) { + RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); + return -1; + } + } + + j -= i; + + if (i == 0) { + RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); + return -1; + } + + } else { + j = flen - 2; + } + + if (p[j] != 0xCC) { + RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER); + return -1; + } + + memcpy(to, p, (unsigned int)j); + + return j; +} + +/* Translate between X931 hash ids and NIDs */ + +int RSA_X931_hash_id(int nid) +{ + switch (nid) { + case NID_sha1: + return 0x33; + + case NID_sha256: + return 0x34; + + case NID_sha384: + return 0x36; + + case NID_sha512: + return 0x35; + + } + return -1; +} diff --git a/contrib/libs/openssl/crypto/rsa/rsa_x931g.c b/contrib/libs/openssl/crypto/rsa/rsa_x931g.c index 322cd14a84..6d4823e1dc 100644 --- a/contrib/libs/openssl/crypto/rsa/rsa_x931g.c +++ b/contrib/libs/openssl/crypto/rsa/rsa_x931g.c @@ -1,198 +1,198 @@ -/* +/* * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <openssl/err.h> -#include <openssl/bn.h> + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <openssl/err.h> +#include <openssl/bn.h> #include "rsa_local.h" - -/* X9.31 RSA key derivation and generation */ - -int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, - BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2, - const BIGNUM *Xp, const BIGNUM *Xq1, const BIGNUM *Xq2, - const BIGNUM *Xq, const BIGNUM *e, BN_GENCB *cb) -{ - BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL; - BN_CTX *ctx = NULL, *ctx2 = NULL; - int ret = 0; - - if (!rsa) - goto err; - - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - BN_CTX_start(ctx); - - r0 = BN_CTX_get(ctx); - r1 = BN_CTX_get(ctx); - r2 = BN_CTX_get(ctx); - r3 = BN_CTX_get(ctx); - - if (r3 == NULL) - goto err; - if (!rsa->e) { - rsa->e = BN_dup(e); - if (!rsa->e) - goto err; - } else { - e = rsa->e; - } - - /* - * If not all parameters present only calculate what we can. This allows - * test programs to output selective parameters. - */ - - if (Xp && rsa->p == NULL) { - rsa->p = BN_new(); - if (rsa->p == NULL) - goto err; - - if (!BN_X931_derive_prime_ex(rsa->p, p1, p2, - Xp, Xp1, Xp2, e, ctx, cb)) - goto err; - } - - if (Xq && rsa->q == NULL) { - rsa->q = BN_new(); - if (rsa->q == NULL) - goto err; - if (!BN_X931_derive_prime_ex(rsa->q, q1, q2, - Xq, Xq1, Xq2, e, ctx, cb)) - goto err; - } - - if (rsa->p == NULL || rsa->q == NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - return 2; - } - - /* - * Since both primes are set we can now calculate all remaining - * components. - */ - - /* calculate n */ - rsa->n = BN_new(); - if (rsa->n == NULL) - goto err; - if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) - goto err; - - /* calculate d */ - if (!BN_sub(r1, rsa->p, BN_value_one())) - goto err; /* p-1 */ - if (!BN_sub(r2, rsa->q, BN_value_one())) - goto err; /* q-1 */ - if (!BN_mul(r0, r1, r2, ctx)) - goto err; /* (p-1)(q-1) */ - - if (!BN_gcd(r3, r1, r2, ctx)) - goto err; - - if (!BN_div(r0, NULL, r0, r3, ctx)) - goto err; /* LCM((p-1)(q-1)) */ - - ctx2 = BN_CTX_new(); - if (ctx2 == NULL) - goto err; - - rsa->d = BN_mod_inverse(NULL, rsa->e, r0, ctx2); /* d */ - if (rsa->d == NULL) - goto err; - - /* calculate d mod (p-1) */ - rsa->dmp1 = BN_new(); - if (rsa->dmp1 == NULL) - goto err; - if (!BN_mod(rsa->dmp1, rsa->d, r1, ctx)) - goto err; - - /* calculate d mod (q-1) */ - rsa->dmq1 = BN_new(); - if (rsa->dmq1 == NULL) - goto err; - if (!BN_mod(rsa->dmq1, rsa->d, r2, ctx)) - goto err; - - /* calculate inverse of q mod p */ - rsa->iqmp = BN_mod_inverse(NULL, rsa->q, rsa->p, ctx2); - if (rsa->iqmp == NULL) - goto err; - - ret = 1; - err: + +/* X9.31 RSA key derivation and generation */ + +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, + BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2, + const BIGNUM *Xp, const BIGNUM *Xq1, const BIGNUM *Xq2, + const BIGNUM *Xq, const BIGNUM *e, BN_GENCB *cb) +{ + BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL; + BN_CTX *ctx = NULL, *ctx2 = NULL; + int ret = 0; + + if (!rsa) + goto err; + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + r3 = BN_CTX_get(ctx); + + if (r3 == NULL) + goto err; + if (!rsa->e) { + rsa->e = BN_dup(e); + if (!rsa->e) + goto err; + } else { + e = rsa->e; + } + + /* + * If not all parameters present only calculate what we can. This allows + * test programs to output selective parameters. + */ + + if (Xp && rsa->p == NULL) { + rsa->p = BN_new(); + if (rsa->p == NULL) + goto err; + + if (!BN_X931_derive_prime_ex(rsa->p, p1, p2, + Xp, Xp1, Xp2, e, ctx, cb)) + goto err; + } + + if (Xq && rsa->q == NULL) { + rsa->q = BN_new(); + if (rsa->q == NULL) + goto err; + if (!BN_X931_derive_prime_ex(rsa->q, q1, q2, + Xq, Xq1, Xq2, e, ctx, cb)) + goto err; + } + + if (rsa->p == NULL || rsa->q == NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return 2; + } + + /* + * Since both primes are set we can now calculate all remaining + * components. + */ + + /* calculate n */ + rsa->n = BN_new(); + if (rsa->n == NULL) + goto err; + if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) + goto err; + + /* calculate d */ + if (!BN_sub(r1, rsa->p, BN_value_one())) + goto err; /* p-1 */ + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; /* q-1 */ + if (!BN_mul(r0, r1, r2, ctx)) + goto err; /* (p-1)(q-1) */ + + if (!BN_gcd(r3, r1, r2, ctx)) + goto err; + + if (!BN_div(r0, NULL, r0, r3, ctx)) + goto err; /* LCM((p-1)(q-1)) */ + + ctx2 = BN_CTX_new(); + if (ctx2 == NULL) + goto err; + + rsa->d = BN_mod_inverse(NULL, rsa->e, r0, ctx2); /* d */ + if (rsa->d == NULL) + goto err; + + /* calculate d mod (p-1) */ + rsa->dmp1 = BN_new(); + if (rsa->dmp1 == NULL) + goto err; + if (!BN_mod(rsa->dmp1, rsa->d, r1, ctx)) + goto err; + + /* calculate d mod (q-1) */ + rsa->dmq1 = BN_new(); + if (rsa->dmq1 == NULL) + goto err; + if (!BN_mod(rsa->dmq1, rsa->d, r2, ctx)) + goto err; + + /* calculate inverse of q mod p */ + rsa->iqmp = BN_mod_inverse(NULL, rsa->q, rsa->p, ctx2); + if (rsa->iqmp == NULL) + goto err; + + ret = 1; + err: BN_CTX_end(ctx); - BN_CTX_free(ctx); - BN_CTX_free(ctx2); - - return ret; - -} - -int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, - BN_GENCB *cb) -{ - int ok = 0; - BIGNUM *Xp = NULL, *Xq = NULL; - BN_CTX *ctx = NULL; - - ctx = BN_CTX_new(); - if (ctx == NULL) - goto error; - - BN_CTX_start(ctx); - Xp = BN_CTX_get(ctx); - Xq = BN_CTX_get(ctx); - if (Xq == NULL) - goto error; - if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx)) - goto error; - - rsa->p = BN_new(); - rsa->q = BN_new(); - if (rsa->p == NULL || rsa->q == NULL) - goto error; - - /* Generate two primes from Xp, Xq */ - - if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp, - e, ctx, cb)) - goto error; - - if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq, - e, ctx, cb)) - goto error; - - /* - * Since rsa->p and rsa->q are valid this call will just derive remaining - * RSA components. - */ - - if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, e, cb)) - goto error; - - ok = 1; - - error: + BN_CTX_free(ctx); + BN_CTX_free(ctx2); + + return ret; + +} + +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, + BN_GENCB *cb) +{ + int ok = 0; + BIGNUM *Xp = NULL, *Xq = NULL; + BN_CTX *ctx = NULL; + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto error; + + BN_CTX_start(ctx); + Xp = BN_CTX_get(ctx); + Xq = BN_CTX_get(ctx); + if (Xq == NULL) + goto error; + if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx)) + goto error; + + rsa->p = BN_new(); + rsa->q = BN_new(); + if (rsa->p == NULL || rsa->q == NULL) + goto error; + + /* Generate two primes from Xp, Xq */ + + if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp, + e, ctx, cb)) + goto error; + + if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq, + e, ctx, cb)) + goto error; + + /* + * Since rsa->p and rsa->q are valid this call will just derive remaining + * RSA components. + */ + + if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, e, cb)) + goto error; + + ok = 1; + + error: BN_CTX_end(ctx); - BN_CTX_free(ctx); - - if (ok) - return 1; - - return 0; - -} + BN_CTX_free(ctx); + + if (ok) + return 1; + + return 0; + +} |