예제 #1
0
static void _wi_cipher_dealloc(wi_runtime_instance_t *instance) {
	wi_cipher_t		*cipher = instance;

#ifdef WI_CIPHER_OPENSSL
	EVP_CIPHER_CTX_cleanup(&cipher->encrypt_ctx);
	EVP_CIPHER_CTX_cleanup(&cipher->decrypt_ctx);
#endif
	
#ifdef WI_CIPHER_COMMONCRYPTO
	CCCryptorRelease(cipher->encrypt_ref);
	CCCryptorRelease(cipher->decrypt_ref);
#endif
	
	wi_release(cipher->key);
	wi_release(cipher->iv);
}
CCCryptorStatus
CCCryptWithMode(CCOperation op, CCMode mode, CCAlgorithm alg, CCPadding padding, const void *iv, 
				const void *key, size_t keyLength, const void *tweak, size_t tweakLength,
                int numRounds, CCModeOptions options,
                const void *dataIn, size_t dataInLength, 
                void *dataOut, size_t dataOutAvailable, size_t *dataOutMoved)
#ifdef CRYPTORWITHMODE
{
    CCCryptorRef cref;
	CCCryptorStatus retval;
    size_t moved;

   	if((retval = CCCryptorCreateWithMode(op, mode, alg, padding, iv, key, keyLength, tweak, tweakLength, numRounds, options, &cref)) != kCCSuccess) {
    	return retval;
    }
    
    if((retval = CCCryptorUpdate(cref, dataIn, dataInLength, dataOut, dataOutAvailable, &moved)) != kCCSuccess) {
    	return retval;
    }
    
    dataOut += moved;
    dataOutAvailable -= moved;
    *dataOutMoved = moved;
    
    if((retval = CCCryptorFinal(cref, dataOut, dataOutAvailable, &moved)) != kCCSuccess) {
    	return retval;
    }
    
    *dataOutMoved += moved;

	CCCryptorRelease(cref);
    
    return kCCSuccess;
}
예제 #3
0
파일: main.c 프로젝트: CarlChenCC/examples
static void AES_Operation(CCOperation operation, void* key, size_t keySize,
						  FILE *fpInput, FILE *fpOutput)
{
	CCCryptorRef cryptorRef;
	CCCryptorStatus rc;
	rc = CCCryptorCreate(operation, kCCAlgorithmAES128, 0, key, keySize, NULL, &cryptorRef);
	assert(rc == kCCSuccess);
	
	char rawData[128/8];
	size_t bytesRead;
	while((bytesRead = fread(rawData, 1, sizeof(rawData), fpInput)) > 0)
	{
		char convertedData[128/8];
		size_t dataOutMoved;
		
		if(bytesRead < sizeof(rawData))
			bzero(&rawData[bytesRead], sizeof(rawData) - bytesRead);
		
		rc = CCCryptorUpdate(cryptorRef, rawData, sizeof(rawData), convertedData, sizeof(convertedData), &dataOutMoved);
		assert(rc == kCCSuccess);
		//assert(dataOutMoved == sizeof(convertedData));
		if(dataOutMoved != sizeof(convertedData))
			printf("Data out moved (%d) != converted (%d)\n", dataOutMoved, convertedData);
		
		if(dataOutMoved > 0)
			fwrite(convertedData, dataOutMoved, 1, fpOutput);
	}
	
	CCCryptorRelease(cryptorRef);
}
예제 #4
0
void crypt_aes_destroy(crypt_aes_p d) {
    
    CCCryptorRelease(d->cryptor);
    
    free(d);
    
}
예제 #5
0
RC4Context::~RC4Context()
{
    if (rc4Key != NULL) {
        CCCryptorRelease(rc4Key);
    }
    rc4Key = NULL;
}
예제 #6
0
void    AES_ECB_Final( AES_ECB_Context *inContext )
{
#if( AES_UTILS_USE_COMMON_CRYPTO )
    if( inContext->cryptor ) CCCryptorRelease( inContext->cryptor );
#endif
    memset( inContext, 0, sizeof( *inContext ) ); // Clear sensitive data.
}
/* 
 * Standard CSPContext init, called from CSPFullPluginSession::init().
 * Reusable, e.g., query followed by en/decrypt.
 */
