//
//  AESCrypt.m
//  Gurpartap Singh
//
//  Created by Gurpartap Singh on 06/05/12.
//  Copyright (c) 2012 Gurpartap Singh
// 
// 	MIT License
// 
// 	Permission is hereby granted, free of charge, to any person obtaining
// 	a copy of this software and associated documentation files (the
// 	"Software"), to deal in the Software without restriction, including
// 	without limitation the rights to use, copy, modify, merge, publish,
// 	distribute, sublicense, and/or sell copies of the Software, and to
// 	permit persons to whom the Software is furnished to do so, subject to
// 	the following conditions:
// 
// 	The above copyright notice and this permission notice shall be
// 	included in all copies or substantial portions of the Software.
// 
// 	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// 	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// 	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// 	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// 	LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// 	OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// 	WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

#import "AESCrypt.h"

#import "NSData+Base64.h"
#import "NSString+Base64.h"
#import "NSData+CommonCrypto.h"
#import "config.h"

@implementation AESCrypt


#pragma simple aes

+(NSString *)AES128Encrypt:(NSString *)plainText key:(NSString*) gkey
{
    NSString* gIv = nil;
    char keyPtr[kCCKeySizeAES128+1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [gkey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    char ivPtr[kCCBlockSizeAES128+1];
    memset(ivPtr, 0, sizeof(ivPtr));
    [gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
    
    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [data length];
    
    int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
    int newSize = 0;
    
    if(diff > 0)
    {
        newSize = dataLength + diff;
    }
    
    //    char dataPtr[newSize];
    //    memcpy(dataPtr, [data bytes], [data length]);
    //    for(int i = 0; i < diff; i++)
    //    {
    //        dataPtr[i + dataLength] = 0x00;
    //    }
    
    size_t bufferSize = newSize + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    memset(buffer, 0, bufferSize);
    
    size_t numBytesCrypted = 0;
    
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          0x0000|kCCOptionECBMode|kCCOptionPKCS7Padding,               //No padding
                                          keyPtr,
                                          kCCKeySizeAES128,
                                          ivPtr,
                                          [data bytes],
                                          [data length],
                                          buffer,
                                          bufferSize,
                                          &numBytesCrypted);
    
    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
        //        return [GTMBase64 stringByEncodingData:resultData];
        
        
        NSString *base64EncodedString = [resultData base64EncodedStringWithOptions:0];//[NSString base64StringFromData:resultData length:[resultData length]];
        return base64EncodedString;
    }
    free(buffer);
    return nil;
}
+(NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString*) gkey
{
    
    NSString* gIv = nil;
    char keyPtr[kCCKeySizeAES128 + 1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [gkey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    char ivPtr[kCCBlockSizeAES128 + 1];
    memset(ivPtr, 0, sizeof(ivPtr));
    [gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
    
    // NSData* d1 = [encryptText dataUsingEncoding:NSUTF8StringEncoding];
    NSData *encryptedData =[[NSData alloc] initWithBase64EncodedString:encryptText options:NSDataBase64DecodingIgnoreUnknownCharacters];
    
    //[[NSData alloc] initWithBase64EncodedString:stringBase64 options:NSDataBase64DecodingIgnoreUnknownCharacters];//[NSData base64DataFromString:encryptText];
    NSData *data = encryptedData;//[GTMBase64 decodeData:];
    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    size_t numBytesCrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          0x0000|kCCOptionECBMode|kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          ivPtr,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesCrypted);
    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
        return [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding] ;
    }
    free(buffer);
    return nil;
}
//+(NSString *)AES128Encrypt:(NSString *)plainText key:(NSString*) gkey
//{
//    NSString* gIv = nil;
//    char keyPtr[kCCKeySizeAES128+1];
//    memset(keyPtr, 0, sizeof(keyPtr));
//    [gkey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
//    
//    char ivPtr[kCCBlockSizeAES128+1];
//    memset(ivPtr, 0, sizeof(ivPtr));
//    [gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
//    
//    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
//    NSUInteger dataLength = [data length];
//    
//    int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
//    int newSize = 0;
//    
//    if(diff > 0)
//    {
//        newSize = dataLength + diff;
//    }
//    
//    char dataPtr[newSize];
//    memcpy(dataPtr, [data bytes], [data length]);
//    for(int i = 0; i < diff; i++)
//    {
//        dataPtr[i + dataLength] = 0x00;
//    }
//    
//    size_t bufferSize = newSize + kCCBlockSizeAES128;
//    void *buffer = malloc(bufferSize);
//    memset(buffer, 0, bufferSize);
//    
//    size_t numBytesCrypted = 0;
//    
//    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
//                                          kCCAlgorithmAES128,
//                                          0x0000|kCCOptionECBMode|kCCOptionPKCS7Padding,               //No padding
//                                          keyPtr,
//                                          kCCKeySizeAES128,
//                                          ivPtr,
//                                          dataPtr,
//                                          sizeof(dataPtr),
//                                          buffer,
//                                          bufferSize,
//                                          &numBytesCrypted);
//    
//    if (cryptStatus == kCCSuccess) {
//        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
////        return [GTMBase64 stringByEncodingData:resultData];
//        
//        
//        NSString *base64EncodedString = [NSString base64StringFromData:resultData length:[resultData length]];
//        return base64EncodedString;
//    }
//    free(buffer);
//    return nil;
//}
//
//+(NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString*) gkey
//{
//    
//    NSString* gIv = nil;
//    char keyPtr[kCCKeySizeAES128 + 1];
//    memset(keyPtr, 0, sizeof(keyPtr));
//    [gkey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
//    
//    char ivPtr[kCCBlockSizeAES128 + 1];
//    memset(ivPtr, 0, sizeof(ivPtr));
//    [gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
//    
//    
//    NSData *encryptedData = [NSData base64DataFromString:encryptText];
//    NSData *data = encryptedData;//[GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];
//    NSUInteger dataLength = [data length];
//    size_t bufferSize = dataLength + kCCBlockSizeAES128;
//    void *buffer = malloc(bufferSize);
//    
//    size_t numBytesCrypted = 0;
//    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
//                                          kCCAlgorithmAES128,
//                                          0x0000|kCCOptionECBMode|kCCOptionPKCS7Padding,
//                                          keyPtr,
//                                          kCCBlockSizeAES128,
//                                          ivPtr,
//                                          [data bytes],
//                                          dataLength,
//                                          buffer,
//                                          bufferSize,
//                                          &numBytesCrypted);
//    if (cryptStatus == kCCSuccess) {
//        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
//        return [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding] ;
//    }
//    free(buffer);
//    return nil;
//}



+ (NSString *)encrypt:(NSString *)message password:(NSString *)password {
    
#ifdef ENCRYPT_OFF
    return message;
#endif
    
//    message=@"NEW PACIFIC DIRECT";
//    NSData* msgdata=[message dataUsingEncoding:NSUTF8StringEncoding];
//    NSData* passdata=[password dataUsingEncoding:NSUTF8StringEncoding];
//    NSData* SHA256Hash = [passdata SHA256Hash];
//    NSString *SHA256Hashresult = [[NSString alloc] initWithData:SHA256Hash  encoding:NSUTF8StringEncoding];
  //  message=@"NEW PACIFIC DIRECT";
  NSData *encryptedData = [[message dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptedDataUsingKey:[[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash]  error:nil];
  NSString *base64EncodedString = [NSString base64StringFromData:encryptedData length:[encryptedData length]];
  return base64EncodedString;
}


//+ (NSString *)simple_encrypt:(NSString *)message password:(NSString *)password {
//    
//
//    
//    //    message=@"NEW PACIFIC DIRECT";
//    //    NSData* msgdata=[message dataUsingEncoding:NSUTF8StringEncoding];
//    //    NSData* passdata=[password dataUsingEncoding:NSUTF8StringEncoding];
//    //    NSData* SHA256Hash = [passdata SHA256Hash];
//    //    NSString *SHA256Hashresult = [[NSString alloc] initWithData:SHA256Hash  encoding:NSUTF8StringEncoding];
//    //  message=@"NEW PACIFIC DIRECT";
//  //  NSString* aaa=[[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash];;
//    NSData *encryptedData = [[message dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptedDataUsingKey:password  error:nil];
//    NSString *base64EncodedString = [NSString base64StringFromData:encryptedData length:[encryptedData length]];
//    return base64EncodedString;
//}

+ (NSString *)decrypt:(NSString *)base64EncodedString password:(NSString *)password {
#ifdef ENCRYPT_OFF
    return base64EncodedString;
#endif
    
    if(base64EncodedString==nil)
        return nil;
    if(base64EncodedString.length==0)
        return @"";
  NSData *encryptedData = [NSData base64DataFromString:base64EncodedString];
  NSData *decryptedData = [encryptedData decryptedAES256DataUsingKey:[[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash] error:nil];
  return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
}


//+ (NSString *)simple_decrypt:(NSString *)base64EncodedString password:(NSString *)password
//{
//
//    
//    if(base64EncodedString==nil)
//        return nil;
//    if(base64EncodedString.length==0)
//        return @"";
//    NSData *encryptedData = [NSData base64DataFromString:base64EncodedString];
//    NSData *decryptedData = [encryptedData decryptedAES256DataUsingKey:password error:nil];
//    return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
//}

+ (NSString *)fastdecrypt:(NSString *)base64EncodedString
{
    NSString* ret=[self decrypt:base64EncodedString password:@"usai"];
    if(ret==nil)
        ret= @"";
    return ret;
}

+ (NSString *)fastencrypt:(NSString *)message
{
    
    return [self encrypt:message password:@"usai"];
}

@end
