int wolfsslSetup(int argc, char** argv, char action) { char outNameE[256]; /* default outFile for encrypt */ char outNameD[256]; /* default outfile for decrypt */ char inName[256]; /* name of the in File if not provided */ char* name = NULL; /* string of algorithm, mode, keysize */ char* alg = NULL; /* algorithm from name */ char* mode = NULL; /* mode from name */ char* out = outNameE; /* default output file name */ char* in = inName; /* default in data */ byte* pwdKey = NULL; /* password for generating pwdKey */ byte* key = NULL; /* user set key NOT PWDBASED */ byte* iv = NULL; /* iv for initial encryption */ int size = 0; /* keysize from name */ int ret = 0; /* return variable */ int block = 0; /* block size based on algorithm */ int pwdKeyChk = 0; /* if a pwdKey has been provided */ int ivCheck = 0; /* if the user sets the IV explicitly */ int keyCheck = 0; /* if ivCheck is 1 this should be set also */ int inCheck = 0; /* if input has been provided */ int outCheck = 0; /* if output has been provided */ int i = 0; /* loop counter */ int eCheck = 0; /* if user is encrypting data */ int dCheck = 0; /* if user is decrypting data */ int inputHex = 0; /* if user is encrypting hexidecimal stuff */ int keyType = 0; /* tells Decrypt which key it will be using * 1 = password based key, 2 = user set key */ word32 ivSize = 0; /* IV if provided should be 2*block */ word32 numBits = 0; /* number of bits in argument from the user */ if (action == 'e') eCheck = 1; if (action == 'd') dCheck = 1; for (i = 2; i < argc; i++) { if (strcmp(argv[i], "-help") == 0) { if (eCheck == 1) { /*wolfsslEncryptHelp*/ wolfsslEncryptHelp(); return 0; } else { /*wolfsslDecryptHelp*/ wolfsslDecryptHelp(); return 0; } } } name = argv[2]; /* gets blocksize, algorithm, mode, and key size from name argument */ block = wolfsslGetAlgo(name, &alg, &mode, &size); if (block != FATAL_ERROR) { pwdKey = (byte*) malloc(size); iv = (byte*) malloc(block); key = (byte*) malloc(size); /* Start at the third flag entered */ i = 3; do { if (argv[i] == NULL){ break; } else if (strcmp(argv[i], "-o") == 0 && argv[i+1] != NULL) { /* output file */ out = argv[i+1]; outCheck = 1; i+=2; /* it is mandatory that this be set last */ continue; } else if (strcmp(argv[i], "-i") == 0 && argv[i+1] != NULL) { /* input file/text */ in = argv[i+1]; inCheck = 1; /* continue while out check not equal 1 */ i+=2; continue; } else if (strcmp(argv[i], "-p") == 0 && argv[i+1] != NULL) { /* password pwdKey */ XMEMCPY(pwdKey, argv[i+1], size); pwdKeyChk = 1; keyType = 1; i+=2; continue; } else if (strcmp(argv[i], "-x") == 0) { /* using hexidecimal format */ inputHex = 1; i++; continue; } else if (strcmp(argv[i], "-V") == 0 && argv[i+1] != NULL) { /* iv for encryption */ if (pwdKeyChk == 1) { printf("Invalid option, attempting to use IV with password" " based key."); wolfsslFreeBins(pwdKey, iv, key, NULL, NULL); return FATAL_ERROR; } ivSize = block*2; if (strlen(argv[i+1]) != ivSize) { printf("Invalid IV. Must match algorithm block size.\n"); printf("Invalid IV size was: %d.\n", (int) strlen(argv[i+1])); printf("size of IV expected was: %d.\n", ivSize); wolfsslFreeBins(pwdKey, iv, key, NULL, NULL); return FATAL_ERROR; } else { char ivString[strlen(argv[i+1])]; XSTRNCPY(ivString, argv[i+1], XSTRLEN(argv[i+1])); ret = wolfsslHexToBin(ivString, &iv, &ivSize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (ret != 0) { printf("failed during conversion of IV, ret = %d\n", ret); wolfsslFreeBins(pwdKey, iv, key, NULL, NULL); return -1; } ivCheck = 1; i+=2; continue; } } else if (strcmp(argv[i], "-K") == 0 && argv[i+1] != NULL) { /* 2 characters = 1 byte. 1 byte = 8 bits * number of characters / 2 = bytes * bytes * 8 = bits */ numBits = (int) (strlen(argv[i+1]) / 2 ) * 8; /* Key for encryption */ if ((int)numBits != size) { printf("Length of key provided was: %d.\n", numBits); printf("Length of key expected was: %d.\n", size); printf("Invalid Key. Must match algorithm key size.\n"); wolfsslFreeBins(pwdKey, iv, key, NULL, NULL); return FATAL_ERROR; } else { char keyString[strlen(argv[i+1])]; XSTRNCPY(keyString, argv[i+1], XSTRLEN(argv[i+1])); ret = wolfsslHexToBin(keyString, &key, &numBits, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (ret != 0) { printf("failed during conversion of Key, ret = %d\n", ret); wolfsslFreeBins(pwdKey, iv, key, NULL, NULL); return -1; } keyCheck = 1; keyType = 2; i+=2; continue; } } else { i++; continue; } }while(i < 15); if (pwdKeyChk == 0 && keyCheck == 0) { if (dCheck == 1) { printf("\nDECRYPT ERROR:\n"); printf("Please type \"wolfssl -d -help\" for decryption usage." "\n\n"); return 0; } /* if no pwdKey is provided */ else { printf("No -p flag set, please enter a password to use for" " encrypting.\n"); printf("Write your password down so you don't forget it.\n"); ret = wolfsslNoEcho((char*)pwdKey, size); pwdKeyChk = 1; } } if (inCheck == 0 && eCheck == 1) { ret = 0; while (ret == 0) { printf("-i flag was not set, please enter a string or\n" "file name to be encrypted: "); ret = (int) scanf("%s", inName); } in = inName; /* if no input is provided */ printf("Ok, We will encrypt:\"%s\" for you.\n", inName); inCheck = 1; } if (eCheck == 1 && dCheck == 1) { printf("You want to encrypt and decrypt simultaneously? That is" "not possible...\n"); wolfsslFreeBins(pwdKey, iv, key, NULL, NULL); return FATAL_ERROR; } if (inCheck == 0 && dCheck == 1) { printf("We are so sorry but you must specify what it is you are " "trying to decrypt.\n"); wolfsslFreeBins(pwdKey, iv, key, NULL, NULL); return FATAL_ERROR; } if (ivCheck == 1) { if (keyCheck == 0) { printf("IV was explicitly set, but no -K <key> was set. User\n" " needs to provide a non-password based key when setting" " the IV.\n"); wolfsslFreeBins(pwdKey, iv, key, NULL, NULL); return FATAL_ERROR; } } if (pwdKeyChk == 1 && keyCheck == 1) { XMEMSET(pwdKey, 0, size); } /* encryption function call */ if (eCheck == 1) { printf("\n"); if (outCheck == 0) { ret = 0; while (ret == 0) { printf("Please enter a name for the output file: "); ret = (int) scanf("%s", outNameE); out = (ret > 0) ? outNameE : '\0'; } } ret = wolfsslEncrypt(alg, mode, pwdKey, key, size, in, out, iv, block, ivCheck, inputHex); } /* decryption function call */ else if (dCheck == 1) { if (outCheck == 0) { ret = 0; while (ret == 0) { printf("Please enter a name for the output file: "); ret = (int) scanf("%s", outNameD); out = (ret > 0) ? outNameD : '\0'; } } ret = wolfsslDecrypt(alg, mode, pwdKey, key, size, in, out, iv, block, keyType); } else { wolfsslHelp(); } /* clear and free data */ XMEMSET(key, 0, size); XMEMSET(pwdKey, 0, size); XMEMSET(iv, 0, block); wolfsslFreeBins(pwdKey, iv, key, NULL, NULL); } else ret = FATAL_ERROR; return ret; }
int wolfsslEncrypt(char* alg, char* mode, byte* pwdKey, byte* key, int size, char* in, char* out, byte* iv, int block, int ivCheck, int inputHex) { #ifndef NO_AES Aes aes; /* aes declaration */ #endif #ifndef NO_DES3 Des3 des3; /* 3des declaration */ #endif #ifdef HAVE_CAMELLIA Camellia camellia; /* camellia declaration */ #endif FILE* tempInFile = NULL; /* if user not provide a file */ FILE* inFile = NULL; /* input file */ FILE* outFile = NULL; /* output file */ RNG rng; /* random number generator declaration */ byte* input = NULL; /* input buffer */ byte* output = NULL; /* output buffer */ byte salt[SALT_SIZE] = {0}; /* salt variable */ int ret = 0; /* return variable */ int inputLength = 0; /* length of input */ int length = 0; /* total length */ int padCounter = 0; /* number of padded bytes */ int i = 0; /* loop variable */ int hexRet = 0; /* hex -> bin return*/ word32 tempInputL = 0; /* temporary input Length */ word32 tempMax = MAX; /* controls encryption amount */ char inputString[MAX]; /* the input string */ char* userInputBuffer = NULL; /* buffer when input is not a file */ if (access (in, F_OK) == -1) { printf("file did not exist, encrypting string following \"-i\"" "instead.\n"); /* use user entered data to encrypt */ inputLength = (int) strlen(in); userInputBuffer = (char*) malloc(inputLength); /* writes the entered text to the input buffer */ XMEMCPY(userInputBuffer, in, inputLength); /* open the file to write */ tempInFile = fopen(in, "wb"); fwrite(userInputBuffer, 1, inputLength, tempInFile); fclose(tempInFile); /* free buffer */ free(userInputBuffer); } /* open the inFile in read mode */ inFile = fopen(in, "rb"); /* find length */ fseek(inFile, 0, SEEK_END); inputLength = (int) ftell(inFile); fseek(inFile, 0, SEEK_SET); length = inputLength; /* Start up the random number generator */ ret = (int) wc_InitRng(&rng); if (ret != 0) { printf("Random Number Generator failed to start.\n"); return ret; } /* pads the length until it matches a block, * and increases pad number */ while (length % block != 0) { length++; padCounter++; } /* if the iv was not explicitly set, * generate an iv and use the pwdKey */ if (ivCheck == 0) { /* IV not set, generate it */ ret = wc_RNG_GenerateBlock(&rng, iv, block); if (ret != 0) { return ret; } /* stretches pwdKey to fit size based on wolfsslGetAlgo() */ ret = wolfsslGenKey(&rng, pwdKey, size, salt, padCounter); if (ret != 0) { printf("failed to set pwdKey.\n"); return ret; } /* move the generated pwdKey to "key" for encrypting */ for (i = 0; i < size; i++) { key[i] = pwdKey[i]; } } /* open the outFile in write mode */ outFile = fopen(out, "wb"); fwrite(salt, 1, SALT_SIZE, outFile); fwrite(iv, 1, block, outFile); fclose(outFile); /* malloc 1kB buffers */ input = (byte*) malloc(MAX); output = (byte*) malloc(MAX); /* loop, encrypt 1kB at a time till length <= 0 */ while (length > 0) { /* Read in 1kB to input[] */ if (inputHex == 1) ret = (int) fread(inputString, 1, MAX, inFile); else ret = (int) fread(input, 1, MAX, inFile); if (ret != MAX) { /* check for end of file */ if (feof(inFile)) { /* hex or ascii */ if (inputHex == 1) { hexRet = wolfsslHexToBin(inputString, &input, &tempInputL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (hexRet != 0) { printf("failed during conversion of input," " ret = %d\n", hexRet); return hexRet; } }/* end hex or ascii */ /* pad to end of block */ for (i = ret ; i < (ret + padCounter); i++) { input[i] = padCounter; } /* adjust tempMax for less than 1kB encryption */ tempMax = ret + padCounter; } else { /* otherwise we got a file read error */ wolfsslFreeBins(input, output, NULL, NULL, NULL); return FREAD_ERROR; }/* End feof check */ }/* End fread check */ /* sets key encrypts the message to ouput from input */ #ifndef NO_AES if (XSTRNCMP(alg, "aes", 3) == 0) { if (XSTRNCMP(mode, "cbc", 3) == 0) { ret = wc_AesSetKey(&aes, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); if (ret != 0) { printf("wc_AesSetKey failed.\n"); wolfsslFreeBins(input, output, NULL, NULL, NULL); return ret; } ret = wc_AesCbcEncrypt(&aes, output, input, tempMax); if (ret != 0) { printf("wc_AesCbcEncrypt failed.\n"); wolfsslFreeBins(input, output, NULL, NULL, NULL); return ENCRYPT_ERROR; } } #ifdef WOLFSSL_AES_COUNTER else if (XSTRNCMP(mode, "ctr", 3) == 0) { /* if mode is ctr */ wc_AesSetKeyDirect(&aes, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); wc_AesCtrEncrypt(&aes, output, input, tempMax); } #endif } #endif #ifndef NO_DES3 if (XSTRNCMP(alg, "3des", 4) == 0) { ret = wc_Des3_SetKey(&des3, key, iv, DES_ENCRYPTION); if (ret != 0) { printf("wc_Des3_SetKey failed.\n"); wolfsslFreeBins(input, output, NULL, NULL, NULL); return ret; } ret = wc_Des3_CbcEncrypt(&des3, output, input, tempMax); if (ret != 0) { printf("wc_Des3_cbcEncrypt failed.\n"); wolfsslFreeBins(input, output, NULL, NULL, NULL); return ENCRYPT_ERROR; } } #endif #ifdef HAVE_CAMELLIA if (XSTRNCMP(alg, "camellia", 8) == 0) { ret = wc_CamelliaSetKey(&camellia, key, block, iv); if (ret != 0) { printf("CamelliaSetKey failed.\n"); wolfsslFreeBins(input, output, NULL, NULL, NULL); return ret; } if (XSTRNCMP(mode, "cbc", 3) == 0) { wc_CamelliaCbcEncrypt(&camellia, output, input, tempMax); } else { printf("Incompatible mode while using Camellia.\n"); wolfsslFreeBins(input, output, NULL, NULL, NULL); return FATAL_ERROR; } } #endif /* HAVE_CAMELLIA */ /* this method added for visual confirmation of nist test vectors, * automated tests to come soon */ /* something in the output buffer and using hex */ if (output != NULL && inputHex == 1) { int tempi; printf("\nUser specified hex input this is a representation of " "what\nis being written to file in hex form.\n\n[ "); for (tempi = 0; tempi < block; tempi++ ) { printf("%02x", output[tempi]); } printf(" ]\n\n"); } /* end visual confirmation */ /* Open the outFile in append mode */ outFile = fopen(out, "ab"); ret = (int) fwrite(output, 1, tempMax, outFile); if (ferror(outFile)) { printf("failed to write to file.\n"); if (input != NULL) XMEMSET(input, 0, tempMax); if (output != NULL) XMEMSET(output, 0, tempMax); wolfsslFreeBins(input, output, NULL, NULL, NULL); return FWRITE_ERROR; } if (ret > MAX) { printf("Wrote too much to file.\n"); if (input != NULL) XMEMSET(input, 0, tempMax); if (output != NULL) XMEMSET(output, 0, tempMax); wolfsslFreeBins(input, output, NULL, NULL, NULL); return FWRITE_ERROR; } /* close the outFile */ fclose(outFile); length -= tempMax; if (length < 0) printf("length went past zero.\n"); if (input != NULL) XMEMSET(input, 0, tempMax); if (output != NULL) XMEMSET(output, 0, tempMax); } /* closes the opened files and frees the memory */ fclose(inFile); XMEMSET(key, 0, size); XMEMSET(iv, 0 , block); XMEMSET(alg, 0, size); XMEMSET(mode, 0 , block); /* Use the wolfssl free for rng */ wc_FreeRng(&rng); wolfsslFreeBins(input, output, NULL, NULL, NULL); return 0; }