Ejemplo n.º 1
0
void
ShaderPrivate::
compile(void)
{
  if(m_shader_ready)
    {
      return;
    }

  //now do the GL work, create a name and compile the source code:
  assert(m_name == 0);

  m_shader_ready = true;
  m_name = glCreateShader(m_shader_type);

  const char *sourceString[1];
  sourceString[0] = m_source_code.c_str();


  glShaderSource(m_name, //shader handle
                 1, //number strings
                 sourceString, //array of strings
                 NULL); //lengths of each string or NULL implies each is 0-terminated

  glCompileShader(m_name);

  GLint logSize(0), shaderOK;
  std::vector<char> raw_log;

  //get shader compile status and log length.
  glGetShaderiv(m_name, GL_COMPILE_STATUS, &shaderOK);
  glGetShaderiv(m_name, GL_INFO_LOG_LENGTH, &logSize);

  //retrieve the compile log string, eh gross.
  raw_log.resize(logSize+2,'\0');
  glGetShaderInfoLog(m_name, //shader handle
                     logSize+1, //maximum size of string
                     NULL, //GLint* return length of string
                     &raw_log[0]); //char* to write log to.

  m_compile_log = &raw_log[0];
  m_compile_success = (shaderOK == GL_TRUE);

  if(!m_compile_success)
    {
      std::ostringstream oo;

      oo << "bad_shader_" << m_name << ".glsl";

      std::ofstream eek(oo.str().c_str());
      eek << m_source_code
          << "\n\n"
          << m_compile_log;
    }

}
/* 
 * Given an initialized CCHmacContext, feed it some data and get the result.
 */
