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 */ 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