/* Decrypt one block using CBC. */ static krb5_error_code cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret = 0, olen = BLOCK_SIZE; unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; EVP_CIPHER_CTX ciph_ctx; struct iov_block_state input_pos, output_pos; EVP_CIPHER_CTX_init(&ciph_ctx); ret = EVP_DecryptInit_ex(&ciph_ctx, map_mode(key->keyblock.length), NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL); if (ret == 0) return KRB5_CRYPTO_INTERNAL; IOV_BLOCK_STATE_INIT(&input_pos); IOV_BLOCK_STATE_INIT(&output_pos); krb5int_c_iov_get_block(iblock, BLOCK_SIZE, data, num_data, &input_pos); EVP_CIPHER_CTX_set_padding(&ciph_ctx,0); ret = EVP_DecryptUpdate(&ciph_ctx, oblock, &olen, iblock, BLOCK_SIZE); if (ret == 1) { krb5int_c_iov_put_block(data, num_data, oblock, BLOCK_SIZE, &output_pos); } EVP_CIPHER_CTX_cleanup(&ciph_ctx); zap(iblock, BLOCK_SIZE); zap(oblock, BLOCK_SIZE); return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL; }
/* Decrypt one block using CBC. */ static krb5_error_code cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret = 0, olen = BLOCK_SIZE; unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; EVP_CIPHER_CTX *ctx; struct iov_cursor cursor; ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) return ENOMEM; ret = EVP_DecryptInit_ex(ctx, map_mode(key->keyblock.length), NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL); if (ret == 0) { EVP_CIPHER_CTX_free(ctx); return KRB5_CRYPTO_INTERNAL; } k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); k5_iov_cursor_get(&cursor, iblock); EVP_CIPHER_CTX_set_padding(ctx,0); ret = EVP_DecryptUpdate(ctx, oblock, &olen, iblock, BLOCK_SIZE); if (ret == 1) k5_iov_cursor_put(&cursor, oblock); EVP_CIPHER_CTX_free(ctx); zap(iblock, BLOCK_SIZE); zap(oblock, BLOCK_SIZE); return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL; }