1/* Copyright (c) 1998 Apple Computer, 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 COMPUTER, INC. AND THE 6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER, 7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL 8 * EXPOSE YOU TO LIABILITY. 9 *************************************************************************** 10 * 11 * CipherFileFEED.c - FEED and FEEDExp related cipherfile support 12 * 13 * Revision History 14 * ---------------- 15 * 24 Jun 97 Doug Mitchell at Apple 16 * Fixed memory leaks via sigData 17 * 18 Feb 97 Doug Mitchell at Apple 18 * Split off from feeCipherFile.c 19 */ 20 21#include "ckconfig.h" 22 23#if CRYPTKIT_CIPHERFILE_ENABLE 24 25#include "Crypt.h" 26#include "CipherFileFEED.h" 27#include "falloc.h" 28#include "feeDebug.h" 29 30feeReturn createFEED(feePubKey sendPrivKey, // required 31 feePubKey recvPubKey, 32 const unsigned char *plainText, 33 unsigned plainTextLen, 34 int genSig, // 1 ==> generate signature 35 unsigned userData, // for caller's convenience 36 feeCipherFile *cipherFile) // RETURNED if successful 37{ 38 feeReturn frtn; 39 feeFEED feed = NULL; 40 unsigned char *cipherText = NULL; 41 unsigned cipherTextLen; 42 unsigned char *sigData = NULL; 43 unsigned sigDataLen = 0; 44 feeCipherFile cfile = NULL; 45 unsigned char *pubKeyString = NULL; // of sendPrivKey 46 unsigned pubKeyStringLen = 0; 47 48 if((sendPrivKey == NULL) || (recvPubKey == NULL)) { 49 return FR_BadPubKey; 50 } 51 52 /* 53 * FEED encrypt plaintext 54 */ 55 feed = feeFEEDNewWithPubKey(sendPrivKey, recvPubKey, FF_ENCRYPT, NULL, NULL); 56 if(feed == NULL) { 57 frtn = FR_BadPubKey; 58 goto out; 59 } 60 frtn = feeFEEDEncrypt(feed, 61 plainText, 62 plainTextLen, 63 &cipherText, 64 &cipherTextLen); 65 if(frtn) { 66 goto out; 67 } 68 69 /* 70 * Sender's public key string 71 */ 72 frtn = feePubKeyCreateKeyString(sendPrivKey, 73 (char **)&pubKeyString, 74 &pubKeyStringLen); 75 if(frtn) { 76 /* 77 * Huh? 78 */ 79 frtn = FR_BadPubKey; 80 goto out; 81 } 82 83 if(genSig) { 84 /* 85 * We generate signature on ciphertext by convention. 86 */ 87 frtn = feePubKeyCreateSignature(sendPrivKey, 88 cipherText, 89 cipherTextLen, 90 &sigData, 91 &sigDataLen); 92 if(frtn) { 93 goto out; 94 } 95 } 96 97 /* 98 * Cons up a cipherfile 99 */ 100 cfile = feeCFileNewFromCipherText(CFE_FEED, 101 cipherText, 102 cipherTextLen, 103 pubKeyString, 104 pubKeyStringLen, 105 NULL, 106 0, 107 sigData, 108 sigDataLen, 109 userData); 110 if(cfile == NULL) { 111 frtn = FR_Internal; 112 goto out; 113 } 114 115out: 116 /* free alloc'd stuff */ 117 118 if(cipherText) { 119 ffree(cipherText); 120 } 121 if(feed) { 122 feeFEEDFree(feed); 123 } 124 if(pubKeyString) { 125 ffree(pubKeyString); 126 } 127 if(sigData) { 128 ffree(sigData); 129 } 130 *cipherFile = cfile; 131 return frtn; 132 133} 134 135feeReturn decryptFEED(feeCipherFile cipherFile, 136 feePubKey recvPrivKey, 137 feePubKey sendPubKey, // optional 138 unsigned char **plainText, // RETURNED 139 unsigned *plainTextLen, // RETURNED 140 feeSigStatus *sigStatus) // RETURNED 141{ 142 feeReturn frtn = FR_Success; 143 unsigned char *cipherText = NULL; 144 unsigned cipherTextLen; 145 feeFEED feed = NULL; 146 unsigned char *sigData = NULL; 147 unsigned sigDataLen; 148 unsigned char *sendPubKeyStr = NULL; 149 unsigned sendPubKeyStrLen = 0; 150 feePubKey parsedSendPubKey = NULL; 151 152 if(feeCFileEncrType(cipherFile) != CFE_FEED) { 153 frtn = FR_Internal; 154 goto out; 155 } 156//printf("decryptFEED\n"); 157//printf("privKey:\n"); printPubKey(recvPrivKey); 158//printf("pubKey:\n"); printPubKey(sendPubKey); 159 /* 160 * Get ciphertext and sender's public key from cipherFile 161 */ 162 cipherText = feeCFileCipherText(cipherFile, &cipherTextLen); 163 if(cipherText == NULL) { 164 frtn = FR_BadCipherFile; 165 goto out; 166 } 167 sendPubKeyStr = feeCFileSendPubKeyData(cipherFile, &sendPubKeyStrLen); 168 if(sendPubKeyStr == NULL) { 169 frtn = FR_BadCipherFile; 170 goto out; 171 } 172 parsedSendPubKey = feePubKeyAlloc(); 173 frtn = feePubKeyInitFromKeyString(parsedSendPubKey, 174 (char *)sendPubKeyStr, 175 sendPubKeyStrLen); 176 if(frtn) { 177 frtn = FR_BadCipherFile; 178 goto out; 179 } 180//printf("parsedSendPubKey:\n"); printPubKey(parsedSendPubKey); 181 182 /* 183 * FEED decrypt 184 */ 185 feed = feeFEEDNewWithPubKey(recvPrivKey, parsedSendPubKey, FF_DECRYPT, NULL, NULL); 186 if(feed == NULL) { 187 frtn = FR_BadPubKey; 188 goto out; 189 } 190 frtn = feeFEEDDecrypt(feed, 191 cipherText, 192 cipherTextLen, 193 plainText, 194 plainTextLen); 195 if(frtn) { 196 goto out; 197 } 198 199 sigData = feeCFileSigData(cipherFile, &sigDataLen); 200 if(sigData) { 201 feeReturn sigFrtn; 202 203 if(sendPubKey == NULL) { 204 /* 205 * use embedded sender's public key 206 */ 207 sendPubKey = parsedSendPubKey; 208 } 209 sigFrtn = feePubKeyVerifySignature(sendPubKey, 210 cipherText, 211 cipherTextLen, 212 sigData, 213 sigDataLen); 214 switch(sigFrtn) { 215 case FR_Success: 216 *sigStatus = SS_PresentValid; 217 break; 218 default: 219 *sigStatus = SS_PresentInvalid; 220 break; 221 } 222 } 223 else { 224 *sigStatus = SS_NotPresent; 225 } 226out: 227 if(cipherText) { 228 ffree(cipherText); 229 } 230 if(feed) { 231 feeFEEDFree(feed); 232 } 233 if(sigData) { 234 ffree(sigData); 235 } 236 if(parsedSendPubKey) { 237 feePubKeyFree(parsedSendPubKey); 238 } 239 if(sendPubKeyStr) { 240 ffree(sendPubKeyStr); 241 } 242 return frtn; 243} 244 245feeReturn createFEEDExp(feePubKey sendPrivKey, // for sig only 246 feePubKey recvPubKey, 247 const unsigned char *plainText, 248 unsigned plainTextLen, 249 int genSig, // 1 ==> generate signature 250 unsigned userData, // for caller's convenience 251 feeCipherFile *cipherFile) // RETURNED if successful 252{ 253 feeReturn frtn; 254 feeFEEDExp feed = NULL; 255 unsigned char *cipherText = NULL; 256 unsigned cipherTextLen; 257 unsigned char *sigData = NULL; 258 unsigned sigDataLen = 0; 259 feeCipherFile cfile = NULL; 260 unsigned char *pubKeyString = NULL; // of sendPrivKey, for sig 261 unsigned pubKeyStringLen = 0; 262 263 if(recvPubKey == NULL) { 264 return FR_BadPubKey; 265 } 266 267 /* 268 * FEEDExp encrypt plaintext 269 */ 270 feed = feeFEEDExpNewWithPubKey(recvPubKey, NULL, NULL); 271 if(feed == NULL) { 272 frtn = FR_BadPubKey; 273 goto out; 274 } 275 frtn = feeFEEDExpEncrypt(feed, 276 plainText, 277 plainTextLen, 278 &cipherText, 279 &cipherTextLen); 280 if(frtn) { 281 goto out; 282 } 283 284 if(genSig) { 285 if(sendPrivKey == NULL) { 286 frtn = FR_IllegalArg; 287 goto out; 288 } 289 /* 290 * We generate signature on ciphertext by convention. 291 */ 292 frtn = feePubKeyCreateSignature(sendPrivKey, 293 cipherText, 294 cipherTextLen, 295 &sigData, 296 &sigDataLen); 297 if(frtn) { 298 goto out; 299 } 300 /* 301 * Sender's public key string 302 */ 303 frtn = feePubKeyCreateKeyString(sendPrivKey, 304 (char **)&pubKeyString, 305 &pubKeyStringLen); 306 if(frtn) { 307 /* 308 * Huh? 309 */ 310 frtn = FR_BadPubKey; 311 goto out; 312 } 313 } 314 315 /* 316 * Cons up a cipherfile 317 */ 318 cfile = feeCFileNewFromCipherText(CFE_FEEDExp, 319 cipherText, 320 cipherTextLen, 321 pubKeyString, 322 pubKeyStringLen, 323 NULL, 324 0, 325 sigData, 326 sigDataLen, 327 userData); 328 if(cfile == NULL) { 329 frtn = FR_Internal; 330 goto out; 331 } 332 333out: 334 /* free alloc'd stuff */ 335 336 if(cipherText) { 337 ffree(cipherText); 338 } 339 if(feed) { 340 feeFEEDExpFree(feed); 341 } 342 if(sigData) { 343 ffree(sigData); 344 } 345 if(pubKeyString) { 346 ffree(pubKeyString); 347 } 348 *cipherFile = cfile; 349 return frtn; 350 351} 352 353feeReturn decryptFEEDExp(feeCipherFile cipherFile, 354 feePubKey recvPrivKey, 355 feePubKey sendPubKey, // optional 356 unsigned char **plainText, // RETURNED 357 unsigned *plainTextLen, // RETURNED 358 feeSigStatus *sigStatus) // RETURNED 359{ 360 feeReturn frtn = FR_Success; 361 unsigned char *cipherText = NULL; 362 unsigned cipherTextLen; 363 feeFEEDExp feed = NULL; 364 unsigned char *sigData = NULL; 365 unsigned sigDataLen; 366 unsigned char *sendPubKeyStr = NULL; 367 unsigned sendPubKeyStrLen = 0; 368 feePubKey parsedSendPubKey = NULL; 369 370 if(feeCFileEncrType(cipherFile) != CFE_FEEDExp) { 371 frtn = FR_Internal; 372 goto out; 373 } 374 375 /* 376 * Get ciphertext from cipherFile 377 */ 378 cipherText = feeCFileCipherText(cipherFile, &cipherTextLen); 379 if(cipherText == NULL) { 380 frtn = FR_BadCipherFile; 381 goto out; 382 } 383 384 /* 385 * FEEDExp decrypt 386 */ 387 feed = feeFEEDExpNewWithPubKey(recvPrivKey, NULL, NULL); 388 if(feed == NULL) { 389 frtn = FR_BadPubKey; 390 goto out; 391 } 392 frtn = feeFEEDExpDecrypt(feed, 393 cipherText, 394 cipherTextLen, 395 plainText, 396 plainTextLen); 397 if(frtn) { 398 goto out; 399 } 400 401 sigData = feeCFileSigData(cipherFile, &sigDataLen); 402 if(sigData) { 403 feeReturn sigFrtn; 404 405 if(sendPubKey == NULL) { 406 /* 407 * use embedded sender's public key 408 */ 409 sendPubKeyStr = feeCFileSendPubKeyData(cipherFile, 410 &sendPubKeyStrLen); 411 if(sendPubKeyStr == NULL) { 412 frtn = FR_BadCipherFile; 413 goto out; 414 } 415 parsedSendPubKey = feePubKeyAlloc(); 416 frtn = feePubKeyInitFromKeyString(parsedSendPubKey, 417 (char *)sendPubKeyStr, sendPubKeyStrLen); 418 if(frtn) { 419 frtn = FR_BadCipherFile; 420 goto out; 421 } 422 sendPubKey = parsedSendPubKey; 423 } 424 sigFrtn = feePubKeyVerifySignature(sendPubKey, 425 cipherText, 426 cipherTextLen, 427 sigData, 428 sigDataLen); 429 switch(sigFrtn) { 430 case FR_Success: 431 *sigStatus = SS_PresentValid; 432 break; 433 default: 434 *sigStatus = SS_PresentInvalid; 435 break; 436 } 437 } 438 else { 439 *sigStatus = SS_NotPresent; 440 } 441out: 442 if(cipherText) { 443 ffree(cipherText); 444 } 445 if(feed) { 446 feeFEEDExpFree(feed); 447 } 448 if(sigData) { 449 ffree(sigData); 450 } 451 if(parsedSendPubKey) { 452 feePubKeyFree(parsedSendPubKey); 453 } 454 if(sendPubKeyStr) { 455 ffree(sendPubKeyStr); 456 } 457 return frtn; 458} 459 460#endif /* CRYPTKIT_CIPHERFILE_ENABLE */ 461