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