1 /*
2 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "util.h"
9
10 #include "trng.h"
11 #include "fih.h"
12
13 /* The average roll should be 4 by the CLT, and our secrets are usually 32
14 * bytes. Do 8 + 3 so there's a bit of extra. Should always be odd so the reseed
15 * oscillates between before and after the forward step.
16 */
17 #define RNG_CHUNK_BYTES (11)
18 /* Reverse every between 0 and 7 bytes */
19 #define SHUFFLE_MASK (0x7)
20
bl_secure_memeql(const void * ptr1,const void * ptr2,size_t num)21 fih_int bl_secure_memeql(const void *ptr1, const void *ptr2, size_t num)
22 {
23 fih_int is_equal = FIH_SUCCESS;
24 size_t block_start;
25 size_t block_end;
26 size_t curr = 0;
27 uint8_t rnd[RNG_CHUNK_BYTES];
28 size_t rnd_curr_idx = sizeof(rnd);
29
30 /* Do comparison. Every n bytes (where n is random between 1 and 9),
31 * reverse the direction.
32 */
33 while (curr < num) {
34 /* Only generate more entropy if we've run out */
35 if (rnd_curr_idx == sizeof(rnd)) {
36 bl1_trng_generate_random(rnd, sizeof(rnd));
37 rnd_curr_idx = 0;
38 }
39
40 /* Forward case. Always at least one byte */
41 block_start = curr;
42 block_end = curr + (rnd[rnd_curr_idx++] & SHUFFLE_MASK) + 1;
43
44 if (block_end > num) {
45 block_end = num;
46 }
47
48 for (; curr < block_end; curr++) {
49 if (((uint8_t *)ptr1)[curr] != ((uint8_t *)ptr2)[curr]) {
50 is_equal = FIH_FAILURE;
51 }
52 }
53
54
55 /* Only generate more entropy if we've run out */
56 if (rnd_curr_idx == sizeof(rnd)) {
57 bl1_trng_generate_random(rnd, sizeof(rnd));
58 rnd_curr_idx = 0;
59 }
60
61 /* Reverse case. Always at least one byte */
62 block_start = curr;
63 block_end = curr + (rnd[rnd_curr_idx++] & SHUFFLE_MASK) + 1;
64
65 if (block_end > num) {
66 block_end = num;
67 }
68
69 for (curr = block_end - 1; curr >= block_start; curr--) {
70 if (((uint8_t *)ptr1)[curr] != ((uint8_t *)ptr2)[curr]) {
71 is_equal = FIH_FAILURE;
72 }
73 }
74 curr = block_end;
75 }
76 if (curr != num) {
77 FIH_PANIC;
78 }
79
80 FIH_RET(is_equal);
81 }
82
bl_secure_memcpy(void * destination,const void * source,size_t num)83 fih_int bl_secure_memcpy(void *destination, const void *source, size_t num)
84 {
85 size_t block_start;
86 size_t block_end;
87 int64_t curr = 0;
88 uint8_t rnd[RNG_CHUNK_BYTES];
89 size_t rnd_curr_idx = sizeof(rnd);
90
91 /* Do copy. Every n bytes (where n is random between 1 and 17), reverse the
92 * direction.
93 */
94 while (curr < num) {
95 /* Only generate more entropy if we've run out */
96 if (rnd_curr_idx == sizeof(rnd)) {
97 bl1_trng_generate_random(rnd, sizeof(rnd));
98 rnd_curr_idx = 0;
99 }
100
101 /* Forward case */
102 bl1_trng_generate_random(rnd, sizeof(rnd));
103 block_start = curr;
104 block_end = curr + (rnd[rnd_curr_idx++] & SHUFFLE_MASK) + 1;
105
106 if (block_end > num) {
107 block_end = num;
108 }
109
110 for (; curr < block_end; curr++) {
111 ((uint8_t *)destination)[curr] = ((uint8_t *)source)[curr];
112 }
113
114
115 /* Only generate more entropy if we've run out */
116 if (rnd_curr_idx == sizeof(rnd)) {
117 bl1_trng_generate_random(rnd, sizeof(rnd));
118 rnd_curr_idx = 0;
119 }
120
121 /* Reverse case */
122 block_start = curr;
123 block_end = curr + (rnd[rnd_curr_idx++] & SHUFFLE_MASK) + 1;
124
125 if (block_end > num) {
126 block_end = num;
127 }
128
129 for (curr = block_end - 1; block_start <= curr; curr--) {
130 ((uint8_t *)destination)[curr] = ((uint8_t *)source)[curr];
131 }
132 curr = block_end;
133 }
134 if (curr != num) {
135 FIH_PANIC;
136 }
137
138 FIH_RET(FIH_SUCCESS);
139 }
140