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