1 |
From f16f247d30f868e84f31e24792b4464488f1c009 Mon Sep 17 00:00:00 2001 |
2 |
From: Peter Wu <peter@lekensteyn.nl> |
3 |
Date: Tue, 2 May 2017 15:53:38 +0200 |
4 |
Subject: [PATCH] vfdecrypt: OpenSSL 1.1 compatibility |
5 |
|
6 |
Allocate contexts from the heap on all OpenSSL versions, this is needed |
7 |
since OpenSSL 1.1.0. No attempt is done at addressing issues like global |
8 |
variables and fixing potential memleaks on error paths. |
9 |
|
10 |
Compile-tested only with OpenSSL 1.1.0e (Arch Linux) and OpenSSL 1.0.2g |
11 |
(Ubuntu 16.04), I have no test file. |
12 |
|
13 |
Fixes https://github.com/Lekensteyn/dmg2img/issues/4 |
14 |
--- |
15 |
vfdecrypt.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++-------------- |
16 |
1 file changed, 80 insertions(+), 23 deletions(-) |
17 |
|
18 |
diff --git a/vfdecrypt.c b/vfdecrypt.c |
19 |
index 56d3530..b1a36d3 100644 |
20 |
--- a/vfdecrypt.c |
21 |
+++ b/vfdecrypt.c |
22 |
@@ -183,7 +183,7 @@ void adjust_v2_header_byteorder(cencrypted_v2_pwheader *pwhdr) { |
23 |
pwhdr->encrypted_keyblob_size = htonl(pwhdr->encrypted_keyblob_size); |
24 |
} |
25 |
|
26 |
-HMAC_CTX hmacsha1_ctx; |
27 |
+HMAC_CTX *hmacsha1_ctx; |
28 |
AES_KEY aes_decrypt_key; |
29 |
int CHUNK_SIZE=4096; // default |
30 |
|
31 |
@@ -196,9 +196,9 @@ void compute_iv(uint32_t chunk_no, uint8_t *iv) { |
32 |
unsigned int mdLen; |
33 |
|
34 |
chunk_no = OSSwapHostToBigInt32(chunk_no); |
35 |
- HMAC_Init_ex(&hmacsha1_ctx, NULL, 0, NULL, NULL); |
36 |
- HMAC_Update(&hmacsha1_ctx, (void *) &chunk_no, sizeof(uint32_t)); |
37 |
- HMAC_Final(&hmacsha1_ctx, mdResult, &mdLen); |
38 |
+ HMAC_Init_ex(hmacsha1_ctx, NULL, 0, NULL, NULL); |
39 |
+ HMAC_Update(hmacsha1_ctx, (void *) &chunk_no, sizeof(uint32_t)); |
40 |
+ HMAC_Final(hmacsha1_ctx, mdResult, &mdLen); |
41 |
memcpy(iv, mdResult, CIPHER_BLOCKSIZE); |
42 |
} |
43 |
|
44 |
@@ -212,52 +212,75 @@ void decrypt_chunk(uint8_t *ctext, uint8_t *ptext, uint32_t chunk_no) { |
45 |
/* DES3-EDE unwrap operation loosely based on to RFC 2630, section 12.6 |
46 |
* wrapped_key has to be 40 bytes in length. */ |
47 |
int apple_des3_ede_unwrap_key(uint8_t *wrapped_key, int wrapped_key_len, uint8_t *decryptKey, uint8_t *unwrapped_key) { |
48 |
- EVP_CIPHER_CTX ctx; |
49 |
+ EVP_CIPHER_CTX *ctx; |
50 |
uint8_t *TEMP1, *TEMP2, *CEKICV; |
51 |
uint8_t IV[8] = { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 }; |
52 |
int outlen, tmplen, i; |
53 |
|
54 |
- EVP_CIPHER_CTX_init(&ctx); |
55 |
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L |
56 |
+ ctx = EVP_CIPHER_CTX_new(); |
57 |
+#else |
58 |
+ ctx = malloc(sizeof(*ctx)); |
59 |
+#endif |
60 |
+ if (!ctx) { |
61 |
+ fprintf(stderr, "Out of memory: EVP_CIPHER_CTX!\n"); |
62 |
+ return(-1); |
63 |
+ } |
64 |
+ |
65 |
+ EVP_CIPHER_CTX_init(ctx); |
66 |
/* result of the decryption operation shouldn't be bigger than ciphertext */ |
67 |
TEMP1 = malloc(wrapped_key_len); |
68 |
TEMP2 = malloc(wrapped_key_len); |
69 |
CEKICV = malloc(wrapped_key_len); |
70 |
/* uses PKCS#7 padding for symmetric key operations by default */ |
71 |
- EVP_DecryptInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, decryptKey, IV); |
72 |
+ EVP_DecryptInit_ex(ctx, EVP_des_ede3_cbc(), NULL, decryptKey, IV); |
73 |
|
74 |
- if(!EVP_DecryptUpdate(&ctx, TEMP1, &outlen, wrapped_key, wrapped_key_len)) { |
75 |
+ if(!EVP_DecryptUpdate(ctx, TEMP1, &outlen, wrapped_key, wrapped_key_len)) { |
76 |
fprintf(stderr, "internal error (1) during key unwrap operation!\n"); |
77 |
return(-1); |
78 |
} |
79 |
- if(!EVP_DecryptFinal_ex(&ctx, TEMP1 + outlen, &tmplen)) { |
80 |
+ if(!EVP_DecryptFinal_ex(ctx, TEMP1 + outlen, &tmplen)) { |
81 |
fprintf(stderr, "internal error (2) during key unwrap operation!\n"); |
82 |
return(-1); |
83 |
} |
84 |
outlen += tmplen; |
85 |
- EVP_CIPHER_CTX_cleanup(&ctx); |
86 |
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L |
87 |
+ EVP_CIPHER_CTX_reset(ctx); |
88 |
+#else |
89 |
+ EVP_CIPHER_CTX_cleanup(ctx); |
90 |
+#endif |
91 |
|
92 |
/* reverse order of TEMP3 */ |
93 |
for(i = 0; i < outlen; i++) TEMP2[i] = TEMP1[outlen - i - 1]; |
94 |
|
95 |
- EVP_CIPHER_CTX_init(&ctx); |
96 |
+ EVP_CIPHER_CTX_init(ctx); |
97 |
/* uses PKCS#7 padding for symmetric key operations by default */ |
98 |
- EVP_DecryptInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, decryptKey, TEMP2); |
99 |
- if(!EVP_DecryptUpdate(&ctx, CEKICV, &outlen, TEMP2+8, outlen-8)) { |
100 |
+ EVP_DecryptInit_ex(ctx, EVP_des_ede3_cbc(), NULL, decryptKey, TEMP2); |
101 |
+ if(!EVP_DecryptUpdate(ctx, CEKICV, &outlen, TEMP2+8, outlen-8)) { |
102 |
fprintf(stderr, "internal error (3) during key unwrap operation!\n"); |
103 |
return(-1); |
104 |
} |
105 |
- if(!EVP_DecryptFinal_ex(&ctx, CEKICV + outlen, &tmplen)) { |
106 |
+ if(!EVP_DecryptFinal_ex(ctx, CEKICV + outlen, &tmplen)) { |
107 |
fprintf(stderr, "internal error (4) during key unwrap operation!\n"); |
108 |
return(-1); |
109 |
} |
110 |
|
111 |
outlen += tmplen; |
112 |
- EVP_CIPHER_CTX_cleanup(&ctx); |
113 |
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L |
114 |
+ EVP_CIPHER_CTX_reset(ctx); |
115 |
+#else |
116 |
+ EVP_CIPHER_CTX_cleanup(ctx); |
117 |
+#endif |
118 |
|
119 |
memcpy(unwrapped_key, CEKICV+4, outlen-4); |
120 |
free(TEMP1); |
121 |
free(TEMP2); |
122 |
free(CEKICV); |
123 |
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L |
124 |
+ EVP_CIPHER_CTX_free(ctx); |
125 |
+#else |
126 |
+ free(ctx); |
127 |
+#endif |
128 |
return(0); |
129 |
} |
130 |
|
131 |
@@ -279,31 +302,46 @@ int unwrap_v1_header(char *passphrase, cencrypted_v1_header *header, uint8_t *ae |
132 |
int unwrap_v2_header(char *passphrase, cencrypted_v2_pwheader *header, uint8_t *aes_key, uint8_t *hmacsha1_key) { |
133 |
/* derived key is a 3DES-EDE key */ |
134 |
uint8_t derived_key[192/8]; |
135 |
- EVP_CIPHER_CTX ctx; |
136 |
+ EVP_CIPHER_CTX *ctx; |
137 |
uint8_t *TEMP1; |
138 |
int outlen, tmplen; |
139 |
|
140 |
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L |
141 |
+ ctx = EVP_CIPHER_CTX_new(); |
142 |
+#else |
143 |
+ ctx = malloc(sizeof(*ctx)); |
144 |
+#endif |
145 |
+ if (!ctx) { |
146 |
+ fprintf(stderr, "Out of memory: EVP_CIPHER_CTX!\n"); |
147 |
+ return(-1); |
148 |
+ } |
149 |
+ |
150 |
PKCS5_PBKDF2_HMAC_SHA1(passphrase, strlen(passphrase), (unsigned char*)header->kdf_salt, 20, |
151 |
PBKDF2_ITERATION_COUNT, sizeof(derived_key), derived_key); |
152 |
|
153 |
print_hex(derived_key, 192/8); |
154 |
|
155 |
- EVP_CIPHER_CTX_init(&ctx); |
156 |
+ EVP_CIPHER_CTX_init(ctx); |
157 |
/* result of the decryption operation shouldn't be bigger than ciphertext */ |
158 |
TEMP1 = malloc(header->encrypted_keyblob_size); |
159 |
/* uses PKCS#7 padding for symmetric key operations by default */ |
160 |
- EVP_DecryptInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, derived_key, header->blob_enc_iv); |
161 |
+ EVP_DecryptInit_ex(ctx, EVP_des_ede3_cbc(), NULL, derived_key, header->blob_enc_iv); |
162 |
|
163 |
- if(!EVP_DecryptUpdate(&ctx, TEMP1, &outlen, header->encrypted_keyblob, header->encrypted_keyblob_size)) { |
164 |
+ if(!EVP_DecryptUpdate(ctx, TEMP1, &outlen, header->encrypted_keyblob, header->encrypted_keyblob_size)) { |
165 |
fprintf(stderr, "internal error (1) during key unwrap operation!\n"); |
166 |
return(-1); |
167 |
} |
168 |
- if(!EVP_DecryptFinal_ex(&ctx, TEMP1 + outlen, &tmplen)) { |
169 |
+ if(!EVP_DecryptFinal_ex(ctx, TEMP1 + outlen, &tmplen)) { |
170 |
fprintf(stderr, "internal error (2) during key unwrap operation!\n"); |
171 |
return(-1); |
172 |
} |
173 |
outlen += tmplen; |
174 |
- EVP_CIPHER_CTX_cleanup(&ctx); |
175 |
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L |
176 |
+ EVP_CIPHER_CTX_free(ctx); |
177 |
+#else |
178 |
+ EVP_CIPHER_CTX_cleanup(ctx); |
179 |
+ free(ctx); |
180 |
+#endif |
181 |
memcpy(aes_key, TEMP1, 16); |
182 |
memcpy(hmacsha1_key, TEMP1, 20); |
183 |
|
184 |
@@ -446,8 +484,21 @@ int main(int argc, char *argv[]) { |
185 |
CHUNK_SIZE = v2header.blocksize; |
186 |
} |
187 |
|
188 |
- HMAC_CTX_init(&hmacsha1_ctx); |
189 |
- HMAC_Init_ex(&hmacsha1_ctx, hmacsha1_key, sizeof(hmacsha1_key), EVP_sha1(), NULL); |
190 |
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L |
191 |
+ hmacsha1_ctx = HMAC_CTX_new(); |
192 |
+#else |
193 |
+ hmacsha1_ctx = malloc(sizeof(*hmacsha1_ctx)); |
194 |
+#endif |
195 |
+ if (!hmacsha1_ctx) { |
196 |
+ fprintf(stderr, "Out of memory: HMAC CTX!\n"); |
197 |
+ exit(1); |
198 |
+ } |
199 |
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L |
200 |
+ HMAC_CTX_reset(hmacsha1_ctx); |
201 |
+#else |
202 |
+ HMAC_CTX_init(hmacsha1_ctx); |
203 |
+#endif |
204 |
+ HMAC_Init_ex(hmacsha1_ctx, hmacsha1_key, sizeof(hmacsha1_key), EVP_sha1(), NULL); |
205 |
AES_set_decrypt_key(aes_key, CIPHER_KEY_LENGTH * 8, &aes_decrypt_key); |
206 |
|
207 |
if (verbose >= 1) { |
208 |
@@ -472,5 +523,11 @@ int main(int argc, char *argv[]) { |
209 |
} |
210 |
|
211 |
if (verbose) fprintf(stderr, "%"PRIX32" chunks written\n", chunk_no); |
212 |
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L |
213 |
+ HMAC_CTX_free(hmacsha1_ctx); |
214 |
+#else |
215 |
+ HMAC_CTX_cleanup(hmacsha1_ctx); |
216 |
+ free(hmacsha1_ctx); |
217 |
+#endif |
218 |
return(0); |
219 |
} |