replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / sample / hw_emul / hw_interface.c
1 /* *****************************************************************\r
2  *\r
3  * Copyright 2017 Samsung Electronics All Rights Reserved.\r
4  *\r
5  *\r
6  *\r
7  * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * you may not use this file except in compliance with the License.\r
9  * You may obtain a copy of the License at\r
10  *\r
11  *     http://www.apache.org/licenses/LICENSE-2.0\r
12  *\r
13  * Unless required by applicable law or agreed to in writing, software\r
14  * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * See the License for the specific language governing permissions and\r
17  * limitations under the License.\r
18  *\r
19  * *****************************************************************/\r
20 \r
21 #include <stdio.h>\r
22 #include <string.h>\r
23 \r
24 #include "ocstack.h"\r
25 #include "oic_malloc.h"\r
26 #include "logger.h"\r
27 #include "mbedtls/pk_internal.h"\r
28 #include "hw_interface.h"\r
29 \r
30 \r
31 #define TAG "OIC_HWIF"\r
32 \r
33 #define HWIF_KEY_DEFAULT_ALIAS "HW_KEY_DEFAULT"\r
34 #define HWIF_KEY_CONTEXT HWIF_KEY_DEFAULT_ALIAS\r
35 #define HWIF_RSA_ALIAS HWIF_KEY_DEFAULT_ALIAS\r
36 \r
37 // own cert chain cache\r
38 uint8_t* g_ownCert = NULL;\r
39 size_t g_ownCertLen = 0;\r
40 \r
41 /********************************************\r
42  * RSA alternative functions\r
43  */\r
44 \r
45 static int RsaDecryptAlt(void *ctx, int mode, size_t *olen,\r
46                                     const unsigned char *input, unsigned char *output,\r
47                                     size_t output_max_len )\r
48 {\r
49     (void)ctx;\r
50     (void)mode;\r
51     (void)olen;\r
52     (void)input;\r
53     (void)output;\r
54     (void)output_max_len;\r
55 \r
56     OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
57     OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
58     return 0;\r
59 }\r
60 \r
61 static int RsaSignAlt(void *ctx,\r
62                                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,\r
63                                     int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,\r
64                                     const unsigned char *hash, unsigned char *sig )\r
65 {\r
66     OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
67 \r
68     if(!ctx || 0 != strncmp((const char*)(ctx), HWIF_RSA_ALIAS, strlen(HWIF_RSA_ALIAS)))\r
69     {\r
70         OIC_LOG(ERROR, TAG, "Invalid paramters, ctx must has same key id");\r
71         OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
72         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;\r
73     }\r
74 \r
75     if(mode != MBEDTLS_RSA_PRIVATE)\r
76     {\r
77         OIC_LOG(ERROR, TAG, "Invalid mode requested");\r
78         OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
79         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;\r
80     }\r
81 \r
82     // RSA encryption with hw stored private key\r
83     int ret = SSemulRsaSign(ctx, f_rng, p_rng, mode, md_alg, hashlen, hash, sig);\r
84     if(0 != ret )\r
85     {\r
86         OIC_LOG_V(ERROR, TAG, "Fail to RSA sign [0x%x]", ret);\r
87         goto exit;\r
88     }\r
89     OIC_LOG_V(INFO, TAG, "Success to RSA sign");\r
90 \r
91 exit:\r
92     OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
93     return ret;\r
94 }\r
95 \r
96 static size_t RsaKeyLen( void *ctx )\r
97 {\r
98     OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
99 \r
100     if(!ctx || 0 != strncmp((const char*)(ctx), HWIF_RSA_ALIAS, strlen(HWIF_RSA_ALIAS)))\r
101     {\r
102         OIC_LOG(ERROR, TAG, "Invalid paramters, ctx must has same key id");\r
103         OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
104         return 0;\r
105     }\r
106 \r
107     // Load private key length from HW Secure Storage\r
108     int ret = SSemulGetKeylen(ctx);\r
109     if (0 >= ret)\r
110     {\r
111         OIC_LOG_V(ERROR, TAG, "Fail to load key length [0x%x]", ret);\r
112         goto exit;\r
113     }\r
114 \r
115     OIC_LOG_V(INFO, TAG, "key length : %d", ret);\r
116 \r
117 exit:\r
118     OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
119     return (size_t)ret;\r
120 }\r
121 \r
122 \r
123 /********************************************\r
124  * ECDSA alternative functions\r
125  */\r
126 \r
127 static int EcdsaSignAlt( void *ctx, mbedtls_md_type_t md_alg,\r
128                    const unsigned char *hash, size_t hash_len,\r
129                    unsigned char *sig, size_t *sig_len,\r
130                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )\r
131 {\r
132     (void)ctx;\r
133     OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
134 \r
135     OIC_LOG_V(ERROR, TAG, "hash_len : %zu md_alg : %d", hash_len, md_alg);\r
136 \r
137     // ECDSA signing with hw stored private key\r
138     int ret = SSemulEcdsaSign(ctx, md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng);\r
139     if(0 != ret )\r
140     {\r
141         OIC_LOG_V(ERROR, TAG, "Fail to ECDSA sign [0x%x]", ret);\r
142         goto exit;\r
143     }\r
144     OIC_LOG_V(INFO, TAG, "Success to ECDSA sign");\r
145 \r
146     OIC_LOG_V(DEBUG, TAG, "# [hash - %zu bytes] #", hash_len);\r
147     OIC_LOG_BUFFER(DEBUG, TAG, hash, hash_len);\r
148     OIC_LOG_V(DEBUG, TAG, "# [signature - %zu bytes] #", *sig_len);\r
149     OIC_LOG_BUFFER(DEBUG, TAG, sig, *sig_len);\r
150 \r
151 exit:\r
152     OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
153     return ret;\r
154 }\r
155 \r
156 \r
157 /********************************************\r
158  * mbedtls pk setup fucntions\r
159  */\r
160 \r
161 int SetupRSAContext(mbedtls_pk_context* ctx, void* key_context)\r
162 {\r
163     OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
164     int ret = HWIF_SUCCESS;\r
165 \r
166     if(NULL == ctx || NULL == key_context)\r
167     {\r
168         OIC_LOG(ERROR, TAG, "Invalid input parameters.");\r
169         ret = HWIF_ERR_INVALID_PARAM;\r
170         goto exit;\r
171     }\r
172 \r
173     ret = mbedtls_pk_setup_rsa_alt( ctx, HWIF_RSA_ALIAS,\r
174                             RsaDecryptAlt, RsaSignAlt, RsaKeyLen);\r
175     if(0 != ret)\r
176     {\r
177         OIC_LOG_V(ERROR, TAG, "Failed to setup rsa alt [%d]", ret);\r
178         ret = HWIF_ERROR;\r
179         goto exit;\r
180     }\r
181 \r
182     OIC_LOG(INFO, TAG, "Success to setup RSA alt");\r
183 \r
184 exit:\r
185     OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
186     return ret;\r
187 }\r
188 \r
189 int SetupECDSAContext(mbedtls_pk_context* ctx, void* key_context)\r
190 {\r
191     OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
192     int ret = HWIF_SUCCESS;\r
193 \r
194     if(NULL == ctx || NULL == key_context)\r
195     {\r
196         OIC_LOG(ERROR, TAG, "Invalid input parameters.");\r
197         ret = HWIF_ERR_INVALID_PARAM;\r
198         goto exit;\r
199     }\r
200 \r
201     // get mbedtls ecdsa structure\r
202     const mbedtls_pk_info_t *mbedtls_ec_info;\r
203     static mbedtls_pk_info_t ec_info;\r
204 \r
205     mbedtls_ec_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);\r
206     if (NULL == mbedtls_ec_info)\r
207     {\r
208         OIC_LOG(ERROR, TAG, "mbedtls_pk_info_from_type error");\r
209         ret = HWIF_ERROR;\r
210         goto exit;\r
211     }\r
212 \r
213     // set hw sign function\r
214     ec_info = *mbedtls_ec_info;\r
215     ec_info.sign_func = EcdsaSignAlt;\r
216     if (0 != mbedtls_pk_setup(ctx, &ec_info))\r
217     {\r
218         OIC_LOG(ERROR, TAG, "mbedtls_pk_setup error");\r
219         ret = HWIF_ERROR;\r
220         goto exit;\r
221     }\r
222 \r
223     OIC_LOG(INFO, TAG, "Success to setup ECDSA alt");\r
224 \r
225 exit:\r
226     OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
227     return ret;\r
228 }\r
229 \r
230 /********************************************\r
231  * HW interface callback functions\r
232  */\r
233 \r
234 void* HWGetKeyContext(const char* service, const char* usage, const char* keytype)\r
235 {\r
236     (void)keytype;\r
237 \r
238     OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
239     if(NULL == service || NULL == usage)\r
240     {\r
241         OIC_LOG(ERROR, TAG, "Invalid input parameters. service and usage should be not NULL.");\r
242         return NULL;\r
243     }\r
244 \r
245     // Implementation should return allocated key context depend on hw library\r
246     // key context is related to service, usage and keytype(optional), which is same with alias name.\r
247     // As for now, Iotivity stack is defining following the service and the usage as a default.\r
248     // Refer to pkix_interface.h file\r
249       // #define HWKEY_SVC_IOTIVITY "iotivity"\r
250       // #define HWKEY_USAGE_PRIMARY "primary"\r
251 \r
252     OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
253     return (void*)HWIF_KEY_CONTEXT;\r
254 }\r
255 \r
256 int HWFreeKeyContext(void* keyContext)\r
257 {\r
258     OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
259     if(NULL == keyContext)\r
260     {\r
261         OIC_LOG(ERROR, TAG, "key context value is NULL.");\r
262         return HWIF_ERR_INVALID_PARAM;\r
263     }\r
264 \r
265     // Implementation should free key context memory if allocated\r
266     if (g_ownCert)\r
267     {\r
268         OICFree(g_ownCert);\r
269         g_ownCert = NULL;\r
270     }\r
271     g_ownCertLen = 0;\r
272 \r
273     OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
274     return HWIF_SUCCESS;\r
275 }\r
276 \r
277 int HWGetOwnCertificateChain(const void* keyContext,\r
278                     uint8_t** cert_chain, size_t* cert_chain_len)\r
279 {\r
280     OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
281     int ret = HWIF_SUCCESS;\r
282 \r
283     if(NULL == keyContext || NULL == cert_chain || NULL == cert_chain_len)\r
284     {\r
285         OIC_LOG(ERROR, TAG, "Invalid input parameters.");\r
286         ret = HWIF_ERR_INVALID_PARAM;\r
287         goto exit;\r
288     }\r
289 \r
290     if (g_ownCert && 0 < g_ownCertLen)\r
291     {\r
292         // Load own certificate from cache\r
293         *cert_chain = g_ownCert;\r
294         *cert_chain_len = g_ownCertLen;\r
295         OIC_LOG(DEBUG, TAG, "Load from the cache");\r
296     }\r
297     else\r
298     {\r
299         // Load own certificate from HW Secure Storage\r
300         ret = SSemulLoadOwncert(keyContext, cert_chain, cert_chain_len);\r
301         if (0 != ret)\r
302         {\r
303             OIC_LOG(ERROR, TAG, "Failed to load the own certificate from Secure Storage");\r
304             ret = HWIF_ERROR;\r
305             goto exit;\r
306         }\r
307 \r
308         // Save to cache\r
309         g_ownCert = *cert_chain;\r
310         g_ownCertLen = *cert_chain_len;\r
311     }\r
312 \r
313     OIC_LOG_V(DEBUG, TAG, "cert chain size : %zu", *cert_chain_len);\r
314 \r
315 exit:\r
316     OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
317     return ret;\r
318 }\r
319 \r
320 int HWSetupPkContext(mbedtls_pk_context* ctx, void* key_context)\r
321 {\r
322     OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
323     int ret = HWIF_SUCCESS;\r
324 \r
325     if(NULL == ctx || NULL == key_context)\r
326     {\r
327         OIC_LOG(ERROR, TAG, "Invalid input parameters.");\r
328         ret = HWIF_ERR_INVALID_PARAM;\r
329         goto exit;\r
330     }\r
331 \r
332     int keytype = SSemulGetKeytype(key_context);\r
333     if (KEYTYPE_RSA == keytype)\r
334     {\r
335         ret = SetupRSAContext(ctx, key_context);\r
336     }\r
337     else if (KEYTYPE_ECC == keytype)\r
338     {\r
339         ret = SetupECDSAContext(ctx, key_context);\r
340     }\r
341 \r
342 exit:\r
343     OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
344     return ret;\r
345 }\r
346 \r
347 \r
348 \r