1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 #include "dev_bind_internal.h"
5 
6 #define AWSS_DEV_RAND_SIGN_FMT \
7     ",\"random\":\"%s\",\"signMethod\":%d,\"sign\":\"%s\""
8 #define AWSS_DEV_BIND_TOKEN_FMT \
9     ",\"token\":\"%s\",\"remainTime\":%d,\"type\":%d"
10 #define AWSS_SUCCESS_FMT ",\"type\":%d"
11 #define AWSS_DEV_INFO_FMT                                                    \
12     "\"awssVer\":%s,\"productKey\":\"%s\",\"deviceName\":\"%s\",\"mac\":\"%" \
13     "s\",\"ip\":\"%s\",\"cipherType\":%d"
14 
15 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
16 extern "C" {
17 #endif
18 
bind_get_encrypt_type()19 static inline int bind_get_encrypt_type()
20 {
21     return 3;
22 }
23 
awss_get_dev_info(void * dev_info,int len)24 static void *awss_get_dev_info(void *dev_info, int len)
25 {
26     char dev_name[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
27     char mac_str[HAL_MAC_LEN + 1] = { 0 };
28     char pk[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
29     char ip_str[OS_IP_LEN + 1] = { 0 };
30 
31     if (dev_info == NULL || len <= 0) {
32         return NULL;
33     }
34 
35     HAL_GetProductKey(pk);
36     HAL_GetDeviceName(dev_name);
37     os_wifi_get_mac_str(mac_str);
38     HAL_Wifi_Get_IP(ip_str, NULL);
39     HAL_Snprintf(dev_info, len - 1, AWSS_DEV_INFO_FMT, AWSS_VER, pk, dev_name,
40                  mac_str, ip_str, bind_get_encrypt_type());
41 
42     return dev_info;
43 }
44 
awss_build_dev_info(int type,void * dev_info,int info_len)45 void *awss_build_dev_info(int type, void *dev_info, int info_len)
46 {
47     int len = 0;
48     char *buf = NULL;
49 
50     if (dev_info == NULL || info_len <= 0) {
51         return NULL;
52     }
53 
54     buf = awss_zalloc(DEV_INFO_LEN_MAX);
55     if (buf == NULL) {
56         return NULL;
57     }
58 
59     len += HAL_Snprintf((char *)dev_info + len, info_len - len - 1, "%s",
60                         (char *)awss_get_dev_info(buf, DEV_INFO_LEN_MAX));
61     HAL_Free(buf);
62     buf = NULL;
63 
64     switch (type) {
65     case AWSS_NOTIFY_DEV_BIND_TOKEN:
66         {
67             char rand_str[(RANDOM_MAX_LEN << 1) + 1] = { 0 };
68             utils_hex_to_str(aes_random, RANDOM_MAX_LEN, rand_str,
69                              sizeof(rand_str));
70             len += HAL_Snprintf((char *)dev_info + len, info_len - len - 1,
71                                 AWSS_DEV_BIND_TOKEN_FMT, rand_str,
72                                 awss_token_remain_time(), 0);
73             break;
74         }
75 #ifdef WIFI_PROVISION_ENABLED
76     case AWSS_NOTIFY_SUCCESS:
77         {
78             len += HAL_Snprintf((char *)dev_info + len, info_len - len - 1,
79                                 AWSS_SUCCESS_FMT, 0);
80             break;
81         }
82     case AWSS_NOTIFY_DEV_RAND_SIGN:
83         {
84             char sign_str[DEV_SIGN_SIZE * 2 + 1] = { 0 };
85             char rand_str[(RANDOM_MAX_LEN << 1) + 1] = { 0 };
86             {
87                 int txt_len = 80;
88                 char txt[80] = { 0 };
89                 char key[IOTX_DEVICE_SECRET_LEN + 1] = { 0 };
90                 uint8_t sign[DEV_SIGN_SIZE + 1] = { 0 };
91 
92                 if (bind_get_encrypt_type() == 3) { /* aes-key per product */
93                     HAL_GetProductSecret(key);
94                 } else { /* aes-key per device */
95                     HAL_GetDeviceSecret(key);
96                 }
97                 awss_build_sign_src(txt, &txt_len);
98                 produce_signature(sign, (uint8_t *)txt, txt_len, key);
99                 utils_hex_to_str(sign, DEV_SIGN_SIZE, sign_str,
100                                  sizeof(sign_str));
101             }
102             utils_hex_to_str(aes_random, RANDOM_MAX_LEN, rand_str,
103                              sizeof(rand_str));
104             len += HAL_Snprintf((char *)dev_info + len, info_len - len - 1,
105                                 AWSS_DEV_RAND_SIGN_FMT, rand_str, 0, sign_str);
106             break;
107         }
108 #endif
109     default:
110         break;
111     }
112 
113     return dev_info;
114 }
115 
116 #ifdef WIFI_PROVISION_ENABLED
awss_build_sign_src(char * sign_src,int * sign_src_len)117 char *awss_build_sign_src(char *sign_src, int *sign_src_len)
118 {
119     char *pk = NULL, *dev_name = NULL;
120     int dev_name_len, pk_len, text_len;
121 
122     if (sign_src == NULL || sign_src_len == NULL) {
123         goto build_sign_src_err;
124     }
125 
126     pk = awss_zalloc(IOTX_PRODUCT_KEY_LEN + 1);
127     dev_name = awss_zalloc(IOTX_DEVICE_NAME_LEN + 1);
128     if (pk == NULL || dev_name == NULL) {
129         goto build_sign_src_err;
130     }
131 
132     HAL_GetProductKey(pk);
133     HAL_GetDeviceName(dev_name);
134 
135     pk_len = strlen(pk);
136     dev_name_len = strlen(dev_name);
137 
138     text_len = RANDOM_MAX_LEN + dev_name_len + pk_len;
139     if (*sign_src_len < text_len) {
140         goto build_sign_src_err;
141     }
142 
143     *sign_src_len = text_len;
144 
145     memcpy(sign_src, aes_random, RANDOM_MAX_LEN);
146     memcpy(sign_src + RANDOM_MAX_LEN, dev_name, dev_name_len);
147     memcpy(sign_src + RANDOM_MAX_LEN + dev_name_len, pk, pk_len);
148 
149     HAL_Free(pk);
150     HAL_Free(dev_name);
151 
152     return sign_src;
153 
154 build_sign_src_err:
155     if (pk) {
156         HAL_Free(pk);
157     }
158     if (dev_name) {
159         HAL_Free(dev_name);
160     }
161     return NULL;
162 }
163 #endif
awss_build_topic(const char * topic_fmt,char * topic,uint32_t tlen)164 const char *awss_build_topic(const char *topic_fmt, char *topic, uint32_t tlen)
165 {
166     char pk[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
167     char dev_name[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
168     if (topic == NULL || topic_fmt == NULL || tlen == 0) {
169         return NULL;
170     }
171 
172     HAL_GetProductKey(pk);
173     HAL_GetDeviceName(dev_name);
174 
175     HAL_Snprintf(topic, tlen - 1, topic_fmt, pk, dev_name);
176 
177     return topic;
178 }
179 
awss_build_packet(int type,void * id,void * ver,void * method,void * data,int code,void * packet,int * packet_len)180 int awss_build_packet(int type, void *id, void *ver, void *method, void *data,
181                       int code, void *packet, int *packet_len)
182 {
183     int len;
184     if (packet_len == NULL || data == NULL || packet == NULL) {
185         return -1;
186     }
187 
188     len = *packet_len;
189     if (len <= 0) {
190         return -1;
191     }
192 
193     if (type == AWSS_CMP_PKT_TYPE_REQ) {
194         if (ver == NULL || method == NULL) {
195             return -1;
196         }
197 
198         len = HAL_Snprintf(packet, len - 1, AWSS_REQ_FMT, (char *)id,
199                            (char *)ver, (char *)method, (char *)data);
200         return 0;
201     } else if (type == AWSS_CMP_PKT_TYPE_RSP) {
202         len = HAL_Snprintf(packet, len - 1, AWSS_ACK_FMT, (char *)id, code,
203                            (char *)data);
204         return 0;
205     }
206     return -1;
207 }
208 
produce_random(uint8_t * random,uint32_t len)209 void produce_random(uint8_t *random, uint32_t len)
210 {
211     int i = 0;
212     int time = HAL_UptimeMs();
213     HAL_Srandom(time);
214     for (i = 0; i < len; i++) {
215         random[i] = HAL_Random(0xFF);
216     }
217 }
218 
219 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
220 }
221 #endif
222