summaryrefslogtreecommitdiff
path: root/debian/patches/01-revert_to_openssl_1.0.diff
blob: ff90ba0af1ef7ec0f398f3d25f0e4cd4e7fb13b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
commit bc48bec97b65534966da74a07ed3edb3f13f6263 (github/revert_openssl_1_1)
Author: Chris Wilson <chris+github@qwirx.com>
Date:   Sun Feb 25 08:18:34 2018 +0000

    Revert "Add support for OpenSSL 1.1 and replace deprecated function calls"
    
    Until shown to be safe. See message from Johann Glaser to the mailing list.
    
    This reverts commit 85e7efc3fa0477f60318d2cd2144503a9ea8feb9.

diff --git a/appveyor.yml b/appveyor.yml
index d75eff77..093113f7 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -18,7 +18,7 @@ configuration:
 environment:
   VisualStudioVersion: 11.0
   Generator_Base: Visual Studio 11 2012
-  OPENSSL_VERSION: 1.1.0f
+  OPENSSL_VERSION: 1.0.2f
   PCRE_VERSION: 8.38
   CMAKE_UNIBUILD_DIR: '%APPVEYOR_BUILD_FOLDER%\..\cmake'
   BOXBACKUP_VERSION_BASE: 0.12
diff --git a/infrastructure/cmake/CMakeLists.txt b/infrastructure/cmake/CMakeLists.txt
index 65f59eb8..25015452 100644
--- a/infrastructure/cmake/CMakeLists.txt
+++ b/infrastructure/cmake/CMakeLists.txt
@@ -407,26 +407,7 @@ else()
 endif()
 
 # Link to OpenSSL
-# Workaround for incorrect library suffixes searched by FindOpenSSL:
-# https://gitlab.kitware.com/cmake/cmake/issues/17604
-if(WIN32 AND MSVC)
-	find_package(OpenSSL)
-	set(OPENSSL_SSL_LIBRARY ${SSL_EAY_RELEASE})
-	set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY_RELEASE})
-	set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} crypt32)
-	find_package_handle_standard_args(OpenSSL
-	REQUIRED_VARS
-		OPENSSL_SSL_LIBRARY
-		OPENSSL_CRYPTO_LIBRARY
-		OPENSSL_INCLUDE_DIR
-	VERSION_VAR
-		OPENSSL_VERSION
-	FAIL_MESSAGE
-		"Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
-	)
-else()
-	find_package(OpenSSL REQUIRED)
-endif()
+find_package(OpenSSL REQUIRED)
 include_directories(${OPENSSL_INCLUDE_DIR})
 target_link_libraries(lib_crypto PUBLIC ${OPENSSL_LIBRARIES})
 
diff --git a/infrastructure/cmake/windows/CMakeLists.txt b/infrastructure/cmake/windows/CMakeLists.txt
index 49a1ea4d..0fbe35e3 100644
--- a/infrastructure/cmake/windows/CMakeLists.txt
+++ b/infrastructure/cmake/windows/CMakeLists.txt
@@ -15,9 +15,9 @@ set(ZLIB_VERSION    1.2.11)
 set(ZLIB_HASH SHA256=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1)
 
 # Version of OpenSSL to download, build, and compile Box Backup against:
-set(OPENSSL_VERSION 1.1.0g)
+set(OPENSSL_VERSION 1.0.2j)
 # Hash of openssl-${OPENSSL_VERSION}.tar.gz, to be verified after download:
-set(OPENSSL_HASH SHA256=de4d501267da39310905cb6dc8c6121f7a2cad45a7707f76df828fe1b85073af)
+set(OPENSSL_HASH SHA256=e7aff292be21c259c6af26469c7a9b3ba26e9abaaffd325e3dccc9785256c431)
 
 # Version of PCRE to download, build, and compile Box Backup against:
 set(PCRE_VERSION    8.39)
@@ -49,21 +49,15 @@ if(WIN32)
 		URL "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz"
 		URL_HASH ${OPENSSL_HASH}
 		DOWNLOAD_NO_PROGRESS 1
