2 * Copyright (c) 2017-2020 Samsung Electronics Co., Ltd. All rights reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
18 * @author Krzysztof Dynowski (k.dynowski@samsung.com)
19 * @author Lukasz Kostyra (l.kostyra@samsung.com)
23 #include <generic-backend/exception.h>
24 #include <generic-backend/algo-validation.h>
25 #include <generic-backend/crypto-params.h>
26 #include <dpl/log/log.h>
28 #include <openssl/evp.h>
29 #include <openssl/dsa.h>
30 #include <openssl/ec.h>
31 #include <openssl/bio.h>
32 #include <openssl/bn.h>
34 #include <tz-backend/internals.h>
35 #include <tz-backend/tz-context.h>
36 #include <openssl-error-handler.h>
37 #include <km_ta_defines.h>
42 #ifndef __has_cpp_attribute
43 #define __has_cpp_attribute(_) 0
46 #if __has_cpp_attribute(fallthrough)
47 #define fallthru [[fallthrough]]
49 #define fallthru ((void)0)
54 CKM::RawBuffer extractBignumData(const BIGNUM* bn)
56 size_t size = static_cast<size_t>(BN_num_bytes(bn));
58 CKM::RawBuffer result(size);
59 int ret = BN_bn2bin(bn, result.data());
60 if (ret != static_cast<int>(size)) {
61 ThrowErr(CKM::Exc::Crypto::InternalError,
62 "Error while converting bignums - expected "
63 + std::to_string(size) + " bytes of data, got " + std::to_string(ret));
69 void generateDSAParams(const int sizeBits, CKM::RawBuffer &prime,
70 CKM::RawBuffer &subprime, CKM::RawBuffer &base)
72 auto dsa = uptr<DSA_free>(DSA_new());
74 ThrowErr(CKM::Exc::Crypto::InternalError,
75 "Failed to create DSA context for parameter gen");
78 if (DSA_generate_parameters_ex(dsa.get(), sizeBits, NULL, 0, NULL, NULL, NULL) == 0) {
79 ThrowErr(CKM::Exc::Crypto::InternalError,
80 "Failed to generate DSA params, err = " + std::to_string(ERR_get_error()));
83 // at this stage dsa->p, dsa->q & dsa->r should contain our params
84 // extract them into buffers
85 const BIGNUM *p, *q, *g;
86 DSA_get0_pqg(dsa.get(), &p, &q, &g);
87 prime = extractBignumData(p);
88 subprime = extractBignumData(q);
89 base = extractBignumData(g);
92 tz_data_type toTzDataType(const CKM::DataType dataType) {
94 case CKM::DataType::BINARY_DATA: return TYPE_GENERIC_SECRET;
95 case CKM::DataType::KEY_AES: return TYPE_SKEY;
96 case CKM::DataType::KEY_DSA_PRIVATE: return TYPE_AKEY_PRIVATE_DSA;
97 case CKM::DataType::KEY_RSA_PRIVATE: return TYPE_AKEY_PRIVATE_RSA;
98 case CKM::DataType::KEY_ECDSA_PRIVATE: return TYPE_AKEY_PRIVATE_EC;
99 case CKM::DataType::KEY_DSA_PUBLIC: return TYPE_AKEY_PUBLIC_DSA;
100 case CKM::DataType::KEY_RSA_PUBLIC: return TYPE_AKEY_PUBLIC_RSA;
101 case CKM::DataType::KEY_ECDSA_PUBLIC: return TYPE_AKEY_PUBLIC_EC;
103 ThrowErr(CKM::Exc::Crypto::DataTypeNotSupported,
104 "Data type could not be imported by tz-backend");
108 tz_ec toTzEc(CKM::ElipticCurve ec)
111 case CKM::ElipticCurve::prime192v1: return EC_NIST_P192;
112 case CKM::ElipticCurve::prime256v1: return EC_NIST_P256;
113 case CKM::ElipticCurve::secp384r1: return EC_NIST_P384;
114 default: ThrowErr(CKM::Exc::Crypto::DataTypeNotSupported, "EC not supported by tz-backend");
118 tz_prf toTzPrf(CKM::KdfPrf prf)
121 case CKM::KdfPrf::HMAC_SHA256: return PRF_HMAC_SHA256;
122 case CKM::KdfPrf::HMAC_SHA384: return PRF_HMAC_SHA384;
123 case CKM::KdfPrf::HMAC_SHA512: return PRF_HMAC_SHA512;
124 default: ThrowErr(CKM::Exc::Crypto::DataTypeNotSupported, "PRF not supported by tz-backend");
128 tz_kbkdf_mode toTzKbkdfMode(CKM::KbkdfMode mode)
131 case CKM::KbkdfMode::COUNTER: return KBKDF_MODE_COUNTER;
133 ThrowErr(CKM::Exc::Crypto::DataTypeNotSupported, "KBKDF mode not supported by tz-backend");
137 tz_kbkdf_ctr_loc toTzCtrLoc(CKM::KbkdfCounterLocation loc)
140 case CKM::KbkdfCounterLocation::BEFORE_FIXED: return KBKDF_LOC_BEFORE_FIXED;
141 case CKM::KbkdfCounterLocation::AFTER_FIXED: return KBKDF_LOC_AFTER_FIXED;
142 case CKM::KbkdfCounterLocation::MIDDLE_FIXED: return KBKDF_LOC_MIDDLE_FIXED;
144 ThrowErr(CKM::Exc::Crypto::DataTypeNotSupported,
145 "KBKDF counter location not supported by tz-backend");
154 namespace Internals {
158 tz_algo_type getGenSKeyType(AlgoType type)
162 case AlgoType::AES_GEN: return ALGO_AES_GEN;
163 default: ThrowErr(Exc::Crypto::OperationNotSupported, "Requested algorithm is not supported");
167 tz_algo_type getAlgType(AlgoType type)
171 case AlgoType::AES_CBC: return ALGO_AES_CBC;
172 case AlgoType::AES_CTR: return ALGO_AES_CTR;
173 case AlgoType::AES_CFB: return ALGO_AES_CFB;
174 case AlgoType::AES_GCM: return ALGO_AES_GCM;
175 case AlgoType::RSA_OAEP: return ALGO_RSA;
176 case AlgoType::RSA_SV: return ALGO_RSA_SV;
177 case AlgoType::DSA_SV: return ALGO_DSA_SV;
178 case AlgoType::ECDSA_SV: return ALGO_ECDSA_SV;
179 default: ThrowErr(Exc::Crypto::OperationNotSupported, "Requested algorithm is not supported");
183 tz_hash_type getHashType(HashAlgorithm hash)
187 case HashAlgorithm::SHA1: return HASH_SHA1;
188 case HashAlgorithm::SHA256: return HASH_SHA256;
189 case HashAlgorithm::SHA384: return HASH_SHA384;
190 case HashAlgorithm::SHA512: return HASH_SHA512;
192 ThrowErr(Exc::Crypto::OperationNotSupported, "Requested algorithm is not supported");
196 void decompose(const CryptoAlgorithm &alg,
198 uint32_t &ctrLenOrTagSizeBits,
202 algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
204 case AlgoType::AES_CTR:
205 iv = unpack<RawBuffer>(alg, ParamName::ED_IV);
206 ctrLenOrTagSizeBits = Params::DEFAULT_AES_IV_LEN * 8;
207 alg.getParam(ParamName::ED_CTR_LEN, ctrLenOrTagSizeBits);
208 // counter length is in bits
209 if (ctrLenOrTagSizeBits != Params::DEFAULT_AES_IV_LEN * 8) {
210 LogError("CTR length invalid: " << std::to_string(ctrLenOrTagSizeBits));
211 ThrowErr(Exc::Crypto::InputParam, "Invalid CTR length");
214 case AlgoType::AES_CBC:
215 iv = unpack<RawBuffer>(alg, ParamName::ED_IV);
217 case AlgoType::AES_CFB:
218 iv = unpack<RawBuffer>(alg, ParamName::ED_IV);
220 case AlgoType::AES_GCM:
221 iv = unpack<RawBuffer>(alg, ParamName::ED_IV);
222 ctrLenOrTagSizeBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS;
223 alg.getParam(ParamName::ED_TAG_LEN, ctrLenOrTagSizeBits);
224 alg.getParam(ParamName::ED_AAD, aad);
226 case AlgoType::RSA_OAEP:
229 ThrowErr(Exc::Crypto::InputParam, "Invalid decryption algorithm");
236 RawBuffer generateIV()
239 TrustZoneContext::Instance().generateIV(result);
243 void generateSKey(const CryptoAlgorithm &alg,
247 const RawBuffer &hash)
249 AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
250 int keyBits = unpack<int>(alg, ParamName::GEN_KEY_LEN);
254 ThrowErr(Exc::InputParam, "Key generation with password encryption requires an IV");
257 RawBuffer pwdBuf(pwd.begin(), pwd.end());
258 TrustZoneContext::Instance().generateSKeyPwd(getGenSKeyType(keyType),
262 TrustZoneContext::Instance().generateSKey(getGenSKeyType(keyType), keyBits,
268 AlgoType generateAKey(const CryptoAlgorithm &alg,
269 const Password &pubPwd,
270 const Password &privPwd,
271 const RawBuffer &pubPwdIv,
272 const RawBuffer &privPwdIv,
275 const RawBuffer &hashPriv,
276 const RawBuffer &hashPub)
278 AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
282 pubPwdBuf.assign(pubPwd.begin(), pubPwd.end());
284 RawBuffer privPwdBuf;
285 if (!privPwd.empty())
286 privPwdBuf.assign(privPwd.begin(), privPwd.end());
289 case AlgoType::RSA_GEN: {
290 int keyBits = unpack<int>(alg, ParamName::GEN_KEY_LEN);
291 TrustZoneContext::Instance().generateRSAKey(keyBits,
302 case AlgoType::DSA_GEN: {
303 int keyBits = unpack<int>(alg, ParamName::GEN_KEY_LEN);
307 generateDSAParams(keyBits, prime, subprime, base);
308 TrustZoneContext::Instance().generateDSAKey(keyBits,
322 case AlgoType::ECDSA_GEN: {
323 CKM::ElipticCurve ec = unpack<CKM::ElipticCurve>(alg, ParamName::GEN_EC);
324 TrustZoneContext::Instance().generateECKey(toTzEc(ec),
336 ThrowErr(Exc::Crypto::InputParam,
337 "Invalid algo type provided for generateAKey function");
344 void destroyKey(const RawBuffer &keyId)
346 TrustZoneContext::Instance().executeDestroy(keyId);
349 void importData(const Data &data,
350 const EncryptionParams &encData,
352 const RawBuffer &pwdIV,
354 const RawBuffer &hash)
357 const auto dataType = toTzDataType(data.type);
359 RawBuffer pwdBuf(pwd.begin(), pwd.end());
360 uint32_t keySizeBits = data.data.size() * 8;
361 TrustZoneContext::Instance().importData(dataType,
371 void importWrappedKey(const RawBuffer &wrappingKeyId,
372 const Pwd &wrappingKeyPwd,
373 const CryptoAlgorithm &alg,
374 const Data &encryptedKey,
375 const Password &encryptedKeyPassword,
376 const RawBuffer &encryptedKeyIV,
377 RawBuffer &encryptedKeyTag,
378 const RawBuffer &encryptedKeyId)
380 RawBuffer encryptedKeyPwdBuf(encryptedKeyPassword.begin(), encryptedKeyPassword.end());
383 uint32_t ctrLenOrTagSizeBits = 0;
386 decompose(alg, algo, ctrLenOrTagSizeBits, iv, aad);
389 TrustZoneContext::Instance().importWrappedKey(wrappingKeyId,
395 toTzDataType(encryptedKey.type),
403 RawBuffer exportWrappedKey(const RawBuffer &wrappingKeyId,
404 const Pwd &wrappingKeyPwd,
405 const CryptoAlgorithm &alg,
406 const RawBuffer &keyToWrapId,
407 const Pwd &keyToWrapPwd,
408 const DataType &keyToWrapType)
411 uint32_t ctrLenOrTagSizeBits = 0;
414 decompose(alg, algo, ctrLenOrTagSizeBits, iv, aad);
417 return TrustZoneContext::Instance().exportWrappedKey(wrappingKeyId,
425 toTzDataType(keyToWrapType));
428 RawBuffer getData(const RawBuffer &dataId,
430 const DataType &type)
433 TrustZoneContext::Instance().getData(dataId,
440 void destroyData(const RawBuffer &dataId)
442 TrustZoneContext::Instance().destroyData(dataId);
445 BufferPair encryptDataAesGcm(const RawBuffer &keyId,
449 const RawBuffer &data,
450 const RawBuffer &aad)
455 TrustZoneContext::Instance().executeEncryptAE(keyId, pwd, iv, tagSize,
456 aad, data, result, tag);
458 return std::make_pair(result, tag);
461 RawBuffer encryptDataAesGcmPacked(const RawBuffer &keyId,
465 const RawBuffer &data,
466 const RawBuffer &aad)
468 auto pair = encryptDataAesGcm(keyId, pwd, iv, tagSize, data, aad);
469 std::copy(pair.second.begin(), pair.second.end(),
470 std::back_inserter(pair.first));
474 RawBuffer decryptDataAesGcm(const RawBuffer &keyId,
478 const RawBuffer &tag,
479 const RawBuffer &data,
480 const RawBuffer &aad)
484 TrustZoneContext::Instance().executeDecryptAE(keyId, pwd, iv, tagSizeBits,
485 tag, aad, data, result);
490 RawBuffer decryptDataAesGcmPacked(const RawBuffer &keyId,
494 const RawBuffer &data,
495 const RawBuffer &aad)
497 int tagSizeBytes = tagSizeBits / 8;
498 if (tagSizeBytes > static_cast<int>(data.size()))
499 ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag");
501 auto tagPos = data.data() + data.size() - tagSizeBytes;
502 return decryptDataAesGcm(keyId,
506 RawBuffer(tagPos, data.data() + data.size()),
507 RawBuffer(data.data(), tagPos),
512 RawBuffer symmetricEncrypt(const RawBuffer &keyId,
514 const CryptoAlgorithm &alg,
515 const RawBuffer &data)
517 AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
518 uint64_t ctrLen = Params::DEFAULT_AES_IV_LEN * 8;
521 case AlgoType::AES_CTR: {
522 alg.getParam(ParamName::ED_CTR_LEN, ctrLen);
523 // counter length is in bits
524 if (ctrLen != Params::DEFAULT_AES_IV_LEN * 8) {
525 LogError("CTR length invalid: " << std::to_string(ctrLen));
526 ThrowErr(Exc::Crypto::InputParam, "Invalid CTR length");
528 // no break here, we still need to slide down to executeCrypt
531 case AlgoType::AES_CBC:
532 case AlgoType::AES_CFB: {
534 TrustZoneContext::Instance().executeCrypt(CMD_ENCRYPT,
538 unpack<RawBuffer>(alg, ParamName::ED_IV),
543 case AlgoType::AES_GCM: {
544 int tagLenBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS;
545 alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
547 alg.getParam(ParamName::ED_AAD, aad);
548 return encryptDataAesGcmPacked(keyId,
550 unpack<RawBuffer>(alg, ParamName::ED_IV),
559 ThrowErr(Exc::Crypto::OperationNotSupported,
560 "Incorrect algorithm provided for symmetric crypto operation");
563 RawBuffer symmetricDecrypt(const RawBuffer &keyId,
565 const CryptoAlgorithm &alg,
566 const RawBuffer &data)
568 AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
569 uint64_t ctrLen = Params::DEFAULT_AES_IV_LEN * 8;
572 case AlgoType::AES_CTR: {
573 alg.getParam(ParamName::ED_CTR_LEN, ctrLen);
574 // counter length is in bits
575 if (ctrLen != Params::DEFAULT_AES_IV_LEN * 8) {
576 LogError("CTR length invalid: " << std::to_string(ctrLen));
577 ThrowErr(Exc::Crypto::InputParam, "Invalid CTR length");
579 // no break here, we still need to slide down to executeCrypt
582 case AlgoType::AES_CBC:
583 case AlgoType::AES_CFB: {
585 TrustZoneContext::Instance().executeCrypt(CMD_DECRYPT,
589 unpack<RawBuffer>(alg, ParamName::ED_IV),
594 case AlgoType::AES_GCM: {
595 int tagSizeBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS;
596 alg.getParam(ParamName::ED_TAG_LEN, tagSizeBits);
598 alg.getParam(ParamName::ED_AAD, aad);
599 return decryptDataAesGcmPacked(keyId,
601 unpack<RawBuffer>(alg, ParamName::ED_IV),
610 ThrowErr(Exc::Crypto::OperationNotSupported,
611 "Incorrect algorithm provided for symmetric crypto operation");
614 RawBuffer asymmetricEncrypt(const RawBuffer &keyId,
616 const CryptoAlgorithm &alg,
617 const RawBuffer &data)
619 AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
624 case AlgoType::RSA_OAEP: {
625 TrustZoneContext::Instance().executeCrypt(CMD_ENCRYPT,
629 result, // unused dummy
638 ThrowErr(Exc::Crypto::OperationNotSupported,
639 "Incorrect algorithm provided for asymmetric crypto operation");
642 RawBuffer asymmetricDecrypt(const RawBuffer &keyId,
644 const CryptoAlgorithm &alg,
645 const RawBuffer &cipher)
647 AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
652 case AlgoType::RSA_OAEP: {
653 TrustZoneContext::Instance().executeCrypt(CMD_DECRYPT,
657 result, // unused dummy
666 ThrowErr(Exc::Crypto::OperationNotSupported,
667 "Incorrect algorithm provided for asymmetric crypto operation");
670 uint32_t initCipher(const RawBuffer &keyId,
672 const CryptoAlgorithm &alg,
675 AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
679 case AlgoType::AES_GCM: {
680 int tagSizeBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS;
681 alg.getParam(ParamName::ED_TAG_LEN, tagSizeBits);
683 alg.getParam(ParamName::ED_AAD, aad);
684 return TrustZoneContext::Instance().initGcmCipher(encrypt ? CIPHER_ENCRYPT : CIPHER_DECRYPT,
687 unpack<RawBuffer>(alg, ParamName::ED_IV),
691 case AlgoType::AES_CBC:
692 case AlgoType::AES_CTR:
693 case AlgoType::AES_CFB:
694 // TODO optionally implement above modes as well
699 ThrowErr(Exc::Crypto::OperationNotSupported,
700 "Incorrect algorithm provided for symmetric crypto operation");
703 void addAAD(uint32_t opId,
704 const RawBuffer &aad)
706 TrustZoneContext::Instance().addGcmAAD(opId, aad);
709 RawBuffer updateCipher(uint32_t opId,
710 const RawBuffer &data)
712 return TrustZoneContext::Instance().updateGcmCipher(opId, data);
715 RawBuffer finalizeCipher(uint32_t opId,
716 const RawBuffer &data)
718 return TrustZoneContext::Instance().finalizeGcmCipher(opId, data);
721 void cleanupCipher(uint32_t opId)
723 return TrustZoneContext::Instance().cleanupCipher(opId);
726 RawBuffer sign(const RawBuffer &pkeyId,
728 const CryptoAlgorithm &alg,
729 const RawBuffer &message)
731 AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
732 HashAlgorithm hash = unpack<HashAlgorithm>(alg, ParamName::SV_HASH_ALGO);
733 if (algo != AlgoType::RSA_SV && hash == HashAlgorithm::NONE)
734 ThrowErr(Exc::Crypto::InputParam, "Only RSA supports no hash option");
737 TrustZoneContext::Instance().executeSign(getAlgType(algo),
746 int verify(const RawBuffer &pkeyId,
748 const CryptoAlgorithm &alg,
749 const RawBuffer &message,
750 const RawBuffer &signature)
752 AlgoType algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
753 HashAlgorithm hash = unpack<HashAlgorithm>(alg, ParamName::SV_HASH_ALGO);
754 if (algo != AlgoType::RSA_SV && hash == HashAlgorithm::NONE)
755 ThrowErr(Exc::Crypto::InputParam, "Only RSA supports no hash option");
757 return TrustZoneContext::Instance().executeVerify(getAlgType(algo),
765 void deriveECDH(const RawBuffer &prvKeyId,
766 const Pwd &prvKeyPwd,
767 const RawBuffer &pubKey,
768 const Password &secretPwd,
769 const RawBuffer &secretPwdIV,
770 RawBuffer &secretTag,
771 const RawBuffer &secretHash)
773 auto peerKey = std::make_shared<KeyImpl>(pubKey);
774 if (peerKey->getType() != KeyType::KEY_ECDSA_PUBLIC)
775 ThrowErr(Exc::Crypto::InputParam, "ECDH requires peer's public EC key");
776 auto peerEvp = peerKey->getEvpShPtr().get();
779 int subType = EVP_PKEY_type(EVP_PKEY_id(peerEvp));
780 if (subType != EVP_PKEY_EC)
781 ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", subType);
783 auto ecKey = EVP_PKEY_get0_EC_KEY(peerEvp);
785 ThrowErr(Exc::Crypto::InternalError, "Can't get EC key");
787 auto ecPoint = EC_KEY_get0_public_key(ecKey);
789 ThrowErr(Exc::Crypto::InternalError, "Can't get EC public key");
791 auto ecGroup = EC_KEY_get0_group(ecKey);
793 ThrowErr(Exc::Crypto::InternalError, "Can't get EC group");
795 BIGNUM *x = BN_new();
796 BIGNUM *y = BN_new();
797 if (!EC_POINT_get_affine_coordinates(ecGroup, ecPoint, x, y, NULL))
798 ThrowErr(Exc::Crypto::InternalError, "Failed to get EC pub key coordinates");
800 auto xBuf = extractBignumData(x);
801 auto yBuf = extractBignumData(y);
803 RawBuffer secretPwdBuf(secretPwd.begin(), secretPwd.end());
805 int pubCurve = EC_GROUP_get_curve_name(ecGroup);
809 case NID_X9_62_prime192v1:
810 tzCurve = EC_NIST_P192;
813 case NID_X9_62_prime256v1:
814 tzCurve = EC_NIST_P256;
818 tzCurve = EC_NIST_P384;
822 ThrowErr(Exc::Crypto::InputParam, "Unsupported public key EC");
825 TrustZoneContext::Instance().executeEcdh(prvKeyId,
836 void deriveKBKDF(const RawBuffer &secretId,
837 const Pwd &secretPwd,
838 const CryptoAlgorithm &alg,
839 const Password &keyPwd,
840 const RawBuffer &keyPwdIV,
842 const RawBuffer &keyHash)
844 RawBuffer label, context, fixed;
845 KbkdfCounterLocation counterLocation;
848 size_t length, rlenBits = 32, llenBits = 32, tmp;
849 bool hasLabel = alg.getParam(ParamName::KBKDF_LABEL, label);
850 bool hasContext = alg.getParam(ParamName::KBKDF_CONTEXT, context);
851 bool hasFixed = alg.getParam(ParamName::KBKDF_FIXED_INPUT, fixed);
852 alg.getParam(ParamName::KBKDF_COUNTER_LOCATION, counterLocation);
853 alg.getParam(ParamName::KBKDF_MODE, mode);
854 alg.getParam(ParamName::KDF_PRF, prf);
855 alg.getParam(ParamName::KDF_LEN, length);
856 alg.getParam(ParamName::KBKDF_RLEN, rlenBits);
857 bool hasLLen = alg.getParam(ParamName::KBKDF_LLEN, llenBits);
858 bool noSeparator = alg.getParam(ParamName::KBKDF_NO_SEPARATOR, tmp);
862 if (hasLabel || hasContext || noSeparator || hasLLen ||
863 counterLocation == KbkdfCounterLocation::MIDDLE_FIXED)
864 ThrowErr(Exc::Crypto::InputParam, "Unexpected parameters for fixed input mode.");
866 if (!hasLabel || !hasContext)
867 ThrowErr(Exc::Crypto::InputParam, "Missing label and/or context.");
869 if (llenBits != 0 && llenBits != 8 && llenBits != 16 && llenBits != 24 && llenBits != 32)
870 ThrowErr(Exc::Crypto::InputParam, "Invalid llen value");
872 if (length != 16 && length != 24 && length != 32)
873 ThrowErr(Exc::Crypto::InputParam, "Invalid key length");
875 if (rlenBits != 8 && rlenBits != 16 && rlenBits != 24 && rlenBits != 32)
876 ThrowErr(Exc::Crypto::InputParam, "Invalid rlen value");
878 RawBuffer keyPwdBuf(keyPwd.begin(), keyPwd.end());
880 TrustZoneContext::Instance().executeKbkdf(secretId,
888 toTzCtrLoc(counterLocation),
898 size_t maxChunkSize()
900 return TrustZoneContext::Instance().getMaxChunkSize();
903 } // namespace Internals
905 } // namespace Crypto