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 FSecCryptoKeaKeyExchange.cpp
19 * @brief This file contains the implementation of Tizen::Security::Crypto::KeaKeyExchange.
22 #include <unique_ptr.h>
23 #include <openssl/bn.h>
24 #include <FBaseResult.h>
25 #include <FBaseErrors.h>
26 #include <FSecKeyPairGenerator.h>
27 #include <FSecCryptoKeaKeyExchange.h>
28 #include <FSecKeaKeyParameters.h>
29 #include <FSecKeyPairGenerator.h>
30 #include <FBaseSysLog.h>
31 #include "FSecCrypto_KeaCore.h"
32 #include "FSecCrypto_SkipJackCore.h"
34 using namespace Tizen::Base;
35 using namespace Tizen::Security;
38 namespace Tizen { namespace Security { namespace Crypto
40 static const int _BITS_IN_BYTE = 8;
42 KeaKeyExchange::KeaKeyExchange(void)
45 , __pPrivateComponent(null)
46 , __pPublicComponent(null)
47 , __pKeaKeyExchangeImpl(null)
52 KeaKeyExchange::~KeaKeyExchange(void)
56 delete __pPrivateComponent;
57 delete __pPublicComponent;
61 * DoPhase computes the phase wise shared secret, It requires 1st party private key and 2nd Party public key to generate shared secret.
62 * Do phase is used in KEA like algorithm and for multiparty key exchange.*/
64 KeaKeyExchange::DoPhase(Tizen::Security::IPrivateKey& privateKey, Tizen::Security::IPublicKey& publicKey)
68 SysTryReturn(NID_SEC_CRYPTO, &privateKey != null && &publicKey != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The input privatekey and publickey values should be valid.");
70 delete __pPublicComponent;
72 __pPublicComponent = publicKey.GetEncodedN();
73 SysTryReturn(NID_SEC_CRYPTO, __pPublicComponent != null, GetLastResult(), GetLastResult(), "[%s] Failed to get public key", GetErrorMessage(GetLastResult()));
75 delete __pPrivateComponent;
77 __pPrivateComponent = privateKey.GetEncodedN();
78 SysTryCatch(NID_SEC_CRYPTO, __pPrivateComponent != null, r = GetLastResult(), GetLastResult(), "[%s] Failed to get private key", GetErrorMessage(GetLastResult()));
83 delete __pPublicComponent;
84 __pPublicComponent = null;
90 KeaKeyExchange::Construct(const Tizen::Security::IKeyParameters& keyParameters)
93 KeaKeyParameters* pKeaParams = null;
95 SysAssertf(__pParamsP == null && __pParamsG == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class");
97 pKeaParams = const_cast< KeaKeyParameters* >(dynamic_cast< const KeaKeyParameters* >(&keyParameters));
98 SysTryReturn(NID_SEC_CRYPTO, pKeaParams != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The kea key parameters value should be valid.");
100 __pParamsP = pKeaParams->GetParameterValueN(KEY_PARAMETER_KEA_P);
101 SysTryReturn(NID_SEC_CRYPTO, __pParamsP != null, GetLastResult(), GetLastResult(), "[%s] Failed to get prime number", GetErrorMessage(GetLastResult()));
103 __pParamsG = pKeaParams->GetParameterValueN(KEY_PARAMETER_KEA_G);
104 SysTryCatch(NID_SEC_CRYPTO, __pParamsG != null, r = GetLastResult(), GetLastResult(), "[%s] Failed to get generator number", GetErrorMessage(GetLastResult()));
116 KeaKeyExchange::GenerateSecretN(Tizen::Security::IPrivateKey& privateKey, Tizen::Security::IPublicKey& publicKey)
118 result r = E_SUCCESS;
119 int outLen = _SKIPJACK_KEY_LENGTH;
121 byte* pKeaPreMasterSecretValue = null;
122 std::unique_ptr<byte[]> pKeaPreMasterSecret(null);
123 std::unique_ptr<ByteBuffer> pOutput(null);
125 BIGNUM* pKeaPuKey1 = null;
126 BIGNUM* pKeaPuKey2 = null;
130 SysAssertf(__pParamsP != null && __pParamsG != null && __pPrivateComponent != null && __pPublicComponent != null,
131 "Not yet constructed. Construct() and DoPhase() should be called before use.");
133 std::unique_ptr<ByteBuffer> pPrivateComponent(privateKey.GetEncodedN());
134 SysTryReturn(NID_SEC_CRYPTO, pPrivateComponent != null, null, GetLastResult(), "[%s] Failed to fill private key buffer.", GetErrorMessage(GetLastResult()));
136 std::unique_ptr<ByteBuffer> pPublicComponent(publicKey.GetEncodedN());
137 SysTryReturn(NID_SEC_CRYPTO, pPublicComponent != null, null, GetLastResult(), "[%s] Failed to fill public key buffer.", GetErrorMessage(GetLastResult()));
139 sizeParams = pPrivateComponent->GetRemaining();
141 pKea = _KeaCore::CreateKeaN();
142 SysTryCatch(NID_SEC_CRYPTO, pKea != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
144 pKea->pP = BN_bin2bn(__pParamsP->GetPointer(), __pParamsP->GetRemaining(), NULL);
145 SysTryCatch(NID_SEC_CRYPTO, pKea->pP != null, r = E_SYSTEM, E_SYSTEM, "E_SYSTEM] An unexpected system error occurred.");
147 pKea->pG = BN_bin2bn(__pParamsG->GetPointer(), __pParamsG->GetRemaining(), NULL);
148 SysTryCatch(NID_SEC_CRYPTO, pKea->pG != null, r = E_SYSTEM, E_SYSTEM, "E_SYSTEM] An unexpected system error occurred.");
150 pKea->length = sizeParams * _BITS_IN_BYTE;
152 pKea->pPrivKey1 = BN_bin2bn(pPrivateComponent->GetPointer(), pPrivateComponent->GetRemaining(), NULL);
153 SysTryCatch(NID_SEC_CRYPTO, pKea->pPrivKey1 != null, r = E_SYSTEM, E_SYSTEM, "E_SYSTEM] An unexpected system error occurred.");
155 pKea->pPrivKey2 = BN_bin2bn(__pPrivateComponent->GetPointer(), __pPrivateComponent->GetRemaining(), NULL);
156 SysTryCatch(NID_SEC_CRYPTO, pKea->pPrivKey2 != null, r = E_SYSTEM, E_SYSTEM, "E_SYSTEM] An unexpected system error occurred.");
158 pKeaPuKey1 = BN_bin2bn(pPublicComponent->GetPointer(), pPublicComponent->GetRemaining(), NULL);
159 SysTryCatch(NID_SEC_CRYPTO, pKeaPuKey1 != null, r = E_SYSTEM, E_SYSTEM, "E_SYSTEM] An unexpected system error occurred.");
161 pKeaPuKey2 = BN_bin2bn(__pPublicComponent->GetPointer(), __pPublicComponent->GetRemaining(), NULL);
162 SysTryCatch(NID_SEC_CRYPTO, pKeaPuKey2 != null, r = E_SYSTEM, E_SYSTEM, "E_SYSTEM] An unexpected system error occurred.");
164 r = _KeaCore::ComputeKeaKey(&pKeaPreMasterSecretValue, pKeaPuKey1, pKeaPuKey2, *pKea);
165 pKeaPreMasterSecret = std::unique_ptr<byte[]> (pKeaPreMasterSecretValue);
167 SysTryCatch(NID_SEC_CRYPTO, pKeaPreMasterSecret != null && !IsFailed(r), , r, "[%s] Failed to call kea compute key.", GetErrorMessage(r));
169 pOutput = std::unique_ptr<ByteBuffer> (new (std::nothrow) ByteBuffer());
170 SysTryCatch(NID_SEC_CRYPTO, pOutput != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
172 r = pOutput->Construct(outLen);
173 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
175 r = pOutput->SetArray(pKeaPreMasterSecret.get(), 0, outLen);
176 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
184 pOutput.reset(null);;
189 _KeaCore::DeleteKea(pKea);
192 return pOutput.release();
195 } } } //Tizen::Security::Crypto