int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl,
                                size_t outsize, const unsigned char *in,
                                size_t inl)
{
    size_t outlint = 0;
    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
    size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, GENERIC_BLOCK_SIZE, &in,
                                  &inl);
    if (ctx->bufsz == GENERIC_BLOCK_SIZE && (ctx->enc || inl > 0 || !ctx->pad)) {
        if (outsize < GENERIC_BLOCK_SIZE) {
            ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
            return 0;
        }
        if (!ctx->hw->cipher(ctx, out, ctx->buf, GENERIC_BLOCK_SIZE)) {
            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
            return 0;
        }
        ctx->bufsz = 0;
        outlint = GENERIC_BLOCK_SIZE;
        out += GENERIC_BLOCK_SIZE;
    }
    if (nextblocks > 0) {
        if (!ctx->enc && ctx->pad && nextblocks == inl) {
            if (!ossl_assert(inl >= GENERIC_BLOCK_SIZE)) {
                ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
                return 0;
            }
            nextblocks -= GENERIC_BLOCK_SIZE;
        }
        outlint += nextblocks;
        if (outsize < outlint) {
            ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
            return 0;
        }
        if (!ctx->hw->cipher(ctx, out, in, nextblocks)) {
            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
            return 0;
        }
        in += nextblocks;
        inl -= nextblocks;
    }
    if (!trailingdata(ctx->buf, &ctx->bufsz, GENERIC_BLOCK_SIZE, &in, &inl)) {
        return 0;
    }
    *outl = outlint;
    return inl == 0;
}
['int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl,\n                                size_t outsize, const unsigned char *in,\n                                size_t inl)\n{\n    size_t outlint = 0;\n    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;\n    size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, GENERIC_BLOCK_SIZE, &in,\n                                  &inl);\n    if (ctx->bufsz == GENERIC_BLOCK_SIZE && (ctx->enc || inl > 0 || !ctx->pad)) {\n        if (outsize < GENERIC_BLOCK_SIZE) {\n            ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);\n            return 0;\n        }\n        if (!ctx->hw->cipher(ctx, out, ctx->buf, GENERIC_BLOCK_SIZE)) {\n            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);\n            return 0;\n        }\n        ctx->bufsz = 0;\n        outlint = GENERIC_BLOCK_SIZE;\n        out += GENERIC_BLOCK_SIZE;\n    }\n    if (nextblocks > 0) {\n        if (!ctx->enc && ctx->pad && nextblocks == inl) {\n            if (!ossl_assert(inl >= GENERIC_BLOCK_SIZE)) {\n                ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);\n                return 0;\n            }\n            nextblocks -= GENERIC_BLOCK_SIZE;\n        }\n        outlint += nextblocks;\n        if (outsize < outlint) {\n            ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);\n            return 0;\n        }\n        if (!ctx->hw->cipher(ctx, out, in, nextblocks)) {\n            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);\n            return 0;\n        }\n        in += nextblocks;\n        inl -= nextblocks;\n    }\n    if (!trailingdata(ctx->buf, &ctx->bufsz, GENERIC_BLOCK_SIZE, &in, &inl)) {\n        return 0;\n    }\n    *outl = outlint;\n    return inl == 0;\n}', 'size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,\n                 const unsigned char **in, size_t *inlen)\n{\n    size_t blockmask = ~(blocksize - 1);\n    assert(*buflen <= blocksize);\n    assert(blocksize > 0 && (blocksize & (blocksize - 1)) == 0);\n    if (*buflen != blocksize && (*buflen != 0 || *inlen < blocksize)) {\n        size_t bufremain = blocksize - *buflen;\n        if (*inlen < bufremain)\n            bufremain = *inlen;\n        memcpy(buf + *buflen, *in, bufremain);\n        *in += bufremain;\n        *inlen -= bufremain;\n        *buflen += bufremain;\n    }\n    return *inlen & blockmask;\n}']