/ OSX / libsecurity_cryptkit / lib / byteRep.c
byteRep.c
  1  /* Copyright (c) 1998,2011,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   * byteRep.c -  FEE portable byte representation support
 12   *
 13   * Revision History
 14   * ----------------
 15   * 10/06/98		ap
 16   *	Changed to compile with C++.
 17   * 18 Apr 98 at Apple
 18   *	Mods for variable size giantDigit.
 19   * 20 Jan 98 at Apple
 20   *	Added curve param fields for CURVE_PARAM_VERSION 2.
 21   * 17 Jul 97 at Apple
 22   *	Added signature routines.
 23   *  9 Jan 97 at NeXT
 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   */
 91  int 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  
100  int 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   */
111  int 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  
123  int 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  
142  int 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  
172  int 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   */
196  int lengthOfByteRepGiant(giant g)
197  {
198  	CKASSERT(g != NULL);
199      	return sizeof(int) + (GIANT_BYTES_PER_DIGIT * abs(g->sign));
200  }
201  
202  int 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  
214  int 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  
236  int 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   */
249  int 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  
259  unsigned 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   */
278  giant 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   */
334  key 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  
376  curveParams *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  
434  abort:
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   */
442  int 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;
474  abort:
475  	return 0;
476  }