]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/lib/ckutilities.c
1 /* Copyright (c) 1998,2011-2012,2014 Apple Inc. All Rights Reserved.
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 ***************************************************************************
11 * ckutilities.c - general C routines
16 * Changed to compile with C++.
18 * Mods for variable size giantDigit.
19 * Rewrote serializeGiant(), deserializeGiant() to conform to IEEE P1363.
21 * Added FR_WrongSignatureType, FR_BadKeyBlob to frtnStrings.
22 * Added initCryptKit().
26 * Added non-FEE_DEBUG version of printGiantHex()
28 * Addd serializeGiant(), deserializeGiant; Deleted data_to_giant()
30 * Added byteRepTo{int,key,giant}().
32 * Broke out from Blaine Garst's original NSCryptors.m
35 #include "ckutilities.h"
39 #include "feeFunctions.h"
42 #include "curveParams.h"
56 const char *frtnString
;
59 static const frtnItem frtnStrings
[] = {
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" },
81 { (feeReturn
) 0, NULL
},
85 * One-time only init of CryptKit library.
87 void initCryptKit(void)
90 curveParamsInitGiants();
97 void terminateCryptKit(void)
105 * Create a giant, initialized with specified char[] data.
107 giant
giant_with_data(const unsigned char *d
, int len
) {
108 int numDigits
= BYTES_TO_GIANT_DIGITS(len
);
111 result
= newGiant(numDigits
);
112 deserializeGiant(d
, result
, len
);
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.
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.
125 unsigned char *mem_from_giant(giant g
,
126 unsigned *memLen
) /* RETURNED size of malloc'd region */
129 unsigned numDigits
= (g
->sign
< 0) ? -g
->sign
: g
->sign
;
131 *memLen
= numDigits
* GIANT_BYTES_PER_DIGIT
;
132 cp
= (unsigned char*) fmalloc(*memLen
);
133 serializeGiant(g
, cp
, *memLen
);
137 extern const char *feeReturnString(feeReturn frtn
)
139 const frtnItem
*fi
= frtnStrings
;
141 while(fi
->frtnString
) {
142 if(fi
->frtn
== frtn
) {
143 return fi
->frtnString
;
147 return "Unknown Status";
151 void printGiant(const giant x
)
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
]);
162 void printGiantHex(const giant x
)
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
]);
175 * sign=8 cap=16 n[]=29787 + 3452 * w^1 + 55260 * w^2 + ...
177 void printGiantExp(const giant x
)
180 int size
= abs(x
->sign
);
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
]);
186 printf("* w^%d ", i
);
195 void printKey(const key k
)
197 printf(" twist %d\n", k
->twist
);
202 void printCurveParams(const curveParams
*p
)
207 switch(p
->primeType
) {
221 switch(p
->curveType
) {
223 ct
= "FCT_Montgomery";
225 case FCT_Weierstrass
:
226 ct
= "FCT_Weierstrass";
235 printf(" q %d k %d primeType %s curveType %s\n",
237 printf(" minBytes %d maxDigits %d\n", p
->minBytes
, p
->maxDigits
);
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
);
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
) {}
266 #endif /* FEE_DEBUG */
268 #if defined(NeXT) && !defined(WIN32)
270 void getpassword(const char *prompt
, char *pbuf
)
279 if ((fi
= fdopen(open("/dev/tty", 2, 0), "r")) == NULL
)
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])
294 fprintf(stderr
, "\n"); fflush(stderr
);
295 ttyb
.sg_flags
= flags
;
296 ioctl(fileno(fi
), TIOCSETP
, &ttyb
);
297 (void)signal(SIGINT
, sig
);
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.
308 * No assumption is made about the alignment of cp.
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
314 void serializeGiant(giant g
,
319 unsigned numDigits
= BYTES_TO_GIANT_DIGITS(numBytes
);
323 int size
= abs(g
->sign
);
328 if(numBytes
> (g
->capacity
* GIANT_BYTES_PER_DIGIT
)) {
329 CKRaise("serializeGiant: CAPACITY EXCEEDED!\n");
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)....
339 * zero out unused digits so we can infer sign during deserialize
341 for(digitDex
=size
; digitDex
<numDigits
; digitDex
++) {
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*.
350 ptr
= &cp
[numBytes
- 1];
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) {
362 } while(numBytes
!= 0);
367 * Resulting sign here is always positive; leading zeroes are reflected
368 * in an altered g->sign.
370 void deserializeGiant(const unsigned char *cp
,
378 const unsigned char *ptr
;
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");
391 * Start at l.s. byte. That's the end of the cp[] array and
392 * the beginning of the giantDigit array.
395 ptr
= &cp
[numBytes
- 1];
397 /* one loop per digit */
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) {
407 g
->n
[digitDex
++] = digit
;
408 } while (numBytes
!= 0);
411 * Infer sign from non-zero n[] elements