TianoCore EDK2 master
Loading...
Searching...
No Matches
CryptParallelHash.c
Go to the documentation of this file.
1
9#include "CryptParallelHash.h"
11
12#define PARALLELHASH_CUSTOMIZATION "ParallelHash"
13
14UINTN mBlockNum;
15UINTN mBlockSize;
16UINTN mLastBlockSize;
17UINT8 *mInput;
18UINTN mBlockResultSize;
19UINT8 *mBlockHashResult;
20BOOLEAN *mBlockIsCompleted;
21SPIN_LOCK *mSpinLockList;
22
30VOID
31EFIAPI
33 IN VOID *ProcedureArgument
34 )
35{
36 UINTN Index;
37 BOOLEAN Status;
38
39 for (Index = 0; Index < mBlockNum; Index++) {
40 if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
41 //
42 // Completed, try next one.
43 //
44 if (mBlockIsCompleted[Index]) {
45 ReleaseSpinLock (&mSpinLockList[Index]);
46 continue;
47 }
48
49 //
50 // Calculate CShake256 for this block.
51 //
52 Status = CShake256HashAll (
53 mInput + Index * mBlockSize,
54 (Index == (mBlockNum - 1)) ? mLastBlockSize : mBlockSize,
55 mBlockResultSize,
56 NULL,
57 0,
58 NULL,
59 0,
60 mBlockHashResult + Index * mBlockResultSize
61 );
62 if (!EFI_ERROR (Status)) {
63 mBlockIsCompleted[Index] = TRUE;
64 }
65
66 ReleaseSpinLock (&mSpinLockList[Index]);
67 }
68 }
69}
70
88BOOLEAN
89EFIAPI
91 IN CONST VOID *Input,
92 IN UINTN InputByteLen,
93 IN UINTN BlockSize,
94 OUT VOID *Output,
95 IN UINTN OutputByteLen,
96 IN CONST VOID *Customization,
97 IN UINTN CustomByteLen
98 )
99{
100 UINT8 EncBufB[sizeof (UINTN)+1];
101 UINTN EncSizeB;
102 UINT8 EncBufN[sizeof (UINTN)+1];
103 UINTN EncSizeN;
104 UINT8 EncBufL[sizeof (UINTN)+1];
105 UINTN EncSizeL;
106 UINTN Index;
107 UINT8 *CombinedInput;
108 UINTN CombinedInputSize;
109 BOOLEAN AllCompleted;
110 UINTN Offset;
111 BOOLEAN ReturnValue;
112
113 if ((InputByteLen == 0) || (OutputByteLen == 0) || (BlockSize == 0)) {
114 return FALSE;
115 }
116
117 if ((Input == NULL) || (Output == NULL)) {
118 return FALSE;
119 }
120
121 if ((CustomByteLen != 0) && (Customization == NULL)) {
122 return FALSE;
123 }
124
125 mBlockSize = BlockSize;
126
127 //
128 // Calculate block number n.
129 //
130 mBlockNum = InputByteLen % mBlockSize == 0 ? InputByteLen / mBlockSize : InputByteLen / mBlockSize + 1;
131
132 //
133 // Set hash result size of each block in bytes.
134 //
135 mBlockResultSize = OutputByteLen;
136
137 //
138 // Encode B, n, L to string and record size.
139 //
140 EncSizeB = LeftEncode (EncBufB, mBlockSize);
141 EncSizeN = RightEncode (EncBufN, mBlockNum);
142 EncSizeL = RightEncode (EncBufL, OutputByteLen * CHAR_BIT);
143
144 //
145 // Allocate buffer for combined input (newX), Block completed flag and SpinLock.
146 //
147 CombinedInputSize = EncSizeB + EncSizeN + EncSizeL + mBlockNum * mBlockResultSize;
148 CombinedInput = AllocateZeroPool (CombinedInputSize);
149 mBlockIsCompleted = AllocateZeroPool (mBlockNum * sizeof (BOOLEAN));
150 mSpinLockList = AllocatePool (mBlockNum * sizeof (SPIN_LOCK));
151 if ((CombinedInput == NULL) || (mBlockIsCompleted == NULL) || (mSpinLockList == NULL)) {
152 ReturnValue = FALSE;
153 goto Exit;
154 }
155
156 //
157 // Fill LeftEncode(B).
158 //
159 CopyMem (CombinedInput, EncBufB, EncSizeB);
160
161 //
162 // Prepare for parallel hash.
163 //
164 mBlockHashResult = CombinedInput + EncSizeB;
165 mInput = (UINT8 *)Input;
166 mLastBlockSize = InputByteLen % mBlockSize == 0 ? mBlockSize : InputByteLen % mBlockSize;
167
168 //
169 // Initialize SpinLock for each result block.
170 //
171 for (Index = 0; Index < mBlockNum; Index++) {
172 InitializeSpinLock (&mSpinLockList[Index]);
173 }
174
175 //
176 // Dispatch blocklist to each AP.
177 //
179
180 //
181 // Wait until all block hash completed.
182 //
183 do {
184 AllCompleted = TRUE;
185 for (Index = 0; Index < mBlockNum; Index++) {
186 if (AcquireSpinLockOrFail (&mSpinLockList[Index])) {
187 if (!mBlockIsCompleted[Index]) {
188 AllCompleted = FALSE;
189 ReturnValue = CShake256HashAll (
190 mInput + Index * mBlockSize,
191 (Index == (mBlockNum - 1)) ? mLastBlockSize : mBlockSize,
192 mBlockResultSize,
193 NULL,
194 0,
195 NULL,
196 0,
197 mBlockHashResult + Index * mBlockResultSize
198 );
199 if (ReturnValue) {
200 mBlockIsCompleted[Index] = TRUE;
201 }
202
203 ReleaseSpinLock (&mSpinLockList[Index]);
204 break;
205 }
206
207 ReleaseSpinLock (&mSpinLockList[Index]);
208 } else {
209 AllCompleted = FALSE;
210 break;
211 }
212 }
213 } while (!AllCompleted);
214
215 //
216 // Fill LeftEncode(n).
217 //
218 Offset = EncSizeB + mBlockNum * mBlockResultSize;
219 CopyMem (CombinedInput + Offset, EncBufN, EncSizeN);
220
221 //
222 // Fill LeftEncode(L).
223 //
224 Offset += EncSizeN;
225 CopyMem (CombinedInput + Offset, EncBufL, EncSizeL);
226
227 ReturnValue = CShake256HashAll (
228 CombinedInput,
229 CombinedInputSize,
230 OutputByteLen,
231 PARALLELHASH_CUSTOMIZATION,
232 AsciiStrLen (PARALLELHASH_CUSTOMIZATION),
233 Customization,
234 CustomByteLen,
235 Output
236 );
237
238Exit:
239 ZeroMem (CombinedInput, CombinedInputSize);
240
241 if (CombinedInput != NULL) {
242 FreePool (CombinedInput);
243 }
244
245 if (mSpinLockList != NULL) {
246 FreePool ((VOID *)mSpinLockList);
247 }
248
249 if (mBlockIsCompleted != NULL) {
250 FreePool (mBlockIsCompleted);
251 }
252
253 return ReturnValue;
254}
UINT64 UINTN
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
BOOLEAN EFIAPI CShake256HashAll(IN CONST VOID *Data, IN UINTN DataSize, IN UINTN OutputLen, IN CONST VOID *Name, IN UINTN NameLen, IN CONST VOID *Customization, IN UINTN CustomizationLen, OUT UINT8 *HashValue)
VOID EFIAPI DispatchBlockToAp(VOID)
BOOLEAN EFIAPI ParallelHash256HashAll(IN CONST VOID *Input, IN UINTN InputByteLen, IN UINTN BlockSize, OUT VOID *Output, IN UINTN OutputByteLen, IN CONST VOID *Customization, IN UINTN CustomByteLen)
VOID EFIAPI ParallelHashApExecute(IN VOID *ProcedureArgument)
UINTN EFIAPI RightEncode(OUT UINT8 *EncBuf, IN UINTN Value)
Definition: CryptXkcp.c:79
UINTN EFIAPI LeftEncode(OUT UINT8 *EncBuf, IN UINTN Value)
Definition: CryptXkcp.c:35
VOID EFIAPI Input(IN CHAR16 *Prompt OPTIONAL, OUT CHAR16 *InStr, IN UINTN StrLen)
Definition: EdbSupportUI.c:187
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
SPIN_LOCK *EFIAPI InitializeSpinLock(OUT SPIN_LOCK *SpinLock)
volatile UINTN SPIN_LOCK
SPIN_LOCK *EFIAPI ReleaseSpinLock(IN OUT SPIN_LOCK *SpinLock)
BOOLEAN EFIAPI AcquireSpinLockOrFail(IN OUT SPIN_LOCK *SpinLock)
VOID EFIAPI Exit(IN EFI_STATUS Status)