1 /*--------------------------------------------------------------------------*/
2 /* Copyright 2020-2021 NXP */
3 /* */
4 /* NXP Confidential. This software is owned or controlled by NXP and may */
5 /* only be used strictly in accordance with the applicable license terms. */
6 /* By expressly accepting such terms or by downloading, installing, */
7 /* activating and/or otherwise using the software, you are agreeing that */
8 /* you have read, and that you agree to comply with and are bound by, such */
9 /* license terms. If you do not agree to be bound by the applicable license */
10 /* terms, then you may not retain, install, activate or otherwise use the */
11 /* software. */
12 /*--------------------------------------------------------------------------*/
13
14 #include <mcuxClMemory.h>
15 #include <mcuxCsslFlowProtection.h>
16 #include <toolchain.h>
17
18
MCUX_CSSL_FP_FUNCTION_DEF(mcuxClMemory_copy)19 MCUX_CSSL_FP_FUNCTION_DEF(mcuxClMemory_copy)
20 mcuxClMemory_Status_Protected_t mcuxClMemory_copy (uint8_t *dst, uint8_t const *src, size_t len, size_t buflen)
21 {
22 MCUX_CSSL_FP_FUNCTION_ENTRY(mcuxClMemory_copy);
23
24 size_t i;
25 MCUX_CSSL_FP_LOOP_DECL(mcuxClMemory_copy_loop);
26
27 // First loop on words
28 // Start at byte 0, increment by 4 bytes. To understand the loop condition, consider without loss of generality a
29 // byte array b_i of len=4 and buflen=4.
30 //
31 // |0 3|4 4|
32 // +-------+-------+-------+-------+-------+
33 // | b_0 | b_1 | b_2 | b_3 | |
34 // +-------+-------+-------+-------+-------+
35 //
36 // In order to determine whether a full word can be copied, check with regard to the copying position i:
37 // * Starting from i=0, a full word can be copied. i+4 is the first position that is outside of the valid range,
38 // and it is equal to len.
39 // * Starting from i=1, 2 or 3, no full word can be copied. i+4 is greater than len.
40 // Therefore, checking that i+4 <= len and i+4 <= buflen is a valid condition to check whether a full word can be
41 // copied.
42 for (i = 0u; ((i + sizeof(uint32_t)) <= len) && ((i + sizeof(uint32_t)) <= buflen); i += sizeof(uint32_t))
43 {
44 /* MISRA Ex. 9 - Rule 11.3 - Use of UNALIGNED keyword. */
45 *(UNALIGNED uint32_t*)dst = *(UNALIGNED uint32_t const*)src;
46 dst += sizeof(uint32_t);
47 src += sizeof(uint32_t);
48
49 MCUX_CSSL_FP_LOOP_ITERATION(mcuxClMemory_copy_loop);
50 }
51
52 //loop on remaining bytes
53 for (; (i < len) && (i < buflen); i++)
54 {
55 *dst = *src;
56 dst++;
57 src++;
58 MCUX_CSSL_FP_LOOP_ITERATION(mcuxClMemory_copy_loop);
59 }
60
61 size_t lenExceeded = len - i;
62 MCUX_CSSL_FP_FUNCTION_EXIT(mcuxClMemory_copy,
63 lenExceeded,
64 MCUX_CSSL_FP_LOOP_ITERATIONS(mcuxClMemory_copy_loop,
65 (i / sizeof(uint32_t)) + (i & 0x3U)));
66 }
67
MCUX_CSSL_FP_FUNCTION_DEF(mcuxClMemory_set)68 MCUX_CSSL_FP_FUNCTION_DEF(mcuxClMemory_set)
69 mcuxClMemory_Status_Protected_t mcuxClMemory_set (uint8_t *dst, uint8_t val, size_t len, size_t buflen)
70 {
71 MCUX_CSSL_FP_FUNCTION_ENTRY(mcuxClMemory_set);
72
73 size_t i;
74 uint32_t unalignedBytes = ((sizeof(uint32_t)) - (uint32_t)dst) & ((sizeof(uint32_t)) - 1u);
75 MCUX_CSSL_FP_LOOP_DECL(mcuxClMemory_set_loop);
76 uint32_t wordVal = ((uint32_t)val << 24) | ((uint32_t)val << 16) | ((uint32_t)val << 8) | (uint32_t)val;
77
78 //clear unaligned bytes first, if any
79 for(i = 0u; (i < len) && (i < buflen) && (i < unalignedBytes); i++)
80 {
81 *dst = val;
82 dst++;
83 MCUX_CSSL_FP_LOOP_ITERATION(mcuxClMemory_set_loop);
84 }
85
86 //loop on words. See mcuxClMemory_copy for an explanation of the condition
87 while(((i + sizeof(uint32_t)) <= len) && ((i + sizeof(uint32_t)) <= buflen))
88 {
89 MCUX_CSSL_FP_LOOP_ITERATION(mcuxClMemory_set_loop);
90 /* MISRA Ex. 9 - Rule 11.3 - Use of UNALIGNED keyword. */
91 *(UNALIGNED uint32_t*)dst = wordVal;
92 MCUX_CSSL_FP_LOOP_ITERATION(mcuxClMemory_set_loop);
93 dst += sizeof(uint32_t);
94 MCUX_CSSL_FP_LOOP_ITERATION(mcuxClMemory_set_loop);
95 i += sizeof(uint32_t);
96 MCUX_CSSL_FP_LOOP_ITERATION(mcuxClMemory_set_loop);
97 }
98
99 //loop on remaining bytes
100 for(; (i < len) && (i < buflen); i++)
101 {
102 *dst = val;
103 dst++;
104 MCUX_CSSL_FP_LOOP_ITERATION(mcuxClMemory_set_loop);
105 }
106
107 size_t lenExceeded = len - i;
108 MCUX_CSSL_FP_FUNCTION_EXIT(mcuxClMemory_set,
109 lenExceeded,
110 MCUX_CSSL_FP_LOOP_ITERATIONS(mcuxClMemory_set_loop,
111 ((len <= buflen) ? len : buflen)));
112 }
113
MCUX_CSSL_FP_FUNCTION_DEF(mcuxClMemory_clear)114 MCUX_CSSL_FP_FUNCTION_DEF(mcuxClMemory_clear)
115 mcuxClMemory_Status_Protected_t mcuxClMemory_clear (uint8_t *dst, size_t len, size_t buflen)
116 {
117 MCUX_CSSL_FP_FUNCTION_ENTRY(mcuxClMemory_clear, MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClMemory_set));
118
119 MCUX_CSSL_FP_FUNCTION_CALL(setResult, mcuxClMemory_set(dst, 0U, len, buflen));
120
121 MCUX_CSSL_FP_FUNCTION_EXIT(mcuxClMemory_clear,
122 setResult);
123 }
124