Fix secret pwd passing in TZ backend KBKDF
[platform/core/security/key-manager.git] / src / manager / crypto / tz-backend / tz-context.cpp
index 672573f..ad09c65 100644 (file)
@@ -50,6 +50,9 @@ namespace {
 // whatever TA will return us.
 const uint32_t CIPHER_EXTRA_PADDING_SIZE = 16;
 
+// Maximum size of GCM tag in bytes.
+const size_t MAX_GCM_TAG_SIZE = 16;
+
 // Identifier of our TA
 const TEEC_UUID KEY_MANAGER_TA_UUID = KM_TA_UUID;
 
@@ -66,7 +69,8 @@ static std::string rawToHexString(const RawBuffer &raw)
 const std::unordered_map<tz_algo_type, size_t> MAX_KEY_SIZE = {
        { ALGO_RSA, 4096 / 8 },
        { ALGO_RSA_SV, 4096 / 8 },
-       { ALGO_DSA_SV, 4096 / 8 }
+       { ALGO_DSA_SV, 4096 / 8 },
+       { ALGO_ECDSA_SV, 1024 / 8 } // 384*2 + additional space for DERR encoding
 };
 
 struct EncPwd {
@@ -235,7 +239,7 @@ void TrustZoneContext::generateSKeyPwd(tz_algo_type algo,
 
 void TrustZoneContext::GenerateAKey(tz_command commandId,
                                     TZSerializer &sIn,
-                                    uint32_t keySizeBits,
+                                    uint32_t genParam, // key size in bits or EC type
                                     const RawBuffer &pubPwd,
                                     const RawBuffer &pubPwdIv,
                                     const RawBuffer &privPwd,
@@ -267,7 +271,7 @@ void TrustZoneContext::GenerateAKey(tz_command commandId,
        TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
 
        TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
-       op.params[0].value.b = keySizeBits;
+       op.params[0].value.b = genParam;
 
        Execute(commandId, &op);
 
@@ -336,6 +340,32 @@ void TrustZoneContext::generateDSAKey(uint32_t keySizeBits,
                     hashPub);
 }
 
+void TrustZoneContext::generateECKey(tz_ec ec,
+                                                                        const RawBuffer &pubPwd,
+                                                                        const RawBuffer &pubPwdIv,
+                                                                        const RawBuffer &privPwd,
+                                                                        const RawBuffer &privPwdIv,
+                                                                        RawBuffer &pubKeyTag,
+                                                                        RawBuffer &privKeyTag,
+                                                                        const RawBuffer &hashPriv,
+                                                                        const RawBuffer &hashPub)
+{
+       // command ID = CMD_GENERATE_EC_KEYPAIR
+       TZSerializer sIn;
+
+       GenerateAKey(CMD_GENERATE_EC_KEYPAIR,
+                    sIn,
+                    static_cast<uint32_t>(ec),
+                    pubPwd,
+                    pubPwdIv,
+                    privPwd,
+                    privPwdIv,
+                    pubKeyTag,
+                    privKeyTag,
+                    hashPriv,
+                    hashPub);
+}
+
 void TrustZoneContext::executeCrypt(tz_command cmd,
                                                                        tz_algo_type algo,
                                                                        const RawBuffer &keyId,
@@ -450,6 +480,91 @@ void TrustZoneContext::executeDecryptAE(const RawBuffer &keyId,
        sOut.Pull(out);
 }
 
+uint32_t TrustZoneContext::initGcmCipher(uint32_t encrypt,
+                                                                                const RawBuffer &keyId,
+                                                                                const Pwd &pwd,
+                                                                                const RawBuffer &iv,
+                                                                                int tagSizeBits,
+                                                                                const RawBuffer &aad)
+{
+       // command ID = CMD_CIPHER_INIT (from km_ta_defines.h)
+       if (keyId.size() != KM_KEY_ID_SIZE) {
+               ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
+       }
+
+       auto sIn = makeSerializer(pwd, iv, keyId, aad, tagSizeBits);
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
+
+       TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
+       op.params[0].value.a = ALGO_AES_GCM;
+       op.params[0].value.b = encrypt;
+
+       Execute(CMD_CIPHER_INIT, &op);
+
+       return op.params[0].value.b;
+}
+
+void TrustZoneContext::addGcmAAD(uint32_t opId,
+                                                                const RawBuffer &aad)
+{
+       // command ID = CMD_CIPHER_INIT_AAD (from km_ta_defines.h)
+       auto sIn = makeSerializer(aad);
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
+
+       TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
+       op.params[0].value.a = opId;
+
+       Execute(CMD_CIPHER_INIT_AAD, &op);
+}
+
+RawBuffer TrustZoneContext::updateGcmCipher(uint32_t opId,
+                                                                                       const RawBuffer &data)
+{
+       auto sIn = makeSerializer(data);
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
+
+       TZSerializer sOut;
+       sOut.Push(new TZSerializableBinary(data.size()));
+       TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
+
+       TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+       op.params[0].value.a = opId;
+
+       Execute(CMD_CIPHER_UPDATE, &op);
+
+       sOut.Deserialize(outMemory);
+
+       RawBuffer out;
+       sOut.Pull(out);
+       return out;
+}
+
+RawBuffer TrustZoneContext::finalizeGcmCipher(uint32_t opId,
+                                                                                         const RawBuffer &data)
+{
+       auto sIn = makeSerializer(data);
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
+
+       TZSerializer sOut;
+       sOut.Push(new TZSerializableBinary(MAX_GCM_TAG_SIZE, false));
+       TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
+
+       TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+       op.params[0].value.a = opId;
+
+       Execute(CMD_CIPHER_FINALIZE, &op);
+
+       sOut.Deserialize(outMemory);
+
+       RawBuffer out;
+       sOut.Pull(out);
+       return out;
+}
+
 void TrustZoneContext::executeSign(tz_algo_type algo,
                                                                tz_hash_type hash,
                                                                const RawBuffer &keyId,
@@ -573,6 +688,104 @@ void TrustZoneContext::importData(
        LogDebug("Imported object ID is (hex): " << rawToHexString(hash));
 }
 
+void TrustZoneContext::importWrappedKey(const RawBuffer &wrappingKeyId,
+                                                                               const Pwd &wrappingKeyPwd,
+                                                                               tz_algo_type algo,
+                                                                               const RawBuffer &iv,
+                                                                               const uint32_t ctrLenOrTagSizeBits,
+                                                                               const RawBuffer &aad,
+                                                                               const tz_data_type encryptedKeyType,
+                                                                               const RawBuffer &encryptedKey,
+                                                                               const RawBuffer &encryptedKeyPwdBuf,
+                                                                               const RawBuffer &encryptedKeyIV,
+                                                                               RawBuffer &encryptedKeyTag,
+                                                                               const RawBuffer &encryptedKeyId)
+{
+       // command ID = CMD_IMPORT_WRAPPED_KEY
+       LogDebug("TrustZoneContext::importWrappedKey encryptedKey size = [" << encryptedKey.size() << "]");
+
+       auto sIn = makeSerializer(wrappingKeyId,
+                                                         wrappingKeyPwd,
+                                                         algo,
+                                                         iv,
+                                                         ctrLenOrTagSizeBits,
+                                                         aad,
+                                                         encryptedKeyType,
+                                                         encryptedKey,
+                                                         EncPwd{encryptedKeyPwdBuf, encryptedKeyIV},
+                                                         encryptedKeyId);
+
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
+
+       TZSerializer sOut;
+       if (!encryptedKeyPwdBuf.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 (!encryptedKeyPwdBuf.empty())
+               op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+
+       Execute(CMD_IMPORT_WRAPPED_KEY, &op);
+
+       if (!encryptedKeyPwdBuf.empty()) {
+               sOut.Deserialize(outMemory);
+               sOut.Pull(encryptedKeyTag);
+       }
+
+       LogDebug("Imported object ID is (hex): " << rawToHexString(encryptedKeyId));
+}
+
+RawBuffer TrustZoneContext::exportWrappedKey(const RawBuffer &wrappingKeyId,
+                                                                                        const Pwd &wrappingKeyPwd,
+                                                                                        tz_algo_type algo,
+                                                                                        const RawBuffer &iv,
+                                                                                        const uint32_t ctrLenOrTagSizeBits,
+                                                                                        const RawBuffer &aad,
+                                                                                        const RawBuffer &keyToWrapId,
+                                                                                        const Pwd &keyToWrapPwd)
+{
+       // command ID = CMD_EXPORT_WRAPPED_KEY
+       LogDebug("TrustZoneContext::exportWrappedKey");
+
+       auto sIn = makeSerializer(wrappingKeyId,
+                                                         wrappingKeyPwd,
+                                                         algo,
+                                                         iv,
+                                                         ctrLenOrTagSizeBits,
+                                                         aad,
+                                                         keyToWrapId,
+                                                         keyToWrapPwd);
+
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
+
+       uint32_t data_size = 0;
+       GetDataSize(keyToWrapId, data_size);
+
+       LogDebug("GetData data_size = [" << data_size << "]");
+
+       // encrypted data may be longer
+       TZSerializer sOut;
+       sOut.Push(new TZSerializableBinary(data_size + KM_ENCRYPTION_OVERHEAD));
+       TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
+       sOut.Serialize(outMemory);
+
+       TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+
+       Execute(CMD_EXPORT_WRAPPED_KEY, &op);
+
+       sOut.Deserialize(outMemory);
+
+       RawBuffer wrappedKey;
+       sOut.Pull(wrappedKey);
+
+       return wrappedKey;
+}
+
 void TrustZoneContext::GetDataSize(const RawBuffer &dataId, uint32_t &dataSize)
 {
        // command ID = CMD_GET_DATA_SIZE
@@ -631,6 +844,108 @@ void TrustZoneContext::destroyData(const RawBuffer &dataId)
        Execute(CMD_DESTROY_DATA, &op);
 }
 
+TZSerializablePwdData* makeSerializablePwd(const Pwd &pwd)
+{
+       auto &tag = pwd.getTag();
+       return new TZSerializablePwdData(pwd.getPassword(), pwd.getIV(), tag.size() * 8, tag);
+}
+
+void TrustZoneContext::executeEcdh(const RawBuffer &prvKeyId,
+                                                                  const Pwd &prvKeyPwd,
+                                                                  const RawBuffer &pubX,
+                                                                  const RawBuffer &pubY,
+                                                                  const RawBuffer &secretPwdBuf,
+                                                                  const RawBuffer &secretPwdIV,
+                                                                  RawBuffer &secretTag,
+                                                                  const RawBuffer &secretHash)
+{
+       // command ID = CMD_DERIVE
+       LogDebug("TrustZoneContext::executeEcdh");
+
+       auto sIn = makeSerializer(
+               prvKeyId, prvKeyPwd, pubX, pubY, EncPwd{secretPwdBuf, secretPwdIV}, secretHash);
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
+
+       TZSerializer sOut;
+       if (!secretPwdBuf.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 (!secretPwdBuf.empty())
+               op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+       op.params[0].value.a = ALGO_ECDH_DRV;
+
+       Execute(CMD_DERIVE, &op);
+
+       if (!secretPwdBuf.empty()) {
+               sOut.Deserialize(outMemory);
+               sOut.Pull(secretTag);
+       }
+
+       LogDebug("Derived object ID is (hex): " << rawToHexString(secretHash));
+}
+
+void TrustZoneContext::executeKbkdf(const RawBuffer& secretId,
+                                                                       const Pwd& secretPwd,
+                                                                       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
+       LogDebug("TrustZoneContext::executeKbkdf");
+
+       auto sIn = makeSerializer(secretId,
+                                                         secretPwd,
+                                                         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, &op);
+
+       if (!keyPwdBuf.empty()) {
+               sOut.Deserialize(outMemory);
+               sOut.Pull(keyTag);
+       }
+
+       LogDebug("Derived object ID is (hex): " << rawToHexString(keyHash));
+}
+
 void TrustZoneContext::Initialize()
 {
        TEEC_Operation op;