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