void DESContext::init( 
	const Context &context, 
	bool encrypting)
{
	CSSM_SIZE	keyLen;
	uint8 		*keyData 	= NULL;
	
	/* obtain key from context */
	symmetricKeyBits(context, session(), CSSM_ALGID_DES, 
		encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,	
		keyData, keyLen);
	if(keyLen != (DES_KEY_SIZE_BITS_EXTERNAL / 8)) {
		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
	}
	
    if (DesInst != NULL)
    {
        CCCryptorRelease(DesInst);
    }
    
    (void) CCCryptorCreateWithMode(0, kCCModeECB, kCCAlgorithmDES, ccDefaultPadding, NULL, keyData, kCCKeySizeDES, NULL, 0, 0, 0, &DesInst);

	/* Finally, have BlockCryptor do its setup */
	setup(DES_BLOCK_SIZE_BYTES, context);
}	
예제 #8
0
void cipher_context_release(cipher_ctx_t *ctx)
{
    if (enc_method >= SALSA20) {
        return;
    }

#ifdef USE_CRYPTO_APPLECC
    cipher_cc_t *cc = &ctx->cc;
    if (cc->cryptor != NULL) {
        CCCryptorRelease(cc->cryptor);
        cc->cryptor = NULL;
    }
    if (cc->valid == kCCContextValid) {
        return;
    }
#endif

    cipher_evp_t *evp = &ctx->evp;
#if defined(USE_CRYPTO_OPENSSL)
    EVP_CIPHER_CTX_cleanup(evp);
#elif defined(USE_CRYPTO_POLARSSL)
// NOTE: cipher_free_ctx deprecated in PolarSSL 1.3.11
    cipher_free_ctx(evp);
#elif defined(USE_CRYPTO_MBEDTLS)
// NOTE: cipher_free_ctx deprecated
    mbedtls_cipher_free(evp);
#endif
}
예제 #9
0
파일: pal_symmetric.c 프로젝트: mono/corefx
void AppleCryptoNative_CryptorFree(CCCryptorRef cryptor)
{
    if (cryptor != NULL)
    {
        CCCryptorRelease(cryptor);
    }
}
예제 #10
0
extern "C" void AppleCryptoNative_CryptorFree(CCCryptorRef cryptor)
{
    if (cryptor != nullptr)
    {
        CCCryptorRelease(cryptor);
    }
}
예제 #11
0
 CommonCryptoCipher::~CommonCryptoCipher()
 {
     if(m_cryptoHandle)
     {
         CCCryptorRelease(m_cryptoHandle);
     }
 }
예제 #12
0
void sln_cryptor_osx_cc_destroy(sln_cryptor_t *enc) {
  selene_t *s = enc->s;
  CCCryptorRef cryptor = enc->baton;

  CCCryptorRelease(cryptor);

  sln_free(s, enc);
}
void CastContext::deleteKey()
{
    if (mCastKey != NULL) {
        CCCryptorRelease(mCastKey);
    }
    mCastKey = NULL;
	mInitFlag = false;
}
예제 #14
0
void mz_crypt_aes_reset(void *handle)
{
    mz_crypt_aes *aes = (mz_crypt_aes *)handle;
    
    if (aes->crypt != NULL)
        CCCryptorRelease(aes->crypt);
    aes->crypt = NULL;
}
DESContext::~DESContext()
{
    if (DesInst != NULL) {
        CCCryptorRelease(DesInst);
    }
    
    DesInst = NULL;
}
예제 #16
0
파일: evp-cc.c 프로젝트: Sp1l/heimdal
static int
cc_cleanup(EVP_CIPHER_CTX *ctx)
{
    struct cc_key *cc = ctx->cipher_data;
    if (cc->href)
	CCCryptorRelease(cc->href);
    return 1;
}
예제 #17
0
 virtual bool decrypt(const byte *iv, const byte *in, byte *out, int size) {
   CCCryptorRef cryptor;
   CCCryptorCreateWithMode(kCCDecrypt, mode, algorithm, 0, iv, key.data(),
                           key.size(), NULL, 0, 0, 0, &cryptor);
   size_t updateLength = 0;
   CCCryptorUpdate(cryptor, in, size, out, size, &updateLength);
   CCCryptorRelease(cryptor);
   return true;
 }
