void cf_cmac_stream_update(cf_cmac_stream *ctx, const uint8_t *data, size_t len, int isfinal) { size_t blocksz = ctx->cmac.prp->blocksz; cf_blockwise_in_fn final_fn = cmac_process; int needpad = 0; if (isfinal) { assert(!ctx->finalised); ctx->finalised = 1; /* If we have a whole number of blocks, and at least 1 block, we XOR in B. * Otherwise, we need to pad and XOR in P. */ if (((len + ctx->used) & 0xf) == 0 && !(len == 0 && ctx->used == 0 && ctx->processed == 0)) final_fn = cmac_process_final_nopad; else needpad = 1; } /* Input data */ cf_blockwise_accumulate_final(ctx->buffer, &ctx->used, blocksz, data, len, cmac_process, final_fn, ctx); /* Input padding */ if (needpad) { cf_blockwise_acc_pad(ctx->buffer, &ctx->used, blocksz, 0x80, 0x00, 0x00, blocksz - ctx->used, cmac_process_final_pad, ctx); } }
void cf_blockwise_accumulate(uint8_t *partial, size_t *npartial, size_t nblock, const void *inp, size_t nbytes, cf_blockwise_in_fn process, void *ctx) { cf_blockwise_accumulate_final(partial, npartial, nblock, inp, nbytes, process, process, ctx); }