#include "cspwrap.h"
#include "common.h"
#include <security_cdsa_utils/cuFileIo.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <Security/cssm.h>
#include <Security/cssmapple.h>
#include <CoreFoundation/CoreFoundation.h>
static void usage(char **argv)
{
printf("usage:\n");
printf(" %s op password inFile outFile [k=keysize] [o=optimize]\n", argv[0]);
printf(" op:\n");
printf(" e encrypt\n");
printf(" d decrypt\n");
printf(" optimize:\n");
printf(" d default\n");
printf(" s size\n");
printf(" e Security\n");
printf(" t time\n");
printf(" z time+size\n");
printf(" a ASCII\n");
exit(1);
}
int main(int argc, char **argv)
{
int rtn;
uint32 keySizeInBytes = CSP_ASC_KEY_SIZE_DEFAULT / 8;
uint32 optimize = CSSM_ASC_OPTIMIZE_DEFAULT;
char *password; char *inFileName; unsigned char *inFile; unsigned inFileSize; char *outFileName; CSSM_CSP_HANDLE cspHand;
CSSM_RETURN crtn;
int doEncrypt = 0;
CSSM_DATA passwordData;
CSSM_DATA saltData = {8, (uint8 *)"someSalt"};
CSSM_DATA inData; CSSM_DATA outData = {0, NULL}; CSSM_KEY_PTR symKey;
int arg;
char *argp;
CFAbsoluteTime start, end;
CSSM_CC_HANDLE ccHand; CSSM_DATA remData = {0, NULL};
CSSM_SIZE bytesProcessed;
CSSM_DATA iv = {0, NULL};
if(argc < 5) {
usage(argv);
}
switch(argv[1][0]) {
case 'e':
doEncrypt = 1;
break;
case 'd':
doEncrypt = 0;
break;
default:
usage(argv);
}
password = argv[2];
passwordData.Data = (uint8 *)password;
passwordData.Length = strlen(password);
inFileName = argv[3];
outFileName = argv[4];
for(arg=5; arg<argc; arg++) {
argp = argv[arg];
switch(argp[0]) {
case 'k':
keySizeInBytes = atoi(&argp[2]);
if(keySizeInBytes == 0) {
printf("keySize of 0 illegal\n");
exit(1);
}
break;
case 'o':
switch(argp[2]) {
case 'd':
optimize = CSSM_ASC_OPTIMIZE_DEFAULT;
break;
case 's':
optimize = CSSM_ASC_OPTIMIZE_SIZE;
break;
case 'e':
optimize = CSSM_ASC_OPTIMIZE_SECURITY;
break;
case 't':
optimize = CSSM_ASC_OPTIMIZE_TIME;
break;
case 'z':
optimize = CSSM_ASC_OPTIMIZE_TIME_SIZE;
break;
case 'a':
optimize = CSSM_ASC_OPTIMIZE_ASCII;
break;
default:
usage(argv);
}
break;
default:
usage(argv);
}
}
rtn = readFile(inFileName, &inFile, &inFileSize);
if(rtn) {
printf("Error reading %s: %s\n", inFileName, strerror(rtn));
exit(1);
}
inData.Data = inFile;
inData.Length = inFileSize;
cspHand = cspStartup();
if(cspHand == 0) {
exit(1);
}
symKey = cspDeriveKey(cspHand,
CSSM_ALGID_PKCS5_PBKDF2,
CSSM_ALGID_ASC,
"someLabel", 9, doEncrypt ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
keySizeInBytes * 8, CSSM_FALSE, &passwordData,
&saltData,
1000, &iv);
if(symKey == NULL) {
exit(1);
}
crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
CSSM_ALGID_ASC, CSSM_ALGMODE_NONE, NULL, symKey,
NULL, CSSM_PADDING_NONE, NULL, &ccHand);
if(crtn) {
printError("CSSM_CSP_CreateSymmetricContext", crtn);
exit(1);
}
if(optimize != CSSM_ASC_OPTIMIZE_DEFAULT) {
crtn = AddContextAttribute(ccHand,
CSSM_ATTRIBUTE_ASC_OPTIMIZATION,
sizeof(uint32),
CAT_Uint32,
NULL,
optimize);
if(crtn) {
exit(1);
}
}
start = CFAbsoluteTimeGetCurrent();
if(doEncrypt) {
crtn = CSSM_EncryptDataInit(ccHand);
if(crtn) {
printError("CSSM_EncryptDataInit", crtn);
exit(1);
}
crtn = CSSM_EncryptDataUpdate(ccHand,
&inData,
1,
&outData,
1,
&bytesProcessed);
if(crtn) {
printError("CSSM_EncryptDataUpdate", crtn);
exit(1);
}
outData.Length = bytesProcessed;
crtn = CSSM_EncryptDataFinal(ccHand, &remData);
if(crtn) {
printError("CSSM_EncryptDataFinal", crtn);
exit(1);
}
if(remData.Length != 0) {
uint32 newLen = outData.Length + remData.Length;
outData.Data = (uint8 *)appRealloc(outData.Data,
newLen,
NULL);
memmove(outData.Data + outData.Length, remData.Data, remData.Length);
outData.Length = newLen;
appFree(remData.Data, NULL);
}
}
else {
crtn = CSSM_DecryptDataInit(ccHand);
if(crtn) {
printError("CSSM_DecryptDataInit", crtn);
exit(1);
}
crtn = CSSM_DecryptDataUpdate(ccHand,
&inData,
1,
&outData,
1,
&bytesProcessed);
if(crtn) {
printError("CSSM_DecryptDataUpdate", crtn);
exit(1);
}
outData.Length = bytesProcessed;
crtn = CSSM_DecryptDataFinal(ccHand, &remData);
if(crtn) {
printError("CSSM_DecryptDataFinal", crtn);
exit(1);
}
if(remData.Length != 0) {
uint32 newLen = outData.Length + remData.Length;
outData.Data = (uint8 *)appRealloc(outData.Data,
newLen,
NULL);
memmove(outData.Data + outData.Length, remData.Data, remData.Length);
outData.Length = newLen;
appFree(remData.Data, NULL);
}
}
end = CFAbsoluteTimeGetCurrent();
if(crtn == CSSM_OK) {
double inSizeD = (double)inFileSize;
double outSizeD = (double)outData.Length;
CFAbsoluteTime delta = end - start;
rtn = writeFile(outFileName, outData.Data, outData.Length);
if(rtn) {
printf("Error writing %s: %s\n", outFileName, strerror(rtn));
exit(1);
}
printf(" inFile length %d bytes, outFile length %lu bytes, "
"%d ms\n",
inFileSize, outData.Length, (unsigned)(delta * 1000.0));
printf(" compression = %.2f %.2f KBytes/s\n",
doEncrypt ? outSizeD / inSizeD : inSizeD / outSizeD,
inSizeD / delta / 1024.0);
}
CSSM_ModuleDetach(cspHand);
return rtn;
}