]>
git.proxmox.com Git - efi-boot-shim.git/blob - PasswordCrypt.c
1 // SPDX-License-Identifier: BSD-2-Clause-Patent
5 #include <Library/BaseCryptLib.h>
6 #include <openssl/sha.h>
7 #include <openssl/md5.h>
9 #define TRAD_DES_HASH_SIZE 13 /* (64/6+1) + (12/6) */
10 #define BSDI_DES_HASH_SIZE 20 /* (64/6+1) + (24/6) + 4 + 1 */
11 #define BLOWFISH_HASH_SIZE 31 /* 184/6+1 */
13 UINT16
get_hash_size (const UINT16 method
)
17 return TRAD_DES_HASH_SIZE
;
19 return BSDI_DES_HASH_SIZE
;
21 return MD5_DIGEST_LENGTH
;
23 return SHA256_DIGEST_LENGTH
;
25 return SHA512_DIGEST_LENGTH
;
27 return BLOWFISH_HASH_SIZE
;
33 static const char md5_salt_prefix
[] = "$1$";
35 static EFI_STATUS
md5_crypt (const char *key
, UINT32 key_len
,
36 const char *salt
, UINT32 salt_size
,
40 UINT8 alt_result
[MD5_DIGEST_LENGTH
];
44 MD5_Update(&ctx
, key
, key_len
);
45 MD5_Update(&ctx
, md5_salt_prefix
, sizeof(md5_salt_prefix
) - 1);
46 MD5_Update(&ctx
, salt
, salt_size
);
49 MD5_Update(&alt_ctx
, key
, key_len
);
50 MD5_Update(&alt_ctx
, salt
, salt_size
);
51 MD5_Update(&alt_ctx
, key
, key_len
);
52 MD5_Final(alt_result
, &alt_ctx
);
54 for (cnt
= key_len
; cnt
> 16; cnt
-= 16)
55 MD5_Update(&ctx
, alt_result
, 16);
56 MD5_Update(&ctx
, alt_result
, cnt
);
60 for (cnt
= key_len
; cnt
> 0; cnt
>>= 1) {
62 MD5_Update(&ctx
, alt_result
, 1);
64 MD5_Update(&ctx
, key
, 1);
67 MD5_Final(alt_result
, &ctx
);
69 for (cnt
= 0; cnt
< 1000; ++cnt
) {
73 MD5_Update(&ctx
, key
, key_len
);
75 MD5_Update(&ctx
, alt_result
, 16);
78 MD5_Update(&ctx
, salt
, salt_size
);
81 MD5_Update(&ctx
, key
, key_len
);
84 MD5_Update(&ctx
, alt_result
, 16);
86 MD5_Update(&ctx
, key
, key_len
);
88 MD5_Final(alt_result
, &ctx
);
91 CopyMem(hash
, alt_result
, MD5_DIGEST_LENGTH
);
96 static EFI_STATUS
sha256_crypt (const char *key
, UINT32 key_len
,
97 const char *salt
, UINT32 salt_size
,
98 const UINT32 rounds
, UINT8
*hash
)
100 SHA256_CTX ctx
, alt_ctx
;
101 UINT8 alt_result
[SHA256_DIGEST_SIZE
];
102 UINT8 tmp_result
[SHA256_DIGEST_SIZE
];
103 UINT8
*cp
, *p_bytes
, *s_bytes
;
107 SHA256_Update(&ctx
, key
, key_len
);
108 SHA256_Update(&ctx
, salt
, salt_size
);
110 SHA256_Init(&alt_ctx
);
111 SHA256_Update(&alt_ctx
, key
, key_len
);
112 SHA256_Update(&alt_ctx
, salt
, salt_size
);
113 SHA256_Update(&alt_ctx
, key
, key_len
);
114 SHA256_Final(alt_result
, &alt_ctx
);
116 for (cnt
= key_len
; cnt
> 32; cnt
-= 32)
117 SHA256_Update(&ctx
, alt_result
, 32);
118 SHA256_Update(&ctx
, alt_result
, cnt
);
120 for (cnt
= key_len
; cnt
> 0; cnt
>>= 1) {
121 if ((cnt
& 1) != 0) {
122 SHA256_Update(&ctx
, alt_result
, 32);
124 SHA256_Update(&ctx
, key
, key_len
);
127 SHA256_Final(alt_result
, &ctx
);
129 SHA256_Init(&alt_ctx
);
130 for (cnt
= 0; cnt
< key_len
; ++cnt
)
131 SHA256_Update(&alt_ctx
, key
, key_len
);
132 SHA256_Final(tmp_result
, &alt_ctx
);
134 cp
= p_bytes
= AllocatePool(key_len
);
135 for (cnt
= key_len
; cnt
>= 32; cnt
-= 32) {
136 CopyMem(cp
, tmp_result
, 32);
139 CopyMem(cp
, tmp_result
, cnt
);
141 SHA256_Init(&alt_ctx
);
142 for (cnt
= 0; cnt
< 16ul + alt_result
[0]; ++cnt
)
143 SHA256_Update(&alt_ctx
, salt
, salt_size
);
144 SHA256_Final(tmp_result
, &alt_ctx
);
146 cp
= s_bytes
= AllocatePool(salt_size
);
147 for (cnt
= salt_size
; cnt
>= 32; cnt
-= 32) {
148 CopyMem(cp
, tmp_result
, 32);
151 CopyMem(cp
, tmp_result
, cnt
);
153 for (cnt
= 0; cnt
< rounds
; ++cnt
) {
157 SHA256_Update(&ctx
, p_bytes
, key_len
);
159 SHA256_Update(&ctx
, alt_result
, 32);
162 SHA256_Update(&ctx
, s_bytes
, salt_size
);
165 SHA256_Update(&ctx
, p_bytes
, key_len
);
168 SHA256_Update(&ctx
, alt_result
, 32);
170 SHA256_Update(&ctx
, p_bytes
, key_len
);
172 SHA256_Final(alt_result
, &ctx
);
175 CopyMem(hash
, alt_result
, SHA256_DIGEST_SIZE
);
183 static EFI_STATUS
sha512_crypt (const char *key
, UINT32 key_len
,
184 const char *salt
, UINT32 salt_size
,
185 const UINT32 rounds
, UINT8
*hash
)
187 SHA512_CTX ctx
, alt_ctx
;
188 UINT8 alt_result
[SHA512_DIGEST_LENGTH
];
189 UINT8 tmp_result
[SHA512_DIGEST_LENGTH
];
190 UINT8
*cp
, *p_bytes
, *s_bytes
;
194 SHA512_Update(&ctx
, key
, key_len
);
195 SHA512_Update(&ctx
, salt
, salt_size
);
197 SHA512_Init(&alt_ctx
);
198 SHA512_Update(&alt_ctx
, key
, key_len
);
199 SHA512_Update(&alt_ctx
, salt
, salt_size
);
200 SHA512_Update(&alt_ctx
, key
, key_len
);
202 SHA512_Final(alt_result
, &alt_ctx
);
204 for (cnt
= key_len
; cnt
> 64; cnt
-= 64)
205 SHA512_Update(&ctx
, alt_result
, 64);
206 SHA512_Update(&ctx
, alt_result
, cnt
);
208 for (cnt
= key_len
; cnt
> 0; cnt
>>= 1) {
209 if ((cnt
& 1) != 0) {
210 SHA512_Update(&ctx
, alt_result
, 64);
212 SHA512_Update(&ctx
, key
, key_len
);
215 SHA512_Final(alt_result
, &ctx
);
217 SHA512_Init(&alt_ctx
);
218 for (cnt
= 0; cnt
< key_len
; ++cnt
)
219 SHA512_Update(&alt_ctx
, key
, key_len
);
220 SHA512_Final(tmp_result
, &alt_ctx
);
222 cp
= p_bytes
= AllocatePool(key_len
);
223 for (cnt
= key_len
; cnt
>= 64; cnt
-= 64) {
224 CopyMem(cp
, tmp_result
, 64);
227 CopyMem(cp
, tmp_result
, cnt
);
229 SHA512_Init(&alt_ctx
);
230 for (cnt
= 0; cnt
< 16ul + alt_result
[0]; ++cnt
)
231 SHA512_Update(&alt_ctx
, salt
, salt_size
);
232 SHA512_Final(tmp_result
, &alt_ctx
);
234 cp
= s_bytes
= AllocatePool(salt_size
);
235 for (cnt
= salt_size
; cnt
>= 64; cnt
-= 64) {
236 CopyMem(cp
, tmp_result
, 64);
239 CopyMem(cp
, tmp_result
, cnt
);
241 for (cnt
= 0; cnt
< rounds
; ++cnt
) {
245 SHA512_Update(&ctx
, p_bytes
, key_len
);
247 SHA512_Update(&ctx
, alt_result
, 64);
250 SHA512_Update(&ctx
, s_bytes
, salt_size
);
253 SHA512_Update(&ctx
, p_bytes
, key_len
);
256 SHA512_Update(&ctx
, alt_result
, 64);
258 SHA512_Update(&ctx
, p_bytes
, key_len
);
260 SHA512_Final(alt_result
, &ctx
);
263 CopyMem(hash
, alt_result
, SHA512_DIGEST_LENGTH
);
271 #define BF_RESULT_SIZE (7 + 22 + 31 + 1)
273 static EFI_STATUS
blowfish_crypt (const char *key
, const char *salt
, UINT8
*hash
)
275 char *retval
, result
[BF_RESULT_SIZE
];
277 retval
= crypt_blowfish_rn (key
, salt
, result
, BF_RESULT_SIZE
);
279 return EFI_UNSUPPORTED
;
281 CopyMem(hash
, result
+ 7 + 22, BF_RESULT_SIZE
);
286 EFI_STATUS
password_crypt (const char *password
, UINT32 pw_length
,
287 const PASSWORD_CRYPT
*pw_crypt
, UINT8
*hash
)
289 EFI_STATUS efi_status
;
292 return EFI_INVALID_PARAMETER
;
294 switch (pw_crypt
->method
) {
295 case TRADITIONAL_DES
:
296 case EXTEND_BSDI_DES
:
297 efi_status
= EFI_UNSUPPORTED
;
300 efi_status
= md5_crypt (password
, pw_length
,
301 (char *)pw_crypt
->salt
,
302 pw_crypt
->salt_size
, hash
);
305 efi_status
= sha256_crypt(password
, pw_length
,
306 (char *)pw_crypt
->salt
,
308 pw_crypt
->iter_count
, hash
);
311 efi_status
= sha512_crypt(password
, pw_length
,
312 (char *)pw_crypt
->salt
,
314 pw_crypt
->iter_count
, hash
);
317 if (pw_crypt
->salt_size
!= (7 + 22 + 1)) {
318 efi_status
= EFI_INVALID_PARAMETER
;
321 efi_status
= blowfish_crypt(password
, (char *)pw_crypt
->salt
,
325 return EFI_INVALID_PARAMETER
;