]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/lib/byteRep.c
1 /* Copyright (c) 1998,2011,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 * byteRep.c - FEE portable byte representation support
16 * Changed to compile with C++.
18 * Mods for variable size giantDigit.
20 * Added curve param fields for CURVE_PARAM_VERSION 2.
22 * Added signature routines.
24 * Split off from utilities.c
29 #include "curveParams.h"
30 #include "giantIntegers.h"
33 #include "ckutilities.h"
38 #define NULL ((void *)0)
42 * Support for portable bytestream representation of keys and signatures.
43 * Platform and endianness independent; format shared with JavaFEE
50 #define ENC_BYTE(n, b, bytes) \
54 #define ENC_INT(n, b, bytes, i) \
55 i = intToByteRep(n, b); \
59 #define ENC_GIANT(g, b, bytes, i) \
60 i = giantToByteRep(g, b); \
64 #define DEC_BYTE(n, b, blen, bytes) \
69 #define DEC_INT(n, b, blen, bytes) \
70 n = byteRepToInt(b); \
72 bytes += sizeof(int); \
75 #define DEC_GIANT(g, b, blen, glen, bytes, out) \
76 g = byteRepToGiant(b, blen, &glen); \
88 * The routines which convert various types to byte reps return the number
89 * of bytes written to the output stream.
91 int intToByteRep(int i
, unsigned char *buf
)
93 *buf
++ = (unsigned char)((i
>> 24) & 0xff);
94 *buf
++ = (unsigned char)((i
>> 16) & 0xff);
95 *buf
++ = (unsigned char)((i
>> 8) & 0xff);
96 *buf
= (unsigned char)(i
& 0xff);
100 int shortToByteRep(short s
, unsigned char *buf
)
102 *buf
++ = (unsigned char)((s
>> 8) & 0xff);
103 *buf
= (unsigned char)(s
& 0xff);
108 * 7 Apr 1998 : leading int is now the number of bytes in the giant's
109 * giantDigits array. This value is signed.
111 int giantToByteRep(giant g
, unsigned char *buf
)
113 int numBytes
= g
->sign
* GIANT_BYTES_PER_DIGIT
;
114 unsigned aNumBytes
= abs(numBytes
);
117 intToByteRep(numBytes
, buf
);
119 serializeGiant(g
, buf
, aNumBytes
);
120 return (sizeof(int) + aNumBytes
);
123 int keyToByteRep(key k
, unsigned char *buf
)
129 ENC_GIANT(k
->x
, buf
, numBytes
, i
);
131 /* only write y for plus curve */
132 if(k
->twist
== CURVE_PLUS
) {
133 CKASSERT(k
->y
!= NULL
);
134 ENC_GIANT(k
->y
, buf
, numBytes
, i
);
139 #define CURVE_PARAM_VERSION 3
140 #define CURVE_PARAM_VERSION_MIN 3
142 int curveParamsToByteRep(curveParams
*cp
, unsigned char *buf
)
147 CKASSERT(cp
!= NULL
);
148 ENC_INT(CURVE_PARAM_VERSION
, buf
, numBytes
, i
);
149 ENC_INT(CURVE_PARAM_VERSION_MIN
, buf
, numBytes
, i
);
150 ENC_BYTE(cp
->primeType
, buf
, numBytes
);
151 ENC_BYTE(cp
->curveType
, buf
, numBytes
);
152 ENC_INT(cp
->q
, buf
, numBytes
, i
);
153 ENC_INT(cp
->k
, buf
, numBytes
, i
);
154 ENC_INT(cp
->m
, buf
, numBytes
, i
);
155 ENC_INT(0, buf
, numBytes
, i
); // spare
157 ENC_GIANT(cp
->a
, buf
, numBytes
, i
);
158 ENC_GIANT(cp
->b
, buf
, numBytes
, i
);
159 ENC_GIANT(cp
->c
, buf
, numBytes
, i
);
160 ENC_GIANT(cp
->x1Plus
, buf
, numBytes
, i
);
161 ENC_GIANT(cp
->x1Minus
, buf
, numBytes
, i
);
162 ENC_GIANT(cp
->cOrderPlus
, buf
, numBytes
, i
);
163 ENC_GIANT(cp
->cOrderMinus
, buf
, numBytes
, i
);
164 ENC_GIANT(cp
->x1OrderPlus
, buf
, numBytes
, i
);
165 ENC_GIANT(cp
->x1OrderMinus
, buf
, numBytes
, i
);
166 if(cp
->primeType
== FPT_General
) {
167 ENC_GIANT(cp
->basePrime
, buf
, numBytes
, i
);
172 int sigToByteRep(int magic
,
182 ENC_INT(magic
, buf
, numBytes
, i
);
183 ENC_INT(version
, buf
, numBytes
, i
);
184 ENC_INT(minVersion
, buf
, numBytes
, i
);
185 ENC_INT(0, buf
, numBytes
, i
); // spare
186 ENC_GIANT(g0
, buf
, numBytes
, i
);
187 ENC_GIANT(g1
, buf
, numBytes
, i
);
194 * return the size of various data types' byte representations.
196 int lengthOfByteRepGiant(giant g
)
199 return sizeof(int) + (GIANT_BYTES_PER_DIGIT
* abs(g
->sign
));
202 int lengthOfByteRepKey(key k
)
204 int len
= lengthOfByteRepGiant(k
->x
);
207 if(k
->twist
== CURVE_PLUS
) {
208 CKASSERT(k
->y
!= NULL
);
209 len
+= lengthOfByteRepGiant(k
->y
);
214 int lengthOfByteRepCurveParams(curveParams
*cp
)
218 CKASSERT(cp
!= NULL
);
219 length
= (6 * sizeof(int)) + // ver, minVers, q, k, m, spare
220 2 + // primeType + curveType
221 lengthOfByteRepGiant(cp
->a
) +
222 lengthOfByteRepGiant(cp
->b
) +
223 lengthOfByteRepGiant(cp
->c
) +
224 lengthOfByteRepGiant(cp
->x1Plus
) +
225 lengthOfByteRepGiant(cp
->x1Minus
) +
226 lengthOfByteRepGiant(cp
->cOrderPlus
) +
227 lengthOfByteRepGiant(cp
->cOrderMinus
) +
228 lengthOfByteRepGiant(cp
->x1OrderPlus
) +
229 lengthOfByteRepGiant(cp
->x1OrderMinus
);
230 if(cp
->primeType
== FPT_General
) {
231 length
+= lengthOfByteRepGiant(cp
->basePrime
);
236 int lengthOfByteRepSig(giant g0
,
239 int length
= (4 * sizeof(int)) + // magic, version, minVersion,
241 lengthOfByteRepGiant(g0
) +
242 lengthOfByteRepGiant(g1
);
247 * Routine to cons up various types from a byte rep stream.
249 int byteRepToInt(const unsigned char *buf
) {
252 result
= (((int)buf
[0] << 24) & 0xff000000) |
253 (((int)buf
[1] << 16) & 0x00ff0000) |
254 (((int)buf
[2] << 8) & 0xff00) |
255 (((int)buf
[3]) & 0xff);
259 unsigned short byteRepToShort(const unsigned char *buf
) {
260 unsigned short result
;
262 result
= (((unsigned short)buf
[0] << 8) & 0xff00) |
263 (((unsigned short)buf
[1]) & 0xff);
268 * Probably need byteRepToShortArray...
272 * byte rep stream to giant. Returns NULL on error; returns number of bytes
273 * of *buf snarfed in *giantLen if successful.
275 * 7 Apr 1998 : leading int is now the number of bytes in the giant's
276 * giantDigits array. This value is signed.
278 giant
byteRepToGiant(const unsigned char *buf
,
284 int numBytes
; // signed!
287 if(bufLen
< sizeof(int)) {
290 numBytes
= byteRepToInt(buf
);
291 aNumBytes
= abs(numBytes
);
292 numDigits
= BYTES_TO_GIANT_DIGITS(aNumBytes
);
294 bufLen
-= sizeof(int);
295 if(numDigits
> MAX_DIGITS
) {
299 if(bufLen
< aNumBytes
) {
303 /* 9 Apr 1998 - sign = 0 means no following n[] bytes in the
304 * byteRep. We do need to alloc one digit, in this case, though...
305 * Note that the giantstruct has one implicit digit in n[].
308 g
= (giant
)fmalloc(sizeof(giantstruct
));
312 g
= (giant
)fmalloc(sizeof(giantstruct
) +
313 aNumBytes
- GIANT_BYTES_PER_DIGIT
);
314 g
->capacity
= numDigits
;
316 deserializeGiant(buf
, g
, aNumBytes
);
318 /* deserializeGiant always cooks up positive giant; sign is
319 * properly trimmed to handle trailing (M.S.) zeroes. */
323 *giantLen
= sizeof(int) + aNumBytes
;
329 * Convert a byte stream (and some other parameters) into a
331 * Returns NULL on error; returns number of bytes of *buf snarfed in
332 * *keyLen if successful.
334 key
byteRepToKey(const unsigned char *buf
,
338 unsigned *keyLen
) // returned
346 x
= byteRepToGiant(buf
, bufLen
, &gLen
);
353 if(twist
== CURVE_PLUS
) {
354 /* this also contains y */
355 y
= byteRepToGiant(buf
, bufLen
, &gLen
);
363 /* minus curve, y is not used */
367 k
= (key
)fmalloc(sizeof(keystruct
));
376 curveParams
*byteRepToCurveParams(const unsigned char *buf
,
387 if(bufLen
< (5 * sizeof(int))) { // ver, minVers, q, k, spare
390 cp
= newCurveParams();
392 DEC_INT(version
, buf
, bufLen
, bytes
);
393 DEC_INT(minVersion
, buf
, bufLen
, bytes
);
394 if(minVersion
> CURVE_PARAM_VERSION
) {
396 * Can't parse this; things have changed too much between
397 * this version of the code and the time this curveParams
403 DEC_BYTE(cp
->primeType
, buf
, bufLen
, bytes
);
404 DEC_BYTE(cp
->curveType
, buf
, bufLen
, bytes
);
405 DEC_INT(cp
->q
, buf
, bufLen
, bytes
);
406 DEC_INT(cp
->k
, buf
, bufLen
, bytes
);
407 DEC_INT(cp
->m
, buf
, bufLen
, bytes
);
408 DEC_INT(spare
, buf
, bufLen
, bytes
);
410 DEC_GIANT(cp
->a
, buf
, bufLen
, gLen
, bytes
, abort
);
411 DEC_GIANT(cp
->b
, buf
, bufLen
, gLen
, bytes
, abort
);
412 DEC_GIANT(cp
->c
, buf
, bufLen
, gLen
, bytes
, abort
);
413 DEC_GIANT(cp
->x1Plus
, buf
, bufLen
, gLen
, bytes
, abort
);
414 DEC_GIANT(cp
->x1Minus
, buf
, bufLen
, gLen
, bytes
, abort
);
415 DEC_GIANT(cp
->cOrderPlus
, buf
, bufLen
, gLen
, bytes
, abort
);
416 DEC_GIANT(cp
->cOrderMinus
, buf
, bufLen
, gLen
, bytes
, abort
);
417 DEC_GIANT(cp
->x1OrderPlus
, buf
, bufLen
, gLen
, bytes
, abort
);
418 DEC_GIANT(cp
->x1OrderMinus
, buf
, bufLen
, gLen
, bytes
, abort
);
421 * basePrime only present in byte rep for PT_GENERAL
423 if(cp
->primeType
== FPT_General
) {
424 DEC_GIANT(cp
->basePrime
, buf
, bufLen
, gLen
, bytes
, abort
);
427 /* remaining fields inferred */
428 curveParamsInferFields(cp
);
429 allocRecipGiants(cp
);
440 * Returns 0 if bad format, e.g., if minVersion of sig is > than codeVersion.
442 int byteRepToSig(const unsigned char *buf
,
445 int *sigMagic
, // RETURNED
446 int *sigVersion
, // RETURNED
447 int *sigMinVersion
, // RETURNED
448 giant
*g0
, // alloc'd & RETURNED
449 giant
*g1
) // alloc'd & RETURNED
455 if(bufLen
< (4 * sizeof(int))) { // magic, version, minVersion,
459 DEC_INT(*sigMagic
, buf
, bufLen
, bytes
);
460 DEC_INT(*sigVersion
, buf
, bufLen
, bytes
);
461 DEC_INT(*sigMinVersion
, buf
, bufLen
, bytes
);
462 if(*sigMinVersion
> codeVersion
) {
465 DEC_INT(spare
, buf
, bufLen
, bytes
);
466 // deleted 2/20/01 DEC_INT(*signerLen, buf, bufLen, bytes);
467 // deleted 2/20/01 *signer = byteRepToUnichars(buf, *signerLen);
468 // deleted 2/20/01 buf += (2 * *signerLen);
469 // deleted 2/20/01 bufLen -= (2 * *signerLen);
470 DEC_GIANT(*g0
, buf
, bufLen
, gLen
, bytes
, abort
);
471 DEC_GIANT(*g1
, buf
, bufLen
, gLen
, bytes
, abort
);