1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * RSA low level APIs are deprecated for public use, but still ok for 12e1051a39Sopenharmony_ci * internal use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <stdio.h> 17e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 18e1051a39Sopenharmony_ci#include <openssl/asn1t.h> 19e1051a39Sopenharmony_ci#include <openssl/x509.h> 20e1051a39Sopenharmony_ci#include <openssl/bn.h> 21e1051a39Sopenharmony_ci#include <openssl/core_names.h> 22e1051a39Sopenharmony_ci#include <openssl/param_build.h> 23e1051a39Sopenharmony_ci#include "crypto/asn1.h" 24e1051a39Sopenharmony_ci#include "crypto/evp.h" 25e1051a39Sopenharmony_ci#include "crypto/rsa.h" 26e1051a39Sopenharmony_ci#include "rsa_local.h" 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_ci/* Set any parameters associated with pkey */ 29e1051a39Sopenharmony_cistatic int rsa_param_encode(const EVP_PKEY *pkey, 30e1051a39Sopenharmony_ci ASN1_STRING **pstr, int *pstrtype) 31e1051a39Sopenharmony_ci{ 32e1051a39Sopenharmony_ci const RSA *rsa = pkey->pkey.rsa; 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_ci *pstr = NULL; 35e1051a39Sopenharmony_ci /* If RSA it's just NULL type */ 36e1051a39Sopenharmony_ci if (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK) != RSA_FLAG_TYPE_RSASSAPSS) { 37e1051a39Sopenharmony_ci *pstrtype = V_ASN1_NULL; 38e1051a39Sopenharmony_ci return 1; 39e1051a39Sopenharmony_ci } 40e1051a39Sopenharmony_ci /* If no PSS parameters we omit parameters entirely */ 41e1051a39Sopenharmony_ci if (rsa->pss == NULL) { 42e1051a39Sopenharmony_ci *pstrtype = V_ASN1_UNDEF; 43e1051a39Sopenharmony_ci return 1; 44e1051a39Sopenharmony_ci } 45e1051a39Sopenharmony_ci /* Encode PSS parameters */ 46e1051a39Sopenharmony_ci if (ASN1_item_pack(rsa->pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), pstr) == NULL) 47e1051a39Sopenharmony_ci return 0; 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_ci *pstrtype = V_ASN1_SEQUENCE; 50e1051a39Sopenharmony_ci return 1; 51e1051a39Sopenharmony_ci} 52e1051a39Sopenharmony_ci/* Decode any parameters and set them in RSA structure */ 53e1051a39Sopenharmony_cistatic int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 54e1051a39Sopenharmony_ci{ 55e1051a39Sopenharmony_ci unsigned char *penc = NULL; 56e1051a39Sopenharmony_ci int penclen; 57e1051a39Sopenharmony_ci ASN1_STRING *str; 58e1051a39Sopenharmony_ci int strtype; 59e1051a39Sopenharmony_ci 60e1051a39Sopenharmony_ci if (!rsa_param_encode(pkey, &str, &strtype)) 61e1051a39Sopenharmony_ci return 0; 62e1051a39Sopenharmony_ci penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); 63e1051a39Sopenharmony_ci if (penclen <= 0) 64e1051a39Sopenharmony_ci return 0; 65e1051a39Sopenharmony_ci if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), 66e1051a39Sopenharmony_ci strtype, str, penc, penclen)) 67e1051a39Sopenharmony_ci return 1; 68e1051a39Sopenharmony_ci 69e1051a39Sopenharmony_ci OPENSSL_free(penc); 70e1051a39Sopenharmony_ci return 0; 71e1051a39Sopenharmony_ci} 72e1051a39Sopenharmony_ci 73e1051a39Sopenharmony_cistatic int rsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) 74e1051a39Sopenharmony_ci{ 75e1051a39Sopenharmony_ci const unsigned char *p; 76e1051a39Sopenharmony_ci int pklen; 77e1051a39Sopenharmony_ci X509_ALGOR *alg; 78e1051a39Sopenharmony_ci RSA *rsa = NULL; 79e1051a39Sopenharmony_ci 80e1051a39Sopenharmony_ci if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &alg, pubkey)) 81e1051a39Sopenharmony_ci return 0; 82e1051a39Sopenharmony_ci if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) 83e1051a39Sopenharmony_ci return 0; 84e1051a39Sopenharmony_ci if (!ossl_rsa_param_decode(rsa, alg)) { 85e1051a39Sopenharmony_ci RSA_free(rsa); 86e1051a39Sopenharmony_ci return 0; 87e1051a39Sopenharmony_ci } 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK); 90e1051a39Sopenharmony_ci switch (pkey->ameth->pkey_id) { 91e1051a39Sopenharmony_ci case EVP_PKEY_RSA: 92e1051a39Sopenharmony_ci RSA_set_flags(rsa, RSA_FLAG_TYPE_RSA); 93e1051a39Sopenharmony_ci break; 94e1051a39Sopenharmony_ci case EVP_PKEY_RSA_PSS: 95e1051a39Sopenharmony_ci RSA_set_flags(rsa, RSA_FLAG_TYPE_RSASSAPSS); 96e1051a39Sopenharmony_ci break; 97e1051a39Sopenharmony_ci default: 98e1051a39Sopenharmony_ci /* Leave the type bits zero */ 99e1051a39Sopenharmony_ci break; 100e1051a39Sopenharmony_ci } 101e1051a39Sopenharmony_ci 102e1051a39Sopenharmony_ci if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa)) { 103e1051a39Sopenharmony_ci RSA_free(rsa); 104e1051a39Sopenharmony_ci return 0; 105e1051a39Sopenharmony_ci } 106e1051a39Sopenharmony_ci return 1; 107e1051a39Sopenharmony_ci} 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_cistatic int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 110e1051a39Sopenharmony_ci{ 111e1051a39Sopenharmony_ci /* 112e1051a39Sopenharmony_ci * Don't check the public/private key, this is mostly for smart 113e1051a39Sopenharmony_ci * cards. 114e1051a39Sopenharmony_ci */ 115e1051a39Sopenharmony_ci if (((RSA_flags(a->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) 116e1051a39Sopenharmony_ci || (RSA_flags(b->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) { 117e1051a39Sopenharmony_ci return 1; 118e1051a39Sopenharmony_ci } 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ci if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 121e1051a39Sopenharmony_ci || BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0) 122e1051a39Sopenharmony_ci return 0; 123e1051a39Sopenharmony_ci return 1; 124e1051a39Sopenharmony_ci} 125e1051a39Sopenharmony_ci 126e1051a39Sopenharmony_cistatic int old_rsa_priv_decode(EVP_PKEY *pkey, 127e1051a39Sopenharmony_ci const unsigned char **pder, int derlen) 128e1051a39Sopenharmony_ci{ 129e1051a39Sopenharmony_ci RSA *rsa; 130e1051a39Sopenharmony_ci 131e1051a39Sopenharmony_ci if ((rsa = d2i_RSAPrivateKey(NULL, pder, derlen)) == NULL) 132e1051a39Sopenharmony_ci return 0; 133e1051a39Sopenharmony_ci EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); 134e1051a39Sopenharmony_ci return 1; 135e1051a39Sopenharmony_ci} 136e1051a39Sopenharmony_ci 137e1051a39Sopenharmony_cistatic int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) 138e1051a39Sopenharmony_ci{ 139e1051a39Sopenharmony_ci return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); 140e1051a39Sopenharmony_ci} 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_cistatic int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 143e1051a39Sopenharmony_ci{ 144e1051a39Sopenharmony_ci unsigned char *rk = NULL; 145e1051a39Sopenharmony_ci int rklen; 146e1051a39Sopenharmony_ci ASN1_STRING *str; 147e1051a39Sopenharmony_ci int strtype; 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci if (!rsa_param_encode(pkey, &str, &strtype)) 150e1051a39Sopenharmony_ci return 0; 151e1051a39Sopenharmony_ci rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ci if (rklen <= 0) { 154e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); 155e1051a39Sopenharmony_ci ASN1_STRING_free(str); 156e1051a39Sopenharmony_ci return 0; 157e1051a39Sopenharmony_ci } 158e1051a39Sopenharmony_ci 159e1051a39Sopenharmony_ci if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, 160e1051a39Sopenharmony_ci strtype, str, rk, rklen)) { 161e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); 162e1051a39Sopenharmony_ci ASN1_STRING_free(str); 163e1051a39Sopenharmony_ci OPENSSL_clear_free(rk, rklen); 164e1051a39Sopenharmony_ci return 0; 165e1051a39Sopenharmony_ci } 166e1051a39Sopenharmony_ci 167e1051a39Sopenharmony_ci return 1; 168e1051a39Sopenharmony_ci} 169e1051a39Sopenharmony_ci 170e1051a39Sopenharmony_cistatic int rsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) 171e1051a39Sopenharmony_ci{ 172e1051a39Sopenharmony_ci int ret = 0; 173e1051a39Sopenharmony_ci RSA *rsa = ossl_rsa_key_from_pkcs8(p8, NULL, NULL); 174e1051a39Sopenharmony_ci 175e1051a39Sopenharmony_ci if (rsa != NULL) { 176e1051a39Sopenharmony_ci ret = 1; 177e1051a39Sopenharmony_ci EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); 178e1051a39Sopenharmony_ci } 179e1051a39Sopenharmony_ci return ret; 180e1051a39Sopenharmony_ci} 181e1051a39Sopenharmony_ci 182e1051a39Sopenharmony_cistatic int int_rsa_size(const EVP_PKEY *pkey) 183e1051a39Sopenharmony_ci{ 184e1051a39Sopenharmony_ci return RSA_size(pkey->pkey.rsa); 185e1051a39Sopenharmony_ci} 186e1051a39Sopenharmony_ci 187e1051a39Sopenharmony_cistatic int rsa_bits(const EVP_PKEY *pkey) 188e1051a39Sopenharmony_ci{ 189e1051a39Sopenharmony_ci return BN_num_bits(pkey->pkey.rsa->n); 190e1051a39Sopenharmony_ci} 191e1051a39Sopenharmony_ci 192e1051a39Sopenharmony_cistatic int rsa_security_bits(const EVP_PKEY *pkey) 193e1051a39Sopenharmony_ci{ 194e1051a39Sopenharmony_ci return RSA_security_bits(pkey->pkey.rsa); 195e1051a39Sopenharmony_ci} 196e1051a39Sopenharmony_ci 197e1051a39Sopenharmony_cistatic void int_rsa_free(EVP_PKEY *pkey) 198e1051a39Sopenharmony_ci{ 199e1051a39Sopenharmony_ci RSA_free(pkey->pkey.rsa); 200e1051a39Sopenharmony_ci} 201e1051a39Sopenharmony_ci 202e1051a39Sopenharmony_cistatic int rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss, 203e1051a39Sopenharmony_ci int indent) 204e1051a39Sopenharmony_ci{ 205e1051a39Sopenharmony_ci int rv = 0; 206e1051a39Sopenharmony_ci X509_ALGOR *maskHash = NULL; 207e1051a39Sopenharmony_ci 208e1051a39Sopenharmony_ci if (!BIO_indent(bp, indent, 128)) 209e1051a39Sopenharmony_ci goto err; 210e1051a39Sopenharmony_ci if (pss_key) { 211e1051a39Sopenharmony_ci if (pss == NULL) { 212e1051a39Sopenharmony_ci if (BIO_puts(bp, "No PSS parameter restrictions\n") <= 0) 213e1051a39Sopenharmony_ci return 0; 214e1051a39Sopenharmony_ci return 1; 215e1051a39Sopenharmony_ci } else { 216e1051a39Sopenharmony_ci if (BIO_puts(bp, "PSS parameter restrictions:") <= 0) 217e1051a39Sopenharmony_ci return 0; 218e1051a39Sopenharmony_ci } 219e1051a39Sopenharmony_ci } else if (pss == NULL) { 220e1051a39Sopenharmony_ci if (BIO_puts(bp,"(INVALID PSS PARAMETERS)\n") <= 0) 221e1051a39Sopenharmony_ci return 0; 222e1051a39Sopenharmony_ci return 1; 223e1051a39Sopenharmony_ci } 224e1051a39Sopenharmony_ci if (BIO_puts(bp, "\n") <= 0) 225e1051a39Sopenharmony_ci goto err; 226e1051a39Sopenharmony_ci if (pss_key) 227e1051a39Sopenharmony_ci indent += 2; 228e1051a39Sopenharmony_ci if (!BIO_indent(bp, indent, 128)) 229e1051a39Sopenharmony_ci goto err; 230e1051a39Sopenharmony_ci if (BIO_puts(bp, "Hash Algorithm: ") <= 0) 231e1051a39Sopenharmony_ci goto err; 232e1051a39Sopenharmony_ci 233e1051a39Sopenharmony_ci if (pss->hashAlgorithm) { 234e1051a39Sopenharmony_ci if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) 235e1051a39Sopenharmony_ci goto err; 236e1051a39Sopenharmony_ci } else if (BIO_puts(bp, "sha1 (default)") <= 0) { 237e1051a39Sopenharmony_ci goto err; 238e1051a39Sopenharmony_ci } 239e1051a39Sopenharmony_ci 240e1051a39Sopenharmony_ci if (BIO_puts(bp, "\n") <= 0) 241e1051a39Sopenharmony_ci goto err; 242e1051a39Sopenharmony_ci 243e1051a39Sopenharmony_ci if (!BIO_indent(bp, indent, 128)) 244e1051a39Sopenharmony_ci goto err; 245e1051a39Sopenharmony_ci 246e1051a39Sopenharmony_ci if (BIO_puts(bp, "Mask Algorithm: ") <= 0) 247e1051a39Sopenharmony_ci goto err; 248e1051a39Sopenharmony_ci if (pss->maskGenAlgorithm) { 249e1051a39Sopenharmony_ci if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0) 250e1051a39Sopenharmony_ci goto err; 251e1051a39Sopenharmony_ci if (BIO_puts(bp, " with ") <= 0) 252e1051a39Sopenharmony_ci goto err; 253e1051a39Sopenharmony_ci maskHash = ossl_x509_algor_mgf1_decode(pss->maskGenAlgorithm); 254e1051a39Sopenharmony_ci if (maskHash != NULL) { 255e1051a39Sopenharmony_ci if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) 256e1051a39Sopenharmony_ci goto err; 257e1051a39Sopenharmony_ci } else if (BIO_puts(bp, "INVALID") <= 0) { 258e1051a39Sopenharmony_ci goto err; 259e1051a39Sopenharmony_ci } 260e1051a39Sopenharmony_ci } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) { 261e1051a39Sopenharmony_ci goto err; 262e1051a39Sopenharmony_ci } 263e1051a39Sopenharmony_ci BIO_puts(bp, "\n"); 264e1051a39Sopenharmony_ci 265e1051a39Sopenharmony_ci if (!BIO_indent(bp, indent, 128)) 266e1051a39Sopenharmony_ci goto err; 267e1051a39Sopenharmony_ci if (BIO_printf(bp, "%s Salt Length: 0x", pss_key ? "Minimum" : "") <= 0) 268e1051a39Sopenharmony_ci goto err; 269e1051a39Sopenharmony_ci if (pss->saltLength) { 270e1051a39Sopenharmony_ci if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) 271e1051a39Sopenharmony_ci goto err; 272e1051a39Sopenharmony_ci } else if (BIO_puts(bp, "14 (default)") <= 0) { 273e1051a39Sopenharmony_ci goto err; 274e1051a39Sopenharmony_ci } 275e1051a39Sopenharmony_ci BIO_puts(bp, "\n"); 276e1051a39Sopenharmony_ci 277e1051a39Sopenharmony_ci if (!BIO_indent(bp, indent, 128)) 278e1051a39Sopenharmony_ci goto err; 279e1051a39Sopenharmony_ci if (BIO_puts(bp, "Trailer Field: 0x") <= 0) 280e1051a39Sopenharmony_ci goto err; 281e1051a39Sopenharmony_ci if (pss->trailerField) { 282e1051a39Sopenharmony_ci if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) 283e1051a39Sopenharmony_ci goto err; 284e1051a39Sopenharmony_ci } else if (BIO_puts(bp, "01 (default)") <= 0) { 285e1051a39Sopenharmony_ci goto err; 286e1051a39Sopenharmony_ci } 287e1051a39Sopenharmony_ci BIO_puts(bp, "\n"); 288e1051a39Sopenharmony_ci 289e1051a39Sopenharmony_ci rv = 1; 290e1051a39Sopenharmony_ci 291e1051a39Sopenharmony_ci err: 292e1051a39Sopenharmony_ci X509_ALGOR_free(maskHash); 293e1051a39Sopenharmony_ci return rv; 294e1051a39Sopenharmony_ci 295e1051a39Sopenharmony_ci} 296e1051a39Sopenharmony_ci 297e1051a39Sopenharmony_cistatic int pkey_rsa_print(BIO *bp, const EVP_PKEY *pkey, int off, int priv) 298e1051a39Sopenharmony_ci{ 299e1051a39Sopenharmony_ci const RSA *x = pkey->pkey.rsa; 300e1051a39Sopenharmony_ci char *str; 301e1051a39Sopenharmony_ci const char *s; 302e1051a39Sopenharmony_ci int ret = 0, mod_len = 0, ex_primes; 303e1051a39Sopenharmony_ci 304e1051a39Sopenharmony_ci if (x->n != NULL) 305e1051a39Sopenharmony_ci mod_len = BN_num_bits(x->n); 306e1051a39Sopenharmony_ci ex_primes = sk_RSA_PRIME_INFO_num(x->prime_infos); 307e1051a39Sopenharmony_ci 308e1051a39Sopenharmony_ci if (!BIO_indent(bp, off, 128)) 309e1051a39Sopenharmony_ci goto err; 310e1051a39Sopenharmony_ci 311e1051a39Sopenharmony_ci if (BIO_printf(bp, "%s ", pkey_is_pss(pkey) ? "RSA-PSS" : "RSA") <= 0) 312e1051a39Sopenharmony_ci goto err; 313e1051a39Sopenharmony_ci 314e1051a39Sopenharmony_ci if (priv && x->d) { 315e1051a39Sopenharmony_ci if (BIO_printf(bp, "Private-Key: (%d bit, %d primes)\n", 316e1051a39Sopenharmony_ci mod_len, ex_primes <= 0 ? 2 : ex_primes + 2) <= 0) 317e1051a39Sopenharmony_ci goto err; 318e1051a39Sopenharmony_ci str = "modulus:"; 319e1051a39Sopenharmony_ci s = "publicExponent:"; 320e1051a39Sopenharmony_ci } else { 321e1051a39Sopenharmony_ci if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0) 322e1051a39Sopenharmony_ci goto err; 323e1051a39Sopenharmony_ci str = "Modulus:"; 324e1051a39Sopenharmony_ci s = "Exponent:"; 325e1051a39Sopenharmony_ci } 326e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, str, x->n, NULL, off)) 327e1051a39Sopenharmony_ci goto err; 328e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, s, x->e, NULL, off)) 329e1051a39Sopenharmony_ci goto err; 330e1051a39Sopenharmony_ci if (priv) { 331e1051a39Sopenharmony_ci int i; 332e1051a39Sopenharmony_ci 333e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, "privateExponent:", x->d, NULL, off)) 334e1051a39Sopenharmony_ci goto err; 335e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, "prime1:", x->p, NULL, off)) 336e1051a39Sopenharmony_ci goto err; 337e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, "prime2:", x->q, NULL, off)) 338e1051a39Sopenharmony_ci goto err; 339e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, "exponent1:", x->dmp1, NULL, off)) 340e1051a39Sopenharmony_ci goto err; 341e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, "exponent2:", x->dmq1, NULL, off)) 342e1051a39Sopenharmony_ci goto err; 343e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, "coefficient:", x->iqmp, NULL, off)) 344e1051a39Sopenharmony_ci goto err; 345e1051a39Sopenharmony_ci for (i = 0; i < sk_RSA_PRIME_INFO_num(x->prime_infos); i++) { 346e1051a39Sopenharmony_ci /* print multi-prime info */ 347e1051a39Sopenharmony_ci BIGNUM *bn = NULL; 348e1051a39Sopenharmony_ci RSA_PRIME_INFO *pinfo; 349e1051a39Sopenharmony_ci int j; 350e1051a39Sopenharmony_ci 351e1051a39Sopenharmony_ci pinfo = sk_RSA_PRIME_INFO_value(x->prime_infos, i); 352e1051a39Sopenharmony_ci for (j = 0; j < 3; j++) { 353e1051a39Sopenharmony_ci if (!BIO_indent(bp, off, 128)) 354e1051a39Sopenharmony_ci goto err; 355e1051a39Sopenharmony_ci switch (j) { 356e1051a39Sopenharmony_ci case 0: 357e1051a39Sopenharmony_ci if (BIO_printf(bp, "prime%d:", i + 3) <= 0) 358e1051a39Sopenharmony_ci goto err; 359e1051a39Sopenharmony_ci bn = pinfo->r; 360e1051a39Sopenharmony_ci break; 361e1051a39Sopenharmony_ci case 1: 362e1051a39Sopenharmony_ci if (BIO_printf(bp, "exponent%d:", i + 3) <= 0) 363e1051a39Sopenharmony_ci goto err; 364e1051a39Sopenharmony_ci bn = pinfo->d; 365e1051a39Sopenharmony_ci break; 366e1051a39Sopenharmony_ci case 2: 367e1051a39Sopenharmony_ci if (BIO_printf(bp, "coefficient%d:", i + 3) <= 0) 368e1051a39Sopenharmony_ci goto err; 369e1051a39Sopenharmony_ci bn = pinfo->t; 370e1051a39Sopenharmony_ci break; 371e1051a39Sopenharmony_ci default: 372e1051a39Sopenharmony_ci break; 373e1051a39Sopenharmony_ci } 374e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, "", bn, NULL, off)) 375e1051a39Sopenharmony_ci goto err; 376e1051a39Sopenharmony_ci } 377e1051a39Sopenharmony_ci } 378e1051a39Sopenharmony_ci } 379e1051a39Sopenharmony_ci if (pkey_is_pss(pkey) && !rsa_pss_param_print(bp, 1, x->pss, off)) 380e1051a39Sopenharmony_ci goto err; 381e1051a39Sopenharmony_ci ret = 1; 382e1051a39Sopenharmony_ci err: 383e1051a39Sopenharmony_ci return ret; 384e1051a39Sopenharmony_ci} 385e1051a39Sopenharmony_ci 386e1051a39Sopenharmony_cistatic int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, 387e1051a39Sopenharmony_ci ASN1_PCTX *ctx) 388e1051a39Sopenharmony_ci{ 389e1051a39Sopenharmony_ci return pkey_rsa_print(bp, pkey, indent, 0); 390e1051a39Sopenharmony_ci} 391e1051a39Sopenharmony_ci 392e1051a39Sopenharmony_cistatic int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, 393e1051a39Sopenharmony_ci ASN1_PCTX *ctx) 394e1051a39Sopenharmony_ci{ 395e1051a39Sopenharmony_ci return pkey_rsa_print(bp, pkey, indent, 1); 396e1051a39Sopenharmony_ci} 397e1051a39Sopenharmony_ci 398e1051a39Sopenharmony_cistatic int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, 399e1051a39Sopenharmony_ci const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) 400e1051a39Sopenharmony_ci{ 401e1051a39Sopenharmony_ci if (OBJ_obj2nid(sigalg->algorithm) == EVP_PKEY_RSA_PSS) { 402e1051a39Sopenharmony_ci int rv; 403e1051a39Sopenharmony_ci RSA_PSS_PARAMS *pss = ossl_rsa_pss_decode(sigalg); 404e1051a39Sopenharmony_ci 405e1051a39Sopenharmony_ci rv = rsa_pss_param_print(bp, 0, pss, indent); 406e1051a39Sopenharmony_ci RSA_PSS_PARAMS_free(pss); 407e1051a39Sopenharmony_ci if (!rv) 408e1051a39Sopenharmony_ci return 0; 409e1051a39Sopenharmony_ci } else if (BIO_puts(bp, "\n") <= 0) { 410e1051a39Sopenharmony_ci return 0; 411e1051a39Sopenharmony_ci } 412e1051a39Sopenharmony_ci if (sig) 413e1051a39Sopenharmony_ci return X509_signature_dump(bp, sig, indent); 414e1051a39Sopenharmony_ci return 1; 415e1051a39Sopenharmony_ci} 416e1051a39Sopenharmony_ci 417e1051a39Sopenharmony_cistatic int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 418e1051a39Sopenharmony_ci{ 419e1051a39Sopenharmony_ci const EVP_MD *md; 420e1051a39Sopenharmony_ci const EVP_MD *mgf1md; 421e1051a39Sopenharmony_ci int min_saltlen; 422e1051a39Sopenharmony_ci 423e1051a39Sopenharmony_ci switch (op) { 424e1051a39Sopenharmony_ci case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 425e1051a39Sopenharmony_ci if (pkey->pkey.rsa->pss != NULL) { 426e1051a39Sopenharmony_ci if (!ossl_rsa_pss_get_param(pkey->pkey.rsa->pss, &md, &mgf1md, 427e1051a39Sopenharmony_ci &min_saltlen)) { 428e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); 429e1051a39Sopenharmony_ci return 0; 430e1051a39Sopenharmony_ci } 431e1051a39Sopenharmony_ci *(int *)arg2 = EVP_MD_get_type(md); 432e1051a39Sopenharmony_ci /* Return of 2 indicates this MD is mandatory */ 433e1051a39Sopenharmony_ci return 2; 434e1051a39Sopenharmony_ci } 435e1051a39Sopenharmony_ci *(int *)arg2 = NID_sha256; 436e1051a39Sopenharmony_ci return 1; 437e1051a39Sopenharmony_ci 438e1051a39Sopenharmony_ci default: 439e1051a39Sopenharmony_ci return -2; 440e1051a39Sopenharmony_ci } 441e1051a39Sopenharmony_ci} 442e1051a39Sopenharmony_ci 443e1051a39Sopenharmony_ci/* 444e1051a39Sopenharmony_ci * Convert EVP_PKEY_CTX in PSS mode into corresponding algorithm parameter, 445e1051a39Sopenharmony_ci * suitable for setting an AlgorithmIdentifier. 446e1051a39Sopenharmony_ci */ 447e1051a39Sopenharmony_ci 448e1051a39Sopenharmony_cistatic RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) 449e1051a39Sopenharmony_ci{ 450e1051a39Sopenharmony_ci const EVP_MD *sigmd, *mgf1md; 451e1051a39Sopenharmony_ci EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); 452e1051a39Sopenharmony_ci int saltlen; 453e1051a39Sopenharmony_ci 454e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0) 455e1051a39Sopenharmony_ci return NULL; 456e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) 457e1051a39Sopenharmony_ci return NULL; 458e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen) <= 0) 459e1051a39Sopenharmony_ci return NULL; 460e1051a39Sopenharmony_ci if (saltlen == -1) { 461e1051a39Sopenharmony_ci saltlen = EVP_MD_get_size(sigmd); 462e1051a39Sopenharmony_ci } else if (saltlen == -2 || saltlen == -3) { 463e1051a39Sopenharmony_ci saltlen = EVP_PKEY_get_size(pk) - EVP_MD_get_size(sigmd) - 2; 464e1051a39Sopenharmony_ci if ((EVP_PKEY_get_bits(pk) & 0x7) == 1) 465e1051a39Sopenharmony_ci saltlen--; 466e1051a39Sopenharmony_ci if (saltlen < 0) 467e1051a39Sopenharmony_ci return NULL; 468e1051a39Sopenharmony_ci } 469e1051a39Sopenharmony_ci 470e1051a39Sopenharmony_ci return ossl_rsa_pss_params_create(sigmd, mgf1md, saltlen); 471e1051a39Sopenharmony_ci} 472e1051a39Sopenharmony_ci 473e1051a39Sopenharmony_ciRSA_PSS_PARAMS *ossl_rsa_pss_params_create(const EVP_MD *sigmd, 474e1051a39Sopenharmony_ci const EVP_MD *mgf1md, int saltlen) 475e1051a39Sopenharmony_ci{ 476e1051a39Sopenharmony_ci RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new(); 477e1051a39Sopenharmony_ci 478e1051a39Sopenharmony_ci if (pss == NULL) 479e1051a39Sopenharmony_ci goto err; 480e1051a39Sopenharmony_ci if (saltlen != 20) { 481e1051a39Sopenharmony_ci pss->saltLength = ASN1_INTEGER_new(); 482e1051a39Sopenharmony_ci if (pss->saltLength == NULL) 483e1051a39Sopenharmony_ci goto err; 484e1051a39Sopenharmony_ci if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) 485e1051a39Sopenharmony_ci goto err; 486e1051a39Sopenharmony_ci } 487e1051a39Sopenharmony_ci if (!ossl_x509_algor_new_from_md(&pss->hashAlgorithm, sigmd)) 488e1051a39Sopenharmony_ci goto err; 489e1051a39Sopenharmony_ci if (mgf1md == NULL) 490e1051a39Sopenharmony_ci mgf1md = sigmd; 491e1051a39Sopenharmony_ci if (!ossl_x509_algor_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) 492e1051a39Sopenharmony_ci goto err; 493e1051a39Sopenharmony_ci if (!ossl_x509_algor_new_from_md(&pss->maskHash, mgf1md)) 494e1051a39Sopenharmony_ci goto err; 495e1051a39Sopenharmony_ci return pss; 496e1051a39Sopenharmony_ci err: 497e1051a39Sopenharmony_ci RSA_PSS_PARAMS_free(pss); 498e1051a39Sopenharmony_ci return NULL; 499e1051a39Sopenharmony_ci} 500e1051a39Sopenharmony_ci 501e1051a39Sopenharmony_ciASN1_STRING *ossl_rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) 502e1051a39Sopenharmony_ci{ 503e1051a39Sopenharmony_ci RSA_PSS_PARAMS *pss = rsa_ctx_to_pss(pkctx); 504e1051a39Sopenharmony_ci ASN1_STRING *os; 505e1051a39Sopenharmony_ci 506e1051a39Sopenharmony_ci if (pss == NULL) 507e1051a39Sopenharmony_ci return NULL; 508e1051a39Sopenharmony_ci 509e1051a39Sopenharmony_ci os = ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), NULL); 510e1051a39Sopenharmony_ci RSA_PSS_PARAMS_free(pss); 511e1051a39Sopenharmony_ci return os; 512e1051a39Sopenharmony_ci} 513e1051a39Sopenharmony_ci 514e1051a39Sopenharmony_ci/* 515e1051a39Sopenharmony_ci * From PSS AlgorithmIdentifier set public key parameters. If pkey isn't NULL 516e1051a39Sopenharmony_ci * then the EVP_MD_CTX is setup and initialised. If it is NULL parameters are 517e1051a39Sopenharmony_ci * passed to pkctx instead. 518e1051a39Sopenharmony_ci */ 519e1051a39Sopenharmony_ci 520e1051a39Sopenharmony_ciint ossl_rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, 521e1051a39Sopenharmony_ci const X509_ALGOR *sigalg, EVP_PKEY *pkey) 522e1051a39Sopenharmony_ci{ 523e1051a39Sopenharmony_ci int rv = -1; 524e1051a39Sopenharmony_ci int saltlen; 525e1051a39Sopenharmony_ci const EVP_MD *mgf1md = NULL, *md = NULL; 526e1051a39Sopenharmony_ci RSA_PSS_PARAMS *pss; 527e1051a39Sopenharmony_ci 528e1051a39Sopenharmony_ci /* Sanity check: make sure it is PSS */ 529e1051a39Sopenharmony_ci if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { 530e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); 531e1051a39Sopenharmony_ci return -1; 532e1051a39Sopenharmony_ci } 533e1051a39Sopenharmony_ci /* Decode PSS parameters */ 534e1051a39Sopenharmony_ci pss = ossl_rsa_pss_decode(sigalg); 535e1051a39Sopenharmony_ci 536e1051a39Sopenharmony_ci if (!ossl_rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) { 537e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PSS_PARAMETERS); 538e1051a39Sopenharmony_ci goto err; 539e1051a39Sopenharmony_ci } 540e1051a39Sopenharmony_ci 541e1051a39Sopenharmony_ci /* We have all parameters now set up context */ 542e1051a39Sopenharmony_ci if (pkey) { 543e1051a39Sopenharmony_ci if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) 544e1051a39Sopenharmony_ci goto err; 545e1051a39Sopenharmony_ci } else { 546e1051a39Sopenharmony_ci const EVP_MD *checkmd; 547e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) 548e1051a39Sopenharmony_ci goto err; 549e1051a39Sopenharmony_ci if (EVP_MD_get_type(md) != EVP_MD_get_type(checkmd)) { 550e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_DIGEST_DOES_NOT_MATCH); 551e1051a39Sopenharmony_ci goto err; 552e1051a39Sopenharmony_ci } 553e1051a39Sopenharmony_ci } 554e1051a39Sopenharmony_ci 555e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) 556e1051a39Sopenharmony_ci goto err; 557e1051a39Sopenharmony_ci 558e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) 559e1051a39Sopenharmony_ci goto err; 560e1051a39Sopenharmony_ci 561e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) 562e1051a39Sopenharmony_ci goto err; 563e1051a39Sopenharmony_ci /* Carry on */ 564e1051a39Sopenharmony_ci rv = 1; 565e1051a39Sopenharmony_ci 566e1051a39Sopenharmony_ci err: 567e1051a39Sopenharmony_ci RSA_PSS_PARAMS_free(pss); 568e1051a39Sopenharmony_ci return rv; 569e1051a39Sopenharmony_ci} 570e1051a39Sopenharmony_ci 571e1051a39Sopenharmony_cistatic int rsa_pss_verify_param(const EVP_MD **pmd, const EVP_MD **pmgf1md, 572e1051a39Sopenharmony_ci int *psaltlen, int *ptrailerField) 573e1051a39Sopenharmony_ci{ 574e1051a39Sopenharmony_ci if (psaltlen != NULL && *psaltlen < 0) { 575e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_SALT_LENGTH); 576e1051a39Sopenharmony_ci return 0; 577e1051a39Sopenharmony_ci } 578e1051a39Sopenharmony_ci /* 579e1051a39Sopenharmony_ci * low-level routines support only trailer field 0xbc (value 1) and 580e1051a39Sopenharmony_ci * PKCS#1 says we should reject any other value anyway. 581e1051a39Sopenharmony_ci */ 582e1051a39Sopenharmony_ci if (ptrailerField != NULL && *ptrailerField != 1) { 583e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_TRAILER); 584e1051a39Sopenharmony_ci return 0; 585e1051a39Sopenharmony_ci } 586e1051a39Sopenharmony_ci return 1; 587e1051a39Sopenharmony_ci} 588e1051a39Sopenharmony_ci 589e1051a39Sopenharmony_ciint ossl_rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, 590e1051a39Sopenharmony_ci const EVP_MD **pmgf1md, int *psaltlen) 591e1051a39Sopenharmony_ci{ 592e1051a39Sopenharmony_ci /* 593e1051a39Sopenharmony_ci * Callers do not care about the trailer field, and yet, we must 594e1051a39Sopenharmony_ci * pass it from get_param to verify_param, since the latter checks 595e1051a39Sopenharmony_ci * its value. 596e1051a39Sopenharmony_ci * 597e1051a39Sopenharmony_ci * When callers start caring, it's a simple thing to add another 598e1051a39Sopenharmony_ci * argument to this function. 599e1051a39Sopenharmony_ci */ 600e1051a39Sopenharmony_ci int trailerField = 0; 601e1051a39Sopenharmony_ci 602e1051a39Sopenharmony_ci return ossl_rsa_pss_get_param_unverified(pss, pmd, pmgf1md, psaltlen, 603e1051a39Sopenharmony_ci &trailerField) 604e1051a39Sopenharmony_ci && rsa_pss_verify_param(pmd, pmgf1md, psaltlen, &trailerField); 605e1051a39Sopenharmony_ci} 606e1051a39Sopenharmony_ci 607e1051a39Sopenharmony_ci/* 608e1051a39Sopenharmony_ci * Customised RSA item verification routine. This is called when a signature 609e1051a39Sopenharmony_ci * is encountered requiring special handling. We currently only handle PSS. 610e1051a39Sopenharmony_ci */ 611e1051a39Sopenharmony_ci 612e1051a39Sopenharmony_cistatic int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, 613e1051a39Sopenharmony_ci const void *asn, const X509_ALGOR *sigalg, 614e1051a39Sopenharmony_ci const ASN1_BIT_STRING *sig, EVP_PKEY *pkey) 615e1051a39Sopenharmony_ci{ 616e1051a39Sopenharmony_ci /* Sanity check: make sure it is PSS */ 617e1051a39Sopenharmony_ci if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { 618e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); 619e1051a39Sopenharmony_ci return -1; 620e1051a39Sopenharmony_ci } 621e1051a39Sopenharmony_ci if (ossl_rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { 622e1051a39Sopenharmony_ci /* Carry on */ 623e1051a39Sopenharmony_ci return 2; 624e1051a39Sopenharmony_ci } 625e1051a39Sopenharmony_ci return -1; 626e1051a39Sopenharmony_ci} 627e1051a39Sopenharmony_ci 628e1051a39Sopenharmony_cistatic int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn, 629e1051a39Sopenharmony_ci X509_ALGOR *alg1, X509_ALGOR *alg2, 630e1051a39Sopenharmony_ci ASN1_BIT_STRING *sig) 631e1051a39Sopenharmony_ci{ 632e1051a39Sopenharmony_ci int pad_mode; 633e1051a39Sopenharmony_ci EVP_PKEY_CTX *pkctx = EVP_MD_CTX_get_pkey_ctx(ctx); 634e1051a39Sopenharmony_ci 635e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) 636e1051a39Sopenharmony_ci return 0; 637e1051a39Sopenharmony_ci if (pad_mode == RSA_PKCS1_PADDING) 638e1051a39Sopenharmony_ci return 2; 639e1051a39Sopenharmony_ci if (pad_mode == RSA_PKCS1_PSS_PADDING) { 640e1051a39Sopenharmony_ci unsigned char aid[128]; 641e1051a39Sopenharmony_ci size_t aid_len = 0; 642e1051a39Sopenharmony_ci OSSL_PARAM params[2]; 643e1051a39Sopenharmony_ci 644e1051a39Sopenharmony_ci params[0] = OSSL_PARAM_construct_octet_string( 645e1051a39Sopenharmony_ci OSSL_SIGNATURE_PARAM_ALGORITHM_ID, aid, sizeof(aid)); 646e1051a39Sopenharmony_ci params[1] = OSSL_PARAM_construct_end(); 647e1051a39Sopenharmony_ci 648e1051a39Sopenharmony_ci if (EVP_PKEY_CTX_get_params(pkctx, params) <= 0) 649e1051a39Sopenharmony_ci return 0; 650e1051a39Sopenharmony_ci if ((aid_len = params[0].return_size) == 0) 651e1051a39Sopenharmony_ci return 0; 652e1051a39Sopenharmony_ci 653e1051a39Sopenharmony_ci if (alg1 != NULL) { 654e1051a39Sopenharmony_ci const unsigned char *pp = aid; 655e1051a39Sopenharmony_ci if (d2i_X509_ALGOR(&alg1, &pp, aid_len) == NULL) 656e1051a39Sopenharmony_ci return 0; 657e1051a39Sopenharmony_ci } 658e1051a39Sopenharmony_ci if (alg2 != NULL) { 659e1051a39Sopenharmony_ci const unsigned char *pp = aid; 660e1051a39Sopenharmony_ci if (d2i_X509_ALGOR(&alg2, &pp, aid_len) == NULL) 661e1051a39Sopenharmony_ci return 0; 662e1051a39Sopenharmony_ci } 663e1051a39Sopenharmony_ci 664e1051a39Sopenharmony_ci return 3; 665e1051a39Sopenharmony_ci } 666e1051a39Sopenharmony_ci return 2; 667e1051a39Sopenharmony_ci} 668e1051a39Sopenharmony_ci 669e1051a39Sopenharmony_cistatic int rsa_sig_info_set(X509_SIG_INFO *siginf, const X509_ALGOR *sigalg, 670e1051a39Sopenharmony_ci const ASN1_STRING *sig) 671e1051a39Sopenharmony_ci{ 672e1051a39Sopenharmony_ci int rv = 0; 673e1051a39Sopenharmony_ci int mdnid, saltlen; 674e1051a39Sopenharmony_ci uint32_t flags; 675e1051a39Sopenharmony_ci const EVP_MD *mgf1md = NULL, *md = NULL; 676e1051a39Sopenharmony_ci RSA_PSS_PARAMS *pss; 677e1051a39Sopenharmony_ci int secbits; 678e1051a39Sopenharmony_ci 679e1051a39Sopenharmony_ci /* Sanity check: make sure it is PSS */ 680e1051a39Sopenharmony_ci if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) 681e1051a39Sopenharmony_ci return 0; 682e1051a39Sopenharmony_ci /* Decode PSS parameters */ 683e1051a39Sopenharmony_ci pss = ossl_rsa_pss_decode(sigalg); 684e1051a39Sopenharmony_ci if (!ossl_rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) 685e1051a39Sopenharmony_ci goto err; 686e1051a39Sopenharmony_ci mdnid = EVP_MD_get_type(md); 687e1051a39Sopenharmony_ci /* 688e1051a39Sopenharmony_ci * For TLS need SHA256, SHA384 or SHA512, digest and MGF1 digest must 689e1051a39Sopenharmony_ci * match and salt length must equal digest size 690e1051a39Sopenharmony_ci */ 691e1051a39Sopenharmony_ci if ((mdnid == NID_sha256 || mdnid == NID_sha384 || mdnid == NID_sha512) 692e1051a39Sopenharmony_ci && mdnid == EVP_MD_get_type(mgf1md) 693e1051a39Sopenharmony_ci && saltlen == EVP_MD_get_size(md)) 694e1051a39Sopenharmony_ci flags = X509_SIG_INFO_TLS; 695e1051a39Sopenharmony_ci else 696e1051a39Sopenharmony_ci flags = 0; 697e1051a39Sopenharmony_ci /* Note: security bits half number of digest bits */ 698e1051a39Sopenharmony_ci secbits = EVP_MD_get_size(md) * 4; 699e1051a39Sopenharmony_ci /* 700e1051a39Sopenharmony_ci * SHA1 and MD5 are known to be broken. Reduce security bits so that 701e1051a39Sopenharmony_ci * they're no longer accepted at security level 1. The real values don't 702e1051a39Sopenharmony_ci * really matter as long as they're lower than 80, which is our security 703e1051a39Sopenharmony_ci * level 1. 704e1051a39Sopenharmony_ci * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack for SHA1 at 705e1051a39Sopenharmony_ci * 2^63.4 706e1051a39Sopenharmony_ci * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf 707e1051a39Sopenharmony_ci * puts a chosen-prefix attack for MD5 at 2^39. 708e1051a39Sopenharmony_ci */ 709e1051a39Sopenharmony_ci if (mdnid == NID_sha1) 710e1051a39Sopenharmony_ci secbits = 64; 711e1051a39Sopenharmony_ci else if (mdnid == NID_md5_sha1) 712e1051a39Sopenharmony_ci secbits = 68; 713e1051a39Sopenharmony_ci else if (mdnid == NID_md5) 714e1051a39Sopenharmony_ci secbits = 39; 715e1051a39Sopenharmony_ci X509_SIG_INFO_set(siginf, mdnid, EVP_PKEY_RSA_PSS, secbits, 716e1051a39Sopenharmony_ci flags); 717e1051a39Sopenharmony_ci rv = 1; 718e1051a39Sopenharmony_ci err: 719e1051a39Sopenharmony_ci RSA_PSS_PARAMS_free(pss); 720e1051a39Sopenharmony_ci return rv; 721e1051a39Sopenharmony_ci} 722e1051a39Sopenharmony_ci 723e1051a39Sopenharmony_cistatic int rsa_pkey_check(const EVP_PKEY *pkey) 724e1051a39Sopenharmony_ci{ 725e1051a39Sopenharmony_ci return RSA_check_key_ex(pkey->pkey.rsa, NULL); 726e1051a39Sopenharmony_ci} 727e1051a39Sopenharmony_ci 728e1051a39Sopenharmony_cistatic size_t rsa_pkey_dirty_cnt(const EVP_PKEY *pkey) 729e1051a39Sopenharmony_ci{ 730e1051a39Sopenharmony_ci return pkey->pkey.rsa->dirty_cnt; 731e1051a39Sopenharmony_ci} 732e1051a39Sopenharmony_ci 733e1051a39Sopenharmony_ci/* 734e1051a39Sopenharmony_ci * There is no need to do RSA_test_flags(rsa, RSA_FLAG_TYPE_RSASSAPSS) 735e1051a39Sopenharmony_ci * checks in this method since the caller tests EVP_KEYMGMT_is_a() first. 736e1051a39Sopenharmony_ci */ 737e1051a39Sopenharmony_cistatic int rsa_int_export_to(const EVP_PKEY *from, int rsa_type, 738e1051a39Sopenharmony_ci void *to_keydata, 739e1051a39Sopenharmony_ci OSSL_FUNC_keymgmt_import_fn *importer, 740e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, const char *propq) 741e1051a39Sopenharmony_ci{ 742e1051a39Sopenharmony_ci RSA *rsa = from->pkey.rsa; 743e1051a39Sopenharmony_ci OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new(); 744e1051a39Sopenharmony_ci OSSL_PARAM *params = NULL; 745e1051a39Sopenharmony_ci int selection = 0; 746e1051a39Sopenharmony_ci int rv = 0; 747e1051a39Sopenharmony_ci 748e1051a39Sopenharmony_ci if (tmpl == NULL) 749e1051a39Sopenharmony_ci return 0; 750e1051a39Sopenharmony_ci /* Public parameters must always be present */ 751e1051a39Sopenharmony_ci if (RSA_get0_n(rsa) == NULL || RSA_get0_e(rsa) == NULL) 752e1051a39Sopenharmony_ci goto err; 753e1051a39Sopenharmony_ci 754e1051a39Sopenharmony_ci if (!ossl_rsa_todata(rsa, tmpl, NULL, 1)) 755e1051a39Sopenharmony_ci goto err; 756e1051a39Sopenharmony_ci 757e1051a39Sopenharmony_ci selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY; 758e1051a39Sopenharmony_ci if (RSA_get0_d(rsa) != NULL) 759e1051a39Sopenharmony_ci selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY; 760e1051a39Sopenharmony_ci 761e1051a39Sopenharmony_ci if (rsa->pss != NULL) { 762e1051a39Sopenharmony_ci const EVP_MD *md = NULL, *mgf1md = NULL; 763e1051a39Sopenharmony_ci int md_nid, mgf1md_nid, saltlen, trailerfield; 764e1051a39Sopenharmony_ci RSA_PSS_PARAMS_30 pss_params; 765e1051a39Sopenharmony_ci 766e1051a39Sopenharmony_ci if (!ossl_rsa_pss_get_param_unverified(rsa->pss, &md, &mgf1md, 767e1051a39Sopenharmony_ci &saltlen, &trailerfield)) 768e1051a39Sopenharmony_ci goto err; 769e1051a39Sopenharmony_ci md_nid = EVP_MD_get_type(md); 770e1051a39Sopenharmony_ci mgf1md_nid = EVP_MD_get_type(mgf1md); 771e1051a39Sopenharmony_ci if (!ossl_rsa_pss_params_30_set_defaults(&pss_params) 772e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_hashalg(&pss_params, md_nid) 773e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_maskgenhashalg(&pss_params, 774e1051a39Sopenharmony_ci mgf1md_nid) 775e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_set_saltlen(&pss_params, saltlen) 776e1051a39Sopenharmony_ci || !ossl_rsa_pss_params_30_todata(&pss_params, tmpl, NULL)) 777e1051a39Sopenharmony_ci goto err; 778e1051a39Sopenharmony_ci selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS; 779e1051a39Sopenharmony_ci } 780e1051a39Sopenharmony_ci 781e1051a39Sopenharmony_ci if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) 782e1051a39Sopenharmony_ci goto err; 783e1051a39Sopenharmony_ci 784e1051a39Sopenharmony_ci /* We export, the provider imports */ 785e1051a39Sopenharmony_ci rv = importer(to_keydata, selection, params); 786e1051a39Sopenharmony_ci 787e1051a39Sopenharmony_ci err: 788e1051a39Sopenharmony_ci OSSL_PARAM_free(params); 789e1051a39Sopenharmony_ci OSSL_PARAM_BLD_free(tmpl); 790e1051a39Sopenharmony_ci return rv; 791e1051a39Sopenharmony_ci} 792e1051a39Sopenharmony_ci 793e1051a39Sopenharmony_cistatic int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, 794e1051a39Sopenharmony_ci int rsa_type) 795e1051a39Sopenharmony_ci{ 796e1051a39Sopenharmony_ci EVP_PKEY_CTX *pctx = vpctx; 797e1051a39Sopenharmony_ci EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); 798e1051a39Sopenharmony_ci RSA *rsa = ossl_rsa_new_with_ctx(pctx->libctx); 799e1051a39Sopenharmony_ci RSA_PSS_PARAMS_30 rsa_pss_params = { 0, }; 800e1051a39Sopenharmony_ci int pss_defaults_set = 0; 801e1051a39Sopenharmony_ci int ok = 0; 802e1051a39Sopenharmony_ci 803e1051a39Sopenharmony_ci if (rsa == NULL) { 804e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); 805e1051a39Sopenharmony_ci return 0; 806e1051a39Sopenharmony_ci } 807e1051a39Sopenharmony_ci 808e1051a39Sopenharmony_ci RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK); 809e1051a39Sopenharmony_ci RSA_set_flags(rsa, rsa_type); 810e1051a39Sopenharmony_ci 811e1051a39Sopenharmony_ci if (!ossl_rsa_pss_params_30_fromdata(&rsa_pss_params, &pss_defaults_set, 812e1051a39Sopenharmony_ci params, pctx->libctx)) 813e1051a39Sopenharmony_ci goto err; 814e1051a39Sopenharmony_ci 815e1051a39Sopenharmony_ci switch (rsa_type) { 816e1051a39Sopenharmony_ci case RSA_FLAG_TYPE_RSA: 817e1051a39Sopenharmony_ci /* 818e1051a39Sopenharmony_ci * Were PSS parameters filled in? 819e1051a39Sopenharmony_ci * In that case, something's wrong 820e1051a39Sopenharmony_ci */ 821e1051a39Sopenharmony_ci if (!ossl_rsa_pss_params_30_is_unrestricted(&rsa_pss_params)) 822e1051a39Sopenharmony_ci goto err; 823e1051a39Sopenharmony_ci break; 824e1051a39Sopenharmony_ci case RSA_FLAG_TYPE_RSASSAPSS: 825e1051a39Sopenharmony_ci /* 826e1051a39Sopenharmony_ci * Were PSS parameters filled in? In that case, create the old 827e1051a39Sopenharmony_ci * RSA_PSS_PARAMS structure. Otherwise, this is an unrestricted key. 828e1051a39Sopenharmony_ci */ 829e1051a39Sopenharmony_ci if (!ossl_rsa_pss_params_30_is_unrestricted(&rsa_pss_params)) { 830e1051a39Sopenharmony_ci /* Create the older RSA_PSS_PARAMS from RSA_PSS_PARAMS_30 data */ 831e1051a39Sopenharmony_ci int mdnid = ossl_rsa_pss_params_30_hashalg(&rsa_pss_params); 832e1051a39Sopenharmony_ci int mgf1mdnid = ossl_rsa_pss_params_30_maskgenhashalg(&rsa_pss_params); 833e1051a39Sopenharmony_ci int saltlen = ossl_rsa_pss_params_30_saltlen(&rsa_pss_params); 834e1051a39Sopenharmony_ci const EVP_MD *md = EVP_get_digestbynid(mdnid); 835e1051a39Sopenharmony_ci const EVP_MD *mgf1md = EVP_get_digestbynid(mgf1mdnid); 836e1051a39Sopenharmony_ci 837e1051a39Sopenharmony_ci if ((rsa->pss = ossl_rsa_pss_params_create(md, mgf1md, 838e1051a39Sopenharmony_ci saltlen)) == NULL) 839e1051a39Sopenharmony_ci goto err; 840e1051a39Sopenharmony_ci } 841e1051a39Sopenharmony_ci break; 842e1051a39Sopenharmony_ci default: 843e1051a39Sopenharmony_ci /* RSA key sub-types we don't know how to handle yet */ 844e1051a39Sopenharmony_ci goto err; 845e1051a39Sopenharmony_ci } 846e1051a39Sopenharmony_ci 847e1051a39Sopenharmony_ci if (!ossl_rsa_fromdata(rsa, params, 1)) 848e1051a39Sopenharmony_ci goto err; 849e1051a39Sopenharmony_ci 850e1051a39Sopenharmony_ci switch (rsa_type) { 851e1051a39Sopenharmony_ci case RSA_FLAG_TYPE_RSA: 852e1051a39Sopenharmony_ci ok = EVP_PKEY_assign_RSA(pkey, rsa); 853e1051a39Sopenharmony_ci break; 854e1051a39Sopenharmony_ci case RSA_FLAG_TYPE_RSASSAPSS: 855e1051a39Sopenharmony_ci ok = EVP_PKEY_assign(pkey, EVP_PKEY_RSA_PSS, rsa); 856e1051a39Sopenharmony_ci break; 857e1051a39Sopenharmony_ci } 858e1051a39Sopenharmony_ci 859e1051a39Sopenharmony_ci err: 860e1051a39Sopenharmony_ci if (!ok) 861e1051a39Sopenharmony_ci RSA_free(rsa); 862e1051a39Sopenharmony_ci return ok; 863e1051a39Sopenharmony_ci} 864e1051a39Sopenharmony_ci 865e1051a39Sopenharmony_cistatic int rsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata, 866e1051a39Sopenharmony_ci OSSL_FUNC_keymgmt_import_fn *importer, 867e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, const char *propq) 868e1051a39Sopenharmony_ci{ 869e1051a39Sopenharmony_ci return rsa_int_export_to(from, RSA_FLAG_TYPE_RSA, to_keydata, 870e1051a39Sopenharmony_ci importer, libctx, propq); 871e1051a39Sopenharmony_ci} 872e1051a39Sopenharmony_ci 873e1051a39Sopenharmony_cistatic int rsa_pss_pkey_export_to(const EVP_PKEY *from, void *to_keydata, 874e1051a39Sopenharmony_ci OSSL_FUNC_keymgmt_import_fn *importer, 875e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, const char *propq) 876e1051a39Sopenharmony_ci{ 877e1051a39Sopenharmony_ci return rsa_int_export_to(from, RSA_FLAG_TYPE_RSASSAPSS, to_keydata, 878e1051a39Sopenharmony_ci importer, libctx, propq); 879e1051a39Sopenharmony_ci} 880e1051a39Sopenharmony_ci 881e1051a39Sopenharmony_cistatic int rsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx) 882e1051a39Sopenharmony_ci{ 883e1051a39Sopenharmony_ci return rsa_int_import_from(params, vpctx, RSA_FLAG_TYPE_RSA); 884e1051a39Sopenharmony_ci} 885e1051a39Sopenharmony_ci 886e1051a39Sopenharmony_cistatic int rsa_pss_pkey_import_from(const OSSL_PARAM params[], void *vpctx) 887e1051a39Sopenharmony_ci{ 888e1051a39Sopenharmony_ci return rsa_int_import_from(params, vpctx, RSA_FLAG_TYPE_RSASSAPSS); 889e1051a39Sopenharmony_ci} 890e1051a39Sopenharmony_ci 891e1051a39Sopenharmony_cistatic int rsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) 892e1051a39Sopenharmony_ci{ 893e1051a39Sopenharmony_ci RSA *rsa = from->pkey.rsa; 894e1051a39Sopenharmony_ci RSA *dupkey = NULL; 895e1051a39Sopenharmony_ci int ret; 896e1051a39Sopenharmony_ci 897e1051a39Sopenharmony_ci if (rsa != NULL) { 898e1051a39Sopenharmony_ci dupkey = ossl_rsa_dup(rsa, OSSL_KEYMGMT_SELECT_ALL); 899e1051a39Sopenharmony_ci if (dupkey == NULL) 900e1051a39Sopenharmony_ci return 0; 901e1051a39Sopenharmony_ci } 902e1051a39Sopenharmony_ci 903e1051a39Sopenharmony_ci ret = EVP_PKEY_assign(to, from->type, dupkey); 904e1051a39Sopenharmony_ci if (!ret) 905e1051a39Sopenharmony_ci RSA_free(dupkey); 906e1051a39Sopenharmony_ci return ret; 907e1051a39Sopenharmony_ci} 908e1051a39Sopenharmony_ci 909e1051a39Sopenharmony_ciconst EVP_PKEY_ASN1_METHOD ossl_rsa_asn1_meths[2] = { 910e1051a39Sopenharmony_ci { 911e1051a39Sopenharmony_ci EVP_PKEY_RSA, 912e1051a39Sopenharmony_ci EVP_PKEY_RSA, 913e1051a39Sopenharmony_ci ASN1_PKEY_SIGPARAM_NULL, 914e1051a39Sopenharmony_ci 915e1051a39Sopenharmony_ci "RSA", 916e1051a39Sopenharmony_ci "OpenSSL RSA method", 917e1051a39Sopenharmony_ci 918e1051a39Sopenharmony_ci rsa_pub_decode, 919e1051a39Sopenharmony_ci rsa_pub_encode, 920e1051a39Sopenharmony_ci rsa_pub_cmp, 921e1051a39Sopenharmony_ci rsa_pub_print, 922e1051a39Sopenharmony_ci 923e1051a39Sopenharmony_ci rsa_priv_decode, 924e1051a39Sopenharmony_ci rsa_priv_encode, 925e1051a39Sopenharmony_ci rsa_priv_print, 926e1051a39Sopenharmony_ci 927e1051a39Sopenharmony_ci int_rsa_size, 928e1051a39Sopenharmony_ci rsa_bits, 929e1051a39Sopenharmony_ci rsa_security_bits, 930e1051a39Sopenharmony_ci 931e1051a39Sopenharmony_ci 0, 0, 0, 0, 0, 0, 932e1051a39Sopenharmony_ci 933e1051a39Sopenharmony_ci rsa_sig_print, 934e1051a39Sopenharmony_ci int_rsa_free, 935e1051a39Sopenharmony_ci rsa_pkey_ctrl, 936e1051a39Sopenharmony_ci old_rsa_priv_decode, 937e1051a39Sopenharmony_ci old_rsa_priv_encode, 938e1051a39Sopenharmony_ci rsa_item_verify, 939e1051a39Sopenharmony_ci rsa_item_sign, 940e1051a39Sopenharmony_ci rsa_sig_info_set, 941e1051a39Sopenharmony_ci rsa_pkey_check, 942e1051a39Sopenharmony_ci 943e1051a39Sopenharmony_ci 0, 0, 944e1051a39Sopenharmony_ci 0, 0, 0, 0, 945e1051a39Sopenharmony_ci 946e1051a39Sopenharmony_ci rsa_pkey_dirty_cnt, 947e1051a39Sopenharmony_ci rsa_pkey_export_to, 948e1051a39Sopenharmony_ci rsa_pkey_import_from, 949e1051a39Sopenharmony_ci rsa_pkey_copy 950e1051a39Sopenharmony_ci }, 951e1051a39Sopenharmony_ci 952e1051a39Sopenharmony_ci { 953e1051a39Sopenharmony_ci EVP_PKEY_RSA2, 954e1051a39Sopenharmony_ci EVP_PKEY_RSA, 955e1051a39Sopenharmony_ci ASN1_PKEY_ALIAS} 956e1051a39Sopenharmony_ci}; 957e1051a39Sopenharmony_ci 958e1051a39Sopenharmony_ciconst EVP_PKEY_ASN1_METHOD ossl_rsa_pss_asn1_meth = { 959e1051a39Sopenharmony_ci EVP_PKEY_RSA_PSS, 960e1051a39Sopenharmony_ci EVP_PKEY_RSA_PSS, 961e1051a39Sopenharmony_ci ASN1_PKEY_SIGPARAM_NULL, 962e1051a39Sopenharmony_ci 963e1051a39Sopenharmony_ci "RSA-PSS", 964e1051a39Sopenharmony_ci "OpenSSL RSA-PSS method", 965e1051a39Sopenharmony_ci 966e1051a39Sopenharmony_ci rsa_pub_decode, 967e1051a39Sopenharmony_ci rsa_pub_encode, 968e1051a39Sopenharmony_ci rsa_pub_cmp, 969e1051a39Sopenharmony_ci rsa_pub_print, 970e1051a39Sopenharmony_ci 971e1051a39Sopenharmony_ci rsa_priv_decode, 972e1051a39Sopenharmony_ci rsa_priv_encode, 973e1051a39Sopenharmony_ci rsa_priv_print, 974e1051a39Sopenharmony_ci 975e1051a39Sopenharmony_ci int_rsa_size, 976e1051a39Sopenharmony_ci rsa_bits, 977e1051a39Sopenharmony_ci rsa_security_bits, 978e1051a39Sopenharmony_ci 979e1051a39Sopenharmony_ci 0, 0, 0, 0, 0, 0, 980e1051a39Sopenharmony_ci 981e1051a39Sopenharmony_ci rsa_sig_print, 982e1051a39Sopenharmony_ci int_rsa_free, 983e1051a39Sopenharmony_ci rsa_pkey_ctrl, 984e1051a39Sopenharmony_ci 0, 0, 985e1051a39Sopenharmony_ci rsa_item_verify, 986e1051a39Sopenharmony_ci rsa_item_sign, 987e1051a39Sopenharmony_ci rsa_sig_info_set, 988e1051a39Sopenharmony_ci rsa_pkey_check, 989e1051a39Sopenharmony_ci 990e1051a39Sopenharmony_ci 0, 0, 991e1051a39Sopenharmony_ci 0, 0, 0, 0, 992e1051a39Sopenharmony_ci 993e1051a39Sopenharmony_ci rsa_pkey_dirty_cnt, 994e1051a39Sopenharmony_ci rsa_pss_pkey_export_to, 995e1051a39Sopenharmony_ci rsa_pss_pkey_import_from, 996e1051a39Sopenharmony_ci rsa_pkey_copy 997e1051a39Sopenharmony_ci}; 998