-		CONFIGURE_COMMAND perl Configure debug-VC-WIN32 no-asm no-shared
-			--prefix=${install_dir}
-			--openssldir=etc
-		# Run tests before install, but don't make the main target depend on them, so that
-		# we don't have to run them whenever we build manually on Windows.
-		TEST_BEFORE_INSTALL 1
-		TEST_EXCLUDE_FROM_MAIN 1
+		CONFIGURE_COMMAND perl Configure debug-VC-WIN32 no-asm --prefix=${install_dir}
+		COMMAND cmd /c ms\\do_ms.bat
 		# You would expect us to use nt.mak to compile a static library here, but mk1mf.pl uses the /MT[d]
 		# CRT in that case, which is incompatible with our dynamic runtime, /MD[d]. It seems that the libs
 		# built by ntdll.mak, which are compiled with /MD[d], are full libraries and not import libs,
 		# so we can link statically against them and still get a dynamic runtime.
 		BUILD_IN_SOURCE 1
-		BUILD_COMMAND   nmake /s
-		TEST_COMMAND    nmake /s test
-		INSTALL_COMMAND nmake /s install
+		BUILD_COMMAND   nmake /s /f ms\\nt.mak
+		INSTALL_COMMAND nmake /s /f ms\\nt.mak install
 	)
 elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
 	ExternalProject_Add(openssl
diff --git a/lib/crypto/CipherBlowfish.cpp b/lib/crypto/CipherBlowfish.cpp
index 4c75b1de..e16cc6ed 100644
--- a/lib/crypto/CipherBlowfish.cpp
+++ b/lib/crypto/CipherBlowfish.cpp
@@ -206,7 +206,7 @@ void CipherBlowfish::SetupParameters(EVP_CIPHER_CTX *pCipherContext) const
 	}
 	// Set key
 #ifndef HAVE_OLD_SSL
-	if(EVP_CipherInit_ex(pCipherContext, GetCipher(), NULL, (unsigned char*)mpKey, (unsigned char*)mpInitialisationVector, -1) != 1)
+	if(EVP_CipherInit_ex(pCipherContext, NULL, NULL, (unsigned char*)mpKey, (unsigned char*)mpInitialisationVector, -1) != 1)
 #else
 	if(EVP_CipherInit(pCipherContext, NULL, (unsigned char*)mKey.c_str(), (unsigned char*)mInitialisationVector, -1) != 1)
 #endif
diff --git a/lib/crypto/CipherContext.cpp b/lib/crypto/CipherContext.cpp
index 3de88c64..fd149395 100644
--- a/lib/crypto/CipherContext.cpp
+++ b/lib/crypto/CipherContext.cpp
@@ -2,7 +2,7 @@
 //
 // File
 //		Name:    CipherContext.cpp
-//		Purpose: Context for symmetric encryption / decryption
+//		Purpose: Context for symmetric encryption / descryption
 //		Created: 1/12/03
 //
 // --------------------------------------------------------------------------
@@ -50,7 +50,7 @@ CipherContext::~CipherContext()
 	if(mInitialised)
 	{
 		// Clean up
-		BOX_OPENSSL_CLEANUP_CTX(ctx);
+		EVP_CIPHER_CTX_cleanup(&ctx);
 		mInitialised = false;
 	}
 #ifdef HAVE_OLD_SSL
