gost_grasshopper_cipher_destroy_ctr,
1,
sizeof(gost_grasshopper_cipher_ctx_ctr),
- 8,
+ /* IV size is set to match full block, to make it responsibility of
+ * user to assign correct values (IV || 0), and to make naive context
+ * copy possible (for software such as openssh) */
+ 16,
false
},
};
static GRASSHOPPER_INLINE void gost_grasshopper_cipher_destroy_ctr(gost_grasshopper_cipher_ctx* c) {
gost_grasshopper_cipher_ctx_ctr* ctx = (gost_grasshopper_cipher_ctx_ctr*) c;
- grasshopper_zero128(&ctx->iv_buffer);
grasshopper_zero128(&ctx->partial_buffer);
}
c->c.type = GRASSHOPPER_CIPHER_CTR;
ctx->num = 0;
- grasshopper_zero128(&c->iv_buffer);
grasshopper_zero128(&c->partial_buffer);
return gost_grasshopper_cipher_init(ctx, key, iv, enc);
ctx->num = n;
size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
- memcpy(&c->iv_buffer, iv, 8);
+ grasshopper_w128_t* iv_buffer = (grasshopper_w128_t*) iv;
// full parts
for (i = 0; i < blocks; i++) {
currentInputBlock = (grasshopper_w128_t*) current_in;
currentOutputBlock = (grasshopper_w128_t*) current_out;
- grasshopper_encrypt_block(&c->c.encrypt_round_keys, &c->iv_buffer, currentOutputBlock, &c->c.buffer);
+ grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer, currentOutputBlock, &c->c.buffer);
grasshopper_append128(currentOutputBlock, currentInputBlock);
- ctr128_inc(c->iv_buffer.b);
+ ctr128_inc(iv_buffer->b);
current_in += GRASSHOPPER_BLOCK_SIZE;
current_out += GRASSHOPPER_BLOCK_SIZE;
}
if (lasted > 0) {
currentInputBlock = (grasshopper_w128_t*) current_in;
currentOutputBlock = (grasshopper_w128_t*) current_out;
- grasshopper_encrypt_block(&c->c.encrypt_round_keys, &c->iv_buffer, &c->partial_buffer, &c->c.buffer);
+ grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer, &c->partial_buffer, &c->c.buffer);
for (i = 0; i < lasted; i++) {
currentOutputBlock->b[i] = c->partial_buffer.b[i] ^ currentInputBlock->b[i];
}
ctx->num = i;
- ctr128_inc(c->iv_buffer.b);
+ ctr128_inc(iv_buffer->b);
}
return 1;