OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
SecureMem.c
Go to the documentation of this file.
1
14#include "CryptoInternal.h"
15
16INTN
18 IN CONST VOID *DestinationBuffer,
19 IN CONST VOID *SourceBuffer,
20 IN UINTN Length
21 )
22{
23 //
24 // Based on libsodium secure_memcmp function implementation.
25 //
26 UINTN Index;
27 //
28 // The loop variables are volatile to prevent compiler optimizations, such as
29 // security-hurting simplifications and intrinsics insertion.
30 //
31 volatile CONST UINT8 *volatile Destination;
32 volatile CONST UINT8 *volatile Source;
33 volatile UINT8 XorDiff;
34
35 if (Length > 0) {
36 ASSERT (DestinationBuffer != NULL);
37 ASSERT (SourceBuffer != NULL);
38 ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));
39 ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));
40 }
41
42 Destination = (volatile CONST UINT8 *)DestinationBuffer;
43 Source = (volatile CONST UINT8 *)SourceBuffer;
44
45 XorDiff = 0;
46 for (Index = 0; Index < Length; ++Index) {
47 //
48 // XOR is used to prevent comparison result based branches causing
49 // slightly different execution times. A XOR operation only yields 0 when
50 // both operands are equal.
51 // Do not break early on mismatch to not leak information about prefixes.
52 // The AND operation with 0xFFU is performed to have a result promotion to
53 // unsigned int rather than int to ensure a safe cast.
54 //
55 XorDiff |= (UINT8)((Destination[Index] ^ (Source[Index])) & 0xFFU);
56 }
57
58 //
59 // This is implemented as an arithmetic operation to have a uniform
60 // execution time for success and failure cases.
61 //
62 // For XorDiff = 0, the subtraction wraps around and leads to a value of
63 // UINT_MAX. All other values, as XorDiff is unsigned, must be greater than 0
64 // and hence cannot wrap around. This means extracting bit 8 of the
65 // operation's result will always yield 1 for XorDiff = 0 and always yield 0
66 // for XorDiff != 0. This is then cast to INTN, which is safe because it
67 // can only ever be 0 or 1, to finally yield the appropiate return value.
68 //
69 return ((INTN)(1U & ((XorDiff - 1U) >> 8U))) - 1;
70}
71
72VOID *
74 OUT VOID *Buffer,
75 IN UINTN Length
76 )
77{
78 volatile UINT8 *Destination;
79
80 if (Length == 0) {
81 return Buffer;
82 }
83
84 ASSERT (Buffer != NULL);
85 ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));
86
87 Destination = (volatile UINT8 *)Buffer;
88
89 while (Length--) {
90 *Destination++ = 0;
91 }
92
93 return Buffer;
94}
UINT64 Length
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
INTN SecureCompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
Definition SecureMem.c:17
VOID * SecureZeroMem(OUT VOID *Buffer, IN UINTN Length)
Definition SecureMem.c:73
#define ASSERT(x)
Definition coder.h:55