2 * Copyright (c) 2015 - 2021 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 Lukasz Kostyra (l.kostyra@samsung.com)
22 #include <generic-backend/exception.h>
23 #include <generic-backend/crypto-params.h>
24 #include <tz-backend/obj.h>
25 #include <tz-backend/store.h>
26 #include <tz-backend/internals.h>
28 #include <dpl/log/log.h>
29 #include <message-buffer.h>
37 // internal SW encryption scheme flags
38 enum EncryptionScheme {
43 RawBuffer unpackData(const RawBuffer &packed)
46 buffer.Push(RawBuffer(packed));
49 buffer.Deserialize(scheme);
52 buffer.Deserialize(data);
58 Store::Store(CryptoBackend backendId) :
63 GObjUPtr Store::getObject(const Token &token, const Password &pass)
69 unpack(token.data, pass, scheme, id, iv, tag);
71 if (token.dataType.isKeyPrivate())
72 return make<AKey>(scheme, std::move(id), Pwd(pass, iv, tag), token.dataType);
74 if (token.dataType.isSymmetricKey())
75 return make<SKey>(scheme, std::move(id), Pwd(pass, iv, tag));
77 if (token.dataType.isCertificate() || token.dataType.isChainCert())
78 return make<Cert>(scheme, std::move(id), Pwd(pass, iv, tag), token.dataType);
80 auto pwd = Pwd(pass, iv, tag);
81 RawBuffer raw = Internals::getData(id, pwd);
83 if (token.dataType.isKeyPublic())
84 return make<AKey>(scheme, std::move(id), std::move(pwd), token.dataType, std::move(raw));
86 if (token.dataType.isBinaryData())
87 return make<BData>(scheme, std::move(id), std::move(pwd), std::move(raw));
89 ThrowErr(Exc::Crypto::DataTypeNotSupported,
90 "This type of data is not supported by trustzone backend: ", token.dataType);
93 TokenPair Store::generateAKey(const CryptoAlgorithm &alg, const Password &privPass,
94 const Password &pubPass, const RawBuffer &hashPriv, const RawBuffer &hashPub)
96 RawBuffer pubIv, privIv;
97 RawBuffer pubTag, privTag;
98 if (!pubPass.empty()) {
99 pubIv = Internals::generateIV();
101 if (!privPass.empty()) {
102 privIv = Internals::generateIV();
106 DataType pubType, privType;
107 keyType = Internals::generateAKey(alg, pubPass, privPass, pubIv, privIv, pubTag, privTag, hashPriv, hashPub);
108 if(keyType == AlgoType::RSA_GEN){
109 pubType = DataType(KeyType::KEY_RSA_PUBLIC);
110 privType = DataType(KeyType::KEY_RSA_PRIVATE);
112 else if(keyType == AlgoType::DSA_GEN){
113 pubType= DataType(KeyType::KEY_DSA_PUBLIC);
114 privType = DataType(KeyType::KEY_DSA_PRIVATE);
116 else if(keyType == AlgoType::ECDSA_GEN){
117 pubType= DataType(KeyType::KEY_ECDSA_PUBLIC);
118 privType = DataType(KeyType::KEY_ECDSA_PRIVATE);
121 return std::make_pair<Token, Token>(
122 Token(m_backendId, privType, pack(hashPriv, privPass, privIv, privTag)),
123 Token(m_backendId, pubType, pack(hashPub, pubPass, pubIv, pubTag))
127 Token Store::generateSKey(const CryptoAlgorithm &alg,
128 const Password &pass,
129 const RawBuffer &hash)
134 // IV is needed for key encryption
135 iv = Internals::generateIV();
138 Internals::generateSKey(alg, pass, iv, tag, hash);
139 return Token(m_backendId, DataType(KeyType::KEY_AES), pack(hash, pass, iv, tag));
142 Token Store::import(const Data &data, const Password &pass, const EncryptionParams &e,
143 const RawBuffer &hash)
145 if (!data.type.isBinaryData() && !data.type.isKey())
146 ThrowErr(Exc::Crypto::DataTypeNotSupported, "Invalid data provided for import");
152 // IV is needed for data encryption with pwd
153 passIV = Internals::generateIV();
156 Internals::importData(data, e, pass, passIV, tag, hash);
157 return Token(m_backendId, data.type, pack(hash, pass, passIV, tag));
160 void Store::destroy(const Token &token)
162 RawBuffer id = unpackData(token.data);
163 if (token.dataType.isBinaryData()) {
164 // TODO this should be a generic "destroy persistent memory object" once
165 // serialization in key-manager-ta is unified
166 Internals::destroyData(id);
168 Internals::destroyKey(id);
171 RawBuffer Store::pack(const RawBuffer &keyId,
174 const RawBuffer &tag)
176 // determine whether the key is password protected and store schema info
177 // we don't need to additionally encrypt key ID
178 int scheme = pwd.empty() ? EncryptionScheme::NONE : EncryptionScheme::PASSWORD;
180 if (scheme == EncryptionScheme::PASSWORD) {
181 return SerializeMessage(scheme, keyId, iv, tag);
183 return SerializeMessage(scheme, keyId);
187 void Store::unpack(const RawBuffer &packed,
188 const Password& password,
194 MessageBuffer buffer;
195 buffer.Push(RawBuffer(packed));
197 buffer.Deserialize(scheme);
199 if (scheme == EncryptionScheme::PASSWORD) {
200 buffer.Deserialize(data, iv, tag);
202 buffer.Deserialize(data);
205 if ((scheme & EncryptionScheme::PASSWORD) && password.empty()) {
206 ThrowErr(Exc::Crypto::AuthenticationFailed,
207 "This token is protected with password and none passed");
208 } else if (!(scheme & EncryptionScheme::PASSWORD) && !password.empty()) {
209 ThrowErr(Exc::Crypto::AuthenticationFailed,
210 "This token is not protected with password but passed one");
215 } // namespace Crypto