static void report( const char *name, CCOperation op, CCAlgorithm alg, size_t definedSize) { char key[4]; size_t cryptorLength = 0; CCCryptorStatus crtn; CCCryptorRef cryptorRef; char buf[1]; crtn = CCCryptorCreateFromData(op, alg, 0, key, 4, NULL, buf, 1, &cryptorRef, &cryptorLength); switch(crtn) { case kCCSuccess: printf("***Unuexpected success on CCCryptorCreate()\n"); return; case kCCBufferTooSmall: break; default: printf("***Unexpected result on CCCryptorCreate: expect %d got %d\n", (int)kCCBufferTooSmall, (int)crtn); return; } printf("%s : %lu bytes\n", name, (unsigned long)cryptorLength); if(definedSize < cryptorLength) { printf("***Defined context size (%u) is less than reported!\n", (unsigned)definedSize); } }
/* * 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; }