]> git.saurik.com Git - apple/security.git/blame - OSX/include/security_cryptkit/byteRep.c
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / include / security_cryptkit / byteRep.c
CommitLineData
d8f41ccd 1/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved.
b1ab9ed8
A
2 *
3 * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
4 * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
d8f41ccd
A
5 * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE
6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE,
b1ab9ed8
A
7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
8 * EXPOSE YOU TO LIABILITY.
9 ***************************************************************************
10 *
11 * byteRep.c - FEE portable byte representation support
12 *
13 * Revision History
14 * ----------------
15 * 10/06/98 ap
16 * Changed to compile with C++.
d8f41ccd 17 * 18 Apr 98 at Apple
b1ab9ed8 18 * Mods for variable size giantDigit.
d8f41ccd 19 * 20 Jan 98 at Apple
b1ab9ed8 20 * Added curve param fields for CURVE_PARAM_VERSION 2.
d8f41ccd 21 * 17 Jul 97 at Apple
b1ab9ed8 22 * Added signature routines.
d8f41ccd 23 * 9 Jan 97 at NeXT
b1ab9ed8
A
24 * Split off from utilities.c
25 */
26
27#include "byteRep.h"
28#include "feeTypes.h"
29#include "curveParams.h"
30#include "giantIntegers.h"
31#include "elliptic.h"
32#include "falloc.h"
33#include "ckutilities.h"
34#include "feeDebug.h"
35#include <stdlib.h>
36
37#ifndef NULL
38#define NULL ((void *)0)
39#endif /* NULL */
40
41/*
42 * Support for portable bytestream representation of keys and signatures.
43 * Platform and endianness independent; format shared with JavaFEE
44 * implementation.
45 */
46
47/*
48 * Some handy macros.
49 */
50#define ENC_BYTE(n, b, bytes) \
51 *b++ = n; \
52 bytes++;
53
54#define ENC_INT(n, b, bytes, i) \
55 i = intToByteRep(n, b); \
56 bytes += i; \
57 b += i;
58
59#define ENC_GIANT(g, b, bytes, i) \
60 i = giantToByteRep(g, b); \
61 bytes += i; \
62 b += i;
63
64#define DEC_BYTE(n, b, blen, bytes) \
65 n = *b++; \
66 bytes++; \
67 blen--;
68
69#define DEC_INT(n, b, blen, bytes) \
70 n = byteRepToInt(b); \
71 b += sizeof(int); \
72 bytes += sizeof(int); \
73 blen -= gLen;
74
75#define DEC_GIANT(g, b, blen, glen, bytes, out) \
76 g = byteRepToGiant(b, blen, &glen); \
77 if(g == NULL) { \
78 goto out; \
79 } \
80 b += glen; \
81 bytes += glen; \
82 blen -= gLen;
83
84
85
86
87/*
88 * The routines which convert various types to byte reps return the number
89 * of bytes written to the output stream.
90 */
91int intToByteRep(int i, unsigned char *buf)
92{
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);
97 return 4;
98}
99
100int shortToByteRep(short s, unsigned char *buf)
101{
102 *buf++ = (unsigned char)((s >> 8) & 0xff);
103 *buf = (unsigned char)(s & 0xff);
104 return 2;
105}
106
107/*
108 * 7 Apr 1998 : leading int is now the number of bytes in the giant's
109 * giantDigits array. This value is signed.
110 */
111int giantToByteRep(giant g, unsigned char *buf)
112{
113 int numBytes = g->sign * GIANT_BYTES_PER_DIGIT;
114 unsigned aNumBytes = abs(numBytes);
115
116 CKASSERT(g != NULL);
117 intToByteRep(numBytes, buf);
118 buf += sizeof(int);
119 serializeGiant(g, buf, aNumBytes);
120 return (sizeof(int) + aNumBytes);
121}
122
123int keyToByteRep(key k, unsigned char *buf)
124{
125 int numBytes = 0;
126 int i;
127
128 CKASSERT(k != NULL);
129 ENC_GIANT(k->x, buf, numBytes, i);
130
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);
135 }
136 return numBytes;
137}
138
139#define CURVE_PARAM_VERSION 3
140#define CURVE_PARAM_VERSION_MIN 3
141
142int curveParamsToByteRep(curveParams *cp, unsigned char *buf)
143{
144 int numBytes = 0;
145 int i;
146
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
156
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);
168 }
169 return numBytes;
170}
171
172int sigToByteRep(int magic,
173 int version,
174 int minVersion,
175 giant g0,
176 giant g1,
177 unsigned char *buf)
178{
179 int numBytes = 0;
180 int i;
181
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);
188
189 return numBytes;
190}
191
192
193/*
194 * return the size of various data types' byte representations.
195 */
196int lengthOfByteRepGiant(giant g)
197{
198 CKASSERT(g != NULL);
199 return sizeof(int) + (GIANT_BYTES_PER_DIGIT * abs(g->sign));
200}
201
202int lengthOfByteRepKey(key k)
203{
204 int len = lengthOfByteRepGiant(k->x);
205
206 CKASSERT(k != NULL);
207 if(k->twist == CURVE_PLUS) {
208 CKASSERT(k->y != NULL);
209 len += lengthOfByteRepGiant(k->y);
210 }
211 return len;
212}
213
214int lengthOfByteRepCurveParams(curveParams *cp)
215{
216 int length;
217
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);
232 }
233 return length;
234}
235
236int lengthOfByteRepSig(giant g0,
237 giant g1)
238{
239 int length = (4 * sizeof(int)) + // magic, version, minVersion,
240 // spare
241 lengthOfByteRepGiant(g0) +
242 lengthOfByteRepGiant(g1);
243 return length;
244}
245
246/*
247 * Routine to cons up various types from a byte rep stream.
248 */
249int byteRepToInt(const unsigned char *buf) {
250 int result;
251
252 result = (((int)buf[0] << 24) & 0xff000000) |
253 (((int)buf[1] << 16) & 0x00ff0000) |
254 (((int)buf[2] << 8) & 0xff00) |
255 (((int)buf[3]) & 0xff);
256 return result;
257}
258
259unsigned short byteRepToShort(const unsigned char *buf) {
260 unsigned short result;
261
262 result = (((unsigned short)buf[0] << 8) & 0xff00) |
263 (((unsigned short)buf[1]) & 0xff);
264 return result;
265}
266
267/*
268 * Probably need byteRepToShortArray...
269 */
270
271/*
272 * byte rep stream to giant. Returns NULL on error; returns number of bytes
273 * of *buf snarfed in *giantLen if successful.
274 *
275 * 7 Apr 1998 : leading int is now the number of bytes in the giant's
276 * giantDigits array. This value is signed.
277 */
278giant byteRepToGiant(const unsigned char *buf,
279 unsigned bufLen,
280 unsigned *giantLen)
281{
282 giant g;
283 int numDigits;
284 int numBytes; // signed!
285 unsigned aNumBytes;
286
287 if(bufLen < sizeof(int)) {
288 return (giant)NULL;
289 }
290 numBytes = byteRepToInt(buf);
291 aNumBytes = abs(numBytes);
292 numDigits = BYTES_TO_GIANT_DIGITS(aNumBytes);
293 buf += sizeof(int);
294 bufLen -= sizeof(int);
295 if(numDigits > MAX_DIGITS) {
296 return (giant)NULL;
297 }
298
299 if(bufLen < aNumBytes) {
300 return (giant)NULL;
301 }
302
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[].
306 */
307 if(aNumBytes == 0) {
308 g = (giant)fmalloc(sizeof(giantstruct));
309 g->capacity = 1;
310 }
311 else {
312 g = (giant)fmalloc(sizeof(giantstruct) +
313 aNumBytes - GIANT_BYTES_PER_DIGIT);
314 g->capacity = numDigits;
315 }
316 deserializeGiant(buf, g, aNumBytes);
317
318 /* deserializeGiant always cooks up positive giant; sign is
319 * properly trimmed to handle trailing (M.S.) zeroes. */
320 if(numBytes < 0) {
321 g->sign = -g->sign;
322 }
323 *giantLen = sizeof(int) + aNumBytes;
324 return g;
325
326}
327
328/*
329 * Convert a byte stream (and some other parameters) into a
330 * keystruct.
331 * Returns NULL on error; returns number of bytes of *buf snarfed in
332 * *keyLen if successful.
333 */
334key byteRepToKey(const unsigned char *buf,
335 unsigned bufLen,
336 int twist,
337 curveParams *cp,
338 unsigned *keyLen) // returned
339{
340 key k;
341 giant x;
342 giant y;
343 unsigned gLen;
344 unsigned totalLen;
345
346 x = byteRepToGiant(buf, bufLen, &gLen);
347 if(x == NULL) {
348 return NULL;
349 }
350 bufLen -= gLen;
351 buf += gLen;
352 totalLen = gLen;
353 if(twist == CURVE_PLUS) {
354 /* this also contains y */
355 y = byteRepToGiant(buf, bufLen, &gLen);
356 if(y == NULL) {
357 freeGiant(x);
358 return NULL;
359 }
360 totalLen += gLen;
361 }
362 else {
363 /* minus curve, y is not used */
364 y = newGiant(1);
365 int_to_giant(0, y);
366 }
367 k = (key)fmalloc(sizeof(keystruct));
368 k->twist = twist;
369 k->cp = cp;
370 k->x = x;
371 k->y = y;
372 *keyLen = totalLen;
373 return k;
374}
375
376curveParams *byteRepToCurveParams(const unsigned char *buf,
377 unsigned bufLen,
378 unsigned *cpLen)
379{
380 curveParams *cp;
381 unsigned gLen = 0;
382 int version;
383 int minVersion;
384 int spare;
385 int bytes = 0;
386
387 if(bufLen < (5 * sizeof(int))) { // ver, minVers, q, k, spare
388 return NULL;
389 }
390 cp = newCurveParams();
391
392 DEC_INT(version, buf, bufLen, bytes);
393 DEC_INT(minVersion, buf, bufLen, bytes);
394 if(minVersion > CURVE_PARAM_VERSION) {
395 /*
396 * Can't parse this; things have changed too much between
397 * this version of the code and the time this curveParams
398 * was written.
399 */
400 goto abort;
401 }
402
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);
409
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);
419
420 /*
421 * basePrime only present in byte rep for PT_GENERAL
422 */
423 if(cp->primeType == FPT_General) {
424 DEC_GIANT(cp->basePrime, buf, bufLen, gLen, bytes, abort);
425 }
426
427 /* remaining fields inferred */
428 curveParamsInferFields(cp);
429 allocRecipGiants(cp);
430
431 *cpLen = bytes;
432 return cp;
433
434abort:
435 freeCurveParams(cp);
436 return NULL;
437}
438
439/*
440 * Returns 0 if bad format, e.g., if minVersion of sig is > than codeVersion.
441 */
442int byteRepToSig(const unsigned char *buf,
443 unsigned bufLen,
444 int codeVersion,
445 int *sigMagic, // RETURNED
446 int *sigVersion, // RETURNED
447 int *sigMinVersion, // RETURNED
448 giant *g0, // alloc'd & RETURNED
449 giant *g1) // alloc'd & RETURNED
450{
451 unsigned gLen = 0;
452 int spare;
453 int bytes = 0;
454
455 if(bufLen < (4 * sizeof(int))) { // magic, version, minVersion,
456 // spare
457 return 0;
458 }
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) {
463 return 0;
464 }
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);
472
473 return 1;
474abort:
475 return 0;
476}