X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmanager%2Fcrypto%2Ftz-backend%2Finternals.cpp;h=2a5d83c67ee709241f977bff7eca0026f2d2228d;hb=cb41ffff1addfb746aa755d434a2f6ce6d8f7376;hp=ae67c8cdcf77504325fcaf954456d895ca740755;hpb=45091056927dfb30e9fef48e6ac702e0f1600fdf;p=platform%2Fcore%2Fsecurity%2Fkey-manager.git diff --git a/src/manager/crypto/tz-backend/internals.cpp b/src/manager/crypto/tz-backend/internals.cpp index ae67c8c..2a5d83c 100644 --- a/src/manager/crypto/tz-backend/internals.cpp +++ b/src/manager/crypto/tz-backend/internals.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2017-2020 Samsung Electronics Co., Ltd. All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,8 +24,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -33,12 +35,21 @@ #include #include #include +#include #include -namespace { +#ifndef __has_cpp_attribute +#define __has_cpp_attribute(_) 0 +#endif -using DSAPtr = std::unique_ptr>; +#if __has_cpp_attribute(fallthrough) +#define fallthru [[fallthrough]] +#else +#define fallthru ((void)0) +#endif + +namespace { CKM::RawBuffer extractBignumData(const BIGNUM* bn) { @@ -58,7 +69,7 @@ CKM::RawBuffer extractBignumData(const BIGNUM* bn) void generateDSAParams(const int sizeBits, CKM::RawBuffer &prime, CKM::RawBuffer &subprime, CKM::RawBuffer &base) { - DSAPtr dsa(DSA_new(), DSA_free); + auto dsa = uptr(DSA_new()); if (!dsa) { ThrowErr(CKM::Exc::Crypto::InternalError, "Failed to create DSA context for parameter gen"); @@ -71,17 +82,68 @@ void generateDSAParams(const int sizeBits, CKM::RawBuffer &prime, // at this stage dsa->p, dsa->q & dsa->r should contain our params // extract them into buffers -#if OPENSSL_VERSION_NUMBER < 0x10100000L - prime = extractBignumData(dsa->p); - subprime = extractBignumData(dsa->q); - base = extractBignumData(dsa->g); -#else const BIGNUM *p, *q, *g; DSA_get0_pqg(dsa.get(), &p, &q, &g); prime = extractBignumData(p); subprime = extractBignumData(q); base = extractBignumData(g); -#endif +} + +tz_data_type toTzDataType(const CKM::DataType dataType) { + switch (dataType) { + case CKM::DataType::BINARY_DATA: return TYPE_GENERIC_SECRET; + case CKM::DataType::KEY_AES: return TYPE_SKEY; + case CKM::DataType::KEY_DSA_PRIVATE: return TYPE_AKEY_PRIVATE_DSA; + case CKM::DataType::KEY_RSA_PRIVATE: return TYPE_AKEY_PRIVATE_RSA; + case CKM::DataType::KEY_ECDSA_PRIVATE: return TYPE_AKEY_PRIVATE_EC; + case CKM::DataType::KEY_DSA_PUBLIC: return TYPE_AKEY_PUBLIC_DSA; + case CKM::DataType::KEY_RSA_PUBLIC: return TYPE_AKEY_PUBLIC_RSA; + case CKM::DataType::KEY_ECDSA_PUBLIC: return TYPE_AKEY_PUBLIC_EC; + default: + ThrowErr(CKM::Exc::Crypto::DataTypeNotSupported, + "Data type could not be imported by tz-backend"); + } +} + +tz_ec toTzEc(CKM::ElipticCurve ec) +{ + switch(ec) { + case CKM::ElipticCurve::prime192v1: return EC_NIST_P192; + case CKM::ElipticCurve::prime256v1: return EC_NIST_P256; + case CKM::ElipticCurve::secp384r1: return EC_NIST_P384; + default: ThrowErr(CKM::Exc::Crypto::DataTypeNotSupported, "EC not supported by tz-backend"); + } +} + +tz_prf toTzPrf(CKM::KdfPrf prf) +{ + switch(prf) { + case CKM::KdfPrf::HMAC_SHA256: return PRF_HMAC_SHA256; + case CKM::KdfPrf::HMAC_SHA384: return PRF_HMAC_SHA384; + case CKM::KdfPrf::HMAC_SHA512: return PRF_HMAC_SHA512; + default: ThrowErr(CKM::Exc::Crypto::DataTypeNotSupported, "PRF not supported by tz-backend"); + } +} + +tz_kbkdf_mode toTzKbkdfMode(CKM::KbkdfMode mode) +{ + switch(mode) { + case CKM::KbkdfMode::COUNTER: return KBKDF_MODE_COUNTER; + default: + ThrowErr(CKM::Exc::Crypto::DataTypeNotSupported, "KBKDF mode not supported by tz-backend"); + } +} + +tz_kbkdf_ctr_loc toTzCtrLoc(CKM::KbkdfCounterLocation loc) +{ + switch(loc) { + case CKM::KbkdfCounterLocation::BEFORE_FIXED: return KBKDF_LOC_BEFORE_FIXED; + case CKM::KbkdfCounterLocation::AFTER_FIXED: return KBKDF_LOC_AFTER_FIXED; + case CKM::KbkdfCounterLocation::MIDDLE_FIXED: return KBKDF_LOC_MIDDLE_FIXED; + default: + ThrowErr(CKM::Exc::Crypto::DataTypeNotSupported, + "KBKDF counter location not supported by tz-backend"); + } } } // namespace @@ -91,6 +153,8 @@ namespace Crypto { namespace TZ { namespace Internals { +namespace { + tz_algo_type getGenSKeyType(AlgoType type) { switch (type) @@ -116,26 +180,6 @@ tz_algo_type getAlgType(AlgoType type) }; } -tz_algo_type getAlgType(KeyType keyType) -{ - switch (keyType) - { - case KeyType::KEY_AES: - return ALGO_AES_GEN; - case KeyType::KEY_RSA_PUBLIC: - case KeyType::KEY_RSA_PRIVATE: - return ALGO_RSA_GEN; - case KeyType::KEY_DSA_PUBLIC: - case KeyType::KEY_DSA_PRIVATE: - return ALGO_DSA_GEN; - case KeyType::KEY_ECDSA_PUBLIC: - case KeyType::KEY_ECDSA_PRIVATE: - return ALGO_ECDSA_GEN; - default: - ThrowErr(Exc::Crypto::OperationNotSupported, "Requested algorithm is not supported"); - }; -} - tz_hash_type getHashType(HashAlgorithm hash) { switch (hash) @@ -149,6 +193,46 @@ tz_hash_type getHashType(HashAlgorithm hash) } } +void decompose(const CryptoAlgorithm &alg, + AlgoType &algo, + uint32_t &ctrLenOrTagSizeBits, + RawBuffer &iv, + RawBuffer &aad) +{ + algo = unpack(alg, ParamName::ALGO_TYPE); + switch (algo) { + case AlgoType::AES_CTR: + iv = unpack(alg, ParamName::ED_IV); + ctrLenOrTagSizeBits = Params::DEFAULT_AES_IV_LEN * 8; + alg.getParam(ParamName::ED_CTR_LEN, ctrLenOrTagSizeBits); + // counter length is in bits + if (ctrLenOrTagSizeBits != Params::DEFAULT_AES_IV_LEN * 8) { + LogError("CTR length invalid: " << std::to_string(ctrLenOrTagSizeBits)); + ThrowErr(Exc::Crypto::InputParam, "Invalid CTR length"); + } + break; + case AlgoType::AES_CBC: + iv = unpack(alg, ParamName::ED_IV); + break; + case AlgoType::AES_CFB: + iv = unpack(alg, ParamName::ED_IV); + break; + case AlgoType::AES_GCM: + iv = unpack(alg, ParamName::ED_IV); + ctrLenOrTagSizeBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS; + alg.getParam(ParamName::ED_TAG_LEN, ctrLenOrTagSizeBits); + alg.getParam(ParamName::ED_AAD, aad); + break; + case AlgoType::RSA_OAEP: + break; + default: + ThrowErr(Exc::Crypto::InputParam, "Invalid decryption algorithm"); + break; + } +} + +} // namespace + RawBuffer generateIV() { RawBuffer result; @@ -156,17 +240,15 @@ RawBuffer generateIV() return result; } -Data generateSKey(const CryptoAlgorithm &alg, +void generateSKey(const CryptoAlgorithm &alg, const Password &pwd, const RawBuffer &iv, - RawBuffer &tag) + RawBuffer &tag, + const RawBuffer &hash) { AlgoType keyType = unpack(alg, ParamName::ALGO_TYPE); int keyBits = unpack(alg, ParamName::GEN_KEY_LEN); - Data keyData; - keyData.type = DataType(KeyType::KEY_AES); - if (!pwd.empty()) { if (iv.empty()) { ThrowErr(Exc::InputParam, "Key generation with password encryption requires an IV"); @@ -175,28 +257,25 @@ Data generateSKey(const CryptoAlgorithm &alg, RawBuffer pwdBuf(pwd.begin(), pwd.end()); TrustZoneContext::Instance().generateSKeyPwd(getGenSKeyType(keyType), pwdBuf, iv, keyBits, - keyData.data, tag); + tag, hash); } else { TrustZoneContext::Instance().generateSKey(getGenSKeyType(keyType), keyBits, - keyData.data); + hash); } - return keyData; } -DataPair generateAKey(const CryptoAlgorithm &alg, +AlgoType generateAKey(const CryptoAlgorithm &alg, const Password &pubPwd, const Password &privPwd, const RawBuffer &pubPwdIv, const RawBuffer &privPwdIv, RawBuffer &pubTag, - RawBuffer &privTag) + RawBuffer &privTag, + const RawBuffer &hashPriv, + const RawBuffer &hashPub) { AlgoType keyType = unpack(alg, ParamName::ALGO_TYPE); - int keyBits = unpack(alg, ParamName::GEN_KEY_LEN); - - Data pubKeyData; - Data privKeyData; RawBuffer pubPwdBuf; if (!pubPwd.empty()) @@ -208,24 +287,20 @@ DataPair generateAKey(const CryptoAlgorithm &alg, switch (keyType) { case AlgoType::RSA_GEN: { - pubKeyData.type = DataType(KeyType::KEY_RSA_PUBLIC); - privKeyData.type = DataType(KeyType::KEY_RSA_PRIVATE); - + int keyBits = unpack(alg, ParamName::GEN_KEY_LEN); TrustZoneContext::Instance().generateRSAKey(keyBits, pubPwdBuf, pubPwdIv, privPwdBuf, privPwdIv, - pubKeyData.data, pubTag, - privKeyData.data, - privTag); + privTag, + hashPriv, + hashPub); break; } case AlgoType::DSA_GEN: { - pubKeyData.type = DataType(KeyType::KEY_DSA_PUBLIC); - privKeyData.type = DataType(KeyType::KEY_DSA_PRIVATE); - + int keyBits = unpack(alg, ParamName::GEN_KEY_LEN); RawBuffer prime; RawBuffer subprime; RawBuffer base; @@ -238,10 +313,23 @@ DataPair generateAKey(const CryptoAlgorithm &alg, pubPwdIv, privPwdBuf, privPwdIv, - pubKeyData.data, pubTag, - privKeyData.data, - privTag); + privTag, + hashPriv, + hashPub); + break; + } + case AlgoType::ECDSA_GEN: { + CKM::ElipticCurve ec = unpack(alg, ParamName::GEN_EC); + TrustZoneContext::Instance().generateECKey(toTzEc(ec), + pubPwdBuf, + pubPwdIv, + privPwdBuf, + privPwdIv, + pubTag, + privTag, + hashPriv, + hashPub); break; } default: { @@ -250,37 +338,23 @@ DataPair generateAKey(const CryptoAlgorithm &alg, } } - return DataPair(pubKeyData, privKeyData); + return keyType; } -void destroyKey(const RawBuffer &key) +void destroyKey(const RawBuffer &keyId) { - TrustZoneContext::Instance().executeDestroy(key); + TrustZoneContext::Instance().executeDestroy(keyId); } -RawBuffer importData(const Data &data, +void importData(const Data &data, const EncryptionParams &encData, const Password &pwd, const RawBuffer &pwdIV, - RawBuffer &tag) + RawBuffer &tag, + const RawBuffer &hash) { - uint32_t dataType; - - if (data.type.isSKey()) { - dataType = TYPE_SKEY; - } else if (data.type.isBinaryData()) { - dataType = TYPE_GENERIC_SECRET; - } else if (data.type.isKeyPrivate()) { - dataType = TYPE_AKEY_PRIVATE; - } else if (data.type.isKeyPublic()) { - dataType = TYPE_AKEY_PUBLIC; - } else { - ThrowErr(Exc::Crypto::DataTypeNotSupported, - "Data type could not be impoted by tz-backend"); - } - - RawBuffer result; + const auto dataType = toTzDataType(data.type); RawBuffer pwdBuf(pwd.begin(), pwd.end()); uint32_t keySizeBits = data.data.size() * 8; @@ -290,18 +364,75 @@ RawBuffer importData(const Data &data, pwdBuf, pwdIV, keySizeBits, - Params::DERIVED_KEY_LENGTH_BITS, - result, - tag); - return result; + tag, + hash); +} + +void importWrappedKey(const RawBuffer &wrappingKeyId, + const Pwd &wrappingKeyPwd, + const CryptoAlgorithm &alg, + const Data &encryptedKey, + const Password &encryptedKeyPassword, + const RawBuffer &encryptedKeyIV, + RawBuffer &encryptedKeyTag, + const RawBuffer &encryptedKeyId) +{ + RawBuffer encryptedKeyPwdBuf(encryptedKeyPassword.begin(), encryptedKeyPassword.end()); + + AlgoType algo; + uint32_t ctrLenOrTagSizeBits = 0; + RawBuffer iv; + RawBuffer aad; + decompose(alg, algo, ctrLenOrTagSizeBits, iv, aad); + + // TODO it is awful! + TrustZoneContext::Instance().importWrappedKey(wrappingKeyId, + wrappingKeyPwd, + getAlgType(algo), + iv, + ctrLenOrTagSizeBits, + aad, + toTzDataType(encryptedKey.type), + encryptedKey.data, + encryptedKeyPwdBuf, + encryptedKeyIV, + encryptedKeyTag, + encryptedKeyId); +} + +RawBuffer exportWrappedKey(const RawBuffer &wrappingKeyId, + const Pwd &wrappingKeyPwd, + const CryptoAlgorithm &alg, + const RawBuffer &keyToWrapId, + const Pwd &keyToWrapPwd, + const DataType &keyToWrapType) +{ + AlgoType algo; + uint32_t ctrLenOrTagSizeBits = 0; + RawBuffer iv; + RawBuffer aad; + decompose(alg, algo, ctrLenOrTagSizeBits, iv, aad); + + // TODO it is awful! + return TrustZoneContext::Instance().exportWrappedKey(wrappingKeyId, + wrappingKeyPwd, + getAlgType(algo), + iv, + ctrLenOrTagSizeBits, + aad, + keyToWrapId, + keyToWrapPwd, + toTzDataType(keyToWrapType)); } RawBuffer getData(const RawBuffer &dataId, - const Pwd &pwd) + const Pwd &pwd, + const DataType &type) { RawBuffer result; TrustZoneContext::Instance().getData(dataId, pwd, + toTzDataType(type), result); return result; } @@ -311,7 +442,7 @@ void destroyData(const RawBuffer &dataId) TrustZoneContext::Instance().destroyData(dataId); } -BufferPair encryptDataAesGcm(const RawBuffer &key, +BufferPair encryptDataAesGcm(const RawBuffer &keyId, const Pwd &pwd, const RawBuffer &iv, int tagSize, @@ -321,26 +452,26 @@ BufferPair encryptDataAesGcm(const RawBuffer &key, RawBuffer result; RawBuffer tag; - TrustZoneContext::Instance().executeEncryptAE(key, pwd, iv, tagSize, + TrustZoneContext::Instance().executeEncryptAE(keyId, pwd, iv, tagSize, aad, data, result, tag); return std::make_pair(result, tag); } -RawBuffer encryptDataAesGcmPacked(const RawBuffer &key, +RawBuffer encryptDataAesGcmPacked(const RawBuffer &keyId, const Pwd &pwd, const RawBuffer &iv, int tagSize, const RawBuffer &data, const RawBuffer &aad) { - auto pair = encryptDataAesGcm(key, pwd, iv, tagSize, data, aad); + auto pair = encryptDataAesGcm(keyId, pwd, iv, tagSize, data, aad); std::copy(pair.second.begin(), pair.second.end(), std::back_inserter(pair.first)); return pair.first; } -RawBuffer decryptDataAesGcm(const RawBuffer &key, +RawBuffer decryptDataAesGcm(const RawBuffer &keyId, const Pwd &pwd, const RawBuffer &iv, int tagSizeBits, @@ -350,13 +481,13 @@ RawBuffer decryptDataAesGcm(const RawBuffer &key, { RawBuffer result; - TrustZoneContext::Instance().executeDecryptAE(key, pwd, iv, tagSizeBits, + TrustZoneContext::Instance().executeDecryptAE(keyId, pwd, iv, tagSizeBits, tag, aad, data, result); return result; } -RawBuffer decryptDataAesGcmPacked(const RawBuffer &key, +RawBuffer decryptDataAesGcmPacked(const RawBuffer &keyId, const Pwd &pwd, const RawBuffer &iv, int tagSizeBits, @@ -368,7 +499,7 @@ RawBuffer decryptDataAesGcmPacked(const RawBuffer &key, ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag"); auto tagPos = data.data() + data.size() - tagSizeBytes; - return decryptDataAesGcm(key, + return decryptDataAesGcm(keyId, pwd, iv, tagSizeBits, @@ -378,30 +509,31 @@ RawBuffer decryptDataAesGcmPacked(const RawBuffer &key, } -RawBuffer symmetricEncrypt(const RawBuffer &key, +RawBuffer symmetricEncrypt(const RawBuffer &keyId, const Pwd &pwd, const CryptoAlgorithm &alg, const RawBuffer &data) { AlgoType algo = unpack(alg, ParamName::ALGO_TYPE); - uint64_t ctrLen = 0; + uint64_t ctrLen = Params::DEFAULT_AES_IV_LEN * 8; switch (algo) { case AlgoType::AES_CTR: { - ctrLen = unpack(alg, ParamName::ED_CTR_LEN); + alg.getParam(ParamName::ED_CTR_LEN, ctrLen); // counter length is in bits if (ctrLen != Params::DEFAULT_AES_IV_LEN * 8) { LogError("CTR length invalid: " << std::to_string(ctrLen)); ThrowErr(Exc::Crypto::InputParam, "Invalid CTR length"); } // no break here, we still need to slide down to executeCrypt + fallthru; } case AlgoType::AES_CBC: case AlgoType::AES_CFB: { RawBuffer result; TrustZoneContext::Instance().executeCrypt(CMD_ENCRYPT, getAlgType(algo), - key, + keyId, pwd, unpack(alg, ParamName::ED_IV), data, @@ -413,7 +545,7 @@ RawBuffer symmetricEncrypt(const RawBuffer &key, alg.getParam(ParamName::ED_TAG_LEN, tagLenBits); RawBuffer aad; alg.getParam(ParamName::ED_AAD, aad); - return encryptDataAesGcmPacked(key, + return encryptDataAesGcmPacked(keyId, pwd, unpack(alg, ParamName::ED_IV), tagLenBits, @@ -428,30 +560,31 @@ RawBuffer symmetricEncrypt(const RawBuffer &key, "Incorrect algorithm provided for symmetric crypto operation"); } -RawBuffer symmetricDecrypt(const RawBuffer &key, +RawBuffer symmetricDecrypt(const RawBuffer &keyId, const Pwd &pwd, const CryptoAlgorithm &alg, const RawBuffer &data) { AlgoType algo = unpack(alg, ParamName::ALGO_TYPE); - uint64_t ctrLen = 0; + uint64_t ctrLen = Params::DEFAULT_AES_IV_LEN * 8; switch (algo) { case AlgoType::AES_CTR: { - ctrLen = unpack(alg, ParamName::ED_CTR_LEN); + alg.getParam(ParamName::ED_CTR_LEN, ctrLen); // counter length is in bits if (ctrLen != Params::DEFAULT_AES_IV_LEN * 8) { LogError("CTR length invalid: " << std::to_string(ctrLen)); ThrowErr(Exc::Crypto::InputParam, "Invalid CTR length"); } // no break here, we still need to slide down to executeCrypt + fallthru; } case AlgoType::AES_CBC: case AlgoType::AES_CFB: { RawBuffer result; TrustZoneContext::Instance().executeCrypt(CMD_DECRYPT, getAlgType(algo), - key, + keyId, pwd, unpack(alg, ParamName::ED_IV), data, @@ -463,7 +596,7 @@ RawBuffer symmetricDecrypt(const RawBuffer &key, alg.getParam(ParamName::ED_TAG_LEN, tagSizeBits); RawBuffer aad; alg.getParam(ParamName::ED_AAD, aad); - return decryptDataAesGcmPacked(key, + return decryptDataAesGcmPacked(keyId, pwd, unpack(alg, ParamName::ED_IV), tagSizeBits, @@ -478,7 +611,7 @@ RawBuffer symmetricDecrypt(const RawBuffer &key, "Incorrect algorithm provided for symmetric crypto operation"); } -RawBuffer asymmetricEncrypt(const RawBuffer &key, +RawBuffer asymmetricEncrypt(const RawBuffer &keyId, const Pwd &pwd, const CryptoAlgorithm &alg, const RawBuffer &data) @@ -491,9 +624,9 @@ RawBuffer asymmetricEncrypt(const RawBuffer &key, case AlgoType::RSA_OAEP: { TrustZoneContext::Instance().executeCrypt(CMD_ENCRYPT, getAlgType(algo), - key, + keyId, pwd, - unpack(alg, ParamName::ED_IV), + result, // unused dummy data, result); return result; @@ -506,7 +639,7 @@ RawBuffer asymmetricEncrypt(const RawBuffer &key, "Incorrect algorithm provided for asymmetric crypto operation"); } -RawBuffer asymmetricDecrypt(const RawBuffer &key, +RawBuffer asymmetricDecrypt(const RawBuffer &keyId, const Pwd &pwd, const CryptoAlgorithm &alg, const RawBuffer &cipher) @@ -519,9 +652,9 @@ RawBuffer asymmetricDecrypt(const RawBuffer &key, case AlgoType::RSA_OAEP: { TrustZoneContext::Instance().executeCrypt(CMD_DECRYPT, getAlgType(algo), - key, + keyId, pwd, - unpack(alg, ParamName::ED_IV), + result, // unused dummy cipher, result); return result; @@ -534,7 +667,63 @@ RawBuffer asymmetricDecrypt(const RawBuffer &key, "Incorrect algorithm provided for asymmetric crypto operation"); } -RawBuffer sign(const RawBuffer &pkey, +uint32_t initCipher(const RawBuffer &keyId, + const Pwd &pwd, + const CryptoAlgorithm &alg, + bool encrypt) +{ + AlgoType algo = unpack(alg, ParamName::ALGO_TYPE); + + switch (algo) + { + case AlgoType::AES_GCM: { + int tagSizeBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS; + alg.getParam(ParamName::ED_TAG_LEN, tagSizeBits); + RawBuffer aad; + alg.getParam(ParamName::ED_AAD, aad); + return TrustZoneContext::Instance().initGcmCipher(encrypt ? CIPHER_ENCRYPT : CIPHER_DECRYPT, + keyId, + pwd, + unpack(alg, ParamName::ED_IV), + tagSizeBits, + aad); + } + case AlgoType::AES_CBC: + case AlgoType::AES_CTR: + case AlgoType::AES_CFB: + // TODO optionally implement above modes as well + default: + break; + }; + + ThrowErr(Exc::Crypto::OperationNotSupported, + "Incorrect algorithm provided for symmetric crypto operation"); +} + +void addAAD(uint32_t opId, + const RawBuffer &aad) +{ + TrustZoneContext::Instance().addGcmAAD(opId, aad); +} + +RawBuffer updateCipher(uint32_t opId, + const RawBuffer &data) +{ + return TrustZoneContext::Instance().updateGcmCipher(opId, data); +} + +RawBuffer finalizeCipher(uint32_t opId, + const RawBuffer &data) +{ + return TrustZoneContext::Instance().finalizeGcmCipher(opId, data); +} + +void cleanupCipher(uint32_t opId) +{ + return TrustZoneContext::Instance().cleanupCipher(opId); +} + +RawBuffer sign(const RawBuffer &pkeyId, const Pwd &pwd, const CryptoAlgorithm &alg, const RawBuffer &message) @@ -547,14 +736,14 @@ RawBuffer sign(const RawBuffer &pkey, RawBuffer signature; TrustZoneContext::Instance().executeSign(getAlgType(algo), getHashType(hash), - pkey, + pkeyId, pwd, message, signature); return signature; } -int verify(const RawBuffer &pkey, +int verify(const RawBuffer &pkeyId, const Pwd &pwd, const CryptoAlgorithm &alg, const RawBuffer &message, @@ -567,12 +756,150 @@ int verify(const RawBuffer &pkey, return TrustZoneContext::Instance().executeVerify(getAlgType(algo), getHashType(hash), - pkey, + pkeyId, pwd, message, signature); } +void deriveECDH(const RawBuffer &prvKeyId, + const Pwd &prvKeyPwd, + const RawBuffer &pubKey, + const Password &secretPwd, + const RawBuffer &secretPwdIV, + RawBuffer &secretTag, + const RawBuffer &secretHash) +{ + auto peerKey = std::make_shared(pubKey); + if (peerKey->getType() != KeyType::KEY_ECDSA_PUBLIC) + ThrowErr(Exc::Crypto::InputParam, "ECDH requires peer's public EC key"); + auto peerEvp = peerKey->getEvpShPtr().get(); + assert(peerEvp); + + int subType = EVP_PKEY_type(EVP_PKEY_id(peerEvp)); + if (subType != EVP_PKEY_EC) + ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", subType); + + auto ecKey = EVP_PKEY_get0_EC_KEY(peerEvp); + if (!ecKey) + ThrowErr(Exc::Crypto::InternalError, "Can't get EC key"); + + auto ecPoint = EC_KEY_get0_public_key(ecKey); + if (!ecPoint) + ThrowErr(Exc::Crypto::InternalError, "Can't get EC public key"); + + auto ecGroup = EC_KEY_get0_group(ecKey); + if (!ecGroup) + ThrowErr(Exc::Crypto::InternalError, "Can't get EC group"); + + BIGNUM *x = BN_new(); + BIGNUM *y = BN_new(); + if (!EC_POINT_get_affine_coordinates(ecGroup, ecPoint, x, y, NULL)) + ThrowErr(Exc::Crypto::InternalError, "Failed to get EC pub key coordinates"); + + auto xBuf = extractBignumData(x); + auto yBuf = extractBignumData(y); + + RawBuffer secretPwdBuf(secretPwd.begin(), secretPwd.end()); + + int pubCurve = EC_GROUP_get_curve_name(ecGroup); + tz_ec tzCurve; + switch (pubCurve) + { + case NID_X9_62_prime192v1: + tzCurve = EC_NIST_P192; + break; + + case NID_X9_62_prime256v1: + tzCurve = EC_NIST_P256; + break; + + case NID_secp384r1: + tzCurve = EC_NIST_P384; + break; + + default: + ThrowErr(Exc::Crypto::InputParam, "Unsupported public key EC"); + } + + TrustZoneContext::Instance().executeEcdh(prvKeyId, + prvKeyPwd, + tzCurve, + xBuf, + yBuf, + secretPwdBuf, + secretPwdIV, + secretTag, + secretHash); +} + +void deriveKBKDF(const RawBuffer &secretId, + const Pwd &secretPwd, + const CryptoAlgorithm &alg, + const Password &keyPwd, + const RawBuffer &keyPwdIV, + RawBuffer &keyTag, + const RawBuffer &keyHash) +{ + RawBuffer label, context, fixed; + KbkdfCounterLocation counterLocation; + KdfPrf prf; + KbkdfMode mode; + size_t length, rlenBits = 32, llenBits = 32, tmp; + bool hasLabel = alg.getParam(ParamName::KBKDF_LABEL, label); + bool hasContext = alg.getParam(ParamName::KBKDF_CONTEXT, context); + bool hasFixed = alg.getParam(ParamName::KBKDF_FIXED_INPUT, fixed); + alg.getParam(ParamName::KBKDF_COUNTER_LOCATION, counterLocation); + alg.getParam(ParamName::KBKDF_MODE, mode); + alg.getParam(ParamName::KDF_PRF, prf); + alg.getParam(ParamName::KDF_LEN, length); + alg.getParam(ParamName::KBKDF_RLEN, rlenBits); + bool hasLLen = alg.getParam(ParamName::KBKDF_LLEN, llenBits); + bool noSeparator = alg.getParam(ParamName::KBKDF_NO_SEPARATOR, tmp); + + RawBuffer key; + if (hasFixed) { + if (hasLabel || hasContext || noSeparator || hasLLen || + counterLocation == KbkdfCounterLocation::MIDDLE_FIXED) + ThrowErr(Exc::Crypto::InputParam, "Unexpected parameters for fixed input mode."); + } else { + if (!hasLabel || !hasContext) + ThrowErr(Exc::Crypto::InputParam, "Missing label and/or context."); + + if (llenBits != 0 && llenBits != 8 && llenBits != 16 && llenBits != 24 && llenBits != 32) + ThrowErr(Exc::Crypto::InputParam, "Invalid llen value"); + } + if (length != 16 && length != 24 && length != 32) + ThrowErr(Exc::Crypto::InputParam, "Invalid key length"); + + if (rlenBits != 8 && rlenBits != 16 && rlenBits != 24 && rlenBits != 32) + ThrowErr(Exc::Crypto::InputParam, "Invalid rlen value"); + + RawBuffer keyPwdBuf(keyPwd.begin(), keyPwd.end()); + + TrustZoneContext::Instance().executeKbkdf(secretId, + secretPwd, + length, + label, + context, + fixed, + toTzPrf(prf), + toTzKbkdfMode(mode), + toTzCtrLoc(counterLocation), + rlenBits, + llenBits, + noSeparator, + keyPwdBuf, + keyPwdIV, + keyTag, + keyHash); +} + +size_t maxChunkSize() +{ + return TrustZoneContext::Instance().getMaxChunkSize(); +} + } // namespace Internals } // namespace TZ } // namespace Crypto