X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_cryptkit/lib/CipherFileFEED.c diff --git a/Security/libsecurity_cryptkit/lib/CipherFileFEED.c b/Security/libsecurity_cryptkit/lib/CipherFileFEED.c new file mode 100644 index 00000000..ce9e075a --- /dev/null +++ b/Security/libsecurity_cryptkit/lib/CipherFileFEED.c @@ -0,0 +1,460 @@ +/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. + * + * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT + * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE + * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE + * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, + * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL + * EXPOSE YOU TO LIABILITY. + *************************************************************************** + * + * CipherFileFEED.c - FEED and FEEDExp related cipherfile support + * + * Revision History + * ---------------- + * 24 Jun 97 at Apple + * Fixed memory leaks via sigData + * 18 Feb 97 at Apple + * Split off from feeCipherFile.c + */ + +#include "ckconfig.h" + +#if CRYPTKIT_CIPHERFILE_ENABLE + +#include "Crypt.h" +#include "CipherFileFEED.h" +#include "falloc.h" +#include "feeDebug.h" + +feeReturn createFEED(feePubKey sendPrivKey, // required + feePubKey recvPubKey, + const unsigned char *plainText, + unsigned plainTextLen, + int genSig, // 1 ==> generate signature + unsigned userData, // for caller's convenience + feeCipherFile *cipherFile) // RETURNED if successful +{ + feeReturn frtn; + feeFEED feed = NULL; + unsigned char *cipherText = NULL; + unsigned cipherTextLen; + unsigned char *sigData = NULL; + unsigned sigDataLen = 0; + feeCipherFile cfile = NULL; + unsigned char *pubKeyString = NULL; // of sendPrivKey + unsigned pubKeyStringLen = 0; + + if((sendPrivKey == NULL) || (recvPubKey == NULL)) { + return FR_BadPubKey; + } + + /* + * FEED encrypt plaintext + */ + feed = feeFEEDNewWithPubKey(sendPrivKey, recvPubKey, FF_ENCRYPT, NULL, NULL); + if(feed == NULL) { + frtn = FR_BadPubKey; + goto out; + } + frtn = feeFEEDEncrypt(feed, + plainText, + plainTextLen, + &cipherText, + &cipherTextLen); + if(frtn) { + goto out; + } + + /* + * Sender's public key string + */ + frtn = feePubKeyCreateKeyString(sendPrivKey, + (char **)&pubKeyString, + &pubKeyStringLen); + if(frtn) { + /* + * Huh? + */ + frtn = FR_BadPubKey; + goto out; + } + + if(genSig) { + /* + * We generate signature on ciphertext by convention. + */ + frtn = feePubKeyCreateSignature(sendPrivKey, + cipherText, + cipherTextLen, + &sigData, + &sigDataLen); + if(frtn) { + goto out; + } + } + + /* + * Cons up a cipherfile + */ + cfile = feeCFileNewFromCipherText(CFE_FEED, + cipherText, + cipherTextLen, + pubKeyString, + pubKeyStringLen, + NULL, + 0, + sigData, + sigDataLen, + userData); + if(cfile == NULL) { + frtn = FR_Internal; + goto out; + } + +out: + /* free alloc'd stuff */ + + if(cipherText) { + ffree(cipherText); + } + if(feed) { + feeFEEDFree(feed); + } + if(pubKeyString) { + ffree(pubKeyString); + } + if(sigData) { + ffree(sigData); + } + *cipherFile = cfile; + return frtn; + +} + +feeReturn decryptFEED(feeCipherFile cipherFile, + feePubKey recvPrivKey, + feePubKey sendPubKey, // optional + unsigned char **plainText, // RETURNED + unsigned *plainTextLen, // RETURNED + feeSigStatus *sigStatus) // RETURNED +{ + feeReturn frtn = FR_Success; + unsigned char *cipherText = NULL; + unsigned cipherTextLen; + feeFEED feed = NULL; + unsigned char *sigData = NULL; + unsigned sigDataLen; + unsigned char *sendPubKeyStr = NULL; + unsigned sendPubKeyStrLen = 0; + feePubKey parsedSendPubKey = NULL; + + if(feeCFileEncrType(cipherFile) != CFE_FEED) { + frtn = FR_Internal; + goto out; + } +//printf("decryptFEED\n"); +//printf("privKey:\n"); printPubKey(recvPrivKey); +//printf("pubKey:\n"); printPubKey(sendPubKey); + /* + * Get ciphertext and sender's public key from cipherFile + */ + cipherText = feeCFileCipherText(cipherFile, &cipherTextLen); + if(cipherText == NULL) { + frtn = FR_BadCipherFile; + goto out; + } + sendPubKeyStr = feeCFileSendPubKeyData(cipherFile, &sendPubKeyStrLen); + if(sendPubKeyStr == NULL) { + frtn = FR_BadCipherFile; + goto out; + } + parsedSendPubKey = feePubKeyAlloc(); + frtn = feePubKeyInitFromKeyString(parsedSendPubKey, + (char *)sendPubKeyStr, + sendPubKeyStrLen); + if(frtn) { + frtn = FR_BadCipherFile; + goto out; + } +//printf("parsedSendPubKey:\n"); printPubKey(parsedSendPubKey); + + /* + * FEED decrypt + */ + feed = feeFEEDNewWithPubKey(recvPrivKey, parsedSendPubKey, FF_DECRYPT, NULL, NULL); + if(feed == NULL) { + frtn = FR_BadPubKey; + goto out; + } + frtn = feeFEEDDecrypt(feed, + cipherText, + cipherTextLen, + plainText, + plainTextLen); + if(frtn) { + goto out; + } + + sigData = feeCFileSigData(cipherFile, &sigDataLen); + if(sigData) { + feeReturn sigFrtn; + + if(sendPubKey == NULL) { + /* + * use embedded sender's public key + */ + sendPubKey = parsedSendPubKey; + } + sigFrtn = feePubKeyVerifySignature(sendPubKey, + cipherText, + cipherTextLen, + sigData, + sigDataLen); + switch(sigFrtn) { + case FR_Success: + *sigStatus = SS_PresentValid; + break; + default: + *sigStatus = SS_PresentInvalid; + break; + } + } + else { + *sigStatus = SS_NotPresent; + } +out: + if(cipherText) { + ffree(cipherText); + } + if(feed) { + feeFEEDFree(feed); + } + if(sigData) { + ffree(sigData); + } + if(parsedSendPubKey) { + feePubKeyFree(parsedSendPubKey); + } + if(sendPubKeyStr) { + ffree(sendPubKeyStr); + } + return frtn; +} + +feeReturn createFEEDExp(feePubKey sendPrivKey, // for sig only + feePubKey recvPubKey, + const unsigned char *plainText, + unsigned plainTextLen, + int genSig, // 1 ==> generate signature + unsigned userData, // for caller's convenience + feeCipherFile *cipherFile) // RETURNED if successful +{ + feeReturn frtn; + feeFEEDExp feed = NULL; + unsigned char *cipherText = NULL; + unsigned cipherTextLen; + unsigned char *sigData = NULL; + unsigned sigDataLen = 0; + feeCipherFile cfile = NULL; + unsigned char *pubKeyString = NULL; // of sendPrivKey, for sig + unsigned pubKeyStringLen = 0; + + if(recvPubKey == NULL) { + return FR_BadPubKey; + } + + /* + * FEEDExp encrypt plaintext + */ + feed = feeFEEDExpNewWithPubKey(recvPubKey, NULL, NULL); + if(feed == NULL) { + frtn = FR_BadPubKey; + goto out; + } + frtn = feeFEEDExpEncrypt(feed, + plainText, + plainTextLen, + &cipherText, + &cipherTextLen); + if(frtn) { + goto out; + } + + if(genSig) { + if(sendPrivKey == NULL) { + frtn = FR_IllegalArg; + goto out; + } + /* + * We generate signature on ciphertext by convention. + */ + frtn = feePubKeyCreateSignature(sendPrivKey, + cipherText, + cipherTextLen, + &sigData, + &sigDataLen); + if(frtn) { + goto out; + } + /* + * Sender's public key string + */ + frtn = feePubKeyCreateKeyString(sendPrivKey, + (char **)&pubKeyString, + &pubKeyStringLen); + if(frtn) { + /* + * Huh? + */ + frtn = FR_BadPubKey; + goto out; + } + } + + /* + * Cons up a cipherfile + */ + cfile = feeCFileNewFromCipherText(CFE_FEEDExp, + cipherText, + cipherTextLen, + pubKeyString, + pubKeyStringLen, + NULL, + 0, + sigData, + sigDataLen, + userData); + if(cfile == NULL) { + frtn = FR_Internal; + goto out; + } + +out: + /* free alloc'd stuff */ + + if(cipherText) { + ffree(cipherText); + } + if(feed) { + feeFEEDExpFree(feed); + } + if(sigData) { + ffree(sigData); + } + if(pubKeyString) { + ffree(pubKeyString); + } + *cipherFile = cfile; + return frtn; + +} + +feeReturn decryptFEEDExp(feeCipherFile cipherFile, + feePubKey recvPrivKey, + feePubKey sendPubKey, // optional + unsigned char **plainText, // RETURNED + unsigned *plainTextLen, // RETURNED + feeSigStatus *sigStatus) // RETURNED +{ + feeReturn frtn = FR_Success; + unsigned char *cipherText = NULL; + unsigned cipherTextLen; + feeFEEDExp feed = NULL; + unsigned char *sigData = NULL; + unsigned sigDataLen; + unsigned char *sendPubKeyStr = NULL; + unsigned sendPubKeyStrLen = 0; + feePubKey parsedSendPubKey = NULL; + + if(feeCFileEncrType(cipherFile) != CFE_FEEDExp) { + frtn = FR_Internal; + goto out; + } + + /* + * Get ciphertext from cipherFile + */ + cipherText = feeCFileCipherText(cipherFile, &cipherTextLen); + if(cipherText == NULL) { + frtn = FR_BadCipherFile; + goto out; + } + + /* + * FEEDExp decrypt + */ + feed = feeFEEDExpNewWithPubKey(recvPrivKey, NULL, NULL); + if(feed == NULL) { + frtn = FR_BadPubKey; + goto out; + } + frtn = feeFEEDExpDecrypt(feed, + cipherText, + cipherTextLen, + plainText, + plainTextLen); + if(frtn) { + goto out; + } + + sigData = feeCFileSigData(cipherFile, &sigDataLen); + if(sigData) { + feeReturn sigFrtn; + + if(sendPubKey == NULL) { + /* + * use embedded sender's public key + */ + sendPubKeyStr = feeCFileSendPubKeyData(cipherFile, + &sendPubKeyStrLen); + if(sendPubKeyStr == NULL) { + frtn = FR_BadCipherFile; + goto out; + } + parsedSendPubKey = feePubKeyAlloc(); + frtn = feePubKeyInitFromKeyString(parsedSendPubKey, + (char *)sendPubKeyStr, sendPubKeyStrLen); + if(frtn) { + frtn = FR_BadCipherFile; + goto out; + } + sendPubKey = parsedSendPubKey; + } + sigFrtn = feePubKeyVerifySignature(sendPubKey, + cipherText, + cipherTextLen, + sigData, + sigDataLen); + switch(sigFrtn) { + case FR_Success: + *sigStatus = SS_PresentValid; + break; + default: + *sigStatus = SS_PresentInvalid; + break; + } + } + else { + *sigStatus = SS_NotPresent; + } +out: + if(cipherText) { + ffree(cipherText); + } + if(feed) { + feeFEEDExpFree(feed); + } + if(sigData) { + ffree(sigData); + } + if(parsedSendPubKey) { + feePubKeyFree(parsedSendPubKey); + } + if(sendPubKeyStr) { + ffree(sendPubKeyStr); + } + return frtn; +} + +#endif /* CRYPTKIT_CIPHERFILE_ENABLE */