tz-backend: Implement symmetric encryption through TA
[platform/core/security/key-manager.git] / src / manager / crypto / platform / decider.cpp
1 /*
2  *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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
15  */
16 /*
17  * @file       decider.cpp
18  * @author     BartÅ‚omiej Grzelewski (b.grzelewski@samsung.com)
19  * @author     Lukasz Kostyra (l.kostyra@samsung.com)
20  * @version    1.0
21  */
22 #include <dpl/log/log.h>
23
24 #include <crypto-backend.h>
25
26 #include <platform/decider.h>
27
28 #include <generic-backend/exception.h>
29 #include <sw-backend/store.h>
30 #include <tz-backend/store.h>
31
32 #include <tee_client_api.h>
33 #include <km_ta_defines.h>
34
35 #include <sstream>
36 #include <fstream>
37 #include <iomanip>
38
39 namespace CKM {
40 namespace Crypto {
41
42 namespace {
43
44 const std::string TA_STORE_PATH = "/usr/lib/tastore";
45
46 template <typename T>
47 std::string ValueToString(const T& value)
48 {
49         std::stringstream str;
50         // we need to re-cast because otherwise stringstream
51         // will write our value incorrectly
52         str << std::setfill('0') << std::setw(2 * sizeof(T)) << std::hex
53                 << static_cast<uint64_t>(value);
54         return str.str();
55 }
56
57 std::string convertTeecUUIDToString(TEEC_UUID uuid)
58 {
59         std::string uuidStr;
60         uuidStr += ValueToString(uuid.timeLow);
61         uuidStr += ValueToString(uuid.timeMid);
62         uuidStr += ValueToString(uuid.timeHiAndVersion);
63         for (auto& c: uuid.clockSeqAndNode)
64                 uuidStr += ValueToString(c);
65
66         return uuidStr;
67 }
68
69 CryptoBackend chooseCryptoBackend(DataType data, bool exportable,
70                                                                   bool encrypted)
71 {
72         // For now only software backend supports device encyption key
73         // TODO tz-backend could support the master key, but it would require
74         //      hardcoding a known key ID and querying TA whether the key is
75         //      reachable
76         if (encrypted)
77                 return CryptoBackend::OpenSSL;
78
79         // Only software backend allows for key export
80         if (exportable)
81                 return CryptoBackend::OpenSSL;
82
83         // Use TrustZone only with symmetric keys until asymmetric
84         // cryptography is implemented
85         if (!data.isSKey())
86                 return CryptoBackend::OpenSSL;
87
88         // Check if key-manager TA exists
89         std::string taUUIDStr = convertTeecUUIDToString(KM_TA_UUID);
90
91         LogDebug("Checking for " << TA_STORE_PATH << "/" << taUUIDStr);
92         std::ifstream taFile(TA_STORE_PATH + "/" + taUUIDStr);
93         if (taFile)
94                 return CryptoBackend::TrustZone;
95
96         // no TA available - fallback to OpenSSL
97         return CryptoBackend::OpenSSL;
98 }
99
100 } // namespace
101
102 Decider::Decider()
103         : m_swStore(new SW::Store(CryptoBackend::OpenSSL))
104         , m_tzStore(new TZ::Store(CryptoBackend::TrustZone))
105 {
106 }
107
108 GStore &Decider::getStore(const Token &token) const
109 {
110         return getStore(token.backendId);
111 };
112
113 GStore &Decider::getStore(CryptoBackend cryptoBackend) const
114 {
115         GStore *gStore = NULL;
116
117         if (cryptoBackend == CryptoBackend::OpenSSL)
118                 gStore = m_swStore.get();
119
120         if (cryptoBackend == CryptoBackend::TrustZone)
121                 gStore = m_tzStore.get();
122
123         if (gStore)
124                 return *gStore;
125
126         ThrowErr(Exc::Crypto::InternalError,
127                          "Backend not available. BackendId: ", (int)cryptoBackend);
128 }
129
130 GStore &Decider::getStore(DataType data, bool exportable, bool encrypted) const
131 {
132         return getStore(chooseCryptoBackend(data, exportable, encrypted));
133 }
134
135 } // namespace Crypto
136 } // namespace CKM
137