1 /*
2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3 */
4 #include "wifi_provision_internal.h"
5 #include "linkkit/infra/infra_sha256.h"
6
7 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
8 extern "C" {
9 #endif
10
11 #ifndef SHA256_DIGEST_SIZE
12 #define SHA256_DIGEST_SIZE (32)
13 #endif
14
cal_passwd(void * key,void * random,void * passwd)15 static const char *cal_passwd(void *key, void *random, void *passwd)
16 {
17 uint16_t key_len;
18 uint8_t digest[SHA256_DIGEST_SIZE + 1] = { 0 };
19 uint8_t passwd_src[KEY_MAX_LEN + RANDOM_MAX_LEN + 2] = { 0 };
20
21 if (!passwd || !key || !random)
22 return NULL;
23
24 /* combine key and random, with split of comma */
25 key_len = strlen(key);
26 if (key_len > KEY_MAX_LEN)
27 key_len = KEY_MAX_LEN;
28 memcpy(passwd_src, key, key_len);
29 passwd_src[key_len++] = ',';
30 memcpy(passwd_src + key_len, random, RANDOM_MAX_LEN);
31 key_len += RANDOM_MAX_LEN;
32
33 utils_sha256(passwd_src, key_len, digest);
34 /* use the first 128bits as AES-Key */
35 memcpy(passwd, digest, AES128_KEY_LEN);
36
37 return passwd;
38 }
39
aes_decrypt_string(char * cipher,char * plain,int len,int cipher_hex,int sec_lvl,char cbc,const char * rand)40 int aes_decrypt_string(char *cipher, char *plain, int len, int cipher_hex,
41 int sec_lvl, char cbc, const char *rand)
42 {
43 char res = 0;
44 char decrypt = 1;
45 uint8_t iv[AES128_KEY_LEN] = { 0 };
46 uint8_t key[AES128_KEY_LEN] = { 0 };
47 uint8_t random[RANDOM_MAX_LEN] = { 0 };
48
49 uint8_t *decoded = (uint8_t *)awss_zalloc(len + 1);
50 if (decoded == NULL)
51 return -1;
52
53 if (cipher_hex == 0) {
54 /*
55 * mobile-ap, router, dev-ap
56 */
57 utils_str_to_hex(cipher, len, decoded, len);
58 } else { /* for smartconfig/wps, zconfig, */
59 /*
60 * smartconfig/wps, zconfig
61 */
62 memcpy(decoded, cipher, len);
63 }
64
65 if (rand) {
66 /*
67 * smartconfig/wps uses zero
68 * zconfig/dev-ap/mobile-ap/router uses random
69 */
70 memcpy(random, rand, sizeof(random));
71 }
72
73 awss_debug("security level: %d", sec_lvl);
74
75 switch (sec_lvl) {
76 case SEC_LVL_AES128_PRODUCT:
77 {
78 char product_sec[OS_PRODUCT_SECRET_LEN + 1] = { 0 };
79 HAL_GetProductSecret(product_sec);
80 cal_passwd(product_sec, random, key);
81 memcpy(iv, random, sizeof(random));
82 break;
83 }
84 case SEC_LVL_AES128_DEVICE:
85 {
86 char dev_sec[OS_DEVICE_SECRET_LEN + 1] = { 0 };
87 HAL_GetDeviceSecret(dev_sec);
88 cal_passwd(dev_sec, random, key);
89 memcpy(iv, random, sizeof(random));
90 break;
91 }
92 default:
93 {
94 decrypt = 0;
95 awss_debug("wrong security level: %d\n", sec_lvl);
96 res = -2;
97 break;
98 }
99 }
100
101 plain[0] = '\0';
102
103 if (decrypt) {
104 p_Aes128_t aes = (p_Aes128_t)infra_aes128_init(key, iv, AES_DECRYPTION);
105 if (cbc) { /* AP */
106 /*
107 * mobile-ap, dev-ap, router
108 */
109 res = infra_aes128_cbc_decrypt(aes, decoded,
110 len / AES128_KEY_LEN / 2, plain);
111 } else { /* smartconfig */
112 /*
113 * smartconfig/wps, zconfig
114 */
115 res = infra_aes128_cfb_decrypt(aes, decoded, len, plain);
116 }
117 infra_aes128_destroy(aes);
118 }
119
120 HAL_Free(decoded);
121
122 return res;
123 }
124
125 /**
126 * @brief 获取配网服务的安全等级
127 *
128 * @param None.
129 * @return The security level:
130 @verbatim
131 0: open (no encrypt)
132 1: aes256cfb with default aes-key and aes-iv
133 2: aes128cfb with default aes-key and aes-iv
134 3: aes128cfb with aes-key per product and aes-iv = 0
135 4: aes128cfb with aes-key per device and aes-iv = 0
136 5: aes128cfb with aes-key per manufacture and aes-iv = 0
137 others: invalid
138 @endverbatim
139 * @see None.
140 */
141
awss_get_encrypt_type()142 int awss_get_encrypt_type()
143 {
144 return 3;
145 }
146
147 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
148 }
149 #endif
150