]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/lib/CipherFileFEED.c
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / libsecurity_cryptkit / lib / CipherFileFEED.c
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 * CipherFileFEED.c - FEED and FEEDExp related cipherfile support
12 *
13 * Revision History
14 * ----------------
15 * 24 Jun 97 at Apple
16 * Fixed memory leaks via sigData
17 * 18 Feb 97 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
30 feeReturn 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
115 out:
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
135 feeReturn 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 }
226 out:
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
245 feeReturn 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
333 out:
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
353 feeReturn 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 }
441 out:
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 */