Skip to content

Commit 86aaf37

Browse files
committed
Add compatibility with OpenSSL 1.1.0
In their continued wisdom OpenSSL developers keep breaking APIs left and right with very poor documentation and forward/backward source compatibility. Signed-off-by: Simo Sorce <simo@redhat.com> Closes #96 Closes #97
1 parent 7156420 commit 86aaf37

File tree

1 file changed

+76
-31
lines changed

1 file changed

+76
-31
lines changed

src/crypto.c

Lines changed: 76 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,48 @@
66
#include <stdbool.h>
77
#include "crypto.h"
88

9+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
10+
HMAC_CTX *HMAC_CTX_new(void)
11+
{
12+
HMAC_CTX *ctx;
13+
14+
ctx = OPENSSL_malloc(sizeof(HMAC_CTX));
15+
if (!ctx) return NULL;
16+
17+
HMAC_CTX_init(ctx);
18+
19+
return ctx;
20+
}
21+
22+
void HMAC_CTX_free(HMAC_CTX *ctx)
23+
{
24+
if (ctx == NULL) return;
25+
26+
HMAC_CTX_cleanup(ctx);
27+
OPENSSL_free(ctx);
28+
}
29+
30+
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
31+
{
32+
EVP_CIPHER_CTX *ctx;
33+
34+
ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX));
35+
if (!ctx) return NULL;
36+
37+
EVP_CIPHER_CTX_init(ctx);
38+
39+
return ctx;
40+
}
41+
42+
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
43+
{
44+
if (ctx == NULL) return;
45+
46+
EVP_CIPHER_CTX_cleanup(ctx);
47+
OPENSSL_free(ctx);
48+
}
49+
#endif
50+
951
struct seal_key {
1052
const EVP_CIPHER *cipher;
1153
const EVP_MD *md;
@@ -29,7 +71,7 @@ apr_status_t SEAL_KEY_CREATE(apr_pool_t *p, struct seal_key **skey,
2971
goto done;
3072
}
3173

32-
keylen = n->cipher->key_len;
74+
keylen = EVP_CIPHER_key_length(n->cipher);
3375

3476
n->md = EVP_sha256();
3577
if (!n->md) {
@@ -81,24 +123,25 @@ apr_status_t SEAL_KEY_CREATE(apr_pool_t *p, struct seal_key **skey,
81123
apr_status_t HMAC_BUFFER(struct seal_key *skey, struct databuf *buffer,
82124
struct databuf *result)
83125
{
84-
HMAC_CTX hmac_ctx = { 0 };
126+
HMAC_CTX *hmac_ctx;
85127
unsigned int len;
86-
int ret;
128+
int ret = 0;
87129

88130
/* now MAC the buffer */
89-
HMAC_CTX_init(&hmac_ctx);
131+
hmac_ctx = HMAC_CTX_new();
132+
if (!hmac_ctx) goto done;
90133

91-
ret = HMAC_Init_ex(&hmac_ctx, skey->hkey,
92-
skey->cipher->key_len, skey->md, NULL);
134+
ret = HMAC_Init_ex(hmac_ctx, skey->hkey,
135+
EVP_CIPHER_key_length(skey->cipher), skey->md, NULL);
93136
if (ret == 0) goto done;
94137

95-
ret = HMAC_Update(&hmac_ctx, buffer->value, buffer->length);
138+
ret = HMAC_Update(hmac_ctx, buffer->value, buffer->length);
96139
if (ret == 0) goto done;
97140

98-
ret = HMAC_Final(&hmac_ctx, result->value, &len);
141+
ret = HMAC_Final(hmac_ctx, result->value, &len);
99142

100143
done:
101-
HMAC_CTX_cleanup(&hmac_ctx);
144+
HMAC_CTX_free(hmac_ctx);
102145
if (ret == 0) return EFAULT;
103146

104147
result->length = len;
@@ -108,15 +151,15 @@ apr_status_t HMAC_BUFFER(struct seal_key *skey, struct databuf *buffer,
108151
apr_status_t SEAL_BUFFER(apr_pool_t *p, struct seal_key *skey,
109152
struct databuf *plain, struct databuf *cipher)
110153
{
111-
int blksz = skey->cipher->block_size;
154+
int blksz = EVP_CIPHER_block_size(skey->cipher);
112155
apr_status_t err = EFAULT;
113-
EVP_CIPHER_CTX ctx = { 0 };
156+
EVP_CIPHER_CTX *ctx;
114157
uint8_t rbuf[blksz];
115158
struct databuf hmacbuf;
116159
int outlen, totlen;
117160
int ret;
118161

119-
EVP_CIPHER_CTX_init(&ctx);
162+
ctx = EVP_CIPHER_CTX_new();
120163

121164
/* confounder to avoid exposing random numbers directly to clients
122165
* as IVs */
@@ -126,30 +169,30 @@ apr_status_t SEAL_BUFFER(apr_pool_t *p, struct seal_key *skey,
126169
if (cipher->length == 0) {
127170
/* add space for confounder and padding and MAC */
128171
cipher->length = (plain->length / blksz + 2) * blksz;
129-
cipher->value = apr_palloc(p, cipher->length + skey->md->md_size);
172+
cipher->value = apr_palloc(p, cipher->length + EVP_MD_size(skey->md));
130173
if (!cipher->value) {
131174
err = ENOMEM;
132175
goto done;
133176
}
134177
}
135178

136-
ret = EVP_EncryptInit_ex(&ctx, skey->cipher, NULL, skey->ekey, NULL);
179+
ret = EVP_EncryptInit_ex(ctx, skey->cipher, NULL, skey->ekey, NULL);
137180
if (ret == 0) goto done;
138181
totlen = 0;
139182

140183
outlen = cipher->length;
141-
ret = EVP_EncryptUpdate(&ctx, cipher->value, &outlen, rbuf, sizeof(rbuf));
184+
ret = EVP_EncryptUpdate(ctx, cipher->value, &outlen, rbuf, sizeof(rbuf));
142185
if (ret == 0) goto done;
143186
totlen += outlen;
144187

145188
outlen = cipher->length - totlen;
146-
ret = EVP_EncryptUpdate(&ctx, &cipher->value[totlen], &outlen,
189+
ret = EVP_EncryptUpdate(ctx, &cipher->value[totlen], &outlen,
147190
plain->value, plain->length);
148191
if (ret == 0) goto done;
149192
totlen += outlen;
150193

151194
outlen = cipher->length - totlen;
152-
ret = EVP_EncryptFinal_ex(&ctx, &cipher->value[totlen], &outlen);
195+
ret = EVP_EncryptFinal_ex(ctx, &cipher->value[totlen], &outlen);
153196
if (ret == 0) goto done;
154197
totlen += outlen;
155198

@@ -163,36 +206,38 @@ apr_status_t SEAL_BUFFER(apr_pool_t *p, struct seal_key *skey,
163206
err = 0;
164207

165208
done:
166-
EVP_CIPHER_CTX_cleanup(&ctx);
209+
EVP_CIPHER_CTX_free(ctx);
167210
return err;
168211
}
169212

170213
apr_status_t UNSEAL_BUFFER(apr_pool_t *p, struct seal_key *skey,
171214
struct databuf *cipher, struct databuf *plain)
172215
{
173216
apr_status_t err = EFAULT;
174-
EVP_CIPHER_CTX ctx = { 0 };
175-
unsigned char mac[skey->md->md_size];
217+
EVP_CIPHER_CTX *ctx = NULL;
218+
int blksz = EVP_CIPHER_block_size(skey->cipher);
219+
int md_size = EVP_MD_size(skey->md);
220+
unsigned char mac[md_size];
176221
struct databuf hmacbuf;
177222
int outlen, totlen;
178223
volatile bool equal = true;
179224
int ret, i;
180225

181226
/* check MAC first */
182-
cipher->length -= skey->md->md_size;
227+
cipher->length -= md_size;
183228
hmacbuf.value = mac;
184229
ret = HMAC_BUFFER(skey, cipher, &hmacbuf);
185230
if (ret != 0) goto done;
186231

187-
if (hmacbuf.length != skey->md->md_size) goto done;
188-
for (i = 0; i < skey->md->md_size; i++) {
232+
if (hmacbuf.length != md_size) goto done;
233+
for (i = 0; i < md_size; i++) {
189234
if (cipher->value[cipher->length + i] != mac[i]) equal = false;
190235
/* not breaking intentionally,
191236
* or we would allow an oracle attack */
192237
}
193238
if (!equal) goto done;
194239

195-
EVP_CIPHER_CTX_init(&ctx);
240+
ctx = EVP_CIPHER_CTX_new();
196241

197242
if (plain->length == 0) {
198243
plain->length = cipher->length;
@@ -203,37 +248,37 @@ apr_status_t UNSEAL_BUFFER(apr_pool_t *p, struct seal_key *skey,
203248
}
204249
}
205250

206-
ret = EVP_DecryptInit_ex(&ctx, skey->cipher, NULL, skey->ekey, NULL);
251+
ret = EVP_DecryptInit_ex(ctx, skey->cipher, NULL, skey->ekey, NULL);
207252
if (ret == 0) goto done;
208253

209254
totlen = 0;
210255
outlen = plain->length;
211-
ret = EVP_DecryptUpdate(&ctx, plain->value, &outlen,
256+
ret = EVP_DecryptUpdate(ctx, plain->value, &outlen,
212257
cipher->value, cipher->length);
213258
if (ret == 0) goto done;
214259

215260
totlen += outlen;
216261
outlen = plain->length - totlen;
217-
ret = EVP_DecryptFinal_ex(&ctx, plain->value, &outlen);
262+
ret = EVP_DecryptFinal_ex(ctx, plain->value, &outlen);
218263
if (ret == 0) goto done;
219264

220265
totlen += outlen;
221266
/* now remove the confounder */
222-
totlen -= skey->cipher->block_size;
223-
memmove(plain->value, plain->value + skey->cipher->block_size, totlen);
267+
totlen -= blksz;
268+
memmove(plain->value, plain->value + blksz, totlen);
224269

225270
plain->length = totlen;
226271
err = 0;
227272

228273
done:
229-
EVP_CIPHER_CTX_cleanup(&ctx);
274+
EVP_CIPHER_CTX_free(ctx);
230275
return err;
231276
}
232277

233278
int get_mac_size(struct seal_key *skey)
234279
{
235280
if (skey) {
236-
return skey->md->md_size;
281+
return EVP_MD_size(skey->md);
237282
} else {
238283
return 0;
239284
}

0 commit comments

Comments
 (0)