@@ -98,7 +98,7 @@ void CipherContext::Init(CipherContext::CipherFunction Function, const CipherDes
 	// Check for bad usage
 	if(mInitialised)
 	{
-		THROW_EXCEPTION(CipherException, AlreadyInitialised);
+		THROW_EXCEPTION(CipherException, AlreadyInitialised)
 	}
 	if(Function != Decrypt && Function != Encrypt)
 	{
@@ -109,45 +109,43 @@ void CipherContext::Init(CipherContext::CipherFunction Function, const CipherDes
 	mFunction = Function;
 
 	// Initialise the cipher
-#ifdef HAVE_OLD_SSL
-	// Use old version of init call
-	if(EVP_CipherInit(&ctx, rDescription.GetCipher(), NULL, NULL,
+#ifndef HAVE_OLD_SSL
+	EVP_CIPHER_CTX_init(&ctx); // no error return code, even though the docs says it does
+
+	if(EVP_CipherInit_ex(&ctx, rDescription.GetCipher(), NULL, NULL, NULL,
 		(mFunction == Encrypt) ? 1 : 0) != 1)
 #else
-	BOX_OPENSSL_INIT_CTX(ctx);
-
-	// Don't set key or IV yet, because we will modify the parameters:
-	if(EVP_CipherInit_ex(BOX_OPENSSL_CTX(ctx), rDescription.GetCipher(), NULL, NULL, NULL,
+	// Use old version of init call
+	if(EVP_CipherInit(&ctx, rDescription.GetCipher(), NULL, NULL,
 		(mFunction == Encrypt) ? 1 : 0) != 1)
 #endif
 	{
 		THROW_EXCEPTION_MESSAGE(CipherException, EVPInitFailure,
 			"Failed to initialise " << rDescription.GetFullName()
-			<< ": " << LogError("initialising cipher"));
+			<< "cipher: " << LogError("initialising cipher"));
 	}
-	UsePadding(mPaddingOn);
 	
 	try
 	{
 		mCipherName = rDescription.GetFullName();
 #ifndef HAVE_OLD_SSL
 		// Let the description set up everything else
-		mpDescription = &rDescription;
+		rDescription.SetupParameters(&ctx);
 #else
 		// With the old version, a copy needs to be taken first.
 		mpDescription = rDescription.Clone();
 		// Mark it as not a leak, otherwise static cipher contexts
 		// cause spurious memory leaks to be reported
 		MEMLEAKFINDER_NOT_A_LEAK(mpDescription);
+		mpDescription->SetupParameters(&ctx);
 #endif
-		mpDescription->SetupParameters(BOX_OPENSSL_CTX(ctx));
 	}
 	catch(...)
 	{
 		THROW_EXCEPTION_MESSAGE(CipherException, EVPInitFailure,
-			"Failed to configure " << mCipherName << ": " <<
+			"Failed to configure " << mCipherName << " cipher: " <<
 			LogError("configuring cipher"));
-		BOX_OPENSSL_CLEANUP_CTX(ctx);
+		EVP_CIPHER_CTX_cleanup(&ctx);
 		throw;
 	}
 
@@ -168,7 +166,7 @@ void CipherContext::Reset()
 	if(mInitialised)
 	{
 		// Clean up
-		EVP_CIPHER_CTX_cleanup(BOX_OPENSSL_CTX(ctx));
+		EVP_CIPHER_CTX_cleanup(&ctx);
 		mInitialised = false;
 	}
 #ifdef HAVE_OLD_SSL
@@ -179,7 +177,6 @@ void CipherContext::Reset()
 	}
 #endif
 	mWithinTransform = false;
-	mIV.clear();
 }
 
 
@@ -195,22 +192,24 @@ void CipherContext::Begin()
 {
 	if(!mInitialised)
 	{
-		THROW_EXCEPTION(CipherException, NotInitialised);
+		THROW_EXCEPTION(CipherException, NotInitialised)
 	}
 
+	// Warn if in a transformation (not an error, because a context might not have been finalised if an exception occured)
 	if(mWithinTransform)
 	{
-		THROW_EXCEPTION(CipherException, AlreadyInTransform);
+		BOX_WARNING("CipherContext::Begin called when context "
+			"flagged as within a transform");
 	}
 
-	if(EVP_CipherInit_ex(BOX_OPENSSL_CTX(ctx), NULL, NULL, NULL,
-		(const unsigned char *)(mIV.size() > 0 ? mIV.c_str() : NULL),
-		-1) != 1)
+	// Initialise the cipher context again
+	if(EVP_CipherInit(&ctx, NULL, NULL, NULL, -1) != 1)
 	{
 		THROW_EXCEPTION_MESSAGE(CipherException, EVPInitFailure,
-			"Failed to set IV for " << mCipherName << ": " << LogError(GetFunction()));
+			"Failed to reset " << mCipherName << " cipher: " <<
+			LogError("resetting cipher"));
 	}
-
+	
 	// Mark as being within a transform
 	mWithinTransform = true;
 }
@@ -252,18 +251,18 @@ int CipherContext::Transform(void *pOutBuffer, int OutLength, const void *pInBuf
 	}
 	
 	// Check output buffer size
-	if(OutLength < (InLength + EVP_CIPHER_CTX_block_size(BOX_OPENSSL_CTX(ctx))))
+	if(OutLength < (InLength + EVP_CIPHER_CTX_block_size(&ctx)))
 	{
 		THROW_EXCEPTION(CipherException, OutputBufferTooSmall);
 	}
 	
 	// Do the transform
 	int outLength = OutLength;
-	if(EVP_CipherUpdate(BOX_OPENSSL_CTX(ctx), (unsigned char*)pOutBuffer, &outLength,
-		(unsigned char*)pInBuffer, InLength) != 1)
+	if(EVP_CipherUpdate(&ctx, (unsigned char*)pOutBuffer, &outLength, (unsigned char*)pInBuffer, InLength) != 1)
 	{
 		THROW_EXCEPTION_MESSAGE(CipherException, EVPUpdateFailure,
-			"Failed to update " << mCipherName << ": " << LogError(GetFunction()));
+			"Failed to " << GetFunction() << " (update) " <<
+			mCipherName << " cipher: " << LogError(GetFunction()));
 	}
 
 	return outLength;
@@ -301,7 +300,7 @@ int CipherContext::Final(void *pOutBuffer, int OutLength)
 	}
 
 	// Check output buffer size
-	if(OutLength < (2 * EVP_CIPHER_CTX_block_size(BOX_OPENSSL_CTX(ctx))))
+	if(OutLength < (2 * EVP_CIPHER_CTX_block_size(&ctx)))
 	{
 		THROW_EXCEPTION(CipherException, OutputBufferTooSmall);
 	}
@@ -309,11 +308,12 @@ int CipherContext::Final(void *pOutBuffer, int OutLength)
 	// Do the transform
 	int outLength = OutLength;
 #ifndef HAVE_OLD_SSL
-	if(EVP_CipherFinal(BOX_OPENSSL_CTX(ctx), (unsigned char*)pOutBuffer, &outLength) != 1)
+	if(EVP_CipherFinal(&ctx, (unsigned char*)pOutBuffer, &outLength) != 1)
 	{
 		mWithinTransform = false;
 		THROW_EXCEPTION_MESSAGE(CipherException, EVPFinalFailure,
-			"Failed to finalise " << mCipherName << ": " << LogError(GetFunction()));
+			"Failed to " << GetFunction() << " (final) " <<
+			mCipherName << " cipher: " << LogError(GetFunction()));
 	}
 #else
 	OldOpenSSLFinal((unsigned char*)pOutBuffer, outLength);
