Add type parameter to "get" commands
[platform/core/security/key-manager.git] / src / manager / crypto / tz-backend / obj.cpp
1 /*
2  *  Copyright (c) 2015 - 2020 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       obj.cpp
18  * @author     Lukasz Kostyra (l.kostyra@samsung.com)
19  * @version    1.0
20  */
21 #include <memory>
22 #include <utility>
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>
29
30 namespace CKM {
31 namespace Crypto {
32 namespace TZ {
33
34 namespace {
35 AlgoType key2algo(DataType type)
36 {
37         switch (type) {
38         case DataType::KEY_RSA_PRIVATE:
39         case DataType::KEY_RSA_PUBLIC:
40                 return AlgoType::RSA_SV;
41
42         case DataType::KEY_DSA_PRIVATE:
43         case DataType::KEY_DSA_PUBLIC:
44                 return AlgoType::DSA_SV;
45
46         case DataType::KEY_ECDSA_PRIVATE:
47         case DataType::KEY_ECDSA_PUBLIC:
48                 return AlgoType::ECDSA_SV;
49
50         default:
51                 ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", type);
52         }
53 }
54 } // namespace anonymous
55
56 Token BData::derive(const CryptoAlgorithm &alg, const Password &pass, const RawBuffer &hash)
57 {
58         auto algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
59         if (algo != AlgoType::KBKDF)
60                 ThrowErr(Exc::Crypto::InputParam, "Wrong algorithm");
61
62         RawBuffer iv;
63         RawBuffer tag;
64         if (!pass.empty()) {
65                 // IV is needed for key encryption
66                 iv = Internals::generateIV();
67         }
68
69         Internals::deriveKBKDF(getId(), getPassword(), alg, pass, iv, tag, hash);
70
71         return Token(backendId(), DataType(KeyType::KEY_AES), Store::pack(hash, pass, iv, tag));
72 }
73
74 Token Key::unwrap(const CryptoAlgorithm &params,
75                                   const Data &encryptedKey,
76                                   const Password &pass,
77                                   const RawBuffer &hash)
78 {
79
80         if (!encryptedKey.type.isKey())
81                 ThrowErr(Exc::Crypto::DataTypeNotSupported, "Invalid data provided for import");
82
83         RawBuffer passIV;
84         RawBuffer tag;
85
86         if (!pass.empty()) {
87                 // IV is needed for data encryption with pwd
88                 passIV = Internals::generateIV();
89         }
90
91         Internals::importWrappedKey(getId(),
92                                                                 getPassword(),
93                                                                 params,
94                                                                 encryptedKey,
95                                                                 pass,
96                                                                 passIV,
97                                                                 tag,
98                                                                 hash);
99
100         return Token(backendId(), encryptedKey.type, Store::pack(hash, pass, passIV, tag));
101 }
102
103 RawBuffer Key::wrap(const CryptoAlgorithm &alg,
104                                         const Token &keyToWrap,
105                                         const Password &keyToWrapPass)
106 {
107         int keyToWrapScheme;
108         RawBuffer keyToWrapId;
109         RawBuffer keyToWrapIV;
110         RawBuffer keyToWrapTag;
111         Store::unpack(keyToWrap.data,
112                                   keyToWrapPass,
113                                   keyToWrapScheme,
114                                   keyToWrapId,
115                                   keyToWrapIV,
116                                   keyToWrapTag);
117
118         return Internals::exportWrappedKey(getId(),
119                                                                            getPassword(),
120                                                                            alg,
121                                                                            keyToWrapId,
122                                                                            Pwd(keyToWrapPass, keyToWrapIV, keyToWrapTag),
123                                                                            m_type);
124 }
125
126 RawBuffer SKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
127 {
128     return Internals::symmetricEncrypt(getId(), getPassword(), alg, data);
129 }
130
131 RawBuffer SKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &cipher)
132 {
133     return Internals::symmetricDecrypt(getId(), getPassword(), alg, cipher);
134 }
135
136 GCtxShPtr SKey::initContext(const CryptoAlgorithm &alg, bool onward)
137 {
138         auto opId = Internals::initCipher(getId(), getPassword(), alg, onward);
139
140         return std::make_shared<CipherCtx>(opId);
141 }
142
143 RawBuffer AKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
144 {
145         return Internals::asymmetricEncrypt(getId(), getPassword(), alg, data);
146 }
147
148 RawBuffer AKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &cipher)
149 {
150         return Internals::asymmetricDecrypt(getId(), getPassword(), alg, cipher);
151 }
152
153 Token AKey::derive(const CryptoAlgorithm &alg, const Password &pass, const RawBuffer &hash)
154 {
155         if (m_type != DataType::KEY_ECDSA_PRIVATE)
156                 ThrowErr(Exc::Crypto::InputParam, "ECDH requires EC private key");
157
158         auto algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
159         if (algo != AlgoType::ECDH)
160                 ThrowErr(Exc::Crypto::InputParam, "Wrong algorithm");
161
162         auto pubKey = unpack<RawBuffer>(alg, ParamName::ECDH_PUBKEY);
163
164         RawBuffer iv;
165         RawBuffer tag;
166         if (!pass.empty()) {
167                 // IV is needed for key encryption
168                 iv = Internals::generateIV();
169         }
170
171         Internals::deriveECDH(getId(), getPassword(), pubKey, pass, iv, tag, hash);
172
173         return Token(backendId(), DataType::BINARY_DATA, Store::pack(hash, pass, iv, tag));
174 }
175
176 GCtxShPtr AKey::initContext(const CryptoAlgorithm &, bool)
177 {
178         ThrowErr(Exc::Crypto::OperationNotSupported);
179 }
180
181 RawBuffer AKey::getBinary() const
182 {
183         if (m_type.isKeyPublic() && m_raw.empty())
184                 m_raw = Internals::getData(getId(), getPassword(), m_type);
185
186         return m_raw;
187 }
188
189 RawBuffer AKey::sign(
190         const CryptoAlgorithm &alg,
191         const RawBuffer &message)
192 {
193         CryptoAlgorithm algWithType(alg);
194         algWithType.setParam(ParamName::ALGO_TYPE, key2algo(m_type));
195         return Internals::sign(getId(), getPassword(), algWithType, message);
196 }
197
198 int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message,
199                                  const RawBuffer &sign)
200 {
201         CryptoAlgorithm algWithType(alg);
202         AlgoType type;
203
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));
207         }
208
209         return Internals::verify(getId(), getPassword(), algWithType, message, sign);
210 }
211
212 Token Cert::unwrap(const CryptoAlgorithm &,
213                                    const Data &,
214                                    const Password &,
215                                    const RawBuffer &)
216 {
217         ThrowErr(Exc::Crypto::OperationNotSupported);
218 }
219
220 RawBuffer Cert::wrap(const CryptoAlgorithm &,
221                                          const Token &,
222                                          const Password &)
223 {
224         ThrowErr(Exc::Crypto::OperationNotSupported);
225 }
226
227 } // namespace TZ
228 } // namespace Crypto
229 } // namespace CKM
230