static void hmacRun(
	CCHmacContext *ctx,
	bool randomUpdates,
	const unsigned char *ptext,
	size_t ptextLen,
	void *dataOut)
{
	while(ptextLen) {
		size_t thisMoveIn;			/* input to CCryptUpdate() */
		
		if(randomUpdates) {
			thisMoveIn = genRandomSize(1, ptextLen);
		}
		else {
			thisMoveIn = ptextLen;
		}
		logSize(("###ptext segment (1) len %lu\n", (unsigned long)thisMoveIn)); 
		CCHmacUpdate(ctx, ptext, thisMoveIn);
		ptext	 += thisMoveIn;
		ptextLen -= thisMoveIn;
	}
	CCHmacFinal(ctx, dataOut);
}
Ejemplo n.º 3
0
static int doTest(CSSM_CSP_HANDLE cspHand,
	CSSM_DATA_PTR ptext,
	uint32 keyAlg,						// CSSM_ALGID_xxx of the key
	uint32 encrAlg,						// encrypt/decrypt
	uint32 mode,
	uint32 padding,
	uint32 effectiveKeySizeInBits,
	CSSM_BOOL refKey,
	CSSM_DATA_PTR pwd,				// password- NULL means use a random key data
	CSSM_BOOL stagedEncr,
	CSSM_BOOL stagedDecr,
	CSSM_BOOL mallocPtext,			// only meaningful if !stagedDecr
	CSSM_BOOL mallocCtext,			// only meaningful if !stagedEncr
	CSSM_BOOL quiet,
	CSSM_BOOL keyGenOnly,
	CSSM_BOOL expectEqualText)		// ptext size must == ctext size
{
	CSSM_KEY_PTR	symKey = NULL;
	CSSM_DATA 		ctext = {0, NULL};
	CSSM_DATA		rptext = {0, NULL};
	CSSM_RETURN		crtn;
	int				rtn = 0;
	uint32			keySizeInBits;
	CSSM_DATA 		initVector;
	uint32			rounds = 0;
	
	/* generate keys with well aligned sizes; effectiveKeySize specified in encrypt
	 * only if not well aligned */
	keySizeInBits = (effectiveKeySizeInBits + 7) & ~7;
	if(keySizeInBits == effectiveKeySizeInBits) {
		effectiveKeySizeInBits = 0;
	}
	
	if(encrAlg == CSSM_ALGID_RC5) {
		/* roll the dice, pick one of three values for rounds */
		unsigned die = genRand(1,3);
		switch(die) {
			case 1:
				rounds = 8;
				break;
			case 2:
				rounds = 12;
				break;
			case 3:
				rounds = 16;
				break;
		}
	}

	if(pwd == NULL) {
		/* random key */
		symKey = cspGenSymKey(cspHand,
				keyAlg,
				"noLabel",
				7,
				CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
				keySizeInBits,
				refKey);
	}
	else {
		/* this code isn't tested */
		uint32	  pbeAlg;
		initVector.Data = NULL;		// we're going to ignore this
		initVector.Length = 0;
		/* one of two random PBE algs */
		if(ptext->Data[0] & 1) {
			pbeAlg = PBE_DERIVE_ALG_ODD;
		}
		else {
			pbeAlg = PBE_DERIVE_ALG_EVEN;
		}
		symKey = cspDeriveKey(cspHand,
			pbeAlg,
			keyAlg,
			"noLabel",
			7,
			CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
			keySizeInBits,
			refKey, 
			pwd,
			&seedData,
			1,			// iteration count
			&initVector);
		if(initVector.Data != NULL) {
			CSSM_FREE(initVector.Data);
		}
	}
	if(symKey == NULL) {
		rtn = testError(quiet);
		goto abort;
	}
	if(keyGenOnly) {
		rtn = 0;
		goto abort;
	}
	
	/* not all algs need this, pass it in anyway */
	initVector.Data = (uint8 *)"someStrangeInitVect";
	switch(encrAlg) {
		case CSSM_ALGID_AES:
		case CSSM_ALGID_NONE:
			initVector.Length = 16;
			break;
		default:
			initVector.Length = 8;
			break;
	}
	if(stagedEncr) {
		crtn = cspStagedEncrypt(cspHand,
			encrAlg,
			mode,
			padding,
			symKey,
			NULL,		// second key unused
			effectiveKeySizeInBits,
			0,			// cipherBlockSize
			rounds,
			&initVector,
			ptext,
			&ctext,
			CSSM_TRUE);	// multi
	}
	else {
		const CSSM_DATA *ptextPtr = ptext;
		if(expectEqualText && mallocCtext && CSPDL_NOPAD_ENFORCE_SIZE) {
			/* 
			 * !pad test: ensure this works when ctextlen == ptextlen by 
			 * mallocing ourself right now (instead of cspEncrypt doing it 
			 * after doing a CSSM_QuerySize())
			 */
			ctext.Data = (uint8 *)appMalloc(ptext->Length, NULL);
			if(ctext.Data == NULL) {
				printf("memmory failure\n");
				rtn = testError(quiet);
				goto abort;
			}
			ctext.Length = ptext->Length;
			#if	EQUAL_TEXT_IN_PLACE
			/* encrypt in place */
			memmove(ctext.Data, ptext->Data, ptext->Length);
			ptextPtr = &ctext;
			#endif
		}
		crtn = cspEncrypt(cspHand,
			encrAlg,
			mode,
			padding,
			symKey,
			NULL,		// second key unused
			effectiveKeySizeInBits,
			rounds,
			&initVector,
			ptextPtr,
			&ctext,
			mallocCtext);
	}
	if(crtn) {
		rtn = testError(quiet);
		goto abort;
	}
	if(expectEqualText && (ptext->Length != ctext.Length)) {
		printf("***ctext/ptext length mismatch: ptextLen %lu  ctextLen %lu\n",
			ptext->Length, ctext.Length);
		rtn = testError(quiet);
		if(rtn) {
			goto abort;
		}
	}
	logSize(("###ctext len %lu\n", ctext.Length)); 
	if(stagedDecr) {
		crtn = cspStagedDecrypt(cspHand,
			encrAlg,
			mode,
			padding,
			symKey,
			NULL,		// second key unused
			effectiveKeySizeInBits,
			0,			// cipherBlockSize
			rounds,
			&initVector,
			&ctext,
			&rptext,
			CSSM_TRUE);	// multi
	}
	else {
		const CSSM_DATA *ctextPtr = &ctext;
		if(expectEqualText && mallocPtext && CSPDL_NOPAD_ENFORCE_SIZE) {
			/* 
			 * !pad test: ensure this works when ctextlen == ptextlen by 
			 * mallocing ourself right now (instead of cspDecrypt doing it 
			 * after doing a CSSM_QuerySize())
			 */
			rptext.Data = (uint8 *)appMalloc(ctext.Length, NULL);
			if(rptext.Data == NULL) {
				printf("memmory failure\n");
				rtn = testError(quiet);
				goto abort;
			}
			rptext.Length = ctext.Length;
			#if	EQUAL_TEXT_IN_PLACE
			/* decrypt in place */
			memmove(rptext.Data, ctext.Data, ctext.Length);
			ctextPtr = &rptext;
			#endif
		}
		crtn = cspDecrypt(cspHand,
			encrAlg,
			mode,
			padding,
			symKey,
			NULL,		// second key unused
			effectiveKeySizeInBits,
			rounds,
			&initVector,
			ctextPtr,
			&rptext,
			mallocPtext);
	}
	if(crtn) {
		rtn = testError(quiet);
		goto abort;
	}
	logSize(("###rptext len %lu\n", rptext.Length)); 
	/* compare ptext, rptext */
	if(ptext->Length != rptext.Length) {
		printf("Ptext length mismatch: expect %lu, got %lu\n", ptext->Length, rptext.Length);
		rtn = testError(quiet);
		if(rtn) {
			goto abort;
		}
	}
	if(memcmp(ptext->Data, rptext.Data, ptext->Length)) {
		printf("***data miscompare\n");
		rtn = testError(quiet);
	}
abort:
	/* free key if we have it*/
	if(symKey != NULL) {
		if(cspFreeKey(cspHand, symKey)) {
			printf("Error freeing privKey\n");
			rtn = 1;
		}
		CSSM_FREE(symKey);
	}
	/* free rptext, ctext */
	appFreeCssmData(&rptext, CSSM_FALSE);
	appFreeCssmData(&ctext, CSSM_FALSE);
	return rtn;
}
Ejemplo n.º 4
0
static int doTest(const uint8_t *ptext,
	size_t ptextLen,
	CCAlgorithm encrAlg,			
	bool doCbc,
	bool doPadding,
	bool nullIV,			/* if CBC, use NULL IV */
	uint32 keySizeInBytes,
	bool stagedEncr,
	bool stagedDecr,
	bool inPlace,	
	size_t ctxSize,		
	bool askOutSize,
	bool quiet)
{
	uint8_t			keyBytes[MAX_KEY_SIZE];
	uint8_t			iv[MAX_BLOCK_SIZE];
	uint8_t			*ivPtrEncrypt;
	uint8_t			*ivPtrDecrypt;
	uint8_t			*ctext = NULL;		/* mallocd by doCCCrypt */
	size_t			ctextLen = 0;
	uint8_t			*rptext = NULL;		/* mallocd by doCCCrypt */
	size_t			rptextLen;
	CCCryptorStatus	crtn;
	int				rtn = 0;
	
	/* random key */
	appGetRandomBytes(keyBytes, keySizeInBytes);
	
	/* random IV if needed */
	if(doCbc) {
		if(nullIV) {
			memset(iv, 0, MAX_BLOCK_SIZE);
			
			/* flip a coin, give one side NULL, the other size zeroes */
			if(genRand(1,2) == 1) {
				ivPtrEncrypt = NULL;
				ivPtrDecrypt = iv;
			}
			else {
				ivPtrEncrypt = iv;
				ivPtrDecrypt = NULL;
			}
		}
		else {
			appGetRandomBytes(iv, MAX_BLOCK_SIZE);
			ivPtrEncrypt = iv;
			ivPtrDecrypt = iv;
		}
	}	
	else {
		ivPtrEncrypt = NULL;
		ivPtrDecrypt = NULL;
	}

	crtn = doCCCrypt(true, encrAlg, doCbc, doPadding,
		keyBytes, keySizeInBytes, ivPtrEncrypt,
		stagedEncr, inPlace, ctxSize, askOutSize,
		ptext, ptextLen,
		&ctext, &ctextLen);
	if(crtn) {
		rtn = testError(quiet);
		if(rtn) {
			goto abort;
		}
	}
	
	logSize(("###ctext len %lu\n", ctextLen)); 
	
	crtn = doCCCrypt(false, encrAlg, doCbc, doPadding,
		keyBytes, keySizeInBytes, ivPtrDecrypt,
		stagedDecr, inPlace, ctxSize, askOutSize,
		ctext, ctextLen,
		&rptext, &rptextLen);
	if(crtn) {
		rtn = testError(quiet);
		if(rtn) {
			goto abort;
		}
	}

	logSize(("###rptext len %lu\n", rptextLen)); 
	
	/* compare ptext, rptext */
	if(ptextLen != rptextLen) {
		printf("Ptext length mismatch: expect %lu, got %lu\n", ptextLen, rptextLen);
		rtn = testError(quiet);
		if(rtn) {
			goto abort;
		}
	}
	if(memcmp(ptext, rptext, ptextLen)) {
		printf("***data miscompare\n");
		rtn = testError(quiet);
	}
abort:
	if(ctext) {
		free(ctext);
	}
	if(rptext) {
		free(rptext);
	}
	return rtn;
}
Ejemplo n.º 5
0
/* 
 * Test harness for CCCryptor with lots of options. 
 */
