keyHash);
}
+void deriveHybridKBKDF(const RawBuffer &firstSecretId,
+ const Pwd &firstSecretPwd,
+ const RawBuffer &secondSecretId,
+ const Pwd &secondSecretPwd,
+ const CryptoAlgorithm &alg,
+ const Password &keyPwd,
+ const RawBuffer &keyPwdIV,
+ RawBuffer &keyTag,
+ const RawBuffer &keyHash)
+{
+ RawBuffer label, context, fixed;
+ size_t 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);
+ auto counterLocation = unpack<KbkdfCounterLocation>(alg, ParamName::KBKDF_COUNTER_LOCATION);
+ auto mode = unpack<KbkdfMode>(alg, ParamName::KBKDF_MODE);
+ auto prf = unpack<KdfPrf>(alg, ParamName::KDF_PRF);
+ auto length = unpack<size_t>(alg, ParamName::KDF_LEN);
+ alg.getParam(ParamName::KBKDF_RLEN, rlenBits);
+ bool hasLLen = alg.getParam(ParamName::KBKDF_LLEN, llenBits);
+ bool noSeparator = alg.getParam(ParamName::KBKDF_NO_SEPARATOR, tmp);
+
+ if (counterLocation != KbkdfCounterLocation::BEFORE_FIXED &&
+ counterLocation != KbkdfCounterLocation::MIDDLE_FIXED &&
+ counterLocation != KbkdfCounterLocation::AFTER_FIXED)
+ ThrowErr(Exc::Crypto::InputParam, "Invalid counter location");
+
+ if (mode != KbkdfMode::COUNTER)
+ ThrowErr(Exc::Crypto::InputParam, "Invalid mode");
+
+ if (prf != KdfPrf::HMAC_SHA256 && prf != KdfPrf::HMAC_SHA384 && prf != KdfPrf::HMAC_SHA512)
+ ThrowErr(Exc::Crypto::InputParam, "Invalid pseudo random function");
+
+ 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().executeHybridKbkdf(firstSecretId,
+ firstSecretPwd,
+ secondSecretId,
+ secondSecretPwd,
+ length,
+ label,
+ context,
+ fixed,
+ toTzPrf(prf),
+ toTzKbkdfMode(mode),
+ toTzCtrLoc(counterLocation),
+ rlenBits,
+ llenBits,
+ noSeparator,
+ keyPwdBuf,
+ keyPwdIV,
+ keyTag,
+ keyHash);
+}
+
size_t maxChunkSize()
{
return TrustZoneContext::Instance().getMaxChunkSize();
RawBuffer &keyTag,
const RawBuffer &keyHash);
+void deriveHybridKBKDF(const RawBuffer &firstSecretId,
+ const Pwd &firstSecretPwd,
+ const RawBuffer &secondSecretId,
+ const Pwd &secondSecretPwd,
+ const CryptoAlgorithm &alg,
+ const Password &keyPwd,
+ const RawBuffer &keyPwdIV,
+ RawBuffer &keyTag,
+ const RawBuffer &keyHash);
+
size_t maxChunkSize();
} // namespace Internals
} // namespace TZ
sharedSecretHash, sharedSecretPass, sharedSecretIV, sharedSecretTag));
}
+Token BData::deriveHybrid(const CryptoAlgorithm &alg,
+ const Token &,
+ const Password &,
+ const Token &secondKey,
+ const Password &secondPass,
+ const Password &newKeyPass,
+ const RawBuffer &hash)
+{
+ auto algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
+ if (algo != AlgoType::KBKDF)
+ ThrowErr(Exc::Crypto::InputParam, "Wrong algorithm");
+
+ RawBuffer newKeyIV;
+ RawBuffer newKeyTag;
+ if (!newKeyPass.empty()) {
+ // IV is needed for key encryption
+ newKeyIV = Internals::generateIV();
+ }
+
+ int secondKeyScheme;
+ RawBuffer secondKeyId;
+ RawBuffer secondKeyIV;
+ RawBuffer secondKeyTag;
+ Store::unpack(secondKey.data,
+ secondPass,
+ secondKeyScheme,
+ secondKeyId,
+ secondKeyIV,
+ secondKeyTag);
+
+ Internals::deriveHybridKBKDF(getId(),
+ getPassword(),
+ secondKeyId,
+ Pwd(secondPass, secondKeyIV, secondKeyTag),
+ alg,
+ newKeyPass,
+ newKeyIV,
+ newKeyTag,
+ hash);
+
+ return Token(backendId(), DataType(KeyType::KEY_AES), Store::pack(hash, newKeyPass, newKeyIV, newKeyTag));
+}
+
Token Key::unwrap(const CryptoAlgorithm ¶ms,
const Data &encryptedKey,
const Password &pass,
return Token(backendId(), DataType::BINARY_DATA, Store::pack(hash, pass, iv, tag));
}
+Token AKey::deriveHybrid(const CryptoAlgorithm &,
+ const Token &,
+ const Password &,
+ const Token &,
+ const Password &,
+ const Password &,
+ const RawBuffer &)
+{
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+}
+
GCtxShPtr AKey::initContext(const CryptoAlgorithm &, bool)
{
ThrowErr(Exc::Crypto::OperationNotSupported);
return m_password;
}
Token derive(const CryptoAlgorithm &, const Password &, const RawBuffer &) override;
+ Token deriveHybrid(const CryptoAlgorithm &alg,
+ const Token &firstKey,
+ const Password &firstPass,
+ const Token &secondKey,
+ const Password &secondPass,
+ const Password &newKeyPass,
+ const RawBuffer &hash) override;
std::tuple<Token, RawBuffer> encapsulateKey(const CryptoAlgorithm ¶ms,
const Token &pubKey,
RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &) override;
RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &) override;
Token derive(const CryptoAlgorithm &, const Password &, const RawBuffer &) override;
+ Token deriveHybrid(const CryptoAlgorithm &,
+ const Token &,
+ const Password &,
+ const Token &,
+ const Password &,
+ const Password &,
+ const RawBuffer &) override;
GCtxShPtr initContext(const CryptoAlgorithm &, bool) override;
RawBuffer wrapConcatenated(const CryptoAlgorithm ¶ms,
LogDebug("Derived object ID is (hex): " << rawToHexString(keyHash));
}
+void TrustZoneContext::executeHybridKbkdf(const RawBuffer& firstSecretId,
+ const Pwd& firstSecretPwd,
+ const RawBuffer& secondSecretId,
+ const Pwd& secondSecretPwd,
+ size_t length,
+ const RawBuffer& label,
+ const RawBuffer& context,
+ const RawBuffer& fixed,
+ tz_prf prf,
+ tz_kbkdf_mode mode,
+ tz_kbkdf_ctr_loc location,
+ size_t rlen,
+ size_t llen,
+ bool noSeparator,
+ const RawBuffer &keyPwdBuf,
+ const RawBuffer &keyPwdIV,
+ RawBuffer &keyTag,
+ const RawBuffer &keyHash)
+{
+ // command ID = CMD_DERIVE_HYBRID
+ LogDebug("TrustZoneContext::executeHybridKbkdf");
+
+ auto sIn = makeSerializer(firstSecretId,
+ firstSecretPwd,
+ secondSecretId,
+ secondSecretPwd,
+ length,
+ label,
+ context,
+ fixed,
+ prf,
+ mode,
+ location,
+ rlen,
+ llen,
+ noSeparator,
+ EncPwd{keyPwdBuf, keyPwdIV}, keyHash);
+
+ TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+ sIn.Serialize(inMemory);
+
+ TZSerializer sOut;
+ if (!keyPwdBuf.empty()) {
+ sOut.Push(new TZSerializableBinary(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES));
+ }
+
+ TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
+
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
+ if (!keyPwdBuf.empty())
+ op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+ op.params[0].value.a = ALGO_KBKDF_DRV;
+
+ Execute(CMD_DERIVE_HYBRID, &op);
+
+ if (!keyPwdBuf.empty()) {
+ sOut.Deserialize(outMemory);
+ sOut.Pull(keyTag);
+ }
+
+ LogDebug("Derived object ID is (hex): " << rawToHexString(keyHash));
+}
+
uint32_t TrustZoneContext::getMaxChunkSize()
{
// command ID = CMD_GET_MAX_CHUNK_SIZE
RawBuffer &keyTag,
const RawBuffer &keyHash);
+ void executeHybridKbkdf(const RawBuffer& firstSecretId,
+ const Pwd& firstSecretPwd,
+ const RawBuffer& secondSecretId,
+ const Pwd& secondSecretPwd,
+ size_t length,
+ const RawBuffer& label,
+ const RawBuffer& context,
+ const RawBuffer& fixed,
+ tz_prf prf,
+ tz_kbkdf_mode mode,
+ tz_kbkdf_ctr_loc location,
+ size_t rlen,
+ size_t llen,
+ bool noSeparator,
+ const RawBuffer &keyPwdBuf,
+ const RawBuffer &keyPwdIV,
+ RawBuffer &keyTag,
+ const RawBuffer &keyHash);
+
uint32_t getMaxChunkSize();
private: