Fix secret pwd passing in TZ backend KBKDF
[platform/core/security/key-manager.git] / src / manager / crypto / tz-backend / tz-context.cpp
index efeb4a9..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 {
@@ -476,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,
@@ -599,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
@@ -702,10 +889,14 @@ void TrustZoneContext::executeEcdh(const RawBuffer &prvKeyId,
        LogDebug("Derived object ID is (hex): " << rawToHexString(secretHash));
 }
 
-void TrustZoneContext::executeKbkdf(const RawBuffer& secret,
-                                                                       KdfPrf prf,
-                                                                       KbkdfMode mode,
-                                                                       KbkdfCounterLocation location,
+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,
@@ -717,8 +908,19 @@ void TrustZoneContext::executeKbkdf(const RawBuffer& secret,
        // command ID = CMD_DERIVE
        LogDebug("TrustZoneContext::executeKbkdf");
 
-       auto sIn = makeSerializer(
-               secret, prf, mode, location, rlen, llen, noSeparator, EncPwd{keyPwdBuf, keyPwdIV}, keyHash);
+       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);