]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/lib/ckutilities.c
Security-59754.80.3.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 }
90
91 /*
92 * Shutdown.
93 */
94 void terminateCryptKit(void)
95 {
96 }
97
98 /*
99 * Create a giant, initialized with specified char[] data.
100 */
101 giant giant_with_data(const unsigned char *d, int len) {
102 int numDigits = BYTES_TO_GIANT_DIGITS(len);
103 giant result;
104
105 result = newGiant(numDigits);
106 deserializeGiant(d, result, len);
107 return result;
108 }
109
110 /*
111 * Obtain a malloc'd memory chunk init'd with specified giant's data.
112 * Resulting bytes are portable. Size of malloc'd memory is always zero
113 * mod GIANT_BYTES_PER_DIGIT.
114 *
115 * Calling this function for a giant obtained by giant_with_data() yields
116 * the original data, with extra byte(s) of leading zeros if the original
117 * was not zero mod GIANT_BYTES_PER_DIGIT.
118 */
119 unsigned char *mem_from_giant(giant g,
120 unsigned *memLen) /* RETURNED size of malloc'd region */
121 {
122 unsigned char *cp;
123 unsigned numDigits = (g->sign < 0) ? -g->sign : g->sign;
124
125 *memLen = numDigits * GIANT_BYTES_PER_DIGIT;
126 cp = (unsigned char*) fmalloc(*memLen);
127 serializeGiant(g, cp, *memLen);
128 return cp;
129 }
130
131 extern const char *feeReturnString(feeReturn frtn)
132 {
133 const frtnItem *fi = frtnStrings;
134
135 while(fi->frtnString) {
136 if(fi->frtn == frtn) {
137 return fi->frtnString;
138 }
139 fi++;
140 }
141 return "Unknown Status";
142 }
143
144 #if FEE_DEBUG
145 void printGiant(const giant x)
146 {
147 int i;
148
149 printf("sign=%d cap=%d n[]=", x->sign, x->capacity);
150 for(i=0; i<abs(x->sign); i++) {
151 printf("%lu:", (unsigned long)x->n[i]);
152 }
153 printf("\n");
154 }
155
156 void printGiantHex(const giant x)
157 {
158 int i;
159
160 printf("sign=%d cap=%d n[]=", x->sign, x->capacity);
161 for(i=0; i<abs(x->sign); i++) {
162 printf("%lx:", (unsigned long)x->n[i]);
163 }
164 printf("\n");
165 }
166
167 /*
168 * Print in the form
169 * sign=8 cap=16 n[]=29787 + 3452 * w^1 + 55260 * w^2 + ...
170 */
171 void printGiantExp(const giant x)
172 {
173 int i;
174 int size = abs(x->sign);
175
176 printf("sign=%d cap=%d n[]=", x->sign, x->capacity);
177 for(i=0; i<size; i++) {
178 printf("%lu ", (unsigned long)x->n[i]);
179 if(i > 0) {
180 printf("* w^%d ", i);
181 }
182 if(i<(size-1)) {
183 printf("+ ");
184 }
185 }
186 printf("\n");
187 }
188
189 void printKey(const key k)
190 {
191 printf(" twist %d\n", k->twist);
192 printf(" x: ");
193 printGiant(k->x);
194 }
195
196 void printCurveParams(const curveParams *p)
197 {
198 const char *pt;
199 const char *ct;
200
201 switch(p->primeType) {
202 case FPT_Mersenne:
203 pt = "FPT_Mersenne";
204 break;
205 case FPT_FEE:
206 pt = "FPT_FEE";
207 break;
208 case FPT_General:
209 pt = "FPT_General";
210 break;
211 default:
212 pt = "UNKNOWN!";
213 break;
214 }
215 switch(p->curveType) {
216 case FCT_Montgomery:
217 ct = "FCT_Montgomery";
218 break;
219 case FCT_Weierstrass:
220 ct = "FCT_Weierstrass";
221 break;
222 case FCT_General:
223 ct = "FCT_General";
224 break;
225 default:
226 ct = "UNKNOWN!";
227 break;
228 }
229 printf(" q %d k %d primeType %s curveType %s\n",
230 p->q, p->k, pt, ct);
231 printf(" minBytes %d maxDigits %d\n", p->minBytes, p->maxDigits);
232 printf(" a : ");
233 printGiant(p->a);
234 printf(" b : ");
235 printGiant(p->b);
236 printf(" c : ");
237 printGiant(p->c);
238 printf(" basePrime : ");
239 printGiant(p->basePrime);
240 printf(" x1Plus : ");
241 printGiant(p->x1Plus);
242 printf(" x1Minus : ");
243 printGiant(p->x1Minus);
244 printf(" cOrderPlus : ");
245 printGiant(p->cOrderPlus);
246 printf(" cOrderMinus : ");
247 printGiant(p->cOrderMinus);
248 printf(" x1OrderPlus : ");
249 printGiant(p->x1OrderPlus);
250 printf(" x1OrderMinus: ");
251 printGiant(p->x1OrderMinus);
252 }
253 #else
254 void printGiant(const giant x) {}
255 void printGiantHex(const giant x) {}
256 void printGiantExp(const giant x) {}
257 void printKey(const key k) {}
258 void printCurveParams(const curveParams *p) {}
259
260 #endif /* FEE_DEBUG */
261
262 /*
263 * serialize, deserialize giants's n[] to/from byte stream.
264 * First byte of byte stream is the MS byte of the resulting giant,
265 * regardless of the size of giantDigit.
266 *
267 * No assumption is made about the alignment of cp.
268 *
269 * As of 7 Apr 1998, these routines are in compliance with IEEE P1363,
270 * section 5.5.1, for the representation of a large integer as a byte
271 * stream.
272 */
273 void serializeGiant(giant g,
274 unsigned char *cp,
275 unsigned numBytes)
276 {
277 unsigned digitDex;
278 unsigned numDigits = BYTES_TO_GIANT_DIGITS(numBytes);
279 giantDigit digit;
280 unsigned char *ptr;
281 unsigned digitByte;
282 int size = abs(g->sign);
283
284 if(numBytes == 0) {
285 return;
286 }
287 if(numBytes > (g->capacity * GIANT_BYTES_PER_DIGIT)) {
288 CKRaise("serializeGiant: CAPACITY EXCEEDED!\n");
289 }
290
291 /*
292 * note we might be asked to write more than the valid number
293 * if bytes in the giant in the case if truncated sign due to
294 * zero M.S. digit(s)....
295 */
296
297 /*
298 * zero out unused digits so we can infer sign during deserialize
299 */
300 for(digitDex=size; digitDex<numDigits; digitDex++) {
301 g->n[digitDex] = 0;
302 }
303
304 /*
305 * Emit bytes starting from l.s. byte. L.s. byte of the outgoing
306 * data stream is *last*. L.s. digit of giant's digits is *first*.
307 */
308 digitDex = 0;
309 ptr = &cp[numBytes - 1];
310 do {
311 /* one loop per giant digit */
312 digit = g->n[digitDex++];
313 for(digitByte=0; digitByte<GIANT_BYTES_PER_DIGIT; digitByte++) {
314 /* one loop per byte in the digit */
315 *ptr-- = (unsigned char)digit;
316 if(--numBytes == 0) {
317 break;
318 }
319 digit >>= 8;
320 }
321 } while(numBytes != 0);
322
323 }
324
325 /*
326 * Resulting sign here is always positive; leading zeroes are reflected
327 * in an altered g->sign.
328 */
329 void deserializeGiant(const unsigned char *cp,
330 giant g,
331 unsigned numBytes)
332 {
333 unsigned numDigits;
334 giantDigit digit;
335 int digitDex;
336 unsigned digitByte;
337 const unsigned char *ptr;
338
339 if(numBytes == 0) {
340 g->sign = 0;
341 return;
342 }
343 numDigits = (numBytes + GIANT_BYTES_PER_DIGIT - 1) /
344 GIANT_BYTES_PER_DIGIT;
345 if(numBytes > (g->capacity * GIANT_BYTES_PER_DIGIT)) {
346 CKRaise("deserializeGiant: CAPACITY EXCEEDED!\n");
347 }
348
349 /*
350 * Start at l.s. byte. That's the end of the cp[] array and
351 * the beginning of the giantDigit array.
352 */
353 digitDex = 0;
354 ptr = &cp[numBytes - 1];
355 do {
356 /* one loop per digit */
357 digit = 0;
358 for(digitByte=0; digitByte<GIANT_BYTES_PER_DIGIT; digitByte++) {
359 /* one loop per byte in the digit */
360 digit |= (*ptr-- << (8 * digitByte));
361 /* FIXME - shouldn't we update g->n before this break? */
362 if(--numBytes == 0) {
363 break;
364 }
365 }
366 g->n[digitDex++] = digit;
367 } while (numBytes != 0);
368
369 /*
370 * Infer sign from non-zero n[] elements
371 */
372 g->sign = numDigits;
373 gtrimSign(g);
374 }
375