CCCryptorStatus doCCCrypt(
	bool forEncrypt,
	CCAlgorithm encrAlg,			
	bool doCbc,
	bool doPadding,
	const void *keyBytes, size_t keyLen,
	const void *iv,
	bool randUpdates,
	bool inPlace,								/* !doPadding only */
	size_t ctxSize,								/* if nonzero, we allocate ctx */
	bool askOutSize,
	const uint8_t *inText, size_t inTextLen,
	uint8_t **outText, size_t *outTextLen)		/* both returned, WE malloc */
{
	CCCryptorRef	cryptor = NULL;
	CCCryptorStatus crtn;
	CCOperation		op = forEncrypt ? kCCEncrypt : kCCDecrypt;
	CCOptions		options = 0;
	uint8_t			*outBuf = NULL;			/* mallocd output buffer */
	uint8_t			*outp;					/* running ptr into outBuf */
	const uint8		*inp;					/* running ptr into inText */
	size_t			outLen;					/* bytes remaining in outBuf */
	size_t			toMove;					/* bytes remaining in inText */
	size_t			thisMoveOut;			/* output from CCCryptUpdate()/CCCryptFinal() */
	size_t			outBytes;				/* total bytes actually produced in outBuf */
	char			ctx[CC_MAX_CTX_SIZE];	/* for CCCryptorCreateFromData() */
	uint8_t			*textMarker = NULL;		/* 8 bytes of marker here after expected end of 
											 * output */
	char			*ctxMarker = NULL;		/* ditto for caller-provided context */
	unsigned		dex;
	size_t			askedOutSize;			/* from the lib */
	size_t			thisOutLen;				/* dataOutAvailable we use */
	
	if(ctxSize > CC_MAX_CTX_SIZE) {
		printf("***HEY! Adjust CC_MAX_CTX_SIZE!\n");
		exit(1);
	}
	if(!doCbc) {
		options |= kCCOptionECBMode;
	}
	if(doPadding) {
		options |= kCCOptionPKCS7Padding;
	}
	
	/* just hack this one */
	outLen = inTextLen;
	if(forEncrypt) {
		outLen += MAX_BLOCK_SIZE;
	}
	
	outBuf = (uint8_t *)malloc(outLen + MARKER_LENGTH);
	memset(outBuf, 0xEE, outLen + MARKER_LENGTH);
	
	/* library should not touch this memory */
	textMarker = outBuf + outLen;
	memset(textMarker, MARKER_BYTE, MARKER_LENGTH);
	
	/* subsequent errors to errOut: */

	if(inPlace) {
		memmove(outBuf, inText, inTextLen);
		inp = outBuf;
	}
	else {
		inp = inText;
	}

	if(!randUpdates) {
		/* one shot */
		if(askOutSize) {
			crtn = CCCrypt(op, encrAlg, options,
				keyBytes, keyLen, iv,
				inp, inTextLen,
				outBuf, 0, &askedOutSize);
			if(crtn != kCCBufferTooSmall) {
				printf("***Did not get kCCBufferTooSmall as expected\n");
				printf("   alg %d inTextLen %lu cbc %d padding %d keyLen %lu\n",
					(int)encrAlg, (unsigned long)inTextLen, (int)doCbc, (int)doPadding,
					(unsigned long)keyLen);
				printCCError("CCCrypt", crtn);
				crtn = -1;
				goto errOut;
			}
			outLen = askedOutSize;
		}
		crtn = CCCrypt(op, encrAlg, options,
			keyBytes, keyLen, iv,
			inp, inTextLen,
			outBuf, outLen, &outLen);
		if(crtn) {
			printCCError("CCCrypt", crtn);
			goto errOut;
		}
		*outText = outBuf;
		*outTextLen = outLen;
		goto errOut;
	}
	
	/* random multi updates */
	if(ctxSize) {
		size_t ctxSizeCreated;
		
		if(askOutSize) {
			crtn = CCCryptorCreateFromData(op, encrAlg, options,
				keyBytes, keyLen, iv,
				ctx, 0 /* ctxSize */,
				&cryptor, &askedOutSize);
			if(crtn != kCCBufferTooSmall) {
				printf("***Did not get kCCBufferTooSmall as expected\n");
				printCCError("CCCryptorCreateFromData", crtn);
				crtn = -1;
				goto errOut;
			}
			ctxSize = askedOutSize;
		}
		crtn = CCCryptorCreateFromData(op, encrAlg, options,
			keyBytes, keyLen, iv,
			ctx, ctxSize, &cryptor, &ctxSizeCreated);
		if(crtn) {
			printCCError("CCCryptorCreateFromData", crtn);
			return crtn;
		}
		ctxMarker = ctx + ctxSizeCreated;
		memset(ctxMarker, MARKER_BYTE, MARKER_LENGTH);
	}
	else {
		crtn = CCCryptorCreate(op, encrAlg, options,
			keyBytes, keyLen, iv,
			&cryptor);
		if(crtn) {
			printCCError("CCCryptorCreate", crtn);
			return crtn;
		}
	}
	
	toMove = inTextLen;		/* total to go */
	outp = outBuf;
	outBytes = 0;			/* bytes actually produced in outBuf */
	
	while(toMove) {
		uint32 thisMoveIn;			/* input to CCryptUpdate() */
		
		thisMoveIn = genRand(1, toMove);
		logSize(("###ptext segment len %lu\n", (unsigned long)thisMoveIn)); 
		if(askOutSize) {
			thisOutLen = CCCryptorGetOutputLength(cryptor, thisMoveIn, false);
		}
		else {
			thisOutLen = outLen;
		}
		crtn = CCCryptorUpdate(cryptor, inp, thisMoveIn,
			outp, thisOutLen, &thisMoveOut);
		if(crtn) {
			printCCError("CCCryptorUpdate", crtn);
			goto errOut;
		}
		inp			+= thisMoveIn;
		toMove		-= thisMoveIn;
		outp		+= thisMoveOut;
		outLen   	-= thisMoveOut;
		outBytes	+= thisMoveOut;
	}
	
	if(doPadding) {
		/* Final is not needed if padding is disabled */
		if(askOutSize) {
			thisOutLen = CCCryptorGetOutputLength(cryptor, 0, true);
		}
		else {
			thisOutLen = outLen;
		}
		crtn = CCCryptorFinal(cryptor, outp, thisOutLen, &thisMoveOut);
	}
	else {
		thisMoveOut = 0;
		crtn = kCCSuccess;
	}
	
	if(crtn) {
		printCCError("CCCryptorFinal", crtn);
		goto errOut;
	}
	
	outBytes += thisMoveOut;
	*outText = outBuf;
	*outTextLen = outBytes;
	crtn = kCCSuccess;

	for(dex=0; dex<MARKER_LENGTH; dex++) {
		if(textMarker[dex] != MARKER_BYTE) {
			printf("***lib scribbled on our textMarker memory (op=%s)!\n",
				forEncrypt ? "encrypt" : "decrypt");
			crtn = (CCCryptorStatus)-1;
		}
	}
	if(ctxSize) {
		for(dex=0; dex<MARKER_LENGTH; dex++) {
			if(ctxMarker[dex] != MARKER_BYTE) {
				printf("***lib scribbled on our ctxMarker memory (op=%s)!\n",
					forEncrypt ? "encrypt" : "decrypt");
				crtn = (CCCryptorStatus)-1;
			}
		}
	}
	
errOut:
	if(crtn) {
		if(outBuf) {
			free(outBuf);
		}
	}
	if(cryptor) {
		CCCryptorRelease(cryptor);
	}
	return crtn;
}
Ejemplo n.º 6
0
int main(int argc, char **argv)
{
    uint8_t totalNumberOfTests = 0;
    uint8_t numberOfTestsPassed = 0;
    uint8_t numberOfTestsFailed = 0;
    char *retString = NULL;

    //Create a log variable
    log l;
    logConstructor(&l);

    //Insert some data in the log
    logInsert(&l, "cd ..");
    logInsert(&l, "pwd");
    logInsert(&l, "ls");
    logInsert(&l, "cd");
    logInsert(&l, "ls -l");

    //Test 1
    totalNumberOfTests++;
    if(logSize(&l) == 5)
        numberOfTestsPassed++;

    //Test 2
    retString = logPop(&l);
    totalNumberOfTests++;
    if(strcmp(retString, "ls -l") == 0)
        numberOfTestsPassed++;

    //Test 3
    totalNumberOfTests++;
    retString = logPop(&l);
    if(strcmp(retString, "cd") == 0)
        numberOfTestsPassed++;

    //Test 4
    totalNumberOfTests++;
    if(logSize(&l) == 3)
        numberOfTestsPassed++;

    //Test 5
    totalNumberOfTests++;
    retString = logPop(&l);
    if(strcmp(retString, "ls") == 0)
        numberOfTestsPassed++;

    //Test 6
    totalNumberOfTests++;
    retString = logPop(&l);
    if(strcmp(retString, "pwd") == 0)
        numberOfTestsPassed++;

    //Test 7
    totalNumberOfTests++;
    if(logSize(&l) == 1)
        numberOfTestsPassed++;

    //Test 8
    totalNumberOfTests++;
    retString = logPop(&l);
    if(strcmp(retString, "cd ..") == 0)
        numberOfTestsPassed++;

    //Test 9
    totalNumberOfTests++;
    if(logSize(&l) == 0)
        numberOfTestsPassed++;

    //Test 10
    totalNumberOfTests++;
    retString = logPop(&l);
    if(retString == NULL)
        numberOfTestsPassed++;

    //Insert some data in the log
    logInsert(&l, "cd ..");
    logInsert(&l, "pwd");
    logInsert(&l, "ls");

    //Test 11
    totalNumberOfTests++;
    if(logSize(&l) == 3)
        numberOfTestsPassed++;

    //Test 12
    totalNumberOfTests++;
    retString = logAt(&l, 0);
    if(strcmp(retString, "cd ..") == 0)
        numberOfTestsPassed++;

    //Test 13
    totalNumberOfTests++;
    retString = logAt(&l, 1);
    if(strcmp(retString, "pwd") == 0)
        numberOfTestsPassed++;

    //Test 14
    totalNumberOfTests++;
    retString = logAt(&l, 2);
    if(strcmp(retString, "ls") == 0)
        numberOfTestsPassed++;

    //Test 15
    totalNumberOfTests++;
    retString = logAt(&l, 3);
    if(retString == NULL)
        numberOfTestsPassed++;

    //Test 16
    totalNumberOfTests++;
    if(logSize(&l) == 3)
        numberOfTestsPassed++;

    //Insert some data in the log
    logInsert(&l, "ab 1");
    logInsert(&l, "abc 2");
    logInsert(&l, "a 3");

    //Test 17
    totalNumberOfTests++;
    retString = logSearch(&l, "pw");
    if(strcmp(retString, "pwd") == 0)
        numberOfTestsPassed++;

    //Test 18
    totalNumberOfTests++;
    retString = logSearch(&l, "a");
    if(strcmp(retString, "a 3") == 0)
        numberOfTestsPassed++;

    //Test 19
    totalNumberOfTests++;
    retString = logSearch(&l, "ab");
    if(strcmp(retString, "abc 2") == 0)
        numberOfTestsPassed++;

    //Test 20
    totalNumberOfTests++;
    retString = logSearch(&l, "ab ");
    if(strcmp(retString, "ab 1") == 0)
        numberOfTestsPassed++;

    //Test 21
    totalNumberOfTests++;
    retString = logSearch(&l, "cd");
    if(strcmp(retString, "cd ..") == 0)
        numberOfTestsPassed++;

    //Test 22
    totalNumberOfTests++;
    retString = logSearch(&l, "devil");
    if(retString == NULL)
        numberOfTestsPassed++;

    logPop(&l);
    logPop(&l);
    logPop(&l);
    logPop(&l);
    logPop(&l);
    logPop(&l);

    //Test 23
    totalNumberOfTests++;
    if(logSize(&l) == 0)
        numberOfTestsPassed++;

    numberOfTestsFailed = totalNumberOfTests - numberOfTestsPassed;
    printf("totalNumberOfTests = %d\n", totalNumberOfTests);
    printf("numberOfTestsPassed = %d\n", numberOfTestsPassed);
    printf("numberOfTestsFailed = %d\n", numberOfTestsFailed);

    return 0;
}
static int doHMacCloneTest(const uint8_t *ptext,
	size_t ptextLen,
	CCHmacAlgorithm hmacAlg,			
	uint32_t keySizeInBytes,
	bool stagedOrig,
	bool stagedClone,
	bool quiet,
	bool verbose)
{
	uint8_t			*keyBytes;
	uint8_t			hmacOrig[MAX_HMAC_SIZE];
	uint8_t			hmacClone[MAX_HMAC_SIZE];
	int				rtn = 1;
	CCHmacContext	ctxOrig;
	CCHmacContext	ctxClone;
	unsigned		die;		/* 0..3 indicates when to clone */
	unsigned		loopNum = 0;
	size_t			hmacLen;
	bool			didClone = false;
	
	switch(hmacAlg) {
		case kCCHmacAlgSHA1:
            if(verbose) diag("hmac-sha1\n");
			hmacLen = CC_SHA1_DIGEST_LENGTH;
			break;
		case kCCHmacAlgMD5:
            if(verbose) diag("hmac-md5\n");
			hmacLen = CC_MD5_DIGEST_LENGTH;
			break;
		case kCCHmacAlgSHA224:
            if(verbose) diag("hmac-sha224\n");
			hmacLen = CC_SHA224_DIGEST_LENGTH;
			break;
		case kCCHmacAlgSHA256:
            if(verbose) diag("hmac-sha256\n");
			hmacLen = CC_SHA256_DIGEST_LENGTH;
			break;
		case kCCHmacAlgSHA384:
            if(verbose) diag("hmac-sha384\n");
			hmacLen = CC_SHA384_DIGEST_LENGTH;
			break;
		case kCCHmacAlgSHA512:
            if(verbose) diag("hmac-sha512\n");
			hmacLen = CC_SHA512_DIGEST_LENGTH;
			break;
		default:
			if(verbose) diag("***BRRRZAP!\n");
			return 0;
	}
	
	/* random key */
    byteBuffer keyBuffer = genRandomByteBuffer(keySizeInBytes, keySizeInBytes);
    keyBytes = keyBuffer->bytes;
	
	/* cook up first context */
	CCHmacInit(&ctxOrig, hmacAlg, keyBytes, keySizeInBytes);
	
	/* roll the dice */
	die = (unsigned) genRandomSize(0, 3);
	
	/* 
	 * In this loop we do updates to the ctxOrig up until we
	 * clone it, then we use hmacRun to finish both of them.
	 */
	while(ptextLen) {
		if((die == loopNum) || !stagedOrig) {
			/* make the clone now */
			if(verbose) {
				diag("   ...cloning at loop %u\n", loopNum);
			}
			ctxClone = ctxOrig;
			didClone = true;
            if(memcmp(&ctxClone, &ctxOrig, CC_HMAC_CONTEXT_SIZE * sizeof(uint32_t))) {
                if(verbose) diag("*** context miscompare\n");
            } else {
                if(verbose) diag("*** context clone worked\n");
            }
			
			/* do all of the clone's updates and final here */
			hmacRun(&ctxClone, stagedClone, ptext, ptextLen, hmacClone);
			
			/* now do all remaining updates and final for original */
			hmacRun(&ctxOrig, stagedOrig, ptext, ptextLen, hmacOrig);
			
			/* we're all done, time to check the HMAC values */
			break;
		}	/* making clone */
		
		/* feed some data into cryptorOrig */
		size_t thisMove;
		if(stagedOrig) {
			thisMove = genRandomSize(1, ptextLen);
		}
		else {
			thisMove = ptextLen;
		}
		logSize(("###ptext segment (2) len %lu\n", (unsigned long)thisMove)); 
		CCHmacUpdate(&ctxOrig, ptext, thisMove);
		ptext += thisMove;
		ptextLen -= thisMove;
		loopNum++;
	}
		
	/* 
	 * It's possible to get here without cloning or doing any finals,
	 * if we ran thru multiple updates and finished ptextLen for cryptorOrig
	 * before we hit the cloning spot.
	 */
	if(!didClone) {
		if(verbose) {
			diag("...ctxOrig finished before we cloned; skipping test\n");
		}
		return 1;
	}
	if(memcmp(hmacOrig, hmacClone, hmacLen)) {
		diag("***data miscompare\n");
		rtn = 0;
	} else {
        if(verbose) diag("*** clone worked\n");
        rtn = 1;
    }
    if(keyBuffer) free(keyBuffer);
    
	return rtn;
}