sync with tizen_2.0
[platform/framework/native/appfw.git] / src / security / crypto / FSecCryptoDhKeyExchange.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  * @file                FSecCryptoDhKeyExchange.cpp
19  * @brief               This file contains the implementation of Tizen::Security::Crypto::DhKeyExchange.
20  *
21  */
22 #include <unique_ptr.h>
23 #include <openssl/dh.h>
24 #include <openssl/bn.h>
25 #include <FBaseResult.h>
26 #include <FBaseErrors.h>
27 #include <FSecDhKeyParameters.h>
28 #include <FSecCryptoDhKeyExchange.h>
29 #include <FSecKeyPairGenerator.h>
30 #include <FBaseSysLog.h>
31
32 using namespace Tizen::Base;
33 using namespace Tizen::Security;
34
35
36 namespace Tizen { namespace Security { namespace Crypto
37 {
38 static const int _BITS_IN_BYTE = 8;
39
40 DhKeyExchange::DhKeyExchange(void)
41         : __pParamsP(null)
42         , __pParamsG(null)
43         , __pDhKeyExchangeImpl(null)
44 {
45
46 }
47
48 DhKeyExchange::~DhKeyExchange(void)
49 {
50         delete __pParamsP;
51         delete __pParamsG;
52 }
53
54 result
55 DhKeyExchange::Construct(const Tizen::Security::IKeyParameters& keyParameters)
56 {
57         result r = E_SUCCESS;
58         DhKeyParameters* pDhParams = null;
59
60         SysAssertf(__pParamsP == null && __pParamsG == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class");
61
62         pDhParams = const_cast< DhKeyParameters* >(dynamic_cast< const DhKeyParameters* >(&keyParameters));
63         SysTryReturn(NID_SEC_CRYPTO, pDhParams != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The dh key parameters value should be valid.");
64
65         //Retreive the value of the parameter 'p' from the instance
66         __pParamsP = pDhParams->GetParameterValueN(KEY_PARAMETER_DH_P);
67         SysTryReturn(NID_SEC_CRYPTO, __pParamsP != null, GetLastResult(), GetLastResult(), "[%s] Failed to get prime number", GetErrorMessage(GetLastResult()));
68
69         //Retreive the value of the parameter 'g' from the instance
70         __pParamsG = pDhParams->GetParameterValueN(KEY_PARAMETER_DH_G);
71         SysTryCatch(NID_SEC_CRYPTO, __pParamsG != null, r = GetLastResult(), GetLastResult(), "[%s] Failed to get generator number", GetErrorMessage(GetLastResult()));
72
73 CATCH:
74         if (IsFailed(r))
75         {
76                 delete __pParamsP;
77                 __pParamsP = null;
78         }
79         return r;
80 }
81
82 ByteBuffer*
83 DhKeyExchange::GenerateSecretN(Tizen::Security::IPrivateKey& privateKey, Tizen::Security::IPublicKey& publicKey)
84 {
85         result r = E_SUCCESS;
86         int outLen = 0;
87         int sizeParams = 0;
88         int sizePreMaster = 0;
89         DH* pDhStx = NULL;
90         BIGNUM* pDhPuKey = null;
91         std::unique_ptr<ByteBuffer> pOutput(null);
92
93         ClearLastResult();
94
95         SysAssertf(__pParamsP != null && __pParamsG != null, "Not yet constructed. Construct() should be called before use.");
96
97         std::unique_ptr<ByteBuffer> pPrivateComponent(privateKey.GetEncodedN());
98         SysTryReturn(NID_SEC_CRYPTO, pPrivateComponent != null, null, GetLastResult(), "[%s] Failed to fill private key buffer.", GetErrorMessage(GetLastResult()));
99
100         std::unique_ptr<ByteBuffer> pPublicComponent(publicKey.GetEncodedN());
101         SysTryReturn(NID_SEC_CRYPTO, pPublicComponent != null, null, GetLastResult(), "[%s] Failed to fill public key buffer.", GetErrorMessage(GetLastResult()));
102
103         sizeParams = pPrivateComponent->GetRemaining();
104         sizePreMaster = __pParamsP->GetRemaining();
105
106         std::unique_ptr<byte[]> pDhPreMasterSecret(new (std::nothrow) byte[sizePreMaster]);
107         SysTryReturn(NID_SEC_CRYPTO, pDhPreMasterSecret != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
108
109         pDhStx = DH_new();
110         SysTryCatch(NID_SEC_CRYPTO, pDhStx != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
111
112         pDhStx->p = BN_bin2bn(__pParamsP->GetPointer(), __pParamsP->GetRemaining(), NULL);
113         SysTryCatch(NID_SEC_CRYPTO, pDhStx->p != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
114
115         pDhStx->g = BN_bin2bn(__pParamsG->GetPointer(), __pParamsG->GetRemaining(), NULL);
116         SysTryCatch(NID_SEC_CRYPTO, pDhStx->g != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
117
118         pDhStx->length = sizeParams * _BITS_IN_BYTE;
119
120         pDhStx->priv_key = BN_bin2bn(pPrivateComponent->GetPointer(), pPrivateComponent->GetRemaining(), NULL);
121         SysTryCatch(NID_SEC_CRYPTO, pDhStx->priv_key != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
122
123         pDhPuKey = BN_bin2bn(pPublicComponent->GetPointer(), pPublicComponent->GetRemaining(), NULL);
124         SysTryCatch(NID_SEC_CRYPTO, pDhPuKey != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
125
126         outLen = DH_compute_key(pDhPreMasterSecret.get(), pDhPuKey, pDhStx);
127         SysTryCatch(NID_SEC_CRYPTO, pDhPreMasterSecret != null && outLen != -1, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
128
129         pOutput = std::unique_ptr<ByteBuffer>(new (std::nothrow) ByteBuffer());
130         SysTryCatch(NID_SEC_CRYPTO, pOutput != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
131
132         r = pOutput->Construct(outLen);
133         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
134
135         r = pOutput->SetArray(pDhPreMasterSecret.get(), 0, outLen);
136         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
137
138         pOutput->Flip();
139
140 CATCH:
141
142         if (IsFailed(r))
143         {
144                 pOutput.reset(null);
145         }
146
147         if (pDhStx != null)
148         {
149                 DH_free(pDhStx);
150         }
151
152         return pOutput.release();
153 }
154
155 } } } //Tizen::Security::Crypto