]>
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 "PasswordCrypt.h"
7 #include "crypt_blowfish.h"
9 #define BLOWFISH_HASH_SIZE 31 /* 184/6+1 */
11 UINT16
get_hash_size (const UINT16 method
)
14 case TRANDITIONAL_DES
:
15 return 64 / 8; /* per "man crypt" */
17 return 64 / 8; /* per "man crypt" */
19 return MD5_DIGEST_LENGTH
;
21 return SHA256_DIGEST_LENGTH
;
23 return SHA512_DIGEST_LENGTH
;
25 return BLOWFISH_HASH_SIZE
;
31 static EFI_STATUS
sha256_crypt (const char *key
, UINT32 key_len
,
32 const char *salt
, UINT32 salt_size
,
33 const UINT32 rounds
, UINT8
*hash
)
35 SHA256_CTX ctx
, alt_ctx
;
36 UINT8 alt_result
[SHA256_DIGEST_SIZE
];
37 UINT8 tmp_result
[SHA256_DIGEST_SIZE
];
38 UINT8
*cp
, *p_bytes
, *s_bytes
;
42 SHA256_Update(&ctx
, key
, key_len
);
43 SHA256_Update(&ctx
, salt
, salt_size
);
45 SHA256_Init(&alt_ctx
);
46 SHA256_Update(&alt_ctx
, key
, key_len
);
47 SHA256_Update(&alt_ctx
, salt
, salt_size
);
48 SHA256_Update(&alt_ctx
, key
, key_len
);
49 SHA256_Final(alt_result
, &alt_ctx
);
51 for (cnt
= key_len
; cnt
> 32; cnt
-= 32)
52 SHA256_Update(&ctx
, alt_result
, 32);
53 SHA256_Update(&ctx
, alt_result
, cnt
);
55 for (cnt
= key_len
; cnt
> 0; cnt
>>= 1) {
57 SHA256_Update(&ctx
, alt_result
, 32);
59 SHA256_Update(&ctx
, key
, key_len
);
62 SHA256_Final(alt_result
, &ctx
);
64 SHA256_Init(&alt_ctx
);
65 for (cnt
= 0; cnt
< key_len
; ++cnt
)
66 SHA256_Update(&alt_ctx
, key
, key_len
);
67 SHA256_Final(tmp_result
, &alt_ctx
);
69 cp
= p_bytes
= AllocatePool(key_len
);
70 for (cnt
= key_len
; cnt
>= 32; cnt
-= 32) {
71 CopyMem(cp
, tmp_result
, 32);
74 CopyMem(cp
, tmp_result
, cnt
);
76 SHA256_Init(&alt_ctx
);
77 for (cnt
= 0; cnt
< 16 + alt_result
[0]; ++cnt
)
78 SHA256_Update(&alt_ctx
, salt
, salt_size
);
79 SHA256_Final(tmp_result
, &alt_ctx
);
81 cp
= s_bytes
= AllocatePool(salt_size
);
82 for (cnt
= salt_size
; cnt
>= 32; cnt
-= 32) {
83 CopyMem(cp
, tmp_result
, 32);
86 CopyMem(cp
, tmp_result
, cnt
);
88 for (cnt
= 0; cnt
< rounds
; ++cnt
) {
92 SHA256_Update(&ctx
, p_bytes
, key_len
);
94 SHA256_Update(&ctx
, alt_result
, 32);
97 SHA256_Update(&ctx
, s_bytes
, salt_size
);
100 SHA256_Update(&ctx
, p_bytes
, key_len
);
103 SHA256_Update(&ctx
, alt_result
, 32);
105 SHA256_Update(&ctx
, p_bytes
, key_len
);
107 SHA256_Final(alt_result
, &ctx
);
110 CopyMem(hash
, alt_result
, SHA256_DIGEST_SIZE
);
118 static EFI_STATUS
sha512_crypt (const char *key
, UINT32 key_len
,
119 const char *salt
, UINT32 salt_size
,
120 const UINT32 rounds
, UINT8
*hash
)
122 SHA512_CTX ctx
, alt_ctx
;
123 UINT8 alt_result
[SHA512_DIGEST_LENGTH
];
124 UINT8 tmp_result
[SHA512_DIGEST_LENGTH
];
125 UINT8
*cp
, *p_bytes
, *s_bytes
;
129 SHA512_Update(&ctx
, key
, key_len
);
130 SHA512_Update(&ctx
, salt
, salt_size
);
132 SHA512_Init(&alt_ctx
);
133 SHA512_Update(&alt_ctx
, key
, key_len
);
134 SHA512_Update(&alt_ctx
, salt
, salt_size
);
135 SHA512_Update(&alt_ctx
, key
, key_len
);
137 SHA512_Final(alt_result
, &alt_ctx
);
139 for (cnt
= key_len
; cnt
> 64; cnt
-= 64)
140 SHA512_Update(&ctx
, alt_result
, 64);
141 SHA512_Update(&ctx
, alt_result
, cnt
);
143 for (cnt
= key_len
; cnt
> 0; cnt
>>= 1) {
144 if ((cnt
& 1) != 0) {
145 SHA512_Update(&ctx
, alt_result
, 64);
147 SHA512_Update(&ctx
, key
, key_len
);
150 SHA512_Final(alt_result
, &ctx
);
152 SHA512_Init(&alt_ctx
);
153 for (cnt
= 0; cnt
< key_len
; ++cnt
)
154 SHA512_Update(&alt_ctx
, key
, key_len
);
155 SHA512_Final(tmp_result
, &alt_ctx
);
157 cp
= p_bytes
= AllocatePool(key_len
);
158 for (cnt
= key_len
; cnt
>= 64; cnt
-= 64) {
159 CopyMem(cp
, tmp_result
, 64);
162 CopyMem(cp
, tmp_result
, cnt
);
164 SHA512_Init(&alt_ctx
);
165 for (cnt
= 0; cnt
< 16 + alt_result
[0]; ++cnt
)
166 SHA512_Update(&alt_ctx
, salt
, salt_size
);
167 SHA512_Final(tmp_result
, &alt_ctx
);
169 cp
= s_bytes
= AllocatePool(salt_size
);
170 for (cnt
= salt_size
; cnt
>= 64; cnt
-= 64) {
171 CopyMem(cp
, tmp_result
, 64);
174 CopyMem(cp
, tmp_result
, cnt
);
176 for (cnt
= 0; cnt
< rounds
; ++cnt
) {
180 SHA512_Update(&ctx
, p_bytes
, key_len
);
182 SHA512_Update(&ctx
, alt_result
, 64);
185 SHA512_Update(&ctx
, s_bytes
, salt_size
);
188 SHA512_Update(&ctx
, p_bytes
, key_len
);
191 SHA512_Update(&ctx
, alt_result
, 64);
193 SHA512_Update(&ctx
, p_bytes
, key_len
);
195 SHA512_Final(alt_result
, &ctx
);
198 CopyMem(hash
, alt_result
, SHA512_DIGEST_LENGTH
);
206 #define BF_RESULT_SIZE (7 + 22 + 31 + 1)
208 static EFI_STATUS
blowfish_crypt (const char *key
, const char *salt
, UINT8
*hash
)
210 char *retval
, result
[BF_RESULT_SIZE
];
212 retval
= crypt_blowfish_rn (key
, salt
, result
, BF_RESULT_SIZE
);
214 return EFI_UNSUPPORTED
;
216 CopyMem(hash
, result
+ 7 + 22, BF_RESULT_SIZE
);
221 EFI_STATUS
password_crypt (const char *password
, UINT32 pw_length
,
222 const PASSWORD_CRYPT
*pw_crypt
, UINT8
*hash
)
227 return EFI_INVALID_PARAMETER
;
229 switch (pw_crypt
->method
) {
230 case TRANDITIONAL_DES
:
231 case EXTEND_BSDI_DES
:
233 /* TODO unsupported */
234 status
= EFI_UNSUPPORTED
;
237 status
= sha256_crypt(password
, pw_length
, (char *)pw_crypt
->salt
,
238 pw_crypt
->salt_size
, pw_crypt
->iter_count
,
242 status
= sha512_crypt(password
, pw_length
, (char *)pw_crypt
->salt
,
243 pw_crypt
->salt_size
, pw_crypt
->iter_count
,
247 if (pw_crypt
->salt_size
!= (7 + 22 + 1)) {
248 status
= EFI_INVALID_PARAMETER
;
251 status
= blowfish_crypt(password
, (char *)pw_crypt
->salt
, hash
);
254 return EFI_INVALID_PARAMETER
;