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