OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
Sha1.c
Go to the documentation of this file.
1
19/*********************************************************************
20* Filename: sha1.c
21* Author: Brad Conte (brad AT bradconte.com)
22* Copyright:
23* Disclaimer: This code is presented "as is" without any guarantees.
24* Details: Implementation of the SHA1 hashing algorithm.
25 Algorithm specification can be found here:
26 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
27 This implementation uses little endian byte order.
28*********************************************************************/
29
30#include "CryptoInternal.h"
31
32#define ROTLEFT(a, b) ((a << b) | (a >> (32 - b)))
33
34#ifdef OC_CRYPTO_SUPPORTS_SHA1
35
36VOID
37Sha1Transform (
38 SHA1_CONTEXT *Ctx,
39 CONST UINT8 *Data
40 )
41{
42 UINT32 A, B, C, D, E, Index1, Index2, T, M[80];
43
44 for (Index1 = 0, Index2 = 0; Index1 < 16; ++Index1, Index2 += 4) {
45 M[Index1] = (Data[Index2] << 24) + (Data[Index2 + 1] << 16)
46 + (Data[Index2 + 2] << 8) + (Data[Index2 + 3]);
47 }
48
49 for ( ; Index1 < 80; ++Index1) {
50 M[Index1] = (M[Index1 - 3] ^ M[Index1 - 8] ^ M[Index1 - 14] ^ M[Index1 - 16]);
51 M[Index1] = (M[Index1] << 1) | (M[Index1] >> 31);
52 }
53
54 A = Ctx->State[0];
55 B = Ctx->State[1];
56 C = Ctx->State[2];
57 D = Ctx->State[3];
58 E = Ctx->State[4];
59
60 for (Index1 = 0; Index1 < 20; ++Index1) {
61 T = ROTLEFT (A, 5) + ((B & C) ^ (~B & D)) + E + Ctx->K[0] + M[Index1];
62 E = D;
63 D = C;
64 C = ROTLEFT (B, 30);
65 B = A;
66 A = T;
67 }
68
69 for ( ; Index1 < 40; ++Index1) {
70 T = ROTLEFT (A, 5) + (B ^ C ^ D) + E + Ctx->K[1] + M[Index1];
71 E = D;
72 D = C;
73 C = ROTLEFT (B, 30);
74 B = A;
75 A = T;
76 }
77
78 for ( ; Index1 < 60; ++Index1) {
79 T = ROTLEFT (A, 5) + ((B & C) ^ (B & D) ^ (C & D)) + E + Ctx->K[2] + M[Index1];
80 E = D;
81 D = C;
82 C = ROTLEFT (B, 30);
83 B = A;
84 A = T;
85 }
86
87 for ( ; Index1 < 80; ++Index1) {
88 T = ROTLEFT (A, 5) + (B ^ C ^ D) + E + Ctx->K[3] + M[Index1];
89 E = D;
90 D = C;
91 C = ROTLEFT (B, 30);
92 B = A;
93 A = T;
94 }
95
96 Ctx->State[0] += A;
97 Ctx->State[1] += B;
98 Ctx->State[2] += C;
99 Ctx->State[3] += D;
100 Ctx->State[4] += E;
101}
102
103VOID
104Sha1Init (
105 SHA1_CONTEXT *Ctx
106 )
107{
108 Ctx->DataLen = 0;
109 Ctx->BitLen = 0;
110 Ctx->State[0] = 0x67452301;
111 Ctx->State[1] = 0xEFCDAB89;
112 Ctx->State[2] = 0x98BADCFE;
113 Ctx->State[3] = 0x10325476;
114 Ctx->State[4] = 0xC3D2E1F0;
115 Ctx->K[0] = 0x5A827999;
116 Ctx->K[1] = 0x6ED9EBA1;
117 Ctx->K[2] = 0x8F1BBCDC;
118 Ctx->K[3] = 0xCA62C1D6;
119}
120
121VOID
123 SHA1_CONTEXT *Ctx,
124 CONST UINT8 *Data,
125 UINTN Len
126 )
127{
128 UINTN Index = 0;
129
130 for (Index = 0; Index < Len; ++Index) {
131 Ctx->Data[Ctx->DataLen] = Data[Index];
132 Ctx->DataLen++;
133 if (Ctx->DataLen == 64) {
134 Sha1Transform (Ctx, Ctx->Data);
135 Ctx->BitLen += 512;
136 Ctx->DataLen = 0;
137 }
138 }
139}
140
141VOID
142Sha1Final (
143 SHA1_CONTEXT *Ctx,
144 UINT8 *Hash
145 )
146{
147 UINT32 Index = Ctx->DataLen;
148
149 //
150 // Pad whatever Data is left in the buffer.
151 //
152 if (Ctx->DataLen < 56) {
153 Ctx->Data[Index++] = 0x80;
154 ZeroMem (Ctx->Data + Index, 56-Index);
155 } else {
156 Ctx->Data[Index++] = 0x80;
157 ZeroMem (Ctx->Data + Index, 64-Index);
158 Sha1Transform (Ctx, Ctx->Data);
159 ZeroMem (Ctx->Data, 56);
160 }
161
162 //
163 // Append to the padding the total message's length in bits and transform.
164 //
165 Ctx->BitLen += Ctx->DataLen * 8;
166 Ctx->Data[63] = (UINT8)(Ctx->BitLen);
167 Ctx->Data[62] = (UINT8)(Ctx->BitLen >> 8);
168 Ctx->Data[61] = (UINT8)(Ctx->BitLen >> 16);
169 Ctx->Data[60] = (UINT8)(Ctx->BitLen >> 24);
170 Ctx->Data[59] = (UINT8)(Ctx->BitLen >> 32);
171 Ctx->Data[58] = (UINT8)(Ctx->BitLen >> 40);
172 Ctx->Data[57] = (UINT8)(Ctx->BitLen >> 48);
173 Ctx->Data[56] = (UINT8)(Ctx->BitLen >> 56);
174 Sha1Transform (Ctx, Ctx->Data);
175
176 //
177 // Since this implementation uses little endian byte ordering and MD uses big endian,
178 // reverse all the bytes when copying the final State to the output Hash.
179 //
180 for (Index = 0; Index < 4; ++Index) {
181 Hash[Index] = (UINT8)((Ctx->State[0] >> (24 - Index * 8)) & 0x000000FF);
182 Hash[Index + 4] = (UINT8)((Ctx->State[1] >> (24 - Index * 8)) & 0x000000FF);
183 Hash[Index + 8] = (UINT8)((Ctx->State[2] >> (24 - Index * 8)) & 0x000000FF);
184 Hash[Index + 12] = (UINT8)((Ctx->State[3] >> (24 - Index * 8)) & 0x000000FF);
185 Hash[Index + 16] = (UINT8)((Ctx->State[4] >> (24 - Index * 8)) & 0x000000FF);
186 }
187}
188
189VOID
190Sha1 (
191 UINT8 *Hash,
192 UINT8 *Data,
193 UINTN Len
194 )
195{
196 SHA1_CONTEXT Ctx;
197
198 Sha1Init (&Ctx);
199 Sha1Update (&Ctx, Data, Len);
200 Sha1Final (&Ctx, Hash);
201 SecureZeroMem (&Ctx, sizeof (Ctx));
202}
203
204#endif
VOID Sha1Update(SHA1_CONTEXT *Context, CONST UINT8 *Data, UINTN Len)
VOID Sha1Init(SHA1_CONTEXT *Context)
VOID Sha1Final(SHA1_CONTEXT *Context, UINT8 *Hash)
VOID Sha1(UINT8 *Hash, UINT8 *Data, UINTN Len)
VOID * SecureZeroMem(OUT VOID *Buffer, IN UINTN Length)
Definition SecureMem.c:73
#define ROTLEFT(a, b)
Definition Sha1.c:32
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define Len
Definition deflate.h:82
UINT32 K[4]
UINT8 Data[64]
UINT32 State[5]