예제 #18
0
파일: symcrypt.c 프로젝트: randix/redside
int
decryptFinal(HMACCheck hmacCheck)
{
  CCCryptorStatus status;
  int rv;
  uint8_t hmacDigest[CC_SHA512_DIGEST_LENGTH];

  status = CCCryptorFinal(cryptorRef,
                          compressed, sizeof(compressed), &compressedLen);
  if (status != kCCSuccess) {
    printf("cryptor update error\n");
    return(-1);
  }
  status = CCCryptorRelease(cryptorRef);
  if (status != kCCSuccess) {
    printf("cryptor release error\n");
  }

  if (compressedLen) {
    strm.next_in = compressed;
    strm.avail_in = (uint)compressedLen;

    do {
      strm.next_out = bufOut;
      strm.avail_out = sizeof(bufOut);

      rv = inflate(&strm, Z_FINISH);
      if (rv != Z_OK && rv != Z_STREAM_END && rv != Z_BUF_ERROR) {
         printf("zlib error\n");
      }

      bufOutLen = sizeof(bufOut) - strm.avail_out;
      if (bufOutLen) {
        CCHmacUpdate(&hmacContextPlain, bufOut, bufOutLen);
        writer(bufOut, bufOutLen);
      }

    } while (strm.avail_out == 0);
  }

  inflateEnd(&strm);

  if (hmacCheck == kHmacNoCheck)
    return(0);

  /* CHECK */
  CCHmacFinal(&hmacContext, &hmacDigest);
  if (memcmp(header.hmacDigest, hmacDigest, sizeof(hmacDigest)))
    printf("CRYPT CORRUPT\n");

  CCHmacFinal(&hmacContextPlain, &hmacDigest);
  if (memcmp(header.hmacDigestPlain, hmacDigest, sizeof(hmacDigest)))
    printf("PLAIN CORRUPT\n");

  return(0);
}
예제 #19
0
파일: symcrypt.c 프로젝트: randix/redside
int
encryptFinal(void)
{
  CCCryptorStatus status;
  int rv;

  /* finish zlib */
  do {
    strm.next_out = compressed;
    strm.avail_out = sizeof(compressed);

    rv = deflate(&strm, Z_FINISH);
    if (rv != Z_OK && rv != Z_STREAM_END && rv != Z_BUF_ERROR) {
      printf("zlib error %d\n", rv);
    }

    status = CCCryptorUpdate(cryptorRef,
                             compressed, sizeof(compressed) - strm.avail_out,
                             bufOut, sizeof(bufOut), &bufOutLen);
    if (status != kCCSuccess) {
      printf("cryptor update error\n");
      return(-1);
    }

    if (bufOutLen) {
      CCHmacUpdate(&hmacContext, bufOut, bufOutLen);
      writer(bufOut, bufOutLen);
    }
  } while (strm.avail_out == 0);

  deflateEnd(&strm);

  status = CCCryptorFinal(cryptorRef,
                          bufOut, sizeof(bufOut), &bufOutLen);
  if (status != kCCSuccess) {
    printf("cryptor update error: %d\n", status);
  }

  if (bufOutLen) {
      CCHmacUpdate(&hmacContext, bufOut, bufOutLen);
      writer(bufOut, bufOutLen);
  }

  status = CCCryptorRelease(cryptorRef);
  if (status != kCCSuccess) {
    printf("cryptor release error\n");
  }

  CCHmacFinal(&hmacContext, &header.hmacDigest);
  CCHmacFinal(&hmacContextPlain, &header.hmacDigestPlain);

  seeker(0);
  writer(&header, sizeof(header));

  return(0);
}
예제 #20
0
int ccmode_gcm_test_one_vector_chained(const struct ccmode_gcm *gcm, const struct ccmode_gcm_vector *v, int dec)
{
    if (v->ptlen!=v->ctlen)
        return -1;

#ifdef USE_COMMONCRYPTO_GCM
    unsigned char temp[v->ptlen];
    unsigned char temptag[v->taglen];
    CCCryptorStatus st;
    size_t taglen = v->taglen;
    CCCryptorRef cryptor = NULL;
    st = CCCryptorCreateWithMode(dec ? kCCDecrypt : kCCEncrypt, 11 /* kCCModeGCM */, kCCAlgorithmAES128, 0, NULL, v->key, v->keylen, NULL, 0, 0, 0, &cryptor);
    st = CCCryptorGCMAddIV(cryptor, v->iv, v->ivlen);
    unsigned long i;
#if 0
    for (i = 0; i < v->adalen; ++i) {
        st = CCCryptorGCMAddADD(cryptor, &v->ada[i], 1);
    }
#else
    st = CCCryptorGCMAddADD(cryptor, v->ada, v->adalen);
#endif

#if 0
    for (i = 0; i < v->ptlen; ++i) {
        st = (dec ? CCCryptorGCMDecrypt(cryptor, &v->ct[i], 1, &temp[i])
              : CCCryptorGCMEncrypt(cryptor, &v->pt[i], 1, &temp[i]));
    }
#else
    st = (dec ? CCCryptorGCMDecrypt(cryptor, v->ct, v->ptlen, temp)
          : CCCryptorGCMEncrypt(cryptor, v->pt, v->ptlen, temp));
#endif
    st = CCCryptorGCMFinal(cryptor, temptag, &taglen);
    CCCryptorRelease(cryptor);

#ifdef _INTERNAL_DEBUG_
    int r1, r2;
    r1 = memcmp(dec ? v->pt : v->ct, temp, v->ptlen);
    r2 = memcmp(v->tag, temptag, v->taglen);
    if (r1 || r2)
    cc_printf("ivlen: %lu adalen: %lu nbytes: %lu taglen: %lu crypt: %d tag: %d\n",
           v->ivlen, v->adalen, v->ptlen, v->taglen, r1, r2);

    return r1 != 0 ? r1 : r2;
#else
    return memcmp(dec ? v->pt : v->ct, temp, v->ptlen) || memcmp(v->tag, temptag, v->taglen);
#endif

#else
    if (dec)
        return ccmode_gcm_test_one_chained(gcm, v->keylen, v->key, v->ivlen, v->iv, v->adalen, v->ada, v->ptlen, v->ct, v->pt, v->taglen, v->tag);
    else
        return ccmode_gcm_test_one_chained(gcm, v->keylen, v->key, v->ivlen, v->iv, v->adalen, v->ada, v->ptlen, v->pt, v->ct, v->taglen, v->tag);
#endif
}
예제 #21
0
void    AES_GCM_Final( AES_GCM_Context *inContext )
{
#if( AES_UTILS_HAS_COMMON_CRYPTO_GCM )
    if( inContext->cryptor ) CCCryptorRelease( inContext->cryptor );
#elif( AES_UTILS_HAS_GLADMAN_GCM )
    gcm_end( &inContext->ctx );
#else
    #error "GCM enabled, but no implementation?"
#endif
    memset( inContext, 0, sizeof( *inContext ) ); // Clear sensitive data.
}
예제 #22
0
GAESContext::~GAESContext()
{
    if(mAesKey) {
        CCCryptorFinal(mAesKey,NULL,0,NULL);
        CCCryptorRelease(mAesKey);
        mAesKey = NULL;
    }
    
	deleteKey();
	memset(mRawKey, 0, MAX_AES_KEY_BITS / 8);
	mInitFlag = false;
}
예제 #23
0
            void CommonCryptoCipher::Reset()
            {
                m_failure = false;
                m_encryptionMode = false;
                m_encDecInitialized = false;

                if(m_cryptoHandle)
                {
                    CCCryptorRelease(m_cryptoHandle);
                }

                m_cryptoHandle = nullptr;
                Init();
            }
