tpm12: Use EVP functions for decryption

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2020-10-22 11:53:52 -04:00 committed by Stefan Berger
parent 03d13d5f19
commit 51d1ca8ce4
4 changed files with 312 additions and 0 deletions

View File

@ -74,6 +74,7 @@ libtpms_tpm12_la_SOURCES = \
tpm12/tpm_nonce.c \
tpm12/tpm_nvfile.c \
tpm12/tpm_nvram.c \
tpm12/tpm_openssl_helpers.c \
tpm12/tpm_owner.c \
tpm12/tpm_pcr.c \
tpm12/tpm_permanent.c \
@ -120,6 +121,7 @@ noinst_HEADERS = \
tpm12/tpm_nvfile.h \
tpm12/tpm_nvram_const.h \
tpm12/tpm_nvram.h \
tpm12/tpm_openssl_helpers.h \
tpm12/tpm_owner.h \
tpm12/tpm_pcr.h \
tpm12/tpm_permanent.h \

View File

@ -61,6 +61,7 @@
#include "tpm_crypto.h"
#include "tpm_openssl_helpers.h" // libtpms added
/* The TPM OAEP encoding parameter */
static const unsigned char tpm_oaep_pad_str[] = { 'T', 'C', 'P', 'A' };
@ -551,6 +552,7 @@ static TPM_RESULT TPM_RSAGeneratePrivateToken(RSA **rsa_pri_key, /* freed by cal
return rc;
}
#if !USE_OPENSSL_FUNCTIONS_RSA // libtpms added
/* TPM_RSAPrivateDecrypt() decrypts 'encrypt_data' using the private key 'n, e, d'. The OAEP
padding is removed and 'decrypt_data_length' bytes are moved to 'decrypt_data'.
@ -659,6 +661,131 @@ TPM_RESULT TPM_RSAPrivateDecrypt(unsigned char *decrypt_data, /* decrypted dat
return rc;
}
#else // libtpms added begin
TPM_RESULT TPM_RSAPrivateDecrypt(unsigned char *decrypt_data, /* decrypted data */
uint32_t *decrypt_data_length, /* length of data put into
decrypt_data */
size_t decrypt_data_size, /* size of decrypt_data buffer */
TPM_ENC_SCHEME encScheme, /* encryption scheme */
unsigned char *encrypt_data, /* encrypted data */
uint32_t encrypt_data_size,
unsigned char *narr, /* public modulus */
uint32_t nbytes,
unsigned char *earr, /* public exponent */
uint32_t ebytes,
unsigned char *darr, /* private exponent */
uint32_t dbytes)
{
TPM_RESULT rc = 0;
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *ctx = NULL;
const EVP_MD *md = NULL;
unsigned char *label = NULL;
size_t outlen;
unsigned char buffer[(TPM_RSA_KEY_LENGTH_MAX + 7) / 8];
printf(" TPM_RSAPrivateDecrypt:\n");
/* construct the OpenSSL private key object */
if (rc == 0) {
rc = TPM_RSAGenerateEVP_PKEY(&pkey, /* freed @1 */
narr, /* public modulus */
nbytes,
earr, /* public exponent */
ebytes,
darr, /* private exponent */
dbytes);
}
if (rc == 0) {
ctx = EVP_PKEY_CTX_new(pkey, NULL);
if (ctx == 0) {
printf("TPM_RSAPrivateDecrypt: Error in EVP_PKEY_CTX_new()\n");
rc = TPM_FAIL;
}
}
if (rc == 0) {
if (EVP_PKEY_decrypt_init(ctx) <= 0) {
printf("TPM_RSAPrivateDecrypt: Error in EVP_PKEY_decrypt_init()\n");
rc = TPM_FAIL;
}
}
if (rc == 0) {
switch (encScheme) {
case TPM_ES_RSAESOAEP_SHA1_MGF1:
if (rc == 0) {
md = EVP_get_digestbyname("sha1");
if (md == NULL ||
EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0 ||
EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0) {
printf("TPM_RSAPrivateDecrypt: Error in setting up decrypt context for TPM_ES_RSAESOAEP_SHA1_MGF\n");
rc = TPM_FAIL;
}
}
if (rc == 0) {
rc = TPM_Malloc(&label, sizeof(tpm_oaep_pad_str));
if (rc) {
printf("TPM_RSAPrivateDecrypt: TPM_Malloc failed\n");
}
}
if (rc == 0) {
memcpy(label, tpm_oaep_pad_str, sizeof(tpm_oaep_pad_str));
if (EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, label, sizeof(tpm_oaep_pad_str)) <= 0) {
printf("TPM_RSAPrivateDecrypt: EVP_PKEY_CTX_set0_rsa_oaep_label() failed\n");
rc = TPM_FAIL;
}
if (rc == 0) {
label = NULL;
}
}
break;
case TPM_ES_RSAESPKCSv15:
if (rc == 0) {
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) {
printf("TPM_RSAPrivateDecrypt: Error in setting up decrypt context for TPM_ES_RSAESPKCSv15\n");
rc = TPM_FAIL;
}
}
break;
default:
if (rc == 0) {
printf("TPM_RSAPrivateDecrypt: Error, unknown encryption scheme %04x\n", encScheme);
rc = TPM_INAPPROPRIATE_ENC;
}
}
}
if (rc == 0) {
outlen = sizeof(buffer);
if (EVP_PKEY_decrypt(ctx, buffer, &outlen,
encrypt_data, encrypt_data_size) <= 0) {
printf("TPM_RSAPrivateDecrypt: EVP_PKEY_decrypt failed\n");
rc = TPM_DECRYPT_ERROR;
}
if (rc == 0) {
if (outlen > decrypt_data_size) {
printf("TPM_RSAPrivateDecrypt: Error, decrypt_data_size %u too small for message size %u\n",
decrypt_data_size, outlen);
rc = TPM_DECRYPT_ERROR;
}
}
if (rc == 0) {
*decrypt_data_length = (uint32_t)outlen;
memcpy(decrypt_data, buffer, outlen);
TPM_PrintFour(" TPM_RSAPrivateDecrypt: Decrypt data", decrypt_data);
}
}
EVP_PKEY_free(pkey);
EVP_PKEY_CTX_free(ctx);
TPM_Free(label);
return rc;
}
#endif // libtpms added end
/* TPM_RSAPublicEncrypt() pads 'decrypt_data' to 'encrypt_data_size' and encrypts using the public
key 'n, e'.
*/