@@ -340,11 +340,11 @@ void CipherContext::OldOpenSSLFinal(unsigned char *Buffer, int &rOutLengthOut)
 	// Old version needs to use a different form, and then set up the cipher again for next time around
 	int outLength = rOutLengthOut;
 	// Have to emulate padding off...
-	int blockSize = EVP_CIPHER_CTX_block_size(ctx);
+	int blockSize = EVP_CIPHER_CTX_block_size(&ctx);
 	if(mPaddingOn)
 	{
 		// Just use normal final call
-		if(EVP_CipherFinal(ctx, Buffer, &outLength) != 1)
+		if(EVP_CipherFinal(&ctx, Buffer, &outLength) != 1)
 		{
 			THROW_EXCEPTION(CipherException, EVPFinalFailure)
 		}
@@ -357,13 +357,13 @@ void CipherContext::OldOpenSSLFinal(unsigned char *Buffer, int &rOutLengthOut)
 		{
 			// NASTY -- fiddling around with internals like this is bad.
 			// But only way to get this working on old versions of OpenSSL.
-			if(!EVP_EncryptUpdate(ctx,Buffer,&outLength,ctx.buf,0)
+			if(!EVP_EncryptUpdate(&ctx,Buffer,&outLength,ctx.buf,0)
 				|| outLength != blockSize)
 			{
 				THROW_EXCEPTION(CipherException, EVPFinalFailure)
 			}
 			// Clean up
-			EVP_CIPHER_CTX_free(ctx);
+			EVP_CIPHER_CTX_cleanup(&ctx);
 		}
 		else
 		{
@@ -391,14 +391,12 @@ void CipherContext::OldOpenSSLFinal(unsigned char *Buffer, int &rOutLengthOut)
 		}
 	}
 	// Reinitialise the cipher for the next time around
-	if(EVP_CipherInit_ex(&ctx, mpDescription->GetCipher(), NULL, NULL,
-		(const unsigned char *)(mIV.size() > 0 ? mIV.c_str() : NULL),
+	if(EVP_CipherInit(&ctx, mpDescription->GetCipher(), NULL, NULL,
 		(mFunction == Encrypt) ? 1 : 0) != 1)
 	{
 		THROW_EXCEPTION(CipherException, EVPInitFailure)
 	}
 	mpDescription->SetupParameters(&ctx);
-	UsePadding(mPaddingOn);
 
 	// Update length for caller
 	rOutLengthOut = outLength;
@@ -423,7 +421,7 @@ int CipherContext::InSizeForOutBufferSize(int OutLength)
 
 	// Strictly speaking, the *2 is unnecessary. However... 
 	// Final() is paranoid, and requires two input blocks of space to work.
-	return OutLength - (EVP_CIPHER_CTX_block_size(BOX_OPENSSL_CTX(ctx)) * 2);
+	return OutLength - (EVP_CIPHER_CTX_block_size(&ctx) * 2);
 }
 
 // --------------------------------------------------------------------------
@@ -444,7 +442,7 @@ int CipherContext::MaxOutSizeForInBufferSize(int InLength)
 
 	// Final() is paranoid, and requires two input blocks of space to work, and so we need to add
 	// three blocks on to be absolutely sure.
-	return InLength + (EVP_CIPHER_CTX_block_size(BOX_OPENSSL_CTX(ctx)) * 3);
+	return InLength + (EVP_CIPHER_CTX_block_size(&ctx) * 3);
 }
 
 
@@ -458,8 +456,20 @@ int CipherContext::MaxOutSizeForInBufferSize(int InLength)
 // --------------------------------------------------------------------------
 int CipherContext::TransformBlock(void *pOutBuffer, int OutLength, const void *pInBuffer, int InLength)
 {
+	if(!mInitialised)
+	{
+		THROW_EXCEPTION(CipherException, NotInitialised)
+	}
+	
+	// Warn if in a transformation
+	if(mWithinTransform)
+	{
+		BOX_WARNING("CipherContext::TransformBlock called when "
+			"context flagged as within a transform");
+	}
+
 	// Check output buffer size
-	if(OutLength < (InLength + EVP_CIPHER_CTX_block_size(BOX_OPENSSL_CTX(ctx))))
+	if(OutLength < (InLength + EVP_CIPHER_CTX_block_size(&ctx)))
 	{
 		// Check if padding is off, in which case the buffer can be smaller
 		if(!mPaddingOn && OutLength <= InLength)
@@ -471,36 +481,40 @@ int CipherContext::TransformBlock(void *pOutBuffer, int OutLength, const void *p
 			THROW_EXCEPTION(CipherException, OutputBufferTooSmall);
 		}
 	}
-
-	Begin();
+	
+	// Initialise the cipher context again
+	if(EVP_CipherInit(&ctx, NULL, NULL, NULL, -1) != 1)
+	{
+		THROW_EXCEPTION(CipherException, EVPInitFailure)
+	}
 	
 	// Do the entire block
-	int output_space_used = OutLength;
+	int outLength = 0;
 
 	// Update
-	if(EVP_CipherUpdate(BOX_OPENSSL_CTX(ctx), (unsigned char*)pOutBuffer, &output_space_used,
-		(unsigned char*)pInBuffer, InLength) != 1)
+	outLength = OutLength;
+	if(EVP_CipherUpdate(&ctx, (unsigned char*)pOutBuffer, &outLength, (unsigned char*)pInBuffer, InLength) != 1)
 	{
 		THROW_EXCEPTION_MESSAGE(CipherException, EVPUpdateFailure,
-			"Failed to update " << mCipherName << ": " << LogError(GetFunction()));
+			"Failed to " << GetFunction() << " (update) " <<
+			mCipherName << " cipher: " << LogError(GetFunction()));
 	}
 
 	// Finalise
-	int output_space_remain = OutLength - output_space_used;
-
-#ifdef HAVE_OLD_SSL
-	OldOpenSSLFinal(((unsigned char*)pOutBuffer) + output_space_used, output_space_remain);
-#else
-	if(EVP_CipherFinal(BOX_OPENSSL_CTX(ctx), ((unsigned char*)pOutBuffer) + output_space_used,
-		&output_space_remain) != 1)
+	int outLength2 = OutLength - outLength;
+#ifndef HAVE_OLD_SSL
+	if(EVP_CipherFinal(&ctx, ((unsigned char*)pOutBuffer) + outLength, &outLength2) != 1)
 	{
 		THROW_EXCEPTION_MESSAGE(CipherException, EVPFinalFailure,
-			"Failed to finalise " << mCipherName << ": " << LogError(GetFunction()));
+			"Failed to " << GetFunction() << " (final) " <<
+			mCipherName << " cipher: " << LogError(GetFunction()));
 	}
