2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file FSecCryptoRsaCipher.cpp
20 * @brief This file contains the implementation of Tizen::Security::Crypto::RsaCipher class.
23 #include <openssl/rsa.h>
24 #include <openssl/evp.h>
25 #include <openssl/x509.h>
26 #include <FBaseResult.h>
27 #include <FBaseErrors.h>
28 #include <FSecCryptoRsaCipher.h>
29 #include <FBaseSysLog.h>
31 using namespace Tizen::Base;
34 namespace Tizen { namespace Security { namespace Crypto
36 static const int _MAX_ARRAY_LENGTH = 4096;
38 RsaCipher::RsaCipher(void)
39 : __pRsaCipherImpl(null)
43 RsaCipher::~RsaCipher(void)
48 RsaCipher::SetPrivateKey(const Tizen::Security::IKey& key)
51 ByteBuffer* pBuffer = null;
53 pBuffer = key.GetEncodedN();
54 SysTryReturn(NID_SEC_CRYPTO, pBuffer != null, GetLastResult(), GetLastResult(), "[%s] Failed to fill the key buffer.", GetErrorMessage(GetLastResult()));
56 r = __privateKey.Construct(*pBuffer);
57 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), , r, "[%s] Input key buffer should be valid.", GetErrorMessage(r));
65 RsaCipher::SetPublicKey(const Tizen::Security::IKey& key)
68 ByteBuffer* pBuffer = null;
70 pBuffer = key.GetEncodedN();
71 SysTryReturn(NID_SEC_CRYPTO, pBuffer != null, GetLastResult(), GetLastResult(), "[%s] Failed to fill the key buffer.", GetErrorMessage(GetLastResult()));
73 r = __publicKey.Construct(*pBuffer);
74 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), , r, "[%s] Input key buffer should be valid.", GetErrorMessage(r));
82 RsaCipher::EncryptN(const Tizen::Base::ByteBuffer& input)
90 byte* pTempBuf = null;
91 byte buffer[_MAX_ARRAY_LENGTH];
92 const byte* pKey = null;
93 ByteBuffer* pOutput = null;
94 EVP_PKEY* pEvpKey = null;
99 pData = const_cast< byte* >(input.GetPointer());
100 SysTryReturn(NID_SEC_CRYPTO, pData != null, null, E_INVALID_ARG, "[E_INVALID_ARG] Input data value should be valid.");
102 dataLen = input.GetRemaining();
103 SysTryReturn(NID_SEC_CRYPTO, dataLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] Input data length should be positive.");
105 pKey = __publicKey.GetPointer();
106 SysTryReturn(NID_SEC_CRYPTO, pKey != null, null, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND] Key value should be valid.");
108 keyLen = __publicKey.GetRemaining();
109 SysTryReturn(NID_SEC_CRYPTO, keyLen > 0, null, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND] Key length should be positive.");
111 pEvpKey = d2i_PublicKey(EVP_PKEY_RSA, null, &pKey, keyLen);
112 SysTryReturn(NID_SEC_CRYPTO, pEvpKey != null, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
114 pRsa = EVP_PKEY_get1_RSA(pEvpKey);
115 SysTryCatch(NID_SEC_CRYPTO, pRsa != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
117 tempLen = BN_bn2bin(pRsa->n, buffer);
118 SysTryCatch(NID_SEC_CRYPTO, tempLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
120 pTempBuf = new (std::nothrow) byte[tempLen];
121 SysTryCatch(NID_SEC_CRYPTO, pTempBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
123 memset(pTempBuf, 0, tempLen);
125 outLen = RSA_public_encrypt(dataLen, pData, pTempBuf, pRsa, RSA_PKCS1_PADDING);
126 SysTryCatch(NID_SEC_CRYPTO, outLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
128 SysTryCatch(NID_SEC_CRYPTO, outLen <= tempLen, r = E_OVERFLOW, E_OVERFLOW, "[E_OVERFLOW] Overflow as output data length > input data length.");
130 pOutput = new (std::nothrow) ByteBuffer();
131 SysTryCatch(NID_SEC_CRYPTO, pOutput != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
133 r = pOutput->Construct(outLen);
134 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
136 r = pOutput->SetArray(pTempBuf, 0, outLen);
137 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
152 EVP_PKEY_free(pEvpKey);
159 RsaCipher::DecryptN(const Tizen::Base::ByteBuffer& input)
161 result r = E_SUCCESS;
167 byte* pTempBuf = null;
168 byte buffer[_MAX_ARRAY_LENGTH];
169 const byte* pKey = null;
170 ByteBuffer* pOutput = null;
171 EVP_PKEY* pEvpKey = null;
176 pData = const_cast< byte* >(input.GetPointer());
177 SysTryReturn(NID_SEC_CRYPTO, pData != null, null, E_INVALID_ARG, "[E_INVALID_ARG] Input data value should be valid.");
179 dataLen = input.GetRemaining();
180 SysTryReturn(NID_SEC_CRYPTO, dataLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] Input data length should be positive.");
182 pKey = __privateKey.GetPointer();
183 SysTryReturn(NID_SEC_CRYPTO, pKey != null, null, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND] Key data should be valid.");
185 keyLen = __privateKey.GetRemaining();
186 SysTryReturn(NID_SEC_CRYPTO, keyLen > 0, null, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND] Key length should be positive.");
188 //res = __SecCrDecodeRSAPrivateKey(&pPriKey, (CrUINT8 *)pKey, (CrUINT32)keyLen);
189 pEvpKey = d2i_PrivateKey(EVP_PKEY_RSA, null, &pKey, keyLen);
190 SysTryReturn(NID_SEC_CRYPTO, pEvpKey != null, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
192 pRsa = EVP_PKEY_get1_RSA(pEvpKey);
193 SysTryCatch(NID_SEC_CRYPTO, pRsa != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
195 tempLen = BN_bn2bin(pRsa->n, buffer);
196 SysTryCatch(NID_SEC_CRYPTO, tempLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
198 pTempBuf = new (std::nothrow) byte[tempLen];
199 SysTryCatch(NID_SEC_CRYPTO, pTempBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_SYSTEM] An unexpected system error occurred.");
201 memset(pTempBuf, 0, tempLen);
203 outLen = RSA_private_decrypt(dataLen, pData, pTempBuf, pRsa, RSA_PKCS1_PADDING);
204 SysTryCatch(NID_SEC_CRYPTO, outLen > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_SYSTEM] An unexpected system error occurred.");
205 SysTryCatch(NID_SEC_CRYPTO, outLen <= tempLen, r = E_OVERFLOW, E_OVERFLOW, "[E_OVERFLOW] Overflow as output data length > input data length.");
207 pOutput = new (std::nothrow) ByteBuffer();
208 SysTryCatch(NID_SEC_CRYPTO, pOutput != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
210 r = pOutput->Construct(outLen);
211 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
213 r = pOutput->SetArray(pTempBuf, 0, outLen);
214 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
229 EVP_PKEY_free(pEvpKey);
235 } } } //Tizen::Security::Crypto