/* Encrypt and decrypt 'nblocks*loop' blocks of zeroes, 'nblocks' at a time. */ int ccmode_cbc_test_chaining_self(const struct ccmode_cbc *encrypt, const struct ccmode_cbc *decrypt, unsigned long nblocks, size_t keylen, const void *keydata, unsigned long loops) { unsigned char temp[nblocks*encrypt->block_size]; unsigned char zeroes[nblocks*encrypt->block_size]; cccbc_ctx_decl(encrypt->size, ekey); cccbc_ctx_decl(decrypt->size, dkey); /* here we have to use two iv contexts */ cccbc_iv_decl(encrypt->block_size, eiv); cccbc_iv_decl(decrypt->block_size, div); cc_zero(nblocks*encrypt->block_size,temp); cc_zero(nblocks*encrypt->block_size,zeroes); cccbc_init(encrypt, ekey, keylen, keydata); cccbc_init(decrypt, dkey, keylen, keydata); cccbc_set_iv(encrypt, eiv, NULL); cccbc_set_iv(decrypt, div, NULL); for (unsigned long i=0; i<loops; i++) { cccbc_update(encrypt, ekey, eiv, nblocks, temp, temp); cccbc_update(decrypt, dkey, div, nblocks, temp, temp); } return memcmp(zeroes, temp, sizeof(temp)); }
/* Initialize a block of 'nblocks' of zeroes, Does 'loops' consecutive encryption (CBC) in place, then 'loops' decryption (CBC) in place, using 0 for iv in each loop, result should be zeroes. */ int ccmode_cbc_test_key_self(const struct ccmode_cbc *encrypt, const struct ccmode_cbc *decrypt, unsigned long nblocks, size_t keylen, const void *keydata, unsigned long loops) { unsigned char temp[nblocks*encrypt->block_size]; unsigned char zeroes[nblocks*encrypt->block_size]; cccbc_iv_decl(encrypt->block_size, iv); // we can use the same iv context for encrypt and decrypt // as long as we are not chaining concurrently for both. cccbc_ctx_decl(encrypt->size, ekey); cccbc_ctx_decl(decrypt->size, dkey); cc_zero(nblocks*encrypt->block_size,temp); cc_zero(nblocks*encrypt->block_size,zeroes); cccbc_init(encrypt, ekey, keylen, keydata); for (unsigned long i=0; i<loops; i++) { cccbc_set_iv(encrypt, iv, NULL); cccbc_update(encrypt, ekey, iv, nblocks, temp, temp); } cccbc_init(decrypt, dkey, keylen, keydata); for (unsigned long i=0; i<loops; i++) { cccbc_set_iv(decrypt, iv, NULL); cccbc_update(decrypt, dkey, iv, nblocks, temp, temp); } return memcmp(zeroes, temp, encrypt->block_size*nblocks); }
aes_rval aes_decrypt_cbc(const unsigned char *in_blk, const unsigned char *in_iv, unsigned int num_blk, unsigned char *out_blk, aes_decrypt_ctx cx[1]) { const struct ccmode_cbc *cbc = g_crypto_funcs->ccaes_cbc_decrypt; cccbc_iv_decl(cbc->block_size, ctx_iv); cccbc_set_iv(cbc, ctx_iv, in_iv); cccbc_update(cbc, cx[0].ctx, ctx_iv, num_blk, in_blk, out_blk); //Actually cbc decrypt. return aes_good; }
/* Test one test vector, 1 block at a time */ int ccmode_cbc_test_one_chained(const struct ccmode_cbc *cbc, size_t keylen, const void *keydata, const void *iv, unsigned long nblocks, const void *in, const void *out) { unsigned long i; const unsigned char *input=in; unsigned char temp[nblocks*cbc->block_size]; cccbc_ctx_decl(cbc->size, key); cccbc_iv_decl(cbc->block_size, iv_ctx); cccbc_init(cbc, key, keylen, keydata); cccbc_set_iv(cbc, iv_ctx, iv); for (i=0; i<nblocks; i++) { cccbc_update(cbc, key, iv_ctx, 1, &input[i*cbc->block_size], &temp[i*cbc->block_size]); } return memcmp(out, temp, cbc->block_size*nblocks); }
static double perf_cccbc_update(unsigned long loops, unsigned long size, const void *arg) { const struct cccbc_perf_test *test=arg; const struct ccmode_cbc *cbc=test->cbc; size_t keylen=test->keylen; unsigned long nblocks=size/cbc->block_size; unsigned char keyd[keylen]; unsigned char temp[nblocks*cbc->block_size]; cc_zero(keylen,keyd); cccbc_ctx_decl(cbc->size, key); cccbc_iv_decl(cbc->block_size, iv); cccbc_init(cbc, key, keylen, keyd); cccbc_set_iv(cbc, iv, NULL); perf_start(); while(loops--) cccbc_update(cbc, key, iv, nblocks, temp, temp); return perf_time(); }