/* * Copyright (C) 2021 Red Hat, Inc. * * Author: Daiki Ueno * * This file is part of GnuTLS. * * The GnuTLS is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see * */ #if HAVE_CONFIG_H # include "config.h" #endif #include "gnutls_int.h" #include #include #include /* These are helper functions to perform RSA padding before signing, only used * for the crypto backends that do not support RSA-PKCS1/PSS natively for the * use with TLS (such as TPM2); not recommended for general usage. */ int _gnutls_rsa_pkcs1_sign_pad(size_t key_bits, const gnutls_datum_t *data, unsigned char *buffer, size_t buffer_size) { size_t key_size = (key_bits + 7) / 8; size_t size; mpz_t m; int ret = 0; mpz_init(m); if (!pkcs1_rsa_digest_encode(m, key_size, data->size, data->data)) { ret = gnutls_assert_val(GNUTLS_E_PK_SIGN_FAILED); goto out; } size = nettle_mpz_sizeinbase_256_u(m); if (size > buffer_size) { ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); goto out; } nettle_mpz_get_str_256(buffer_size, buffer, m); out: mpz_clear(m); return ret; } int _gnutls_rsa_pss_sign_pad(gnutls_x509_spki_st *params, size_t key_bits, const gnutls_datum_t *data, unsigned char *buffer, size_t buffer_size) { mpz_t m; int ret = 0; const struct nettle_hash *hash; uint8_t salt[SHA512_DIGEST_SIZE]; size_t size; mpz_init(m); switch (params->rsa_pss_dig) { case GNUTLS_DIG_SHA256: hash = &nettle_sha256; break; case GNUTLS_DIG_SHA384: hash = &nettle_sha384; break; case GNUTLS_DIG_SHA512: hash = &nettle_sha512; break; default: ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); goto out; } if (data->size != hash->digest_size) { ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); goto out; } ret = gnutls_rnd(GNUTLS_RND_NONCE, salt, params->salt_size); if (ret < 0) { goto out; } /* The emBits for EMSA-PSS encoding is actually one *fewer* * bit than the RSA modulus. */ if (!pss_encode_mgf1(m, key_bits - 1, hash, params->salt_size, salt, data->data)) { ret = gnutls_assert_val(GNUTLS_E_PK_SIGN_FAILED); goto out; } size = nettle_mpz_sizeinbase_256_u(m); if (size > buffer_size) { ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); goto out; } nettle_mpz_get_str_256(buffer_size, buffer, m); out: mpz_clear(m); return ret; }