]>
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)
94 void terminateCryptKit(void)
99 * Create a giant, initialized with specified char[] data.
101 giant
giant_with_data(const unsigned char *d
, int len
) {
102 int numDigits
= BYTES_TO_GIANT_DIGITS(len
);
105 result
= newGiant(numDigits
);
106 deserializeGiant(d
, result
, len
);
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.
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.
119 unsigned char *mem_from_giant(giant g
,
120 unsigned *memLen
) /* RETURNED size of malloc'd region */
123 unsigned numDigits
= (g
->sign
< 0) ? -g
->sign
: g
->sign
;
125 *memLen
= numDigits
* GIANT_BYTES_PER_DIGIT
;
126 cp
= (unsigned char*) fmalloc(*memLen
);
127 serializeGiant(g
, cp
, *memLen
);
131 extern const char *feeReturnString(feeReturn frtn
)
133 const frtnItem
*fi
= frtnStrings
;
135 while(fi
->frtnString
) {
136 if(fi
->frtn
== frtn
) {
137 return fi
->frtnString
;
141 return "Unknown Status";
145 void printGiant(const giant x
)
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
]);
156 void printGiantHex(const giant x
)
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
]);
169 * sign=8 cap=16 n[]=29787 + 3452 * w^1 + 55260 * w^2 + ...
171 void printGiantExp(const giant x
)
174 int size
= abs(x
->sign
);
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
]);
180 printf("* w^%d ", i
);
189 void printKey(const key k
)
191 printf(" twist %d\n", k
->twist
);
196 void printCurveParams(const curveParams
*p
)
201 switch(p
->primeType
) {
215 switch(p
->curveType
) {
217 ct
= "FCT_Montgomery";
219 case FCT_Weierstrass
:
220 ct
= "FCT_Weierstrass";
229 printf(" q %d k %d primeType %s curveType %s\n",
231 printf(" minBytes %d maxDigits %d\n", p
->minBytes
, p
->maxDigits
);
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
);
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
) {}
260 #endif /* FEE_DEBUG */
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.
267 * No assumption is made about the alignment of cp.
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
273 void serializeGiant(giant g
,
278 unsigned numDigits
= BYTES_TO_GIANT_DIGITS(numBytes
);
282 int size
= abs(g
->sign
);
287 if(numBytes
> (g
->capacity
* GIANT_BYTES_PER_DIGIT
)) {
288 CKRaise("serializeGiant: CAPACITY EXCEEDED!\n");
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)....
298 * zero out unused digits so we can infer sign during deserialize
300 for(digitDex
=size
; digitDex
<numDigits
; digitDex
++) {
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*.
309 ptr
= &cp
[numBytes
- 1];
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) {
321 } while(numBytes
!= 0);
326 * Resulting sign here is always positive; leading zeroes are reflected
327 * in an altered g->sign.
329 void deserializeGiant(const unsigned char *cp
,
337 const unsigned char *ptr
;
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");
350 * Start at l.s. byte. That's the end of the cp[] array and
351 * the beginning of the giantDigit array.
354 ptr
= &cp
[numBytes
- 1];
356 /* one loop per digit */
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) {
366 g
->n
[digitDex
++] = digit
;
367 } while (numBytes
!= 0);
370 * Infer sign from non-zero n[] elements