Getting a heap buffer overflow runtime crash when trying to encrypt "large" amounts of data. On my 16GB MBPr, the magic number is anything over 1536 bytes for it to crash. When I change out the encryption implementation to an OpenSSL-based one (using IBM-Swift/BlueCryptor on Linux - not Mac since it'll sub it for CommonCrypto), it successfully encrypts the data with seemingly no limit on size. The implementation of cbc128.c
for both LibreSSL and OpenSSL is identical.
import Cipher
import Random
let key = "passwordpasswordpasswordpassword".bytes
let iv = "passwordpassword".bytes
let plainText = URandom.bytes(1537)
let encryptedText = try Cipher(.aes256(.cbc), key: key, iv: iv).encrypt(plainText).base64String
AddressSanitizer debugger support is active. Memory error breakpoint has been installed and you can now use the 'memory history' command.
=================================================================
==2334==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6190000072a0 at pc 0x000100f9a7fd bp 0x7fff5fbfdc80 sp 0x7fff5fbfdc78
WRITE of size 8 at 0x6190000072a0 thread T0
#0 0x100f9a7fc in CRYPTO_cbc128_encrypt cbc128.c:91
#1 0x100fe78b7 in aes_cbc_cipher e_aes.c:584
#2 0x10101fdd9 in EVP_EncryptUpdate evp_enc.c:359
#3 0x1014f09e8 in @nonobjc EVP_EncryptUpdate(UnsafeMutablePointer<evp_cipher_ctx_st>!, UnsafeMutablePointer<UInt8>!, UnsafeMutablePointer<Int32>!, UnsafePointer<UInt8>!, Int32) -> Int32 Cipher.swift
#4 0x1014f0a08 in thunk Cipher.swift
#5 0x1014f0b65 in partial apply for thunk Cipher.swift
#6 0x1014efb3d in Cipher.libreCipher(stream : ByteStream, initialize : (UnsafeMutablePointer<evp_cipher_ctx_st>, UnsafePointer<evp_cipher_st>, UnsafePointer<UInt8>, UnsafePointer<UInt8>?) -> Int32, update : (UnsafeMutablePointer<evp_cipher_ctx_st>, UnsafeMutablePointer<UInt8>, UnsafeMutablePointer<Int32>, UnsafePointer<UInt8>, Int32) -> Int32, final : (UnsafeMutablePointer<evp_cipher_ctx_st>, UnsafeMutablePointer<UInt8>, UnsafeMutablePointer<Int32>) -> Int32) throws -> [UInt8] Cipher.swift:111
#7 0x1014eaf7d in Cipher.encrypt(ByteStream) throws -> [UInt8] Cipher.swift:60
#8 0x1014f1bc7 in Cipher.encrypt([UInt8]) throws -> [UInt8] Cipher.swift:136
#9 0x1000022c8 in main main.swift:83
#10 0x7fff9e0c0254 in start (libdyld.dylib+0x5254)
0x6190000072a0 is located 0 bytes to the right of 1056-byte region [0x619000006e80,0x6190000072a0)
allocated by thread T0 here:
#0 0x100107c60 in wrap_malloc (libclang_rt.asan_osx_dynamic.dylib+0x4ac60)
#1 0x102e14958 in swift_slowAlloc (libswiftCore.dylib+0x21a958)
#2 0x1014ef05a in Cipher.libreCipher(stream : ByteStream, initialize : (UnsafeMutablePointer<evp_cipher_ctx_st>, UnsafePointer<evp_cipher_st>, UnsafePointer<UInt8>, UnsafePointer<UInt8>?) -> Int32, update : (UnsafeMutablePointer<evp_cipher_ctx_st>, UnsafeMutablePointer<UInt8>, UnsafeMutablePointer<Int32>, UnsafePointer<UInt8>, Int32) -> Int32, final : (UnsafeMutablePointer<evp_cipher_ctx_st>, UnsafeMutablePointer<UInt8>, UnsafeMutablePointer<Int32>) -> Int32) throws -> [UInt8] Cipher.swift:102
#3 0x1014eaf7d in Cipher.encrypt(ByteStream) throws -> [UInt8] Cipher.swift:60
#4 0x1014f1bc7 in Cipher.encrypt([UInt8]) throws -> [UInt8] Cipher.swift:136
#5 0x1000022c8 in main main.swift:83
#6 0x7fff9e0c0254 in start (libdyld.dylib+0x5254)
SUMMARY: AddressSanitizer: heap-buffer-overflow cbc128.c:91 in CRYPTO_cbc128_encrypt
Shadow bytes around the buggy address:
0x1c3200000e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1c3200000e10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1c3200000e20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1c3200000e30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1c3200000e40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x1c3200000e50: 00 00 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa
0x1c3200000e60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c3200000e70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c3200000e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c3200000e90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c3200000ea0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
2016-10-17 10:44:07.451185 App[2334:221509] =================================================================
2016-10-17 10:44:07.452415 App[2334:221509] ==2334==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6190000072a0 at pc 0x000100f9a7fd bp 0x7fff5fbfdc80 sp 0x7fff5fbfdc78
2016-10-17 10:44:07.452458 App[2334:221509] WRITE of size 8 at 0x6190000072a0 thread T0
2016-10-17 10:44:07.452483 App[2334:221509] #0 0x100f9a7fc in CRYPTO_cbc128_encrypt cbc128.c:91
2016-10-17 10:44:07.452518 App[2334:221509] #1 0x100fe78b7 in aes_cbc_cipher e_aes.c:584
2016-10-17 10:44:07.452540 App[2334:221509] #2 0x10101fdd9 in EVP_EncryptUpdate evp_enc.c:359
2016-10-17 10:44:07.452560 App[2334:221509] #3 0x1014f09e8 in @nonobjc EVP_EncryptUpdate(UnsafeMutablePointer<evp_cipher_ctx_st>!, UnsafeMutablePointer<UInt8>!, UnsafeMutablePointer<Int32>!, UnsafePointer<UInt8>!, Int32) -> Int32 Cipher.swift
2016-10-17 10:44:07.452624 App[2334:221509] #4 0x1014f0a08 in thunk Cipher.swift
2016-10-17 10:44:07.452709 App[2334:221509] #5 0x1014f0b65 in partial apply for thunk Cipher.swift
2016-10-17 10:44:07.452741 App[2334:221509] #6 0x1014efb3d in Cipher.libreCipher(stream : ByteStream, initialize : (UnsafeMutablePointer<evp_cipher_ctx_st>, UnsafePointer<evp_cipher_st>, UnsafePointer<UInt8>, UnsafePointer<UInt8>?) -> Int32, update : (UnsafeMutablePointer<evp_cipher_ctx_st>, UnsafeMutablePointer<UInt8>, UnsafeMutablePointer<Int32>, UnsafePointer<UInt8>, Int32) -> Int32, final : (UnsafeMutablePointer<evp_cipher_ctx_st>, UnsafeMutablePointer<UInt8>, UnsafeMutablePointer<Int32>) -> Int32) throws -> [UInt8] Cipher.swift:111
2016-10-17 10:44:07.452760 App[2334:221509] #7 0x1014eaf7d in Cipher.encrypt(ByteStream) throws -> [UInt8] Cipher.swift:60
2016-10-17 10:44:07.452782 App[2334:221509] #8 0x1014f1bc7 in Cipher.encrypt([UInt8]) throws -> [UInt8] Cipher.swift:136
2016-10-17 10:44:07.452807 App[2334:221509] #9 0x1000022c8 in main main.swift:83
2016-10-17 10:44:07.452824 App[2334:221509] #10 0x7fff9e0c0254 in start (libdyld.dylib+0x5254)
2016-10-17 10:44:07.452836 App[2334:221509]
2016-10-17 10:44:07.452851 App[2334:221509] 0x6190000072a0 is located 0 bytes to the right of 1056-byte region [0x619000006e80,0x6190000072a0)
2016-10-17 10:44:07.452866 App[2334:221509] allocated by thread T0 here:
2016-10-17 10:44:07.452875 App[2334:221509] #0 0x100107c60 in wrap_malloc (libclang_rt.asan_osx_dynamic.dylib+0x4ac60)
2016-10-17 10:44:07.452884 App[2334:221509] #1 0x102e14958 in swift_slowAlloc (libswiftCore.dylib+0x21a958)
2016-10-17 10:44:07.452896 App[2334:221509] #2 0x1014ef05a in Cipher.libreCipher(stream : ByteStream, initialize : (UnsafeMutablePointer<evp_cipher_ctx_st>, UnsafePointer<evp_cipher_st>, UnsafePointer<UInt8>, UnsafePointer<UInt8>?) -> Int32, update : (UnsafeMutablePointer<evp_cipher_ctx_st>, UnsafeMutablePointer<UInt8>, UnsafeMutablePointer<Int32>, UnsafePointer<UInt8>, Int32) -> Int32, final : (UnsafeMutablePointer<evp_cipher_ctx_st>, UnsafeMutablePointer<UInt8>, UnsafeMutablePointer<Int32>) -> Int32) throws -> [UInt8] Cipher.swift:102
2016-10-17 10:44:07.453105 App[2334:221509] #3 0x1014eaf7d in Cipher.encrypt(ByteStream) throws -> [UInt8] Cipher.swift:60
2016-10-17 10:44:07.453148 App[2334:221509] #4 0x1014f1bc7 in Cipher.encrypt([UInt8]) throws -> [UInt8] Cipher.swift:136
2016-10-17 10:44:07.453176 App[2334:221509] #5 0x1000022c8 in main main.swift:83
2016-10-17 10:44:07.453187 App[2334:221509] #6 0x7fff9e0c0254 in start (libdyld.dylib+0x5254)
2016-10-17 10:44:07.453195 App[2334:221509]
2016-10-17 10:44:07.453205 App[2334:221509] SUMMARY: AddressSanitizer: heap-buffer-overflow cbc128.c:91 in CRYPTO_cbc128_encrypt
2016-10-17 10:44:07.453214 App[2334:221509] Shadow bytes around the buggy address:
2016-10-17 10:44:07.453272 App[2334:221509] 0x1c3200000e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2016-10-17 10:44:07.453349 App[2334:221509] 0x1c3200000e10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2016-10-17 10:44:07.453363 App[2334:221509] 0x1c3200000e20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2016-10-17 10:44:07.453396 App[2334:221509] 0x1c3200000e30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2016-10-17 10:44:07.453430 App[2334:221509] 0x1c3200000e40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2016-10-17 10:44:07.453452 App[2334:221509] =>0x1c3200000e50: 00 00 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa
2016-10-17 10:44:07.453463 App[2334:221509] 0x1c3200000e60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
2016-10-17 10:44:07.453472 App[2334:221509] 0x1c3200000e70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
2016-10-17 10:44:07.453481 App[2334:221509] 0x1c3200000e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
2016-10-17 10:44:07.453490 App[2334:221509] 0x1c3200000e90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
2016-10-17 10:44:07.453507 App[2334:221509] 0x1c3200000ea0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
2016-10-17 10:44:07.453524 App[2334:221509] Shadow byte legend (one shadow byte represents 8 application bytes):
2016-10-17 10:44:07.453639 App[2334:221509] Addressable: 00
2016-10-17 10:44:07.453657 App[2334:221509] Partially addressable: 01 02 03 04 05 06 07
2016-10-17 10:44:07.453666 App[2334:221509] Heap left redzone: fa
2016-10-17 10:44:07.453675 App[2334:221509] Heap right redzone: fb
2016-10-17 10:44:07.453702 App[2334:221509] Freed heap region: fd
2016-10-17 10:44:07.453732 App[2334:221509] Stack left redzone: f1
2016-10-17 10:44:07.453749 App[2334:221509] Stack mid redzone: f2
2016-10-17 10:44:07.453758 App[2334:221509] Stack right redzone: f3
2016-10-17 10:44:07.453767 App[2334:221509] Stack partial redzone: f4
2016-10-17 10:44:07.453775 App[2334:221509] Stack after return: f5
2016-10-17 10:44:07.453783 App[2334:221509] Stack use after scope: f8
2016-10-17 10:44:07.453792 App[2334:221509] Global redzone: f9
2016-10-17 10:44:07.453800 App[2334:221509] Global init order: f6
2016-10-17 10:44:07.453808 App[2334:221509] Poisoned by user: f7
2016-10-17 10:44:07.453822 App[2334:221509] Container overflow: fc
2016-10-17 10:44:07.453937 App[2334:221509] Array cookie: ac
2016-10-17 10:44:07.453954 App[2334:221509] Intra object redzone: bb
2016-10-17 10:44:07.453963 App[2334:221509] ASan internal: fe
2016-10-17 10:44:07.453971 App[2334:221509] Left alloca redzone: ca
2016-10-17 10:44:07.453979 App[2334:221509] Right alloca redzone: cb
2016-10-17 10:44:07.454013 App[2334:221509]
==2334==ABORTING
AddressSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.
Program ended with exit code: 9