2 * Copyright (c) 2015 - 2020 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)
23 #include <generic-backend/exception.h>
24 #include <generic-backend/algo-validation.h>
25 #include <tz-backend/obj.h>
26 #include <tz-backend/ctx.h>
27 #include <tz-backend/store.h>
28 #include <tz-backend/internals.h>
35 AlgoType key2algo(DataType type)
38 case DataType::KEY_RSA_PRIVATE:
39 case DataType::KEY_RSA_PUBLIC:
40 return AlgoType::RSA_SV;
42 case DataType::KEY_DSA_PRIVATE:
43 case DataType::KEY_DSA_PUBLIC:
44 return AlgoType::DSA_SV;
46 case DataType::KEY_ECDSA_PRIVATE:
47 case DataType::KEY_ECDSA_PUBLIC:
48 return AlgoType::ECDSA_SV;
51 ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", type);
54 } // namespace anonymous
56 Token BData::derive(const CryptoAlgorithm &alg, const Password &pass, const RawBuffer &hash)
58 auto algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
59 if (algo != AlgoType::KBKDF)
60 ThrowErr(Exc::Crypto::InputParam, "Wrong algorithm");
65 // IV is needed for key encryption
66 iv = Internals::generateIV();
69 Internals::deriveKBKDF(getId(), getPassword(), alg, pass, iv, tag, hash);
71 return Token(backendId(), DataType(KeyType::KEY_AES), Store::pack(hash, pass, iv, tag));
74 Token Key::unwrap(const CryptoAlgorithm ¶ms,
75 const Data &encryptedKey,
77 const RawBuffer &hash)
80 if (!encryptedKey.type.isKey())
81 ThrowErr(Exc::Crypto::DataTypeNotSupported, "Invalid data provided for import");
87 // IV is needed for data encryption with pwd
88 passIV = Internals::generateIV();
91 Internals::importWrappedKey(getId(),
100 return Token(backendId(), encryptedKey.type, Store::pack(hash, pass, passIV, tag));
103 RawBuffer Key::wrap(const CryptoAlgorithm &alg,
104 const Token &keyToWrap,
105 const Password &keyToWrapPass)
108 RawBuffer keyToWrapId;
109 RawBuffer keyToWrapIV;
110 RawBuffer keyToWrapTag;
111 Store::unpack(keyToWrap.data,
118 return Internals::exportWrappedKey(getId(),
122 Pwd(keyToWrapPass, keyToWrapIV, keyToWrapTag),
126 RawBuffer SKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
128 return Internals::symmetricEncrypt(getId(), getPassword(), alg, data);
131 RawBuffer SKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &cipher)
133 return Internals::symmetricDecrypt(getId(), getPassword(), alg, cipher);
136 GCtxShPtr SKey::initContext(const CryptoAlgorithm &alg, bool onward)
138 auto opId = Internals::initCipher(getId(), getPassword(), alg, onward);
140 return std::make_shared<CipherCtx>(opId);
143 RawBuffer AKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
145 return Internals::asymmetricEncrypt(getId(), getPassword(), alg, data);
148 RawBuffer AKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &cipher)
150 return Internals::asymmetricDecrypt(getId(), getPassword(), alg, cipher);
153 Token AKey::derive(const CryptoAlgorithm &alg, const Password &pass, const RawBuffer &hash)
155 if (m_type != DataType::KEY_ECDSA_PRIVATE)
156 ThrowErr(Exc::Crypto::InputParam, "ECDH requires EC private key");
158 auto algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
159 if (algo != AlgoType::ECDH)
160 ThrowErr(Exc::Crypto::InputParam, "Wrong algorithm");
162 auto pubKey = unpack<RawBuffer>(alg, ParamName::ECDH_PUBKEY);
167 // IV is needed for key encryption
168 iv = Internals::generateIV();
171 Internals::deriveECDH(getId(), getPassword(), pubKey, pass, iv, tag, hash);
173 return Token(backendId(), DataType::BINARY_DATA, Store::pack(hash, pass, iv, tag));
176 GCtxShPtr AKey::initContext(const CryptoAlgorithm &, bool)
178 ThrowErr(Exc::Crypto::OperationNotSupported);
181 RawBuffer AKey::getBinary() const
183 if (m_type.isKeyPublic() && m_raw.empty())
184 m_raw = Internals::getData(getId(), getPassword(), m_type);
189 RawBuffer AKey::sign(
190 const CryptoAlgorithm &alg,
191 const RawBuffer &message)
193 CryptoAlgorithm algWithType(alg);
194 algWithType.setParam(ParamName::ALGO_TYPE, key2algo(m_type));
195 return Internals::sign(getId(), getPassword(), algWithType, message);
198 int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message,
199 const RawBuffer &sign)
201 CryptoAlgorithm algWithType(alg);
204 // setup algorithm type basing on key type if it doesn't exist
205 if (!algWithType.getParam(ParamName::ALGO_TYPE, type)) {
206 algWithType.setParam(ParamName::ALGO_TYPE, key2algo(m_type));
209 return Internals::verify(getId(), getPassword(), algWithType, message, sign);
212 Token Cert::unwrap(const CryptoAlgorithm &,
217 ThrowErr(Exc::Crypto::OperationNotSupported);
220 RawBuffer Cert::wrap(const CryptoAlgorithm &,
224 ThrowErr(Exc::Crypto::OperationNotSupported);
228 } // namespace Crypto