1/* 2 * Copyright (c) 1997,2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25#ifndef _COMCRYPT_PRIV_H_ 26#define _COMCRYPT_PRIV_H_ 27 28#include "comcryption.h" 29#include "comDebug.h" 30 31#ifdef __cplusplus 32extern "C" { 33#endif 34 35extern comMallocExternFcn *comMallocExt; 36extern comFreeExternFcn *comFreeExt; 37 38/* 39 * type of element in comcryptBuf.queue[]. Making this an unsigned int gives 40 * a slight performance improvement on the i486 platform, but it does use up 41 * more memory. 42 */ 43typedef unsigned queueElt; 44 45/* 46 * Enable queue lookahead via comcryptBuf.lookAhead[]. This is currently 47 * just the default value for comcryptBuf.laEnable. 48 */ 49#define QUEUE_LOOKAHEAD 1 50 51/* 52 * lookahead queue is bit array if 1, else byte array. 53 * FIXME - this will most likely be a hard-coded 1 for Mac and 54 * dynamically configurable for other platforms. 55 */ 56#define QUEUE_LOOKAHEAD_BIT 1 57 58/* 59 * Size of lookAhead buffer in bytes. 60 */ 61#if QUEUE_LOOKAHEAD_BIT 62/* 63 * 1 bit per potential queueElt value. 64 */ 65#define LOOKAHEAD_SIZE (1 << ((2 * 8) - 3)) 66#else /* QUEUE_LOOKAHEAD_BIT */ 67/* 68 * One byte per queueElt value; avoids shifts and masks in accessing 69 * array elements at the cost of additional memory. 70 */ 71#define LOOKAHEAD_SIZE (1 << (2 * 8)) 72#endif /* QUEUE_LOOKAHEAD_BIT */ 73 74/* 75 * When true, optimize away the cost of the keynybble() call on a hit 76 * on queue[0]. 77 */ 78#define SKIP_NIBBLE_ON_QUEUE_0 1 79 80/* 81 * pre-malloc'd buffers, one per level of comcryption. This allows each level 82 * to maintain its own queue state machine as well as its own comcryption 83 * parameters. 84 */ 85typedef struct _comcryptBuf { 86 queueElt *queue; // mallocd, QLEN elements 87 unsigned nybbleDex; // index for keynybble() 88 struct _comcryptBuf *nextBuf; // for recursion 89 90 /* 91 * Used to temporarily store bytecode fragments during comcryption and 92 * partial blocks during decomcryption. 93 */ 94 unsigned char *codeBuf; 95 unsigned codeBufSize; // malloc'd size of codeBuf 96 unsigned codeBufLength; // valid bytes in codeBuf 97 98 /* 99 * Buffer for two-level comcryption. During comcryption, 2nd level 100 * comcrypted bytecode is placed here. During decomcryption, the result 101 * of decomcrytping the 2nd level bytecode is placed here. 102 */ 103 unsigned char *level2Buf; 104 unsigned level2BufSize; // malloc'd size of level2Buf 105 106 /* 107 * comcryption parameters, may (eventually) be different for different 108 * levels. Tweakable, for now, only via private API in comDebug.h. 109 */ 110 unsigned f1; 111 unsigned f2; 112 unsigned jmatchThresh; // max avg jmatch for 2 level 113 unsigned minByteCode; // min numByteCodes for 2 level 114 115 /* 116 * Bit map, one bit per potential value in queue[]; 1 means "this value 117 * is somewhere in queue[]" 118 */ 119 unsigned char *lookAhead; 120 121 /* 122 * Signature Sequence array - to be Xord with ciphertext 123 * size = MAX_TOKENS 124 */ 125 unsigned *sigArray; 126} comcryptBuf; 127 128 129/* 130 * Private struct associated with client's comcryptObj. 131 */ 132typedef struct { 133 unsigned char *key; 134 unsigned keybytes; // valid bytes in *key 135 comcryptOptimize optimize; // CCO_SIZE, etc. 136 unsigned char *map; 137 unsigned char *invmap; 138 unsigned version; // from ciphertext 139 unsigned versionBytes; // valid bytes in version; 140 // also nonzero on comcrypt 141 // means version has been 142 // written 143 unsigned spareBytes; // # ciphertext header spare 144 // bytes skipped 145 comcryptBuf cbuf; 146 147 /* 148 * To save a tiny bit of memory, these could/should be bits, but 149 * we examine some of them on every code word, so we'll expand them into 150 * bytes... 151 */ 152 unsigned char laEnable; // lookahead enable 153 unsigned char sigSeqEnable; // signature sequence enable 154 unsigned char level2enable; // 2-level comcryption 155 156} comcryptPriv; 157 158 159/* 160 * Block and buffer sizes. Subject to tweaking... 161 */ 162#define CC_BLOCK_SIZE 256 /* bytes of plaintext */ 163 164/* 165 * For comcryptMaxInBufSize(CCOP_COMCRYPT), if outBufSize exceeds this 166 * threshhold, truncate the max inBufSize so that 167 * inBufSize = 0 mod CC_BLOCK_SIZE. 168 */ 169#define INBUF_TRUNC_THRESH (16 * 1024) 170 171/* 172 * Macros to calculate number of token bits and bytes associated with 173 * a quantity of plaintext (in bytes) 174 */ 175#define TOKEN_BITS_FROM_PTEXT(pt) ((pt + 1) >> 1) 176#define TOKEN_BYTES_FROM_PTEXT(pt) ((pt + 15) >> 4) 177#define TOKEN_BYTES_FROM_TOKEN_BITS(tb) ((tb + 7) >> 3) 178 179/* 180 * Max number of token bits or code fragments in a block 181 */ 182#define MAX_TOKENS (CC_BLOCK_SIZE / 2) 183 184/* 185 * Size of comcryptBuf.queue[]. 186 */ 187#define QLEN 256 188 189/* 190 * FIXME - some info on these constants? 191 */ 192#define F1_DEFAULT 12 193#define F2_DEFAULT 12 194#define ABOVE(F2) ((F2 * QLEN) >> 4) 195 196/* 197 * Constants for obfuscation via signature sequence. 198 */ 199#define HASH_Q 19 200#define HASH_PRIME ((1<<HASH_Q)-1) /* Must be prime less than 2^19. */ 201#define IN_OFFSET 3 /* Must be in [1,255]. */ 202#define OUT_OFFSET 5 /* Must be in [1,255]. */ 203 204/* 205 * Ciphertext structure: 206 * 207 * 4 bytes of version 208 * 4 bytes spare 209 * n blocks, format described below 210 */ 211#define VERSION_3_Dec_97 0xc0de0003 212#define VERSION_BYTES 4 213#define SPARE_BYTES 4 214#define CTEXT_HDR_SIZE (VERSION_BYTES + SPARE_BYTES) 215 216/* 217 * Format of CBD_SINGLE block 218 * 219 * block description (see CBD_xxx, below) 220 * number of longCodes 221 * number of tokens - optional, absent if CBD_FULL_BLOCK 222 * token array 223 * longCode array 224 * byteCode array - length implied from number of longCodes, tokens 225 * 226 * Format of CBD_DOUBLE block 227 * 228 * block description (see CBD_xxx, below) 229 * number of longCodes 230 * number of tokens - optional, absent if CBD_FULL_BLOCK 231 * token array 232 * longCode array 233 * length of 2nd level comcrypted byte code to follow 234 * 2nd level comcrypted byte code array 235 */ 236 237/* 238 * Offsets (block-relative) of ciphertext components. All fields are byte-wide. 239 * This limits block size to < 512 (the limiting case is a whole block of 240 * bytecodes or a whole block of longcodes). Changing the counts to 241 * two bytes would add flexibility and is necessary for block sizes of 512 242 * or greater, but it would cost up to 3 bytes per block. 243 */ 244#define CTBO_BLOCK_DESC 0x00 /* descriptor bits, see below */ 245#define CTBO_NUM_LONG_CODES 0x01 /* in 16-bit words */ 246 247/* 248 * if block[CTBO_BLOCK_DESC] & CBD_FULL_BLOCK, the following byte 249 * is deleted (actually, implied) and subsequent fields are moved 250 * up one byte. This saves one byte per block for most blocks. 251 */ 252#define CTBO_NUM_TOKENS 0x02 253 254/* 255 * Offsets of remaining fields not constant; they depend on CBD_FULL_BLOCK and 256 * CBD_SINGLE/CBD_DOUBLE. 257 */ 258 259/* 260 * Min block size - blockDesc, numLongCodes, numTokens, one token byte, 261 * one bytecode 262 */ 263#define MIN_CBLOCK_SIZE 5 /* min cipherblock size */ 264 265/* 266 * Max block size - blockDesc, numLongCodes, full block's tokens, and 267 * a full block of longcodes 268 */ 269#define MAX_CBLOCK_SIZE (2 + \ 270 TOKEN_BYTES_FROM_PTEXT(CC_BLOCK_SIZE) + \ 271 CC_BLOCK_SIZE) 272 273/* 274 * Bits in block[CTBO_BLOCK_DESC] 275 */ 276#define CBD_MAGIC 0xd0 /* high nibble must be 0xd */ 277#define CBD_MAGIC_MASK 0xf0 278#define CBD_BLOCK_TYPE_MASK 0x01 279#define CBD_SINGLE 0x00 /* single-level comcrypt */ 280#define CBD_DOUBLE 0x01 /* double-level comcrypt */ 281#define CBD_ODD_MASK 0x02 282#define CBD_ODD 0x02 /* last code maps to single */ 283 /* (odd) byte */ 284#define CBD_EVEN 0x00 285#define CBD_FULL_BLOCK_MASK 0x04 286#define CBD_FULL_BLOCK 0x04 /* expands to CC_BLOCK_SIZE, also */ 287 /* implies no CTBO_NUM_TOKENS byte 288 * in block */ 289/* 290 * Defining this non-zero limits effective key size to 40 bits for export 291 */ 292#define COMCRYPT_EXPORT_ONLY 0 293#define EXPORT_KEY_SIZE 5 /* in bytes */ 294 295/* 296 * Threshholds for performing 2-level comcrypt 297 */ 298#define THRESH_2LEVEL_JMATCH_DEF 40 /* max average jmatch */ 299#define THRESH_2LEVEL_NUMBYTECODES_DEF 30 /* min number of bytecodes */ 300 301 302/* 303 * Private routines in comcryptPriv.c 304 */ 305extern void key_perm( 306 const unsigned char *key, 307 int keybytes, 308 unsigned char *map, 309 unsigned char *invmap); 310extern int keybyte( 311 const unsigned char *key, 312 int keybytes, 313 int index); 314extern int keynybble( 315 const unsigned char *key, 316 int keybytes, 317 int index); 318extern void mallocCodeBufs(comcryptBuf *cbufs); 319extern void freeCodeBufs(comcryptBuf *cbufs); 320extern void initCodeBufs( 321 comcryptBuf *cbuf, 322 const unsigned char *key, 323 unsigned keyLen, 324 unsigned char laEnable, 325 unsigned char sigSeqEnable); 326#if 0 327extern void serializeShort( 328 unsigned short s, 329 unsigned char *buf); 330unsigned short deserializeShort(unsigned char *buf); 331#endif /*0*/ 332void serializeInt( 333 unsigned i, 334 unsigned char *buf); 335unsigned deserializeInt(unsigned char *buf); 336void initSigSequence(comcryptBuf *cbuf, 337 const unsigned char *key, 338 unsigned keyLen); 339void sigMunge(comcryptBuf *cbuf, 340 const unsigned char *tokenPtr, 341 unsigned numTokens, 342 unsigned char *byteCodePtr, 343 unsigned char *longCodePtr); 344#if 0 345void nextSigWord(comcryptBuf *cbuf, 346 unsigned sigDex, // same as tokenDex 347 unsigned match, 348 unsigned above); 349#endif 350 351#if COM_LA_DEBUG 352extern int testLookAhead(comcryptBuf *cbuf, int i1, int i2); 353extern int initTestLookAhead(comcryptBuf *cbuf); 354#else /*COM_LA_DEBUG*/ 355#define testLookAhead(cbuf, i1, i2) 356#define initTestLookAhead(cbuf) 357#endif /* COM_LA_DEBUG */ 358 359/* 360 * Routines written as macros solely for performance reasons 361 */ 362 363/* 364 * try a couple different mersenne mods... 365 */ 366#define MOD_HASH(x) { \ 367 while(x > HASH_PRIME) { \ 368 x = (x >> HASH_Q) + (x & HASH_PRIME); \ 369 } \ 370} 371 372/* 373 * Haven't gotten this to work for the Mac yet... 374 */ 375#ifdef NeXT 376#define SIG_WORD_INLINE 1 377#else /*NeXT*/ 378#define SIG_WORD_INLINE 0 379#endif 380 381#if SIG_WORD_INLINE 382 383static inline void nextSigWord(comcryptBuf *cbuf, 384 unsigned sigDex, // same as tokenDex 385 unsigned match, 386 unsigned above) // (jabove, keyabove) + nibbleDex 387{ 388 unsigned offset; 389 unsigned *sigArray = cbuf->sigArray; 390 391 #if COM_DEBUG 392 if(sigDex == 0) { 393 printf("nextSigWord underflow\n"); 394 exit(1); 395 } 396 if(sigDex > MAX_TOKENS) { 397 printf("nextSigWord overflow\n"); 398 exit(1); 399 } 400 #endif 401 402 if(match) { 403 offset = IN_OFFSET; 404 } 405 else { 406 offset = OUT_OFFSET; 407 } 408 sigArray[sigDex] = sigArray[sigDex-1] * (above + offset); 409 MOD_HASH(sigArray[sigDex]); 410} 411 412#else /*SIG_WORD_INLINE*/ 413 414#define nextSigWord(cbuf, sigDex, match, above) { \ 415 unsigned offset = (match ? IN_OFFSET : OUT_OFFSET); \ 416 unsigned *sigArray = cbuf->sigArray; \ 417 unsigned result = (sigArray[sigDex-1] * (above + offset)); \ 418 MOD_HASH(result); \ 419 sigArray[sigDex] = result; \ 420} 421 422#endif /*SIG_WORD_INLINE*/ 423 424/* 425 * Inline serializeShort(), deserializeShort() 426 */ 427#define serializeShort(s, buf) \ 428 buf[0] = (unsigned char)(s >> 8); \ 429 buf[1] = (unsigned char)(s); \ 430 431#define deserializeShort(s, buf) \ 432 s = ((unsigned short)buf[0]) << 8; \ 433 s |= buf[1]; \ 434 435 436/* 437 * General purpose macros for accessing bit arrays. Used for accessing 438 * token bits and lookahead array bits if QUEUE_LOOKAHEAD_BIT = 1. 439 */ 440#define MARK_BIT_ARRAY(cp, index, val) { \ 441 unsigned char bit = 1 << (index & 7); \ 442 unsigned char *bytePtr = &cp[index>>3]; \ 443 if(val) { \ 444 *bytePtr |= bit; \ 445 } \ 446 else { \ 447 *bytePtr &= ~bit; \ 448 } \ 449} 450#define GET_BIT_ARRAY(cp, index) \ 451 (cp[index >> 3] & (1 << (index & 7))) 452 453#define getToken(tokenPtr, tokenDex) \ 454 GET_BIT_ARRAY(tokenPtr, tokenDex) 455 456#define updateToken(tokenPtr, tokenDex, tokenBit) \ 457 MARK_BIT_ARRAY(tokenPtr, tokenDex, tokenBit) 458 459/* 460 * Macros for accessing lookahead array elements 461 */ 462 463#if QUEUE_LOOKAHEAD_BIT 464/* 465 * This way saves memory 466 */ 467#define markInQueue(cbuf, codeWord, val) \ 468 MARK_BIT_ARRAY(cbuf->lookAhead, codeWord, val) 469 470#define inQueue(cbuf, codeWord) \ 471 GET_BIT_ARRAY(cbuf->lookAhead, codeWord) 472 473#else /* QUEUE_LOOKAHEAD_BIT */ 474 475/* 476 * This way saves time 477 */ 478#define markInQueue(cbuf, codeWord, val) { \ 479 cbuf->lookAhead[codeWord] = val; \ 480} 481#define inQueue(cbuf, codeWord) (cbuf->lookAhead[codeWord]) 482 483#endif /* QUEUE_LOOKAHEAD_BIT */ 484 485void *ascMalloc(unsigned size); 486void ascFree(void *data); 487 488#ifdef __cplusplus 489} 490#endif 491 492#endif /*_COMCRYPT_PRIV_H_*/ 493