1/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. 2 * 3 * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT 4 * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE 5 * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE 6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, 7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL 8 * EXPOSE YOU TO LIABILITY. 9 *************************************************************************** 10 * 11 * feeCipherFile.c - general cipherfile support 12 * 13 * Revision History 14 * ---------------- 15 * 05 Feb 97 at Apple 16 * Added CFE_FEED and CFE_FEEDExp types. 17 * 24 Oct 96 at NeXT 18 * Created. 19 */ 20 21#include "feeCipherFile.h" 22#include "falloc.h" 23#include "feeFEEDExp.h" 24#include "feeFEED.h" 25#include "feeDebug.h" 26#include "CipherFileFEED.h" 27#include "CipherFileDES.h" 28 29 30/* 31 * Create a cipherfile of specified cipherFileEncrType. 32 */ 33feeReturn createCipherFile(feePubKey sendPrivKey, 34 feePubKey recvPubKey, 35 cipherFileEncrType encrType, 36 const unsigned char *plainText, 37 unsigned plainTextLen, 38 int genSig, // 1 ==> generate signature 39 int doEnc64, // 1 ==> perform enc64 40 unsigned userData, // for caller's convenience 41 unsigned char **cipherFileData, // RETURNED 42 unsigned *cipherFileDataLen) // RETURNED 43{ 44 feeReturn frtn = FR_Success; 45 feeCipherFile cipherFile = NULL; 46 unsigned char *cipherData = NULL; 47 unsigned cipherDataLen; 48 49 /* 50 * Dispatch to encrType-specific code. 51 */ 52 switch(encrType) { 53 case CFE_RandDES: 54 frtn = createRandDES(sendPrivKey, 55 recvPubKey, 56 plainText, 57 plainTextLen, 58 genSig, 59 userData, 60 &cipherFile); 61 break; 62 case CFE_PublicDES: 63 frtn = createPubDES(sendPrivKey, 64 recvPubKey, 65 plainText, 66 plainTextLen, 67 genSig, 68 userData, 69 &cipherFile); 70 break; 71 case CFE_FEED: 72 frtn = createFEED(sendPrivKey, 73 recvPubKey, 74 plainText, 75 plainTextLen, 76 genSig, 77 userData, 78 &cipherFile); 79 break; 80 case CFE_FEEDExp: 81 frtn = createFEEDExp(sendPrivKey, 82 recvPubKey, 83 plainText, 84 plainTextLen, 85 genSig, 86 userData, 87 &cipherFile); 88 break; 89 default: 90 frtn = FR_Unimplemented; 91 break; 92 } 93 94 if(frtn) { 95 goto out; 96 } 97 98 /* 99 * Common logic for all encrTypes 100 */ 101 102 /* 103 * Get the cipherfile's raw data 104 */ 105 frtn = feeCFileDataRepresentation(cipherFile, 106 (const unsigned char **)&cipherData, 107 &cipherDataLen); 108 if(frtn) { 109 goto out; 110 } 111 112 /* 113 * Optionally encode in 64-char ASCII 114 */ 115 if(doEnc64) { 116 *cipherFileData = enc64(cipherData, 117 cipherDataLen, 118 cipherFileDataLen); 119 ffree(cipherData); 120 if(*cipherFileData == NULL) { 121 frtn = FR_Internal; 122 ffree(cipherData); 123 goto out; 124 } 125 } 126 else { 127 *cipherFileData = cipherData; 128 *cipherFileDataLen = cipherDataLen; 129 } 130out: 131 /* free stuff */ 132 if(cipherFile) { 133 feeCFileFree(cipherFile); 134 } 135 return frtn; 136} 137 138/* 139 * Parse a cipherfile. 140 * 141 * sendPubKey only needed for cipherFileEncrType CFE_RandDES if signature 142 * is present. If sendPubKey is present, it will be used for signature 143 * validation rather than the embedded sender's public key. 144 */ 145feeReturn parseCipherFile(feePubKey recvPrivKey, 146 feePubKey sendPubKey, 147 const unsigned char *cipherFileData, 148 unsigned cipherFileDataLen, 149 int doDec64, // 1 ==> perform dec64 150 cipherFileEncrType *encrType, // RETURNED 151 unsigned char **plainText, // RETURNED 152 unsigned *plainTextLen, // RETURNED 153 feeSigStatus *sigStatus, // RETURNED 154 unsigned *userData) // RETURNED 155{ 156 feeReturn frtn; 157 unsigned char *cipherData = NULL; 158 unsigned cipherDataLen; 159 int freeCipherData = 0; 160 feeCipherFile cipherFile = NULL; 161 162 *plainText = NULL; 163 *plainTextLen = 0; 164 165 if(recvPrivKey == NULL) { // always required 166 frtn = FR_BadPubKey; 167 goto out; 168 } 169 170 /* 171 * First, optional dec64() 172 */ 173 if(doDec64) { 174 cipherData = dec64(cipherFileData, 175 cipherFileDataLen, 176 &cipherDataLen); 177 if(cipherData == NULL) { 178 frtn = FR_BadEnc64; 179 goto out; 180 } 181 else { 182 freeCipherData = 1; 183 } 184 } 185 else { 186 cipherData = (unsigned char *)cipherFileData; 187 cipherDataLen = cipherFileDataLen; 188 } 189 190 /* 191 * Cons up a feeCipherFile object. 192 */ 193 frtn = feeCFileNewFromDataRep(cipherData, 194 cipherDataLen, 195 &cipherFile); 196 if(frtn) { 197 goto out; 198 } 199 *encrType = feeCFileEncrType(cipherFile); 200 *userData = feeCFileUserData(cipherFile); 201 frtn = decryptCipherFile(cipherFile, 202 recvPrivKey, 203 sendPubKey, 204 plainText, 205 plainTextLen, 206 sigStatus); 207 208out: 209 /* free stuff */ 210 211 if(cipherData && freeCipherData) { 212 ffree(cipherData); 213 } 214 if(cipherFile) { 215 feeCFileFree(cipherFile); 216 } 217 return frtn; 218} 219 220/* 221 * Decrypt a feeCipherFile obtained via feeCFileNewFromDataRep(). 222 * recvPrivKey is required in all cases. If sendPubKey is present, 223 * sendPubKey - rather than the embedded sender's public key - will be 224 * used for signature validation. 225 */ 226feeReturn decryptCipherFile(feeCipherFile cipherFile, 227 feePubKey recvPrivKey, // required 228 feePubKey sendPubKey, // optional, for signature 229 unsigned char **plainText, // malloc'd & RETURNED 230 unsigned *plainTextLen, // RETURNED 231 feeSigStatus *sigStatus) // RETURNED 232{ 233 cipherFileEncrType encrType = feeCFileEncrType(cipherFile); 234 feeReturn frtn; 235 236 *plainText = NULL; 237 *plainTextLen = 0; 238 239 /* 240 * Dispatch to encrType-specific code. 241 */ 242 switch(encrType) { 243 case CFE_RandDES: 244 frtn = decryptRandDES(cipherFile, 245 recvPrivKey, 246 sendPubKey, 247 plainText, 248 plainTextLen, 249 sigStatus); 250 break; 251 case CFE_PublicDES: 252 frtn = decryptPubDES(cipherFile, 253 recvPrivKey, 254 sendPubKey, 255 plainText, 256 plainTextLen, 257 sigStatus); 258 break; 259 case CFE_FEED: 260 frtn = decryptFEED(cipherFile, 261 recvPrivKey, 262 sendPubKey, 263 plainText, 264 plainTextLen, 265 sigStatus); 266 break; 267 case CFE_FEEDExp: 268 frtn = decryptFEEDExp(cipherFile, 269 recvPrivKey, 270 sendPubKey, 271 plainText, 272 plainTextLen, 273 sigStatus); 274 break; 275 default: 276 frtn = FR_Unimplemented; 277 break; 278 } 279 return frtn; 280} 281