X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_comcryption/lib/comcryptPriv.h diff --git a/Security/libsecurity_comcryption/lib/comcryptPriv.h b/Security/libsecurity_comcryption/lib/comcryptPriv.h new file mode 100644 index 00000000..d99c9637 --- /dev/null +++ b/Security/libsecurity_comcryption/lib/comcryptPriv.h @@ -0,0 +1,492 @@ +/* + * Copyright (c) 1997,2011,2014 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +#ifndef _COMCRYPT_PRIV_H_ +#define _COMCRYPT_PRIV_H_ + +#include "comcryption.h" +#include "comDebug.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern comMallocExternFcn *comMallocExt; +extern comFreeExternFcn *comFreeExt; + +/* + * type of element in comcryptBuf.queue[]. Making this an unsigned int gives + * a slight performance improvement on the i486 platform, but it does use up + * more memory. + */ +typedef unsigned queueElt; + +/* + * Enable queue lookahead via comcryptBuf.lookAhead[]. This is currently + * just the default value for comcryptBuf.laEnable. + */ +#define QUEUE_LOOKAHEAD 1 + +/* + * lookahead queue is bit array if 1, else byte array. + * FIXME - this will most likely be a hard-coded 1 for Mac and + * dynamically configurable for other platforms. + */ +#define QUEUE_LOOKAHEAD_BIT 1 + +/* + * Size of lookAhead buffer in bytes. + */ +#if QUEUE_LOOKAHEAD_BIT +/* + * 1 bit per potential queueElt value. + */ +#define LOOKAHEAD_SIZE (1 << ((2 * 8) - 3)) +#else /* QUEUE_LOOKAHEAD_BIT */ +/* + * One byte per queueElt value; avoids shifts and masks in accessing + * array elements at the cost of additional memory. + */ +#define LOOKAHEAD_SIZE (1 << (2 * 8)) +#endif /* QUEUE_LOOKAHEAD_BIT */ + +/* + * When true, optimize away the cost of the keynybble() call on a hit + * on queue[0]. + */ +#define SKIP_NIBBLE_ON_QUEUE_0 1 + +/* + * pre-malloc'd buffers, one per level of comcryption. This allows each level + * to maintain its own queue state machine as well as its own comcryption + * parameters. + */ +typedef struct _comcryptBuf { + queueElt *queue; // mallocd, QLEN elements + unsigned nybbleDex; // index for keynybble() + struct _comcryptBuf *nextBuf; // for recursion + + /* + * Used to temporarily store bytecode fragments during comcryption and + * partial blocks during decomcryption. + */ + unsigned char *codeBuf; + unsigned codeBufSize; // malloc'd size of codeBuf + unsigned codeBufLength; // valid bytes in codeBuf + + /* + * Buffer for two-level comcryption. During comcryption, 2nd level + * comcrypted bytecode is placed here. During decomcryption, the result + * of decomcrytping the 2nd level bytecode is placed here. + */ + unsigned char *level2Buf; + unsigned level2BufSize; // malloc'd size of level2Buf + + /* + * comcryption parameters, may (eventually) be different for different + * levels. Tweakable, for now, only via private API in comDebug.h. + */ + unsigned f1; + unsigned f2; + unsigned jmatchThresh; // max avg jmatch for 2 level + unsigned minByteCode; // min numByteCodes for 2 level + + /* + * Bit map, one bit per potential value in queue[]; 1 means "this value + * is somewhere in queue[]" + */ + unsigned char *lookAhead; + + /* + * Signature Sequence array - to be Xord with ciphertext + * size = MAX_TOKENS + */ + unsigned *sigArray; +} comcryptBuf; + + +/* + * Private struct associated with client's comcryptObj. + */ +typedef struct { + unsigned char *key; + unsigned keybytes; // valid bytes in *key + comcryptOptimize optimize; // CCO_SIZE, etc. + unsigned char *map; + unsigned char *invmap; + unsigned version; // from ciphertext + unsigned versionBytes; // valid bytes in version; + // also nonzero on comcrypt + // means version has been + // written + unsigned spareBytes; // # ciphertext header spare + // bytes skipped + comcryptBuf cbuf; + + /* + * To save a tiny bit of memory, these could/should be bits, but + * we examine some of them on every code word, so we'll expand them into + * bytes... + */ + unsigned char laEnable; // lookahead enable + unsigned char sigSeqEnable; // signature sequence enable + unsigned char level2enable; // 2-level comcryption + +} comcryptPriv; + + +/* + * Block and buffer sizes. Subject to tweaking... + */ +#define CC_BLOCK_SIZE 256 /* bytes of plaintext */ + +/* + * For comcryptMaxInBufSize(CCOP_COMCRYPT), if outBufSize exceeds this + * threshhold, truncate the max inBufSize so that + * inBufSize = 0 mod CC_BLOCK_SIZE. + */ +#define INBUF_TRUNC_THRESH (16 * 1024) + +/* + * Macros to calculate number of token bits and bytes associated with + * a quantity of plaintext (in bytes) + */ +#define TOKEN_BITS_FROM_PTEXT(pt) ((pt + 1) >> 1) +#define TOKEN_BYTES_FROM_PTEXT(pt) ((pt + 15) >> 4) +#define TOKEN_BYTES_FROM_TOKEN_BITS(tb) ((tb + 7) >> 3) + +/* + * Max number of token bits or code fragments in a block + */ +#define MAX_TOKENS (CC_BLOCK_SIZE / 2) + +/* + * Size of comcryptBuf.queue[]. + */ +#define QLEN 256 + +/* + * FIXME - some info on these constants? + */ +#define F1_DEFAULT 12 +#define F2_DEFAULT 12 +#define ABOVE(F2) ((F2 * QLEN) >> 4) + +/* + * Constants for obfuscation via signature sequence. + */ +#define HASH_Q 19 +#define HASH_PRIME ((1< HASH_PRIME) { \ + x = (x >> HASH_Q) + (x & HASH_PRIME); \ + } \ +} + +/* + * Haven't gotten this to work for the Mac yet... + */ +#ifdef NeXT +#define SIG_WORD_INLINE 1 +#else /*NeXT*/ +#define SIG_WORD_INLINE 0 +#endif + +#if SIG_WORD_INLINE + +static inline void nextSigWord(comcryptBuf *cbuf, + unsigned sigDex, // same as tokenDex + unsigned match, + unsigned above) // (jabove, keyabove) + nibbleDex +{ + unsigned offset; + unsigned *sigArray = cbuf->sigArray; + + #if COM_DEBUG + if(sigDex == 0) { + printf("nextSigWord underflow\n"); + exit(1); + } + if(sigDex > MAX_TOKENS) { + printf("nextSigWord overflow\n"); + exit(1); + } + #endif + + if(match) { + offset = IN_OFFSET; + } + else { + offset = OUT_OFFSET; + } + sigArray[sigDex] = sigArray[sigDex-1] * (above + offset); + MOD_HASH(sigArray[sigDex]); +} + +#else /*SIG_WORD_INLINE*/ + +#define nextSigWord(cbuf, sigDex, match, above) { \ + unsigned offset = (match ? IN_OFFSET : OUT_OFFSET); \ + unsigned *sigArray = cbuf->sigArray; \ + unsigned result = (sigArray[sigDex-1] * (above + offset)); \ + MOD_HASH(result); \ + sigArray[sigDex] = result; \ +} + +#endif /*SIG_WORD_INLINE*/ + +/* + * Inline serializeShort(), deserializeShort() + */ +#define serializeShort(s, buf) \ + buf[0] = (unsigned char)(s >> 8); \ + buf[1] = (unsigned char)(s); \ + +#define deserializeShort(s, buf) \ + s = ((unsigned short)buf[0]) << 8; \ + s |= buf[1]; \ + + +/* + * General purpose macros for accessing bit arrays. Used for accessing + * token bits and lookahead array bits if QUEUE_LOOKAHEAD_BIT = 1. + */ +#define MARK_BIT_ARRAY(cp, index, val) { \ + unsigned char bit = 1 << (index & 7); \ + unsigned char *bytePtr = &cp[index>>3]; \ + if(val) { \ + *bytePtr |= bit; \ + } \ + else { \ + *bytePtr &= ~bit; \ + } \ +} +#define GET_BIT_ARRAY(cp, index) \ + (cp[index >> 3] & (1 << (index & 7))) + +#define getToken(tokenPtr, tokenDex) \ + GET_BIT_ARRAY(tokenPtr, tokenDex) + +#define updateToken(tokenPtr, tokenDex, tokenBit) \ + MARK_BIT_ARRAY(tokenPtr, tokenDex, tokenBit) + +/* + * Macros for accessing lookahead array elements + */ + +#if QUEUE_LOOKAHEAD_BIT +/* + * This way saves memory + */ +#define markInQueue(cbuf, codeWord, val) \ + MARK_BIT_ARRAY(cbuf->lookAhead, codeWord, val) + +#define inQueue(cbuf, codeWord) \ + GET_BIT_ARRAY(cbuf->lookAhead, codeWord) + +#else /* QUEUE_LOOKAHEAD_BIT */ + +/* + * This way saves time + */ +#define markInQueue(cbuf, codeWord, val) { \ + cbuf->lookAhead[codeWord] = val; \ +} +#define inQueue(cbuf, codeWord) (cbuf->lookAhead[codeWord]) + +#endif /* QUEUE_LOOKAHEAD_BIT */ + +void *ascMalloc(unsigned size); +void ascFree(void *data); + +#ifdef __cplusplus +} +#endif + +#endif /*_COMCRYPT_PRIV_H_*/