1/* Copyright (c) 1998 Apple Computer, 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 COMPUTER, INC. AND THE
6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
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	Doug Mitchell at Apple
18 *	Mods for variable size giantDigit.
19 * 20 Jan 98	Doug Mitchell at Apple
20 *	Added curve param fields for CURVE_PARAM_VERSION 2.
21 * 17 Jul 97	Doug Mitchell at Apple
22 *	Added signature routines.
23 *  9 Jan 97	Doug Mitchell 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 */
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}
477