mirror of
https://github.com/stefanberger/libtpms
synced 2026-08-10 07:08:22 +00:00
tpm12: Use EVP functions for decryption
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
parent
03d13d5f19
commit
51d1ca8ce4
@ -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 \
|
||||
|
||||
@ -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'.
|
||||
*/
|
||||
|
||||
133
src/tpm12/tpm_openssl_helpers.c
Normal file
133
src/tpm12/tpm_openssl_helpers.c
Normal 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
|
||||
|
||||
50
src/tpm12/tpm_openssl_helpers.h
Normal file
50
src/tpm12/tpm_openssl_helpers.h
Normal 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
|
||||
Loading…
Reference in New Issue
Block a user