ReactOS 0.4.17-dev-1281-g065abb3
hubsha1.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS SuperSpeed USB Hub Driver
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: SHA-1 (FIPS 180-4) for generated container ids
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "usbhub3.h"
9#include "hubid.h"
10
11static
12inline
17 _In_ ULONG Bits)
18{
19 return (Value << Bits) | (Value >> (32 - Bits));
20}
21
22/* One 64 byte block, FIPS 180-4 6.1.2 */
23static
24VOID
28 _In_reads_bytes_(64) const UCHAR* Block)
29{
30 ULONG Schedule[80];
31 ULONG Work[5];
32 ULONG Mix;
34 ULONG Next;
35 ULONG Round;
36
37 for (Round = 0; Round < 16; Round++)
38 {
39 Schedule[Round] = ((ULONG)Block[Round * 4] << 24) |
40 ((ULONG)Block[Round * 4 + 1] << 16) |
41 ((ULONG)Block[Round * 4 + 2] << 8) |
42 (ULONG)Block[Round * 4 + 3];
43 }
44
45 for (Round = 16; Round < 80; Round++)
46 {
47 Schedule[Round] = HubSha1Rotate(Schedule[Round - 3] ^ Schedule[Round - 8] ^
48 Schedule[Round - 14] ^ Schedule[Round - 16], 1);
49 }
50
51 RtlCopyMemory(Work, State, sizeof(Work));
52
53 for (Round = 0; Round < 80; Round++)
54 {
55 if (Round < 20)
56 {
57 Mix = (Work[1] & Work[2]) | (~Work[1] & Work[3]);
58 Constant = 0x5A827999;
59 }
60 else if (Round < 40)
61 {
62 Mix = Work[1] ^ Work[2] ^ Work[3];
63 Constant = 0x6ED9EBA1;
64 }
65 else if (Round < 60)
66 {
67 Mix = (Work[1] & Work[2]) | (Work[1] & Work[3]) | (Work[2] & Work[3]);
68 Constant = 0x8F1BBCDC;
69 }
70 else
71 {
72 Mix = Work[1] ^ Work[2] ^ Work[3];
73 Constant = 0xCA62C1D6;
74 }
75
76 Next = HubSha1Rotate(Work[0], 5) + Mix + Work[4] + Constant + Schedule[Round];
77 Work[4] = Work[3];
78 Work[3] = Work[2];
79 Work[2] = HubSha1Rotate(Work[1], 30);
80 Work[1] = Work[0];
81 Work[0] = Next;
82 }
83
84 for (Round = 0; Round < 5; Round++)
85 State[Round] += Work[Round];
86}
87
88VOID
92{
93 RtlZeroMemory(Context, sizeof(*Context));
94 Context->State[0] = 0x67452301;
95 Context->State[1] = 0xEFCDAB89;
96 Context->State[2] = 0x98BADCFE;
97 Context->State[3] = 0x10325476;
98 Context->State[4] = 0xC3D2E1F0;
99}
100
101VOID
102NTAPI
107{
108 const UCHAR* Bytes = (const UCHAR*)Data;
109 SIZE_T Chunk;
110
111 Context->TotalBytes += Length;
112
113 while (Length != 0)
114 {
115 Chunk = min(Length, sizeof(Context->Block) - Context->BlockUsed);
116 RtlCopyMemory(&Context->Block[Context->BlockUsed], Bytes, Chunk);
117 Context->BlockUsed += (ULONG)Chunk;
118 Bytes += Chunk;
119 Length -= Chunk;
120
121 if (Context->BlockUsed == sizeof(Context->Block))
122 {
123 HubSha1Compress(Context->State, Context->Block);
124 Context->BlockUsed = 0;
125 }
126 }
127}
128
129/* Pads with 0x80, zeros and the message length in bits, big endian (FIPS 180-4 5.1.1) */
130VOID
131NTAPI
135{
136 ULONG64 Bits = Context->TotalBytes * 8;
137 ULONG Index;
138
139 Context->Block[Context->BlockUsed++] = 0x80;
140
141 if (Context->BlockUsed > sizeof(Context->Block) - 8)
142 {
143 RtlZeroMemory(&Context->Block[Context->BlockUsed], sizeof(Context->Block) - Context->BlockUsed);
144 HubSha1Compress(Context->State, Context->Block);
145 Context->BlockUsed = 0;
146 }
147
148 RtlZeroMemory(&Context->Block[Context->BlockUsed], sizeof(Context->Block) - 8 - Context->BlockUsed);
149
150 for (Index = 0; Index < 8; Index++)
151 Context->Block[56 + Index] = (UCHAR)(Bits >> (56 - Index * 8));
152
153 HubSha1Compress(Context->State, Context->Block);
154
155 for (Index = 0; Index < HUB_SHA1_DIGEST_BYTES; Index++)
156 Digest[Index] = (UCHAR)(Context->State[Index / 4] >> (24 - (Index % 4) * 8));
157
159}
#define HUB_SHA1_DIGEST_BYTES
Definition: hubid.h:53
VOID NTAPI HubSha1Init(_Out_ HubSha1 *Context)
Definition: hubsha1.cpp:90
VOID NTAPI HubSha1Update(_Inout_ HubSha1 *Context, _In_reads_bytes_(Length) const VOID *Data, _In_ SIZE_T Length)
Definition: hubsha1.cpp:103
VOID NTAPI HubSha1Final(_Inout_ HubSha1 *Context, _Out_writes_bytes_all_(HUB_SHA1_DIGEST_BYTES) PUCHAR Digest)
Definition: hubsha1.cpp:132
static VOID NTAPI HubSha1Compress(_Inout_updates_(5) PULONG State, _In_reads_bytes_(64) const UCHAR *Block)
Definition: hubsha1.cpp:26
static ULONG NTAPI HubSha1Rotate(_In_ ULONG Value, _In_ ULONG Bits)
Definition: hubsha1.cpp:15
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
_In_ UINT Bytes
Definition: mmcopy.h:9
unsigned __int64 ULONG64
Definition: imports.h:198
#define min(a, b)
Definition: monoChain.cc:55
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _Inout_updates_(s)
Definition: no_sal2.h:182
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_all_(s)
Definition: no_sal2.h:194
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PACPI_METHOD_ARGUMENT Next
Definition: slotdev.cpp:96
Definition: hubid.h:46
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
PUSBUSER_REQUEST_HEADER Block
Definition: userreq.cpp:697
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
FORCEINLINE PVOID RtlSecureZeroMemory(_Out_writes_bytes_all_(Size) PVOID Pointer, _In_ SIZE_T Size)
Definition: rtlfuncs.h:3149