extern "C" int AppleCryptoNative_CryptorUpdate(CCCryptorRef cryptor, const uint8_t* pbData, int32_t cbData, uint32_t* pbOutput, int32_t cbOutput, int32_t* pcbWritten, int32_t* pccStatus) { if (pccStatus == nullptr) return -1; *pccStatus = 0; if (pbData == nullptr || cbData < 0 || pbOutput == nullptr || cbOutput < cbData || pcbWritten == nullptr) return -1; CCStatus status = CCCryptorUpdate(cryptor, pbData, static_cast<size_t>(cbData), pbOutput, static_cast<size_t>(cbOutput), reinterpret_cast<size_t*>(pcbWritten)); *pccStatus = status; return status == kCCSuccess; }
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; }
static int cipher_context_update(cipher_ctx_t *ctx, uint8_t *output, size_t *olen, const uint8_t *input, size_t ilen) { #ifdef USE_CRYPTO_APPLECC cipher_cc_t *cc = &ctx->cc; if (cc->valid == kCCContextValid) { CCCryptorStatus ret; ret = CCCryptorUpdate(cc->cryptor, input, ilen, output, ilen, olen); return (ret == kCCSuccess) ? 1 : 0; } #endif cipher_evp_t *evp = &ctx->evp; #if defined(USE_CRYPTO_OPENSSL) int err = 0, tlen = *olen; err = EVP_CipherUpdate(evp, (uint8_t *)output, &tlen, (const uint8_t *)input, ilen); *olen = tlen; return err; #elif defined(USE_CRYPTO_POLARSSL) return !cipher_update(evp, (const uint8_t *)input, ilen, (uint8_t *)output, olen); #elif defined(USE_CRYPTO_MBEDTLS) return !mbedtls_cipher_update(evp, (const uint8_t *)input, ilen, (uint8_t *)output, olen); #endif }
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); }
int32_t AppleCryptoNative_CryptorUpdate(CCCryptorRef cryptor, const uint8_t* pbData, int32_t cbData, uint32_t* pbOutput, int32_t cbOutput, int32_t* pcbWritten, int32_t* pccStatus) { if (pccStatus == NULL) return -1; *pccStatus = 0; if (pbData == NULL || cbData < 0 || pbOutput == NULL || cbOutput < cbData || pcbWritten == NULL) return -1; CCStatus status = CCCryptorUpdate(cryptor, pbData, (size_t)cbData, pbOutput, (size_t)cbOutput, (size_t*)pcbWritten); *pccStatus = status; return status == kCCSuccess; }
CryptoBuffer CommonCryptoCipher::DecryptBuffer(const CryptoBuffer& encryptedData) { if (m_failure) { AWS_LOGSTREAM_FATAL(CC_LOG_TAG, "Cipher not properly initialized for decryption. Aborting"); return CryptoBuffer(); } CheckInitDecryptor(); size_t lengthWritten = encryptedData.GetLength() + (GetBlockSizeBytes() - 1); CryptoBuffer decryptedText(static_cast<size_t>(lengthWritten)); CCStatus status = CCCryptorUpdate(m_cryptoHandle, encryptedData.GetUnderlyingData(), encryptedData.GetLength(), decryptedText.GetUnderlyingData(), decryptedText.GetLength(), &lengthWritten); if (status != kCCSuccess) { m_failure = true; AWS_LOGSTREAM_ERROR(CC_LOG_TAG, "Decryption of buffer failed with status code: " << status); return CryptoBuffer(); } if (lengthWritten < decryptedText.GetLength()) { return CryptoBuffer(decryptedText.GetUnderlyingData(), static_cast<size_t>(lengthWritten)); } return decryptedText; }
void sln_cryptor_osx_cc_encrypt(sln_cryptor_t *enc, const void *data, size_t len, char *buf, size_t *blen) { /* TODO: output buffer must be exactly the right size, our interface never * pads for you */ CCCryptorRef cryptor = enc->baton; CCCryptorUpdate(cryptor, data, len, buf, *blen, blen); }
/* * All of these functions are called by CSPFullPluginSession. */ void RC4Context::update( void *inp, size_t &inSize, // in/out void *outp, size_t &outSize) // in/out { (void) CCCryptorUpdate(rc4Key, inp, inSize, outp, inSize, &outSize); }
size_t crypt_aes_decrypt(crypt_aes_p d, void* encrypted_data, size_t encrypted_data_size, void* data, size_t data_size) { size_t data_moved = 0; CCCryptorUpdate(d->cryptor, encrypted_data, encrypted_data_size, data, data_size, &data_moved); return data_moved; }
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; }
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); }
OSStatus AES_CBCFrame_Update( AES_CBCFrame_Context *inContext, const void *inSrc, size_t inSrcLen, void *inDst ) { OSStatus err; const uint8_t * src; const uint8_t * end; uint8_t * dst; size_t len; src = (const uint8_t *) inSrc; end = src + inSrcLen; dst = (uint8_t *) inDst; // Process whole blocks. len = inSrcLen & ~( (size_t)( kAES_CBCFrame_Size - 1 ) ); if( len > 0 ) { #if( AES_UTILS_USE_COMMON_CRYPTO ) err = CCCryptorReset( inContext->cryptor, inContext->iv ); require_noerr( err, exit ); err = CCCryptorUpdate( inContext->cryptor, src, len, dst, len, &len ); require_noerr( err, exit ); #elif( AES_UTILS_USE_GLADMAN_AES ) uint8_t iv[ kAES_CBCFrame_Size ]; memcpy( iv, inContext->iv, kAES_CBCFrame_Size ); // Use local copy so original IV is not changed. if( inContext->encrypt ) aes_cbc_encrypt( src, dst, (int) len, iv, &inContext->ctx.encrypt ); else aes_cbc_decrypt( src, dst, (int) len, iv, &inContext->ctx.decrypt ); #elif( AES_UTILS_USE_USSL ) uint8_t iv[ kAES_CBCFrame_Size ]; memcpy( iv, inContext->iv, kAES_CBCFrame_Size ); // Use local copy so original IV is not changed. if( inContext->encrypt ) aes_crypt_cbc( &inContext->ctx, AES_ENCRYPT, len, iv, (unsigned char *) src, dst ); else aes_crypt_cbc( &inContext->ctx, AES_DECRYPT, len, iv, (unsigned char *) src, dst ); #else uint8_t iv[ kAES_CBCFrame_Size ]; memcpy( iv, inContext->iv, kAES_CBCFrame_Size ); // Use local copy so original IV is not changed. AES_cbc_encrypt( src, dst, (unsigned long) len, &inContext->key, iv, inContext->mode ); #endif src += len; dst += len; } // The remaining bytes are just copied unencrypted. while( src != end ) *dst++ = *src++; err = kNoErr; #if( AES_UTILS_USE_COMMON_CRYPTO ) exit: #endif return( err ); }
static int aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) { CCCryptorRef ref = ctx->ctx; CCCryptorStatus r; r = CCCryptorReset(ref, NULL); if (r != kCCSuccess) return -1; r = CCCryptorUpdate(ref, ctx->nonce, AES_BLOCK_SIZE, ctx->encr_buf, AES_BLOCK_SIZE, NULL); return (r == kCCSuccess)? 0: -1; }
int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size) { mz_crypt_aes *aes = (mz_crypt_aes *)handle; size_t data_moved = 0; if (aes == NULL || buf == NULL) return MZ_PARAM_ERROR; if (size != MZ_AES_BLOCK_SIZE) return MZ_PARAM_ERROR; aes->error = CCCryptorUpdate(aes->crypt, buf, size, buf, size, &data_moved); if (aes->error != kCCSuccess) return MZ_HASH_ERROR; return size; }
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); }
OSStatus AES_ECB_Update( AES_ECB_Context *inContext, const void *inSrc, size_t inLen, void *inDst ) { OSStatus err; const uint8_t * src; uint8_t * dst; size_t n; // inSrc and inDst may be the same, but otherwise, the buffers must not overlap. #if( DEBUG ) if( inSrc != inDst ) check_ptr_overlap( inSrc, inLen, inDst, inLen ); if( ( inLen % kAES_ECB_Size ) != 0 ) aes_log( "ECB doesn't support non-block-sized operations (%d bytes)", (int)inLen ); #endif src = (const uint8_t *) inSrc; dst = (uint8_t *) inDst; for( n = inLen / kAES_ECB_Size; n > 0; --n ) { #if( AES_UTILS_USE_COMMON_CRYPTO ) size_t len; err = CCCryptorUpdate( inContext->cryptor, src, kAES_ECB_Size, dst, kAES_ECB_Size, &len ); require_noerr( err, exit ); check( len == kAES_ECB_Size ); #elif( AES_UTILS_USE_GLADMAN_AES ) if( inContext->encrypt ) aes_ecb_encrypt( src, dst, kAES_ECB_Size, &inContext->ctx.encrypt ); else aes_ecb_decrypt( src, dst, kAES_ECB_Size, &inContext->ctx.decrypt ); #elif( AES_UTILS_USE_USSL ) aes_crypt_ecb( &inContext->ctx, inContext->mode, (unsigned char *) src, dst ); #else inContext->cryptFunc( src, dst, &inContext->key ); #endif src += kAES_ECB_Size; dst += kAES_ECB_Size; } err = kNoErr; #if( AES_UTILS_USE_COMMON_CRYPTO ) exit: #endif return( err ); }
static int cipher_context_update(cipher_ctx_t *ctx, uint8_t *output, int *olen, const uint8_t *input, int ilen) { #ifdef USE_CRYPTO_APPLECC cipher_cc_t *cc = &ctx->cc; if (cc->valid == kCCContextValid) { CCCryptorStatus ret; ret = CCCryptorUpdate(cc->cryptor, input, ilen, output, ilen + BLOCK_SIZE, (size_t *) olen); return (ret == kCCSuccess) ? 1 : 0; } #endif cipher_evp_t *evp = &ctx->evp; #if defined(USE_CRYPTO_OPENSSL) return EVP_CipherUpdate(evp, (uint8_t *) output, olen, (const uint8_t *) input, (size_t) ilen); #elif defined(USE_CRYPTO_POLARSSL) return !cipher_update(evp, (const uint8_t *) input, (size_t) ilen, (uint8_t *) output, (size_t *) olen); #endif }
static int cc_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int size) { struct cc_key *cc = ctx->cipher_data; CCCryptorStatus ret; size_t moved; memcpy(out, in, size); ret = CCCryptorUpdate(cc->href, in, size, out, size, &moved); if (ret) return 0; if (moved != size) return 0; return 1; }
int decryptData(void *bufIn, size_t bufInLen) { CCCryptorStatus status; int rv; CCHmacUpdate(&hmacContext, bufIn, bufInLen); status = CCCryptorUpdate(cryptorRef, bufIn, bufInLen, compressed, sizeof(compressed), &compressedLen); if (status != kCCSuccess) { printf("cryptor update error\n"); return(-1); } 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_NO_FLUSH); if (rv != Z_OK && rv != Z_STREAM_END && rv != Z_BUF_ERROR) { printf("zlib error %d\n", rv); } bufOutLen = sizeof(bufOut) - strm.avail_out; if (bufOutLen) { CCHmacUpdate(&hmacContextPlain, bufOut, bufOutLen); writer(bufOut, bufOutLen); } } while (strm.avail_out == 0); } return(0); }
static int __aes_process (crypto_aes_t *crypto, CCCryptorRef cryptor, const void *src, unsigned int src_size, void *dst, unsigned int *dst_size) { size_t out_avail; size_t used = 0; uint8_t *outp; size_t moved; pthread_mutex_lock(&(crypto->lock)); outp = (uint8_t *)dst; out_avail = src_size + 16; if (CCCryptorUpdate(cryptor, src, src_size, outp, out_avail, &moved)) { pthread_mutex_unlock(&(crypto->lock)); CCCryptorReset(cryptor, crypto->iv); return(-2); } outp += moved; used += moved; out_avail -= moved; if (CCCryptorFinal(cryptor, outp, out_avail, &moved)) { pthread_mutex_unlock(&(crypto->lock)); CCCryptorReset(cryptor, crypto->iv); return(-3); } used += moved; if (dst_size != NULL) *dst_size = used; CCCryptorReset(cryptor, crypto->iv); pthread_mutex_unlock(&(crypto->lock)); return(0); }
static int cc_do_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int size) { struct cc_key *cc = ctx->cipher_data; CCCryptorStatus ret; size_t moved; unsigned int i; for (i = 0; i < size; i++) { unsigned char oiv[EVP_MAX_IV_LENGTH + 1]; assert(ctx->cipher->iv_len + 1 <= sizeof(oiv)); memcpy(oiv, ctx->iv, ctx->cipher->iv_len); ret = CCCryptorUpdate(cc->href, ctx->iv, ctx->cipher->iv_len, ctx->iv, ctx->cipher->iv_len, &moved); if (ret) return 0; if (moved != ctx->cipher->iv_len) return 0; if (!ctx->encrypt) oiv[ctx->cipher->iv_len] = in[i]; out[i] = in[i] ^ ctx->iv[0]; if (ctx->encrypt) oiv[ctx->cipher->iv_len] = out[i]; memcpy(ctx->iv, &oiv[1], ctx->cipher->iv_len); } return 1; }
int main(int argc, char **argv) { unsigned loops = LOOPS_DEF; unsigned bufSize = BUFSIZE_DEF; unsigned algFirst = ALG_FIRST; unsigned algLast = ALG_LAST; bool ecbMode = false; extern char *optarg; int arg; while ((arg = getopt(argc, argv, "a:l:b:eh")) != -1) { switch (arg) { case 'a': switch(optarg[0]) { case 'a': algFirst = algLast = ALG_AES_128; break; case 'n': algFirst = algLast = ALG_AES_192; break; case 'A': algFirst = algLast = ALG_AES_256; break; case 'd': algFirst = algLast = ALG_DES; break; case '3': algFirst = algLast = ALG_3DES; break; case 'c': algFirst = algLast = ALG_CAST; case '4': algFirst = algLast = ALG_RC4; } break; case 'l': loops = atoi(optarg); break; case 'b': bufSize = atoi(optarg); break; case 'e': ecbMode = true; break; case 'h': usage(argv); } } if(optind != argc) { usage(argv); } /* * encrypt and decrypt on workBuf * save original ptext in saveBuf, compare at end as sanity check * for ECB only */ unsigned char *workBuf = (unsigned char *)malloc(bufSize); unsigned char *saveBuf = (unsigned char *)malloc(bufSize); if((workBuf == NULL) || (saveBuf == NULL)) { printf("***malloc failure\n"); exit(1); } appGetRandomBytes(workBuf, bufSize); memmove(saveBuf, workBuf, bufSize); uint8_t keyBytes[MAX_KEY_SIZE]; size_t keyLength; appGetRandomBytes(keyBytes, MAX_KEY_SIZE); CCCryptorRef cryptor; CCAlgorithm alg; CCOptions options = 0; OSStatus ortn; if(ecbMode) { options |= kCCOptionECBMode; } unsigned currAlg; for(currAlg=algFirst; currAlg<=algLast; currAlg++) { const char *algStr = NULL; switch(currAlg) { case ALG_DES: keyLength = kCCKeySizeDES; alg = kCCAlgorithmDES; algStr = "DES "; break; case ALG_3DES: keyLength = kCCKeySize3DES; alg = kCCAlgorithm3DES; algStr = "3DES"; break; case ALG_AES_128: keyLength = kCCKeySizeAES128; alg = kCCAlgorithmAES128; algStr = "AES128"; break; case ALG_AES_192: keyLength = kCCKeySizeAES192; alg = kCCAlgorithmAES128; algStr = "AES192"; break; case ALG_AES_256: keyLength = kCCKeySizeAES256; alg = kCCAlgorithmAES128; algStr = "AES256"; break; case ALG_CAST: keyLength = kCCKeySizeMaxCAST; alg = kCCAlgorithmCAST; algStr = "CAST"; break; case ALG_RC4: keyLength = kCCKeySizeMaxRC4; alg = kCCAlgorithmRC4; algStr = "RC4"; break; } printf("Algorithm: %s keySize: %u mode: %s loops: %u bufSize: %u\n", algStr, (unsigned)keyLength, ecbMode ? "ECB" : "CBC", (unsigned)loops, (unsigned)bufSize); CFAbsoluteTime start, end; unsigned loop; size_t thisMoved; /* encrypt: GO */ start = CFAbsoluteTimeGetCurrent(); ortn = CCCryptorCreate(kCCEncrypt, alg, options, keyBytes, keyLength, NULL, &cryptor); if(ortn) { printCCError("CCCryptorCreate", ortn); exit(1); } for(loop=0; loop<loops; loop++) { ortn = CCCryptorUpdate(cryptor, workBuf, bufSize, workBuf, bufSize, &thisMoved); if(ortn) { printCCError("CCCryptorUpdate", ortn); exit(1); } } /* no padding, CCCryptFinal not needed */ end = CFAbsoluteTimeGetCurrent(); printf(" encrypt %u * %u bytes took %gs: %g KBytes/s\n", (unsigned)loops, (unsigned)bufSize, end - start, (loops * bufSize) / (end - start) / 1024.0); /* dncrypt: GO */ start = CFAbsoluteTimeGetCurrent(); ortn = CCCryptorCreate(kCCDecrypt, alg, options, keyBytes, keyLength, NULL, &cryptor); if(ortn) { printCCError("CCCryptorCreate", ortn); exit(1); } for(loop=0; loop<loops; loop++) { ortn = CCCryptorUpdate(cryptor, workBuf, bufSize, workBuf, bufSize, &thisMoved); if(ortn) { printCCError("CCCryptorUpdate", ortn); exit(1); } } /* no padding, CCCryptFinal not needed */ end = CFAbsoluteTimeGetCurrent(); printf(" decrypt %u * %u bytes took %gs: %g KBytes/s\n", (unsigned)loops, (unsigned)bufSize, end - start, (loops * bufSize) / (end - start) / 1024.0); if(ecbMode) { if(memcmp(workBuf, saveBuf, bufSize)) { printf("***plaintext miscompare!\n"); } } } return 0; }
OSStatus AES_CBCFrame_Update2( AES_CBCFrame_Context * inContext, const void * inSrc1, size_t inLen1, const void * inSrc2, size_t inLen2, void * inDst ) { const uint8_t * src1 = (const uint8_t *) inSrc1; const uint8_t * end1 = src1 + inLen1; const uint8_t * src2 = (const uint8_t *) inSrc2; const uint8_t * end2 = src2 + inLen2; uint8_t * dst = (uint8_t *) inDst; OSStatus err; size_t len; size_t i; #if( !AES_UTILS_USE_COMMON_CRYPTO ) uint8_t iv[ kAES_CBCFrame_Size ]; #endif #if( AES_UTILS_USE_COMMON_CRYPTO ) if( ( inLen1 + inLen2 ) >= kAES_CBCFrame_Size ) { err = CCCryptorReset( inContext->cryptor, inContext->iv ); require_noerr( err, exit ); } #else memcpy( iv, inContext->iv, kAES_CBCFrame_Size ); // Use local copy so original IV is not changed. #endif // Process all whole blocks from buffer 1. len = inLen1 & ~( (size_t)( kAES_CBCFrame_Size - 1 ) ); if( len > 0 ) { #if( AES_UTILS_USE_COMMON_CRYPTO ) err = CCCryptorUpdate( inContext->cryptor, src1, len, dst, len, &len ); require_noerr( err, exit ); #elif( AES_UTILS_USE_GLADMAN_AES ) if( inContext->encrypt ) aes_cbc_encrypt( src1, dst, (int) len, iv, &inContext->ctx.encrypt ); else aes_cbc_decrypt( src1, dst, (int) len, iv, &inContext->ctx.decrypt ); #elif( AES_UTILS_USE_USSL ) if( inContext->encrypt ) aes_crypt_cbc( &inContext->ctx, AES_ENCRYPT, len, iv, (unsigned char *) src1, dst ); else aes_crypt_cbc( &inContext->ctx, AES_DECRYPT, len, iv, (unsigned char *) src1, dst ); #else AES_cbc_encrypt( src1, dst, (unsigned long) len, &inContext->key, iv, inContext->mode ); #endif src1 += len; dst += len; } // If there are any partial block bytes in buffer 1 and enough bytes in buffer 2 to fill a // block then combine them into a temporary buffer and encrypt it. if( ( src1 != end1 ) && ( ( ( end1 - src1 ) + ( end2 - src2 ) ) >= kAES_CBCFrame_Size ) ) { uint8_t buf[ kAES_CBCFrame_Size ]; for( i = 0; src1 != end1; ++i ) { buf[ i ] = *src1++; } for( ; ( i < kAES_CBCFrame_Size ) && ( src2 != end2 ); ++i ) { buf[ i ] = *src2++; } #if( AES_UTILS_USE_COMMON_CRYPTO ) err = CCCryptorUpdate( inContext->cryptor, buf, i, dst, i, &i ); require_noerr( err, exit ); #elif( AES_UTILS_USE_GLADMAN_AES ) if( inContext->encrypt ) aes_cbc_encrypt( buf, dst, (int) i, iv, &inContext->ctx.encrypt ); else aes_cbc_decrypt( buf, dst, (int) i, iv, &inContext->ctx.decrypt ); #elif( AES_UTILS_USE_USSL ) if( inContext->encrypt ) aes_crypt_cbc( &inContext->ctx, AES_ENCRYPT, i, iv, buf, dst ); else aes_crypt_cbc( &inContext->ctx, AES_DECRYPT, i, iv, buf, dst ); #else AES_cbc_encrypt( buf, dst, (unsigned long) i, &inContext->key, iv, inContext->mode ); #endif dst += i; } // Process any remaining whole blocks in buffer 2. len = ( (size_t)( end2 - src2 ) ) & ~( (size_t)( kAES_CBCFrame_Size - 1 ) ); if( len > 0 ) { #if( AES_UTILS_USE_COMMON_CRYPTO ) err = CCCryptorUpdate( inContext->cryptor, src2, len, dst, len, &len ); require_noerr( err, exit ); #elif( AES_UTILS_USE_GLADMAN_AES ) if( inContext->encrypt ) aes_cbc_encrypt( src2, dst, (int) len, iv, &inContext->ctx.encrypt ); else aes_cbc_decrypt( src2, dst, (int) len, iv, &inContext->ctx.decrypt ); #elif( AES_UTILS_USE_USSL ) if( inContext->encrypt ) aes_crypt_cbc( &inContext->ctx, AES_ENCRYPT, len, iv, (unsigned char *) src2, dst ); else aes_crypt_cbc( &inContext->ctx, AES_DECRYPT, len, iv, (unsigned char *) src2, dst ); #else AES_cbc_encrypt( src2, dst, (unsigned long) len, &inContext->key, iv, inContext->mode ); #endif src2 += len; dst += len; } // Any remaining bytes are just copied unencrypted. while( src1 != end1 ) *dst++ = *src1++; while( src2 != end2 ) *dst++ = *src2++; err = kNoErr; #if( AES_UTILS_USE_COMMON_CRYPTO ) exit: #endif return( err ); }
/* * 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; }
OSStatus AES_CTR_Update( AES_CTR_Context *inContext, const void *inSrc, size_t inLen, void *inDst ) { OSStatus err; const uint8_t * src; uint8_t * dst; uint8_t * buf; size_t used; size_t i; // inSrc and inDst may be the same, but otherwise, the buffers must not overlap. #if( DEBUG ) if( inSrc != inDst ) check_ptr_overlap( inSrc, inLen, inDst, inLen ); #endif src = (const uint8_t *) inSrc; dst = (uint8_t *) inDst; // If there's any buffered key material from a previous block then use that first. buf = inContext->buf; used = inContext->used; while( ( inLen > 0 ) && ( used != 0 ) ) { *dst++ = *src++ ^ buf[ used++ ]; used %= kAES_CTR_Size; inLen -= 1; } inContext->used = used; // Process whole blocks. while( inLen >= kAES_CTR_Size ) { #if( AES_UTILS_USE_COMMON_CRYPTO ) err = CCCryptorUpdate( inContext->cryptor, inContext->ctr, kAES_CTR_Size, buf, kAES_CTR_Size, &i ); require_noerr( err, exit ); require_action( i == kAES_CTR_Size, exit, err = kSizeErr ); #elif( AES_UTILS_USE_GLADMAN_AES ) aes_ecb_encrypt( inContext->ctr, buf, kAES_CTR_Size, &inContext->ctx ); #elif( AES_UTILS_USE_USSL ) aes_crypt_ecb( &inContext->ctx, AES_ENCRYPT, inContext->ctr, buf ); #else AES_encrypt( inContext->ctr, buf, &inContext->key ); #endif AES_CTR_Increment( inContext->ctr ); for( i = 0; i < kAES_CTR_Size; ++i ) { dst[ i ] = src[ i ] ^ buf[ i ]; } src += kAES_CTR_Size; dst += kAES_CTR_Size; inLen -= kAES_CTR_Size; } // Process any trailing sub-block bytes. Extra key material is buffered for next time. if( inLen > 0 ) { #if( AES_UTILS_USE_COMMON_CRYPTO ) err = CCCryptorUpdate( inContext->cryptor, inContext->ctr, kAES_CTR_Size, buf, kAES_CTR_Size, &i ); require_noerr( err, exit ); require_action( i == kAES_CTR_Size, exit, err = kSizeErr ); #elif( AES_UTILS_USE_GLADMAN_AES ) aes_ecb_encrypt( inContext->ctr, buf, kAES_CTR_Size, &inContext->ctx ); #elif( AES_UTILS_USE_USSL ) aes_crypt_ecb( &inContext->ctx, AES_ENCRYPT, inContext->ctr, buf ); #else AES_encrypt( inContext->ctr, buf, &inContext->key ); #endif AES_CTR_Increment( inContext->ctr ); for( i = 0; i < inLen; ++i ) { *dst++ = *src++ ^ buf[ used++ ]; } // For legacy mode, always leave the used amount as 0 so we always increment the counter each time. if( !inContext->legacy ) { inContext->used = used; } } err = kNoErr; #if( AES_UTILS_USE_COMMON_CRYPTO ) exit: #endif return( err ); }
wi_integer_t wi_cipher_decrypt_bytes(wi_cipher_t *cipher, const void *encrypted_buffer, wi_uinteger_t encrypted_length, void *decrypted_buffer) { #ifdef WI_CIPHER_OPENSSL int decrypted_length, padded_length; if(EVP_DecryptUpdate(&cipher->decrypt_ctx, decrypted_buffer, &decrypted_length, encrypted_buffer, encrypted_length) != 1) { wi_error_set_openssl_error(); return -1; } if(EVP_DecryptFinal_ex(&cipher->decrypt_ctx, decrypted_buffer + decrypted_length, &padded_length) != 1) { wi_error_set_openssl_error(); return -1; } if(EVP_DecryptInit_ex(&cipher->decrypt_ctx, NULL, NULL, NULL, NULL) != 1) { wi_error_set_openssl_error(); return -1; } return decrypted_length + padded_length; #endif #ifdef WI_CIPHER_COMMONCRYPTO CCCryptorStatus status; size_t available_length, decrypted_length, padded_length; available_length = wi_cipher_block_size(cipher) + encrypted_length; status = CCCryptorUpdate(cipher->decrypt_ref, encrypted_buffer, encrypted_length, decrypted_buffer, available_length, &decrypted_length); if(status != kCCSuccess) { wi_error_set_commoncrypto_error(status); return -1; } status = CCCryptorFinal(cipher->decrypt_ref, decrypted_buffer + decrypted_length, available_length - decrypted_length, &padded_length); if(status != kCCSuccess) { wi_error_set_commoncrypto_error(status); return -1; } status = CCCryptorReset(cipher->decrypt_ref, cipher->iv ? wi_data_bytes(cipher->iv) : NULL); if(status != kCCSuccess) { wi_error_set_commoncrypto_error(status); return -1; } return decrypted_length + padded_length; #endif }
int Crypto::CipherUpdate(Cipher c, const StringPiece &in, char *out, int outlen) { size_t wrote = 0; if (CCCryptorUpdate(FromVoid<CCCipher*>(c)->ctx, in.data(), in.size(), out, outlen, &wrote) != kCCSuccess) return -1; return wrote; }
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)); } }