+#else
+	OldOpenSSLFinal(((unsigned char*)pOutBuffer) + outLength, outLength2);
 #endif
+	outLength += outLength2;
 
-	mWithinTransform = false;
-	return output_space_used + output_space_remain;
+	return outLength;
 }
 
 
@@ -519,7 +533,7 @@ int CipherContext::GetIVLength()
 		THROW_EXCEPTION(CipherException, NotInitialised)
 	}
 	
-	return EVP_CIPHER_CTX_iv_length(BOX_OPENSSL_CTX(ctx));
+	return EVP_CIPHER_CTX_iv_length(&ctx);
 }
 
 
@@ -545,14 +559,12 @@ void CipherContext::SetIV(const void *pIV)
 			"flagged as within a transform");
 	}
 
-	mIV = std::string((const char *)pIV, GetIVLength());
-
 	// Set IV
-	if(EVP_CipherInit_ex(BOX_OPENSSL_CTX(ctx), NULL, NULL, NULL,
-		(const unsigned char *)mIV.c_str(), -1) != 1)
+	if(EVP_CipherInit(&ctx, NULL, NULL, (unsigned char *)pIV, -1) != 1)
 	{
 		THROW_EXCEPTION_MESSAGE(CipherException, EVPInitFailure,
-			"Failed to set IV for " << mCipherName << ": " << LogError(GetFunction()));
+			"Failed to " << GetFunction() << " (set IV) " <<
+			mCipherName << " cipher: " << LogError(GetFunction()));
 	}
 
 #ifdef HAVE_OLD_SSL
