]>
git.proxmox.com Git - efi-boot-shim.git/blob - PasswordCrypt.c
3 #include <Library/BaseCryptLib.h>
4 #include <openssl/sha.h>
5 #include <openssl/md5.h>
6 #include <openssl/des.h>
7 #include "PasswordCrypt.h"
8 #include "crypt_blowfish.h"
10 #define TRAD_DES_HASH_SIZE 13 /* (64/6+1) + (12/6) */
11 #define BSDI_DES_HASH_SIZE 20 /* (64/6+1) + (24/6) + 4 + 1 */
12 #define BLOWFISH_HASH_SIZE 31 /* 184/6+1 */
14 UINT16
get_hash_size (const UINT16 method
)
18 return TRAD_DES_HASH_SIZE
;
20 return BSDI_DES_HASH_SIZE
;
22 return MD5_DIGEST_LENGTH
;
24 return SHA256_DIGEST_LENGTH
;
26 return SHA512_DIGEST_LENGTH
;
28 return BLOWFISH_HASH_SIZE
;
34 static EFI_STATUS
trad_des_crypt (const char *key
, const char *salt
, UINT8
*hash
)
36 char result
[TRAD_DES_HASH_SIZE
+ 1];
39 ret
= DES_fcrypt(key
, salt
, result
);
41 CopyMem(hash
, result
, TRAD_DES_HASH_SIZE
);
45 return EFI_UNSUPPORTED
;
48 static const char md5_salt_prefix
[] = "$1$";
50 static EFI_STATUS
md5_crypt (const char *key
, UINT32 key_len
,
51 const char *salt
, UINT32 salt_size
,
55 UINT8 alt_result
[MD5_DIGEST_LENGTH
];
59 MD5_Update(&ctx
, key
, key_len
);
60 MD5_Update(&ctx
, md5_salt_prefix
, sizeof(md5_salt_prefix
) - 1);
61 MD5_Update(&ctx
, salt
, salt_size
);
64 MD5_Update(&alt_ctx
, key
, key_len
);
65 MD5_Update(&alt_ctx
, salt
, salt_size
);
66 MD5_Update(&alt_ctx
, key
, key_len
);
67 MD5_Final(alt_result
, &alt_ctx
);
69 for (cnt
= key_len
; cnt
> 16; cnt
-= 16)
70 MD5_Update(&ctx
, alt_result
, 16);
71 MD5_Update(&ctx
, alt_result
, cnt
);
75 for (cnt
= key_len
; cnt
> 0; cnt
>>= 1) {
77 MD5_Update(&ctx
, alt_result
, 1);
79 MD5_Update(&ctx
, key
, 1);
82 MD5_Final(alt_result
, &ctx
);
84 for (cnt
= 0; cnt
< 1000; ++cnt
) {
88 MD5_Update(&ctx
, key
, key_len
);
90 MD5_Update(&ctx
, alt_result
, 16);
93 MD5_Update(&ctx
, salt
, salt_size
);
96 MD5_Update(&ctx
, key
, key_len
);
99 MD5_Update(&ctx
, alt_result
, 16);
101 MD5_Update(&ctx
, key
, key_len
);
103 MD5_Final(alt_result
, &ctx
);
106 CopyMem(hash
, alt_result
, MD5_DIGEST_LENGTH
);
111 static EFI_STATUS
sha256_crypt (const char *key
, UINT32 key_len
,
112 const char *salt
, UINT32 salt_size
,
113 const UINT32 rounds
, UINT8
*hash
)
115 SHA256_CTX ctx
, alt_ctx
;
116 UINT8 alt_result
[SHA256_DIGEST_SIZE
];
117 UINT8 tmp_result
[SHA256_DIGEST_SIZE
];
118 UINT8
*cp
, *p_bytes
, *s_bytes
;
122 SHA256_Update(&ctx
, key
, key_len
);
123 SHA256_Update(&ctx
, salt
, salt_size
);
125 SHA256_Init(&alt_ctx
);
126 SHA256_Update(&alt_ctx
, key
, key_len
);
127 SHA256_Update(&alt_ctx
, salt
, salt_size
);
128 SHA256_Update(&alt_ctx
, key
, key_len
);
129 SHA256_Final(alt_result
, &alt_ctx
);
131 for (cnt
= key_len
; cnt
> 32; cnt
-= 32)
132 SHA256_Update(&ctx
, alt_result
, 32);
133 SHA256_Update(&ctx
, alt_result
, cnt
);
135 for (cnt
= key_len
; cnt
> 0; cnt
>>= 1) {
136 if ((cnt
& 1) != 0) {
137 SHA256_Update(&ctx
, alt_result
, 32);
139 SHA256_Update(&ctx
, key
, key_len
);
142 SHA256_Final(alt_result
, &ctx
);
144 SHA256_Init(&alt_ctx
);
145 for (cnt
= 0; cnt
< key_len
; ++cnt
)
146 SHA256_Update(&alt_ctx
, key
, key_len
);
147 SHA256_Final(tmp_result
, &alt_ctx
);
149 cp
= p_bytes
= AllocatePool(key_len
);
150 for (cnt
= key_len
; cnt
>= 32; cnt
-= 32) {
151 CopyMem(cp
, tmp_result
, 32);
154 CopyMem(cp
, tmp_result
, cnt
);
156 SHA256_Init(&alt_ctx
);
157 for (cnt
= 0; cnt
< 16ul + alt_result
[0]; ++cnt
)
158 SHA256_Update(&alt_ctx
, salt
, salt_size
);
159 SHA256_Final(tmp_result
, &alt_ctx
);
161 cp
= s_bytes
= AllocatePool(salt_size
);
162 for (cnt
= salt_size
; cnt
>= 32; cnt
-= 32) {
163 CopyMem(cp
, tmp_result
, 32);
166 CopyMem(cp
, tmp_result
, cnt
);
168 for (cnt
= 0; cnt
< rounds
; ++cnt
) {
172 SHA256_Update(&ctx
, p_bytes
, key_len
);
174 SHA256_Update(&ctx
, alt_result
, 32);
177 SHA256_Update(&ctx
, s_bytes
, salt_size
);
180 SHA256_Update(&ctx
, p_bytes
, key_len
);
183 SHA256_Update(&ctx
, alt_result
, 32);
185 SHA256_Update(&ctx
, p_bytes
, key_len
);
187 SHA256_Final(alt_result
, &ctx
);
190 CopyMem(hash
, alt_result
, SHA256_DIGEST_SIZE
);
198 static EFI_STATUS
sha512_crypt (const char *key
, UINT32 key_len
,
199 const char *salt
, UINT32 salt_size
,
200 const UINT32 rounds
, UINT8
*hash
)
202 SHA512_CTX ctx
, alt_ctx
;
203 UINT8 alt_result
[SHA512_DIGEST_LENGTH
];
204 UINT8 tmp_result
[SHA512_DIGEST_LENGTH
];
205 UINT8
*cp
, *p_bytes
, *s_bytes
;
209 SHA512_Update(&ctx
, key
, key_len
);
210 SHA512_Update(&ctx
, salt
, salt_size
);
212 SHA512_Init(&alt_ctx
);
213 SHA512_Update(&alt_ctx
, key
, key_len
);
214 SHA512_Update(&alt_ctx
, salt
, salt_size
);
215 SHA512_Update(&alt_ctx
, key
, key_len
);
217 SHA512_Final(alt_result
, &alt_ctx
);
219 for (cnt
= key_len
; cnt
> 64; cnt
-= 64)
220 SHA512_Update(&ctx
, alt_result
, 64);
221 SHA512_Update(&ctx
, alt_result
, cnt
);
223 for (cnt
= key_len
; cnt
> 0; cnt
>>= 1) {
224 if ((cnt
& 1) != 0) {
225 SHA512_Update(&ctx
, alt_result
, 64);
227 SHA512_Update(&ctx
, key
, key_len
);
230 SHA512_Final(alt_result
, &ctx
);
232 SHA512_Init(&alt_ctx
);
233 for (cnt
= 0; cnt
< key_len
; ++cnt
)
234 SHA512_Update(&alt_ctx
, key
, key_len
);
235 SHA512_Final(tmp_result
, &alt_ctx
);
237 cp
= p_bytes
= AllocatePool(key_len
);
238 for (cnt
= key_len
; cnt
>= 64; cnt
-= 64) {
239 CopyMem(cp
, tmp_result
, 64);
242 CopyMem(cp
, tmp_result
, cnt
);
244 SHA512_Init(&alt_ctx
);
245 for (cnt
= 0; cnt
< 16ul + alt_result
[0]; ++cnt
)
246 SHA512_Update(&alt_ctx
, salt
, salt_size
);
247 SHA512_Final(tmp_result
, &alt_ctx
);
249 cp
= s_bytes
= AllocatePool(salt_size
);
250 for (cnt
= salt_size
; cnt
>= 64; cnt
-= 64) {
251 CopyMem(cp
, tmp_result
, 64);
254 CopyMem(cp
, tmp_result
, cnt
);
256 for (cnt
= 0; cnt
< rounds
; ++cnt
) {
260 SHA512_Update(&ctx
, p_bytes
, key_len
);
262 SHA512_Update(&ctx
, alt_result
, 64);
265 SHA512_Update(&ctx
, s_bytes
, salt_size
);
268 SHA512_Update(&ctx
, p_bytes
, key_len
);
271 SHA512_Update(&ctx
, alt_result
, 64);
273 SHA512_Update(&ctx
, p_bytes
, key_len
);
275 SHA512_Final(alt_result
, &ctx
);
278 CopyMem(hash
, alt_result
, SHA512_DIGEST_LENGTH
);
286 #define BF_RESULT_SIZE (7 + 22 + 31 + 1)
288 static EFI_STATUS
blowfish_crypt (const char *key
, const char *salt
, UINT8
*hash
)
290 char *retval
, result
[BF_RESULT_SIZE
];
292 retval
= crypt_blowfish_rn (key
, salt
, result
, BF_RESULT_SIZE
);
294 return EFI_UNSUPPORTED
;
296 CopyMem(hash
, result
+ 7 + 22, BF_RESULT_SIZE
);
301 EFI_STATUS
password_crypt (const char *password
, UINT32 pw_length
,
302 const PASSWORD_CRYPT
*pw_crypt
, UINT8
*hash
)
307 return EFI_INVALID_PARAMETER
;
309 switch (pw_crypt
->method
) {
310 case TRADITIONAL_DES
:
311 status
= trad_des_crypt (password
, (char *)pw_crypt
->salt
, hash
);
313 case EXTEND_BSDI_DES
:
314 status
= EFI_UNSUPPORTED
;
317 status
= md5_crypt (password
, pw_length
, (char *)pw_crypt
->salt
,
318 pw_crypt
->salt_size
, hash
);
321 status
= sha256_crypt(password
, pw_length
, (char *)pw_crypt
->salt
,
322 pw_crypt
->salt_size
, pw_crypt
->iter_count
,
326 status
= sha512_crypt(password
, pw_length
, (char *)pw_crypt
->salt
,
327 pw_crypt
->salt_size
, pw_crypt
->iter_count
,
331 if (pw_crypt
->salt_size
!= (7 + 22 + 1)) {
332 status
= EFI_INVALID_PARAMETER
;
335 status
= blowfish_crypt(password
, (char *)pw_crypt
->salt
, hash
);
338 return EFI_INVALID_PARAMETER
;