2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FSecCryptoRsaCipher.cpp
19 * @brief This file contains the implementation of Tizen::Security::Crypto::RsaCipher class.
22 #include <openssl/rsa.h>
23 #include <openssl/evp.h>
24 #include <openssl/pem.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;
100 pData = const_cast< byte* >(input.GetPointer());
101 SysTryReturn(NID_SEC_CRYPTO, pData != null, null, E_INVALID_ARG, "[E_INVALID_ARG] Input data value should be valid.");
103 dataLen = input.GetRemaining();
104 SysTryReturn(NID_SEC_CRYPTO, dataLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] Input data length should be positive.");
106 pKey = __publicKey.GetPointer();
107 SysTryReturn(NID_SEC_CRYPTO, pKey != null, null, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND] Key value should be valid.");
109 keyLen = __publicKey.GetRemaining();
110 SysTryReturn(NID_SEC_CRYPTO, keyLen > 0, null, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND] Key length should be positive.");
112 pEvpKey = d2i_PublicKey(EVP_PKEY_RSA, null, &pKey, keyLen);
116 pEvpKey = d2i_PUBKEY(null, &pKey, keyLen);
121 pBio = BIO_new(BIO_s_mem());
122 SysTryReturn(NID_SEC_CRYPTO, pBio != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
124 int readCount = BIO_write(pBio, (const void*) pKey, keyLen);
127 pEvpKey = PEM_read_bio_PUBKEY(pBio, null, 0, null);
131 SysTryCatch(NID_SEC_CRYPTO, pEvpKey != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
133 pRsa = EVP_PKEY_get1_RSA(pEvpKey);
134 SysTryCatch(NID_SEC_CRYPTO, pRsa != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
136 tempLen = BN_bn2bin(pRsa->n, buffer);
137 SysTryCatch(NID_SEC_CRYPTO, tempLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
139 pTempBuf = new (std::nothrow) byte[tempLen];
140 SysTryCatch(NID_SEC_CRYPTO, pTempBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
142 memset(pTempBuf, 0, tempLen);
144 outLen = RSA_public_encrypt(dataLen, pData, pTempBuf, pRsa, RSA_PKCS1_PADDING);
145 SysTryCatch(NID_SEC_CRYPTO, outLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
147 SysTryCatch(NID_SEC_CRYPTO, outLen <= tempLen, r = E_OVERFLOW, E_OVERFLOW, "[E_OVERFLOW] Overflow as output data length > input data length.");
149 pOutput = new (std::nothrow) ByteBuffer();
150 SysTryCatch(NID_SEC_CRYPTO, pOutput != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
152 r = pOutput->Construct(outLen);
153 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
155 r = pOutput->SetArray(pTempBuf, 0, outLen);
156 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
177 EVP_PKEY_free(pEvpKey);
185 RsaCipher::DecryptN(const Tizen::Base::ByteBuffer& input)
187 result r = E_SUCCESS;
193 byte* pTempBuf = null;
194 byte buffer[_MAX_ARRAY_LENGTH];
195 const byte* pKey = null;
196 ByteBuffer* pOutput = null;
197 EVP_PKEY* pEvpKey = null;
203 pData = const_cast< byte* >(input.GetPointer());
204 SysTryReturn(NID_SEC_CRYPTO, pData != null, null, E_INVALID_ARG, "[E_INVALID_ARG] Input data value should be valid.");
206 dataLen = input.GetRemaining();
207 SysTryReturn(NID_SEC_CRYPTO, dataLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] Input data length should be positive.");
209 pKey = __privateKey.GetPointer();
210 SysTryReturn(NID_SEC_CRYPTO, pKey != null, null, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND] Key data should be valid.");
212 keyLen = __privateKey.GetRemaining();
213 SysTryReturn(NID_SEC_CRYPTO, keyLen > 0, null, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND] Key length should be positive.");
215 //res = __SecCrDecodeRSAPrivateKey(&pPriKey, (CrUINT8 *)pKey, (CrUINT32)keyLen);
216 pEvpKey = d2i_PrivateKey(EVP_PKEY_RSA, null, &pKey, keyLen);
220 PKCS8_PRIV_KEY_INFO* pPrivKeyInfo = d2i_PKCS8_PRIV_KEY_INFO(null, &pKey, keyLen);
221 if (pPrivKeyInfo != null)
223 pEvpKey = EVP_PKCS82PKEY(pPrivKeyInfo);
224 PKCS8_PRIV_KEY_INFO_free(pPrivKeyInfo);
229 pBio = BIO_new(BIO_s_mem());
230 SysTryReturn(NID_SEC_CRYPTO, pBio != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
232 int readCount = BIO_write(pBio, (const void*) pKey, keyLen);
235 pEvpKey = PEM_read_bio_PrivateKey(pBio, null, 0, null);
239 SysTryCatch(NID_SEC_CRYPTO, pEvpKey != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
241 pRsa = EVP_PKEY_get1_RSA(pEvpKey);
242 SysTryCatch(NID_SEC_CRYPTO, pRsa != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
244 tempLen = BN_bn2bin(pRsa->n, buffer);
245 SysTryCatch(NID_SEC_CRYPTO, tempLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
247 pTempBuf = new (std::nothrow) byte[tempLen];
248 SysTryCatch(NID_SEC_CRYPTO, pTempBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_SYSTEM] An unexpected system error occurred.");
250 memset(pTempBuf, 0, tempLen);
252 outLen = RSA_private_decrypt(dataLen, pData, pTempBuf, pRsa, RSA_PKCS1_PADDING);
253 SysTryCatch(NID_SEC_CRYPTO, outLen > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_SYSTEM] An unexpected system error occurred.");
254 SysTryCatch(NID_SEC_CRYPTO, outLen <= tempLen, r = E_OVERFLOW, E_OVERFLOW, "[E_OVERFLOW] Overflow as output data length > input data length.");
256 pOutput = new (std::nothrow) ByteBuffer();
257 SysTryCatch(NID_SEC_CRYPTO, pOutput != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
259 r = pOutput->Construct(outLen);
260 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
262 r = pOutput->SetArray(pTempBuf, 0, outLen);
263 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
280 EVP_PKEY_free(pEvpKey);
291 } } } //Tizen::Security::Crypto