1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 
5 #ifndef __AWSS_ENROLLEE_H__
6 #define __AWSS_ENROLLEE_H__
7 
8 #include <stdint.h>
9 #include "linkkit/infra/infra_sha1.h"
10 #include "linkkit/infra/infra_sha256.h"
11 #include "passwd.h"
12 #include "os.h"
13 #include "zconfig_ieee80211.h"
14 
15 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
16 extern "C" {
17 #endif
18 
19 /* enrollee/registrar doc see following
20  * http://docs.alibaba-inc.com/pages/viewpage.action?pageId=450855381
21  */
22 /* ie oui def. */
23 #define WLAN_OUI_ALIBABA        (0xD896E0)
24 #define WLAN_OUI_TYPE_ENROLLEE  (0xAA)
25 #define WLAN_OUI_TYPE_REGISTRAR (0xAB)
26 
27 #define DEVICE_TYPE_VERSION     (1)
28 #define ENROLLEE_FRAME_TYPE     (0)
29 #define REGISTRAR_FRAME_TYPE    (1)
30 #define REGISTRAR_IDLE_DUTY     (0)
31 
32 struct ieee80211_enrollee_alibaba_ie {
33     uint8_t element_id; /* 221 */
34     uint8_t len;        /* len of this struct, exclude element id & len field */
35     uint8_t oui[3];     /* D896E0 */
36     uint8_t oui_type;   /* 0xAA, device request */
37 
38     uint8_t version:4;  /* bit7 - bit4 */
39     uint8_t dev_type:4; /* bit3 - bit0; alink=0, alink_cloud=1, yoc=8 */
40     uint8_t dn_len;       /* device name length*/
41 #ifdef __GNUC__
42     uint8_t dev_name[0]; /* device name, unique name for device */
43 #endif
44     uint8_t frame_type; /* frame_type = 0 */
45 
46     uint8_t pk_len; /* product key length */
47 #ifdef __GNUC__
48     uint8_t pk[0]; /* product key */
49 #endif
50     uint8_t rand_len; /* random length */
51 #ifdef __GNUC__
52     uint8_t random[0]; /* random salt */
53 #endif
54     uint8_t security;    /* securation type, per product(3) or device(4) or
55                             manufacture(5) */
56     uint8_t sign_method; /* 0: hmacsha1, 1:hmacsha256 */
57     uint8_t sign_len;    /* signature length */
58 #ifdef __GNUC__
59     uint8_t sign[0]; /* sign = hmacsha1(secret, random+dev_name+product_key) */
60 #endif
61 };
62 
63 /* len = 17 + sign[n] + ssid[n] + passwd[n] */
64 struct ieee80211_registrar_alibaba_ie {
65     uint8_t element_id; /* 221 */
66     uint8_t len;        /* len of this struct, exclude element id & len field */
67     uint8_t oui[3];     /* D896E0 */
68     uint8_t oui_type;   /* 0xAB, device response */
69 
70     uint8_t version:4;  /* bit7 - bit4 */
71     uint8_t dev_type:4; /* bit3 - bit0; alink=0, alink_cloud=1, yoc=8 */
72     uint8_t sign_len;     /* signature length */
73 #ifdef __GNUC__
74     uint8_t sign[0]; /* sign = hmacsha1(secret, random+dev_name+product_key)*/
75 #endif
76     uint8_t frame_type; /* frame_type = 0 */
77 
78     uint8_t ssid_len; /* AP's SSID length */
79 #ifdef __GNUC__
80     uint8_t ssid[0]; /* SSID of AP */
81 #endif
82     uint8_t passwd_len; /* AP's PASSWORD length */
83 #ifdef __GNUC__
84     uint8_t passwd[0]; /* PASSWORD of AP */
85 #endif
86     uint8_t bssid[6]; /* BSSID of AP */
87 };
88 
89 #define MAX_DEV_NAME_LEN   (64)
90 #define MAX_PK_LEN         (20)
91 #define MAX_KEY_LEN        (32)
92 #define MAX_TOKEN_LEN      (32)
93 #define ZC_PROBE_LEN       (46)
94 #define ENROLLEE_SIGN_SIZE (SHA1_DIGEST_SIZE)
95 #define ENROLLEE_IE_FIX_LEN                                          \
96     (sizeof(struct ieee80211_enrollee_alibaba_ie) + RANDOM_MAX_LEN + \
97      ENROLLEE_SIGN_SIZE)
98 #define REGISTRAR_IE_FIX_LEN (sizeof(struct ieee80211_registrar_alibaba_ie))
99 #define ENROLLEE_INFO_HDR_SIZE \
100     (ENROLLEE_IE_FIX_LEN - 6 + MAX_DEV_NAME_LEN + 1 + MAX_PK_LEN + 1)
101 
102 #ifndef AWSS_DISABLE_REGISTRAR
103 struct enrollee_info {
104     uint8_t dev_type_ver;
105     uint8_t dev_name_len;
106     uint8_t dev_name[MAX_DEV_NAME_LEN + 1];
107     uint8_t frame_type;
108 
109     uint8_t pk_len;
110     uint8_t pk[MAX_PK_LEN + 1];
111     uint8_t rand_len;
112     uint8_t random[RANDOM_MAX_LEN];
113     uint8_t
114         security; /* encryption per product(3) or device(4) or manufacture(5) */
115     uint8_t sign_method; /* 0:hmacsha1, 1:hmacsha256 */
116     uint8_t sign_len;
117     uint8_t sign[ENROLLEE_SIGN_SIZE];
118 
119     signed char rssi;
120 
121     uint8_t key[MAX_KEY_LEN + 1]; /* aes key */
122 
123     uint8_t state;            /* free or not */
124     uint8_t checkin_priority; /* smaller means high pri */
125     uint32_t checkin_timestamp;
126     uint32_t report_timestamp;
127     uint32_t interval; /* report timeout */
128     uint32_t checkin_timeout;
129 };
130 #endif
131 /* registrar configuration */
132 #define MAX_ENROLLEE_NUM (5) /* Note: max enrollee num supported */
133 
134 /*
135  * ENR_FREE     --producer-->   ENR_IN_QUEUE
136  * ENR_IN_QUEUE     --cloud----->   ENR_CHECKIN_ENABLE
137  * ENR_CHECKIN_ENABLE   --consumer-->   ENR_CHECKIN_ONGOING -->
138  * ENR_CHECKIN_END/ENR_FREE *any state*      --consumer-->   ENR_FREE
139  */
140 enum enrollee_state {
141     ENR_FREE = 0,
142     ENR_IN_QUEUE,
143     ENR_FOUND,
144     ENR_CHECKIN_ENABLE,
145     ENR_CHECKIN_CIPHER,
146     ENR_CHECKIN_ONGOING,
147     ENR_CHECKIN_END,
148     /* ENR_OUTOFDATE = 0 */
149 };
150 
151 #define AES_KEY_LEN (16)
152 /* return 0 for success, -1 dev_name not match, otherwise return -2 */
153 extern const uint8_t probe_req_frame[ZC_PROBE_LEN];
154 #define SA_POS   (10) /* source mac pos */
155 #define FCS_SIZE (4)
156 
157 /* enrollee API */
158 #ifndef AWSS_DISABLE_ENROLLEE
159 void awss_init_enrollee_info(void);
160 void awss_broadcast_enrollee_info(void);
161 void awss_destroy_enrollee_info(void);
162 int awss_recv_callback_zconfig(struct parser_res *res);
163 int awss_ieee80211_zconfig_process(uint8_t *mgmt_header, int len, int link_type,
164                                    struct parser_res *res, signed char rssi);
165 #endif
166 
167 /* registrar API */
168 #ifndef AWSS_DISABLE_REGISTRAR
169 void awss_registrar_init(void);
170 void awss_registrar_deinit(void);
171 #endif
172 
173 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
174 }
175 #endif
176 
177 #endif
178