예제 #24
0
static void transformAES_CBC(CCOperation operation, const CryptoAlgorithmAesCbcParams& parameters, const CryptoKeyAES& key, const CryptoOperationData& data, std::unique_ptr<PromiseWrapper> promise)
{
    static_assert(sizeof(parameters.iv) == kCCBlockSizeAES128, "Initialization vector size must be the same as algorithm block size");

    size_t keyLengthInBytes = key.key().size();
    if (keyLengthInBytes != 16 && keyLengthInBytes != 24 && keyLengthInBytes != 32) {
        promise->reject(nullptr);
        return;
    }

    CCCryptorRef cryptor;
#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
    CCAlgorithm aesAlgorithm = kCCAlgorithmAES;
#else
    CCAlgorithm aesAlgorithm = kCCAlgorithmAES128;
#endif
    CCCryptorStatus status = CCCryptorCreate(operation, aesAlgorithm, kCCOptionPKCS7Padding, key.key().data(), keyLengthInBytes, parameters.iv.data(), &cryptor);
    if (status) {
        promise->reject(nullptr);
        return;
    }

    Vector<uint8_t> result(CCCryptorGetOutputLength(cryptor, data.second, true));

    size_t bytesWritten;
    status = CCCryptorUpdate(cryptor, data.first, data.second, result.data(), result.size(), &bytesWritten);
    if (status) {
        promise->reject(nullptr);
        return;
    }

    uint8_t* p = result.data() + bytesWritten;
    status = CCCryptorFinal(cryptor, p, result.end() - p, &bytesWritten);
    p += bytesWritten;
    if (status) {
        promise->reject(nullptr);
        return;
    }

    ASSERT(p <= result.end());
    result.shrink(p - result.begin());

    CCCryptorRelease(cryptor);

    promise->fulfill(result);
}
예제 #25
0
crypto_aes_t *crypto_aes_open (const void *key,
                               unsigned int key_size,
                               const void *salt,
                               unsigned int salt_size)
{
    unsigned char ikey[32];
    crypto_aes_t *crypto;

    /* Allocate Crypto AES Object */
    if ((crypto = (crypto_aes_t *) malloc(sizeof(crypto_aes_t))) == NULL)
        return(NULL);

    if (crypto_aes_key(ikey, crypto->iv, key, key_size, salt, salt_size)) {
        free(crypto);
        return(NULL);
    }

    if (pthread_mutex_init(&(crypto->lock), NULL)) {
        free(crypto);
        return(NULL);
    }

    /* Initialize Encryption */
    if (__aes_cryptor_create(&(crypto->enc), kCCEncrypt, ikey, crypto->iv)) {
        pthread_mutex_destroy(&(crypto->lock));
        free(crypto);
        return(NULL);
    }

    /* Initialize Decryption */
    if (__aes_cryptor_create(&(crypto->dec), kCCDecrypt, ikey, crypto->iv)) {
        CCCryptorRelease(crypto->enc);
        pthread_mutex_destroy(&(crypto->lock));
        free(crypto);
        return(NULL);
    }

    return(crypto);
}
예제 #26
0
void cipher_context_release(cipher_ctx_t *ctx)
{
#ifdef USE_CRYPTO_APPLECC
    cipher_cc_t *cc = &ctx->cc;
    if (cc->cryptor != NULL)
    {
        CCCryptorRelease(cc->cryptor);
        cc->cryptor = NULL;
    }
    if (cc->valid == kCCContextValid)
    {
        return;
    }
#endif

    cipher_evp_t *evp = &ctx->evp;
#if defined(USE_CRYPTO_OPENSSL)
    EVP_CIPHER_CTX_cleanup(evp);
#elif defined(USE_CRYPTO_POLARSSL)
    cipher_free_ctx(evp);
#endif
}
예제 #27
0
파일: evp-cc.c 프로젝트: Sp1l/heimdal
static int
init_cc_key(int encp, CCAlgorithm alg, CCOptions opts, const void *key,
	    size_t keylen, const void *iv, CCCryptorRef *ref)
{
    CCOperation op = encp ? kCCEncrypt : kCCDecrypt;
    CCCryptorStatus ret;

    if (*ref) {
	if (key == NULL && iv) {
	    CCCryptorReset(*ref, iv);
	    return 1;
	}
	CCCryptorRelease(*ref);
    }

    if (key) {
        ret = CCCryptorCreate(op, alg, opts, key, keylen, iv, ref);
        if (ret)
	    return 0;
    }

    return 1;
}
예제 #28
0
void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len,
                           int enc)
{
    const unsigned char *true_key;

    if (iv == NULL) {
        LOGE("cipher_context_set_iv(): IV is null");
        return;
    }

    if (!enc) {
        memcpy(ctx->iv, iv, iv_len);
    }

    if (enc_method >= SALSA20) {
        return;
    }

    if (enc_method == RC4_MD5) {
        unsigned char key_iv[32];
        memcpy(key_iv, enc_key, 16);
        memcpy(key_iv + 16, iv, 16);
        true_key = enc_md5(key_iv, 32, NULL);
        iv_len   = 0;
    } else {
        true_key = enc_key;
    }

#ifdef USE_CRYPTO_APPLECC
    cipher_cc_t *cc = &ctx->cc;
    if (cc->valid == kCCContextValid) {
        memcpy(cc->iv, iv, iv_len);
        memcpy(cc->key, true_key, enc_key_len);
        cc->iv_len  = iv_len;
        cc->key_len = enc_key_len;
        cc->encrypt = enc ? kCCEncrypt : kCCDecrypt;
        if (cc->cryptor != NULL) {
            CCCryptorRelease(cc->cryptor);
            cc->cryptor = NULL;
        }

        CCCryptorStatus ret;
        ret = CCCryptorCreateWithMode(
            cc->encrypt,
            cc->mode,
            cc->cipher,
            cc->padding,
            cc->iv, cc->key, cc->key_len,
            NULL, 0, 0, 0,
            &cc->cryptor);
        if (ret != kCCSuccess) {
            if (cc->cryptor != NULL) {
                CCCryptorRelease(cc->cryptor);
                cc->cryptor = NULL;
            }
            FATAL("Cannot set CommonCrypto key and IV");
        }
        return;
    }
#endif

    cipher_evp_t *evp = &ctx->evp;
    if (evp == NULL) {
        LOGE("cipher_context_set_iv(): Cipher context is null");
        return;
    }
#if defined(USE_CRYPTO_OPENSSL)
    if (!EVP_CipherInit_ex(evp, NULL, NULL, true_key, iv, enc)) {
        EVP_CIPHER_CTX_cleanup(evp);
        FATAL("Cannot set key and IV");
    }
#elif defined(USE_CRYPTO_POLARSSL)
    // XXX: PolarSSL 1.3.11: cipher_free_ctx deprecated, Use cipher_free() instead.
    if (cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) {
        cipher_free_ctx(evp);
        FATAL("Cannot set PolarSSL cipher key");
    }
#if POLARSSL_VERSION_NUMBER >= 0x01030000
    if (cipher_set_iv(evp, iv, iv_len) != 0) {
        cipher_free_ctx(evp);
        FATAL("Cannot set PolarSSL cipher IV");
    }
    if (cipher_reset(evp) != 0) {
        cipher_free_ctx(evp);
        FATAL("Cannot finalize PolarSSL cipher context");
    }
#else
    if (cipher_reset(evp, iv) != 0) {
        cipher_free_ctx(evp);
        FATAL("Cannot set PolarSSL cipher IV");
    }
#endif
#elif defined(USE_CRYPTO_MBEDTLS)
    if (mbedtls_cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) {
        mbedtls_cipher_free(evp);
        FATAL("Cannot set mbed TLS cipher key");
    }

    if (mbedtls_cipher_set_iv(evp, iv, iv_len) != 0) {
        mbedtls_cipher_free(evp);
        FATAL("Cannot set mbed TLS cipher IV");
    }
    if (mbedtls_cipher_reset(evp) != 0) {
        mbedtls_cipher_free(evp);
        FATAL("Cannot finalize mbed TLS cipher context");
    }
#endif

#ifdef DEBUG
    dump("IV", (char *)iv, iv_len);
#endif
}
예제 #29
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;
}
예제 #30
0
U8_EXPORT ssize_t u8_cryptic
(int do_encrypt,const char *cname,
 const unsigned char *key,int keylen,
 const unsigned char *iv,int ivlen,
 u8_block_reader reader,u8_block_writer writer,
 void *readstate,void *writestate,
 u8_context caller)
{
  if (strncasecmp(cname,"rsa",3)==0) {
    u8_seterr(_("RSA support NYI"),"u8_cryptic/CommonCrypto",u8_strdup(cname));
    return -1;}
  else {
    CCCryptorRef ctx;
    CCOptions options=0;
    ssize_t inlen, outlen, totalin=0, totalout=0, retval=0;
    unsigned char inbuf[1024], outbuf[1024];
    struct U8_CCCIPHER *cipher=get_cipher(cname);
    if (cipher) {
      size_t blocksize=cipher->cc_blocksize;
      ssize_t needivlen=cipher->cc_ivlen;
      if (!((keylen<=cipher->cc_keymax)&&(keylen>=cipher->cc_keymin)))
	return u8_reterr(u8_BadCryptoKey,
			 ((caller)?(caller):((u8_context)"u8_cryptic")),
			 u8_mkstring("%d!=[%d,%d](%s)",keylen,
				     cipher->cc_keymin,cipher->cc_keymax,
				     cname));
      if ((needivlen)&&(ivlen!=needivlen))
	return u8_reterr(u8_BadCryptoIV,
			 ((caller)?(caller):(COMMONCRYPTO_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",ivlen,needivlen,cname));

      if (needivlen==0) iv=NULL;

      memset(&ctx,0,sizeof(ctx));

      CCCryptorStatus status=CCCryptorCreate
	(((do_encrypt)? (kCCEncrypt) : (kCCDecrypt)),
	 cipher->cc_algorithm,cipher->cc_opts,key,keylen,iv,&ctx);

      u8_log(CRYPTO_LOGLEVEL,COMMONCRYPTO_CRYPTIC,
	     " %s cipher=%s, keylen=%d/[%d,%d], ivlen=%d, blocksize=%d\n",
	     ((do_encrypt)?("encrypt"):("decrypt")),
	     cname,keylen,cipher->cc_keymin,cipher->cc_keymax,
	     ivlen,blocksize);

      while (1) {
	inlen = reader(inbuf,blocksize,readstate);
	if (inlen <= 0) {
	  u8_log(CRYPTO_LOGLEVEL,COMMONCRYPTO_CRYPTIC,
		 "Finished %s(%s) with %ld in, %ld out",
		 ((do_encrypt)?("encrypt"):("decrypt")),cname,
		 totalin,totalout);
	  break;}
	if ((status=CCCryptorUpdate(ctx,inbuf,inlen,outbuf,1024,&outlen))
	    !=kCCSuccess) {
	  CCCryptorRelease(ctx);
	  return u8_reterr(u8_InternalCryptoError,
			   ((caller)?(caller):((u8_context)"u8_cryptic")),
			   NULL);}
	else {
	  u8_log(CRYPTO_LOGLEVEL,COMMONCRYPTO_CRYPTIC,
		 "%s(%s) consumed %d/%ld bytes, emitted %d/%ld bytes"
		 " in=<%v>\n out=<%v>",
		 ((do_encrypt)?("encrypt"):("decrypt")),cname,
		 inlen,totalin,outlen,totalout+outlen,
		 inbuf,inlen,outbuf,outlen);
	  writer(outbuf,outlen,writestate);
	  totalout=totalout+outlen;}}

      if ((status=CCCryptorFinal(ctx,outbuf,1024,&outlen))!=kCCSuccess) {
	CCCryptorRelease(ctx);
	return u8_reterr(u8_InternalCryptoError,
			 ((caller)?(caller):((u8_context)"u8_cryptic")),
			 NULL);}
      else {
	writer(outbuf,outlen,writestate);
	u8_log(CRYPTO_LOGLEVEL,COMMONCRYPTO_CRYPTIC,
	       "%s(%s) done after consuming %ld/%ld bytes, emitting %ld/%ld bytes"
	       "\n final out=<%v>",
	       ((do_encrypt)?("encrypt"):("decrypt")),cname,
	       inlen,totalin,outlen,totalout+outlen,
	       outbuf,outlen);
	CCCryptorRelease(ctx);
	totalout=totalout+outlen;
	return totalout;}}
    else return u8_reterr("Unknown cipher",
			  ((caller)?(caller):((u8_context)"u8_cryptic")),
			  u8_strdup(cname));
  }
}