/********************************************************************************/ /* */ /* Sample Crypto Utilities */ /* Written by Ken Goldman */ /* IBM Thomas J. Watson Research Center */ /* */ /* (c) Copyright IBM Corporation 2017 - 2019. */ /* */ /* 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 CRYPTUTILS_H #define CRYPTUTILS_H /* Windows 10 crypto API clashes with openssl */ #ifdef TPM_WINDOWS #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include #include #endif /* TPM_TSS_NO_OPENSSL is a legacy macro. cryptoutils was exposing several OpenSSL specific functions. They are not available for other crypto libraries. For OpenSSL, they are available but deprecated. */ #ifndef TPM_TSS_NO_OPENSSL #include #include #endif /* TPM_TSS_NO_OPENSSL */ #ifdef TPM_TSS_MBEDTLS #include #endif /* TPM_TSS_MBEDTLS */ #include #ifdef __cplusplus extern "C" { #endif /* crypto library independent functions */ void getCryptoLibrary(const char **name); TPM_RC convertPemToRsaPrivKey(void **rsaKey, const char *pemKeyFilename, const char *password); TPM_RC convertRsaKeyToPublicKeyBin(int *modulusBytes, uint8_t **modulusBin, void *rsaKey); TPM_RC convertRsaKeyToPublic(TPM2B_PUBLIC *objectPublic, int keyType, TPMI_ALG_SIG_SCHEME scheme, TPMI_ALG_HASH nalg, TPMI_ALG_HASH halg, void *rsaKey); TPM_RC convertRsaPemToKeyPair(TPM2B_PUBLIC *objectPublic, TPM2B_PRIVATE *objectPrivate, int keyType, TPMI_ALG_SIG_SCHEME scheme, TPMI_ALG_HASH nalg, TPMI_ALG_HASH halg, const char *pemKeyFilename, const char *password); TPM_RC convertRsaDerToKeyPair(TPM2B_PUBLIC *objectPublic, TPM2B_SENSITIVE *objectSensitive, int keyType, TPMI_ALG_SIG_SCHEME scheme, TPMI_ALG_HASH nalg, TPMI_ALG_HASH halg, const char *derKeyFilename, const char *password); TPM_RC convertRsaDerToPublic(TPM2B_PUBLIC *objectPublic, int keyType, TPMI_ALG_SIG_SCHEME scheme, TPMI_ALG_HASH nalg, TPMI_ALG_HASH halg, const char *derKeyFilename); TPM_RC convertRsaPemToPublic(TPM2B_PUBLIC *objectPublic, int keyType, TPMI_ALG_SIG_SCHEME scheme, TPMI_ALG_HASH nalg, TPMI_ALG_HASH halg, const char *pemKeyFilename); TPM_RC convertRsaPrivateKeyBinToPrivate(TPM2B_PRIVATE *objectPrivate, TPM2B_SENSITIVE *objectSensitive, int privateKeyBytes, uint8_t *privateKeyBin, const char *password); TPM_RC convertRsaPublicKeyBinToPublic(TPM2B_PUBLIC *objectPublic, int keyType, TPMI_ALG_SIG_SCHEME scheme, TPMI_ALG_HASH nalg, TPMI_ALG_HASH halg, int modulusBytes, uint8_t *modulusBin); TPM_RC convertPublicToPEM(const TPM2B_PUBLIC *public, const char *pemFilename); TPM_RC signRSAFromRSA(uint8_t *signature, size_t *signatureLength, size_t signatureSize, const uint8_t *digest, size_t digestLength, TPMI_ALG_HASH hashAlg, void *rsaKey); TPM_RC verifySignatureFromPem(unsigned char *message, unsigned int messageSize, TPMT_SIGNATURE *tSignature, TPMI_ALG_HASH halg, const char *pemFilename); TPM_RC verifyRSASignatureFromRSA(unsigned char *message, unsigned int messageSize, TPMT_SIGNATURE *tSignature, TPMI_ALG_HASH halg, void *rsaPubKey); TPM_RC verifySignatureFromHmacKey(unsigned char *message, unsigned int messageSize, TPMT_SIGNATURE *tSignature, TPMI_ALG_HASH halg, const char *hmacKeyFilename); TPM_RC convertRsaBinToTSignature(TPMT_SIGNATURE *tSignature, TPMI_ALG_HASH halg, uint8_t *signatureBin, size_t signatureBinLen); /* Some OpenSSL builds do not include ECC */ #ifndef TPM_TSS_NOECC TPM_RC convertEcPemToKeyPair(TPM2B_PUBLIC *objectPublic, TPM2B_PRIVATE *objectPrivate, int keyType, TPMI_ALG_SIG_SCHEME scheme, TPMI_ALG_HASH nalg, TPMI_ALG_HASH halg, const char *pemKeyFilename, const char *password); TPM_RC convertEcPemToPublic(TPM2B_PUBLIC *objectPublic, int keyType, TPMI_ALG_SIG_SCHEME scheme, TPMI_ALG_HASH nalg, TPMI_ALG_HASH halg, const char *pemKeyFilename); TPM_RC convertEcDerToKeyPair(TPM2B_PUBLIC *objectPublic, TPM2B_SENSITIVE *objectSensitive, int keyType, TPMI_ALG_SIG_SCHEME scheme, TPMI_ALG_HASH nalg, TPMI_ALG_HASH halg, const char *derKeyFilename, const char *password); TPM_RC convertEcDerToPublic(TPM2B_PUBLIC *objectPublic, int keyType, TPMI_ALG_SIG_SCHEME scheme, TPMI_ALG_HASH nalg, TPMI_ALG_HASH halg, const char *derKeyFilename); TPM_RC convertEcPrivateKeyBinToPrivate(TPM2B_PRIVATE *objectPrivate, TPM2B_SENSITIVE *objectSensitive, int privateKeyBytes, uint8_t *privateKeyBin, const char *password); TPM_RC convertEcBinToTSignature(TPMT_SIGNATURE *tSignature, TPMI_ALG_HASH halg, const uint8_t *signatureBin, size_t signatureBinLen); #endif /* TPM_TSS_NOECC */ /* OpenSSL specific functions These are not intended for general use. */ #ifndef TPM_TSS_NO_OPENSSL /* Some functions add const to parameters as of openssl 1.1.0 */ #if OPENSSL_VERSION_NUMBER < 0x10100000 #define OSSLCONST #else #define OSSLCONST const #endif #if OPENSSL_VERSION_NUMBER < 0x10100000 int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x); void RSA_get0_key(const RSA *rsaKey, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); void RSA_get0_factors(const RSA *rsaKey, const BIGNUM **p, const BIGNUM **q); #endif /* pre openssl 1.1 */ #if OPENSSL_VERSION_NUMBER < 0x10002000 void X509_get0_signature(OSSLCONST ASN1_BIT_STRING **psig, OSSLCONST X509_ALGOR **palg, const X509 *x); #endif /* pre openssl 1.0.2 */ TPM_RC convertPemToEvpPrivKey(EVP_PKEY **evpPkey, const char *pemKeyFilename, const char *password); TPM_RC convertPemToEvpPubKey(EVP_PKEY **evpPkey, const char *pemKeyFilename); TPM_RC convertEvpPubkeyToPem(EVP_PKEY *evpPubkey, const char *pemFilename); TPM_RC convertBin2Bn(BIGNUM **bn, const unsigned char *bin, unsigned int bytes); TPM_RC convertEvpPkeyToRsakey(RSA **rsaKey, EVP_PKEY *evpPkey); TPM_RC convertRsaKeyToPrivateKeyBin(int *privateKeyBytes, uint8_t **privateKeyBin, const RSA *rsaKey); TPM_RC convertRsaKeyToPrivate(TPM2B_PRIVATE *objectPrivate, TPM2B_SENSITIVE *objectSensitive, RSA *rsaKey, const char *password); TPM_RC getRsaKeyParts(const BIGNUM **n, const BIGNUM **e, const BIGNUM **d, const BIGNUM **p, const BIGNUM **q, const RSA *rsaKey); int getRsaPubkeyAlgorithm(EVP_PKEY *pkey); TPM_RC convertRsaPublicToEvpPubKey(EVP_PKEY **evpPubkey, const TPM2B_PUBLIC_KEY_RSA *tpm2bRsa); TPM_RC verifyRSASignatureFromEvpPubKey(unsigned char *message, unsigned int messageSize, TPMT_SIGNATURE *tSignature, TPMI_ALG_HASH halg, EVP_PKEY *evpPkey); #ifndef TPM_TSS_NOECC TPM_RC convertEvpPkeyToEckey(EC_KEY **ecKey, EVP_PKEY *evpPkey); TPM_RC convertEcKeyToPrivateKeyBin(int *privateKeyBytes, uint8_t **privateKeyBin, const EC_KEY *ecKey); TPM_RC convertEcKeyToPublicKeyBin(int *modulusBytes, uint8_t **modulusBin, const EC_KEY *ecKey); TPM_RC convertEcPublicKeyBinToPublic(TPM2B_PUBLIC *objectPublic, int keyType, TPMI_ALG_SIG_SCHEME scheme, TPMI_ALG_HASH nalg, TPMI_ALG_HASH halg, TPMI_ECC_CURVE curveID, int modulusBytes, uint8_t *modulusBin); TPM_RC convertEcKeyToPrivate(TPM2B_PRIVATE *objectPrivate, TPM2B_SENSITIVE *objectSensitive, EC_KEY *ecKey, const char *password); TPM_RC convertEcKeyToPublic(TPM2B_PUBLIC *objectPublic, int keyType, TPMI_ALG_SIG_SCHEME scheme, TPMI_ALG_HASH nalg, TPMI_ALG_HASH halg, EC_KEY *ecKey); TPM_RC convertEcPublicToEvpPubKey(EVP_PKEY **evpPubkey, const TPMS_ECC_POINT *tpmsEccPoint); TPM_RC verifyEcSignatureFromEvpPubKey(unsigned char *message, unsigned int messageSize, TPMT_SIGNATURE *tSignature, EVP_PKEY *evpPkey); TPM_RC getEcCurve(TPMI_ECC_CURVE *curveID, const EC_KEY *ecKey); #endif /* TPM_TSS_NOECC */ #endif /* TPM_TSS_NO_OPENSSL */ /* mbedtls specific functions These are not intended for general use, but are used by ekutils.c */ #ifdef TPM_TSS_MBEDTLS TPM_RC convertPkToRsaKey(mbedtls_rsa_context **rsaCtx, mbedtls_pk_context *pkCtx); TPM_RC convertPkToEckey(mbedtls_ecp_keypair **ecCtx, mbedtls_pk_context *pkCtx); TPM_RC convertEcKeyToPublicKeyXYBin(size_t *xBytes, uint8_t **xBin, size_t *yBytes, uint8_t **yBin, mbedtls_ecp_keypair *ecKp); #endif /* TPM_TSS_MBEDTLS */ #ifdef __cplusplus } #endif #endif