Merge "Fix accessing freed memory in X509CertificateStore::Update()" into tizen
[platform/framework/native/appfw.git] / src / security / crypto / FSecCryptoCastCipher.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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 /**
18  * @file                FSecCryptoCastCipher.cpp
19  * @brief               This file contains the implementation of Tizen::Security::Crypto::CastCipher.
20  */
21 #include <unique_ptr.h>
22 #include <openssl/evp.h>
23 #include <openssl/crypto.h>
24 #include <FBaseResult.h>
25 #include <FBaseErrors.h>
26 #include <FSecCryptoCastCipher.h>
27 #include <FSecSecretKey.h>
28 #include <FBaseSysLog.h>
29 #include "FSecCrypto_SymmetricCipher.h"
30
31 using namespace Tizen::Base;
32
33
34 namespace Tizen { namespace Security { namespace Crypto
35 {
36
37 static const int _TRANSFORMATION_STRING_PART_1_LENGTH = 3;
38 static const int _TRANSFORMATION_STRING_PART_2_BEGIN = 4;
39 static const int _TRANSFORMATION_STRING_PART_2_LENGTH_A = 9;
40 static const int _TRANSFORMATION_STRING_PART_2_LENGTH_B = 12;
41
42 CastCipher::CastCipher(void)
43         : __pSymmetricCipher(null)      // Default is CAST/CBC/128
44         , __pCipherAlgorithm(null)
45         , __pCastCipherImpl(null)
46 {
47 }
48
49 CastCipher::~CastCipher(void)
50 {
51         delete __pSymmetricCipher;
52 }
53
54 result
55 CastCipher::Construct(const Tizen::Base::String& transformation, CipherOperation opMode)
56 {
57         result r = E_SUCCESS;
58         bool padVal = false;
59         String cipherMode = null;
60         String padding = null;
61
62         SysAssertf(__pSymmetricCipher == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class");
63
64         __pSymmetricCipher = new (std::nothrow) _SymmetricCipher();
65         SysTryReturn(NID_SEC_CRYPTO, __pSymmetricCipher != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
66
67         SysTryCatch(NID_SEC_CRYPTO, transformation.GetLength() > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The transformation string should be valid.");
68
69         // Setting the key size, cipher mode and padding for the Cast Construct
70         r = transformation.SubString(0, _TRANSFORMATION_STRING_PART_1_LENGTH, cipherMode);
71         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "The transformation string should be valid.");
72
73         if (cipherMode.CompareTo(L"128") == E_SUCCESS)
74         {
75                 __pCipherAlgorithm = EVP_cast5_cbc();
76         }
77         else
78         {
79                 r = E_INVALID_ARG;
80                 SysLogException(NID_SEC_CRYPTO, r, "The cipher algorithm for requested key length is not supported.");
81                 goto CATCH;
82         }
83
84         r = transformation.SubString(_TRANSFORMATION_STRING_PART_2_BEGIN, _TRANSFORMATION_STRING_PART_2_LENGTH_A, padding);
85         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "The transformation string should be valid.");
86
87         if (padding.CompareTo(L"NOPADDING") == E_SUCCESS)
88         {
89                 padVal = false;
90         }
91         else
92         {
93                 r = transformation.SubString(_TRANSFORMATION_STRING_PART_2_BEGIN, _TRANSFORMATION_STRING_PART_2_LENGTH_B, padding);
94                 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "The transformation string should be valid.");
95
96                 if (padding.CompareTo(L"PKCS7PADDING") == E_SUCCESS)
97                 {
98                         padVal = true;
99                 }
100                 else
101                 {
102                         r = E_INVALID_ARG;
103                         SysLogException(NID_SEC_CRYPTO, r, "The cipher algorithm for requested padding is not supported.");
104                         goto CATCH;
105                 }
106         }
107
108         // sets the transformation
109         r = __pSymmetricCipher->SetTransformation(__pCipherAlgorithm, padVal);
110         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), , r, "[%s] Failed to do set transformation operation.", GetErrorMessage(r));
111
112         SysTryCatch(NID_SEC_CRYPTO, opMode == CIPHER_ENCRYPT || opMode == CIPHER_DECRYPT,
113                         r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The opMode should be valid.");
114
115         // sets the SetCipherOpearation
116         r = __pSymmetricCipher->SetCipherOperation(opMode);
117         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), , r, "[%s] The cipher operation request should be valid.", GetErrorMessage(r));
118
119 CATCH:
120         if (IsFailed(r))
121         {
122                 delete __pSymmetricCipher;
123                 __pSymmetricCipher = null;
124         }
125         return r;
126 }
127
128 result
129 CastCipher::SetKey(const Tizen::Security::ISecretKey& key)
130 {
131         result r = E_SUCCESS;
132         int keyLen = 0;
133
134         SysAssertf(__pSymmetricCipher != null, "Not yet constructed. Construct() should be called before use.");
135
136         std::unique_ptr<ByteBuffer> pKey(key.GetEncodedN());
137         SysTryReturnResult(NID_SEC_CRYPTO, pKey != null, E_INVALID_ARG, "Input key data should be valid.");
138
139         keyLen = static_cast< int >(pKey->GetRemaining());
140         SysTryReturnResult(NID_SEC_CRYPTO, keyLen == __pCipherAlgorithm->key_len, E_INVALID_ARG, "Input key length should be equal to algorithm key length.");
141
142         r = __pSymmetricCipher->SetKey(key);
143         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to do set key operation.", GetErrorMessage(r));
144
145         return r;
146 }
147
148 result
149 CastCipher::SetInitialVector(const Tizen::Base::ByteBuffer& initialVector)
150 {
151         result r = E_SUCCESS;
152
153         SysAssertf(__pSymmetricCipher != null, "Not yet constructed. Construct() should be called before use.");
154
155         r = __pSymmetricCipher->SetInitialVector(initialVector);
156         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to do set initial vector operation.", GetErrorMessage(r));
157
158         return r;
159 }
160
161 ByteBuffer*
162 CastCipher::EncryptN(const Tizen::Base::ByteBuffer& input)
163 {
164         ByteBuffer* pOutput = null;
165
166         ClearLastResult();
167
168         SysAssertf(__pSymmetricCipher != null, "Not yet constructed. Construct() should be called before use.");
169
170         pOutput = __pSymmetricCipher->DoCipherN(input);
171         SysTryReturn(NID_SEC_CRYPTO, pOutput != null, null, GetLastResult(), "[%s]Failed to do encrypt operation", GetErrorMessage(GetLastResult()));
172
173         return pOutput;
174 }
175
176 ByteBuffer*
177 CastCipher::DecryptN(const Tizen::Base::ByteBuffer& input)
178 {
179         ByteBuffer* pOutput = null;
180
181         ClearLastResult();
182
183         SysAssertf(__pSymmetricCipher != null, "Not yet constructed. Construct() should be called before use.");
184
185         pOutput = __pSymmetricCipher->DoCipherN(input);
186         SysTryReturn(NID_SEC_CRYPTO, pOutput != null, null, GetLastResult(), "[%s]Failed to do decrypt operation", GetErrorMessage(GetLastResult()));
187
188         return pOutput;
189 }
190
191 result
192 CastCipher::Initialize(void)
193 {
194         result r = E_SUCCESS;
195
196         SysAssertf(__pSymmetricCipher != null, "Not yet constructed. Construct() should be called before use.");
197
198         r = __pSymmetricCipher->Initialize();
199         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to do initialize operation.", GetErrorMessage(r));
200
201         return r;
202 }
203
204 ByteBuffer*
205 CastCipher::UpdateN(const Tizen::Base::ByteBuffer& input)
206 {
207         ByteBuffer* pOutput = null;
208
209         ClearLastResult();
210
211         SysAssertf(__pSymmetricCipher != null, "Not yet constructed. Construct() should be called before use.");
212
213         pOutput = __pSymmetricCipher->UpdateN(input);
214         SysTryReturn(NID_SEC_CRYPTO, pOutput != null, null, GetLastResult(), "[%s]Failed to do update operation", GetErrorMessage(GetLastResult()));
215
216         return pOutput;
217 }
218
219 ByteBuffer*
220 CastCipher::FinalizeN(void)
221 {
222         ByteBuffer* pOutput = null;
223
224         ClearLastResult();
225
226         SysAssertf(__pSymmetricCipher != null, "Not yet constructed. Construct() should be called before use.");
227
228         pOutput = __pSymmetricCipher->FinalizeN();
229         SysTryReturn(NID_SEC_CRYPTO, pOutput != null, null, GetLastResult(), "[%s]Failed to do finalize operation", GetErrorMessage(GetLastResult()));
230
231         return pOutput;
232 }
233
234 ByteBuffer*
235 CastCipher::WrapN(const Tizen::Base::ByteBuffer& secretKey)
236 {
237         ClearLastResult();
238
239         SetLastResult(E_UNSUPPORTED_ALGORITHM);
240
241         return null;
242 }
243
244 ByteBuffer*
245 CastCipher::UnwrapN(const Tizen::Base::ByteBuffer& wrappedKey)
246 {
247         ClearLastResult();
248
249         SetLastResult(E_UNSUPPORTED_ALGORITHM);
250
251         return null;
252 }
253
254 } } } //Tizen::Security::Crypto