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(), 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() || encryptedKey.type.isEllipticCurve())
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));
125 RawBuffer SKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
127 return Internals::symmetricEncrypt(getId(), getPassword(), alg, data);
130 RawBuffer SKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &cipher)
132 return Internals::symmetricDecrypt(getId(), getPassword(), alg, cipher);
135 GCtxShPtr SKey::initContext(const CryptoAlgorithm &alg, bool onward)
137 auto opId = Internals::initCipher(getId(), getPassword(), alg, onward);
139 return std::make_shared<CipherCtx>(opId);
142 RawBuffer AKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
144 return Internals::asymmetricEncrypt(getId(), getPassword(), alg, data);
147 RawBuffer AKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &cipher)
149 return Internals::asymmetricDecrypt(getId(), getPassword(), alg, cipher);
152 Token AKey::derive(const CryptoAlgorithm &alg, const Password &pass, const RawBuffer &hash)
154 if (m_type != DataType::KEY_ECDSA_PRIVATE)
155 ThrowErr(Exc::Crypto::InputParam, "ECDH requires EC private key");
157 auto algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
158 if (algo != AlgoType::ECDH)
159 ThrowErr(Exc::Crypto::InputParam, "Wrong algorithm");
161 auto pubKey = unpack<RawBuffer>(alg, ParamName::ECDH_PUBKEY);
166 // IV is needed for key encryption
167 iv = Internals::generateIV();
170 Internals::deriveECDH(getId(), getPassword(), pubKey, pass, iv, tag, hash);
172 return Token(backendId(), DataType::BINARY_DATA, Store::pack(hash, pass, iv, tag));
175 GCtxShPtr AKey::initContext(const CryptoAlgorithm &, bool)
177 ThrowErr(Exc::Crypto::OperationNotSupported);
180 RawBuffer AKey::sign(
181 const CryptoAlgorithm &alg,
182 const RawBuffer &message)
184 CryptoAlgorithm algWithType(alg);
185 algWithType.setParam(ParamName::ALGO_TYPE, key2algo(m_type));
186 return Internals::sign(getId(), getPassword(), algWithType, message);
189 int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message,
190 const RawBuffer &sign)
192 CryptoAlgorithm algWithType(alg);
195 // setup algorithm type basing on key type if it doesn't exist
196 if (!algWithType.getParam(ParamName::ALGO_TYPE, type)) {
197 algWithType.setParam(ParamName::ALGO_TYPE, key2algo(m_type));
200 return Internals::verify(getId(), getPassword(), algWithType, message, sign);
203 Token Cert::unwrap(const CryptoAlgorithm &,
208 ThrowErr(Exc::Crypto::OperationNotSupported);
211 RawBuffer Cert::wrap(const CryptoAlgorithm &,
215 ThrowErr(Exc::Crypto::OperationNotSupported);
219 } // namespace Crypto