]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/lib/ckutilities.c
Security-58286.51.6.tar.gz
[apple/security.git] / OSX / libsecurity_cryptkit / lib / ckutilities.c
1 /* Copyright (c) 1998,2011-2012,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 * ckutilities.c - general C routines
12 *
13 * Revision History
14 * ----------------
15 * 10/06/98 ap
16 * Changed to compile with C++.
17 * 08 Apr 98 at Apple
18 * Mods for variable size giantDigit.
19 * Rewrote serializeGiant(), deserializeGiant() to conform to IEEE P1363.
20 * 23 Mar 98 at Apple
21 * Added FR_WrongSignatureType, FR_BadKeyBlob to frtnStrings.
22 * Added initCryptKit().
23 * 19 Jan 98 at Apple
24 * Added cStringToUc()
25 * 09 Jan 98 at Apple
26 * Added non-FEE_DEBUG version of printGiantHex()
27 * 27 Jan 97 at NeXT
28 * Addd serializeGiant(), deserializeGiant; Deleted data_to_giant()
29 * 12 Dec 96 at NeXT
30 * Added byteRepTo{int,key,giant}().
31 * 2 Aug 96 at NeXT
32 * Broke out from Blaine Garst's original NSCryptors.m
33 */
34
35 #include "ckutilities.h"
36 #include "falloc.h"
37 #include "feeTypes.h"
38 #include "feeDebug.h"
39 #include "feeFunctions.h"
40 #include "byteRep.h"
41 #include "platform.h"
42 #include "curveParams.h"
43 #include <stdlib.h>
44 #ifdef NeXT
45 #include <libc.h>
46 #include <stdio.h>
47 #include <signal.h>
48 #include <sgtty.h>
49 #endif // NeXT
50
51 /*
52 * feeReturn strings.
53 */
54 typedef struct {
55 feeReturn frtn;
56 const char *frtnString;
57 } frtnItem;
58
59 static const frtnItem frtnStrings[] = {
60 #ifndef NDEBUG
61 { FR_Success, "Success" },
62 { FR_BadPubKey, "Bad Public Key" },
63 { FR_BadPubKeyString, "Bad Public Key String" },
64 { FR_IncompatibleKey, "Incompatible key format" },
65 { FR_IllegalDepth, "Illegal Depth" },
66 { FR_BadUsageName, "Bad Usage Name" },
67 { FR_BadSignatureFormat, "Bad Signature Format" },
68 { FR_InvalidSignature, "Invalid Signature" },
69 { FR_IllegalArg, "Illegal Argument" },
70 { FR_BadCipherText, "Bad Ciphertext Format" },
71 { FR_Unimplemented, "Unimplemented Function" },
72 { FR_BadCipherFile, "Bad CipherFile Format" },
73 { FR_BadEnc64, "Bad enc64 Format" },
74 { FR_WrongSignatureType, "Wrong Signature Type" },
75 { FR_BadKeyBlob, "Bad Key Blob" },
76 { FR_IllegalCurve, "Bad curve type" },
77 { FR_Internal, "Internal Library Error" },
78 { FR_Memory, "Out of Memory" },
79 { FR_ShortPrivData, "Insufficient Seed Data" },
80 #endif /* NDEBUG */
81 { (feeReturn) 0, NULL },
82 };
83
84 /*
85 * One-time only init of CryptKit library.
86 */
87 void initCryptKit(void)
88 {
89 #if GIANTS_VIA_STACK
90 curveParamsInitGiants();
91 #endif
92 }
93
94 /*
95 * Shutdown.
96 */
97 void terminateCryptKit(void)
98 {
99 #if GIANTS_VIA_STACK
100 freeGiantStacks();
101 #endif
102 }
103
104 /*
105 * Create a giant, initialized with specified char[] data.
106 */
107 giant giant_with_data(const unsigned char *d, int len) {
108 int numDigits = BYTES_TO_GIANT_DIGITS(len);
109 giant result;
110
111 result = newGiant(numDigits);
112 deserializeGiant(d, result, len);
113 return result;
114 }
115
116 /*
117 * Obtain a malloc'd memory chunk init'd with specified giant's data.
118 * Resulting bytes are portable. Size of malloc'd memory is always zero
119 * mod GIANT_BYTES_PER_DIGIT.
120 *
121 * Calling this function for a giant obtained by giant_with_data() yields
122 * the original data, with extra byte(s) of leading zeros if the original
123 * was not zero mod GIANT_BYTES_PER_DIGIT.
124 */
125 unsigned char *mem_from_giant(giant g,
126 unsigned *memLen) /* RETURNED size of malloc'd region */
127 {
128 unsigned char *cp;
129 unsigned numDigits = (g->sign < 0) ? -g->sign : g->sign;
130
131 *memLen = numDigits * GIANT_BYTES_PER_DIGIT;
132 cp = (unsigned char*) fmalloc(*memLen);
133 serializeGiant(g, cp, *memLen);
134 return cp;
135 }
136
137 extern const char *feeReturnString(feeReturn frtn)
138 {
139 const frtnItem *fi = frtnStrings;
140
141 while(fi->frtnString) {
142 if(fi->frtn == frtn) {
143 return fi->frtnString;
144 }
145 fi++;
146 }
147 return "Unknown Status";
148 }
149
150 #if FEE_DEBUG
151 void printGiant(const giant x)
152 {
153 int i;
154
155 printf("sign=%d cap=%d n[]=", x->sign, x->capacity);
156 for(i=0; i<abs(x->sign); i++) {
157 printf("%lu:", (unsigned long)x->n[i]);
158 }
159 printf("\n");
160 }
161
162 void printGiantHex(const giant x)
163 {
164 int i;
165
166 printf("sign=%d cap=%d n[]=", x->sign, x->capacity);
167 for(i=0; i<abs(x->sign); i++) {
168 printf("%lx:", (unsigned long)x->n[i]);
169 }
170 printf("\n");
171 }
172
173 /*
174 * Print in the form
175 * sign=8 cap=16 n[]=29787 + 3452 * w^1 + 55260 * w^2 + ...
176 */
177 void printGiantExp(const giant x)
178 {
179 int i;
180 int size = abs(x->sign);
181
182 printf("sign=%d cap=%d n[]=", x->sign, x->capacity);
183 for(i=0; i<size; i++) {
184 printf("%lu ", (unsigned long)x->n[i]);
185 if(i > 0) {
186 printf("* w^%d ", i);
187 }
188 if(i<(size-1)) {
189 printf("+ ");
190 }
191 }
192 printf("\n");
193 }
194
195 void printKey(const key k)
196 {
197 printf(" twist %d\n", k->twist);
198 printf(" x: ");
199 printGiant(k->x);
200 }
201
202 void printCurveParams(const curveParams *p)
203 {
204 const char *pt;
205 const char *ct;
206
207 switch(p->primeType) {
208 case FPT_Mersenne:
209 pt = "FPT_Mersenne";
210 break;
211 case FPT_FEE:
212 pt = "FPT_FEE";
213 break;
214 case FPT_General:
215 pt = "FPT_General";
216 break;
217 default:
218 pt = "UNKNOWN!";
219 break;
220 }
221 switch(p->curveType) {
222 case FCT_Montgomery:
223 ct = "FCT_Montgomery";
224 break;
225 case FCT_Weierstrass:
226 ct = "FCT_Weierstrass";
227 break;
228 case FCT_General:
229 ct = "FCT_General";
230 break;
231 default:
232 ct = "UNKNOWN!";
233 break;
234 }
235 printf(" q %d k %d primeType %s curveType %s\n",
236 p->q, p->k, pt, ct);
237 printf(" minBytes %d maxDigits %d\n", p->minBytes, p->maxDigits);
238 printf(" a : ");
239 printGiant(p->a);
240 printf(" b : ");
241 printGiant(p->b);
242 printf(" c : ");
243 printGiant(p->c);
244 printf(" basePrime : ");
245 printGiant(p->basePrime);
246 printf(" x1Plus : ");
247 printGiant(p->x1Plus);
248 printf(" x1Minus : ");
249 printGiant(p->x1Minus);
250 printf(" cOrderPlus : ");
251 printGiant(p->cOrderPlus);
252 printf(" cOrderMinus : ");
253 printGiant(p->cOrderMinus);
254 printf(" x1OrderPlus : ");
255 printGiant(p->x1OrderPlus);
256 printf(" x1OrderMinus: ");
257 printGiant(p->x1OrderMinus);
258 }
259 #else
260 void printGiant(const giant x) {}
261 void printGiantHex(const giant x) {}
262 void printGiantExp(const giant x) {}
263 void printKey(const key k) {}
264 void printCurveParams(const curveParams *p) {}
265
266 #endif /* FEE_DEBUG */
267
268 #if defined(NeXT) && !defined(WIN32)
269
270 void getpassword(const char *prompt, char *pbuf)
271 {
272 struct sgttyb ttyb;
273 int flags;
274 register char *p;
275 register int c;
276 FILE *fi;
277 void (*sig)(int);
278
279 if ((fi = fdopen(open("/dev/tty", 2, 0), "r")) == NULL)
280 fi = stdin;
281 else
282 setbuf(fi, (char *)NULL);
283 sig = signal(SIGINT, SIG_IGN);
284 ioctl(fileno(fi), TIOCGETP, &ttyb);
285 flags = ttyb.sg_flags;
286 ttyb.sg_flags &= ~ECHO;
287 ioctl(fileno(fi), TIOCSETP, &ttyb);
288 fprintf(stderr, "%s", prompt); fflush(stderr);
289 for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
290 if (p < &pbuf[PHRASELEN-1])
291 *p++ = c;
292 }
293 *p = '\0';
294 fprintf(stderr, "\n"); fflush(stderr);
295 ttyb.sg_flags = flags;
296 ioctl(fileno(fi), TIOCSETP, &ttyb);
297 (void)signal(SIGINT, sig);
298 if (fi != stdin)
299 fclose(fi);
300 }
301 #endif // NeXT
302
303 /*
304 * serialize, deserialize giants's n[] to/from byte stream.
305 * First byte of byte stream is the MS byte of the resulting giant,
306 * regardless of the size of giantDigit.
307 *
308 * No assumption is made about the alignment of cp.
309 *
310 * As of 7 Apr 1998, these routines are in compliance with IEEE P1363,
311 * section 5.5.1, for the representation of a large integer as a byte
312 * stream.
313 */
314 void serializeGiant(giant g,
315 unsigned char *cp,
316 unsigned numBytes)
317 {
318 unsigned digitDex;
319 unsigned numDigits = BYTES_TO_GIANT_DIGITS(numBytes);
320 giantDigit digit;
321 unsigned char *ptr;
322 unsigned digitByte;
323 int size = abs(g->sign);
324
325 if(numBytes == 0) {
326 return;
327 }
328 if(numBytes > (g->capacity * GIANT_BYTES_PER_DIGIT)) {
329 CKRaise("serializeGiant: CAPACITY EXCEEDED!\n");
330 }
331
332 /*
333 * note we might be asked to write more than the valid number
334 * if bytes in the giant in the case if truncated sign due to
335 * zero M.S. digit(s)....
336 */
337
338 /*
339 * zero out unused digits so we can infer sign during deserialize
340 */
341 for(digitDex=size; digitDex<numDigits; digitDex++) {
342 g->n[digitDex] = 0;
343 }
344
345 /*
346 * Emit bytes starting from l.s. byte. L.s. byte of the outgoing
347 * data stream is *last*. L.s. digit of giant's digits is *first*.
348 */
349 digitDex = 0;
350 ptr = &cp[numBytes - 1];
351 do {
352 /* one loop per giant digit */
353 digit = g->n[digitDex++];
354 for(digitByte=0; digitByte<GIANT_BYTES_PER_DIGIT; digitByte++) {
355 /* one loop per byte in the digit */
356 *ptr-- = (unsigned char)digit;
357 if(--numBytes == 0) {
358 break;
359 }
360 digit >>= 8;
361 }
362 } while(numBytes != 0);
363
364 }
365
366 /*
367 * Resulting sign here is always positive; leading zeroes are reflected
368 * in an altered g->sign.
369 */
370 void deserializeGiant(const unsigned char *cp,
371 giant g,
372 unsigned numBytes)
373 {
374 unsigned numDigits;
375 giantDigit digit;
376 int digitDex;
377 unsigned digitByte;
378 const unsigned char *ptr;
379
380 if(numBytes == 0) {
381 g->sign = 0;
382 return;
383 }
384 numDigits = (numBytes + GIANT_BYTES_PER_DIGIT - 1) /
385 GIANT_BYTES_PER_DIGIT;
386 if(numBytes > (g->capacity * GIANT_BYTES_PER_DIGIT)) {
387 CKRaise("deserializeGiant: CAPACITY EXCEEDED!\n");
388 }
389
390 /*
391 * Start at l.s. byte. That's the end of the cp[] array and
392 * the beginning of the giantDigit array.
393 */
394 digitDex = 0;
395 ptr = &cp[numBytes - 1];
396 do {
397 /* one loop per digit */
398 digit = 0;
399 for(digitByte=0; digitByte<GIANT_BYTES_PER_DIGIT; digitByte++) {
400 /* one loop per byte in the digit */
401 digit |= (*ptr-- << (8 * digitByte));
402 /* FIXME - shouldn't we update g->n before this break? */
403 if(--numBytes == 0) {
404 break;
405 }
406 }
407 g->n[digitDex++] = digit;
408 } while (numBytes != 0);
409
410 /*
411 * Infer sign from non-zero n[] elements
412 */
413 g->sign = numDigits;
414 gtrimSign(g);
415 }
416