|
@@ -567,23 +567,11 @@
|
|
|
|
|
|
- (BOOL)decryptFile:(NSString *)fileName fileNameView:(NSString *)fileNameView ocId:(NSString *)ocId key:(NSString *)key initializationVector:(NSString *)initializationVector authenticationTag:(NSString *)authenticationTag
|
|
|
{
|
|
|
- NSMutableData *plainData;
|
|
|
-
|
|
|
- NSData *cipherData = [[NSFileManager defaultManager] contentsAtPath:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileName]];
|
|
|
- if (cipherData == nil)
|
|
|
- return false;
|
|
|
-
|
|
|
NSData *keyData = [[NSData alloc] initWithBase64EncodedString:key options:0];
|
|
|
NSData *initializationVectorData = [[NSData alloc] initWithBase64EncodedString:initializationVector options:0];
|
|
|
NSData *authenticationTagData = [[NSData alloc] initWithBase64EncodedString:authenticationTag options:0];
|
|
|
|
|
|
- BOOL result = [self decryptData:cipherData plain:&plainData key:keyData keyLen:AES_KEY_128_LENGTH initializationVector:initializationVectorData authenticationTag:authenticationTagData];
|
|
|
- if (plainData != nil && result) {
|
|
|
- [plainData writeToFile:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileNameView] atomically:YES];
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
+ return [self decryptFile:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileName] fileNamePlain:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileNameView] key:keyData keyLen:AES_KEY_128_LENGTH initializationVector:initializationVectorData authenticationTag:authenticationTagData];
|
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
@@ -728,7 +716,7 @@
|
|
|
#pragma mark - AES/GCM/NoPadding
|
|
|
#
|
|
|
|
|
|
-// Encryption NSData using GCM mode
|
|
|
+// Encryption data using GCM mode
|
|
|
- (BOOL)encryptData:(NSData *)plain cipher:(NSMutableData **)cipher key:(NSData *)key keyLen:(int)keyLen initializationVector:(NSData *)initializationVector authenticationTag:(NSData **)authenticationTag
|
|
|
{
|
|
|
int status = 0;
|
|
@@ -762,31 +750,41 @@
|
|
|
else if (keyLen == AES_KEY_256_LENGTH)
|
|
|
status = EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
|
|
|
|
|
|
- if (status <= 0)
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
return NO;
|
|
|
+ }
|
|
|
|
|
|
// Set IV length. Not necessary if this is 12 bytes (96 bits)
|
|
|
status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)sizeof(cIV), NULL);
|
|
|
- if (status <= 0)
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
return NO;
|
|
|
+ }
|
|
|
|
|
|
// Initialise key and IV
|
|
|
status = EVP_EncryptInit_ex (ctx, NULL, NULL, cKey, cIV);
|
|
|
- if (status <= 0)
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
return NO;
|
|
|
+ }
|
|
|
|
|
|
// Provide the message to be encrypted, and obtain the encrypted output
|
|
|
*cipher = [NSMutableData dataWithLength:[plain length]];
|
|
|
unsigned char * cCipher = [*cipher mutableBytes];
|
|
|
int cCipherLen = 0;
|
|
|
status = EVP_EncryptUpdate(ctx, cCipher, &cCipherLen, [plain bytes], (int)[plain length]);
|
|
|
- if (status <= 0)
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
return NO;
|
|
|
+ }
|
|
|
|
|
|
// Finalise the encryption
|
|
|
status = EVP_EncryptFinal_ex(ctx, cCipher, &cCipherLen);
|
|
|
- if (status <= 0)
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
return NO;
|
|
|
+ }
|
|
|
|
|
|
// Get the tag
|
|
|
status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, (int)sizeof(cTag), cTag);
|
|
@@ -795,7 +793,6 @@
|
|
|
// Append TAG
|
|
|
[*cipher appendData:*authenticationTag];
|
|
|
|
|
|
- // Free
|
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
|
|
|
|
return status; // OpenSSL uses 1 for success
|
|
@@ -928,8 +925,7 @@
|
|
|
return status; // OpenSSL uses 1 for success
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-// Decryption using GCM mode
|
|
|
+// Decryption data using GCM mode
|
|
|
- (BOOL)decryptData:(NSData *)cipher plain:(NSMutableData **)plain key:(NSData *)key keyLen:(int)keyLen initializationVector:(NSData *)initializationVector authenticationTag:(NSData *)authenticationTag
|
|
|
{
|
|
|
int status = 0;
|
|
@@ -964,31 +960,41 @@
|
|
|
else if (keyLen == AES_KEY_256_LENGTH)
|
|
|
status = EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
|
|
|
|
|
|
- if (status <= 0)
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
return NO;
|
|
|
+ }
|
|
|
|
|
|
// Set IV length. Not necessary if this is 12 bytes (96 bits)
|
|
|
status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)sizeof(cIV), NULL);
|
|
|
- if (status <= 0)
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
return NO;
|
|
|
+ }
|
|
|
|
|
|
// Initialise key and IV
|
|
|
status = EVP_DecryptInit_ex(ctx, NULL, NULL, cKey, cIV);
|
|
|
- if (status <= 0)
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
return NO;
|
|
|
+ }
|
|
|
|
|
|
// Provide the message to be decrypted, and obtain the plaintext output
|
|
|
*plain = [NSMutableData dataWithLength:([cipher length])];
|
|
|
int cPlainLen = 0;
|
|
|
unsigned char * cPlain = [*plain mutableBytes];
|
|
|
status = EVP_DecryptUpdate(ctx, cPlain, &cPlainLen, [cipher bytes], (int)([cipher length]));
|
|
|
- if (status <= 0)
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
return NO;
|
|
|
+ }
|
|
|
|
|
|
// Tag is the last 16 bytes
|
|
|
status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, (int)sizeof(cTag), cTag);
|
|
|
- if (status <= 0)
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
return NO;
|
|
|
+ }
|
|
|
|
|
|
// Finalise the encryption
|
|
|
EVP_DecryptFinal_ex(ctx,NULL, &cPlainLen);
|
|
@@ -999,6 +1005,115 @@
|
|
|
return status; // OpenSSL uses 1 for success
|
|
|
}
|
|
|
|
|
|
+// Decryption file using GCM mode
|
|
|
+- (BOOL)decryptFile:(NSString *)fileName fileNamePlain:(NSString *)fileNamePlain key:(NSData *)key keyLen:(int)keyLen initializationVector:(NSData *)initializationVector authenticationTag:(NSData *)authenticationTag
|
|
|
+{
|
|
|
+ int status = 0;
|
|
|
+ int len = 0;
|
|
|
+
|
|
|
+ // set up key
|
|
|
+ len = keyLen;
|
|
|
+ unsigned char cKey[len];
|
|
|
+ bzero(cKey, sizeof(cKey));
|
|
|
+ [key getBytes:cKey length:len];
|
|
|
+
|
|
|
+ // set up ivec
|
|
|
+ len = (int)[initializationVector length];
|
|
|
+ unsigned char cIV[len];
|
|
|
+ bzero(cIV, sizeof(cIV));
|
|
|
+ [initializationVector getBytes:cIV length:len];
|
|
|
+
|
|
|
+ // set up tag
|
|
|
+ len = (int)[authenticationTag length];;
|
|
|
+ unsigned char cTag[len];
|
|
|
+ bzero(cTag, sizeof(cTag));
|
|
|
+ [authenticationTag getBytes:cTag length:len];
|
|
|
+
|
|
|
+ // Create and initialise the context
|
|
|
+ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
|
|
+ if (!ctx)
|
|
|
+ return NO;
|
|
|
+
|
|
|
+ // Initialise the decryption operation
|
|
|
+ if (keyLen == AES_KEY_128_LENGTH)
|
|
|
+ status = EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
|
|
|
+ else if (keyLen == AES_KEY_256_LENGTH)
|
|
|
+ status = EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
|
|
|
+
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
+ return NO;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Set IV length. Not necessary if this is 12 bytes (96 bits)
|
|
|
+ status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)sizeof(cIV), NULL);
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
+ return NO;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Initialise key and IV
|
|
|
+ status = EVP_DecryptInit_ex(ctx, NULL, NULL, cKey, cIV);
|
|
|
+ if (status <= 0) {
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
+ return NO;
|
|
|
+ }
|
|
|
+
|
|
|
+ NSInputStream *inStream = [NSInputStream inputStreamWithFileAtPath:fileName];
|
|
|
+ [inStream open];
|
|
|
+ NSOutputStream *outStream = [NSOutputStream outputStreamToFileAtPath:fileNamePlain append:false];
|
|
|
+ [outStream open];
|
|
|
+
|
|
|
+ Byte buffer[streamBuffer];
|
|
|
+ NSInteger totalNumberOfBytesWritten = 0;
|
|
|
+
|
|
|
+ int cPlainLen = 0;
|
|
|
+ unsigned char *cPlain;
|
|
|
+
|
|
|
+ while ([inStream hasBytesAvailable]) {
|
|
|
+
|
|
|
+ NSInteger bytesRead = [inStream read:buffer maxLength:streamBuffer];
|
|
|
+
|
|
|
+ if (bytesRead > 0) {
|
|
|
+
|
|
|
+ cPlain = [[NSMutableData dataWithLength:bytesRead] mutableBytes];
|
|
|
+ status = EVP_DecryptUpdate(ctx, cPlain, &cPlainLen, [[NSData dataWithBytes:buffer length:bytesRead] bytes], (int)bytesRead);
|
|
|
+ if (status <= 0) {
|
|
|
+ [inStream close];
|
|
|
+ [outStream close];
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
+ return NO;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ([outStream hasSpaceAvailable]) {
|
|
|
+ totalNumberOfBytesWritten = [outStream write:cPlain maxLength:cPlainLen];
|
|
|
+ if (totalNumberOfBytesWritten != cPlainLen) {
|
|
|
+ [inStream close];
|
|
|
+ [outStream close];
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
+ return NO;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [inStream close];
|
|
|
+ [outStream close];
|
|
|
+
|
|
|
+ // Tag is the last 16 bytes
|
|
|
+ status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, (int)sizeof(cTag), cTag);
|
|
|
+ if (status <= 0)
|
|
|
+ return NO;
|
|
|
+
|
|
|
+ // Finalise the encryption
|
|
|
+ EVP_DecryptFinal_ex(ctx,NULL, &cPlainLen);
|
|
|
+
|
|
|
+ // Free
|
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
|
+
|
|
|
+ return status; // OpenSSL uses 1 for success
|
|
|
+}
|
|
|
+
|
|
|
#
|
|
|
#pragma mark - Utility
|
|
|
#
|