@@ -589,20 +601,19 @@ const void *CipherContext::SetRandomIV(int &rLengthOut)
 	}
 
 	// Get length of IV
-	uint8_t generated_iv[CIPHERCONTEXT_MAX_GENERATED_IV_LENGTH];
-	unsigned int ivLen = EVP_CIPHER_CTX_iv_length(BOX_OPENSSL_CTX(ctx));
-	if(ivLen > sizeof(generated_iv))
+	unsigned int ivLen = EVP_CIPHER_CTX_iv_length(&ctx);
+	if(ivLen > sizeof(mGeneratedIV))
 	{
 		THROW_EXCEPTION(CipherException, IVSizeImplementationLimitExceeded)
 	}
 	
 	// Generate some random data
-	Random::Generate(generated_iv, ivLen);
-	SetIV(generated_iv);
+	Random::Generate(mGeneratedIV, ivLen);
+	SetIV(mGeneratedIV);
 
 	// Return the IV and it's length
 	rLengthOut = ivLen;
-	return mIV.c_str();
+	return mGeneratedIV;
 }
 
 
@@ -617,11 +628,9 @@ const void *CipherContext::SetRandomIV(int &rLengthOut)
 void CipherContext::UsePadding(bool Padding)
 {
 #ifndef HAVE_OLD_SSL
-	if(EVP_CIPHER_CTX_set_padding(BOX_OPENSSL_CTX(ctx), Padding) != 1)
+	if(EVP_CIPHER_CTX_set_padding(&ctx, Padding) != 1)
 	{
-		THROW_EXCEPTION_MESSAGE(CipherException, EVPSetPaddingFailure,
-			"Failed to set padding for " << mCipherName << ": " <<
-			LogError(GetFunction()));
+		THROW_EXCEPTION(CipherException, EVPSetPaddingFailure)
 	}
 #endif
 	mPaddingOn = Padding;
diff --git a/lib/crypto/CipherContext.h b/lib/crypto/CipherContext.h
index b6e97b4e..93c889d6 100644
--- a/lib/crypto/CipherContext.h
+++ b/lib/crypto/CipherContext.h
@@ -19,22 +19,6 @@ class CipherDescription;
 
 #define CIPHERCONTEXT_MAX_GENERATED_IV_LENGTH		32
 
-// Macros to allow compatibility with OpenSSL 1.0 and 1.1 APIs. See
-// https://github.com/charybdis-ircd/charybdis/blob/release/3.5/libratbox/src/openssl_ratbox.h
-// for the gory details.
-#if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER >= 0x10100000L) // OpenSSL >= 1.1
-#	define BOX_OPENSSL_INIT_CTX(ctx) ctx = EVP_CIPHER_CTX_new();
-#	define BOX_OPENSSL_CTX(ctx) ctx
-#	define BOX_OPENSSL_CLEANUP_CTX(ctx) EVP_CIPHER_CTX_free(ctx)
-typedef EVP_CIPHER_CTX* BOX_EVP_CIPHER_CTX;
-#else // OpenSSL < 1.1
-#	define BOX_OPENSSL_INIT_CTX(ctx) EVP_CIPHER_CTX_init(&ctx); // no error return code, even though the docs says it does
-#	define BOX_OPENSSL_CTX(ctx) &ctx
-#	define BOX_OPENSSL_CLEANUP_CTX(ctx) EVP_CIPHER_CTX_cleanup(&ctx)
-typedef EVP_CIPHER_CTX BOX_EVP_CIPHER_CTX;
-#endif
-
-
 // --------------------------------------------------------------------------
 //
 // Class
@@ -90,14 +74,16 @@ public:
 #endif
 	
 private:
-	BOX_EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX ctx;
 	bool mInitialised;
 	bool mWithinTransform;
 	bool mPaddingOn;
+	uint8_t mGeneratedIV[CIPHERCONTEXT_MAX_GENERATED_IV_LENGTH];
 	CipherFunction mFunction;
 	std::string mCipherName;
-	const CipherDescription *mpDescription;
-	std::string mIV;
+#ifdef HAVE_OLD_SSL
+	CipherDescription *mpDescription;
+#endif
 };
 
 
