• 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 CRYPT_UTILS_H
17 #define CRYPT_UTILS_H
18 
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <stdbool.h>
22 #include "bsl_err_internal.h"
23 #include "crypt_errno.h"
24 #include "crypt_algid.h"
25 #include "crypt_local_types.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif // __cplusplus
30 
31 #if defined(__GNUC__) || defined(__clang__)
32     #define LIKELY(x) __builtin_expect(!!(x), 1)
33     #define UNLIKELY(x) __builtin_expect(!!(x), 0)
34     #define ALIGN32     __attribute__((aligned(32)))
35     #define ALIGN64     __attribute__((aligned(64)))
36 #else
37     #define LIKELY(x) x
38     #define UNLIKELY(x) x
39     #define ALIGN32
40     #define ALIGN64
41 #endif
42 
43 #define BITS_PER_BYTE   8
44 #define SHIFTS_PER_BYTE 3
45 #define BITSIZE(t)      (sizeof(t) * BITS_PER_BYTE)
46 
47 #define PUT_UINT32_BE(v, p, i)               \
48 do {                                         \
49     (p)[(i) + 0] = (uint8_t)((v) >> 24);     \
50     (p)[(i) + 1] = (uint8_t)((v) >> 16);     \
51     (p)[(i) + 2] = (uint8_t)((v) >>  8);     \
52     (p)[(i) + 3] = (uint8_t)((v) >>  0);     \
53 } while (0)
54 
55 #define PUT_UINT64_BE(v, p, i)               \
56 do {                                         \
57     (p)[(i) + 0] = (uint8_t)((v) >> 56);     \
58     (p)[(i) + 1] = (uint8_t)((v) >> 48);     \
59     (p)[(i) + 2] = (uint8_t)((v) >> 40);     \
60     (p)[(i) + 3] = (uint8_t)((v) >> 32);     \
61     (p)[(i) + 4] = (uint8_t)((v) >> 24);     \
62     (p)[(i) + 5] = (uint8_t)((v) >> 16);     \
63     (p)[(i) + 6] = (uint8_t)((v) >>  8);     \
64     (p)[(i) + 7] = (uint8_t)((v) >>  0);     \
65 } while (0)
66 
67 #define GET_UINT32_BE(p, i)                  \
68 (                                            \
69     ((uint32_t)(p)[(i) + 0] << 24) |         \
70     ((uint32_t)(p)[(i) + 1] << 16) |         \
71     ((uint32_t)(p)[(i) + 2] <<  8) |         \
72     ((uint32_t)(p)[(i) + 3] <<  0)           \
73 )
74 
75 #define PUT_UINT32_LE(v, p, i)               \
76 do {                                         \
77     (p)[(i) + 3] = (uint8_t)((v) >> 24);     \
78     (p)[(i) + 2] = (uint8_t)((v) >> 16);     \
79     (p)[(i) + 1] = (uint8_t)((v) >>  8);     \
80     (p)[(i) + 0] = (uint8_t)((v) >>  0);     \
81 } while (0)
82 
83 #define PUT_UINT64_LE(v, p, i) do {          \
84     (p)[(i) + 7] = (uint8_t)((v) >> 56);     \
85     (p)[(i) + 6] = (uint8_t)((v) >> 48);     \
86     (p)[(i) + 5] = (uint8_t)((v) >> 40);     \
87     (p)[(i) + 4] = (uint8_t)((v) >> 32);     \
88     (p)[(i) + 3] = (uint8_t)((v) >> 24);     \
89     (p)[(i) + 2] = (uint8_t)((v) >> 16);     \
90     (p)[(i) + 1] = (uint8_t)((v) >>  8);     \
91     (p)[(i) + 0] = (uint8_t)((v) >>  0);     \
92 } while (0)
93 
94 #define GET_UINT64_LE(p, i)                                            \
95 (                                                                      \
96     ((uint64_t)(p)[(i) + 7] << 56) | ((uint64_t)(p)[(i) + 6] << 48) |  \
97     ((uint64_t)(p)[(i) + 5] << 40) | ((uint64_t)(p)[(i) + 4] << 32) |  \
98     ((uint64_t)(p)[(i) + 3] << 24) | ((uint64_t)(p)[(i) + 2] << 16) |  \
99     ((uint64_t)(p)[(i) + 1] <<  8) | ((uint64_t)(p)[(i) + 0] <<  0)    \
100 )
101 
102 
103 /**
104  * Check whether conditions are met. If conditions are met, go to the label EXIT.
105  */
106 #define GOTO_EXIT_IF(condition, ret) \
107     do {                        \
108         if (condition) {        \
109             BSL_ERR_PUSH_ERROR((ret));   \
110             goto EXIT;          \
111         }                       \
112     } while (0)
113 
114 /**
115  * Check whether conditions are met. If yes, an error code is returned.
116  */
117 #define RETURN_RET_IF(condition, ret) \
118     do {                              \
119         if (condition) {              \
120             BSL_ERR_PUSH_ERROR(ret);  \
121             return ret;               \
122         }                             \
123     } while (0)
124 
125 /**
126  * If the return value of func is not CRYPT_SUCCESS, go to the label ERR.
127  */
128 #define GOTO_ERR_IF(func, ret) do { \
129         (ret) = (func); \
130         if ((ret) != CRYPT_SUCCESS) { \
131             BSL_ERR_PUSH_ERROR((ret)); \
132             goto ERR; \
133         } \
134     } while (0)
135 
136 #define GOTO_ERR_IF_EX(func, ret) do { \
137         (ret) = (func); \
138         if ((ret) != CRYPT_SUCCESS) { \
139             goto ERR; \
140         } \
141     } while (0)
142 
143 /**
144  * Check whether conditions are met. If yes, an error code is returned.
145  */
146 #define RETURN_RET_IF_ERR(func, ret)   \
147     do {                               \
148         (ret) = (func);                \
149         if ((ret) != CRYPT_SUCCESS) {  \
150             BSL_ERR_PUSH_ERROR((ret)); \
151             return ret;                \
152         }                              \
153     } while (0)
154 
155 #define RETURN_RET_IF_ERR_EX(func, ret)   \
156     do {                               \
157         (ret) = (func);                \
158         if ((ret) != CRYPT_SUCCESS) {  \
159             return ret;                \
160         }                              \
161     } while (0)
162 
163 #define BREAK_IF(condition) \
164     do {                    \
165         if (condition) {    \
166             break;          \
167         }                   \
168     } while (0)
169 
170 /**
171  * If src is not NULL, then execute the fun function. If the operation fails, go to the label ERR.
172  */
173 #define GOTO_ERR_IF_SRC_NOT_NULL(dest, src, func, ret)                  \
174     do {                                                    \
175         if ((src) != NULL) {                                \
176             (dest) = (func);                                \
177             if ((dest) == NULL) {                           \
178                 BSL_ERR_PUSH_ERROR((ret));                           \
179                 goto ERR;                                   \
180             }                                               \
181         }                                                   \
182     } while (0)
183 
184 /**
185  * @brief Perform the XOR operation on the data of two arrays.
186  *
187  * @param a [IN] Input data a
188  * @param b [IN] Input data b
189  * @param r [out] Output the result data.
190  * @param len [IN] Output result data length
191  */
192 #define DATA_XOR(a, b, r, len)       \
193     do {                             \
194         uint32_t subscript;          \
195         for (subscript = 0; subscript < (len); subscript++) { \
196             (r)[subscript] = (a)[subscript] ^ (b)[subscript]; \
197         }                             \
198     } while (0)
199 
200 /**
201  * @brief Perform the XOR operation on the data of 32 bits in two arrays each time.
202  * Ensure that the input and output are integer multiples of 32 bits.
203  * Type conversion is performed only when the address is 4-byte aligned.
204  *
205  * @param a [IN] Input data a
206  * @param b [IN] Input data b
207  * @param r [out] Output the result data.
208  * @param len [IN] Output result data length
209  */
210 #define DATA32_XOR(a, b, r, len)                                \
211     do {                                                        \
212         uint32_t ii;                                            \
213         uintptr_t aPtr = (uintptr_t)(a);                        \
214         uintptr_t bPtr = (uintptr_t)(b);                        \
215         uintptr_t rPtr = (uintptr_t)(r);                        \
216         if (((aPtr & 0x3) != 0) || ((bPtr & 0x3) != 0) || ((rPtr & 0x3) != 0)) {     \
217             for (ii = 0; ii < (len); ii++) {                    \
218                 (r)[ii] = (a)[ii] ^ (b)[ii];                    \
219             }                                                   \
220         } else {                                                \
221             for (ii = 0; ii < (len); ii += 4) {                 \
222                 *(uint32_t *)((r) + ii) = (*(const uint32_t *)((a) + ii)) ^ (*(const uint32_t *)((b) + ii)); \
223             }                                                   \
224         }                                                       \
225     } while (0)
226 
227 /**
228  * @brief Perform the XOR operation on 64 bits of data in two arrays each time.
229  * Ensure that the input and output are integer multiples of 64 bits.
230  * Type conversion is performed only when the address is 8-byte aligned.
231  *
232  * @param a [IN] Input data a
233  * @param b [IN] Input data b
234  * @param r [out] Output the result data.
235  * @param len [IN] Output result data length
236  */
237 #define DATA64_XOR(a, b, r, len)                                \
238     do {                                                        \
239         uint32_t ii;                                            \
240         uintptr_t aPtr = (uintptr_t)(a);                        \
241         uintptr_t bPtr = (uintptr_t)(b);                        \
242         uintptr_t rPtr = (uintptr_t)(r);                        \
243         if (((aPtr & 0x7) != 0) || ((bPtr & 0x7) != 0) || ((rPtr & 0x7) != 0)) {     \
244             for (ii = 0; ii < (len); ii++) {                    \
245                 (r)[ii] = (a)[ii] ^ (b)[ii];                    \
246             }                                                   \
247         } else {                                                \
248             for (ii = 0; ii < (len); ii += 8) {                 \
249                 *(uint64_t *)((r) + ii) = (*(const uint64_t *)((a) + ii)) ^ (*(const uint64_t *)((b) + ii)); \
250             }                                                   \
251         }                                                       \
252     } while (0)
253 
254 /**
255  * @brief Calculate the hash value of the input data.
256  *
257  * @param hashMethod [IN] Hash method
258  * @param hashData [IN] Hash data
259  * @param size [IN] Size of hash data
260  * @param out [OUT] Output hash value
261  */
262 int32_t CRYPT_CalcHash(const EAL_MdMethod *hashMethod, const CRYPT_ConstData *hashData, uint32_t size,
263     uint8_t *out, uint32_t *outlen);
264 
265 /**
266  * @ingroup rsa
267  * @brief mgf1 of PKCS1
268  *
269  * @param hashMethod [IN] Hash method
270  * @param seed [IN] Seed
271  * @param seedLen [IN] Seed length
272  * @param mask [OUT] Mask
273  * @param maskLen [IN] Mask length
274  *
275  * @retval CRYPT_SUCCESS on success
276  */
277 int32_t CRYPT_Mgf1(const EAL_MdMethod *hashMethod, const uint8_t *seed, const uint32_t seedLen,
278     uint8_t *mask, uint32_t maskLen);
279 
280 /**
281  * @brief Retrieves the process function callback and its arguments from a parameter list.
282  *
283  * @param params A pointer to the BSL_Param list containing the parameters.
284  * @param processCb A pointer to a pointer to the process function callback.
285  * @param args A pointer to a pointer to the process function arguments.
286  * @return int32_t Returns CRYPT_SUCCESS if the operation is successful, otherwise an error code.
287  */
288 int32_t CRYPT_GetPkeyProcessParams(BSL_Param *params, CRYPT_EAL_ProcessFuncCb *processCb, void **args);
289 
290 /* Assumes that x is uint32_t and 0 < n < 32 */
291 #define ROTL32(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
292 
293 #define ROTR64(x, n) (((x) << (64 - (n))) | ((x) >> (n))) // Assumes that x is uint64_t and 0 < n < 64
294 
295 #define IS_BUF_NON_ZERO(out, outLen)  (((out) != NULL) && ((outLen) > 0))
296 #define CRYPT_IS_BUF_NON_ZERO(out, outLen)  (((out) != NULL) && ((outLen) > 0))
297 #define CRYPT_CHECK_DATA_INVALID(d) (((d)->data == NULL && (d)->len != 0))
298 #define CRYPT_IsDataNull(d) ((d) == NULL || (d)->data == NULL || (d)->len == 0)
299 #define CRYPT_IN_RANGE(x, range) ((x) >= (range)->min && (x) <= (range)->max)
300 #define CRYPT_CHECK_BUF_INVALID(buf, len) (((buf) == NULL && (len) != 0))
301 #define CRYPT_SWAP32(x) ((((x) & 0xff000000) >> 24) | \
302                          (((x) & 0x00ff0000) >> 8) | \
303                          (((x) & 0x0000ff00) << 8) | \
304                          (((x) & 0x000000ff) << 24))
305 #ifdef HITLS_BIG_ENDIAN
306 
307 #define CRYPT_HTONL(x) (x)
308 
309 // Interpret p + i as little endian order. The type of p must be uint8_t *.
310 #define GET_UINT32_LE(p, i)                                            \
311 (                                                                      \
312     ((uint32_t)((const uint8_t *)(p))[(i) + 3] << 24) |             \
313     ((uint32_t)((const uint8_t *)(p))[(i) + 2] << 16) |             \
314     ((uint32_t)((const uint8_t *)(p))[(i) + 1] <<  8) |             \
315     ((uint32_t)((const uint8_t *)(p))[(i) + 0] <<  0)               \
316 )
317 
318 // Convert little-endian order to host order
319 #define CRYPT_LE32TOH(x)    CRYPT_SWAP32(x)
320 // Convert host order to little-endian order
321 #define CRYPT_HTOLE32(x)    CRYPT_SWAP32(x)
322 
323 #else
324 
325 #define CRYPT_HTONL(x) CRYPT_SWAP32(x)
326 
327 // Interpret p + i as little endian.
328 #define GET_UINT32_LE(p, i)         \
329 (                                   \
330     (((uintptr_t)(p) & 0x7) != 0) ? ((uint32_t)((const uint8_t *)(p))[(i) + 3] << 24) |    \
331                                     ((uint32_t)((const uint8_t *)(p))[(i) + 2] << 16) |    \
332                                     ((uint32_t)((const uint8_t *)(p))[(i) + 1] <<  8) |    \
333                                     ((uint32_t)((const uint8_t *)(p))[(i) + 0] <<  0)      \
334                                   : (*(uint32_t *)((uint8_t *)(uintptr_t)(p) + (i)))       \
335 )
336 // Convert little-endian order to host order
337 #define CRYPT_LE32TOH(x)    (x)
338 // Convert host order to little-endian order
339 #define CRYPT_HTOLE32(x)    (x)
340 
341 #endif
342 
343 #ifdef HITLS_BIG_ENDIAN
344 
345 // Interpret p + i as little endian. The type of p must be uint8_t *.
346 #define GET_UINT16_LE(p, i)                                            \
347 (                                                                      \
348     ((uint16_t)((const uint8_t *)(p))[(i) + 1] <<  8) |                \
349     ((uint16_t)((const uint8_t *)(p))[(i) + 0] <<  0)                  \
350 )
351 #else
352 // Interpret p + i as little endian.
353 #define GET_UINT16_LE(p, i)         \
354 (                                   \
355     (((uintptr_t)(p) & 0x7) != 0) ? ((uint16_t)((const uint8_t *)(p))[(i) + 1] <<  8) |     \
356                                     ((uint16_t)((const uint8_t *)(p))[(i) + 0] <<  0)       \
357                                   : (*(uint16_t *)((uint8_t *)(uintptr_t)(p) + (i)))        \
358 )
359 #endif
360 
361 #define PUT_UINT16_LE(v, p, i)                                \
362     do                                                        \
363     {                                                         \
364         (p)[(i) + 1] = (uint8_t)((v) >> 8);                   \
365         (p)[(i) + 0] = (uint8_t)((v) >> 0);                   \
366     } while (0)
367 
368 /**
369  * 64-bit integer manipulation functions (big endian)
370  */
Uint64FromBeBytes(const uint8_t * bytes)371 static inline uint64_t Uint64FromBeBytes(const uint8_t *bytes)
372 {
373     return (((uint64_t)bytes[0] << 56) |
374             ((uint64_t)bytes[1] << 48) |
375             ((uint64_t)bytes[2] << 40) |
376             ((uint64_t)bytes[3] << 32) |
377             ((uint64_t)bytes[4] << 24) |
378             ((uint64_t)bytes[5] << 16) |
379             ((uint64_t)bytes[6] << 8) |
380             (uint64_t)bytes[7]);
381 }
382 
Uint64ToBeBytes(uint64_t v,uint8_t * bytes)383 static inline void Uint64ToBeBytes(uint64_t v, uint8_t *bytes)
384 {
385     bytes[0] = (uint8_t)(v >> 56);
386     bytes[1] = (uint8_t)(v >> 48);
387     bytes[2] = (uint8_t)(v >> 40);
388     bytes[3] = (uint8_t)(v >> 32);
389     bytes[4] = (uint8_t)(v >> 24);
390     bytes[5] = (uint8_t)(v >> 16);
391     bytes[6] = (uint8_t)(v >> 8);
392     bytes[7] = (uint8_t)(v & 0xffu);
393 }
394 
395 #if defined(HITLS_CRYPTO_RSA_SIGN) || defined(HITLS_CRYPTO_RSA_VERIFY)
396 uint32_t CRYPT_GetMdSizeById(CRYPT_MD_AlgId id);
397 #endif
398 
ParamIdIsValid(uint32_t id,const uint32_t * list,uint32_t num)399 static inline bool ParamIdIsValid(uint32_t id, const uint32_t *list, uint32_t num)
400 {
401     for (uint32_t i = 0; i < num; i++) {
402         if (id == list[i]) {
403             return true;
404         }
405     }
406     return false;
407 }
408 
409 typedef uint32_t (*GetUintCallBack)(const void *key);
GetUintCtrl(const void * ctx,void * val,uint32_t len,GetUintCallBack getUint)410 static inline int32_t GetUintCtrl(const void *ctx, void *val, uint32_t len, GetUintCallBack getUint)
411 {
412     if (val == NULL) {
413         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
414         return CRYPT_NULL_INPUT;
415     }
416     if (len != sizeof(uint32_t)) {
417         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
418         return CRYPT_INVALID_ARG;
419     }
420     *(uint32_t *)val = getUint(ctx);
421     return CRYPT_SUCCESS;
422 }
423 
424 void GetCpuInstrSupportState(void);
425 
426 #ifdef __x86_64__
427 #define CPU_ID_OUT_U32_CNT      4
428 #define EAX_OUT_IDX             0
429 #define EBX_OUT_IDX             1
430 #define ECX_OUT_IDX             2
431 #define EDX_OUT_IDX             3
432 
433 /* %eax */
434 #define XCR0_BIT_SSE            (1ULL << 1)
435 #define XCR0_BIT_AVX            (1ULL << 2)
436 #define XCR0_BIT_OPMASK         (1ULL << 5)
437 #define XCR0_BIT_ZMM_LOW        (1ULL << 6)
438 #define XCR0_BIT_ZMM_HIGH       (1ULL << 7)
439 
440 typedef struct {
441     uint32_t code1Out[CPU_ID_OUT_U32_CNT];
442     uint32_t code7Out[CPU_ID_OUT_U32_CNT];
443     bool osSupportAVX;      /* input ecx = 0, output edx:eax bit 2 */
444     bool osSupportAVX512;   /* input ecx = 0, output edx:eax bit 6 */
445 } CpuInstrSupportState;
446 
447 bool IsSupportAES(void);
448 bool IsSupportBMI1(void);
449 bool IsSupportBMI2(void);
450 bool IsSupportADX(void);
451 bool IsSupportAVX(void);
452 bool IsSupportAVX2(void);
453 bool IsSupportSSE(void);
454 bool IsSupportSSE2(void);
455 bool IsSupportSSE3(void);
456 bool IsSupportMOVBE(void);
457 bool IsSupportAVX512F(void);
458 bool IsSupportAVX512VL(void);
459 bool IsSupportAVX512BW(void);
460 bool IsSupportAVX512DQ(void);
461 bool IsSupportXSAVE(void);
462 bool IsSupportOSXSAVE(void);
463 bool IsOSSupportAVX(void);
464 bool IsOSSupportAVX512(void);
465 
466 void GetCpuId(uint32_t eax, uint32_t ecx, uint32_t cpuId[CPU_ID_OUT_U32_CNT]);
467 
468 #elif defined(__arm__) || defined(__arm) || defined(__aarch64__)
469 
470 bool IsSupportAES(void);
471 bool IsSupportPMULL(void);
472 bool IsSupportSHA1(void);
473 bool IsSupportSHA256(void);
474 bool IsSupportNEON(void);
475 
476 #if defined(__aarch64__)
477 bool IsSupportSHA512(void);
478 #endif // __aarch64__
479 
480 #endif // __arm__ || __arm || __aarch64__
481 
482 #ifdef __cplusplus
483 }
484 #endif // __cplusplus
485 
486 #endif // CRYPT_UTILS_H
487