Imported Upstream version 1.1.0
[platform/upstream/iotivity.git] / resource / csdk / security / src / oxmpincommon.c
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include <memory.h>
22
23 #include "ocstack.h"
24 #include "ocrandom.h"
25 #include "logger.h"
26 #include "pinoxmcommon.h"
27 #include "pbkdf2.h"
28 #include "securevirtualresourcetypes.h"
29
30 #define TAG "PIN_OXM_COMMON"
31
32 static GeneratePinCallback gGenPinCallback = NULL;
33 static InputPinCallback gInputPinCallback = NULL;
34
35 typedef struct PinOxmData {
36     uint8_t pinData[OXM_RANDOM_PIN_SIZE + 1];
37     OicUuid_t newDevice;
38 }PinOxmData_t;
39
40 static PinOxmData_t g_PinOxmData;
41
42
43 void SetInputPinCB(InputPinCallback pinCB)
44 {
45     if(NULL == pinCB)
46     {
47         OIC_LOG(ERROR, TAG, "Failed to set callback for input pin.");
48         return;
49     }
50
51     gInputPinCallback = pinCB;
52 }
53
54 void SetGeneratePinCB(GeneratePinCallback pinCB)
55 {
56     if(NULL == pinCB)
57     {
58         OIC_LOG(ERROR, TAG, "Failed to set callback for generate pin.");
59         return;
60     }
61
62     gGenPinCallback = pinCB;
63 }
64
65 OCStackResult GeneratePin(char* pinBuffer, size_t bufferSize)
66 {
67     if(!pinBuffer)
68     {
69         OIC_LOG(ERROR, TAG, "PIN buffer is NULL");
70         return OC_STACK_INVALID_PARAM;
71     }
72     if(OXM_RANDOM_PIN_SIZE + 1 > bufferSize)
73     {
74         OIC_LOG(ERROR, TAG, "PIN buffer size is too small");
75         return OC_STACK_INVALID_PARAM;
76     }
77     for(size_t i = 0; i < OXM_RANDOM_PIN_SIZE; i++)
78     {
79         pinBuffer[i] = OCGetRandomRange((uint32_t)'0', (uint32_t)'9');
80         g_PinOxmData.pinData[i] = pinBuffer[i];
81     }
82     pinBuffer[OXM_RANDOM_PIN_SIZE] = '\0';
83     g_PinOxmData.pinData[OXM_RANDOM_PIN_SIZE] = '\0';
84
85     if(gGenPinCallback)
86     {
87         gGenPinCallback(pinBuffer, OXM_RANDOM_PIN_SIZE);
88     }
89     else
90     {
91         OIC_LOG(ERROR, TAG, "Invoke PIN callback failed!");
92         OIC_LOG(ERROR, TAG, "Callback for genrate PIN should be registered to use PIN based OxM.");
93         return OC_STACK_ERROR;
94     }
95
96     return OC_STACK_OK;
97 }
98
99
100 OCStackResult InputPin(char* pinBuffer, size_t bufferSize)
101 {
102     if(!pinBuffer)
103     {
104         OIC_LOG(ERROR, TAG, "PIN buffer is NULL");
105         return OC_STACK_INVALID_PARAM;
106     }
107     if(OXM_RANDOM_PIN_SIZE + 1 > bufferSize)
108     {
109         OIC_LOG(ERROR, TAG, "PIN buffer size is too small");
110         return OC_STACK_INVALID_PARAM;
111     }
112
113     if(gInputPinCallback)
114     {
115         gInputPinCallback(pinBuffer, OXM_RANDOM_PIN_SIZE + 1);
116         memcpy(g_PinOxmData.pinData, pinBuffer, OXM_RANDOM_PIN_SIZE);
117         g_PinOxmData.pinData[OXM_RANDOM_PIN_SIZE] = '\0';
118     }
119     else
120     {
121         OIC_LOG(ERROR, TAG, "Invoke PIN callback failed!");
122         OIC_LOG(ERROR, TAG, "Callback for input PIN should be registered to use PIN based OxM.");
123         return OC_STACK_ERROR;
124     }
125
126     return OC_STACK_OK;
127 }
128
129 #ifdef __WITH_DTLS__
130
131 void SetUuidForRandomPinOxm(const OicUuid_t* uuid)
132 {
133     if(NULL != uuid)
134     {
135         memcpy(g_PinOxmData.newDevice.id, uuid->id, UUID_LENGTH);
136     }
137 }
138
139 int32_t GetDtlsPskForRandomPinOxm( CADtlsPskCredType_t type,
140               const unsigned char *UNUSED1, size_t UNUSED2,
141               unsigned char *result, size_t result_length)
142 {
143     int32_t ret = -1;
144
145     (void)UNUSED1;
146     (void)UNUSED2;
147
148     if (NULL == result || result_length < OWNER_PSK_LENGTH_128)
149     {
150         return ret;
151     }
152
153     switch (type)
154     {
155         case CA_DTLS_PSK_HINT:
156         case CA_DTLS_PSK_IDENTITY:
157             /**
158              * The server will provide PSK hint to identify PSK according to RFC 4589 and RFC 4279.
159              *
160              * At this point, The server generate random hint and
161              * provide it to client through server key exchange message.
162              */
163             OCFillRandomMem(result, result_length);
164             ret = result_length;
165
166             OIC_LOG(DEBUG, TAG, "PSK HINT : ");
167             OIC_LOG_BUFFER(DEBUG, TAG, result, result_length);
168             break;
169
170         case CA_DTLS_PSK_KEY:
171             {
172                 int dtlsRes = DeriveCryptoKeyFromPassword(
173                                                           (const unsigned char *)g_PinOxmData.pinData,
174                                                           OXM_RANDOM_PIN_SIZE,
175                                                           g_PinOxmData.newDevice.id,
176                                                           UUID_LENGTH, PBKDF_ITERATIONS,
177                                                           OWNER_PSK_LENGTH_128, (uint8_t*)result);
178
179                 OIC_LOG_V(DEBUG, TAG, "DeriveCryptoKeyFromPassword Completed (%d)", dtlsRes);
180                 OIC_LOG_V(DEBUG, TAG, "PIN : %s", g_PinOxmData.pinData);
181                 OIC_LOG(DEBUG, TAG, "UUID : ");
182                 OIC_LOG_BUFFER(DEBUG, TAG, g_PinOxmData.newDevice.id, UUID_LENGTH);
183
184                 if(0 == dtlsRes)
185                 {
186                     ret = OWNER_PSK_LENGTH_128;
187                 }
188                 else
189                 {
190                     OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result=%d", dtlsRes);
191                     ret = -1;
192                 }
193             }
194             break;
195
196         default:
197             {
198                 OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
199                 ret = -1;
200             }
201             break;
202     }
203
204     return ret;
205 }
206 #endif //__WITH_DTLS__