1 /* *****************************************************************
\r
3 * Copyright 2017 Samsung Electronics All Rights Reserved.
\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
11 * http://www.apache.org/licenses/LICENSE-2.0
\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
19 * *****************************************************************/
\r
24 #include "ocstack.h"
\r
25 #include "oic_malloc.h"
\r
27 #include "mbedtls/pk_internal.h"
\r
28 #include "hw_interface.h"
\r
31 #define TAG "OIC_HWIF"
\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
37 // own cert chain cache
\r
38 uint8_t* g_ownCert = NULL;
\r
39 size_t g_ownCertLen = 0;
\r
41 /********************************************
\r
42 * RSA alternative functions
\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
54 (void)output_max_len;
\r
56 OIC_LOG_V(INFO, TAG, "In %s", __func__);
\r
57 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
\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
66 OIC_LOG_V(INFO, TAG, "In %s", __func__);
\r
68 if(!ctx || 0 != strncmp((const char*)(ctx), HWIF_RSA_ALIAS, strlen(HWIF_RSA_ALIAS)))
\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
75 if(mode != MBEDTLS_RSA_PRIVATE)
\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
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
86 OIC_LOG_V(ERROR, TAG, "Fail to RSA sign [0x%x]", ret);
\r
89 OIC_LOG_V(INFO, TAG, "Success to RSA sign");
\r
92 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
\r
96 static size_t RsaKeyLen( void *ctx )
\r
98 OIC_LOG_V(INFO, TAG, "In %s", __func__);
\r
100 if(!ctx || 0 != strncmp((const char*)(ctx), HWIF_RSA_ALIAS, strlen(HWIF_RSA_ALIAS)))
\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
107 // Load private key length from HW Secure Storage
\r
108 int ret = SSemulGetKeylen(ctx);
\r
111 OIC_LOG_V(ERROR, TAG, "Fail to load key length [0x%x]", ret);
\r
115 OIC_LOG_V(INFO, TAG, "key length : %d", ret);
\r
118 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
\r
119 return (size_t)ret;
\r
123 /********************************************
\r
124 * ECDSA alternative functions
\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
133 OIC_LOG_V(INFO, TAG, "In %s", __func__);
\r
135 OIC_LOG_V(ERROR, TAG, "hash_len : %zu md_alg : %d", hash_len, md_alg);
\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
141 OIC_LOG_V(ERROR, TAG, "Fail to ECDSA sign [0x%x]", ret);
\r
144 OIC_LOG_V(INFO, TAG, "Success to ECDSA sign");
\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
152 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
\r
157 /********************************************
\r
158 * mbedtls pk setup fucntions
\r
161 int SetupRSAContext(mbedtls_pk_context* ctx, void* key_context)
\r
163 OIC_LOG_V(INFO, TAG, "In %s", __func__);
\r
164 int ret = HWIF_SUCCESS;
\r
166 if(NULL == ctx || NULL == key_context)
\r
168 OIC_LOG(ERROR, TAG, "Invalid input parameters.");
\r
169 ret = HWIF_ERR_INVALID_PARAM;
\r
173 ret = mbedtls_pk_setup_rsa_alt( ctx, HWIF_RSA_ALIAS,
\r
174 RsaDecryptAlt, RsaSignAlt, RsaKeyLen);
\r
177 OIC_LOG_V(ERROR, TAG, "Failed to setup rsa alt [%d]", ret);
\r
182 OIC_LOG(INFO, TAG, "Success to setup RSA alt");
\r
185 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
\r
189 int SetupECDSAContext(mbedtls_pk_context* ctx, void* key_context)
\r
191 OIC_LOG_V(INFO, TAG, "In %s", __func__);
\r
192 int ret = HWIF_SUCCESS;
\r
194 if(NULL == ctx || NULL == key_context)
\r
196 OIC_LOG(ERROR, TAG, "Invalid input parameters.");
\r
197 ret = HWIF_ERR_INVALID_PARAM;
\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
205 mbedtls_ec_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
\r
206 if (NULL == mbedtls_ec_info)
\r
208 OIC_LOG(ERROR, TAG, "mbedtls_pk_info_from_type error");
\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
218 OIC_LOG(ERROR, TAG, "mbedtls_pk_setup error");
\r
223 OIC_LOG(INFO, TAG, "Success to setup ECDSA alt");
\r
226 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
\r
230 /********************************************
\r
231 * HW interface callback functions
\r
234 void* HWGetKeyContext(const char* service, const char* usage, const char* keytype)
\r
238 OIC_LOG_V(INFO, TAG, "In %s", __func__);
\r
239 if(NULL == service || NULL == usage)
\r
241 OIC_LOG(ERROR, TAG, "Invalid input parameters. service and usage should be not NULL.");
\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
252 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
\r
253 return (void*)HWIF_KEY_CONTEXT;
\r
256 int HWFreeKeyContext(void* keyContext)
\r
258 OIC_LOG_V(INFO, TAG, "In %s", __func__);
\r
259 if(NULL == keyContext)
\r
261 OIC_LOG(ERROR, TAG, "key context value is NULL.");
\r
262 return HWIF_ERR_INVALID_PARAM;
\r
265 // Implementation should free key context memory if allocated
\r
268 OICFree(g_ownCert);
\r
273 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
\r
274 return HWIF_SUCCESS;
\r
277 int HWGetOwnCertificateChain(const void* keyContext,
\r
278 uint8_t** cert_chain, size_t* cert_chain_len)
\r
280 OIC_LOG_V(INFO, TAG, "In %s", __func__);
\r
281 int ret = HWIF_SUCCESS;
\r
283 if(NULL == keyContext || NULL == cert_chain || NULL == cert_chain_len)
\r
285 OIC_LOG(ERROR, TAG, "Invalid input parameters.");
\r
286 ret = HWIF_ERR_INVALID_PARAM;
\r
290 if (g_ownCert && 0 < g_ownCertLen)
\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
299 // Load own certificate from HW Secure Storage
\r
300 ret = SSemulLoadOwncert(keyContext, cert_chain, cert_chain_len);
\r
303 OIC_LOG(ERROR, TAG, "Failed to load the own certificate from Secure Storage");
\r
309 g_ownCert = *cert_chain;
\r
310 g_ownCertLen = *cert_chain_len;
\r
313 OIC_LOG_V(DEBUG, TAG, "cert chain size : %zu", *cert_chain_len);
\r
316 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
\r
320 int HWSetupPkContext(mbedtls_pk_context* ctx, void* key_context)
\r
322 OIC_LOG_V(INFO, TAG, "In %s", __func__);
\r
323 int ret = HWIF_SUCCESS;
\r
325 if(NULL == ctx || NULL == key_context)
\r
327 OIC_LOG(ERROR, TAG, "Invalid input parameters.");
\r
328 ret = HWIF_ERR_INVALID_PARAM;
\r
332 int keytype = SSemulGetKeytype(key_context);
\r
333 if (KEYTYPE_RSA == keytype)
\r
335 ret = SetupRSAContext(ctx, key_context);
\r
337 else if (KEYTYPE_ECC == keytype)
\r
339 ret = SetupECDSAContext(ctx, key_context);
\r
343 OIC_LOG_V(INFO, TAG, "Out %s", __func__);
\r