View File

@ -0,0 +1,133 @@
/********************************************************************************/
/* */
/* OpenSSL helper functions */
/* Written by Stefan Berger */
/* IBM Thomas J. Watson Research Center */
/* */
/* (c) Copyright IBM Corporation 2020. */
/* */
/* All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or without */
/* modification, are permitted provided that the following conditions are */
/* met: */
/* */
/* Redistributions of source code must retain the above copyright notice, */
/* this list of conditions and the following disclaimer. */
/* */
/* Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the */
/* documentation and/or other materials provided with the distribution. */
/* */
/* Neither the names of the IBM Corporation nor the names of its */
/* contributors may be used to endorse or promote products derived from */
/* this software without specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/********************************************************************************/
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/bn.h>
#include "tpm_debug.h"
#include "tpm_error.h"
#include "tpm_openssl_helpers.h"
#include "tpm_crypto.h"
#if USE_OPENSSL_FUNCTIONS_RSA
TPM_RESULT TPM_RSAGenerateEVP_PKEY(EVP_PKEY **pkey, /* out: pkey */
unsigned char *narr, /* public modulus */
uint32_t nbytes,
unsigned char *earr, /* public exponent */
uint32_t ebytes,
unsigned char *darr, /* private exponent */
uint32_t dbytes)
{
TPM_RESULT rc = 0;
int irc;
BIGNUM * n = NULL;
BIGNUM * e = NULL;
BIGNUM * d = NULL;
RSA * rsakey = NULL;
/* sanity check for the free */
if (rc == 0) {
if (*pkey != NULL) {
printf("TPM_RSAGeneratePrivateToken: Error (fatal), pkey %p should be NULL\n",
*pkey);
rc = TPM_FAIL;
}
}
/* construct the OpenSSL private key object */
if (rc == 0) {
*pkey = EVP_PKEY_new(); /* freed by caller */
if (*pkey == NULL) {
printf("TPM_RSAGeneratePrivateToken: Error in EVP_PKEY_new()\n");
rc = TPM_FAIL;
}
}
if (rc == 0) {
rc = TPM_bin2bn((TPM_BIGNUM *)&n, narr, nbytes); /* freed by caller */
}
if (rc == 0) {
rc = TPM_bin2bn((TPM_BIGNUM *)&e, earr, ebytes); /* freed by caller */
}
if (rc == 0) {
rc = TPM_bin2bn((TPM_BIGNUM *)&d, darr, dbytes); /* freed by caller */
}
if (rc == 0) {
rsakey = RSA_new();
if (rsakey == NULL) {
printf("TPM_RSAGeneratePrivateToken: Error in RSA_new()\n");
rc = TPM_FAIL;
}
}
if (rc == 0) {
irc = RSA_set0_key(rsakey, n, e, d);
if (irc != 1) {
printf("TPM_RSAGeneratePrivateToken: Error in RSA_set0_key()\n");
rc = TPM_FAIL;
} else {
n = NULL;
e = NULL;
d = NULL;
}
}
if (rc == 0) {
RSA_set_flags(rsakey, RSA_FLAG_NO_BLINDING);
irc = EVP_PKEY_assign_RSA(*pkey, rsakey);
if (irc == 0) {
printf("TPM_RSAGeneratePrivateToken: Error in EVP_PKEY_assign_RSA()\n");
rc = TPM_FAIL;
} else {
rsakey = NULL;
}
}
if (rc != 0) {
EVP_PKEY_free(*pkey);
*pkey = NULL;
RSA_free(rsakey);
BN_free(n);
BN_free(e);
BN_clear_free(d);
}
return rc;
}
#endif

View File

@ -0,0 +1,50 @@
/********************************************************************************/
/* */
/* OpenSSL helper functions */
/* Written by Stefan Berger */
/* IBM Thomas J. Watson Research Center */
/* */
/* (c) Copyright IBM Corporation 2020. */
/* */
/* All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or without */
/* modification, are permitted provided that the following conditions are */
/* met: */
/* */
/* Redistributions of source code must retain the above copyright notice, */
/* this list of conditions and the following disclaimer. */
/* */
/* Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the */
/* documentation and/or other materials provided with the distribution. */
/* */
/* Neither the names of the IBM Corporation nor the names of its */
/* contributors may be used to endorse or promote products derived from */
/* this software without specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/********************************************************************************/
#ifndef TPM_OPENSSL_HELPERS_H
#define TPM_OPENSSL_HELPERS_H
TPM_RESULT TPM_RSAGenerateEVP_PKEY(EVP_PKEY **pkey, /* out: pkey */
unsigned char *narr, /* public modulus */
uint32_t nbytes,
unsigned char *earr, /* public exponent */
uint32_t ebytes,
unsigned char *darr, /* private exponent */
uint32_t dbytes);
#endif