Report abuse

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
#import <CommonCrypto/CommonCryptor.h>
#import "NSData-AES.h"

@implementation NSData (AES256)

- (NSData *)AES256EncryptWithKey:(NSString *)key andInitializationVector: (NSString *)iv {
	return [self wingardiumLeviosa: YES withKey: key andInitializationVector: iv];
}

- (NSData *)AES256DecryptWithKey:(NSString *)key andInitializationVector: (NSString *)iv {
	return [self wingardiumLeviosa: NO withKey: key andInitializationVector: iv];
}

//todo: the padding created when dealing with the 16-byte blocks (50 bytes fits into 4 16 byte blocks for 64 bytes with 14 bytes of padding) seems to not decode to utf8 but decodes to ascii just fine.
- (NSData *)wingardiumLeviosa:(BOOL)isEncrypting withKey:(NSString *)key andInitializationVector: (NSString *)iv {
	size_t outAvailableLength = 0;
	size_t outAvailableLengthFinal = 0;
	size_t outSizeUpdate = 0;
	CCOperation operation = 0;
	CCCryptorRef cccCryptor = nil;
	NSMutableData *data;
	const void *bytes; 
	NSUInteger length;
	
	data = [NSMutableData dataWithLength:0];
	bytes = [self bytes];
	length = [self length];
	
	
	if(isEncrypting){
		operation = kCCEncrypt;
	} else {
		operation = kCCDecrypt;
	}
	
	CCCryptorCreate(operation, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
					[key UTF8String], [key length],
					[iv UTF8String],
					&cccCryptor);
	
	outAvailableLength = CCCryptorGetOutputLength(cccCryptor, length, false);
	void *outBytes = malloc(outAvailableLength);
	
	if (cccCryptor) {
		CCCryptorUpdate(cccCryptor, bytes, length, outBytes, outAvailableLength, &outSizeUpdate);
		[data appendBytes:outBytes length:outSizeUpdate];
		outAvailableLengthFinal = CCCryptorGetOutputLength(cccCryptor, length, true);
		void *finalBuffer = malloc(outAvailableLengthFinal); 
		CCCryptorFinal(cccCryptor, finalBuffer, kCCBlockSizeAES128, &outSizeUpdate); 
		[data appendBytes:finalBuffer length:outSizeUpdate]; 
		CCCryptorRelease(cccCryptor);
		return data;
	}
	
	return nil;
}

@end