f256eea92dd148cd4d5baaaba3290d1fec624066
[platform/core/security/key-manager.git] / src / manager / crypto / sw-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     BartÅ‚omiej Grzelewski (b.grzelewski@samsung.com)
19  * @version    1.0
20  */
21 #include <openssl/bio.h>
22 #include <openssl/evp.h>
23 #include <openssl/x509.h>
24
25 #include <dpl/log/log.h>
26 #include <utils.h>
27
28 #include <generic-backend/exception.h>
29 #include <sw-backend/obj.h>
30 #include <sw-backend/store.h>
31 #include <sw-backend/internals.h>
32
33 namespace CKM {
34 namespace Crypto {
35 namespace SW {
36
37 namespace {
38
39 AlgoType key2algo(DataType type)
40 {
41         switch (type) {
42         case DataType::KEY_RSA_PRIVATE:
43         case DataType::KEY_RSA_PUBLIC:
44                 return AlgoType::RSA_SV;
45
46         case DataType::KEY_DSA_PRIVATE:
47         case DataType::KEY_DSA_PUBLIC:
48                 return AlgoType::DSA_SV;
49
50         case DataType::KEY_ECDSA_PRIVATE:
51         case DataType::KEY_ECDSA_PUBLIC:
52                 return AlgoType::ECDSA_SV;
53
54         default:
55                 ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", type);
56         }
57 }
58
59 } // namespace anonymous
60
61 Token BData::derive(const CryptoAlgorithm &, const Password &, const RawBuffer &)
62 {
63         return Token();
64 }
65
66 RawBuffer SKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
67 {
68         return Internals::symmetricEncrypt(getBinary(), alg, data);
69 }
70 RawBuffer SKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &cipher)
71 {
72         return Internals::symmetricDecrypt(getBinary(), alg, cipher);
73 }
74
75 RawBuffer AKey::sign(
76         const CryptoAlgorithm &alg,
77         const RawBuffer &message)
78 {
79         CryptoAlgorithm algWithType(alg);
80         algWithType.setParam(ParamName::ALGO_TYPE, key2algo(m_type));
81         return Internals::sign(getEvpShPtr().get(), algWithType, message);
82 }
83
84 int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message,
85                                  const RawBuffer &sign)
86 {
87         CryptoAlgorithm algWithType(alg);
88         EVP_PKEY *evp = getEvpShPtr().get();
89         AlgoType type;
90
91         // setup algorithm type basing on evp key type if it doesn't exist
92         if (!algWithType.getParam(ParamName::ALGO_TYPE, type)) {
93                 int subType = EVP_PKEY_type(EVP_PKEY_id(evp));
94
95                 switch (subType) {
96                 case EVP_PKEY_RSA:
97                         type = AlgoType::RSA_SV;
98                         break;
99
100                 case EVP_PKEY_DSA:
101                         type = AlgoType::DSA_SV;
102                         break;
103
104                 case EVP_PKEY_EC:
105                         type = AlgoType::ECDSA_SV;
106                         break;
107
108                 default:
109                         ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", subType);
110                 }
111
112                 algWithType.setParam(ParamName::ALGO_TYPE, type);
113         }
114
115         return Internals::verify(evp, algWithType, message, sign);
116 }
117
118 RawBuffer AKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
119 {
120         return Internals::asymmetricEncrypt(getEvpShPtr(), alg, data);
121 }
122
123 RawBuffer AKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
124 {
125         return Internals::asymmetricDecrypt(getEvpShPtr(), alg, data);
126 }
127
128 Token AKey::derive(const CryptoAlgorithm &alg, const Password &pass, const RawBuffer & /* digest */)
129 {
130         auto data = Internals::deriveECDH(getEvpShPtr(), alg);
131
132         return Token(backendId(), data.type, Store::pack(data.buffer, pass));
133 }
134
135 EvpShPtr AKey::getEvpShPtr()
136 {
137         if (m_evp)
138                 return m_evp;
139
140         EVP_PKEY *pkey = NULL;
141         auto bio = uptr<BIO_free_all>(BIO_new(BIO_s_mem()));
142
143         LogDebug("Start to parse key:");
144
145         if (!pkey) {
146                 (void)BIO_reset(bio.get());
147                 BIO_write(bio.get(), m_raw.data(), m_raw.size());
148                 pkey = d2i_PrivateKey_bio(bio.get(), NULL);
149                 LogDebug("Trying d2i_PrivateKey_bio Status: " << (void *)pkey);
150         }
151
152         if (!pkey) {
153                 (void)BIO_reset(bio.get());
154                 BIO_write(bio.get(), m_raw.data(), m_raw.size());
155                 pkey = d2i_PUBKEY_bio(bio.get(), NULL);
156                 LogDebug("Trying d2i_PUBKEY_bio Status: " << (void *)pkey);
157         }
158
159         if (!pkey)
160                 ThrowErr(Exc::Crypto::InternalError, "Failed to parse key");
161
162         m_evp.reset(pkey, EVP_PKEY_free);
163         return m_evp;
164 }
165
166 EvpShPtr Cert::getEvpShPtr()
167 {
168         if (m_evp)
169                 return m_evp;
170
171         int size = static_cast<int>(m_raw.size());
172         const unsigned char *ptr = reinterpret_cast<const unsigned char *>
173                                                            (m_raw.data());
174
175         X509 *x509 = d2i_X509(NULL, &ptr, size);
176
177         if (!x509)
178                 ThrowErr(Exc::Crypto::InternalError, "Failed to parse certificate.");
179
180         m_evp.reset(X509_get_pubkey(x509), EVP_PKEY_free);
181         X509_free(x509);
182         return m_evp;
183 }
184
185 } // namespace SW
186 } // namespace Crypto
187 } // namespace CKM