diff options
author | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-03-10 21:03:56 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-03-10 21:03:56 +0000 |
commit | 2cf6caea1354cad25f19f4d573f199fa1f1c7862 (patch) | |
tree | 44f9cb4e9bfeb7cbe2db3d402f0ec46fcd881e6a | |
parent | ded8a7efd977b327c063f605fa453cd8c2884045 (diff) | |
parent | 7633c0d6135e93787db31c57ef92c545425b7c51 (diff) | |
download | tpm2-tss-2cf6caea1354cad25f19f4d573f199fa1f1c7862.tar.gz |
ANDROID: Add boringssl copies of openssl code. am: 7633c0d613
Change-Id: I04b394749c46d3366e92723d652142472b2595f9
-rw-r--r-- | src/tss2-esys/esys_crypto_bssl.c | 1120 | ||||
-rw-r--r-- | src/tss2-esys/esys_crypto_bssl.h | 144 |
2 files changed, 1264 insertions, 0 deletions
diff --git a/src/tss2-esys/esys_crypto_bssl.c b/src/tss2-esys/esys_crypto_bssl.c new file mode 100644 index 00000000..3c5d86d6 --- /dev/null +++ b/src/tss2-esys/esys_crypto_bssl.c @@ -0,0 +1,1120 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/******************************************************************************* + * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG + * All rights reserved. + ******************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <openssl/evp.h> +#include <openssl/aes.h> +#include <openssl/rsa.h> +#include <openssl/engine.h> +#include <stdio.h> + +#include "tss2_esys.h" + +#include "esys_crypto.h" +#include "esys_crypto_ossl.h" + +#include "esys_iutil.h" +#include "esys_mu.h" +#define LOGMODULE esys_crypto +#include "util/log.h" +#include "util/aux_util.h" + +static int +iesys_bn2binpad(const BIGNUM *bn, unsigned char *bin, int bin_length) +{ + int len_bn = BN_num_bytes(bn); + int offset = bin_length - len_bn; + memset(bin,0,offset); + BN_bn2bin(bn, bin + offset); + return 1; +} + +/** Context to hold temporary values for iesys_crypto */ +typedef struct _IESYS_CRYPTO_CONTEXT { + enum { + IESYS_CRYPTOSSL_TYPE_HASH = 1, + IESYS_CRYPTOSSL_TYPE_HMAC, + } type; /**< The type of context to hold; hash or hmac */ + union { + struct { + EVP_MD_CTX *ossl_context; + const EVP_MD *ossl_hash_alg; + size_t hash_len; + } hash; /**< the state variables for a hash context */ + struct { + EVP_MD_CTX *ossl_context; + const EVP_MD *ossl_hash_alg; + size_t hmac_len; + } hmac; /**< the state variables for an hmac context */ + }; +} IESYS_CRYPTOSSL_CONTEXT; + +const EVP_MD * +get_ossl_hash_md(TPM2_ALG_ID hashAlg) +{ + switch (hashAlg) { + case TPM2_ALG_SHA1: + return EVP_sha1(); + break; + case TPM2_ALG_SHA256: + return EVP_sha256(); + break; + case TPM2_ALG_SHA384: + return EVP_sha384(); + break; + case TPM2_ALG_SHA512: + return EVP_sha512(); + break; + default: + return NULL; + } +} + +/** Provide the context for the computation of a hash digest. + * + * The context will be created and initialized according to the hash function. + * @param[out] context The created context (callee-allocated). + * @param[in] hashAlg The hash algorithm for the creation of the context. + * @retval TSS2_RC_SUCCESS on success. + * @retval TSS2_ESYS_RC_BAD_VALUE or TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters. + * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated. + * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library. + */ +TSS2_RC +iesys_cryptossl_hash_start(IESYS_CRYPTO_CONTEXT_BLOB ** context, + TPM2_ALG_ID hashAlg) +{ + TSS2_RC r = TSS2_RC_SUCCESS; + LOG_TRACE("call: context=%p hashAlg=%"PRIu16, context, hashAlg); + return_if_null(context, "Context is NULL", TSS2_ESYS_RC_BAD_REFERENCE); + return_if_null(context, "Null-Pointer passed for context", TSS2_ESYS_RC_BAD_REFERENCE); + IESYS_CRYPTOSSL_CONTEXT *mycontext; + mycontext = calloc(1, sizeof(IESYS_CRYPTOSSL_CONTEXT)); + return_if_null(mycontext, "Out of Memory", TSS2_ESYS_RC_MEMORY); + mycontext->type = IESYS_CRYPTOSSL_TYPE_HASH; + + if (!(mycontext->hash.ossl_hash_alg = get_ossl_hash_md(hashAlg))) { + goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED, + "Unsupported hash algorithm (%"PRIu16")", cleanup, hashAlg); + } + + if (iesys_crypto_hash_get_digest_size(hashAlg, &mycontext->hash.hash_len)) { + goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED, + "Unsupported hash algorithm (%"PRIu16")", cleanup, hashAlg); + } + + if (!(mycontext->hash.ossl_context = EVP_MD_CTX_create())) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Error EVP_MD_CTX_create", cleanup); + } + + if (1 != EVP_DigestInit_ex(mycontext->hash.ossl_context, + mycontext->hash.ossl_hash_alg, + NULL)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Errror EVP_DigestInit_ex", cleanup); + } + + *context = (IESYS_CRYPTO_CONTEXT_BLOB *) mycontext; + + return TSS2_RC_SUCCESS; + + cleanup: + if (mycontext->hash.ossl_context) + EVP_MD_CTX_destroy(mycontext->hash.ossl_context); + SAFE_FREE(mycontext); + + return r; +} + +/** Update the digest value of a digest object from a byte buffer. + * + * The context of a digest object will be updated according to the hash + * algorithm of the context. < + * @param[in,out] context The context of the digest object which will be updated. + * @param[in] buffer The data for the update. + * @param[in] size The size of the data buffer. + * @retval TSS2_RC_SUCCESS on success. + * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters. + */ +TSS2_RC +iesys_cryptossl_hash_update(IESYS_CRYPTO_CONTEXT_BLOB * context, + const uint8_t * buffer, size_t size) +{ + LOG_TRACE("called for context %p, buffer %p and size %zd", context, buffer, + size); + if (context == NULL || buffer == NULL) { + LOG_ERROR("Null-Pointer passed"); + return TSS2_ESYS_RC_BAD_REFERENCE; + } + IESYS_CRYPTOSSL_CONTEXT *mycontext = (IESYS_CRYPTOSSL_CONTEXT *) context; + if (mycontext->type != IESYS_CRYPTOSSL_TYPE_HASH) { + LOG_ERROR("bad context"); + return TSS2_ESYS_RC_BAD_REFERENCE; + } + + LOGBLOB_TRACE(buffer, size, "Updating hash with"); + + if (1 != EVP_DigestUpdate(mycontext->hash.ossl_context, buffer, size)) { + return_error(TSS2_ESYS_RC_GENERAL_FAILURE, "OSSL hash update"); + } + + return TSS2_RC_SUCCESS; +} + +/** Update the digest value of a digest object from a TPM2B object. + * + * The context of a digest object will be updated according to the hash + * algorithm of the context. + * @param[in,out] context The context of the digest object which will be updated. + * @param[in] b The TPM2B object for the update. + * @retval TSS2_RC_SUCCESS on success. + * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters. + */ +TSS2_RC +iesys_cryptossl_hash_update2b(IESYS_CRYPTO_CONTEXT_BLOB * context, TPM2B * b) +{ + LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, b); + if (context == NULL || b == NULL) { + LOG_ERROR("Null-Pointer passed"); + return TSS2_ESYS_RC_BAD_REFERENCE; + } + TSS2_RC ret = iesys_cryptossl_hash_update(context, &b->buffer[0], b->size); + return ret; +} + +/** Get the digest value of a digest object and close the context. + * + * The digest value will written to a passed buffer and the resources of the + * digest object are released. + * @param[in,out] context The context of the digest object to be released + * @param[out] buffer The buffer for the digest value (caller-allocated). + * @param[out] size The size of the digest. + * @retval TSS2_RC_SUCCESS on success. + * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters. + * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library. + */ +TSS2_RC +iesys_cryptossl_hash_finish(IESYS_CRYPTO_CONTEXT_BLOB ** context, + uint8_t * buffer, size_t * size) +{ + unsigned int digest_size = 0; + + LOG_TRACE("called for context-pointer %p, buffer %p and size-pointer %p", + context, buffer, size); + if (context == NULL || *context == NULL || buffer == NULL || size == NULL) { + return_error(TSS2_ESYS_RC_BAD_REFERENCE, "Null-Pointer passed"); + } + IESYS_CRYPTOSSL_CONTEXT *mycontext = * context; + if (mycontext->type != IESYS_CRYPTOSSL_TYPE_HASH) { + return_error(TSS2_ESYS_RC_BAD_REFERENCE, "bad context"); + } + + if (*size < mycontext->hash.hash_len) { + return_error(TSS2_ESYS_RC_BAD_SIZE, "Buffer too small"); + } + + if (1 != EVP_DigestFinal_ex(mycontext->hash.ossl_context, buffer, &digest_size)) { + return_error(TSS2_ESYS_RC_GENERAL_FAILURE, "Ossl error."); + } + + if (digest_size != mycontext->hash.hash_len) { + return_error(TSS2_ESYS_RC_GENERAL_FAILURE, + "Invalid size computed by EVP_DigestFinal_ex"); + } + + LOGBLOB_TRACE(buffer, mycontext->hash.hash_len, "read hash result"); + + *size = mycontext->hash.hash_len; + EVP_MD_CTX_destroy(mycontext->hash.ossl_context); + free(mycontext); + *context = NULL; + + return TSS2_RC_SUCCESS; +} + +/** Release the resources of a digest object. + * + * The assigned resources will be released and the context will be set to NULL. + * @param[in,out] context The context of the digest object. + */ +void +iesys_cryptossl_hash_abort(IESYS_CRYPTO_CONTEXT_BLOB ** context) +{ + LOG_TRACE("called for context-pointer %p", context); + if (context == NULL || *context == NULL) { + LOG_DEBUG("Null-Pointer passed"); + return; + } + IESYS_CRYPTOSSL_CONTEXT *mycontext = + (IESYS_CRYPTOSSL_CONTEXT *) * context; + if (mycontext->type != IESYS_CRYPTOSSL_TYPE_HASH) { + LOG_DEBUG("bad context"); + return; + } + + EVP_MD_CTX_destroy(mycontext->hash.ossl_context); + free(mycontext); + *context = NULL; +} + +/* HMAC */ + +/** Provide the context an HMAC digest object from a byte buffer key. + * + * The context will be created and initialized according to the hash function + * and the used HMAC key. + * @param[out] context The created context (callee-allocated). + * @param[in] hmacAlg The hash algorithm for the HMAC computation. + * @param[in] key The byte buffer of the HMAC key. + * @param[in] size The size of the HMAC key. + * @retval TSS2_RC_SUCCESS on success. + * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters. + * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated. + * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library. + */ +TSS2_RC +iesys_cryptossl_hmac_start(IESYS_CRYPTO_CONTEXT_BLOB ** context, + TPM2_ALG_ID hashAlg, + const uint8_t * key, size_t size) +{ + TSS2_RC r = TSS2_RC_SUCCESS; + EVP_PKEY *hkey = NULL; + + LOG_TRACE("called for context-pointer %p and hmacAlg %d", context, hashAlg); + LOGBLOB_TRACE(key, size, "Starting hmac with"); + if (context == NULL || key == NULL) { + return_error(TSS2_ESYS_RC_BAD_REFERENCE, + "Null-Pointer passed in for context"); + } + IESYS_CRYPTOSSL_CONTEXT *mycontext = calloc(1, sizeof(IESYS_CRYPTOSSL_CONTEXT)); + return_if_null(mycontext, "Out of Memory", TSS2_ESYS_RC_MEMORY); + + if (!(mycontext->hmac.ossl_hash_alg = get_ossl_hash_md(hashAlg))) { + goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED, + "Unsupported hash algorithm (%"PRIu16")", cleanup, hashAlg); + } + + if (iesys_crypto_hash_get_digest_size(hashAlg, &mycontext->hmac.hmac_len)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Unsupported hash algorithm (%"PRIu16")", cleanup, hashAlg); + } + + if (!(mycontext->hmac.ossl_context = EVP_MD_CTX_create())) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Error EVP_MD_CTX_create", cleanup); + } + + if (!(hkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key, size))) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "EVP_PKEY_new_mac_key", cleanup); + } + + if(1 != EVP_DigestSignInit(mycontext->hmac.ossl_context, NULL, + mycontext->hmac.ossl_hash_alg, NULL, hkey)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "DigestSignInit", cleanup); + } + + mycontext->type = IESYS_CRYPTOSSL_TYPE_HMAC; + + *context = (IESYS_CRYPTO_CONTEXT_BLOB *) mycontext; + + EVP_PKEY_free(hkey); + + return TSS2_RC_SUCCESS; + + cleanup: + if (mycontext->hmac.ossl_context) + EVP_MD_CTX_destroy(mycontext->hmac.ossl_context); + if(hkey) + EVP_PKEY_free(hkey); + SAFE_FREE(mycontext); + return r; +} + +/** Update and HMAC digest value from a byte buffer. + * + * The context of a digest object will be updated according to the hash + * algorithm and the key of the context. + * @param[in,out] context The context of the digest object which will be updated. + * @param[in] buffer The data for the update. + * @param[in] size The size of the data buffer. + * @retval TSS2_RC_SUCCESS on success. + * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters. + */ +TSS2_RC +iesys_cryptossl_hmac_update(IESYS_CRYPTO_CONTEXT_BLOB * context, + const uint8_t * buffer, size_t size) +{ + LOG_TRACE("called for context %p, buffer %p and size %zd", + context, buffer, size); + if (context == NULL || buffer == NULL) { + return_error(TSS2_ESYS_RC_BAD_REFERENCE, "Null-Pointer passed"); + } + IESYS_CRYPTOSSL_CONTEXT *mycontext = (IESYS_CRYPTOSSL_CONTEXT *) context; + if (mycontext->type != IESYS_CRYPTOSSL_TYPE_HMAC) { + return_error(TSS2_ESYS_RC_BAD_REFERENCE, "bad context"); + } + + LOGBLOB_TRACE(buffer, size, "Updating hmac with"); + + /* Call update with the message */ + if(1 != EVP_DigestSignUpdate(mycontext->hmac.ossl_context, buffer, size)) { + return_error(TSS2_ESYS_RC_GENERAL_FAILURE, "OSSL HMAC update"); + } + + return TSS2_RC_SUCCESS; +} + +/** Update and HMAC digest value from a TPM2B object. + * + * The context of a digest object will be updated according to the hash + * algorithm and the key of the context. + * @param[in,out] context The context of the digest object which will be updated. + * @param[in] b The TPM2B object for the update. + * @retval TSS2_RC_SUCCESS on success. + * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters. + */ +TSS2_RC +iesys_cryptossl_hmac_update2b(IESYS_CRYPTO_CONTEXT_BLOB * context, TPM2B * b) +{ + LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, b); + if (context == NULL || b == NULL) { + return_error(TSS2_ESYS_RC_BAD_REFERENCE, "Null-Pointer passed"); + } + TSS2_RC ret = iesys_cryptossl_hmac_update(context, &b->buffer[0], b->size); + return ret; +} + +/** Write the HMAC digest value to a byte buffer and close the context. + * + * The digest value will written to a passed buffer and the resources of the + * HMAC object are released. + * @param[in,out] context The context of the HMAC object. + * @param[out] buffer The buffer for the digest value (caller-allocated). + * @param[out] size The size of the digest. + * @retval TSS2_RC_SUCCESS on success. + * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters. + * @retval TSS2_ESYS_RC_BAD_SIZE If the size passed is lower than the HMAC length. + * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library. + */ +TSS2_RC +iesys_cryptossl_hmac_finish(IESYS_CRYPTO_CONTEXT_BLOB ** context, + uint8_t * buffer, size_t * size) +{ + + TSS2_RC r = TSS2_RC_SUCCESS; + + LOG_TRACE("called for context-pointer %p, buffer %p and size-pointer %p", + context, buffer, size); + if (context == NULL || *context == NULL || buffer == NULL || size == NULL) { + return_error(TSS2_ESYS_RC_BAD_REFERENCE, "Null-Pointer passed"); + } + IESYS_CRYPTOSSL_CONTEXT *mycontext = + (IESYS_CRYPTOSSL_CONTEXT *) * context; + if (mycontext->type != IESYS_CRYPTOSSL_TYPE_HMAC) { + return_error(TSS2_ESYS_RC_BAD_REFERENCE, "bad context"); + } + + if (*size < mycontext->hmac.hmac_len) { + return_error(TSS2_ESYS_RC_BAD_SIZE, "Buffer too small"); + } + + if (1 != EVP_DigestSignFinal(mycontext->hmac.ossl_context, buffer, size)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "DigestSignFinal", cleanup); + } + + LOGBLOB_TRACE(buffer, *size, "read hmac result"); + + cleanup: + EVP_MD_CTX_destroy(mycontext->hmac.ossl_context); + SAFE_FREE(mycontext); + *context = NULL; + return r; +} + +/** Write the HMAC digest value to a TPM2B object and close the context. + * + * The digest value will written to a passed TPM2B object and the resources of + * the HMAC object are released. + * @param[in,out] context The context of the HMAC object. + * @param[out] hmac The buffer for the digest value (caller-allocated). + * @retval TSS2_RC_SUCCESS on success. + * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters. + * @retval TSS2_ESYS_RC_BAD_SIZE if the size passed is lower than the HMAC length. + * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library. + */ +TSS2_RC +iesys_cryptossl_hmac_finish2b(IESYS_CRYPTO_CONTEXT_BLOB ** context, TPM2B * hmac) +{ + LOG_TRACE("called for context-pointer %p and 2b-pointer %p", context, hmac); + if (context == NULL || *context == NULL || hmac == NULL) { + return_error(TSS2_ESYS_RC_BAD_REFERENCE, "Null-Pointer passed"); + } + size_t s = hmac->size; + TSS2_RC ret = iesys_cryptossl_hmac_finish(context, &hmac->buffer[0], &s); + hmac->size = s; + return ret; +} + +/** Release the resources of an HAMC object. + * + * The assigned resources will be released and the context will be set to NULL. + * @param[in,out] context The context of the HMAC object. + */ +void +iesys_cryptossl_hmac_abort(IESYS_CRYPTO_CONTEXT_BLOB ** context) +{ + LOG_TRACE("called for context-pointer %p", context); + if (context == NULL || *context == NULL) { + LOG_DEBUG("Null-Pointer passed"); + return; + } + if (*context != NULL) { + IESYS_CRYPTOSSL_CONTEXT *mycontext = + (IESYS_CRYPTOSSL_CONTEXT *) * context; + if (mycontext->type != IESYS_CRYPTOSSL_TYPE_HMAC) { + LOG_DEBUG("bad context"); + return; + } + + EVP_MD_CTX_destroy(mycontext->hmac.ossl_context); + + free(mycontext); + *context = NULL; + } +} + +/** Compute random TPM2B data. + * + * The random data will be generated and written to a passed TPM2B structure. + * @param[out] nonce The TPM2B structure for the random data (caller-allocated). + * @param[in] num_bytes The number of bytes to be generated. + * @retval TSS2_RC_SUCCESS on success. + * + * NOTE: the TPM should not be used to obtain the random data + */ +TSS2_RC +iesys_cryptossl_random2b(TPM2B_NONCE * nonce, size_t num_bytes) +{ + const RAND_METHOD *rand_save = RAND_get_rand_method(); + + if (num_bytes == 0) { + nonce->size = sizeof(TPMU_HA); + } else { + nonce->size = num_bytes; + } + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + RAND_set_rand_method(RAND_OpenSSL()); +#else + RAND_set_rand_method(RAND_SSLeay()); +#endif + if (1 != RAND_bytes(&nonce->buffer[0], nonce->size)) { + RAND_set_rand_method(rand_save); + return_error(TSS2_ESYS_RC_GENERAL_FAILURE, + "Failure in random number generator."); + } + RAND_set_rand_method(rand_save); + return TSS2_RC_SUCCESS; +} + +/** Encryption of a buffer using a public (RSA) key. + * + * Encrypting a buffer using a public key is used for example during + * Esys_StartAuthSession in order to encrypt the salt value. + * @param[in] key The key to be used for encryption. + * @param[in] in_size The size of the buffer to be encrypted. + * @param[in] in_buffer The data buffer to be encrypted. + * @param[in] max_out_size The maximum size for the output encrypted buffer. + * @param[out] out_buffer The encrypted buffer. + * @param[out] out_size The size of the encrypted output. + * @param[in] label The label used in the encryption scheme. + * @retval TSS2_RC_SUCCESS on success + * @retval TSS2_ESYS_RC_BAD_VALUE The algorithm of key is not implemented. + * @retval TSS2_ESYS_RC_GENERAL_FAILURE The internal crypto engine failed. + */ +TSS2_RC +iesys_cryptossl_pk_encrypt(TPM2B_PUBLIC * pub_tpm_key, + size_t in_size, + BYTE * in_buffer, + size_t max_out_size, + BYTE * out_buffer, + size_t * out_size, const char *label) +{ + const RAND_METHOD *rand_save = RAND_get_rand_method(); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + RAND_set_rand_method(RAND_OpenSSL()); +#else + RAND_set_rand_method(RAND_SSLeay()); +#endif + + TSS2_RC r = TSS2_RC_SUCCESS; + const EVP_MD * hashAlg = NULL; + RSA * rsa_key = NULL; + EVP_PKEY *evp_rsa_key = NULL; + EVP_PKEY_CTX *ctx = NULL; + BIGNUM* bne = NULL; + int padding; + char *label_copy = NULL; + + if (!(hashAlg = get_ossl_hash_md(pub_tpm_key->publicArea.nameAlg))) { + LOG_ERROR("Unsupported hash algorithm (%"PRIu16")", + pub_tpm_key->publicArea.nameAlg); + RAND_set_rand_method(rand_save); + return TSS2_ESYS_RC_NOT_IMPLEMENTED; + } + + if (!(bne = BN_new())) { + goto_error(r, TSS2_ESYS_RC_MEMORY, + "Could not allocate Big Number", cleanup); + } + + switch (pub_tpm_key->publicArea.parameters.rsaDetail.scheme.scheme) { + case TPM2_ALG_NULL: + padding = RSA_NO_PADDING; + break; + case TPM2_ALG_RSAES: + padding = RSA_PKCS1_PADDING; + break; + case TPM2_ALG_OAEP: + padding = RSA_PKCS1_OAEP_PADDING; + break; + default: + goto_error(r, TSS2_ESYS_RC_BAD_VALUE, "Illegal RSA scheme", cleanup); + } + + UINT32 exp; + if (pub_tpm_key->publicArea.parameters.rsaDetail.exponent == 0) + exp = 65537; + else + exp = pub_tpm_key->publicArea.parameters.rsaDetail.exponent; + if (1 != BN_set_word(bne, exp)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not set exponent.", cleanup); + } + + if (!(rsa_key = RSA_new())) { + goto_error(r, TSS2_ESYS_RC_MEMORY, + "Could not allocate RSA key", cleanup); + } + + if (1 != RSA_generate_key_ex(rsa_key, + pub_tpm_key->publicArea.parameters.rsaDetail.keyBits, + bne, NULL)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not generate RSA key", + cleanup); + } + + if (!(evp_rsa_key = EVP_PKEY_new())) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not create evp key.", cleanup); + } +#if OPENSSL_VERSION_NUMBER < 0x10100000L + if (!BN_bin2bn(pub_tpm_key->publicArea.unique.rsa.buffer, + pub_tpm_key->publicArea.unique.rsa.size, + rsa_key->n)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not create rsa n.", cleanup); + } +#else + BIGNUM *n = NULL; + if (!(n = BN_bin2bn(pub_tpm_key->publicArea.unique.rsa.buffer, + pub_tpm_key->publicArea.unique.rsa.size, + NULL))) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not create rsa n.", cleanup); + } + + if (1 != RSA_set0_key(rsa_key, n, NULL, NULL)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not set rsa n.", cleanup); + } +#endif + + if (1 != EVP_PKEY_set1_RSA(evp_rsa_key, rsa_key)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not set rsa key.", cleanup); + } + + if (!(ctx = EVP_PKEY_CTX_new(evp_rsa_key, NULL))) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not create evp context.", cleanup); + } + + if (1 != EVP_PKEY_encrypt_init(ctx)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not init encrypt context.", cleanup); + } + + if (1 != EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not set RSA passing.", cleanup); + } + + label_copy = OPENSSL_strdup(label); + if (!label_copy) { + goto_error(r, TSS2_ESYS_RC_MEMORY, + "Could not duplicate OAEP label", cleanup); + } + + if (1 != EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, label_copy, strlen(label_copy)+1)) { + OPENSSL_free(label_copy); + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not set RSA label.", cleanup); + } + + if (1 != EVP_PKEY_CTX_set_rsa_oaep_md(ctx, hashAlg)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not set hash algorithm.", cleanup); + } + + /* Determine out size */ + if (1 != EVP_PKEY_encrypt(ctx, NULL, out_size, in_buffer, in_size)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not determine ciper size.", cleanup); + } + + if ((size_t)*out_size > max_out_size) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Encrypted data too big", cleanup); + } + + /* Encrypt data */ + if (1 != EVP_PKEY_encrypt(ctx, out_buffer, out_size, in_buffer, in_size)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Could not encrypt data.", cleanup); + } + + r = TSS2_RC_SUCCESS; + + cleanup: + OSSL_FREE(ctx, EVP_PKEY_CTX); + OSSL_FREE(evp_rsa_key, EVP_PKEY); + OSSL_FREE(rsa_key, RSA); + OSSL_FREE(bne, BN); + RAND_set_rand_method(rand_save); + return r; +} + +/** Computation of OSSL ec public point from TPM public point. + * + * @param[in] group The definition of the used ec curve. + * @param[in] key The TPM public key. + * @param[out] The TPM's public point in OSSL format. + * @retval TSS2_RC_SUCCESS on success. + * @retval TSS2_ESYS_RC_GENERAL_FAILURE The internal crypto engine failed. + */ +static TSS2_RC +tpm_pub_to_ossl_pub(EC_GROUP *group, TPM2B_PUBLIC *key, EC_POINT **tpm_pub_key) +{ + + TSS2_RC r = TSS2_RC_SUCCESS; + BIGNUM *bn_x = NULL; + BIGNUM *bn_y = NULL; + + /* Create the big numbers for the coordinates of the point */ + if (!(bn_x = BN_bin2bn(&key->publicArea.unique.ecc.x.buffer[0], + key->publicArea.unique.ecc.x.size, + NULL))) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Create big num from byte buffer.", cleanup); + } + + if (!(bn_y = BN_bin2bn(&key->publicArea.unique.ecc.y.buffer[0], + key->publicArea.unique.ecc.y.size, + NULL))) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Create big num from byte buffer.", cleanup); + } + + /* Create the ec point with the affine coordinates of the TPM point */ + if (!(*tpm_pub_key = EC_POINT_new(group))) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Create point.", cleanup); + } + + if (1 != EC_POINT_set_affine_coordinates_GFp(group, + *tpm_pub_key, bn_x, + bn_y, NULL)) { + OSSL_FREE(*tpm_pub_key, EC_POINT); + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Set affine coordinates", cleanup); + } + + if (1 != EC_POINT_is_on_curve(group, *tpm_pub_key, NULL)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "The TPM point is not on the curve", cleanup); + } + + cleanup: + OSSL_FREE(bn_x, BN); + OSSL_FREE(bn_y, BN); + + return r; +} + +/** Computation of ephemeral ECC key and shared secret Z. + * + * According to the description in TPM spec part 1 C 6.1 a shared secret + * between application and TPM is computed (ECDH). An ephemeral ECC key and a + * TPM keyare used for the ECDH key exchange. + * @param[in] key The key to be used for ECDH key exchange. + * @param[in] max_out_size the max size for the output of the public key of the + * computed ephemeral key. + * @param[out] Z The computed shared secret. + * @param[out] Q The public part of the ephemeral key in TPM format. + * @param[out] out_buffer The public part of the ephemeral key will be marshaled + * to this buffer. + * @param[out] out_size The size of the marshaled output. + * @retval TSS2_RC_SUCCESS on success + * @retval TSS2_ESYS_RC_BAD_VALUE The algorithm of key is not implemented. + * @retval TSS2_ESYS_RC_GENERAL_FAILURE The internal crypto engine failed. + */ +TSS2_RC +iesys_cryptossl_get_ecdh_point(TPM2B_PUBLIC *key, + size_t max_out_size, + TPM2B_ECC_PARAMETER *Z, + TPMS_ECC_POINT *Q, + BYTE * out_buffer, + size_t * out_size) +{ + TSS2_RC r = TSS2_RC_SUCCESS; + EC_GROUP *group = NULL; /* Group defines the used curve */ + EC_KEY *eph_ec_key = NULL; /* Ephemeral ec key of application */ + const EC_POINT *eph_pub_key = NULL; /* Public part of ephemeral key */ + EC_POINT *tpm_pub_key = NULL; /* Public part of TPM key */ + EC_POINT *mul_eph_tpm = NULL; + BIGNUM *bn_x = NULL; + BIGNUM *bn_y = NULL; + size_t key_size; + int curveId; + size_t offset; + + /* Set ossl constant for curve type and create group for curve */ + switch (key->publicArea.parameters.eccDetail.curveID) { + case TPM2_ECC_NIST_P192: + curveId = NID_X9_62_prime192v1; + key_size = 24; + break; + case TPM2_ECC_NIST_P224: + curveId = NID_secp224r1; + key_size = 28; + break; + case TPM2_ECC_NIST_P256: + curveId = NID_X9_62_prime256v1; + key_size = 32; + break; + case TPM2_ECC_NIST_P384: + curveId = NID_secp384r1; + key_size = 48; + break; + case TPM2_ECC_NIST_P521: + curveId = NID_secp521r1; + key_size = 66; + break; + default: + return_error(TSS2_ESYS_RC_NOT_IMPLEMENTED, + "ECC curve not implemented."); + } + + if (!(group = EC_GROUP_new_by_curve_name(curveId))) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Create group for curve", cleanup); + } + + /* Create ephemeral key */ + if (!(eph_ec_key = EC_KEY_new())) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Create ec key", cleanup); + } + if (1 != EC_KEY_set_group(eph_ec_key , group)) { + + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Set group", cleanup); + } + + if (1 != EC_KEY_generate_key(eph_ec_key)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Generate ec key", cleanup); + } + + if (!(eph_pub_key = EC_KEY_get0_public_key(eph_ec_key))) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Get public key", cleanup); + } + + if (1 != EC_POINT_is_on_curve(group, eph_pub_key, NULL)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Ephemeral public key is on curve",cleanup); + } + + /* Write affine coordinates of ephemeral pub key to TPM point Q */ + if (!(bn_x = BN_new())) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create bignum", cleanup); + } + + if (!(bn_y = BN_new())) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create bignum", cleanup); + } + + if (1 != EC_POINT_get_affine_coordinates_GFp(group, eph_pub_key, bn_x, + bn_y, NULL)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Get affine x coordinate", cleanup); + } + + if (1 != iesys_bn2binpad(bn_x, &Q->x.buffer[0], key_size)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Write big num byte buffer", cleanup); + } + + if (1 != iesys_bn2binpad(bn_y, &Q->y.buffer[0], key_size)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Write big num byte buffer", cleanup); + } + + Q->x.size = key_size; + Q->y.size = key_size; + + /* Create an OSSL EC point from the TPM public point */ + r = tpm_pub_to_ossl_pub(group, key, &tpm_pub_key); + goto_if_error(r, "Convert TPM pub point to ossl pub point", cleanup); + + /* Multiply the ephemeral private key with TPM public key */ + const BIGNUM * eph_priv_key = EC_KEY_get0_private_key(eph_ec_key); + + if (!(mul_eph_tpm = EC_POINT_new(group))) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Create point.", cleanup); + } + + if (1 != EC_POINT_mul(group, mul_eph_tpm, NULL, + tpm_pub_key, eph_priv_key, NULL)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "ec point multiplication", cleanup); + } + + /* Write the x-part of the affine coordinate to Z */ + if (1 != EC_POINT_get_affine_coordinates_GFp(group, mul_eph_tpm, bn_x, + bn_y, NULL)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Get affine x coordinate", cleanup); + } + + if (1 != iesys_bn2binpad(bn_x, &Z->buffer[0], key_size)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Write big num byte buffer", cleanup); + } + + Z->size = key_size; + + /* Write the public ephemeral key in TPM format to out buffer */ + offset = 0; + r = Tss2_MU_TPMS_ECC_POINT_Marshal(Q, &out_buffer[0], max_out_size, &offset); + goto_if_error(r, "Error marshaling", cleanup); + *out_size = offset; + + cleanup: + OSSL_FREE(mul_eph_tpm, EC_POINT); + OSSL_FREE(tpm_pub_key, EC_POINT); + OSSL_FREE(group,EC_GROUP); + OSSL_FREE(eph_ec_key, EC_KEY); + /* Note: free of eph_pub_key already done by free of eph_ec_key */ + OSSL_FREE(bn_x, BN); + OSSL_FREE(bn_y, BN); + return r; +} + +/** Encrypt data with AES. + * + * @param[in] key key used for AES. + * @param[in] tpm_sym_alg AES type in TSS2 notation (must be TPM2_ALG_AES). + * @param[in] key_bits Key size in bits. + * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CFB). + * For parameter encryption only CFB can be used. + * @param[in] blk_len Length Block length of AES. + * @param[in,out] buffer Data to be encrypted. The encrypted date will be stored + * in this buffer. + * @param[in] buffer_size size of data to be encrypted. + * @param[in] iv The initialization vector. The size is equal to blk_len. + * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE and + * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters, + * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library. + */ +TSS2_RC +iesys_cryptossl_sym_aes_encrypt(uint8_t * key, + TPM2_ALG_ID tpm_sym_alg, + TPMI_AES_KEY_BITS key_bits, + TPM2_ALG_ID tpm_mode, + size_t blk_len, + uint8_t * buffer, + size_t buffer_size, + uint8_t * iv) +{ + TSS2_RC r = TSS2_RC_SUCCESS; + const EVP_CIPHER *cipher_alg = NULL; + EVP_CIPHER_CTX *ctx = NULL; + int cipher_len; + + if (key == NULL || buffer == NULL) { + return_error(TSS2_ESYS_RC_BAD_REFERENCE, "Bad reference"); + } + + LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES input"); + + /* Parameter blk_len needed for other crypto libraries */ + (void)blk_len; + + if (key_bits == 128 && tpm_mode == TPM2_ALG_CFB) + cipher_alg = EVP_aes_128_cfb(); + else if (key_bits == 192 && tpm_mode == TPM2_ALG_CFB) + cipher_alg = EVP_aes_192_cfb(); + else if (key_bits == 256 && tpm_mode == TPM2_ALG_CFB) + cipher_alg = EVP_aes_256_cfb(); + else { + goto_error(r, TSS2_ESYS_RC_BAD_VALUE, + "AES algorithm not implemented or illegal mode (CFB expected).", + cleanup); + } + + if (tpm_sym_alg != TPM2_ALG_AES) { + goto_error(r, TSS2_ESYS_RC_BAD_VALUE, + "AES encrypt called with wrong algorithm.", cleanup); + } + + /* Create and initialize the context */ + if(!(ctx = EVP_CIPHER_CTX_new())) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Initialize cipher context", cleanup); + } + + if (1 != EVP_EncryptInit_ex(ctx, cipher_alg, NULL, key, iv)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Initialize cipher operation", cleanup); + } + if (1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Set key and iv", cleanup); + } + + /* Perform the encryption */ + if (1 != EVP_EncryptUpdate(ctx, buffer, &cipher_len, buffer, buffer_size)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypt update", cleanup); + } + + if (1 != EVP_EncryptFinal_ex(ctx, buffer, &cipher_len)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypt final", cleanup); + } + LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES output"); + + cleanup: + + OSSL_FREE(ctx,EVP_CIPHER_CTX); + + return r; +} + +/** Decrypt data with AES. + * + * @param[in] key key used for AES. + * @param[in] tpm_sym_alg AES type in TSS2 notation (must be TPM2_ALG_AES). + * @param[in] key_bits Key size in bits. + * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CFB). + * For parameter encryption only CFB can be used. + * @param[in] blk_len Length Block length of AES. + * @param[in,out] buffer Data to be decrypted. The decrypted date will be stored + * in this buffer. + * @param[in] buffer_size size of data to be encrypted. + * @param[in] iv The initialization vector. The size is equal to blk_len. + * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE and + * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters, + * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library. + */ +TSS2_RC +iesys_cryptossl_sym_aes_decrypt(uint8_t * key, + TPM2_ALG_ID tpm_sym_alg, + TPMI_AES_KEY_BITS key_bits, + TPM2_ALG_ID tpm_mode, + size_t blk_len, + uint8_t * buffer, + size_t buffer_size, + uint8_t * iv) +{ + TSS2_RC r = TSS2_RC_SUCCESS; + const EVP_CIPHER *cipher_alg = NULL; + EVP_CIPHER_CTX *ctx = NULL; + int cipher_len = 0; + + /* Parameter blk_len needed for other crypto libraries */ + (void)blk_len; + + if (key == NULL || buffer == NULL) { + return_error(TSS2_ESYS_RC_BAD_REFERENCE, "Bad reference"); + } + + if (tpm_sym_alg != TPM2_ALG_AES) { + goto_error(r, TSS2_ESYS_RC_BAD_VALUE, + "AES encrypt called with wrong algorithm.", cleanup); + } + + if (key_bits == 128 && tpm_mode == TPM2_ALG_CFB) + cipher_alg = EVP_aes_128_cfb(); + else if (key_bits == 192 && tpm_mode == TPM2_ALG_CFB) + cipher_alg = EVP_aes_192_cfb(); + else if (key_bits == 256 && tpm_mode == TPM2_ALG_CFB) + cipher_alg = EVP_aes_256_cfb(); + else { + + goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED, + "AES algorithm not implemented.", cleanup); + } + + /* Create and initialize the context */ + if(!(ctx = EVP_CIPHER_CTX_new())) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Initialize cipher context", cleanup); + } + + LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES input"); + + if (1 != EVP_DecryptInit_ex(ctx, cipher_alg, NULL, key, iv)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, + "Initialize cipher operation", cleanup); + } + + if (1 != EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Set key and iv", cleanup); + } + + /* Perform the decryption */ + if (1 != EVP_DecryptUpdate(ctx, buffer, &cipher_len, buffer, buffer_size)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypt update", cleanup); + } + + if (1 != EVP_DecryptFinal_ex(ctx, buffer, &cipher_len)) { + goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypt final", cleanup); + } + LOGBLOB_TRACE(buffer, buffer_size, "IESYS AES output"); + + cleanup: + + OSSL_FREE(ctx,EVP_CIPHER_CTX); + return r; +} + + +/** Initialize OpenSSL crypto backend. + * + * Initialize OpenSSL internal tables. + * + * @retval TSS2_RC_SUCCESS always returned because OpenSSL_add_all_algorithms + * does not deliver + * a return code. + */ +TSS2_RC +iesys_cryptossl_init() { + ENGINE_load_builtin_engines(); + OpenSSL_add_all_algorithms(); + return TSS2_RC_SUCCESS; +} diff --git a/src/tss2-esys/esys_crypto_bssl.h b/src/tss2-esys/esys_crypto_bssl.h new file mode 100644 index 00000000..de1bf68b --- /dev/null +++ b/src/tss2-esys/esys_crypto_bssl.h @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/******************************************************************************* + * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG + * All rights reserved. + ******************************************************************************/ +#ifndef ESYS_CRYPTO_OSSL_H +#define ESYS_CRYPTO_OSSL_H + +#include <stddef.h> +#include "tss2_tpm2_types.h" +#include "tss2-sys/sysapi_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define OSSL_FREE(S,TYPE) if((S) != NULL) {TYPE##_free((void*) (S)); (S)=NULL;} + +typedef struct _IESYS_CRYPTO_CONTEXT IESYS_CRYPTO_CONTEXT_BLOB; + +TSS2_RC iesys_cryptossl_hash_start( + IESYS_CRYPTO_CONTEXT_BLOB **context, + TPM2_ALG_ID hashAlg); + +TSS2_RC iesys_cryptossl_hash_update( + IESYS_CRYPTO_CONTEXT_BLOB *context, + const uint8_t *buffer, size_t size); + +TSS2_RC iesys_cryptossl_hash_update2b( + IESYS_CRYPTO_CONTEXT_BLOB *context, + TPM2B *b); + +TSS2_RC iesys_cryptossl_hash_finish( + IESYS_CRYPTO_CONTEXT_BLOB **context, + uint8_t *buffer, + size_t *size); + +TSS2_RC iesys_cryptossl_hash_finish2b( + IESYS_CRYPTO_CONTEXT_BLOB **context, + TPM2B *b); + +void iesys_cryptossl_hash_abort(IESYS_CRYPTO_CONTEXT_BLOB **context); + +#define iesys_crypto_pk_encrypt iesys_cryptossl_pk_encrypt +#define iesys_crypto_hash_start iesys_cryptossl_hash_start +#define iesys_crypto_hash_update iesys_cryptossl_hash_update +#define iesys_crypto_hash_update2b iesys_cryptossl_hash_update2b +#define iesys_crypto_hash_finish iesys_cryptossl_hash_finish +#define iesys_crypto_hash_finish2b iesys_cryptossl_hash_finish2b +#define iesys_crypto_hash_abort iesys_cryptossl_hash_abort + +TSS2_RC iesys_cryptossl_hmac_start( + IESYS_CRYPTO_CONTEXT_BLOB **context, + TPM2_ALG_ID hmacAlg, + const uint8_t *key, + size_t size); + +TSS2_RC iesys_cryptossl_hmac_start2b( + IESYS_CRYPTO_CONTEXT_BLOB **context, + TPM2_ALG_ID hmacAlg, + TPM2B *b); + +TSS2_RC iesys_cryptossl_hmac_update( + IESYS_CRYPTO_CONTEXT_BLOB *context, + const uint8_t *buffer, + size_t size); + +TSS2_RC iesys_cryptossl_hmac_update2b( + IESYS_CRYPTO_CONTEXT_BLOB *context, + TPM2B *b); + +TSS2_RC iesys_cryptossl_hmac_finish( + IESYS_CRYPTO_CONTEXT_BLOB **context, + uint8_t *buffer, + size_t *size); + +TSS2_RC iesys_cryptossl_hmac_finish2b( + IESYS_CRYPTO_CONTEXT_BLOB **context, + TPM2B *b); + +void iesys_cryptossl_hmac_abort(IESYS_CRYPTO_CONTEXT_BLOB **context); + +#define iesys_crypto_hmac_start iesys_cryptossl_hmac_start +#define iesys_crypto_hmac_start2b iesys_cryptossl_hmac_start2b +#define iesys_crypto_hmac_update iesys_cryptossl_hmac_update +#define iesys_crypto_hmac_update2b iesys_cryptossl_hmac_update2b +#define iesys_crypto_hmac_finish iesys_cryptossl_hmac_finish +#define iesys_crypto_hmac_finish2b iesys_cryptossl_hmac_finish2b +#define iesys_crypto_hmac_abort iesys_cryptossl_hmac_abort + +TSS2_RC iesys_cryptossl_random2b(TPM2B_NONCE *nonce, size_t num_bytes); + +TSS2_RC iesys_cryptossl_pk_encrypt( + TPM2B_PUBLIC *key, + size_t in_size, + BYTE *in_buffer, + size_t max_out_size, + BYTE *out_buffer, + size_t *out_size, + const char *label); + + +TSS2_RC iesys_cryptossl_sym_aes_encrypt( + uint8_t *key, + TPM2_ALG_ID tpm_sym_alg, + TPMI_AES_KEY_BITS key_bits, + TPM2_ALG_ID tpm_mode, + size_t blk_len, + uint8_t *dst, + size_t dst_size, + uint8_t *iv); + +TSS2_RC iesys_cryptossl_sym_aes_decrypt( + uint8_t *key, + TPM2_ALG_ID tpm_sym_alg, + TPMI_AES_KEY_BITS key_bits, + TPM2_ALG_ID tpm_mode, + size_t blk_len, + uint8_t *dst, + size_t dst_size, + uint8_t *iv); + +TSS2_RC iesys_cryptossl_get_ecdh_point( + TPM2B_PUBLIC *key, + size_t max_out_size, + TPM2B_ECC_PARAMETER *Z, + TPMS_ECC_POINT *Q, + BYTE * out_buffer, + size_t * out_size); + +#define iesys_crypto_random2b iesys_cryptossl_random2b +#define iesys_crypto_get_ecdh_point iesys_cryptossl_get_ecdh_point +#define iesys_crypto_sym_aes_encrypt iesys_cryptossl_sym_aes_encrypt +#define iesys_crypto_sym_aes_decrypt iesys_cryptossl_sym_aes_decrypt + +TSS2_RC iesys_cryptossl_init(); + +#define iesys_crypto_init iesys_cryptossl_init + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ESYS_CRYPTO_OSSL_H */ |