replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / sample / hw_emul / ss_emul.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 "oic_malloc.h"\r
25 #include "logger.h"\r
26 #include "ss_emul.h"\r
27 \r
28 \r
29 #define TAG "OIC_SSEMUL"\r
30 \r
31 #define HWIF_MAXPATH (4096)\r
32 static char HWIF_OWNCERT_FILE_NAME[HWIF_MAXPATH] = {0,};\r
33 static char HWIF_KEY_FILE_NAME[HWIF_MAXPATH] = {0,};\r
34 static char HWIF_KEY_PASS[HWIF_MAXPATH] = {0,};\r
35 \r
36 \r
37 /********************************************\r
38  * utility functions\r
39  */\r
40 \r
41 int LoadCertFile(const char* filepath, uint8_t** cert_chain, size_t* cert_chain_len)\r
42 {\r
43     if (NULL == filepath || NULL == cert_chain || NULL == cert_chain_len)\r
44     {\r
45         OIC_LOG(ERROR, TAG, "Invalid parameters");\r
46         return -1;\r
47     }\r
48 \r
49     uint8_t *certchain;\r
50     size_t certLen;\r
51 \r
52     FILE *fp = fopen(filepath, "rb");\r
53     if (fp)\r
54     {\r
55         char buffer[1024];\r
56         size_t fsize = 0;\r
57         size_t bytesRead = 0;\r
58         do\r
59         {\r
60             bytesRead = fread(buffer, 1, sizeof(buffer), fp);\r
61             fsize += bytesRead;\r
62         } while (bytesRead);\r
63 \r
64         if (!fsize)\r
65         {\r
66             OIC_LOG(ERROR,TAG,"File is empty");\r
67             fclose(fp);\r
68             return -1;\r
69         }\r
70 \r
71         certchain = (uint8_t*)OICCalloc(1, fsize);\r
72         certLen = fsize;\r
73         if (NULL == certchain)\r
74         {\r
75             OIC_LOG(ERROR,TAG,"Failed to allocate memory");\r
76             fclose(fp);\r
77             return -1;\r
78         }\r
79 \r
80         rewind(fp);\r
81         if (fsize != fread(certchain, 1, fsize, fp))\r
82         {\r
83             OIC_LOG(ERROR, TAG, "Certiface was not read completely");\r
84         }\r
85         fclose(fp);\r
86     }\r
87     else\r
88     {\r
89         OIC_LOG_V(ERROR,TAG,"Failed to open cert file : %s", filepath);\r
90         return -1;\r
91     }\r
92 \r
93     *cert_chain = certchain;\r
94     *cert_chain_len = certLen;\r
95 \r
96     OIC_LOG_V(INFO, TAG, "Loading cert success [%s]", filepath);\r
97     OIC_LOG_BUFFER(DEBUG, TAG, certchain, certLen);\r
98     return 0;\r
99 }\r
100 \r
101 \r
102 int LoadKeyFile(mbedtls_pk_context *pkey, const char* filepath, const char* password)\r
103 {\r
104     if(!filepath)\r
105     {\r
106         OIC_LOG(ERROR, TAG, "Invalid key file path" );\r
107         return -1;\r
108     }\r
109 \r
110     int ret = mbedtls_pk_parse_keyfile(pkey, filepath, password);\r
111     if( ret != 0 )\r
112     {\r
113         OIC_LOG_V(ERROR, TAG, "Faile to parse key file [0x%x]", ret );\r
114         return ret;\r
115     }\r
116 \r
117     OIC_LOG_V(INFO, TAG, "Loading key success [%s]", filepath);\r
118     return ret;\r
119 }\r
120 \r
121 \r
122 /********************************************\r
123  * HW Secure Storage emulation functions\r
124  */\r
125 int SSemulSetCertkeyFilepath(const char* cert_filepath,\r
126                                             const char* key_filepath, const char* pwd)\r
127 {\r
128     if (NULL == cert_filepath || NULL == key_filepath)\r
129     {\r
130         OIC_LOG(ERROR, TAG, "Invalid parameters");\r
131         return -1;\r
132     }\r
133 \r
134     if (HWIF_MAXPATH <= strlen(cert_filepath) || !strlen(cert_filepath)\r
135         || HWIF_MAXPATH <= strlen(key_filepath) || !strlen(key_filepath)\r
136         || (pwd && (HWIF_MAXPATH <= strlen(pwd))))\r
137     {\r
138         OIC_LOG(ERROR, TAG, "Invalid large path length");\r
139         return -1;\r
140     }\r
141 \r
142     memset(HWIF_OWNCERT_FILE_NAME, 0, HWIF_MAXPATH);\r
143     memset(HWIF_KEY_FILE_NAME, 0, HWIF_MAXPATH);\r
144     memset(HWIF_KEY_PASS, 0, HWIF_MAXPATH);\r
145 \r
146     strncpy(HWIF_OWNCERT_FILE_NAME, cert_filepath, strlen(cert_filepath));\r
147     strncpy(HWIF_KEY_FILE_NAME, key_filepath, strlen(key_filepath));\r
148     if (pwd)\r
149     {\r
150         strncpy(HWIF_KEY_PASS, pwd, strlen(pwd) + 1);\r
151     }\r
152 \r
153     OIC_LOG(INFO, TAG, "[Configure Secure Storage Emulation files]");\r
154     OIC_LOG_V(INFO, TAG, "OwnCert file[%zu]: %s", strlen(cert_filepath), cert_filepath);\r
155     OIC_LOG_V(INFO, TAG, "Key file[%zu]: %s", strlen(key_filepath), key_filepath);\r
156     if (pwd)\r
157     {\r
158         OIC_LOG_V(INFO, TAG, "Password[%zu]: %s", strlen(pwd), pwd);\r
159     }\r
160     return 0;\r
161 }\r
162 \r
163 int SSemulGetKeytype(const void* keyContext)\r
164 {\r
165     (void)keyContext;\r
166     if (0 == strlen(HWIF_KEY_FILE_NAME))\r
167     {\r
168         OIC_LOG(ERROR, TAG, "Need to set key file name");\r
169         return KEYTYPE_NONE;\r
170     }\r
171 \r
172     int ret = KEYTYPE_NONE;\r
173     mbedtls_pk_context pk;\r
174     mbedtls_pk_init(&pk);\r
175 \r
176     // 1. load key\r
177     const char* key_file = HWIF_KEY_FILE_NAME;\r
178     const char* key_pass = !strlen(HWIF_KEY_PASS) ? NULL : HWIF_KEY_PASS;\r
179     if (0 > LoadKeyFile(&pk, key_file, key_pass))\r
180     {\r
181         OIC_LOG(ERROR, TAG, "Fail to load key file");\r
182         goto exit;\r
183     }\r
184 \r
185     // 2. get key type\r
186     mbedtls_pk_type_t keytype = mbedtls_pk_get_type(&pk);\r
187     if(MBEDTLS_PK_RSA == keytype)\r
188     {\r
189         ret = KEYTYPE_RSA;\r
190     }\r
191     else if(MBEDTLS_PK_ECKEY == keytype ||\r
192                MBEDTLS_PK_ECKEY_DH == keytype)\r
193     {\r
194         ret = KEYTYPE_ECC;\r
195     }\r
196 \r
197 exit:\r
198     mbedtls_pk_free(&pk);\r
199     return ret;\r
200 }\r
201 \r
202 int SSemulLoadOwncert(const void* keyContext,\r
203                                            uint8_t** cert_chain, size_t* cert_chain_len)\r
204 {\r
205     (void)keyContext;\r
206     if (0 == strlen(HWIF_OWNCERT_FILE_NAME))\r
207     {\r
208         OIC_LOG(ERROR, TAG, "Need to set owncert file name");\r
209         return -1;\r
210     }\r
211 \r
212     if (0 != LoadCertFile(HWIF_OWNCERT_FILE_NAME, cert_chain, cert_chain_len))\r
213     {\r
214         OIC_LOG(ERROR, TAG, "Faile to load the own certificate file");\r
215         return -1;\r
216     }\r
217 \r
218     return 0;\r
219 }\r
220 \r
221 int SSemulGetKeylen(const void* keyContext)\r
222 {\r
223     (void)keyContext;\r
224     if (0 == strlen(HWIF_KEY_FILE_NAME))\r
225     {\r
226         OIC_LOG(ERROR, TAG, "Need to set private key file name");\r
227         return -1;\r
228     }\r
229 \r
230     int ret = -1;\r
231     size_t key_len = 0;\r
232     mbedtls_pk_context pk;\r
233     mbedtls_pk_init(&pk);\r
234 \r
235     // 1. load key\r
236     const char* key_file = HWIF_KEY_FILE_NAME;\r
237     const char* key_pass = !strlen(HWIF_KEY_PASS) ? NULL : HWIF_KEY_PASS;\r
238     ret = LoadKeyFile(&pk, key_file, key_pass);\r
239     if (0 > ret)\r
240     {\r
241         OIC_LOG_V(ERROR, TAG, "Fail to load key file [0x%x]", ret);\r
242         goto exit;\r
243     }\r
244 \r
245     key_len = ( 8 * ((const mbedtls_rsa_context *) pk.pk_ctx)->len );\r
246     if(0 >= key_len)\r
247     {\r
248         OIC_LOG(ERROR, TAG, "Invalid key length");\r
249         goto exit;\r
250     }\r
251 \r
252 exit:\r
253     mbedtls_pk_free(&pk);\r
254     return key_len;\r
255 }\r
256 \r
257 int SSemulRsaSign(const void *keyContext,\r
258                             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,\r
259                             int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,\r
260                             const unsigned char *hash, unsigned char *sig )\r
261 {\r
262     if (0 == strlen(HWIF_KEY_FILE_NAME))\r
263     {\r
264         OIC_LOG(ERROR, TAG, "Need to set private key file name");\r
265         return -1;\r
266     }\r
267 \r
268     // workaround for test under sw - 1. load key, 2. sign\r
269 \r
270     int ret;\r
271     size_t key_len;\r
272     mbedtls_pk_context pk;\r
273     mbedtls_pk_init(&pk);\r
274 \r
275     // 1. load key\r
276     const char* key_file = HWIF_KEY_FILE_NAME;\r
277     const char* key_pass = !strlen(HWIF_KEY_PASS) ? NULL : HWIF_KEY_PASS;\r
278     ret = LoadKeyFile(&pk, key_file, key_pass);\r
279     if (0 > ret)\r
280     {\r
281         OIC_LOG_V(ERROR, TAG, "Fail to load key file [0x%x]", ret);\r
282         goto exit;\r
283     }\r
284 \r
285     key_len = ( 8 * ((const mbedtls_rsa_context *) pk.pk_ctx)->len );\r
286     if(0 >= key_len)\r
287     {\r
288         OIC_LOG(ERROR, TAG, "Invalid key length");\r
289         ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;\r
290         goto exit;\r
291     }\r
292     OIC_LOG_V(INFO, TAG, "key name : %s, mode : %d hashlen : %u md_alg : %d keylen : %zu",\r
293             (const char*)(keyContext), mode, hashlen, md_alg, key_len);\r
294 \r
295     // 2. sign\r
296     ret = mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *)pk.pk_ctx, f_rng, p_rng,\r
297                         MBEDTLS_RSA_PRIVATE, md_alg, (unsigned int) hashlen, hash, sig);\r
298     if(0 != ret )\r
299     {\r
300         OIC_LOG_V(ERROR, TAG, "Fail to sign [0x%x]", ret);\r
301         goto exit;\r
302     }\r
303 \r
304 exit:\r
305     mbedtls_pk_free(&pk);\r
306     return ret;\r
307 }\r
308 \r
309 int SSemulEcdsaSign( void *ctx, mbedtls_md_type_t md_alg,\r
310                    const unsigned char *hash, size_t hash_len,\r
311                    unsigned char *sig, size_t *sig_len,\r
312                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )\r
313 {\r
314     (void)ctx;\r
315     if (0 == strlen(HWIF_KEY_FILE_NAME))\r
316     {\r
317         OIC_LOG(ERROR, TAG, "Need to set private key file name");\r
318         return -1;\r
319     }\r
320 \r
321     // workaround for test under sw  - 1. load key, 2. set temp ctx, 3.sign\r
322 \r
323     int ret;\r
324     mbedtls_pk_context pk;\r
325     mbedtls_ecdsa_context ecdsa;\r
326     mbedtls_ecp_keypair *eckey;\r
327     mbedtls_pk_init(&pk);\r
328     mbedtls_ecdsa_init( &ecdsa );\r
329 \r
330     // 1. load key\r
331     const char* key_file = HWIF_KEY_FILE_NAME;\r
332     const char* key_pass = !strlen(HWIF_KEY_PASS) ? NULL : HWIF_KEY_PASS;\r
333     ret = LoadKeyFile(&pk, key_file, key_pass);\r
334     if (0 > ret)\r
335     {\r
336         OIC_LOG_V(ERROR, TAG, "Fail to load key file [0x%x]", ret);\r
337         goto exit;\r
338     }\r
339 \r
340     // 2. set temp ctx\r
341     eckey = (mbedtls_ecp_keypair*)pk.pk_ctx;\r
342     ret = mbedtls_ecdsa_from_keypair(&ecdsa, eckey);\r
343     if(0 != ret )\r
344     {\r
345         OIC_LOG_V(ERROR, TAG, "Fail to copy key pair [0x%x]", ret);\r
346         goto exit;\r
347     }\r
348 \r
349     // 3. sign\r
350     ret = mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) &ecdsa,\r
351                 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng );\r
352     if(0 != ret )\r
353     {\r
354         OIC_LOG_V(ERROR, TAG, "Fail to sign [0x%x]", ret);\r
355         goto exit;\r
356     }\r
357     OIC_LOG_V(INFO, TAG, "Success to sign");\r
358 \r
359 exit:\r
360     mbedtls_ecdsa_free( &ecdsa );\r
361     mbedtls_pk_free(&pk);\r
362     OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
363     return ret;\r
364 }\r
365 \r
366 \r