• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #ifndef BSL_BYTES_H
17 #define BSL_BYTES_H
18 
19 #include <stdint.h>
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 /**
26  * @brief   convert uint8_t byte stream to uint16_t data
27  *
28  * @attention data cannot be empty
29  *
30  * @param   data [IN] uint8_t byte stream
31  *
32  * @return  uint16_t converted data
33  */
BSL_ByteToUint16(const uint8_t * data)34 static inline uint16_t BSL_ByteToUint16(const uint8_t *data)
35 {
36     /** Byte 0 is shifted by 8 bits to the left, and byte 1 remains unchanged. uint16_t is obtained after OR */
37     return ((uint16_t)data[0] << 8) | ((uint16_t)data[1]);
38 }
39 
40 /**
41  * @brief   convert uint16_t data to uint8_t byte stream
42  *
43  * @attention data cannot be empty
44  *
45  * @param   num [IN] data to be converted
46  * @param   data [OUT] converted data
47  */
BSL_Uint16ToByte(uint16_t num,uint8_t * data)48 static inline void BSL_Uint16ToByte(uint16_t num, uint8_t *data)
49 {
50     /** convert to byte stream */
51     data[0] = (uint8_t)(num >> 8);    // data is shifted rightwards by 8 bits and put in byte 0
52     data[1] = (uint8_t)(num & 0xffu); // data AND 0xffu, put in byte 1
53     return;
54 }
55 
56 /**
57  * @brief   convert uint8_t byte stream to uint24_t data
58  *
59  * @attention data cannot be empty
60  *
61  * @param   data [IN] uint8_t byte stream
62  *
63  * @return  uint24_t, converted data
64  */
BSL_ByteToUint24(const uint8_t * data)65 static inline uint32_t BSL_ByteToUint24(const uint8_t *data)
66 {
67     /** Byte 0 is shifted left by 16 bits, byte 1 is shifted left by 8 bits, and byte 2 remains unchanged,
68         uint24_t is obtained after the OR operation. */
69     return ((uint32_t)data[0] << 16) | ((uint32_t)data[1] << 8) | ((uint32_t)data[2]);
70 }
71 
72 /**
73  * @brief   convert uint24_t data to uint8_t byte stream
74  *
75  * @attention data cannot be empty
76  *
77  * @param   num [IN] data to be converted
78  * @param   data [OUT] converted data
79  */
BSL_Uint24ToByte(uint32_t num,uint8_t * data)80 static inline void BSL_Uint24ToByte(uint32_t num, uint8_t *data)
81 {
82     /** convert to byte stream */
83     data[0] = (uint8_t)(num >> 16);   // data is shifted rightwards by 16 bits and put in byte 0
84     data[1] = (uint8_t)(num >> 8);    // data is shifted rightwards by 8 bits and placed in byte 1
85     data[2] = (uint8_t)(num & 0xffu); // data AND 0xffu, put in byte 2
86     return;
87 }
88 
89 /**
90  * @brief   convert uint8_t byte stream to uint32_t data
91  *
92  * @attention data cannot be empty
93  *
94  * @param   data [IN]  uint8_t byte stream
95  *
96  * @return  uint32_t, converted data
97  */
BSL_ByteToUint32(const uint8_t * data)98 static inline uint32_t BSL_ByteToUint32(const uint8_t *data)
99 {
100     /** Byte 0 is shifted leftward by 24 bits, byte 1 is shifted leftward by 16 bits,
101         byte 2 is shifted leftward by 8 bits, and byte 3 remains unchanged, uint32_t is obtained after OR operation. */
102     return ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) | ((uint32_t)data[2] << 8) | ((uint32_t)data[3]);
103 }
104 
105 /**
106  * @brief   convert uint8_t byte stream to uint48_t data
107  *
108  * @attention data cannot be empty
109  *
110  * @param   data [IN]  uint8_t byte stream
111  *
112  * @return  uint48_t, converted data
113  */
BSL_ByteToUint48(const uint8_t * data)114 static inline uint64_t BSL_ByteToUint48(const uint8_t *data)
115 {
116     /** Byte 0 is shifted leftward by 40 bits, byte 1 is shifted leftward by 32 bits,
117         byte 2 is shifted leftward by 24 bits, byte 3 is shifted leftward by 16 bits,
118         byte 4 is shifted leftward by 8 bits, and byte 5 remains unchanged, uint48_t is obtained after OR operation. */
119     return ((uint64_t)data[0] << 40) | ((uint64_t)data[1] << 32) | ((uint64_t)data[2] << 24) |
120         ((uint64_t)data[3] << 16) | ((uint64_t)data[4] << 8) | ((uint64_t)data[5]);
121 }
122 
123 /**
124  * @brief   convert uint48_t data to uint8_t byte stream
125  *
126  * @attention data cannot be empty
127  *
128  * @param   num [IN] data to be converted
129  * @param   data [OUT] converted data
130  */
BSL_Uint48ToByte(uint64_t num,uint8_t * data)131 static inline void BSL_Uint48ToByte(uint64_t num, uint8_t *data)
132 {
133     /** convert to byte stream */
134     data[0] = (uint8_t)(num >> 40);   // data is shifted rightwards by 40 bits and put in byte 0
135     data[1] = (uint8_t)(num >> 32);   // data is shifted rightwards by 32 bits and put in byte 1
136     data[2] = (uint8_t)(num >> 24);   // data is shifted rightwards by 24 bits and put in byte 2
137     data[3] = (uint8_t)(num >> 16);   // data is shifted rightwards by 16 bits and put in byte 3
138     data[4] = (uint8_t)(num >> 8);    // data is shifted rightwards by 8 bits and put in byte 4
139     data[5] = (uint8_t)(num & 0xffu); // data AND 0xffu, put in byte 5
140     return;
141 }
142 
143 /**
144  * @brief   convert uint8_t byte stream to uint64_t data
145  *
146  * @attention data cannot be empty
147  *
148  * @param   data [IN] uint8_t byte stream
149  *
150  * @return  uint32_t, converted data
151  */
BSL_ByteToUint64(const uint8_t * data)152 static inline uint64_t BSL_ByteToUint64(const uint8_t *data)
153 {
154     /** Byte 0 is shifted leftward by 56 bits, byte 1 is shifted leftward by 48 bits,
155         byte 2 is shifted leftward by 40 bits, byte 3 is shifted leftward by 32 bits,
156         byte 4 is shifted leftward by 24 bits, byte 5 is shifted leftward by 16 bits,
157         byte 6 is shifted leftward by 8 bits, and byte 7 remains unchanged, uint64_t is obtained after OR operation. */
158     return ((uint64_t)data[0] << 56) | ((uint64_t)data[1] << 48) | ((uint64_t)data[2] << 40) |
159         ((uint64_t)data[3] << 32) | ((uint64_t)data[4] << 24) | ((uint64_t)data[5] << 16) |
160         ((uint64_t)data[6] << 8) | ((uint64_t)data[7]);
161 }
162 
163 /**
164  * @brief   convert uint32_t data to uint8_t byte stream
165  *
166  * @attention data cannot be empty
167  *
168  * @param   num [IN] data to be converted
169  * @param   data [OUT] converted data
170  */
BSL_Uint32ToByte(uint32_t num,uint8_t * data)171 static inline void BSL_Uint32ToByte(uint32_t num, uint8_t *data)
172 {
173     /** convert to byte stream */
174     data[0] = (uint8_t)(num >> 24);   // data is shifted rightwards by 24 bits and put in byte 0
175     data[1] = (uint8_t)(num >> 16);   // data is shifted rightwards by 16 bits and put in byte 1
176     data[2] = (uint8_t)(num >> 8);    // data is shifted rightwards by 8 bits and put in byte 2
177     data[3] = (uint8_t)(num & 0xffu); // data AND 0xffu, put in byte 3
178     return;
179 }
180 
181 /**
182  * @brief   convert uint64_t data to uint8_t byte stream
183  *
184  * @attention data cannot be empty
185  *
186  * @param   num [IN] data to be converted
187  * @param   data [OUT] converted data
188  */
BSL_Uint64ToByte(uint64_t num,uint8_t * data)189 static inline void BSL_Uint64ToByte(uint64_t num, uint8_t *data)
190 {
191     /** convert to byte stream */
192     data[0] = (uint8_t)(num >> 56);   // data is shifted rightwards by 56 bits and put in byte 0
193     data[1] = (uint8_t)(num >> 48);   // data is shifted rightwards by 48 bits and put in byte 1
194     data[2] = (uint8_t)(num >> 40);   // data is shifted rightwards by 40 bits and put in byte 2
195     data[3] = (uint8_t)(num >> 32);   // data is shifted rightwards by 32 bits and put in byte 3
196     data[4] = (uint8_t)(num >> 24);   // data is shifted rightwards by 24 bits and put in byte 4
197     data[5] = (uint8_t)(num >> 16);   // data is shifted rightwards by 16 bits and put in byte 5
198     data[6] = (uint8_t)(num >> 8);    // data is shifted rightwards by 8 bits and put in byte 6
199     data[7] = (uint8_t)(num & 0xffu); // data AND 0xffu, put in byte 7
200     return;
201 }
202 
203 // if a's MSB is 0, output 0
204 // else if a' MSB is 1 output 0xffffffff
Uint32ConstTimeMsb(uint32_t a)205 static inline uint32_t Uint32ConstTimeMsb(uint32_t a)
206 {
207     // 31 == (4 * 8 - 1)
208     return 0u - (a >> 31);
209 }
210 
211 // if a is 0, output 0xffffffff, else output 0
Uint32ConstTimeIsZero(uint32_t a)212 static inline uint32_t Uint32ConstTimeIsZero(uint32_t a)
213 {
214     return Uint32ConstTimeMsb(~a & (a - 1));
215 }
216 
217 // if a == b, output 0xffffffff, else output 0
Uint32ConstTimeEqual(uint32_t a,uint32_t b)218 static inline uint32_t Uint32ConstTimeEqual(uint32_t a, uint32_t b)
219 {
220     return Uint32ConstTimeIsZero(a ^ b);
221 }
222 
223 // if mask == 0xffffffff, return a,
224 // else if mask == 0, return b
Uint32ConstTimeSelect(uint32_t mask,uint32_t a,uint32_t b)225 static inline uint32_t Uint32ConstTimeSelect(uint32_t mask, uint32_t a, uint32_t b)
226 {
227     return ((mask) & a) | ((~mask) & b);
228 }
229 
Uint8ConstTimeSelect(uint32_t mask,uint8_t a,uint8_t b)230 static inline uint32_t Uint8ConstTimeSelect(uint32_t mask, uint8_t a, uint8_t b)
231 {
232     return (((mask) & a) | ((~mask) & b)) & 0xff;
233 }
234 
235 // if a < b, output 0xffffffff, else output 0
Uint32ConstTimeLt(uint32_t a,uint32_t b)236 static inline uint32_t Uint32ConstTimeLt(uint32_t a, uint32_t b)
237 {
238     return Uint32ConstTimeMsb(a ^ ((a ^ b) | ((a - b) ^ a)));
239 }
240 
241 // if a >= b, output 0xffffffff, else output 0
Uint32ConstTimeGe(uint32_t a,uint32_t b)242 static inline uint32_t Uint32ConstTimeGe(uint32_t a, uint32_t b)
243 {
244     return ~Uint32ConstTimeLt(a, b);
245 }
246 
247 // if a > b, output 0xffffffff, else output 0
Uint32ConstTimeGt(uint32_t a,uint32_t b)248 static inline uint32_t Uint32ConstTimeGt(uint32_t a, uint32_t b)
249 {
250     return Uint32ConstTimeLt(b, a);
251 }
252 
Uint32ConstTimeLe(uint32_t a,uint32_t b)253 static inline uint32_t Uint32ConstTimeLe(uint32_t a, uint32_t b)
254 {
255     return Uint32ConstTimeGe(b, a);
256 }
257 
258 // if a == b, return 0xffffffff, else return 0
ConstTimeMemcmp(uint8_t * a,uint8_t * b,uint32_t l)259 static inline uint32_t ConstTimeMemcmp(uint8_t *a, uint8_t *b, uint32_t l)
260 {
261     uint8_t r = 0;
262     for (uint32_t i = 0; i < l; i++) {
263         r |= a[i] ^ b[i];
264     }
265     return Uint32ConstTimeIsZero(r);
266 }
267 
268 #ifdef __cplusplus
269 }
270 #endif /* __cplusplus */
271 
272 #endif // BSL_BYTES_H
273