/* 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); }
/* 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)); }
void cccmac_init(const struct ccmode_cbc *cbc, cccmac_ctx_t cmac, const void *key_data) { cccbc_init(cbc, cccmac_mode_sym_ctx(cbc, cmac), 16, key_data); uint8_t zeros[CMAC_BLOCKSIZE]; cc_zero(CMAC_BLOCKSIZE,zeros); cccbc_set_iv(cbc, cccmac_mode_iv(cbc, cmac), zeros); ccmac_generate_subkeys(ccaes_ecb_encrypt_mode(), key_data, cccmac_k1(cmac), cccmac_k2(cmac)); }
aes_rval aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]) { const struct ccmode_cbc *cbc = g_crypto_funcs->ccaes_cbc_decrypt; /* Make sure the context size for the mode fits in the one we have */ if(cbc->size>sizeof(aes_decrypt_ctx)) panic("%s: inconsistent size for AES decrypt context", __FUNCTION__); cccbc_init(cbc, cx[0].ctx, key_len, key); 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_init(unsigned long loops, unsigned long size CC_UNUSED, const void *arg) { const struct cccbc_perf_test *test=arg; const struct ccmode_cbc *cbc=test->cbc; size_t keylen=test->keylen; unsigned char keyd[keylen]; cc_zero(keylen,keyd); cccbc_ctx_decl(cbc->size, key); perf_start(); while(loops--) cccbc_init(cbc, key, keylen, keyd); return perf_time(); }
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(); }