diff --git a/lib/crypto/CipherException.txt b/lib/crypto/CipherException.txt
index 494ed3cc..abdbac87 100644
--- a/lib/crypto/CipherException.txt
+++ b/lib/crypto/CipherException.txt
@@ -16,4 +16,3 @@ PseudoRandNotAvailable				12
 EVPSetPaddingFailure				13
 RandomInitFailed					14	Failed to read from random device
 LengthRequestedTooLongForRandomHex	15
-AlreadyInTransform			16	Tried to initialise crypto when already in a transform
diff --git a/lib/server/TLSContext.cpp b/lib/server/TLSContext.cpp
index 1a6d4a53..35e254fd 100644
--- a/lib/server/TLSContext.cpp
+++ b/lib/server/TLSContext.cpp
@@ -23,17 +23,6 @@
 #define MAX_VERIFICATION_DEPTH		2
 #define CIPHER_LIST					"ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
 
-// Macros to allow compatibility with OpenSSL 1.0 and 1.1 APIs. See
-// https://github.com/charybdis-ircd/charybdis/blob/release/3.5/libratbox/src/openssl_ratbox.h
-// for the gory details.
-#if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER >= 0x10100000L) // OpenSSL >= 1.1
-#	define BOX_TLS_SERVER_METHOD TLS_server_method
-#	define BOX_TLS_CLIENT_METHOD TLS_client_method
-#else // OpenSSL < 1.1
-#	define BOX_TLS_SERVER_METHOD TLSv1_server_method
-#	define BOX_TLS_CLIENT_METHOD TLSv1_client_method
-#endif
-
 // --------------------------------------------------------------------------
 //
 // Function
@@ -78,7 +67,7 @@ void TLSContext::Initialise(bool AsServer, const char *CertificatesFile, const c
 		::SSL_CTX_free(mpContext);
 	}
 
-	mpContext = ::SSL_CTX_new(AsServer ? BOX_TLS_SERVER_METHOD() : BOX_TLS_CLIENT_METHOD());
+	mpContext = ::SSL_CTX_new(AsServer?TLSv1_server_method():TLSv1_client_method());
 	if(mpContext == NULL)
 	{
 		THROW_EXCEPTION(ServerException, TLSAllocationFailed)
diff --git a/test/crypto/testcrypto.cpp b/test/crypto/testcrypto.cpp
index 32d2efb8..4e623cc2 100644
--- a/test/crypto/testcrypto.cpp
+++ b/test/crypto/testcrypto.cpp
@@ -266,7 +266,7 @@ int test(int argc, const char *argv[])
 	// Check rolling checksums
 	uint8_t *checkdata_blk = (uint8_t *)malloc(CHECKSUM_DATA_SIZE);
 	uint8_t *checkdata = checkdata_blk;
-	RAND_bytes(checkdata, CHECKSUM_DATA_SIZE);
+	RAND_pseudo_bytes(checkdata, CHECKSUM_DATA_SIZE);
 	for(int size = CHECKSUM_BLOCK_SIZE_BASE; size <= CHECKSUM_BLOCK_SIZE_LAST; ++size)
 	{
 		// Test skip-roll code